コード例 #1
0
ファイル: FormEngine.php プロジェクト: adrolli/TYPO3.CMS
 /**
  * Handle AJAX calls to show a new inline-record of the given table.
  *
  * @param string $domObjectId The calling object in hierarchy, that requested a new record.
  * @param string|int $foreignUid If set, the new record should be inserted after that one.
  * @return array An array to be used for JSON
  */
 protected function renderInlineNewChildRecord($domObjectId, $foreignUid)
 {
     // The current table - for this table we should add/import records
     $current = $this->inlineStackProcessor->getUnstableStructure();
     // The parent table - this table embeds the current table
     $parent = $this->inlineStackProcessor->getStructureLevel(-1);
     $config = $parent['config'];
     if (empty($config['foreign_table']) || !is_array($GLOBALS['TCA'][$config['foreign_table']])) {
         return $this->getErrorMessageForAJAX('Wrong configuration in table ' . $parent['table']);
     }
     $inlineRelatedRecordResolver = GeneralUtility::makeInstance(InlineRelatedRecordResolver::class);
     $config = FormEngineUtility::mergeInlineConfiguration($config);
     $collapseAll = isset($config['appearance']['collapseAll']) && $config['appearance']['collapseAll'];
     $expandSingle = isset($config['appearance']['expandSingle']) && $config['appearance']['expandSingle'];
     $inlineFirstPid = FormEngineUtility::getInlineFirstPidFromDomObjectId($domObjectId);
     // Dynamically create a new record using \TYPO3\CMS\Backend\Form\DataPreprocessor
     if (!$foreignUid || !MathUtility::canBeInterpretedAsInteger($foreignUid) || $config['foreign_selector']) {
         $record = $inlineRelatedRecordResolver->getNewRecord($inlineFirstPid, $current['table']);
         // Set default values for new created records
         if (isset($config['foreign_record_defaults']) && is_array($config['foreign_record_defaults'])) {
             $foreignTableConfig = $GLOBALS['TCA'][$current['table']];
             // The following system relevant fields can't be set by foreign_record_defaults
             $notSettableFields = array('uid', 'pid', 't3ver_oid', 't3ver_id', 't3ver_label', 't3ver_wsid', 't3ver_state', 't3ver_stage', 't3ver_count', 't3ver_tstamp', 't3ver_move_id');
             $configurationKeysForNotSettableFields = array('crdate', 'cruser_id', 'delete', 'origUid', 'transOrigDiffSourceField', 'transOrigPointerField', 'tstamp');
             foreach ($configurationKeysForNotSettableFields as $configurationKey) {
                 if (isset($foreignTableConfig['ctrl'][$configurationKey])) {
                     $notSettableFields[] = $foreignTableConfig['ctrl'][$configurationKey];
                 }
             }
             foreach ($config['foreign_record_defaults'] as $fieldName => $defaultValue) {
                 if (isset($foreignTableConfig['columns'][$fieldName]) && !in_array($fieldName, $notSettableFields)) {
                     $record[$fieldName] = $defaultValue;
                 }
             }
         }
         // Set language of new child record to the language of the parent record:
         if ($parent['localizationMode'] === 'select') {
             $parentRecord = $inlineRelatedRecordResolver->getRecord($parent['table'], $parent['uid']);
             $parentLanguageField = $GLOBALS['TCA'][$parent['table']]['ctrl']['languageField'];
             $childLanguageField = $GLOBALS['TCA'][$current['table']]['ctrl']['languageField'];
             if ($parentRecord[$parentLanguageField] > 0) {
                 $record[$childLanguageField] = $parentRecord[$parentLanguageField];
             }
         }
     } else {
         // @todo: Check this: Else also hits if $foreignUid = 0?
         $record = $inlineRelatedRecordResolver->getRecord($current['table'], $foreignUid);
     }
     // Now there is a foreign_selector, so there is a new record on the intermediate table, but
     // this intermediate table holds a field, which is responsible for the foreign_selector, so
     // we have to set this field to the uid we get - or if none, to a new uid
     if ($config['foreign_selector'] && $foreignUid) {
         $selConfig = FormEngineUtility::getInlinePossibleRecordsSelectorConfig($config, $config['foreign_selector']);
         // For a selector of type group/db, prepend the tablename (<tablename>_<uid>):
         $record[$config['foreign_selector']] = $selConfig['type'] != 'groupdb' ? '' : $selConfig['table'] . '_';
         $record[$config['foreign_selector']] .= $foreignUid;
         if ($selConfig['table'] === 'sys_file') {
             $fileRecord = $inlineRelatedRecordResolver->getRecord($selConfig['table'], $foreignUid);
             if ($fileRecord !== FALSE && !$this->checkInlineFileTypeAccessForField($selConfig, $fileRecord)) {
                 return $this->getErrorMessageForAJAX('File extension ' . $fileRecord['extension'] . ' is not allowed here!');
             }
         }
     }
     // The HTML-object-id's prefix of the dynamically created record
     $objectName = $this->inlineStackProcessor->getCurrentStructureDomObjectIdPrefix($inlineFirstPid);
     $objectPrefix = $objectName . '-' . $current['table'];
     $objectId = $objectPrefix . '-' . $record['uid'];
     $options = $this->getConfigurationOptionsForChildElements();
     $options['databaseRow'] = array('uid' => $parent['uid']);
     $options['inlineFirstPid'] = $inlineFirstPid;
     $options['inlineRelatedRecordToRender'] = $record;
     $options['inlineRelatedRecordConfig'] = $config;
     $options['inlineStructure'] = $this->inlineStackProcessor->getStructure();
     $options['isAjaxContext'] = TRUE;
     $options['renderType'] = 'inlineRecordContainer';
     $childArray = $this->nodeFactory->create($options)->render();
     if ($childArray === FALSE) {
         return $this->getErrorMessageForAJAX('Access denied');
     }
     $this->mergeResult($childArray);
     $jsonArray = array('data' => $childArray['html'], 'scriptCall' => array());
     if (!$current['uid']) {
         $jsonArray['scriptCall'][] = 'inline.domAddNewRecord(\'bottom\',' . GeneralUtility::quoteJSvalue($objectName . '_records') . ',' . GeneralUtility::quoteJSvalue($objectPrefix) . ',json.data);';
         $jsonArray['scriptCall'][] = 'inline.memorizeAddRecord(' . GeneralUtility::quoteJSvalue($objectPrefix) . ',' . GeneralUtility::quoteJSvalue($record['uid']) . ',null,' . GeneralUtility::quoteJSvalue($foreignUid) . ');';
     } else {
         $jsonArray['scriptCall'][] = 'inline.domAddNewRecord(\'after\',' . GeneralUtility::quoteJSvalue($domObjectId . '_div') . ',' . GeneralUtility::quoteJSvalue($objectPrefix) . ',json.data);';
         $jsonArray['scriptCall'][] = 'inline.memorizeAddRecord(' . GeneralUtility::quoteJSvalue($objectPrefix) . ',' . GeneralUtility::quoteJSvalue($record['uid']) . ',' . GeneralUtility::quoteJSvalue($current['uid']) . ',' . GeneralUtility::quoteJSvalue($foreignUid) . ');';
     }
     $jsonArray = $this->getInlineAjaxCommonScriptCalls($jsonArray, $config, $inlineFirstPid);
     // Collapse all other records if requested:
     if (!$collapseAll && $expandSingle) {
         $jsonArray['scriptCall'][] = 'inline.collapseAllRecords(' . GeneralUtility::quoteJSvalue($objectId) . ', ' . GeneralUtility::quoteJSvalue($objectPrefix) . ', ' . GeneralUtility::quoteJSvalue($record['uid']) . ');';
     }
     // Tell the browser to scroll to the newly created record
     $jsonArray['scriptCall'][] = 'Element.scrollTo(' . GeneralUtility::quoteJSvalue($objectId . '_div') . ');';
     // Fade out and fade in the new record in the browser view to catch the user's eye
     $jsonArray['scriptCall'][] = 'inline.fadeOutFadeIn(' . GeneralUtility::quoteJSvalue($objectId . '_div') . ');';
     return $jsonArray;
 }