/**
  * Processing/Preparing content for copyRecord() function
  *
  * @param	string		Table name
  * @param	integer		Record uid
  * @param	string		Field name being processed
  * @param	string		Input value to be processed.
  * @param	array		Record array
  * @param	array		TCA field configuration
  * @param	integer		Real page id (pid) the record is copied to
  * @param	integer		Language ID (from sys_language table) used in the duplicated record
  * @return	mixed		Processed value. Normally a string/integer, but can be an array for flexforms!
  * @access private
  * @see copyRecord()
  */
 function copyRecord_procBasedOnFieldType($table, $uid, $field, $value, $row, $conf, $realDestPid, $language = 0)
 {
     global $TCA;
     // Process references and files, currently that means only the files, prepending absolute paths (so the TCEmain engine will detect the file as new and one that should be made into a copy)
     $value = $this->copyRecord_procFilesRefs($conf, $uid, $value);
     $inlineSubType = $this->getInlineFieldType($conf);
     // Register if there are references to take care of or MM is used on an inline field (no change to value):
     if ($this->isReferenceField($conf) || $inlineSubType == 'mm') {
         $allowedTables = $conf['type'] == 'group' ? $conf['allowed'] : $conf['foreign_table'] . ',' . $conf['neg_foreign_table'];
         $prependName = $conf['type'] == 'group' ? $conf['prepend_tname'] : $conf['neg_foreign_table'];
         $localizeReferences = isset($conf['foreign_table']) && t3lib_BEfunc::isTableLocalizable($conf['foreign_table']) && isset($conf['localizeReferencesAtParentLocalization']) && $conf['localizeReferencesAtParentLocalization'];
         if ($conf['MM'] || $language > 0 && $localizeReferences) {
             $dbAnalysis = t3lib_div::makeInstance('t3lib_loadDBGroup');
             /* @var $dbAnalysis t3lib_loadDBGroup */
             $dbAnalysis->start($value, $allowedTables, $conf['MM'], $uid, $table, $conf);
             if (!$conf['MM']) {
                 // Localize referenced records of select fields:
                 foreach ($dbAnalysis->itemArray as $index => $item) {
                     // Since select fields can reference many records, check whether there's already a localization:
                     $recordLocalization = t3lib_BEfunc::getRecordLocalization($item['table'], $item['id'], $language);
                     if (!$recordLocalization) {
                         $dbAnalysis->itemArray[$index]['id'] = $this->localize($item['table'], $item['id'], $language);
                     } else {
                         $dbAnalysis->itemArray[$index]['id'] = $recordLocalization[0]['uid'];
                     }
                 }
             }
             $value = implode(',', $dbAnalysis->getValueArray($prependName));
         }
         if ($value) {
             // Setting the value in this array will notify the remapListedDBRecords() function that this field MAY need references to be corrected
             $this->registerDBList[$table][$uid][$field] = $value;
         }
         // If another inline subtype is used (comma-separated-values or the foreign_field property):
     } elseif ($inlineSubType !== FALSE) {
         // Get the localization mode for the current (parent) record (keep|select|all):
         $localizationMode = t3lib_BEfunc::getInlineLocalizationMode($table, $field);
         // Localization in mode 'keep', isn't a real localization, but keeps the children of the original parent record:
         if ($language > 0 && $localizationMode == 'keep') {
             $value = $inlineSubType == 'field' ? 0 : '';
             // Execute copy or localization actions:
         } else {
             /*
              * Fetch the related child records by using t3lib_loadDBGroup:
              * @var $dbAnalysis t3lib_loadDBGroup
              */
             $dbAnalysis = t3lib_div::makeInstance('t3lib_loadDBGroup');
             $dbAnalysis->start($value, $conf['foreign_table'], '', $uid, $table, $conf);
             // Walk through the items, copy them and remember the new id:
             foreach ($dbAnalysis->itemArray as $k => $v) {
                 // If language is set and differs from original record, this isn't a copy action but a localization of our parent/ancestor:
                 if ($language > 0 && t3lib_BEfunc::isTableLocalizable($table) && $language != $row[$TCA[$table]['ctrl']['languageField']]) {
                     // If children should be localized when the parent gets localized the first time, just do it:
                     if ($localizationMode != FALSE && isset($conf['behaviour']['localizeChildrenAtParentLocalization']) && $conf['behaviour']['localizeChildrenAtParentLocalization']) {
                         $newId = $this->localize($v['table'], $v['id'], $language);
                     }
                     // If no language it set, this is a regular copy action:
                 } else {
                     if (!t3lib_div::testInt($realDestPid)) {
                         $newId = $this->copyRecord($v['table'], $v['id'], -$v['id']);
                     } elseif ($realDestPid == -1 && t3lib_BEfunc::isTableWorkspaceEnabled($v['table'])) {
                         $workspaceVersion = t3lib_BEfunc::getWorkspaceVersionOfRecord($this->BE_USER->workspace, $v['table'], $v['id'], 'uid');
                         // If workspace version does not exist, create a new one:
                         if ($workspaceVersion === FALSE) {
                             $newId = $this->versionizeRecord($v['table'], $v['id'], 'Auto-created for WS #' . $this->BE_USER->workspace);
                             // If workspace version already exists, use it:
                         } else {
                             $newId = $workspaceVersion['uid'];
                         }
                     } else {
                         $newId = $this->copyRecord_raw($v['table'], $v['id'], $realDestPid);
                     }
                 }
                 // If the current field is set on a page record, update the pid of related child records:
                 if ($table == 'pages') {
                     $this->registerDBPids[$v['table']][$v['id']] = $uid;
                     // 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])) {
                     $this->registerDBPids[$v['table']][$v['id']] = $this->registerDBPids[$table][$uid];
                 }
                 $dbAnalysis->itemArray[$k]['id'] = $newId;
             }
             // Store the new values, we will set up the uids for the subtype later on (exception keep localization from original record):
             $value = implode(',', $dbAnalysis->getValueArray());
             $this->registerDBList[$table][$uid][$field] = $value;
         }
     }
     // For "flex" fieldtypes we need to traverse the structure for two reasons: If there are file references they have to be prepended with absolute paths and if there are database reference they MIGHT need to be remapped (still done in remapListedDBRecords())
     if ($conf['type'] == 'flex') {
         // Get current value array:
         $dataStructArray = t3lib_BEfunc::getFlexFormDS($conf, $row, $table);
         $currentValueArray = t3lib_div::xml2array($value);
         // Traversing the XML structure, processing files:
         if (is_array($currentValueArray)) {
             $currentValueArray['data'] = $this->checkValue_flex_procInData($currentValueArray['data'], array(), array(), $dataStructArray, array($table, $uid, $field, $realDestPid), 'copyRecord_flexFormCallBack');
             $value = $currentValueArray;
             // Setting value as an array! -> which means the input will be processed according to the 'flex' type when the new copy is created.
         }
     }
     return $value;
 }
 /**
  * Write the sorting values to a foreign_table, that has a foreign_field (uid of the parent record)
  *
  * @param	array		$conf: TCA configuration for current field
  * @param	integer		$parentUid: The uid of the parent record
  * @param	boolean		$updateToUid: Whether to update the foreign field with the $parentUid (on Copy)
  * @param	 boolean		$skipSorting: Do not update the sorting columns, this could happen for imported values
  * @return	void
  */
 function writeForeignField($conf, $parentUid, $updateToUid = 0, $skipSorting = FALSE)
 {
     $c = 0;
     $foreign_table = $conf['foreign_table'];
     $foreign_field = $conf['foreign_field'];
     $symmetric_field = $conf['symmetric_field'];
     $foreign_table_field = $conf['foreign_table_field'];
     // if there are table items and we have a proper $parentUid
     if (t3lib_div::testInt($parentUid) && count($this->tableArray)) {
         // if updateToUid is not a positive integer, set it to '0', so it will be ignored
         if (!(t3lib_div::testInt($updateToUid) && $updateToUid > 0)) {
             $updateToUid = 0;
         }
         $considerWorkspaces = $GLOBALS['BE_USER']->workspace !== 0 && t3lib_BEfunc::isTableWorkspaceEnabled($foreign_table);
         $fields = 'uid,' . $foreign_field;
         // Consider the symmetric field if defined:
         if ($symmetric_field) {
             $fields .= ',' . $symmetric_field;
         }
         // Consider workspaces if defined and currently used:
         if ($considerWorkspaces) {
             $fields .= ',' . 't3ver_state,t3ver_oid';
         }
         // update all items
         foreach ($this->itemArray as $val) {
             $uid = $val['id'];
             $table = $val['table'];
             // fetch the current (not overwritten) relation record if we should handle symmetric relations
             if ($symmetric_field || $considerWorkspaces) {
                 $row = t3lib_BEfunc::getRecord($table, $uid, $fields, '', FALSE);
             }
             if ($symmetric_field) {
                 $isOnSymmetricSide = t3lib_loadDBGroup::isOnSymmetricSide($parentUid, $conf, $row);
             }
             $updateValues = array();
             $workspaceValues = array();
             // no update to the uid is requested, so this is the normal behaviour
             // just update the fields and care about sorting
             if (!$updateToUid) {
                 // Always add the pointer to the parent uid
                 if ($isOnSymmetricSide) {
                     $updateValues[$symmetric_field] = $parentUid;
                 } else {
                     $updateValues[$foreign_field] = $parentUid;
                 }
                 // if it is configured in TCA also to store the parent table in the child record, just do it
                 if ($foreign_table_field && $this->currentTable) {
                     $updateValues[$foreign_table_field] = $this->currentTable;
                 }
                 // update sorting columns if not to be skipped
                 if (!$skipSorting) {
                     // get the correct sorting field
                     if ($conf['foreign_sortby']) {
                         // specific manual sortby for data handled by this field
                         $sortby = $conf['foreign_sortby'];
                     } elseif ($GLOBALS['TCA'][$foreign_table]['ctrl']['sortby']) {
                         // manual sortby for all table records
                         $sortby = $GLOBALS['TCA'][$foreign_table]['ctrl']['sortby'];
                     }
                     // Apply sorting on the symmetric side (it depends on who created the relation, so what uid is in the symmetric_field):
                     if ($isOnSymmetricSide && isset($conf['symmetric_sortby']) && $conf['symmetric_sortby']) {
                         $sortby = $conf['symmetric_sortby'];
                         // Strip a possible "ORDER BY" in front of the $sortby value:
                     } else {
                         $sortby = $GLOBALS['TYPO3_DB']->stripOrderBy($sortby);
                     }
                     if ($sortby) {
                         $updateValues[$sortby] = $workspaceValues[$sortby] = ++$c;
                     }
                 }
                 // update to a foreign_field/symmetric_field pointer is requested, normally used on record copies
                 // only update the fields, if the old uid is found somewhere - for select fields, TCEmain is doing this already!
             } else {
                 if ($isOnSymmetricSide) {
                     $updateValues[$symmetric_field] = $updateToUid;
                 } else {
                     $updateValues[$foreign_field] = $updateToUid;
                 }
             }
             // Update accordant fields in the database:
             if (count($updateValues)) {
                 $GLOBALS['TYPO3_DB']->exec_UPDATEquery($table, 'uid=' . intval($uid), $updateValues);
                 $this->updateRefIndex($table, $uid);
             }
             // Update accordant fields in the database for workspaces overlays/placeholders:
             if (count($workspaceValues) && $considerWorkspaces) {
                 if (isset($row['t3ver_oid']) && $row['t3ver_oid'] && $row['t3ver_state'] == -1) {
                     $GLOBALS['TYPO3_DB']->exec_UPDATEquery($table, 'uid=' . intval($row['t3ver_oid']), $workspaceValues);
                 }
             }
         }
     }
 }
