Пример #1
0
 /**
  * Handler for Flex Forms
  *
  * @param string $table The table name of the record
  * @param string $field The field name of the flexform field to work on
  * @param array $row The record data array
  * @param object $callBackObj Object in which the call back function is located
  * @param string $callBackMethod_value Method name of call back function in object for values
  * @return bool|string If TRUE, error happened (error string returned)
  */
 public function traverseFlexFormXMLData($table, $field, $row, $callBackObj, $callBackMethod_value)
 {
     if (!is_array($GLOBALS['TCA'][$table]) || !is_array($GLOBALS['TCA'][$table]['columns'][$field])) {
         return 'TCA table/field was not defined.';
     }
     $this->callBackObj = $callBackObj;
     // Get Data Structure:
     $dataStructArray = BackendUtility::getFlexFormDS($GLOBALS['TCA'][$table]['columns'][$field]['config'], $row, $table, $field);
     // If data structure was ok, proceed:
     if (is_array($dataStructArray)) {
         // Get flexform XML data:
         $xmlData = $row[$field];
         // Convert charset:
         if ($this->convertCharset) {
             $xmlHeaderAttributes = GeneralUtility::xmlGetHeaderAttribs($xmlData);
             $storeInCharset = strtolower($xmlHeaderAttributes['encoding']);
             if ($storeInCharset) {
                 $currentCharset = $GLOBALS['LANG']->charSet;
                 $xmlData = $GLOBALS['LANG']->csConvObj->conv($xmlData, $storeInCharset, $currentCharset, 1);
             }
         }
         $editData = GeneralUtility::xml2array($xmlData);
         if (!is_array($editData)) {
             return 'Parsing error: ' . $editData;
         }
         // Tabs sheets
         if (is_array($dataStructArray['sheets'])) {
             $sKeys = array_keys($dataStructArray['sheets']);
         } else {
             $sKeys = array('sDEF');
         }
         // Traverse languages:
         foreach ($sKeys as $sheet) {
             list($dataStruct, $sheet) = GeneralUtility::resolveSheetDefInDS($dataStructArray, $sheet);
             // Render sheet:
             if (is_array($dataStruct['ROOT']) && is_array($dataStruct['ROOT']['el'])) {
                 $PA['vKeys'] = array('DEF');
                 $PA['lKey'] = 'lDEF';
                 $PA['callBackMethod_value'] = $callBackMethod_value;
                 $PA['table'] = $table;
                 $PA['field'] = $field;
                 $PA['uid'] = $row['uid'];
                 $this->traverseFlexFormXMLData_DS =& $dataStruct;
                 $this->traverseFlexFormXMLData_Data =& $editData;
                 // Render flexform:
                 $this->traverseFlexFormXMLData_recurse($dataStruct['ROOT']['el'], $editData['data'][$sheet]['lDEF'], $PA, 'data/' . $sheet . '/lDEF');
             } else {
                 return 'Data Structure ERROR: No ROOT element found for sheet "' . $sheet . '".';
             }
         }
     } else {
         return 'Data Structure ERROR: ' . $dataStructArray;
     }
 }
Пример #2
0
	/**
	 * Entry method
	 *
	 * @return array As defined in initializeResultArray() of AbstractNode
	 */
	public function render() {
		$languageService = $this->getLanguageService();

		$table = $this->globalOptions['table'];
		$row = $this->globalOptions['databaseRow'];
		$field = $this->globalOptions['fieldName'];
		$parameterArray = $this->globalOptions['parameterArray'];

		// Data Structure
		$flexFormDataStructureArray = BackendUtility::getFlexFormDS($parameterArray['fieldConf']['config'], $row, $table, $field);

		// Early return if no data structure was found at all
		if (!is_array($flexFormDataStructureArray)) {
			$resultArray = $this->initializeResultArray();
			$resultArray['html'] = 'Data Structure ERROR: ' . $flexFormDataStructureArray;
			return $resultArray;
		}

		// Manipulate Flex form DS via TSConfig and group access lists
		if (is_array($flexFormDataStructureArray)) {
			$flexFormHelper = GeneralUtility::makeInstance(FlexFormsHelper::class);
			$flexFormDataStructureArray = $flexFormHelper->modifyFlexFormDS($flexFormDataStructureArray, $table, $field, $row, $parameterArray['fieldConf']);
		}

		// Get data
		$xmlData = $parameterArray['itemFormElValue'];
		$xmlHeaderAttributes = GeneralUtility::xmlGetHeaderAttribs($xmlData);
		$storeInCharset = strtolower($xmlHeaderAttributes['encoding']);
		if ($storeInCharset) {
			$currentCharset = $languageService->charSet;
			$xmlData = $languageService->csConvObj->conv($xmlData, $storeInCharset, $currentCharset, 1);
		}
		$flexFormRowData = GeneralUtility::xml2array($xmlData);

		// Must be XML parsing error...
		if (!is_array($flexFormRowData)) {
			$flexFormRowData = array();
		} elseif (!isset($flexFormRowData['meta']) || !is_array($flexFormRowData['meta'])) {
			$flexFormRowData['meta'] = array();
		}

		$options = $this->globalOptions;
		$options['flexFormDataStructureArray'] = $flexFormDataStructureArray;
		$options['flexFormRowData'] = $flexFormRowData;
		$options['renderType'] = 'flexFormLanguageContainer';
		/** @var NodeFactory $nodeFactory */
		$nodeFactory = $this->globalOptions['nodeFactory'];
		return $nodeFactory->create($options)->render();
	}
Пример #3
0
 /**
  * Fetch / initialize data structure.
  *
  * The sub array with different possible data structures in ['config']['ds'] is
  * resolved here, ds array contains only the one resolved data structure after this method.
  *
  * @param array $result Result array
  * @param string $fieldName Currently handled field name
  * @return array Modified result
  * @throws \UnexpectedValueException
  */
 protected function initializeDataStructure(array $result, $fieldName)
 {
     // Fetch / initialize data structure
     $dataStructureArray = BackendUtility::getFlexFormDS($result['processedTca']['columns'][$fieldName]['config'], $result['databaseRow'], $result['tableName'], $fieldName);
     // If data structure can't be parsed, this is a developer error, so throw a non catchable exception
     if (!is_array($dataStructureArray)) {
         throw new \UnexpectedValueException('Data structure error: ' . $dataStructureArray, 1440506893);
     }
     if (!isset($dataStructureArray['meta']) || !is_array($dataStructureArray['meta'])) {
         $dataStructureArray['meta'] = array();
     }
     // This kicks one array depth:  config['ds']['matchingIdentifier'] becomes config['ds']
     $result['processedTca']['columns'][$fieldName]['config']['ds'] = $dataStructureArray;
     return $result;
 }
