[BUGFIX] Fix suggest wizard for new CE in flexforms 70/33570/2
authorMarkus Klein <klein.t3@reelworx.at>
Fri, 24 Oct 2014 14:34:59 +0000 (16:34 +0200)
committerGeorg Ringer <georg.ringer@gmail.com>
Mon, 27 Oct 2014 19:53:09 +0000 (20:53 +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.

Change-Id: If7f8abe66554a3164bbfe98ad396fdf8448f5569
Resolves: #50549
Releases: master, 6.2, 6.1
Reviewed-on: http://review.typo3.org/33570
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 06e79cd..d46e6f4 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'
                        }
                );