Commit 6e796c6e authored by Rafael Ostertag's avatar Rafael Ostertag
Browse files

Merge remote-tracking branch 'remotes/origin/crose_work' into raos_work

parents 06cefd48 7cf2b3ce
......@@ -50,9 +50,9 @@ The SIP will store:
Use with SQL: `typeAheadSql`
Use with LDAP:
* `typeAheadLdapServer`
* `typeAheadLdapBaseDn`
Use with LDAP: `typeAheadLdap`
* `ldapServer`
* `ldapBaseDn`
* `typeAheadLdapSearch`
* `typeAheadLdapValuePrintf`
* `typeAheadLdapKeyPrintf`
......
Notes
=====
* Surround <p> Tag - https://www.tinymce.com/docs/configure/content-filtering/#forced_root_block >>
In QFQ Formeditor on the specific FormElement.parameter: `editor-forced_root_block=false`
\ No newline at end of file
......@@ -58,4 +58,5 @@ QFQ Extension
:maxdepth: 4
Manual
Release
Links
This diff is collapsed.
.. _release:
Release
=======
Version 0.future
----------------
Changes
^^^^^^^
Features
^^^^^^^^
Bug Fixes
^^^^^^^^^
Version 0.14
------------
GIT Last Commit: Sun Mar 19 20:38:18 2017 +0100
Changes
^^^^^^^
* Play formEditor.sql.
* All Form & FormEditor input elements now have a maxlength definition of 0, which means take the column definition value.
* Drop-down list of container assignment:
* Display 'type' ('pill', 'fieldset', 'templategroup') instead of 'class' (always 'container').
* Display 'name' (internal name) instead of 'label' (shown on the website and might not so usefull as 'name' which is nowhere else used than in that drop-down.
* FormElement.placeholder colum width extended to 512:
ALTER TABLE `FormElement` CHANGE `placeholder` `placeholder` VARCHAR(512) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '';
* New class Ldap.php.
Features
^^^^^^^^
* Typeahead for SQL and LDAP Datasources implemented.
* formEditor.sql: Changed width of column FormElement.placeholder from 255 to 512. Removed hardcoded 'size' in FormElement 'placeholder'.
* Character Count: Display a `counter` on input or textarea fields, activated by specifying the formElement.parameter 'characterCountWrap'.
* Evaluate.php: Two new escape options 'l' and 'L'. Backport of ldap_escape() for PHP <5.6. Multiple escaping for one value now possible.
* Manual.rst: add some example for TypeAhead and for saving LDAP value.
Bug Fixes
^^^^^^^^^
* Dynamic Update has been broken since implementing of 'element-update' (#3180). Now both methods, 'element-update' and 'form-update' should be fine.
* qfq-bs.css.less: Fixed problem with 'typeahead input elements' not expanded to Bootstrap column width. Changed
Layout/Design Typeahead drop-down box. Add hoover for the drop-down box with a blue background
* AbstractBuildForm.php: #3374 - textarea elements now contains 'maxlength' attribute.
* BuildFormBootstrap.php: wrapping of optional 'submitButtonText' now done with the 'per form' values.
* typeahead.php: if there is an exception, the message body is sent as regular 'content' for the drop-down box. At the
moment this is the only way to transmit any error messages.
Version 0.13
------------
Changes
^^^^^^^
* Play formEditor.sql.
* formEditor.sql:
* Checktype of `Form.name` restricted to `alnumx` (prior `all`).
* Changed `access` for Form `form` & '`ormElement` from `always` to `sip`.
* Table `FormElement`
* Modified column: `checkType` - new value `numerical`
ALTER TABLE FormElement MODIFY COLUMN checkType ENUM('alnumx','digit','numerical','email','min|max','min|max date',
'pattern','allbut','all') NOT NULL DEFAULT 'alnumx'
* Example Report for `forms` extended by a delete button per row.
Features
^^^^^^^^
* print.php: offers 'print page' for any local page - create a PDF on the fly (printout is then browser independent).
* Install `wkhtmltopdf` on the webserver (http://wkhtmltopdf.org/).
* In config.qfq.ini setup:
BASE_URL_PRINT=http://www.../
WKHTMLTOPDF=/opt/wkhtmltox/bin/wkhtmltopdf
* Check and error report if 'php_intl' is missing.
* New Checktype 'allow numerical'.
* Documentation: example for 'radio' with no pre selection.
* #3063, Radios and checkboxes optional rendered in Bootstrap layout.
* Added 'help-box with-errors'-DIV after radios and checkboxes.
* Respect attribute `data-class-on-change` on save buttons.
Bug Fixes
^^^^^^^^^
* #2138 / digit sanitize: new class 'numerical' implemented.
* Fixed recursive thrown exception.
* #2064 / search of a default value for a non existing tablecolumn returns 'false'.
* Fixed setting of STORE_SYSTEM / showDebugInfo during API call.
* #2081, #3180 Form: Label & note - update via `DynamicUpdate`
* #3253, if there is no STORE_TYPO3 (calls through .../api/ like save, delete, load): use SIP / CLIENT_TYPO3VARS.
* qfq-bs.css:
* Alignment of checkboxes and radios optimized.
* CSS class 'qfq-note' for 'notes' (third column in a form).
Version 0.12
------------
Changes
^^^^^^^
* Table 'FormElement'
* New column: rowLabelInputNote
ALTER TABLE `FormElement` ADD `rowLabelInputNote` set('row','label','/label','input','/input','note','/note','/row')
NOT NULL DEFAULT 'row,label,/label,input,/input,note,/note,/row' AFTER `bsNoteColumns` ;
* Modified column: 'type' - new value 'templateGroup'
ALTER TABLE `FormElement` CHANGE `type` `type` ENUM( 'checkbox', 'date', 'datetime', 'dateJQW', 'datetimeJQW', 'extra',
'gridJQW', 'text', 'editor', 'time', 'note', 'password', 'radio', 'select', 'subrecord', 'upload', 'fieldset', 'pill',
'templateGroup', 'beforeLoad', 'beforeSave', 'beforeInsert', 'beforeUpdate', 'beforeDelete', 'afterLoad', 'afterSave',
'afterInsert', 'afterUpdate', 'afterDelete', 'sendMail' ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'text';
* formEditor.sql: Added HTML 'placeholder' in FormEditor for bs*Columns.
* PLAY 'formEditor.sql'.
* User Input will be UTF8 normalized.
* INSTALL 'php5-intl' or 'php7.0-intl' on Webserver.
* Add globalize.js to be included. Needed by jqx-all.js
* UPDATE EXISTING TypoScript TEMPLATES of QFQ Installation.
* Name of variable '_filename' (used in field 'parameter') has changed. Old: '_filename', New: 'filename'
* UPDATE `FormElement` SET parameter = REPLACE(parameter, '_filename', 'filename')
Features
^^^^^^^^
* User input will be UTF8 normalized
* config.qfq-ini:
* New configuration values: FORM_BS_LABEL_COLUMNS / FORM_BS_INPUT_COLUMNS / FORM_BS_NOTE_COLUMNS
* Comment empty variables - the new default setting is, that empty parameter in config.qfq.ini means EMPTY (=parameter is set and will not be overwritten by internal default), not UNDEFINED (overwritten by internal default).
* FileUpload:
* Implemented new Formelement.parameter: fileReplace=always - will replace existing files.
* Multiple / Advanced Upload: new logic implements slaveId, sqlInsert, sqlUpdate, sqlDelete.
* FormElement.parameter: sqlBefore / sqlAfter fired during 'Form' save for action elements.
* STORE FORM: variable 'filename' moved to STORE VAR - sanatize class needs no longer specified.
* STORE VAR: two new variables 'filename' and 'fileDestination' valid during processing of current upload FormElement.
* Default store priority list changed. Old: 'FSRD', New: 'FSRVD'.
* CODING.md: update doc for FormElement 'upload' and general 'Form' rendering & save (recursive rendering).
* User manual:
* Described form layout options: description for bsLabelColumn, bsInputColumn, bsNoteColumn
* Update 'file-upload' doc.
* Described 3 examples for upload forms.
* Administrator manual:
* Add description page.meta...
* New FormElement (type= 'container') added: 'templateGroup'
* FormElement.parameter.tgAddClass | tgAddText | tgRemoveClass | tgRemoveText | tgClass
* FormElement.maxSize: max number of duplicates
* #3230 templateGroup: margin between copies. 'tgClass' implemented.
* Native FormElements:
* FormElement.parameter.htlmlBefore|htmlAfter - add the specified HTML code before or after the element (outside of any wrapping)
* #3224, #3231 Html Tag <hr> als FormElement. >> htmlBefore | htmlAfter.
* FormElement.parameter.wrapLabel | wrapInput | wrapAfter | wrapRow - if specified, any default wrapping is omitted.
* FormElement.bsNoteColumns | bsInputColumns | bsNoteColumns - a '0' will suppress the whole rendering of the item.
* FormElement.rowLabelInputNote - switch on/off rendering of the corresponding system wrapping items.
* #3232 Define custom 'on-change' color - used for the save button: Form.parameter.buttonOnChangeClass=...
* Form.parameter & FormElement.parameter: Lines starting with '#' are treated as comments and will not be parsed.
Bug fixes
^^^^^^^^^
* User manual:
* Fixed double include of validator.js in T3 Typoscript template example.
* Fixed wrong store name SYSTEM: S > Y
* Fixed wrong STORE_FORM variable names.
* Reformat FormElement.parameter description.
* Styling errors fixed.
* Use of 'decryptCurlyBraces()' to get better error messages.
* Skip unwanted parameter expansion during save.
* Fixed bug with uninitialized FE_SLAVE_ID
* formEditor.sql:
* The defintion as 'editor' (not text) for FormElement 'note' has been lost - reinserted.
* Fixed problem while playing SQL query - deleting old FormElements of Formeditor deleted also FormElements of other forms.
* #3066 / help-text with-error - CSS class 'hidden' will be rendered by default (as long there is no error).
* Labels are skipped, if FormElement.bsLabelColumns=0.
* Respect attribute `data-class-on-change` on save buttons.
Version 0.11
------------
Features
^^^^^^^^
* Added STORE_BEFORE, #3146 - Mainly used to compare old and new values during a form 'save' action.
* Added 'best practice' for defining and using of 'Central configure values' in UserManual.
* Added accent characters to sanatize class 'alnumx', #3183.
* Set default all QFQ send mails to 'auto-submit'.
* Added possibility to customize error messages ('data-pattern-error', 'data-rquired-error', 'data-match-error',
'data-error') if validation fails. Customization can be done on global level (config.qfq.ini), per Form or per FormElement.
* *FormElement*: Double an input element and validate that the input match: FormElement.parameter.retype=1
* Autofocus in Forms is now supported. By default the first Input Element receives the focus. Can be customized.
* Added a timestamp in shown exceptions. Usefull for screenshots, send by customer, to find the problem in SQL logfiles.
Bug fixes
^^^^^^^^^
* Fixed missing docutmentation for FormElement 'note'.
* Failed SQL queries will now always be logged, even if they do not modify some data.
Version 0.10
------------
Features
^^^^^^^^
* Implemented Parameter 'extraDeleteForm' for 'forms' and 'subrecords'. Update doc.
Bug fixes
^^^^^^^^^
* Suppress rendering of form title during a 'delete' call. No one will see it and required parameters are not supplied.
* In case of broken SQL queries, print them in ajax error message.
* Remove parameter 'table' from Delete SIP URLs. ToolTip updated.
Version 0.9
-----------
Features
^^^^^^^^
* FormEditor:
* design update - new default background color: grey.
* per form configureable background colors.
* Optional right align of all form element labels.
* Added config.qfq.ini values CSS_CLASS_QFQ_FORM_PILL, CSS_CLASS_QFQ_FORM_BODY, CSS_CLASS_QFQ_CONTAINER.
Bug fixes
^^^^^^^^^
* BuildFormBootstrap.php: added new class name 'qfq-label' to form labels - needed to assign 'qfq-form-right' class. Changed wrapping of formelements from 'col-md-8' (wrong) to 'col-md-12'.
* QuickFormQuery.php: Set default for new F_CLASS_PILL & F_CLASS_BODY.
* formEditor.sql: New default background color for formElements is blue.
* qfq-bs.css.less: add classes qfq-form-pill, qfq-form-body, form-group (center), qfq-color-..., qfq-form-right.
* Index.rst: Add note to hierachy chars. Fixed uncomplete doc to a) bs*Columns, showButton. Add classPill, classBody. Rewrote form.paramter.class.
* QuickFormQuery.php: Button save/ close/ delete/ new - align to right border of form.
* UsersManual/index.rst: renamed chapter for formelements. Cleanup formelement types. Wrote chapter 'Detailed concept'.
* QuickFormQuery.php, FormAction.php: '#2931 / afterSave Hauptrecord xId nicht direkt verfügbar' - load master record again, after 'action'-elements has been processed.
* UsersManual/index.rst: Startet FAQ section.
* config.qfq.example.ini: Added comment where to save config.qfq.ini.
* UsersManual/index.rst: Rewrite of 'action'-FormElement definition.
* #2739: beforeDelete / afterDelete.
* PROTOCOL.md: update 'delete' description.
* delete.php: fixed unwanted loose of MSG_CONTENT.
* Report.php: Fixed double '&&' in building UrlParam.
* FormAction.php: In case of 'AFTER_DELETE', do not try to load primary record - that one is already deleted.
* Sip.php: Do not skip SIP_TARGET_URL as parameter for the SIP.
* #3001 Report: delete implementieren.
* Index.rst, Constants.php: reverted parameter '_table' in delete links back to 'table' - Reason: 'form' needs to be 'form' (instead of '_form') due to many used places already.
* Sip.php: move SIP_TARGET_URL back to stored inside SIP - it's necessary for 'delete'-links.
* Report.php, Constants.php: Remove code to handle unecessary 'p:' tag for delete links.
* Link.php: Check paged / Paged that the parameter r, table and form are given in the right combination.
* Link.php, Report.php: New '_link' token 'x'. '_paged' and '_Paged' are rendered via Link() class, Link() class now supports delete links.
* QuickFormQuery.php: for modeForm='Form Delete' the 'required param' are not respected - this makes sense, cause these parameters typically filled in newly created records.
* Fixed: #3076 Delete Button bei Subrecords erzeugt sporadisch Javascript Exceptions (Webkit: Chrome / Vivaldi) - kein loeschen moeglich.
......@@ -19,15 +19,14 @@ require_once(__DIR__ . '/../qfq/Constants.php');
* Return JSON encoded answer
*
*/
try {
$qfq = new \qfq\TypeAhead();
$answer = $qfq->process();
} catch (\Exception $e) {
$answer[API_MESSAGE] = "Generic Exception: " . $e->getMessage();
// $answer[API_MESSAGE] = "Generic Exception: " . $e->getMessage();
$answer[] = [API_TYPEAHEAD_KEY => 'errror', API_TYPEAHEAD_VALUE => "Error: " . $e->getMessage()];
}
header("Content-Type: application/json");
......
......@@ -22,6 +22,7 @@ require_once(__DIR__ . '/../qfq/Database.php');
require_once(__DIR__ . '/../qfq/helper/HelperFormElement.php');
require_once(__DIR__ . '/../qfq/helper/Support.php');
require_once(__DIR__ . '/../qfq/helper/OnArray.php');
require_once(__DIR__ . '/../qfq/helper/Ldap.php');
require_once(__DIR__ . '/../qfq/report/Link.php');
/**
......@@ -375,13 +376,16 @@ abstract class AbstractBuildForm {
continue; // skip this FE
}
$flagOutput = ($fe[FE_TYPE] !== FE_TYPE_EXTRA); // type='extra' will not displayed not trasnmitted to the form
$flagOutput = ($fe[FE_TYPE] !== FE_TYPE_EXTRA); // type='extra' will not displayed and not transmitted to the form
$debugStack = array();
// Preparation for Log, Debug
$this->store->setVar(SYSTEM_FORM_ELEMENT, Logger::formatFormElementName($fe), STORE_SYSTEM);
// Fill STORE_LDAP
$fe = $this->prepareFillStoreFireLdap($fe);
// for Upload FormElements, it's necessary to precalculate an optional given 'slaveId'.
if ($fe[FE_TYPE] === FE_TYPE_UPLOAD) {
Support::setIfNotSet($fe, FE_SLAVE_ID);
......@@ -389,7 +393,7 @@ abstract class AbstractBuildForm {
$this->store->setVar(VAR_SLAVE_ID, $slaveId, STORE_VAR);
}
// evaluate current FormElement
// ** evaluate current FormElement **
$formElement = $this->evaluate->parseArray($fe, $skip, $debugStack);
// Some Defaults
......@@ -402,8 +406,24 @@ abstract class AbstractBuildForm {
//In case the current element is a 'RETYPE' element: take the element name of the source FormElement. Needed in the next row to retrieve the default value.
$name = (isset($formElement[FE_RETYPE_SOURCE_NAME])) ? $formElement[FE_RETYPE_SOURCE_NAME] : $formElement[FE_NAME];
// If there is a value explicit defined: take it
$value = '';
Support::setIfNotSet($formElement, FE_VALUE);
// If is FormElement['value'] explicit defined: take it
// There are two options: a) single value, b) array of values (template Group)
// if (is_array($formElement[FE_VALUE])) {
// // For Templates Groups, the 'value' has to be defined as '{{!SELECT ...' wich returns all selected records in an array.
// $idx = isset($formElement[FE_TEMPLATE_GROUP_CURRENT_IDX]) ? $formElement[FE_TEMPLATE_GROUP_CURRENT_IDX] - 1 : 0;
// if (isset($formElement[FE_VALUE][$idx]) && is_array($formElement[FE_VALUE][$idx])) {
// $value = current($formElement[FE_VALUE][$idx]);
// if ($value === false) {
// $value = '';
// }
// }
// } else {
$value = $formElement[FE_VALUE];
// }
if ($value === '') {
// Only take the default, if the FE is a real tablecolumn. See #2064
if ($this->store->getVar($formElement[FE_NAME], STORE_TABLE_COLUMN_TYPES) !== false) {
......@@ -461,6 +481,41 @@ abstract class AbstractBuildForm {
return $html;
}
/**
* Checks if LDAP search is requested.
* Yes: prepare configuration and fire the query.
* No: do nothing.
*
* @param array $formElement
* @return array
* @throws CodeException
* @throws UserFormException
*/
private function prepareFillStoreFireLdap(array $formElement) {
$config = array();
if (isset($formElement[FE_FILL_STORE_LDAP]) || isset($formElement[FE_TYPEAHEAD_LDAP])) {
$keyNames = [F_LDAP_SERVER, F_LDAP_BASE_DN, F_LDAP_ATTRIBUTES, F_LDAP_SEARCH, F_TYPEAHEAD_LDAP_SEARCH, F_TYPEAHEAD_LIMIT,
F_TYPEAHEAD_MINLENGTH, F_TYPEAHEAD_LDAP_VALUE_PRINTF, F_TYPEAHEAD_LDAP_KEY_PRINTF, F_LDAP_TIME_LIMIT];
$formElement = OnArray::copyArrayItemsIfNotAlreadyExist($this->formSpec, $formElement, $keyNames);
} else {
return $formElement; // nothing to do.
}
if (isset($formElement[FE_FILL_STORE_LDAP])) {
// Extract necessary elements
$config = OnArray::getArrayItems($formElement, [FE_LDAP_SERVER, FE_LDAP_BASE_DN, FE_LDAP_SEARCH, FE_LDAP_ATTRIBUTES]);
$config = $this->evaluate->parseArray($config);
$ldap = new Ldap();
$arr = $ldap->process($config, '', MODE_LDAP_SINGLE);
$this->store->setStore($arr, STORE_LDAP, true);
}
return $formElement;
}
/**
* Check if there is an explicit 'autofocus' definition in at least one FE.
* Found: do nothing, it will be rendered at the correct position.
......@@ -727,6 +782,7 @@ abstract class AbstractBuildForm {
$textarea = '';
$attribute = '';
$class = 'form-control';
$elementCharacterCount = '';
$typeAheadUrlParam = $this->typeAheadBuildParam($formElement);
if ($typeAheadUrlParam != '') {
......@@ -737,15 +793,43 @@ abstract class AbstractBuildForm {
$attribute .= Support::doAttribute(DATA_TYPEAHEAD_MINLENGTH, $formElement[FE_TYPEAHEAD_MINLENGTH]);
}
if (isset($formElement[FE_CHARACTER_COUNT_WRAP])) {
$class .= ' ' . CLASS_CHARACTER_COUNT;
$attribute .= Support::doAttribute(DATA_CHARACTER_COUNT_ID, $formElement[FE_HTML_ID] . HTML_ID_EXTENSION_CHARACTER_COUNT);
$attributeCC = Support::doAttribute('id', $formElement[FE_HTML_ID] . HTML_ID_EXTENSION_CHARACTER_COUNT);
$classCC = ($formElement[FE_CHARACTER_COUNT_WRAP] == '') ? Support::doAttribute('class', 'qfq-cc-style') : '';
$elementCharacterCount = "<span $attributeCC $classCC></span>";
if ($formElement[FE_CHARACTER_COUNT_WRAP] != '') {
$arr = explode('|', $formElement[FE_CHARACTER_COUNT_WRAP], 2);
$arr[] = '';
$arr[] = ''; //skip check that at least 2 elements exist
$elementCharacterCount = $arr[0] . $elementCharacterCount . $arr[1];
}
}
$attribute .= Support::doAttribute('id', $formElement[FE_HTML_ID]);
$attribute .= Support::doAttribute('name', $htmlFormElementName);
$attribute .= Support::doAttribute('class', $class);
if (isset($formElement[FE_RETYPE_SOURCE_NAME])) {
$htmlFormElementNamePrimary = str_replace(RETYPE_FE_NAME_EXTENSION, '', $htmlFormElementName);
$attribute .= Support::doAttribute('data-match', '[name=' . str_replace(':', '\\:', $htmlFormElementNamePrimary) . ']');
}
$this->adjustMaxLength($formElement);
if ($formElement[FE_MAX_LENGTH] > 0 && $value !== '') {
// crop string only if it's not empty (substr returns false on empty strings)
$value = substr($value, 0, $formElement[FE_MAX_LENGTH]);
}
// 'maxLength' needs an upper 'L': naming convention for DB tables!
if ($formElement[FE_MAX_LENGTH] > 0) {
$attribute .= Support::doAttribute('maxlength', $formElement[FE_MAX_LENGTH], false);
}
// Check for input type 'textarea'.
$colsRows = explode(',', $formElement['size'], 2);
if (count($colsRows) === 2) {
......@@ -759,15 +843,7 @@ abstract class AbstractBuildForm {
} else {
$htmlTag = '<input';
$this->adjustMaxLength($formElement);
if ($formElement[FE_MAX_LENGTH] > 0 && $value !== '') {
// crop string only if it's not empty (substr returns false on empty strings)
$value = substr($value, 0, $formElement[FE_MAX_LENGTH]);
}
// 'maxLength' needs an upper 'L': naming convention for DB tables!
$attribute .= $this->getAttributeList($formElement, ['type', 'size', 'maxLength']);
$attribute .= $this->getAttributeList($formElement, ['type', 'size']);
$attribute .= Support::doAttribute('value', htmlentities($value), false);
}
......@@ -781,17 +857,18 @@ abstract class AbstractBuildForm {
$json = $this->getFormElementForJson($htmlFormElementName, $value, $formElement);
return "$htmlTag $attribute>$textarea" . $this->getHelpBlock();
return "$htmlTag $attribute>$textarea" . $elementCharacterCount . $this->getHelpBlock();
}
/**
* Check $formElement for FE_TYPE_AHEAD_SQL or FE_TYPE_AHEAD_LDAP_SERVER.
* If one of them is given: fill $urlParam.
* Set some parameter for later outside use, especially FE_TYPEAHEAD_LIMIT, FE_TYPEAHEAD_MINLENGTH
* If one of them is given: build $urlParam with typeAhead Params.
* Additionally set some parameter for later outside use, especially FE_TYPEAHEAD_LIMIT, FE_TYPEAHEAD_MINLENGTH
*
* @param array $formElement
* @return string
* @throws UserFormException
*/
private function typeAheadBuildParam(array &$formElement) {
......@@ -803,16 +880,26 @@ abstract class AbstractBuildForm {
if (isset($formElement[FE_TYPEAHEAD_SQL])) {
$sql = $this->checkSqlAppendLimit($formElement[FE_TYPEAHEAD_SQL], $formElement[FE_TYPEAHEAD_LIMIT]);
$urlParam = FE_TYPEAHEAD_SQL . '=' . $sql;
} elseif (isset($formElement[FE_TYPEAHEAD_LDAP_SERVER])) {
$formElement[FE_TYPEAHEAD_LDAP_SERVER] = Support::setIfNotSet($formElement, FE_TYPEAHEAD_LDAP_SERVER);
$formElement[FE_TYPEAHEAD_LDAP_BASE_DN] = Support::setIfNotSet($formElement, FE_TYPEAHEAD_LDAP_BASE_DN);
} elseif (isset($formElement[FE_TYPEAHEAD_LDAP])) {
$formElement[FE_LDAP_SERVER] = Support::setIfNotSet($formElement, FE_LDAP_SERVER);
$formElement[FE_LDAP_BASE_DN] = Support::setIfNotSet($formElement, FE_LDAP_BASE_DN);
$formElement[FE_TYPEAHEAD_LDAP_SEARCH] = Support::setIfNotSet($formElement, FE_TYPEAHEAD_LDAP_SEARCH);
$formElement[FE_TYPEAHEAD_LDAP_VALUE_PRINTF] = Support::setIfNotSet($formElement, FE_TYPEAHEAD_LDAP_VALUE_PRINTF);
$formElement[FE_TYPEAHEAD_LDAP_KEY_PRINTF] = Support::setIfNotSet($formElement, FE_TYPEAHEAD_LDAP_KEY_PRINTF);
foreach ([FE_LDAP_SERVER, FE_LDAP_BASE_DN, FE_TYPEAHEAD_LDAP_SEARCH] as $key) {
if ($formElement[$key] == '') {
throw new UserFormException('Missing definition: ' . $key, ERROR_MISSING_DEFINITON);
}
}
if ($formElement[FE_TYPEAHEAD_LDAP_VALUE_PRINTF] . $formElement[FE_TYPEAHEAD_LDAP_KEY_PRINTF] == '') {
throw new UserFormException('Missing definition: ' . FE_TYPEAHEAD_LDAP_VALUE_PRINTF . ' or ' . FE_TYPEAHEAD_LDAP_KEY_PRINTF, ERROR_MISSING_DEFINITON);
}
$arr = [
FE_TYPEAHEAD_LDAP_SERVER => $formElement[FE_TYPEAHEAD_LDAP_SERVER],
FE_TYPEAHEAD_LDAP_BASE_DN => $formElement[FE_TYPEAHEAD_LDAP_BASE_DN],
FE_LDAP_SERVER => $formElement[FE_LDAP_SERVER],
FE_LDAP_BASE_DN => $formElement[FE_LDAP_BASE_DN],
FE_TYPEAHEAD_LDAP_SEARCH => $formElement[FE_TYPEAHEAD_LDAP_SEARCH],
FE_TYPEAHEAD_LDAP_VALUE_PRINTF => $formElement[FE_TYPEAHEAD_LDAP_VALUE_PRINTF],
FE_TYPEAHEAD_LDAP_KEY_PRINTF => $formElement[FE_TYPEAHEAD_LDAP_KEY_PRINTF],
......@@ -820,6 +907,7 @@ abstract class AbstractBuildForm {
];
$urlParam = OnArray::toString($arr);
}
return $urlParam;
......@@ -2694,7 +2782,8 @@ abstract class AbstractBuildForm {
* @return mixed
*/
public function buildNote(array $formElement, $htmlFormElementName, $value, array &$json, $mode = FORM_LOAD) {
return Support::wrapTag("<div class='qfq-note'>", $value);
//
return Support::wrapTag("<div class='" . CLASS_NOTE . "'>", $value);
}
/**
......@@ -2888,29 +2977,38 @@ EOT;
}
$default = $this->store->getStore(STORE_TABLE_DEFAULT); // current defaults
// evaluate FE_VALUE on all templateGroup FormElements.
$maxForeignRecords = $this->templateGroupDoValue();
$lastFilled = 0; // Marker if there is at least one element per copy who is filled.
$feSpecNativeCopy = array();
for ($ii = 1; $ii < $max; $ii++) {
for ($ii = 1; $ii <= $max; $ii++) {
// Per copy, iterate over all templateGroup FormElements
// Per copy, iterate over all templateGroup FormElements.
foreach ($this->feSpecNative as $fe) {
$columnName = str_replace(FE_TEMPLATE_GROUP_NAME_PATTERN, $ii, $fe[FE_NAME]);
$fe[FE_LABEL] = str_replace(FE_TEMPLATE_GROUP_NAME_PATTERN, $ii, $fe[FE_LABEL]);
$fe[FE_NOTE] = str_replace(FE_TEMPLATE_GROUP_NAME_PATTERN, $ii, $fe[FE_NOTE]);
// Column of primary table?
if (isset($record[$columnName])) {
if ($record[$columnName] != $default[$columnName]) {
$lastFilled = $ii;
$lastFilled = max($ii, $lastFilled);
}
$fe[FE_NAME] = $columnName;
} else {
throw new UserFormException("Not implemented: templateGroup FormElement-columns not found in primary table.", ERROR_NOT_IMPLEMENTED);
$lastFilled = max($maxForeignRecords, $lastFilled);
if (is_array($fe[FE_VALUE]) && isset($fe[FE_VALUE][$ii - 1])) {
$fe[FE_VALUE] = current($fe[FE_VALUE][$ii - 1]); // replace array with current value
}
// $fe[FE_TEMPLATE_GROUP_CURRENT_IDX] = $ii;
}
$fe[FE_NAME] = $columnName;
$feSpecNativeCopy[$ii - 1][] = $fe; // Build array with current copy of templateGroup.
}
// Append $htmlDelete on the last element of all copies,, but not the first.
// Append $htmlDelete on the last element of all copies, but not the first.
if ($ii > 1) {
// Count defined FormElements in the current templateGroup
$last = count($feSpecNativeCopy[$ii - 1]) - 1;
......@@ -2926,6 +3024,7 @@ EOT;