Пример #4
0
 /**
  * Processing of soft references
  *
  * @return void
  */
 public function processSoftReferences()
 {
     // Initialize:
     $inData = array();
     // Traverse records:
     if (is_array($this->dat['header']['records'])) {
         foreach ($this->dat['header']['records'] as $table => $recs) {
             foreach ($recs as $uid => $thisRec) {
                 // If there are soft references defined, traverse those:
                 if (isset($GLOBALS['TCA'][$table]) && is_array($thisRec['softrefs'])) {
                     // First traversal is to collect softref configuration and split them up based on fields.
                     // This could probably also have been done with the "records" key instead of the header.
                     $fieldsIndex = array();
                     foreach ($thisRec['softrefs'] as $softrefDef) {
                         // If a substitution token is set:
                         if ($softrefDef['field'] && is_array($softrefDef['subst']) && $softrefDef['subst']['tokenID']) {
                             $fieldsIndex[$softrefDef['field']][$softrefDef['subst']['tokenID']] = $softrefDef;
                         }
                     }
                     // The new id:
                     $thisNewUid = BackendUtility::wsMapId($table, $this->import_mapId[$table][$uid]);
                     // Now, if there are any fields that require substitution to be done, lets go for that:
                     foreach ($fieldsIndex as $field => $softRefCfgs) {
                         if (is_array($GLOBALS['TCA'][$table]['columns'][$field])) {
                             $conf = $GLOBALS['TCA'][$table]['columns'][$field]['config'];
                             if ($conf['type'] === 'flex') {
                                 // This will fetch the new row for the element (which should be updated with any references to data structures etc.)
                                 $origRecordRow = BackendUtility::getRecord($table, $thisNewUid, '*');
                                 if (is_array($origRecordRow)) {
                                     // Get current data structure and value array:
                                     $dataStructArray = BackendUtility::getFlexFormDS($conf, $origRecordRow, $table, $field);
                                     $currentValueArray = GeneralUtility::xml2array($origRecordRow[$field]);
                                     // Do recursive processing of the XML data:
                                     /** @var $iteratorObj DataHandler */
                                     $iteratorObj = GeneralUtility::makeInstance(DataHandler::class);
                                     $iteratorObj->callBackObj = $this;
                                     $currentValueArray['data'] = $iteratorObj->checkValue_flex_procInData($currentValueArray['data'], array(), array(), $dataStructArray, array($table, $uid, $field, $softRefCfgs), 'processSoftReferences_flexFormCallBack');
                                     // The return value is set as an array which means it will be processed by tcemain for file and DB references!
                                     if (is_array($currentValueArray['data'])) {
                                         $inData[$table][$thisNewUid][$field] = $currentValueArray;
                                     }
                                 }
                             } else {
                                 // Get tokenizedContent string and proceed only if that is not blank:
                                 $tokenizedContent = $this->dat['records'][$table . ':' . $uid]['rels'][$field]['softrefs']['tokenizedContent'];
                                 if (strlen($tokenizedContent) && is_array($softRefCfgs)) {
                                     $inData[$table][$thisNewUid][$field] = $this->processSoftReferences_substTokens($tokenizedContent, $softRefCfgs, $table, $uid);
                                 }
                             }
                         }
                     }
                 }
             }
         }
     }
     // Now write to database:
     $tce = $this->getNewTCE();
     $tce->isImporting = true;
     $this->callHook('before_processSoftReferences', array('tce' => $tce, 'data' => &$inData));
     $tce->enableLogging = true;
     $tce->start($inData, array());
     $tce->process_datamap();
     $this->callHook('after_processSoftReferences', array('tce' => $tce));
 }
Пример #5
0
 /**
  * Ajax handler for the "suggest" feature in TCEforms.
  *
  * @param array $params The parameters from the AJAX call
  * @param \TYPO3\CMS\Core\Http\AjaxRequestHandler $ajaxObj The AJAX object representing the AJAX call
  * @return void
  */
 public function processAjaxRequest($params, &$ajaxObj)
 {
     // Get parameters from $_GET/$_POST
     $search = GeneralUtility::_GP('value');
     $table = GeneralUtility::_GP('table');
     $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)
     $row = NULL;
     if (is_numeric($uid)) {
         $row = BackendUtility::getRecord($table, $uid);
         if ($table == 'pages') {
             $pageId = $uid;
         } 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 ($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);
         $flexformElement = $parts[count($parts) - 2];
         $continue = TRUE;
         foreach ($flexformDSArray as $sheet) {
             foreach ($sheet as $dataStructure) {
                 $fieldConfig = $this->getNestedDsFieldConfig($dataStructure, $flexformElement);
                 if (!empty($fieldConfig)) {
                     $continue = FALSE;
                     break;
                 }
             }
             if (!$continue) {
                 break;
             }
         }
         $field = str_replace('|', '][', $field);
     }
     $wizardConfig = $fieldConfig['wizards']['suggest'];
     if (isset($fieldConfig['allowed'])) {
         if ($fieldConfig['allowed'] === '*') {
             foreach ($GLOBALS['TCA'] as $tableName => $tableConfig) {
                 // @todo Refactor function to BackendUtility
                 if (empty($tableConfig['ctrl']['hideTable']) && ($GLOBALS['BE_USER']->isAdmin() || empty($tableConfig['ctrl']['adminOnly']) && (empty($tableConfig['ctrl']['rootLevel']) || !empty($tableConfig['ctrl']['security']['ignoreRootLevelRestriction'])))) {
                     $queryTables[] = $tableName;
                 }
             }
             unset($tableName, $tableConfig);
         } else {
             $queryTables = GeneralUtility::trimExplode(',', $fieldConfig['allowed']);
         }
     } elseif (isset($fieldConfig['foreign_table'])) {
         $queryTables = array($fieldConfig['foreign_table']);
         $foreign_table_where = $fieldConfig['foreign_table_where'];
         // strip ORDER BY clause
         $foreign_table_where = trim(preg_replace('/ORDER[[:space:]]+BY.*/i', '', $foreign_table_where));
     }
     $resultRows = array();
     // fetch the records for each query table. A query table is a table from which records are allowed to
     // be added to the TCEForm selector, originally fetched from the "allowed" config option in the TCA
     foreach ($queryTables as $queryTable) {
         // if the table does not exist, skip it
         if (!is_array($GLOBALS['TCA'][$queryTable]) || empty($GLOBALS['TCA'][$queryTable])) {
             continue;
         }
         $config = (array) $wizardConfig['default'];
         if (is_array($wizardConfig[$queryTable])) {
             \TYPO3\CMS\Core\Utility\ArrayUtility::mergeRecursiveWithOverrule($config, $wizardConfig[$queryTable]);
         }
         // merge the configurations of different "levels" to get the working configuration for this table and
         // field (i.e., go from the most general to the most special configuration)
         if (is_array($TSconfig['TCEFORM.']['suggest.']['default.'])) {
             \TYPO3\CMS\Core\Utility\ArrayUtility::mergeRecursiveWithOverrule($config, $TSconfig['TCEFORM.']['suggest.']['default.']);
         }
         if (is_array($TSconfig['TCEFORM.']['suggest.'][$queryTable . '.'])) {
             \TYPO3\CMS\Core\Utility\ArrayUtility::mergeRecursiveWithOverrule($config, $TSconfig['TCEFORM.']['suggest.'][$queryTable . '.']);
         }
         // use $table instead of $queryTable here because we overlay a config
         // for the input-field here, not for the queried table
         if (is_array($TSconfig['TCEFORM.'][$table . '.'][$field . '.']['suggest.']['default.'])) {
             \TYPO3\CMS\Core\Utility\ArrayUtility::mergeRecursiveWithOverrule($config, $TSconfig['TCEFORM.'][$table . '.'][$field . '.']['suggest.']['default.']);
         }
         if (is_array($TSconfig['TCEFORM.'][$table . '.'][$field . '.']['suggest.'][$queryTable . '.'])) {
             \TYPO3\CMS\Core\Utility\ArrayUtility::mergeRecursiveWithOverrule($config, $TSconfig['TCEFORM.'][$table . '.'][$field . '.']['suggest.'][$queryTable . '.']);
         }
         //process addWhere
         if (!isset($config['addWhere']) && $foreign_table_where) {
             $config['addWhere'] = $foreign_table_where;
         }
         if (isset($config['addWhere'])) {
             $replacement = array('###THIS_UID###' => (int) $uid, '###CURRENT_PID###' => (int) $pageId);
             if (isset($TSconfig['TCEFORM.'][$table . '.'][$field . '.'])) {
                 $fieldTSconfig = $TSconfig['TCEFORM.'][$table . '.'][$field . '.'];
                 if (isset($fieldTSconfig['PAGE_TSCONFIG_ID'])) {
                     $replacement['###PAGE_TSCONFIG_ID###'] = (int) $fieldTSconfig['PAGE_TSCONFIG_ID'];
                 }
                 if (isset($fieldTSconfig['PAGE_TSCONFIG_IDLIST'])) {
                     $replacement['###PAGE_TSCONFIG_IDLIST###'] = $GLOBALS['TYPO3_DB']->cleanIntList($fieldTSconfig['PAGE_TSCONFIG_IDLIST']);
                 }
                 if (isset($fieldTSconfig['PAGE_TSCONFIG_STR'])) {
                     $replacement['###PAGE_TSCONFIG_STR###'] = $GLOBALS['TYPO3_DB']->quoteStr($fieldTSconfig['PAGE_TSCONFIG_STR'], $fieldConfig['foreign_table']);
                 }
             }
             $config['addWhere'] = strtr(' ' . $config['addWhere'], $replacement);
         }
         // instantiate the class that should fetch the records for this $queryTable
         $receiverClassName = $config['receiverClass'];
         if (!class_exists($receiverClassName)) {
             $receiverClassName = SuggestWizardDefaultReceiver::class;
         }
         $receiverObj = GeneralUtility::makeInstance($receiverClassName, $queryTable, $config);
         $params = array('value' => $search);
         $rows = $receiverObj->queryTable($params);
         if (empty($rows)) {
             continue;
         }
         $resultRows = $rows + $resultRows;
         unset($rows);
     }
     $listItems = array();
     if (!empty($resultRows)) {
         // traverse all found records and sort them
         $rowsSort = array();
         foreach ($resultRows as $key => $row) {
             $rowsSort[$key] = $row['text'];
         }
         asort($rowsSort);
         $rowsSort = array_keys($rowsSort);
         // Limit the number of items in the result list
         $maxItems = $config['maxItemsInResultList'] ?: 10;
         $maxItems = min(count($resultRows), $maxItems);
         // put together the selector entry
         for ($i = 0; $i < $maxItems; $i++) {
             $row = $resultRows[$rowsSort[$i]];
             $rowId = $row['table'] . '-' . $row['uid'] . '-' . $table . '-' . $uid . '-' . $field;
             $listItems[] = '<li' . ($row['class'] != '' ? ' class="' . $row['class'] . '"' : '') . ' id="' . $rowId . '"' . ($row['style'] != '' ? ' style="' . $row['style'] . '"' : '') . '>' . $row['sprite'] . $row['text'] . '</li>';
         }
     }
     if (!empty($listItems)) {
         $list = implode('', $listItems);
     } else {
         $list = '<li class="suggest-noresults"><i>' . $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:labels.noRecordFound') . '</i></li>';
     }
     $list = '<ul class="' . $this->cssClass . '-resultlist">' . $list . '</ul>';
     $ajaxObj->addContent(0, $list);
 }
