Commit 7eeed2a8 authored by Carsten  Rose's avatar Carsten Rose
Browse files

User Input will be UTF8 normalized - Webserver needs package php5-intl or php7.0-intl.

Add FORM_BS_LABEL_COLUMNS, FORM_BS_INPUT_COLUMNS, FORM_BS_NOTE_COLUMNS to config.qfq.ini.

AdministratorManual/Index.rst: added notes to install php-intl, new config.qfq.ini parameter (see above).
UserManual/index.rst: Fix wrong store name SYSTEM: S > Y. Add new config.qfq.ini parameter (see above).
Store.php: new general function to translate upper case config prameter names to to camel hook FormElement names. Split function fillSystemStore(). Add function normalizeArray().
Constants.php: add new error, renumber error codes 1056-1073. Introduce new config.qfq.ini parameter SYSTEM_FORM_BS_*
QuickFormQuery.php: Use of new bs*Column values defined in config.qfq.inc (not hardcoded here anymore)
parent 2b29d2ca
......@@ -14,21 +14,25 @@ Administrator Manual
Preparation
-----------
The QFQ extension needs the PHP MySQL native driver. The following functions are used and are only available with the
The QFQ extension needs in PHP 5.x the PHP MySQL native driver. The following functions are used and are only available with the
native driver (see also: http://dev.mysql.com/downloads/connector/php-mysqlnd/):
* mysqli::get_result (important),
* mysqli::fetch_all (nice to use)
To normalize UTF8 input, the *php5-intl* resp. *php7.0-intl* package is needed by
* normalizer::normalize()
Preparation for Ubuntu 14.04::
sudo apt-get install php5-mysqlnd
sudo apt-get install php5-mysqlnd php5-intl
sudo php5enmod mysqlnd
sudo service apache2 restart
Preparation steps for Ubuntu 16.04::
none
sudo apt-get install php7-intl
Setup
-----
......@@ -169,6 +173,10 @@ Example: *typo3conf/config.qfq.ini*
CSS_CLASS_QFQ_CONTAINER =
CSS_CLASS_QFQ_FORM_PILL = qfq-color-grey-1
CSS_CLASS_QFQ_FORM_BODY = qfq-color-grey-2
FORM_DATA_PATTERN_ERROR =
FORM_DATA_REQUIRED_ERROR =
FORM_DATA_MATCH_ERROR =
FORM_DATA_ERROR =
Documentation
-------------
......
......@@ -422,7 +422,7 @@ Store: *VARS* - V
.. _STORE_SYSTEM:
Store: *SYSTEM* - S
Store: *SYSTEM* - Y
^^^^^^^^^^^^^^^^^^^
+-------------------------+------------------------------------------------------------+
......@@ -454,6 +454,14 @@ Store: *SYSTEM* - S
+-------------------------+------------------------------------------------------------+
| DATE_FORMAT | defined in config.ini |
+-------------------------+------------------------------------------------------------+
| FORM_DATA_PATTERN_ERROR | defined in config.ini |
+-------------------------+------------------------------------------------------------+
| FORM_DATA_REQUIRED_ERROR| defined in config.ini |
+-------------------------+------------------------------------------------------------+
| FORM_DATA_MATCH_ERROR | defined in config.ini |
+-------------------------+------------------------------------------------------------+
| FORM_DATA_ERROR | defined in config.ini |
+-------------------------+------------------------------------------------------------+
| sqlFinal | computed during runtime, used for error reporting |
+-------------------------+------------------------------------------------------------+
| sqlParamArray | computed during runtime, used for error reporting |
......
......@@ -36,3 +36,8 @@ FORM_DATA_PATTERN_ERROR =
FORM_DATA_REQUIRED_ERROR =
FORM_DATA_MATCH_ERROR =
FORM_DATA_ERROR =
; Default size for Bootstrap Form Elements
FORM_BS_LABEL_COLUMNS = 3
FORM_BS_INPUT_COLUMNS = 6
FORM_BS_NOTE_COLUMNS = 3
......@@ -139,22 +139,23 @@ const ERROR_DATE_TIME_FORMAT_NOT_RECOGNISED = 1053;
const ERROR_SANATIZE_INVALID_VALUE = 1054;
const ERROR_REQUIRED_VALUE_EMPTY = 1055;
const ERROR_DATE_UNEXPECTED_FORMAT = 1056;
const ERROR_NOT_APPLICABLE = 1057;
const ERROR_FORMELEMENT_TYPE = 1058;
const ERROR_MISSING_OPEN_DELIMITER = 1059;
const ERROR_MISSING_CLOSE_DELIMITER = 1060;
const ERROR_EXPECTED_ARRAY = 1061;
const ERROR_REPORT_FAILED_ACTION = 1062;
const ERROR_MISSING_MESSAGE_FAIL = 1063;
const ERROR_MISSING_TABLE_NAME = 1064;
const ERROR_MISSING_TABLE = 1065;
const ERROR_RECORD_NOT_FOUND = 1066;
const ERROR_INVALID_EDITOR_PROPERTY_NAME = 1067;
const ERROR_UNKNOWN_ESCAPE_MODE = 1068;
const ERROR_MISSING_CONFIG_INI_VALUE = 1069;
const ERROR_SENDMAIL = 1070;
const ERROR_SENDMAIL_MISSING_VALUE = 1071;
const ERROR_OVERWRITE_RECORD_ID = 1072;
const ERROR_UNEXPECTED_TYPE = 1057;
const ERROR_NOT_APPLICABLE = 108;
const ERROR_FORMELEMENT_TYPE = 1059;
const ERROR_MISSING_OPEN_DELIMITER = 1060;
const ERROR_MISSING_CLOSE_DELIMITER = 1061;
const ERROR_EXPECTED_ARRAY = 1062;
const ERROR_REPORT_FAILED_ACTION = 1063;
const ERROR_MISSING_MESSAGE_FAIL = 1064;
const ERROR_MISSING_TABLE_NAME = 1065;
const ERROR_MISSING_TABLE = 1066;
const ERROR_RECORD_NOT_FOUND = 1067;
const ERROR_INVALID_EDITOR_PROPERTY_NAME = 1068;
const ERROR_UNKNOWN_ESCAPE_MODE = 1069;
const ERROR_MISSING_CONFIG_INI_VALUE = 1070;
const ERROR_SENDMAIL = 1071;
const ERROR_SENDMAIL_MISSING_VALUE = 1072;
const ERROR_OVERWRITE_RECORD_ID = 1073;
// Subrecord
const ERROR_SUBRECORD_MISSING_COLUMN_ID = 1100;
......@@ -305,6 +306,9 @@ const SYSTEM_FORM_DATA_REQUIRED_ERROR = 'FORM_DATA_REQUIRED_ERROR';
const SYSTEM_FORM_DATA_MATCH_ERROR = 'FORM_DATA_MATCH_ERROR';
const SYSTEM_FORM_DATA_ERROR = 'FORM_DATA_ERROR';
const SYSTEM_FORM_BS_LABEL_COLUMNS = 'FORM_BS_LABEL_COLUMNS';
const SYSTEM_FORM_BS_INPUT_COLUMNS = 'FORM_BS_INPUT_COLUMNS';
const SYSTEM_FORM_BS_NOTE_COLUMNS = 'FORM_BS_NOTE_COLUMNS';
// computed automatically during runtime
const SYSTEM_PATH_EXT = 'EXT_PATH';
......
......@@ -511,11 +511,19 @@ class QuickFormQuery {
* @return array
*/
private function setFormDefault(array $formSpec) {
# Set defaults:
Support::setIfNotSet($formSpec, 'class', '');
Support::setIfNotSet($formSpec, F_BS_LABEL_COLUMNS, 3, '');
Support::setIfNotSet($formSpec, F_BS_INPUT_COLUMNS, 6, '');
Support::setIfNotSet($formSpec, F_BS_NOTE_COLUMNS, 3, '');
$value = $this->store->getVar(F_BS_LABEL_COLUMNS, STORE_SYSTEM);
Support::setIfNotSet($formSpec, F_BS_LABEL_COLUMNS, $value, '');
$value = $this->store->getVar(F_BS_INPUT_COLUMNS, STORE_SYSTEM);
Support::setIfNotSet($formSpec, F_BS_INPUT_COLUMNS, $value, '');
$value = $this->store->getVar(F_BS_NOTE_COLUMNS, STORE_SYSTEM);
Support::setIfNotSet($formSpec, F_BS_NOTE_COLUMNS, $value, '');
Support::setIfNotSet($formSpec, F_SUBMIT_BUTTON_TEXT, '');
Support::setIfNotSet($formSpec, F_EXTRA_DELETE_FORM, '');
......
......@@ -20,7 +20,6 @@ require_once(__DIR__ . '/../../qfq/store/Sip.php');
//require_once(__DIR__ . '/../../qfq/store/Session.php');
require_once(__DIR__ . '/../../qfq/Database.php');
/*
* Stores:
* - SIP
......@@ -187,22 +186,81 @@ class Store {
}
try {
//TODO: Vernuenftige Fehlermeldung falls nicht auf qfq.ini zugegriffen werden kann.
// $config = parse_ini_file(__DIR__ . '/../../../' . CONFIG_INI, false);
$config = parse_ini_file($configIni, false);
//TODO: auskommentiert weil dann die Unittests nicht mehr laufen. Sollte eigentlich wieder aktiviert werden.
// $config['SQLLOG'] = Support::ifRelativePathPrependExtensionPath($config['SQLLOG']);
} catch (\Exception $e) {
throw new qfq\UserFormException ("Error read file " . CONFIG_INI . ": " . $e->getMessage(), ERROR_IO_READ_FILE);
}
$config = self::renameConfigElements($config);
// Defaults
Support::setIfNotSet($config, SYSTEM_DATE_FORMAT, 'yyyy-mm-dd');
Support::setIfNotSet($config, SYSTEM_SHOW_DEBUG_INFO, 'auto');
Support::setIfNotSet($config, F_BS_LABEL_COLUMNS, '3');
Support::setIfNotSet($config, F_BS_INPUT_COLUMNS, '6');
Support::setIfNotSet($config, F_BS_NOTE_COLUMNS, '3');
// Adjust config
if (!isset($config['SHOW_DEBUG_INFO']) || $config['SHOW_DEBUG_INFO'] === 'auto') {
$config['SHOW_DEBUG_INFO'] = (isset($GLOBALS["TSFE"]->beUserLogin) && $GLOBALS["TSFE"]->beUserLogin === true) ? 'yes' : 'no';
if ($config[SYSTEM_SHOW_DEBUG_INFO] === 'auto') {
$config[SYSTEM_SHOW_DEBUG_INFO] = (isset($GLOBALS["TSFE"]->beUserLogin) && $GLOBALS["TSFE"]->beUserLogin === true) ? 'yes' : 'no';
}
$config = self::doSystemPath($config);
// make SQL PATH absolute. This is necessary to work in different directories correctly.
if (isset($config[SYSTEM_SQL_LOG]) && $config[SYSTEM_SQL_LOG][0] !== '/') {
$config[SYSTEM_SQL_LOG] = $config[SYSTEM_PATH_EXT] . '/' . $config[SYSTEM_SQL_LOG];
}
// Verify existence
$names = array('DB_USER', 'DB_SERVER', 'DB_PASSWORD', 'DB_NAME', 'SQL_LOG', 'SQL_LOG_MODE');
foreach ($names as $name) {
if (!isset($config[$name])) {
throw new qfq\UserFormException ("Missing configuration in `config.ini`: $name", ERROR_MISSING_CONFIG_INI_VALUE);
}
}
self::setVarArray($config, STORE_SYSTEM, true);
}
/**
* Rename Elements defined in config.qfq.ini to more appropriate in user interaction.
* E.g.: in config.qfq.ini everything is in upper case and word space is '_'. In Form.parameter it's lowercase and camel hook.
*
* @param array $config
* @return array
*/
private function renameConfigElements(array $config) {
// oldname > newname
$setting = [
[SYSTEM_FORM_BS_LABEL_COLUMNS, F_BS_LABEL_COLUMNS],
[SYSTEM_FORM_BS_INPUT_COLUMNS, F_BS_INPUT_COLUMNS],
[SYSTEM_FORM_BS_NOTE_COLUMNS, F_BS_NOTE_COLUMNS],
];
foreach ($setting as $row) {
$oldName = $row[0];
$newName = $row[1];
if (isset($config[$oldName])) {
$config[$newName] = $config[$oldName];
if ($oldName != $newName) {
unset($config[$oldName]);
}
}
}
return $config;
}
/**
* @param array $config
* @return array
*/
private function doSystemPath(array $config) {
// SYSTEM_PATH_EXT: compute only if not already defined.
if (!isset($config[SYSTEM_PATH_EXT]) || $config[SYSTEM_PATH_EXT] === '' || $config[SYSTEM_PATH_EXT][0] !== '/') {
$relExtDir = '/typo3conf/ext/' . EXT_KEY;
......@@ -226,24 +284,7 @@ class Store {
$config[SYSTEM_PATH_EXT] = getcwd();
}
}
// Defaults
Support::setIfNotSet($config, SYSTEM_DATE_FORMAT, 'yyyy-mm-dd');
// make SQL PATH absolute. This is necessary to work in different directories correctly.
if (isset($config[SYSTEM_SQL_LOG]) && $config[SYSTEM_SQL_LOG][0] !== '/') {
$config[SYSTEM_SQL_LOG] = $config[SYSTEM_PATH_EXT] . '/' . $config[SYSTEM_SQL_LOG];
}
// Verify existence
$names = array('DB_USER', 'DB_SERVER', 'DB_PASSWORD', 'DB_NAME', 'SQL_LOG', 'SQL_LOG_MODE');
foreach ($names as $name) {
if (!isset($config[$name])) {
throw new qfq\UserFormException ("Missing configuration in `config.ini`: $name", ERROR_MISSING_CONFIG_INI_VALUE);
}
}
self::setVarArray($config, STORE_SYSTEM, true);
return $config;
}
/**
......@@ -341,12 +382,41 @@ class Store {
if (isset($_POST))
$arr = array_merge($arr, $_POST);
// It's important to merge the SERVER array last: those entries shall overwrite client values.
if (isset($_SERVER))
$arr = array_merge($arr, $_SERVER);
$arr = self::normalizeArray($arr);
self::setVarArray($arr, STORE_CLIENT, true);
}
/**
* Iterates over all elements of the given array and normalize the input. Only strings will be normalized.
* Skip numeric content and throw an exception for everything else.
*
* It's important to normalize the user input: e.g. someone is searching for a record and input the search string
* with compositons characters.
*
* @param array $arr
* @return array
* @throws \qfq\CodeException
*/
private function normalizeArray(array $arr) {
foreach ($arr as $key => $value) {
if (is_string($value)) {
$arr[$key] = \normalizer::normalize($value);
} else {
if (!is_numeric($value)) {
throw new qfq\CodeException ("Expect type 'string'", ERROR_UNEXPECTED_TYPE);
}
}
}
return $arr;
}
/**
* Fills the STORE_SIP. Reads therefore specified SIP, decode the values and stores them in STORE_SIP.
*
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment