[BUGFIX] Fix suggest wizard for new CE in flexforms 05/33505/3
authorMarkus Klein <klein.t3@reelworx.at>
Fri, 24 Oct 2014 14:34:59 +0000 (16:34 +0200)
committerGeorg Ringer <georg.ringer@gmail.com>
Sun, 26 Oct 2014 18:59:30 +0000 (19:59 +0100)
When having a suggest wizard inside a flexform on a
new content element edit form, we have the problem that
we can't load the wizard's config in the AJAX request due
to missing record information. We don't know what flexform
definition to load, as we don't know what ctype is requested.

Two possible solutions exist:
 - Generate the blank record again in the AJAX request, which
   means we have to copy lots of code from the DataPreProcessor.
   Moreover we would still need to pass the defVal GET parameter
   of the EditDocumentController to the AJAX request handler
   somehow, since we need that information in the DataPreProcessor
   to generate the correct dummy record.
 - Push the record to the AJAX request as serialized array

I chose the second implementation.

Resolves: #50549
Releases: master, 6.2, 6.1
Change-Id: Ic27125d0a901aee10461f88ea49c0f354cb43a54
Reviewed-on: http://review.typo3.org/33505
Reviewed-by: Steffen Müller <typo3@t3node.com>
Tested-by: Steffen Müller <typo3@t3node.com>
Reviewed-by: Georg Ringer <georg.ringer@gmail.com>
Tested-by: Georg Ringer <georg.ringer@gmail.com>
typo3/sysext/backend/Classes/Form/Element/SuggestElement.php
typo3/sysext/backend/Resources/Public/JavaScript/jsfunc.tceforms_suggest.js

index 9d595a8..903cf16 100644 (file)
@@ -16,6 +16,7 @@ namespace TYPO3\CMS\Backend\Form\Element;
 
 use TYPO3\CMS\Backend\Utility\BackendUtility;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Core\Utility\MathUtility;
 
 /**
  * TCEforms wizard for rendering an AJAX selector for records
@@ -64,7 +65,8 @@ class SuggestElement {
                $this->suggestCount++;
                $containerCssClass = $this->cssClass . ' ' . $this->cssClass . '-position-right';
                $suggestId = 'suggest-' . $table . '-' . $field . '-' . $row['uid'];
-               if ($GLOBALS['TCA'][$table]['columns'][$field]['config']['type'] === 'flex') {
+               $isFlexFormField = $GLOBALS['TCA'][$table]['columns'][$field]['config']['type'] === 'flex';
+               if ($isFlexFormField) {
                        $fieldPattern = 'data[' . $table . '][' . $row['uid'] . '][';
                        $flexformField = str_replace($fieldPattern, '', $fieldname);
                        $flexformField = substr($flexformField, 0, -1);
@@ -96,12 +98,19 @@ class SuggestElement {
                        $type = $config['fieldConf']['config']['type'];
                }
 
+               $jsRow = '';
+               if ($isFlexFormField && !MathUtility::canBeInterpretedAsInteger($row['uid'])) {
+                       // Ff we have a new record, we hand that row over to JS.
+                       // This way we can properly retrieve the configuration of our wizard
+                       // if it is shown in a flexform
+                       $jsRow = serialize($row);
+               }
+
                // Replace "-" with ucwords for the JS object name
                $jsObj = str_replace(' ', '', ucwords(str_replace(array('-', '.'), ' ', GeneralUtility::strtolower($suggestId))));
                $this->TCEformsObj->additionalJS_post[] = '
-                       var ' . $jsObj . ' = new TCEForms.Suggest("' . $fieldname . '", "' . $table . '", "' . $field . '", "' . $row['uid'] . '", ' . $row['pid'] . ', ' . $minChars . ', "' . $type . '");
-                       ' . $jsObj . '.defaultValue = "' . GeneralUtility::slashJS($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:labels.findRecord')) . '";
-               ';
+                       var ' . $jsObj . ' = new TCEForms.Suggest("' . $fieldname . '", "' . $table . '", "' . $field . '", "' . $row['uid'] . '", ' . $row['pid'] . ', ' . $minChars . ', "' . $type . '", ' . GeneralUtility::quoteJSvalue($jsRow) . ');' . LF
+                               . $jsObj . '.defaultValue = "' . GeneralUtility::slashJS($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:labels.findRecord')) . '";' . LF;
                return $selector;
        }
 
@@ -146,6 +155,7 @@ class SuggestElement {
                $field = GeneralUtility::_GP('field');
                $uid = GeneralUtility::_GP('uid');
                $pageId = GeneralUtility::_GP('pid');
+               $newRecordRow = GeneralUtility::_GP('newRecordRow');
                // If the $uid is numeric, we have an already existing element, so get the
                // TSconfig of the page itself or the element container (for non-page elements)
                // otherwise it's a new element, so use given id of parent page (i.e., don't modify it here)
@@ -157,13 +167,15 @@ class SuggestElement {
                        } else {
                                $pageId = $row['pid'];
                        }
+               } else {
+                       $row = unserialize($newRecordRow);
                }
                $TSconfig = BackendUtility::getPagesTSconfig($pageId);
                $queryTables = array();
                $foreign_table_where = '';
                $fieldConfig = $GLOBALS['TCA'][$table]['columns'][$field]['config'];
                $parts = explode('|', $field);
-               if (!empty($row) && $GLOBALS['TCA'][$table]['columns'][$parts[0]]['config']['type'] === 'flex') {
+               if ($GLOBALS['TCA'][$table]['columns'][$parts[0]]['config']['type'] === 'flex') {
                        $flexfieldTCAConfig = $GLOBALS['TCA'][$table]['columns'][$parts[0]]['config'];
                        $flexformDSArray = BackendUtility::getFlexFormDS($flexfieldTCAConfig, $row, $table, $parts[0]);
                        $flexformDSArray = GeneralUtility::resolveAllSheetsInDS($flexformDSArray);
index 20b2396..686d0c7 100644 (file)
@@ -40,8 +40,9 @@ TCEForms.Suggest = Class.create({
         * @param  integer pid       The pid of the record which is currently edited
         * @param  integer minimumCharacters the minimum characters that is need to trigger the initial search
         * @param  string  fieldType The TCA type of the field (e.g. group, select, ...)
+        * @param string newRecordRow JSON encoded new content element. Only set when new record is inside flexform
         */
-       initialize: function(objectId, table, field, uid, pid, minimumCharacters, fieldType) {
+       initialize: function(objectId, table, field, uid, pid, minimumCharacters, fieldType, newRecordRow) {
                var PATH_typo3 = top.TS.PATH_typo3 || window.opener.top.TS.PATH_typo3;
                this.objectId = objectId;
                this.suggestField = objectId + 'Suggest';
@@ -52,7 +53,7 @@ TCEForms.Suggest = Class.create({
                                paramName: 'value',
                                minChars: (minimumCharacters ? minimumCharacters : this.minimumCharacters),
                                updateElement: this.addElementToList.bind(this),
-                               parameters: 'table=' + table + '&field=' + field + '&uid=' + uid + '&pid=' + pid,
+                               parameters: 'table=' + table + '&field=' + field + '&uid=' + uid + '&pid=' + pid + '&newRecordRow=' + newRecordRow,
                                indicator: objectId + 'SuggestIndicator'
                        }
                );