Пример #6
0
 /**
  * Checks if the query comes from a Flexform element and if yes, resolves the field configuration from the Flexform
  * data structure.
  *
  * @param string $table
  * @param string &$field The field identifier, either a simple table field or a Flexform field path separated with |
  * @param array $row The row we're dealing with; optional (only required for Flexform records)
  * @param array|NULL &$fieldConfig
  */
 protected function overrideFieldNameAndConfigurationForFlexform($table, &$field, array $row, &$fieldConfig)
 {
     // check if field is a flexform reference
     if (strpos($field, '|') === false) {
         $fieldConfig = $GLOBALS['TCA'][$table]['columns'][$field]['config'];
     } else {
         $parts = explode('|', $field);
         if ($GLOBALS['TCA'][$table]['columns'][$parts[0]]['config']['type'] !== 'flex') {
             return;
         }
         $flexfieldTCAConfig = $GLOBALS['TCA'][$table]['columns'][$parts[0]]['config'];
         // @todo: should be done via data preparation, resolveAllSheetsInDS() can be deprecated then
         $flexformDSArray = BackendUtility::getFlexFormDS($flexfieldTCAConfig, $row, $table, $parts[0]);
         $flexformDSArray = GeneralUtility::resolveAllSheetsInDS($flexformDSArray);
         $flexformElement = $parts[count($parts) - 2];
         $continue = true;
         foreach ($flexformDSArray as $sheet) {
             foreach ($sheet as $_ => $dataStructure) {
                 $fieldConfig = $this->getNestedDsFieldConfig($dataStructure, $flexformElement);
                 if (!empty($fieldConfig)) {
                     $continue = false;
                     break;
                 }
             }
             if (!$continue) {
                 break;
             }
         }
         // Flexform field name levels are separated with | instead of encapsulation in [];
         // reverse this here to be compatible with regular field names.
         $field = str_replace('|', '][', $field);
     }
 }
Пример #7
0
 /**
  * Processes the fields with references as registered during the copy process. This includes all FlexForm fields which had references.
  *
  * @return void
  */
 public function remapListedDBRecords()
 {
     if (!empty($this->registerDBList)) {
         foreach ($this->registerDBList as $table => $records) {
             foreach ($records as $uid => $fields) {
                 $newData = array();
                 $theUidToUpdate = $this->copyMappingArray_merged[$table][$uid];
                 $theUidToUpdate_saveTo = BackendUtility::wsMapId($table, $theUidToUpdate);
                 foreach ($fields as $fieldName => $value) {
                     $conf = $GLOBALS['TCA'][$table]['columns'][$fieldName]['config'];
                     switch ($conf['type']) {
                         case 'group':
                         case 'select':
                             $vArray = $this->remapListedDBRecords_procDBRefs($conf, $value, $theUidToUpdate, $table);
                             if (is_array($vArray)) {
                                 $newData[$fieldName] = implode(',', $vArray);
                             }
                             break;
                         case 'flex':
                             if ($value == 'FlexForm_reference') {
                                 // This will fetch the new row for the element
                                 $origRecordRow = $this->recordInfo($table, $theUidToUpdate, '*');
                                 if (is_array($origRecordRow)) {
                                     BackendUtility::workspaceOL($table, $origRecordRow);
                                     // Get current data structure and value array:
                                     $dataStructArray = BackendUtility::getFlexFormDS($conf, $origRecordRow, $table, $fieldName);
                                     $currentValueArray = GeneralUtility::xml2array($origRecordRow[$fieldName]);
                                     // Do recursive processing of the XML data:
                                     $currentValueArray['data'] = $this->checkValue_flex_procInData($currentValueArray['data'], array(), array(), $dataStructArray, array($table, $theUidToUpdate, $fieldName), 'remapListedDBRecords_flexFormCallBack');
                                     // The return value should be compiled back into XML, ready to insert directly in the field (as we call updateDB() directly later):
                                     if (is_array($currentValueArray['data'])) {
                                         $newData[$fieldName] = $this->checkValue_flexArray2Xml($currentValueArray, true);
                                     }
                                 }
                             }
                             break;
                         case 'inline':
                             $this->remapListedDBRecords_procInline($conf, $value, $uid, $table);
                             break;
                         default:
                             debug('Field type should not appear here: ' . $conf['type']);
                     }
                 }
                 // If any fields were changed, those fields are updated!
                 if (!empty($newData)) {
                     $this->updateDB($table, $theUidToUpdate_saveTo, $newData);
                 }
             }
         }
     }
 }
