/** * Performs remapping of old UID values to NEW uid values for a inline field. * * @param array $conf: TCA field config * @param string $value: Field value * @param integer $uid: The uid of the ORIGINAL record * @param string $table: Table name * @return void */ function remapListedDBRecords_procInline($conf, $value, $uid, $table) { $theUidToUpdate = $this->copyMappingArray_merged[$table][$uid]; if ($conf['foreign_table']) { $inlineType = $this->getInlineFieldType($conf); if ($inlineType == 'mm') { $this->remapListedDBRecords_procDBRefs($conf, $value, $theUidToUpdate, $table); } elseif ($inlineType !== FALSE) { /** @var $dbAnalysis t3lib_loadDBGroup */ $dbAnalysis = t3lib_div::makeInstance('t3lib_loadDBGroup'); $dbAnalysis->start($value, $conf['foreign_table'], '', 0, $table, $conf); // Update child records if using pointer fields ('foreign_field'): if ($inlineType == 'field') { $dbAnalysis->writeForeignField($conf, $uid, $theUidToUpdate); } // If the current field is set on a page record, update the pid of related child records: if ($table == 'pages') { $thePidToUpdate = $theUidToUpdate; // If the current field has ancestors that have a field on a page record, update the pid of related child records: } elseif (isset($this->registerDBPids[$table][$uid])) { $thePidToUpdate = $this->registerDBPids[$table][$uid]; $thePidToUpdate = $this->copyMappingArray_merged['pages'][$thePidToUpdate]; } // Update child records if change to pid is required (only if the current record is not on a workspace): if ($thePidToUpdate) { $updateValues = array('pid' => $thePidToUpdate); foreach ($dbAnalysis->itemArray as $v) { if ($v['id'] && $v['table'] && is_null(t3lib_BEfunc::getLiveVersionIdOfRecord($v['table'], $v['id']))) { $GLOBALS['TYPO3_DB']->exec_UPDATEquery($v['table'], 'uid=' . intval($v['id']), $updateValues); } } } } } }
/** * Callback to add additional data to new elements created in the dependency resolver utility. * * @param t3lib_utility_Dependency_Element $caller * @param array $callerArguments * @param array $targetArgument * @return void */ public function createNewDependentElementCallback(array $callerArguments, array $targetArgument, t3lib_utility_Dependency_Element $caller) { if ($caller->hasDataValue('liveId') === FALSE) { $liveId = t3lib_BEfunc::getLiveVersionIdOfRecord($caller->getTable(), $caller->getId()); if (is_null($liveId) === FALSE) { $caller->setDataValue('liveId', $liveId); } } }
/** * Generates a view link for a page. * * @static * @param $table * @param $uid * @param $record * @return string */ public static function viewSingleRecord($table, $uid, $record = null) { $viewUrl = ''; if ($table == 'pages') { $viewUrl = t3lib_BEfunc::viewOnClick(t3lib_BEfunc::getLiveVersionIdOfRecord('pages', $uid)); } elseif ($table == 'pages_language_oderlay' || $table == 'tt_content') { $elementRecord = is_array($record) ? $record : t3lib_BEfunc::getLiveVersionOfRecord($table, $uid); $viewUrl = t3lib_BEfunc::viewOnClick($elementRecord['pid']); } else { if (isset($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['workspaces']['viewSingleRecord'])) { $_params = array('table' => $table, 'uid' => $uid, 'record' => $record); $_funcRef = $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['workspaces']['viewSingleRecord']; $viewUrl = t3lib_div::callUserFunction($_funcRef, $_params, null); } } return $viewUrl; }
/** * Generation of TCEform elements of the type "inline" * This will render inline-relational-record sets. Relations. * * @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 */ function getSingleField_typeInline($table, $field, $row, &$PA) { // check the TCA configuration - if false is returned, something was wrong if ($this->checkConfiguration($PA['fieldConf']['config']) === FALSE) { return FALSE; } // count the number of processed inline elements $this->inlineCount++; // Init: $config = $PA['fieldConf']['config']; $foreign_table = $config['foreign_table']; t3lib_div::loadTCA($foreign_table); if (t3lib_BEfunc::isTableLocalizable($table)) { $language = intval($row[$GLOBALS['TCA'][$table]['ctrl']['languageField']]); } $minitems = t3lib_div::intInRange($config['minitems'], 0); $maxitems = t3lib_div::intInRange($config['maxitems'], 0); if (!$maxitems) { $maxitems = 100000; } // Register the required number of elements: $this->fObj->requiredElements[$PA['itemFormElName']] = array($minitems, $maxitems, 'imgName' => $table . '_' . $row['uid'] . '_' . $field); // remember the page id (pid of record) where inline editing started first // we need that pid for ajax calls, so that they would know where the action takes place on the page structure if (!isset($this->inlineFirstPid)) { // if this record is not new, try to fetch the inlineView states // @TODO: Add checking/cleaning for unused tables, records, etc. to save space in uc-field if (t3lib_div::testInt($row['uid'])) { $inlineView = unserialize($GLOBALS['BE_USER']->uc['inlineView']); $this->inlineView = $inlineView[$table][$row['uid']]; } // If the parent is a page, use the uid(!) of the (new?) page as pid for the child records: if ($table == 'pages') { $liveVersionId = t3lib_BEfunc::getLiveVersionIdOfRecord('pages', $row['uid']); $this->inlineFirstPid = is_null($liveVersionId) ? $row['uid'] : $liveVersionId; // If pid is negative, fetch the previous record and take its pid: } elseif ($row['pid'] < 0) { $prevRec = t3lib_BEfunc::getRecord($table, abs($row['pid'])); $this->inlineFirstPid = $prevRec['pid']; // Take the pid as it is: } else { $this->inlineFirstPid = $row['pid']; } } // add the current inline job to the structure stack $this->pushStructure($table, $row['uid'], $field, $config); // e.g. data[<table>][<uid>][<field>] $nameForm = $this->inlineNames['form']; // e.g. data-<pid>-<table1>-<uid1>-<field1>-<table2>-<uid2>-<field2> $nameObject = $this->inlineNames['object']; // get the records related to this inline record $relatedRecords = $this->getRelatedRecords($table, $field, $row, $PA, $config); // set the first and last record to the config array $relatedRecordsUids = array_keys($relatedRecords['records']); $config['inline']['first'] = reset($relatedRecordsUids); $config['inline']['last'] = end($relatedRecordsUids); // Tell the browser what we have (using JSON later): $top = $this->getStructureLevel(0); $this->inlineData['config'][$nameObject] = array('table' => $foreign_table, 'md5' => md5($nameObject)); $this->inlineData['config'][$nameObject . self::Structure_Separator . $foreign_table] = array('min' => $minitems, 'max' => $maxitems, 'sortable' => $config['appearance']['useSortable'], 'top' => array('table' => $top['table'], 'uid' => $top['uid'])); // Set a hint for nested IRRE and tab elements: $this->inlineData['nested'][$nameObject] = $this->fObj->getDynNestedStack(FALSE, $this->isAjaxCall); // if relations are required to be unique, get the uids that have already been used on the foreign side of the relation if ($config['foreign_unique']) { // If uniqueness *and* selector are set, they should point to the same field - so, get the configuration of one: $selConfig = $this->getPossibleRecordsSelectorConfig($config, $config['foreign_unique']); // Get the used unique ids: $uniqueIds = $this->getUniqueIds($relatedRecords['records'], $config, $selConfig['type'] == 'groupdb'); $possibleRecords = $this->getPossibleRecords($table, $field, $row, $config, 'foreign_unique'); $uniqueMax = $config['appearance']['useCombination'] || $possibleRecords === FALSE ? -1 : count($possibleRecords); $this->inlineData['unique'][$nameObject . self::Structure_Separator . $foreign_table] = array('max' => $uniqueMax, 'used' => $uniqueIds, 'type' => $selConfig['type'], 'table' => $config['foreign_table'], 'elTable' => $selConfig['table'], 'field' => $config['foreign_unique'], 'selector' => $selConfig['selector'], 'possible' => $this->getPossibleRecordsFlat($possibleRecords)); } // if it's required to select from possible child records (reusable children), add a selector box if ($config['foreign_selector']) { // if not already set by the foreign_unique, set the possibleRecords here and the uniqueIds to an empty array if (!$config['foreign_unique']) { $possibleRecords = $this->getPossibleRecords($table, $field, $row, $config); $uniqueIds = array(); } $selectorBox = $this->renderPossibleRecordsSelector($possibleRecords, $config, $uniqueIds); $item .= $selectorBox; } // wrap all inline fields of a record with a <div> (like a container) $item .= '<div id="' . $nameObject . '">'; // define how to show the "Create new record" link - if there are more than maxitems, hide it if ($relatedRecords['count'] >= $maxitems || $uniqueMax > 0 && $relatedRecords['count'] >= $uniqueMax) { $config['inline']['inlineNewButtonStyle'] = 'display: none;'; } // Render the level links (create new record, localize all, synchronize): if ($config['appearance']['levelLinksPosition'] != 'none') { $levelLinks = $this->getLevelInteractionLink('newRecord', $nameObject . self::Structure_Separator . $foreign_table, $config); if ($language > 0) { // Add the "Localize all records" link before all child records: if (isset($config['appearance']['showAllLocalizationLink']) && $config['appearance']['showAllLocalizationLink']) { $levelLinks .= $this->getLevelInteractionLink('localize', $nameObject . self::Structure_Separator . $foreign_table, $config); } // Add the "Synchronize with default language" link before all child records: if (isset($config['appearance']['showSynchronizationLink']) && $config['appearance']['showSynchronizationLink']) { $levelLinks .= $this->getLevelInteractionLink('synchronize', $nameObject . self::Structure_Separator . $foreign_table, $config); } } } // Add the level links before all child records: if (in_array($config['appearance']['levelLinksPosition'], array('both', 'top'))) { $item .= $levelLinks; } $item .= '<div id="' . $nameObject . '_records">'; $relationList = array(); if (count($relatedRecords['records'])) { foreach ($relatedRecords['records'] as $rec) { $item .= $this->renderForeignRecord($row['uid'], $rec, $config); if (!isset($rec['__virtual']) || !$rec['__virtual']) { $relationList[] = $rec['uid']; } } } $item .= '</div>'; // Add the level links after all child records: if (in_array($config['appearance']['levelLinksPosition'], array('both', 'bottom'))) { $item .= $levelLinks; } // add Drag&Drop functions for sorting to TCEforms::$additionalJS_post if (count($relationList) > 1 && $config['appearance']['useSortable']) { $this->addJavaScriptSortable($nameObject . '_records'); } // publish the uids of the child records in the given order to the browser $item .= '<input type="hidden" name="' . $nameForm . '" value="' . implode(',', $relationList) . '" class="inlineRecord" />'; // close the wrap for all inline fields (container) $item .= '</div>'; // on finishing this section, remove the last item from the structure stack $this->popStructure(); // if this was the first call to the inline type, restore the values if (!$this->getStructureDepth()) { unset($this->inlineFirstPid); } return $item; }