Esempio n. 3
0
 /**
  * Check if record ($table, $uid) is a workspace record
  *
  * @param string $table The table the record belongs to
  * @param integer $uid The record's uid
  * @return boolean TRUE if the record is in a draft workspace, FALSE if it's a LIVE record
  */
 public static function isDraftRecord($table, $uid)
 {
     $isWorkspaceRecord = FALSE;
     if (t3lib_BEfunc::isTableWorkspaceEnabled($table)) {
         $record = t3lib_BEfunc::getRecord($table, $uid);
         if ($record['pid'] == '-1' || $record['t3ver_state'] > 0) {
             $isWorkspaceRecord = TRUE;
         }
     }
     return $isWorkspaceRecord;
 }
Esempio n. 4
0
 /**
  * Flushes elements of a particular workspace to avoid orphan records.
  *
  * @param integer $workspaceId The workspace to be flushed
  * @return void
  */
 protected function flushWorkspaceElements($workspaceId)
 {
     $command = array();
     foreach ($this->getTcaTables() as $tcaTable) {
         if (t3lib_BEfunc::isTableWorkspaceEnabled($tcaTable)) {
             $where = '1=1';
             $where .= t3lib_BEfunc::getWorkspaceWhereClause($tcaTable, $workspaceId);
             $where .= t3lib_BEfunc::deleteClause($tcaTable);
             $records = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('uid', $tcaTable, $where, '', '', '', 'uid');
             if (is_array($records)) {
                 foreach (array_keys($records) as $recordId) {
                     $command[$tcaTable][$recordId]['version']['action'] = 'flush';
                 }
             }
         }
     }
     if (count($command)) {
         $tceMain = $this->getTceMain();
         $tceMain->start(array(), $command);
         $tceMain->process_cmdmap();
     }
 }