Пример #8
0
 /**
  * Handler for Flex Forms
  *
  * @param string $table The table name of the record
  * @param string $field The field name which this element is supposed to edit
  * @param array $row The record data array where the value(s) for the field can be found
  * @param array $PA An array with additional configuration options.
  * @return string The HTML code for the TCEform field
  * @todo Define visibility
  */
 public function getSingleField_typeFlex($table, $field, $row, &$PA)
 {
     // Data Structure:
     $dataStructArray = BackendUtility::getFlexFormDS($PA['fieldConf']['config'], $row, $table, $field);
     $item = '';
     // Manipulate Flexform DS via TSConfig and group access lists
     if (is_array($dataStructArray)) {
         $flexFormHelper = GeneralUtility::makeInstance('TYPO3\\CMS\\Backend\\Form\\FlexFormsHelper');
         $dataStructArray = $flexFormHelper->modifyFlexFormDS($dataStructArray, $table, $field, $row, $PA['fieldConf']);
         unset($flexFormHelper);
     }
     // Get data structure:
     if (is_array($dataStructArray)) {
         // Get data:
         $xmlData = $PA['itemFormElValue'];
         $xmlHeaderAttributes = GeneralUtility::xmlGetHeaderAttribs($xmlData);
         $storeInCharset = strtolower($xmlHeaderAttributes['encoding']);
         if ($storeInCharset) {
             $currentCharset = $this->getLanguageService()->charSet;
             $xmlData = $this->getLanguageService()->csConvObj->conv($xmlData, $storeInCharset, $currentCharset, 1);
         }
         $editData = GeneralUtility::xml2array($xmlData);
         // Must be XML parsing error...
         if (!is_array($editData)) {
             $editData = array();
         } elseif (!isset($editData['meta']) || !is_array($editData['meta'])) {
             $editData['meta'] = array();
         }
         // Find the data structure if sheets are found:
         $sheet = $editData['meta']['currentSheetId'] ? $editData['meta']['currentSheetId'] : 'sDEF';
         // Sheet to display
         // Create language menu:
         $langChildren = $dataStructArray['meta']['langChildren'] ? 1 : 0;
         $langDisabled = $dataStructArray['meta']['langDisable'] ? 1 : 0;
         $editData['meta']['currentLangId'] = array();
         // Look up page overlays:
         $checkPageLanguageOverlay = $this->getBackendUserAuthentication()->getTSConfigVal('options.checkPageLanguageOverlay') ? TRUE : FALSE;
         if ($checkPageLanguageOverlay) {
             $where_clause = 'pid=' . (int) $row['pid'] . BackendUtility::deleteClause('pages_language_overlay') . BackendUtility::versioningPlaceholderClause('pages_language_overlay');
             $pageOverlays = $this->getDatabaseConnection()->exec_SELECTgetRows('*', 'pages_language_overlay', $where_clause, '', '', '', 'sys_language_uid');
         }
         $languages = $this->getAvailableLanguages();
         foreach ($languages as $lInfo) {
             if ($this->getBackendUserAuthentication()->checkLanguageAccess($lInfo['uid']) && (!$checkPageLanguageOverlay || $lInfo['uid'] <= 0 || is_array($pageOverlays[$lInfo['uid']]))) {
                 $editData['meta']['currentLangId'][] = $lInfo['ISOcode'];
             }
         }
         if (!is_array($editData['meta']['currentLangId']) || !count($editData['meta']['currentLangId'])) {
             $editData['meta']['currentLangId'] = array('DEF');
         }
         $editData['meta']['currentLangId'] = array_unique($editData['meta']['currentLangId']);
         $PA['_noEditDEF'] = FALSE;
         if ($langChildren || $langDisabled) {
             $rotateLang = array('DEF');
         } else {
             if (!in_array('DEF', $editData['meta']['currentLangId'])) {
                 array_unshift($editData['meta']['currentLangId'], 'DEF');
                 $PA['_noEditDEF'] = TRUE;
             }
             $rotateLang = $editData['meta']['currentLangId'];
         }
         // Tabs sheets
         if (is_array($dataStructArray['sheets'])) {
             $tabsToTraverse = array_keys($dataStructArray['sheets']);
         } else {
             $tabsToTraverse = array($sheet);
         }
         /** @var $elementConditionMatcher \TYPO3\CMS\Backend\Form\ElementConditionMatcher */
         $elementConditionMatcher = GeneralUtility::makeInstance('TYPO3\\CMS\\Backend\\Form\\ElementConditionMatcher');
         foreach ($rotateLang as $lKey) {
             if (!$langChildren && !$langDisabled) {
                 $item .= '<strong>' . $this->getLanguageIcon($table, $row, 'v' . $lKey) . $lKey . ':</strong>';
             }
             // Default language, other options are "lUK" or whatever country code (independent of system!!!)
             $lang = 'l' . $lKey;
             $tabParts = array();
             $sheetContent = '';
             foreach ($tabsToTraverse as $sheet) {
                 list($dataStruct, $sheet) = GeneralUtility::resolveSheetDefInDS($dataStructArray, $sheet);
                 // If sheet has displayCond
                 if ($dataStruct['ROOT']['TCEforms']['displayCond']) {
                     $splitCondition = GeneralUtility::trimExplode(':', $dataStruct['ROOT']['TCEforms']['displayCond']);
                     $skipCondition = FALSE;
                     $fakeRow = array();
                     switch ($splitCondition[0]) {
                         case 'FIELD':
                             list($sheetName, $fieldName) = GeneralUtility::trimExplode('.', $splitCondition[1]);
                             $fieldValue = $editData['data'][$sheetName][$lang][$fieldName];
                             $splitCondition[1] = $fieldName;
                             $dataStruct['ROOT']['TCEforms']['displayCond'] = join(':', $splitCondition);
                             $fakeRow = array($fieldName => $fieldValue);
                             break;
                         case 'HIDE_FOR_NON_ADMINS':
                         case 'VERSION':
                         case 'HIDE_L10N_SIBLINGS':
                         case 'EXT':
                             break;
                         case 'REC':
                             $fakeRow = array('uid' => $row['uid']);
                             break;
                         default:
                             $skipCondition = TRUE;
                     }
                     $displayConditionResult = TRUE;
                     if ($dataStruct['ROOT']['TCEforms']['displayCond']) {
                         $displayConditionResult = $elementConditionMatcher->match($dataStruct['ROOT']['TCEforms']['displayCond'], $fakeRow, 'vDEF');
                     }
                     // If sheets displayCond leads to false
                     if (!$skipCondition && !$displayConditionResult) {
                         // Don't create this sheet
                         continue;
                     }
                 }
                 // Render sheet:
                 if (is_array($dataStruct['ROOT']) && is_array($dataStruct['ROOT']['el'])) {
                     // Default language, other options are "lUK" or whatever country code (independent of system!!!)
                     $PA['_valLang'] = $langChildren && !$langDisabled ? $editData['meta']['currentLangId'] : 'DEF';
                     $PA['_lang'] = $lang;
                     // Assemble key for loading the correct CSH file
                     $dsPointerFields = GeneralUtility::trimExplode(',', $GLOBALS['TCA'][$table]['columns'][$field]['config']['ds_pointerField'], TRUE);
                     $PA['_cshKey'] = $table . '.' . $field;
                     foreach ($dsPointerFields as $key) {
                         $PA['_cshKey'] .= '.' . $row[$key];
                     }
                     // Push the sheet level tab to DynNestedStack
                     $tabIdentString = '';
                     if (is_array($dataStructArray['sheets'])) {
                         $tabIdentString = $this->getDocumentTemplate()->getDynTabMenuId('TCEFORMS:flexform:' . $PA['itemFormElName'] . $PA['_lang']);
                         $this->pushToDynNestedStack('tab', $tabIdentString . '-' . (count($tabParts) + 1));
                     }
                     // Render flexform:
                     $tRows = $this->getSingleField_typeFlex_draw($dataStruct['ROOT']['el'], $editData['data'][$sheet][$lang], $table, $field, $row, $PA, '[data][' . $sheet . '][' . $lang . ']');
                     $sheetContent = '<div class="typo3-TCEforms-flexForm">' . $tRows . '</div>';
                     // Pop the sheet level tab from DynNestedStack
                     if (is_array($dataStructArray['sheets'])) {
                         $this->popFromDynNestedStack('tab', $tabIdentString . '-' . (count($tabParts) + 1));
                     }
                 } else {
                     $sheetContent = 'Data Structure ERROR: No ROOT element found for sheet "' . $sheet . '".';
                 }
                 // Add to tab:
                 $tabParts[] = array('label' => $dataStruct['ROOT']['TCEforms']['sheetTitle'] ? $this->sL($dataStruct['ROOT']['TCEforms']['sheetTitle']) : $sheet, 'description' => $dataStruct['ROOT']['TCEforms']['sheetDescription'] ? $this->sL($dataStruct['ROOT']['TCEforms']['sheetDescription']) : '', 'linkTitle' => $dataStruct['ROOT']['TCEforms']['sheetShortDescr'] ? $this->sL($dataStruct['ROOT']['TCEforms']['sheetShortDescr']) : '', 'content' => $sheetContent);
             }
             if (is_array($dataStructArray['sheets'])) {
                 $dividersToTabsBehaviour = isset($GLOBALS['TCA'][$table]['ctrl']['dividers2tabs']) ? $GLOBALS['TCA'][$table]['ctrl']['dividers2tabs'] : 1;
                 $item .= $this->getDynTabMenu($tabParts, 'TCEFORMS:flexform:' . $PA['itemFormElName'] . $PA['_lang'], $dividersToTabsBehaviour);
             } else {
                 $item .= $sheetContent;
             }
         }
     } else {
         $item = 'Data Structure ERROR: ' . $dataStructArray;
     }
     return $item;
 }
Пример #9
0
 /**
  * Checks if the query comes from a Flexform element and if yes, resolves the field configuration from the Flexform
  * data structure.
  *
  * @param string $table
  * @param string &$field The field identifier, either a simple table field or a Flexform field path separated with |
  * @param array $row The row we're dealing with; optional (only required for Flexform records)
  * @param array|NULL &$fieldConfig
  */
 protected function overrideFieldNameAndConfigurationForFlexform($table, &$field, array $row, &$fieldConfig)
 {
     // check if field is a flexform reference
     if (strpos($field, '|') === false) {
         $fieldConfig = $GLOBALS['TCA'][$table]['columns'][$field]['config'];
     } else {
         $parts = explode('|', $field);
         if ($GLOBALS['TCA'][$table]['columns'][$parts[0]]['config']['type'] !== 'flex') {
             return;
         }
         $flexfieldTCAConfig = $GLOBALS['TCA'][$table]['columns'][$parts[0]]['config'];
         // @todo: should be done via data preparation, resolveAllSheetsInDS() can be deprecated then
         if (substr($row['uid'], 0, 3) === 'NEW') {
             // We have to cleanup record information as they are coming from FormEngines DataProvider
             $pointerFields = GeneralUtility::trimExplode(',', $flexfieldTCAConfig['ds_pointerField']);
             foreach ($pointerFields as $pointerField) {
                 if (is_array($row[$pointerField])) {
                     $row[$pointerField] = $row[$pointerField][0];
                 }
             }
         }
         $flexformDSArray = BackendUtility::getFlexFormDS($flexfieldTCAConfig, $row, $table, $parts[0]);
         $flexformDSArray = GeneralUtility::resolveAllSheetsInDS($flexformDSArray);
         $fieldConfig = $this->getFieldConfiguration($parts, $flexformDSArray);
         // Flexform field name levels are separated with | instead of encapsulation in [];
         // reverse this here to be compatible with regular field names.
         $field = str_replace('|', '][', $field);
     }
 }
Пример #10
0
 /**
  * Processing of the data value in case the field type is "flex"
  * MUST NOT be called in case of already INSIDE a flexform!
  *
  * @param string $data The field value
  * @param array $fieldConfig CA field config
  * @param array $TSconfig TCEform TSconfig for the record
  * @param string $table Table name
  * @param array $row The row
  * @param string $field Field name
  * @return string The processed input field value ($data)
  * @access private
  * @see renderRecord()
  */
 public function renderRecord_flexProc($data, $fieldConfig, $TSconfig, $table, $row, $field)
 {
     // Convert the XML data to PHP array:
     if (!is_array($data)) {
         $currentValueArray = GeneralUtility::xml2array($data);
     } else {
         $currentValueArray = $data;
     }
     if (is_array($currentValueArray)) {
         // Get current value array:
         $dataStructArray = BackendUtility::getFlexFormDS($fieldConfig['config'], $row, $table, $field);
         // Manipulate Flexform DS via TSConfig and group access lists
         if (is_array($dataStructArray)) {
             $flexFormHelper = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Form\FlexFormsHelper::class);
             $dataStructArray = $flexFormHelper->modifyFlexFormDS($dataStructArray, $table, $field, $row, $fieldConfig);
             unset($flexFormHelper);
         }
         if (is_array($dataStructArray)) {
             $currentValueArray['data'] = $this->renderRecord_flexProc_procInData($currentValueArray['data'], $dataStructArray, array($data, $fieldConfig, $TSconfig, $table, $row, $field));
             $flexObj = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Configuration\FlexForm\FlexFormTools::class);
             $data = $flexObj->flexArray2Xml($currentValueArray, TRUE);
         }
     }
     return $data;
 }
Пример #11
0
 /**
  * Returns relation information for a $table/$row-array
  * Traverses all fields in input row which are configured in TCA/columns
  * It looks for hard relations to files and records in the TCA types "select" and "group"
  *
  * @param string $table Table name
  * @param array $row Row from table
  * @param string $onlyField Specific field to fetch for.
  * @return array Array with information about relations
  * @see export_addRecord()
  * @todo Define visibility
  */
 public function getRelations($table, $row, $onlyField = '')
 {
     // Initialize:
     $uid = $row['uid'];
     $nonFields = explode(',', 'uid,perms_userid,perms_groupid,perms_user,perms_group,perms_everybody,pid');
     $outRow = array();
     foreach ($row as $field => $value) {
         if (!in_array($field, $nonFields) && is_array($GLOBALS['TCA'][$table]['columns'][$field]) && (!$onlyField || $onlyField === $field)) {
             $conf = $GLOBALS['TCA'][$table]['columns'][$field]['config'];
             // Add files
             $resultsFromFiles = $this->getRelations_procFiles($value, $conf, $uid);
             if (!empty($resultsFromFiles)) {
                 // We have to fill different arrays here depending on the result.
                 // internal_type file is still a relation of type file and
                 // since http://forge.typo3.org/issues/49538 internal_type file_reference
                 // is a database relation to a sys_file record
                 $fileResultsFromFiles = array();
                 $dbResultsFromFiles = array();
                 foreach ($resultsFromFiles as $resultFromFiles) {
                     if (isset($resultFromFiles['table']) && $resultFromFiles['table'] === 'sys_file') {
                         $dbResultsFromFiles[] = $resultFromFiles;
                     } else {
                         // Creates an entry for the field with all the files:
                         $fileResultsFromFiles[] = $resultFromFiles;
                     }
                 }
                 if (!empty($fileResultsFromFiles)) {
                     $outRow[$field] = array('type' => 'file', 'newValueFiles' => $fileResultsFromFiles);
                 }
                 if (!empty($dbResultsFromFiles)) {
                     $outRow[$field] = array('type' => 'db', 'itemArray' => $dbResultsFromFiles);
                 }
             }
             // Add DB:
             $resultsFromDatabase = $this->getRelations_procDB($value, $conf, $uid, $table, $field);
             if (!empty($resultsFromDatabase)) {
                 // Create an entry for the field with all DB relations:
                 $outRow[$field] = array('type' => 'db', 'itemArray' => $resultsFromDatabase);
             }
             // For "flex" fieldtypes we need to traverse the structure looking for file and db references of course!
             if ($conf['type'] == 'flex') {
                 // Get current value array:
                 // NOTICE: failure to resolve Data Structures can lead to integrity problems with the reference index. Please look up the note in the JavaDoc documentation for the function \TYPO3\CMS\Backend\Utility\BackendUtility::getFlexFormDS()
                 $dataStructArray = BackendUtility::getFlexFormDS($conf, $row, $table, $field, $this->WSOL);
                 $currentValueArray = GeneralUtility::xml2array($value);
                 // Traversing the XML structure, processing files:
                 if (is_array($currentValueArray)) {
                     $this->temp_flexRelations = array('db' => array(), 'file' => array(), 'softrefs' => array());
                     // Create and call iterator object:
                     $flexObj = GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Configuration\\FlexForm\\FlexFormTools');
                     $flexObj->traverseFlexFormXMLData($table, $field, $row, $this, 'getRelations_flexFormCallBack');
                     // Create an entry for the field:
                     $outRow[$field] = array('type' => 'flex', 'flexFormRels' => $this->temp_flexRelations);
                 }
             }
             // Soft References:
             if (strlen($value) && ($softRefs = BackendUtility::explodeSoftRefParserList($conf['softref']))) {
                 $softRefValue = $value;
                 foreach ($softRefs as $spKey => $spParams) {
                     $softRefObj = BackendUtility::softRefParserObj($spKey);
                     if (is_object($softRefObj)) {
                         $resultArray = $softRefObj->findRef($table, $field, $uid, $softRefValue, $spKey, $spParams);
                         if (is_array($resultArray)) {
                             $outRow[$field]['softrefs']['keys'][$spKey] = $resultArray['elements'];
                             if (strlen($resultArray['content'])) {
                                 $softRefValue = $resultArray['content'];
                             }
                         }
                     }
                 }
                 if (is_array($outRow[$field]['softrefs']) && count($outRow[$field]['softrefs']) && (string) $value !== (string) $softRefValue && strstr($softRefValue, '{softref:')) {
                     $outRow[$field]['softrefs']['tokenizedContent'] = $softRefValue;
                 }
             }
         }
     }
     return $outRow;
 }
Пример #12
0
 /**
  * Returns relation information for a $table/$row-array
  * Traverses all fields in input row which are configured in TCA/columns
  * It looks for hard relations to files and records in the TCA types "select" and "group"
  *
  * @param string $table Table name
  * @param array $row Row from table
  * @param string $onlyField Specific field to fetch for.
  * @return array Array with information about relations
  * @see export_addRecord()
  * @todo Define visibility
  */
 public function getRelations($table, $row, $onlyField = '')
 {
     // Load full table description
     \TYPO3\CMS\Core\Utility\GeneralUtility::loadTCA($table);
     // Initialize:
     $uid = $row['uid'];
     $nonFields = explode(',', 'uid,perms_userid,perms_groupid,perms_user,perms_group,perms_everybody,pid');
     $outRow = array();
     foreach ($row as $field => $value) {
         if (!in_array($field, $nonFields) && is_array($GLOBALS['TCA'][$table]['columns'][$field]) && (!$onlyField || $onlyField === $field)) {
             $conf = $GLOBALS['TCA'][$table]['columns'][$field]['config'];
             // Add files
             if ($result = $this->getRelations_procFiles($value, $conf, $uid)) {
                 // Creates an entry for the field with all the files:
                 $outRow[$field] = array('type' => 'db', 'itemArray' => $result);
             }
             // Add DB:
             if ($result = $this->getRelations_procDB($value, $conf, $uid, $table, $field)) {
                 // Create an entry for the field with all DB relations:
                 $outRow[$field] = array('type' => 'db', 'itemArray' => $result);
             }
             // For "flex" fieldtypes we need to traverse the structure looking for file and db references of course!
             if ($conf['type'] == 'flex') {
                 // Get current value array:
                 // NOTICE: failure to resolve Data Structures can lead to integrity problems with the reference index. Please look up the note in the JavaDoc documentation for the function t3lib_BEfunc::getFlexFormDS()
                 $dataStructArray = \TYPO3\CMS\Backend\Utility\BackendUtility::getFlexFormDS($conf, $row, $table, '', $this->WSOL);
                 $currentValueArray = \TYPO3\CMS\Core\Utility\GeneralUtility::xml2array($value);
                 // Traversing the XML structure, processing files:
                 if (is_array($currentValueArray)) {
                     $this->temp_flexRelations = array('db' => array(), 'file' => array(), 'softrefs' => array());
                     // Create and call iterator object:
                     $flexObj = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Configuration\\FlexForm\\FlexFormTools');
                     $flexObj->traverseFlexFormXMLData($table, $field, $row, $this, 'getRelations_flexFormCallBack');
                     // Create an entry for the field:
                     $outRow[$field] = array('type' => 'flex', 'flexFormRels' => $this->temp_flexRelations);
                 }
             }
             // Soft References:
             if (strlen($value) && ($softRefs = \TYPO3\CMS\Backend\Utility\BackendUtility::explodeSoftRefParserList($conf['softref']))) {
                 $softRefValue = $value;
                 foreach ($softRefs as $spKey => $spParams) {
                     $softRefObj = \TYPO3\CMS\Backend\Utility\BackendUtility::softRefParserObj($spKey);
                     if (is_object($softRefObj)) {
                         $resultArray = $softRefObj->findRef($table, $field, $uid, $softRefValue, $spKey, $spParams);
                         if (is_array($resultArray)) {
                             $outRow[$field]['softrefs']['keys'][$spKey] = $resultArray['elements'];
                             if (strlen($resultArray['content'])) {
                                 $softRefValue = $resultArray['content'];
                             }
                         }
                     }
                 }
                 if (is_array($outRow[$field]['softrefs']) && count($outRow[$field]['softrefs']) && strcmp($value, $softRefValue) && strstr($softRefValue, '{softref:')) {
                     $outRow[$field]['softrefs']['tokenizedContent'] = $softRefValue;
                 }
             }
         }
     }
     return $outRow;
 }
Пример #13
0
 /**
  * Handler for Flex Forms
  *
  * @param string $table The table name of the record
  * @param string $field The field name of the flexform field to work on
  * @param array $row The record data array
  * @param object $callBackObj Object in which the call back function is located
  * @param string $callBackMethod_value Method name of call back function in object for values
  * @return bool|string If TRUE, error happened (error string returned)
  */
 public function traverseFlexFormXMLData($table, $field, $row, $callBackObj, $callBackMethod_value)
 {
     if (!is_array($GLOBALS['TCA'][$table]) || !is_array($GLOBALS['TCA'][$table]['columns'][$field])) {
         return 'TCA table/field was not defined.';
     }
     $this->callBackObj = $callBackObj;
     // Get Data Structure:
     $dataStructArray = BackendUtility::getFlexFormDS($GLOBALS['TCA'][$table]['columns'][$field]['config'], $row, $table, $field);
     // If data structure was ok, proceed:
     if (is_array($dataStructArray)) {
         // Get flexform XML data:
         $xmlData = $row[$field];
         // Convert charset:
         if ($this->convertCharset) {
             $xmlHeaderAttributes = GeneralUtility::xmlGetHeaderAttribs($xmlData);
             $storeInCharset = strtolower($xmlHeaderAttributes['encoding']);
             if ($storeInCharset) {
                 $currentCharset = $GLOBALS['LANG']->charSet;
                 $xmlData = $GLOBALS['LANG']->csConvObj->conv($xmlData, $storeInCharset, $currentCharset, 1);
             }
         }
         $editData = GeneralUtility::xml2array($xmlData);
         if (!is_array($editData)) {
             return 'Parsing error: ' . $editData;
         }
         // Language settings:
         $langChildren = $dataStructArray['meta']['langChildren'] ? 1 : 0;
         $langDisabled = $dataStructArray['meta']['langDisable'] ? 1 : 0;
         // Empty or invalid <meta>
         if (!is_array($editData['meta'])) {
             $editData['meta'] = array();
         }
         $editData['meta']['currentLangId'] = array();
         $languages = $this->getAvailableLanguages();
         foreach ($languages as $lInfo) {
             $editData['meta']['currentLangId'][] = $lInfo['ISOcode'];
         }
         if (empty($editData['meta']['currentLangId'])) {
             $editData['meta']['currentLangId'] = array('DEF');
         }
         $editData['meta']['currentLangId'] = array_unique($editData['meta']['currentLangId']);
         if ($langChildren || $langDisabled) {
             $lKeys = array('DEF');
         } else {
             $lKeys = $editData['meta']['currentLangId'];
         }
         // Tabs sheets
         if (is_array($dataStructArray['sheets'])) {
             $sKeys = array_keys($dataStructArray['sheets']);
         } else {
             $sKeys = array('sDEF');
         }
         // Traverse languages:
         foreach ($lKeys as $lKey) {
             foreach ($sKeys as $sheet) {
                 $sheetCfg = $dataStructArray['sheets'][$sheet];
                 list($dataStruct, $sheet) = GeneralUtility::resolveSheetDefInDS($dataStructArray, $sheet);
                 // Render sheet:
                 if (is_array($dataStruct['ROOT']) && is_array($dataStruct['ROOT']['el'])) {
                     // Separate language key
                     $lang = 'l' . $lKey;
                     $PA['vKeys'] = $langChildren && !$langDisabled ? $editData['meta']['currentLangId'] : array('DEF');
                     $PA['lKey'] = $lang;
                     $PA['callBackMethod_value'] = $callBackMethod_value;
                     $PA['table'] = $table;
                     $PA['field'] = $field;
                     $PA['uid'] = $row['uid'];
                     $this->traverseFlexFormXMLData_DS =& $dataStruct;
                     $this->traverseFlexFormXMLData_Data =& $editData;
                     // Render flexform:
                     $this->traverseFlexFormXMLData_recurse($dataStruct['ROOT']['el'], $editData['data'][$sheet][$lang], $PA, 'data/' . $sheet . '/' . $lang);
                 } else {
                     return 'Data Structure ERROR: No ROOT element found for sheet "' . $sheet . '".';
                 }
             }
         }
     } else {
         return 'Data Structure ERROR: ' . $dataStructArray;
     }
 }
Пример #14
0
 /**
  * Ajax handler for the "suggest" feature in TCEforms.
  *
  * @param array $params The parameters from the AJAX call
  * @param \TYPO3\CMS\Core\Http\AjaxRequestHandler $ajaxObj The AJAX object representing the AJAX call
  * @return void
  */
 public function processAjaxRequest($params, &$ajaxObj)
 {
     // Get parameters from $_GET/$_POST
     $search = \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('value');
     $table = \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('table');
     $field = \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('field');
     $uid = \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('uid');
     $pageId = \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('pid');
     \TYPO3\CMS\Core\Utility\GeneralUtility::loadTCA($table);
     // 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)
     if (is_numeric($uid)) {
         if ($table == 'pages') {
             $pageId = $uid;
         } else {
             $row = \TYPO3\CMS\Backend\Utility\BackendUtility::getRecord($table, $uid);
             $pageId = $row['pid'];
         }
     }
     $TSconfig = \TYPO3\CMS\Backend\Utility\BackendUtility::getPagesTSconfig($pageId);
     $queryTables = array();
     $foreign_table_where = '';
     $fieldConfig = $GLOBALS['TCA'][$table]['columns'][$field]['config'];
     $parts = explode('|', $field);
     if ($GLOBALS['TCA'][$table]['columns'][$parts[0]]['config']['type'] === 'flex') {
         if (is_array($row) && count($row) > 0) {
             $flexfieldTCAConfig = $GLOBALS['TCA'][$table]['columns'][$parts[0]]['config'];
             $flexformDSArray = \TYPO3\CMS\Backend\Utility\BackendUtility::getFlexFormDS($flexfieldTCAConfig, $row, $table);
             $flexformDSArray = \TYPO3\CMS\Core\Utility\GeneralUtility::resolveAllSheetsInDS($flexformDSArray);
             $flexformElement = $parts[count($parts) - 2];
             $continue = TRUE;
             foreach ($flexformDSArray as $sheet) {
                 foreach ($sheet as $_ => $dataStructure) {
                     if (isset($dataStructure['ROOT']['el'][$flexformElement]['TCEforms']['config'])) {
                         $fieldConfig = $dataStructure['ROOT']['el'][$flexformElement]['TCEforms']['config'];
                         $continue = FALSE;
                         break;
                     }
                 }
                 if (!$continue) {
                     break;
                 }
             }
             $field = str_replace('|', '][', $field);
         }
     }
     $wizardConfig = $fieldConfig['wizards']['suggest'];
     if (isset($fieldConfig['allowed'])) {
         $queryTables = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $fieldConfig['allowed']);
     } elseif (isset($fieldConfig['foreign_table'])) {
         $queryTables = array($fieldConfig['foreign_table']);
         $foreign_table_where = $fieldConfig['foreign_table_where'];
         // strip ORDER BY clause
         $foreign_table_where = trim(preg_replace('/ORDER[[:space:]]+BY.*/i', '', $foreign_table_where));
     }
     $resultRows = array();
     // fetch the records for each query table. A query table is a table from which records are allowed to
     // be added to the TCEForm selector, originally fetched from the "allowed" config option in the TCA
     foreach ($queryTables as $queryTable) {
         \TYPO3\CMS\Core\Utility\GeneralUtility::loadTCA($queryTable);
         // if the table does not exist, skip it
         if (!is_array($GLOBALS['TCA'][$queryTable]) || !count($GLOBALS['TCA'][$queryTable])) {
             continue;
         }
         $config = (array) $wizardConfig['default'];
         if (is_array($wizardConfig[$queryTable])) {
             $config = \TYPO3\CMS\Core\Utility\GeneralUtility::array_merge_recursive_overrule($config, $wizardConfig[$queryTable]);
         }
         // merge the configurations of different "levels" to get the working configuration for this table and
         // field (i.e., go from the most general to the most special configuration)
         if (is_array($TSconfig['TCEFORM.']['suggest.']['default.'])) {
             $config = \TYPO3\CMS\Core\Utility\GeneralUtility::array_merge_recursive_overrule($config, $TSconfig['TCEFORM.']['suggest.']['default.']);
         }
         if (is_array($TSconfig['TCEFORM.']['suggest.'][$queryTable . '.'])) {
             $config = \TYPO3\CMS\Core\Utility\GeneralUtility::array_merge_recursive_overrule($config, $TSconfig['TCEFORM.']['suggest.'][$queryTable . '.']);
         }
         // use $table instead of $queryTable here because we overlay a config
         // for the input-field here, not for the queried table
         if (is_array($TSconfig['TCEFORM.'][$table . '.'][$field . '.']['suggest.']['default.'])) {
             $config = \TYPO3\CMS\Core\Utility\GeneralUtility::array_merge_recursive_overrule($config, $TSconfig['TCEFORM.'][$table . '.'][$field . '.']['suggest.']['default.']);
         }
         if (is_array($TSconfig['TCEFORM.'][$table . '.'][$field . '.']['suggest.'][$queryTable . '.'])) {
             $config = \TYPO3\CMS\Core\Utility\GeneralUtility::array_merge_recursive_overrule($config, $TSconfig['TCEFORM.'][$table . '.'][$field . '.']['suggest.'][$queryTable . '.']);
         }
         //process addWhere
         if (!isset($config['addWhere']) && $foreign_table_where) {
             $config['addWhere'] = $foreign_table_where;
         }
         if (isset($config['addWhere'])) {
             $config['addWhere'] = strtr(' ' . $config['addWhere'], array('###THIS_UID###' => intval($uid), '###CURRENT_PID###' => intval($pageId)));
         }
         // instantiate the class that should fetch the records for this $queryTable
         $receiverClassName = $config['receiverClass'];
         if (!class_exists($receiverClassName)) {
             $receiverClassName = 'TYPO3\\CMS\\Backend\\Form\\Element\\SuggestDefaultReceiver';
         }
         $receiverObj = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance($receiverClassName, $queryTable, $config);
         $params = array('value' => $search);
         $rows = $receiverObj->queryTable($params);
         if (empty($rows)) {
             continue;
         }
         $resultRows = \TYPO3\CMS\Core\Utility\GeneralUtility::array_merge($resultRows, $rows);
         unset($rows);
     }
     $listItems = array();
     if (count($resultRows) > 0) {
         // traverse all found records and sort them
         $rowsSort = array();
         foreach ($resultRows as $key => $row) {
             $rowsSort[$key] = $row['text'];
         }
         asort($rowsSort);
         $rowsSort = array_keys($rowsSort);
         // Limit the number of items in the result list
         $maxItems = $config['maxItemsInResultList'] ? $config['maxItemsInResultList'] : 10;
         $maxItems = min(count($resultRows), $maxItems);
         // put together the selector entry
         for ($i = 0; $i < $maxItems; $i++) {
             $row = $resultRows[$rowsSort[$i]];
             $rowId = $row['table'] . '-' . $row['uid'] . '-' . $table . '-' . $uid . '-' . $field;
             $listItems[] = '<li' . ($row['class'] != '' ? ' class="' . $row['class'] . '"' : '') . ' id="' . $rowId . '" style="' . $row['style'] . '">' . $row['text'] . '</li>';
         }
     }
     if (count($listItems) > 0) {
         $list = implode('', $listItems);
     } else {
         $list = '<li class="suggest-noresults"><i>' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:labels.noRecordFound') . '</i></li>';
     }
     $list = '<ul class="' . $this->cssClass . '-resultlist">' . $list . '</ul>';
     $ajaxObj->addContent(0, $list);
 }
Пример #15
0
 /**
  * Look for flexform field and add to internal translation details
  *
  * @param string $table Table name
  * @param array $row Table row
  * @return void
  */
 function _lookForFlexFormFieldAndAddToInternalTranslationDetails($table, $row)
 {
     global $TCA;
     foreach ($TCA[$table]['columns'] as $field => $cfg) {
         $conf = $cfg['config'];
         // For "flex" fieldtypes we need to traverse the structure looking for file and db references of course!
         if ($conf['type'] == 'flex') {
             // We might like to add the filter that detects if record is tt_content/CType is "tx_flex...:" since otherwise we would translate flexform content that might be hidden if say the record had a DS set but was later changed back to "Text w/Image" or so... But probably this is a rare case.
             // Get current data structure to see if translation is needed:
             $dataStructArray = BackendUtility::getFlexFormDS($conf, $row, $table);
             $this->detailsOutput['log'][] = 'FlexForm field "' . $field . '": DataStructure status: ' . (is_array($dataStructArray) ? 'OK' : 'Error: ' . $dataStructArray);
             if (is_array($dataStructArray) && !$dataStructArray['meta']['langDisable']) {
                 $this->detailsOutput['log'][] = 'FlexForm Localization enabled, type: ' . ($dataStructArray['meta']['langChildren'] ? 'Inheritance: Continue' : 'Separate: Stop');
                 if ($dataStructArray['meta']['langChildren']) {
                     $currentValueArray = GeneralUtility::xml2array($row[$field]);
                     // Traversing the XML structure, processing files:
                     if (is_array($currentValueArray)) {
                         // Create and call iterator object:
                         /** @var $flexObj t3lib_flexformtools */
                         $flexObj = GeneralUtility::makeInstance(FlexFormTools::class);
                         $flexObj->traverseFlexFormXMLData($table, $field, $row, $this, 'translationDetails_flexFormCallBack');
                     }
                 }
             } else {
                 $this->detailsOutput['log'][] = 'FlexForm Localization disabled. Nothing to do.';
             }
         }
     }
 }