/**
  * Initialize object with page id.
  *
  * @param	integer		UID of page in processing
  * @return	void
  */
 function init($page_uid)
 {
     // Initialize TemplaVoila API class:
     $apiObj = t3lib_div::makeInstance('tx_templavoila_api', 'pages');
     // Fetch the content structure of page:
     $contentTreeData = $apiObj->getContentTree('pages', t3lib_BEfunc::getRecordRaw('pages', 'uid=' . intval($page_uid)));
     if ($contentTreeData['tree']['ds_is_found']) {
         $this->usedUids = array_keys($contentTreeData['contentElementUsage']);
         $this->usedUids[] = 0;
     }
 }
 /**
  * The main function in the class
  *
  * @return	string		HTML content
  */
 function main()
 {
     $output = 'Enter [table]:[uid]:[fieldlist (optional)] <input name="table_uid" value="' . htmlspecialchars(t3lib_div::_POST('table_uid')) . '" />';
     $output .= '<input type="submit" name="_" value="REFRESH" /><br/>';
     // Show record:
     if (t3lib_div::_POST('table_uid')) {
         list($table, $uid, $fieldName) = t3lib_div::trimExplode(':', t3lib_div::_POST('table_uid'), 1);
         if ($GLOBALS['TCA'][$table]) {
             $rec = t3lib_BEfunc::getRecordRaw($table, 'uid=' . intval($uid), $fieldName ? $fieldName : '*');
             if (count($rec)) {
                 $pidOfRecord = $rec['pid'];
                 $output .= '<input type="checkbox" name="show_path" value="1"' . (t3lib_div::_POST('show_path') ? ' checked="checked"' : '') . '/> Show path and rootline of record<br/>';
                 if (t3lib_div::_POST('show_path')) {
                     $output .= '<br/>Path of PID ' . $pidOfRecord . ': <em>' . t3lib_BEfunc::getRecordPath($pidOfRecord, '', 30) . '</em><br/>';
                     $output .= 'RL:' . Tx_Extdeveval_Compatibility::viewArray(t3lib_BEfunc::BEgetRootLine($pidOfRecord)) . '<br/>';
                     $output .= 'FLAGS:' . ($rec['deleted'] ? ' <b>DELETED</b>' : '') . ($rec['pid'] == -1 ? ' <b>OFFLINE VERSION of ' . $rec['t3ver_oid'] . '</b>' : '') . '<br/><hr/>';
                 }
                 if (t3lib_div::_POST('_EDIT')) {
                     $output .= '<hr/>Edit:<br/><br/>';
                     $output .= '<input type="submit" name="_SAVE" value="SAVE" /><br/>';
                     foreach ($rec as $field => $value) {
                         $output .= '<b>' . htmlspecialchars($field) . ':</b><br/>';
                         if (count(explode(chr(10), $value)) > 1) {
                             $output .= '<textarea name="record[' . $table . '][' . $uid . '][' . $field . ']" cols="100" rows="10">' . t3lib_div::formatForTextarea($value) . '</textarea><br/>';
                         } else {
                             $output .= '<input name="record[' . $table . '][' . $uid . '][' . $field . ']" value="' . htmlspecialchars($value) . '" size="100" /><br/>';
                         }
                     }
                 } elseif (t3lib_div::_POST('_SAVE')) {
                     $incomingData = t3lib_div::_POST('record');
                     $GLOBALS['TYPO3_DB']->exec_UPDATEquery($table, 'uid=' . intval($uid), $incomingData[$table][$uid]);
                     $output .= '<br/>Updated ' . $table . ':' . $uid . '...';
                     $this->updateRefIndex($table, $uid);
                 } else {
                     if (t3lib_div::_POST('_DELETE')) {
                         $GLOBALS['TYPO3_DB']->exec_DELETEquery($table, 'uid=' . intval($uid));
                         $output .= '<br/>Deleted ' . $table . ':' . $uid . '...';
                         $this->updateRefIndex($table, $uid);
                     } else {
                         $output .= '<input type="submit" name="_EDIT" value="EDIT" />';
                         $output .= '<input type="submit" name="_DELETE" value="DELETE" onclick="return confirm(\'Are you sure you wish to delete?\');" />';
                         $output .= '<br/>' . md5(implode($rec));
                         $output .= Tx_Extdeveval_Compatibility::viewArray($rec);
                     }
                 }
             } else {
                 $output .= 'No record existed!';
             }
         }
     }
     return $output;
 }
 /**
  * exportEXCELXML which is called over cli
  *
  * @param integer $l10ncfg ID of the configuration to load
  * @param integer $tlang ID of the language to translate to
  * @return string An error message in case of failure
  */
 function exportEXCELXML($l10ncfg, $tlang)
 {
     global $lang;
     $error = '';
     // Load the configuration
     $this->loadExtConf();
     /** @var $l10nmgrCfgObj tx_l10nmgr_l10nConfiguration */
     $l10nmgrCfgObj = t3lib_div::makeInstance('tx_l10nmgr_l10nConfiguration');
     $l10nmgrCfgObj->load($l10ncfg);
     if ($l10nmgrCfgObj->isLoaded()) {
         /** @var $l10nmgrGetXML tx_l10nmgr_excelXMLView */
         $l10nmgrGetXML = t3lib_div::makeInstance('tx_l10nmgr_excelXMLView', $l10nmgrCfgObj, $tlang);
         // Check if sourceLangStaticId is set in configuration and set setForcedSourceLanguage to this value
         if ($l10nmgrCfgObj->getData('sourceLangStaticId') && t3lib_extMgm::isLoaded('static_info_tables')) {
             $staticLangArr = t3lib_BEfunc::getRecordRaw('sys_language', 'static_lang_isocode = ' . $l10nmgrCfgObj->getData('sourceLangStaticId'), 'uid');
             if (is_array($staticLangArr) && $staticLangArr['uid'] > 0) {
                 $forceLanguage = $staticLangArr['uid'];
                 $l10nmgrGetXML->setForcedSourceLanguage($forceLanguage);
             }
         }
         $onlyChanged = isset($this->cli_args['--updated']) ? $this->cli_args['--updated'][0] : 'FALSE';
         if ($onlyChanged === 'TRUE') {
             $l10nmgrGetXML->setModeOnlyChanged();
         }
         $hidden = isset($this->cli_args['--hidden']) ? $this->cli_args['--hidden'][0] : 'FALSE';
         if ($hidden === 'TRUE') {
             $GLOBALS['BE_USER']->uc['moduleData']['xMOD_tx_l10nmgr_cm1']['noHidden'] = TRUE;
             $l10nmgrGetXML->setModeNoHidden();
         }
         // If the check for already exported content is enabled, run the ckeck.
         $checkExportsCli = isset($this->cli_args['--check-exports']) ? (bool) $this->cli_args['--check-exports'][0] : FALSE;
         $checkExports = $l10nmgrGetXML->checkExports();
         if ($checkExportsCli === TRUE && $checkExports == FALSE) {
             $this->cli_echo($lang->getLL('export.process.duplicate.title') . ' ' . $lang->getLL('export.process.duplicate.message') . LF);
             $this->cli_echo($l10nmgrGetXML->renderExportsCli() . LF);
         } else {
             // Save export to XML file
             $xmlFileName = $l10nmgrGetXML->render();
             $l10nmgrGetXML->saveExportInformation();
             // If email notification is set send export files to responsible translator
             if ($this->lConf['enable_notification'] == 1) {
                 if (empty($this->lConf['email_recipient'])) {
                     $this->cli_echo($lang->getLL('error.email.repient_missing.msg') . "\n");
                 } else {
                     $this->emailNotification($xmlFileName, $l10nmgrCfgObj, $tlang);
                 }
             } else {
                 $this->cli_echo($lang->getLL('error.email.notification_disabled.msg') . "\n");
             }
             // If FTP option is set upload files to remote server
             if ($this->lConf['enable_ftp'] == 1) {
                 if (file_exists($xmlFileName)) {
                     $error .= $this->ftpUpload($xmlFileName, $l10nmgrGetXML->getFileName());
                 } else {
                     $this->cli_echo($lang->getLL('error.ftp.file_not_found.msg') . "\n");
                 }
             } else {
                 $this->cli_echo($lang->getLL('error.ftp.disabled.msg') . "\n");
             }
             if ($this->lConf['enable_notification'] == 0 && $this->lConf['enable_ftp'] == 0) {
                 $this->cli_echo(sprintf($lang->getLL('export.file_saved.msg'), $xmlFileName) . "\n");
             }
         }
     } else {
         $error .= $lang->getLL('error.l10nmgr.object_not_loaded.msg') . "\n";
     }
     return $error;
 }
 /**
  * Sub function of insertElement: creates a new tt_content record in the database.
  *
  * @param	array		$destinationPointer: flexform pointer to the parent element of the new record
  * @param	array		$row: The record data to insert into the database
  * @return	mixed		The UID of the newly created record or FALSE if operation was not successful
  * @access	public
  */
 function insertElement_createRecord($destinationPointer, $row)
 {
     if ($this->debug) {
         t3lib_div::devLog('API: insertElement_createRecord()', 'templavoila', 0, array('destinationPointer' => $destinationPointer, 'row' => $row));
     }
     $parentRecord = t3lib_BEfunc::getRecordWSOL($destinationPointer['table'], $destinationPointer['uid'], 'uid,pid,t3ver_oid,tx_templavoila_flex' . ($destinationPointer['table'] == 'pages' ? ',t3ver_swapmode' : ''));
     if ($destinationPointer['position'] > 0) {
         $currentReferencesArr = $this->flexform_getElementReferencesFromXML($parentRecord['tx_templavoila_flex'], $destinationPointer);
     }
     $newRecordPid = $destinationPointer['table'] == 'pages' ? $parentRecord['pid'] == -1 && $parentRecord['t3ver_swapmode'] == -1 ? $parentRecord['t3ver_oid'] : $parentRecord['uid'] : $parentRecord['pid'];
     $dataArr = array();
     $dataArr['tt_content']['NEW'] = $row;
     $dataArr['tt_content']['NEW']['pid'] = $newRecordPid;
     unset($dataArr['tt_content']['NEW']['uid']);
     // If the destination is not the default language, try to set the old-style sys_language_uid field accordingly
     if ($destinationPointer['sLang'] != 'lDEF' || $destinationPointer['vLang'] != 'vDEF') {
         $languageKey = $destinationPointer['vLang'] != 'vDEF' ? $destinationPointer['vLang'] : $destinationPointer['sLang'];
         $staticLanguageRows = t3lib_BEfunc::getRecordsByField('static_languages', 'lg_iso_2', substr($languageKey, 1));
         if (isset($staticLanguageRows[0]['uid'])) {
             $languageRecord = t3lib_BEfunc::getRecordRaw('sys_language', 'static_lang_isocode=' . intval($staticLanguageRows[0]['uid']));
             if (isset($languageRecord['uid'])) {
                 $dataArr['tt_content']['NEW']['sys_language_uid'] = $languageRecord['uid'];
             }
         }
     }
     // Instantiate TCEmain and create the record:
     $tce = t3lib_div::makeInstance('t3lib_TCEmain');
     /* @var $tce t3lib_TCEmain */
     // set default TCA values specific for the user
     $TCAdefaultOverride = $GLOBALS['BE_USER']->getTSConfigProp('TCAdefaults');
     $pageTS = t3lib_BEfunc::getPagesTSconfig($newRecordPid, true);
     if (isset($pageTS['TCAdefaults.'])) {
         $TCAdefaultOverride = array_merge($TCAdefaultOverride, $pageTS['TCAdefaults.']);
     }
     if (is_array($TCAdefaultOverride)) {
         $tce->setDefaultsFromUserTS($TCAdefaultOverride);
     }
     $tce->stripslashes_values = 0;
     $flagWasSet = $this->getTCEmainRunningFlag();
     $this->setTCEmainRunningFlag(TRUE);
     if ($this->debug) {
         t3lib_div::devLog('API: insertElement_createRecord()', 'templavoila', 0, array('dataArr' => $dataArr));
     }
     $tce->start($dataArr, array());
     $tce->process_datamap();
     if ($this->debug && count($tce->errorLog)) {
         t3lib_div::devLog('API: insertElement_createRecord(): tcemain failed', 'templavoila', 0, array('errorLog' => $tce->errorLog));
     }
     $newUid = $tce->substNEWwithIDs['NEW'];
     if (!$flagWasSet) {
         $this->setTCEmainRunningFlag(FALSE);
     }
     return intval($newUid) ? intval($newUid) : FALSE;
 }
 /**
  * Recursive traversal of page tree:
  *
  * @param	integer		Page root id (must be online, valid page record - or zero for page tree root)
  * @param	integer		Depth
  * @param	integer		Echo Level
  * @param	string		Call back function (from this class or subclass)
  * @param	string		DON'T set from outside, internal. (indicates we are inside a version of a page)
  * @param	integer		DON'T set from outside, internal. (1: Indicates that rootID is a version of a page, 2: ...that it is even a version of a version (which triggers a warning!)
  * @param	string		Internal string that accumulates the path
  * @return	void
  * @access private
  */
 function genTree_traverse($rootID, $depth, $echoLevel = 0, $callBack = '', $versionSwapmode = '', $rootIsVersion = 0, $accumulatedPath = '')
 {
     // Register page:
     $this->recStats['all']['pages'][$rootID] = $rootID;
     $pageRecord = t3lib_BEfunc::getRecordRaw('pages', 'uid=' . intval($rootID), 'deleted,title,t3ver_count,t3ver_wsid');
     $accumulatedPath .= '/' . $pageRecord['title'];
     // Register if page is deleted:
     if ($pageRecord['deleted']) {
         $this->recStats['deleted']['pages'][$rootID] = $rootID;
     }
     // If rootIsVersion is set it means that the input rootID is that of a version of a page. See below where the recursive call is made.
     if ($rootIsVersion) {
         $this->recStats['versions']['pages'][$rootID] = $rootID;
         if ($pageRecord['t3ver_count'] >= 1 && $pageRecord['t3ver_wsid'] == 0) {
             // If it has been published and is in archive now...
             $this->recStats['versions_published']['pages'][$rootID] = $rootID;
         }
         if ($pageRecord['t3ver_wsid'] == 0) {
             // If it has been published and is in archive now...
             $this->recStats['versions_liveWS']['pages'][$rootID] = $rootID;
         }
         if (!isset($this->workspaceIndex[$pageRecord['t3ver_wsid']])) {
             // If it doesn't belong to a workspace...
             $this->recStats['versions_lost_workspace']['pages'][$rootID] = $rootID;
         }
         if ($rootIsVersion == 2) {
             // In case the rootID is a version inside a versioned page
             $this->recStats['versions_inside_versioned_page']['pages'][$rootID] = $rootID;
         }
     }
     if ($echoLevel > 0) {
         echo LF . $accumulatedPath . ' [' . $rootID . ']' . ($pageRecord['deleted'] ? ' (DELETED)' : '') . ($this->recStats['versions_published']['pages'][$rootID] ? ' (PUBLISHED)' : '');
     }
     if ($echoLevel > 1 && $this->recStats['versions_lost_workspace']['pages'][$rootID]) {
         echo LF . '	ERROR! This version belongs to non-existing workspace (' . $pageRecord['t3ver_wsid'] . ')!';
     }
     if ($echoLevel > 1 && $this->recStats['versions_inside_versioned_page']['pages'][$rootID]) {
         echo LF . '	WARNING! This version is inside an already versioned page or branch!';
     }
     // Call back:
     if ($callBack) {
         $this->{$callBack}('pages', $rootID, $echoLevel, $versionSwapmode, $rootIsVersion);
     }
     $pt3 = t3lib_div::milliseconds();
     // Traverse tables of records that belongs to page:
     foreach ($GLOBALS['TCA'] as $tableName => $cfg) {
         if ($tableName != 'pages') {
             // Select all records belonging to page:
             $pt4 = t3lib_div::milliseconds();
             $resSub = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid' . ($GLOBALS['TCA'][$tableName]['ctrl']['delete'] ? ',' . $GLOBALS['TCA'][$tableName]['ctrl']['delete'] : ''), $tableName, 'pid=' . intval($rootID) . ($this->genTree_traverseDeleted ? '' : t3lib_BEfunc::deleteClause($tableName)));
             $this->performanceStatistics['genTree_traverse():TraverseTables:']['MySQL']['(ALL)'] += t3lib_div::milliseconds() - $pt4;
             $this->performanceStatistics['genTree_traverse():TraverseTables:']['MySQL'][$tableName] += t3lib_div::milliseconds() - $pt4;
             $pt5 = t3lib_div::milliseconds();
             $count = $GLOBALS['TYPO3_DB']->sql_num_rows($resSub);
             if ($count) {
                 if ($echoLevel == 2) {
                     echo LF . '	\\-' . $tableName . ' (' . $count . ')';
                 }
             }
             while ($rowSub = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($resSub)) {
                 if ($echoLevel == 3) {
                     echo LF . '	\\-' . $tableName . ':' . $rowSub['uid'];
                 }
                 // If the rootID represents an "element" or "page" version type, we must check if the record from this table is allowed to belong to this:
                 if ($versionSwapmode == 'SWAPMODE:-1' || $versionSwapmode == 'SWAPMODE:0' && !$GLOBALS['TCA'][$tableName]['ctrl']['versioning_followPages']) {
                     // This is illegal records under a versioned page - therefore not registered in $this->recStats['all'] so they should be orphaned:
                     $this->recStats['illegal_record_under_versioned_page'][$tableName][$rowSub['uid']] = $rowSub['uid'];
                     if ($echoLevel > 1) {
                         echo LF . '		ERROR! Illegal record (' . $tableName . ':' . $rowSub['uid'] . ') under versioned page!';
                     }
                 } else {
                     $this->recStats['all'][$tableName][$rowSub['uid']] = $rowSub['uid'];
                     // Register deleted:
                     if ($GLOBALS['TCA'][$tableName]['ctrl']['delete'] && $rowSub[$GLOBALS['TCA'][$tableName]['ctrl']['delete']]) {
                         $this->recStats['deleted'][$tableName][$rowSub['uid']] = $rowSub['uid'];
                         if ($echoLevel == 3) {
                             echo ' (DELETED)';
                         }
                     }
                     // Check location of records regarding tree root:
                     if (!$GLOBALS['TCA'][$tableName]['ctrl']['rootLevel'] && $rootID == 0) {
                         $this->recStats['misplaced_at_rootlevel'][$tableName][$rowSub['uid']] = $rowSub['uid'];
                         if ($echoLevel > 1) {
                             echo LF . '		ERROR! Misplaced record (' . $tableName . ':' . $rowSub['uid'] . ') on rootlevel!';
                         }
                     }
                     if ($GLOBALS['TCA'][$tableName]['ctrl']['rootLevel'] == 1 && $rootID > 0) {
                         $this->recStats['misplaced_inside_tree'][$tableName][$rowSub['uid']] = $rowSub['uid'];
                         if ($echoLevel > 1) {
                             echo LF . '		ERROR! Misplaced record (' . $tableName . ':' . $rowSub['uid'] . ') inside page tree!';
                         }
                     }
                     // Traverse plugins:
                     if ($callBack) {
                         $this->{$callBack}($tableName, $rowSub['uid'], $echoLevel, $versionSwapmode, $rootIsVersion);
                     }
                     // Add any versions of those records:
                     if ($this->genTree_traverseVersions) {
                         $versions = t3lib_BEfunc::selectVersionsOfRecord($tableName, $rowSub['uid'], 'uid,t3ver_wsid,t3ver_count' . ($GLOBALS['TCA'][$tableName]['ctrl']['delete'] ? ',' . $GLOBALS['TCA'][$tableName]['ctrl']['delete'] : ''), 0, TRUE);
                         if (is_array($versions)) {
                             foreach ($versions as $verRec) {
                                 if (!$verRec['_CURRENT_VERSION']) {
                                     if ($echoLevel == 3) {
                                         echo LF . '		\\-[#OFFLINE VERSION: WS#' . $verRec['t3ver_wsid'] . '/Cnt:' . $verRec['t3ver_count'] . '] ' . $tableName . ':' . $verRec['uid'] . ')';
                                     }
                                     $this->recStats['all'][$tableName][$verRec['uid']] = $verRec['uid'];
                                     // Register deleted:
                                     if ($GLOBALS['TCA'][$tableName]['ctrl']['delete'] && $verRec[$GLOBALS['TCA'][$tableName]['ctrl']['delete']]) {
                                         $this->recStats['deleted'][$tableName][$verRec['uid']] = $verRec['uid'];
                                         if ($echoLevel == 3) {
                                             echo ' (DELETED)';
                                         }
                                     }
                                     // Register version:
                                     $this->recStats['versions'][$tableName][$verRec['uid']] = $verRec['uid'];
                                     if ($verRec['t3ver_count'] >= 1 && $verRec['t3ver_wsid'] == 0) {
                                         // Only register published versions in LIVE workspace (published versions in draft workspaces are allowed)
                                         $this->recStats['versions_published'][$tableName][$verRec['uid']] = $verRec['uid'];
                                         if ($echoLevel == 3) {
                                             echo ' (PUBLISHED)';
                                         }
                                     }
                                     if ($verRec['t3ver_wsid'] == 0) {
                                         $this->recStats['versions_liveWS'][$tableName][$verRec['uid']] = $verRec['uid'];
                                     }
                                     if (!isset($this->workspaceIndex[$verRec['t3ver_wsid']])) {
                                         $this->recStats['versions_lost_workspace'][$tableName][$verRec['uid']] = $verRec['uid'];
                                         if ($echoLevel > 1) {
                                             echo LF . '		ERROR! Version (' . $tableName . ':' . $verRec['uid'] . ') belongs to non-existing workspace (' . $verRec['t3ver_wsid'] . ')!';
                                         }
                                     }
                                     if ($versionSwapmode) {
                                         // In case we are inside a versioned branch, there should not exists versions inside that "branch".
                                         $this->recStats['versions_inside_versioned_page'][$tableName][$verRec['uid']] = $verRec['uid'];
                                         if ($echoLevel > 1) {
                                             echo LF . '		ERROR! This version (' . $tableName . ':' . $verRec['uid'] . ') is inside an already versioned page or branch!';
                                         }
                                     }
                                     // Traverse plugins:
                                     if ($callBack) {
                                         $this->{$callBack}($tableName, $verRec['uid'], $echoLevel, $versionSwapmode, $rootIsVersion);
                                     }
                                 }
                             }
                         }
                         unset($versions);
                     }
                 }
             }
             $this->performanceStatistics['genTree_traverse():TraverseTables:']['Proc']['(ALL)'] += t3lib_div::milliseconds() - $pt5;
             $this->performanceStatistics['genTree_traverse():TraverseTables:']['Proc'][$tableName] += t3lib_div::milliseconds() - $pt5;
         }
     }
     unset($resSub);
     unset($rowSub);
     $this->performanceStatistics['genTree_traverse():TraverseTables'] += t3lib_div::milliseconds() - $pt3;
     // Find subpages to root ID and traverse (only when rootID is not a version or is a branch-version):
     if (!$versionSwapmode || $versionSwapmode == 'SWAPMODE:1') {
         if ($depth > 0) {
             $depth--;
             $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid', 'pages', 'pid=' . intval($rootID) . ($this->genTree_traverseDeleted ? '' : t3lib_BEfunc::deleteClause('pages')), '', 'sorting');
             while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
                 $this->genTree_traverse($row['uid'], $depth, $echoLevel, $callBack, $versionSwapmode, 0, $accumulatedPath);
             }
         }
         // Add any versions of pages
         if ($rootID > 0 && $this->genTree_traverseVersions) {
             $versions = t3lib_BEfunc::selectVersionsOfRecord('pages', $rootID, 'uid,t3ver_oid,t3ver_wsid,t3ver_count,t3ver_swapmode', 0, TRUE);
             if (is_array($versions)) {
                 foreach ($versions as $verRec) {
                     if (!$verRec['_CURRENT_VERSION']) {
                         $this->genTree_traverse($verRec['uid'], $depth, $echoLevel, $callBack, 'SWAPMODE:' . t3lib_div::intInRange($verRec['t3ver_swapmode'], -1, 1), $versionSwapmode ? 2 : 1, $accumulatedPath . ' [#OFFLINE VERSION: WS#' . $verRec['t3ver_wsid'] . '/Cnt:' . $verRec['t3ver_count'] . ']');
                     }
                 }
             }
         }
     }
 }
 /**
  * Call back function for page tree traversal!
  *
  * @param	string		Table name
  * @param	integer		UID of record in processing
  * @param	integer		Echo level  (see calling function
  * @param	string		Version swap mode on that level (see calling function
  * @param	integer		Is root version (see calling function
  * @return	void
  */
 function main_parseTreeCallBack($tableName, $uid, $echoLevel, $versionSwapmode, $rootIsVersion)
 {
     if ($tableName == 'pages' && $uid > 0 && !in_array($uid, $this->excludePageIdList)) {
         if (!$versionSwapmode) {
             // Initialize TemplaVoila API class:
             $apiObj = t3lib_div::makeInstance('tx_templavoila_api', 'pages');
             // Fetch the content structure of page:
             $contentTreeData = $apiObj->getContentTree('pages', t3lib_BEfunc::getRecordRaw('pages', 'uid=' . intval($uid)));
             if ($contentTreeData['tree']['ds_is_found']) {
                 $usedUids = array_keys($contentTreeData['contentElementUsage']);
                 $usedUids[] = 0;
                 // Look up all content elements that are NOT used on this page...
                 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid, header', 'tt_content', 'pid=' . intval($uid) . ' ' . 'AND uid NOT IN (' . implode(',', $usedUids) . ') ' . 'AND t3ver_state!=1 ' . 'AND t3ver_state!=3 ' . t3lib_BEfunc::deleteClause('tt_content') . t3lib_BEfunc::versioningPlaceholderClause('tt_content'), '', 'uid');
                 // Traverse, for each find references if any and register them.
                 while (false !== ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))) {
                     // Look up references to elements:
                     $refrows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('hash', 'sys_refindex', 'ref_table=' . $GLOBALS['TYPO3_DB']->fullQuoteStr('tt_content', 'sys_refindex') . ' AND ref_uid=' . intval($row['uid']) . ' AND deleted=0');
                     // Look up TRANSLATION references FROM this element to another content element:
                     $isATranslationChild = false;
                     $refrows_From = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('ref_uid', 'sys_refindex', 'tablename=' . $GLOBALS['TYPO3_DB']->fullQuoteStr('tt_content', 'sys_refindex') . ' AND recuid=' . intval($row['uid']) . ' AND field=' . $GLOBALS['TYPO3_DB']->fullQuoteStr('l18n_parent', 'sys_refindex'));
                     // Check if that other record is deleted or not:
                     if ($refrows_From[0] && $refrows_From[0]['ref_uid']) {
                         $isATranslationChild = t3lib_BEfunc::getRecord('tt_content', $refrows_From[0]['ref_uid'], 'uid') ? TRUE : FALSE;
                     }
                     // Register elements etc:
                     $this->resultArray['all_unused'][$row['uid']] = array($row['header'], count($refrows));
                     if ($echoLevel > 2) {
                         echo chr(10) . '			[tx_templavoila_unusedce:] tt_content:' . $row['uid'] . ' was not used on page...';
                     }
                     if (!count($refrows)) {
                         if ($isATranslationChild) {
                             if ($echoLevel > 2) {
                                 echo ' but is a translation of a non-deleted records and so do not delete...';
                             }
                         } else {
                             $this->resultArray['deleteMe'][$row['uid']] = $row['uid'];
                             if ($echoLevel > 2) {
                                 echo ' and can be DELETED';
                             }
                         }
                     } else {
                         if ($echoLevel > 2) {
                             echo ' but is referenced to (' . count($refrows) . ') so do not delete...';
                         }
                     }
                 }
             } else {
                 if ($echoLevel > 2) {
                     echo chr(10) . '			[tx_templavoila_unusedce:] Did not check page - did not have a Data Structure set.';
                 }
             }
         } else {
             if ($echoLevel > 2) {
                 echo chr(10) . '			[tx_templavoila_unusedce:] Did not check page - was on offline page.';
             }
         }
     }
 }
 /**
  * Checks if record can be selected based on given permission criteria
  *
  * @param	string		Record table name
  * @param	integer		Record UID
  * @param	mixed		Permission restrictions to observe: Either an integer that will be bitwise AND'ed or a string, which points to a key in the ->pMap array
  * @return	boolean		Returns true if the record given by $table, $id and $perms can be selected
  */
 function doesRecordExist($table, $id, $perms)
 {
     global $TCA;
     if ($this->bypassAccessCheckForRecords) {
         return is_array(t3lib_BEfunc::getRecordRaw($table, 'uid=' . intval($id), 'uid'));
     }
     $res = 0;
     $id = intval($id);
     // Processing the incoming $perms (from possible string to integer that can be AND'ed)
     if (!t3lib_div::testInt($perms)) {
         if ($table != 'pages') {
             switch ($perms) {
                 case 'edit':
                 case 'delete':
                 case 'new':
                     $perms = 'editcontent';
                     // This holds it all in case the record is not page!!
                     break;
             }
         }
         $perms = intval($this->pMap[$perms]);
     } else {
         $perms = intval($perms);
     }
     if (!$perms) {
         throw new RuntimeException('Internal ERROR: no permissions to check for non-admin user', 1270853920);
     }
     // For all tables: Check if record exists:
     if (is_array($TCA[$table]) && $id > 0 && ($this->isRecordInWebMount($table, $id) || $this->admin)) {
         if ($table != 'pages') {
             // Find record without checking page:
             $mres = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid,pid', $table, 'uid=' . intval($id) . $this->deleteClause($table));
             // THIS SHOULD CHECK FOR editlock I think!
             $output = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($mres);
             t3lib_BEfunc::fixVersioningPid($table, $output, TRUE);
             // If record found, check page as well:
             if (is_array($output)) {
                 // Looking up the page for record:
                 $mres = $this->doesRecordExist_pageLookUp($output['pid'], $perms);
                 $pageRec = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($mres);
                 // Return true if either a page was found OR if the PID is zero AND the user is ADMIN (in which case the record is at root-level):
                 if (is_array($pageRec) || !$output['pid'] && $this->admin) {
                     return TRUE;
                 }
             }
             return FALSE;
         } else {
             $mres = $this->doesRecordExist_pageLookUp($id, $perms);
             return $GLOBALS['TYPO3_DB']->sql_num_rows($mres);
         }
     }
 }
 /**
  * Mandatory autofix function
  * Will run auto-fix on the result array. Echos status during processing.
  *
  * @param	array		Result array from main() function
  * @return	void
  */
 function main_autoFix($resultArray)
 {
     foreach ($resultArray['dirty'] as $fieldID) {
         list($table, $uid, $field) = explode(':', $fieldID);
         echo 'Cleaning XML in "' . $fieldID . '": ';
         if ($bypass = $this->cli_noExecutionCheck($fieldID)) {
             echo $bypass;
         } else {
             // Clean XML:
             $data = array();
             $recRow = t3lib_BEfunc::getRecordRaw($table, 'uid=' . intval($uid));
             $flexObj = t3lib_div::makeInstance('t3lib_flexformtools');
             if ($recRow[$field]) {
                 $data[$table][$uid][$field] = $flexObj->cleanFlexFormXML($table, $field, $recRow);
             }
             // Execute Data array:
             $tce = t3lib_div::makeInstance('t3lib_TCEmain');
             $tce->stripslashes_values = FALSE;
             $tce->dontProcessTransformations = TRUE;
             $tce->bypassWorkspaceRestrictions = TRUE;
             $tce->bypassFileHandling = TRUE;
             $tce->start($data, array());
             // check has been done previously that there is a backend user which is Admin and also in live workspace
             $tce->process_datamap();
             // Return errors if any:
             if (count($tce->errorLog)) {
                 echo '	ERROR from "TCEmain":' . LF . 'TCEmain:' . implode(LF . 'TCEmain:', $tce->errorLog);
             } else {
                 echo 'DONE';
             }
         }
         echo LF;
     }
 }
 function quickDBlookUp()
 {
     $output = 'Enter [table]:[uid]:[fieldlist (optional)] <input name="table_uid" value="' . htmlspecialchars(t3lib_div::_POST('table_uid')) . '" />';
     $output .= '<input type="submit" name="_" value="REFRESH" /><br />';
     // Show record:
     if (t3lib_div::_POST('table_uid')) {
         list($table, $uid, $fieldName) = t3lib_div::trimExplode(':', t3lib_div::_POST('table_uid'), 1);
         if ($GLOBALS['TCA'][$table]) {
             $rec = t3lib_BEfunc::getRecordRaw($table, 'uid=' . intval($uid), $fieldName ? $fieldName : '*');
             if (count($rec)) {
                 if (t3lib_div::_POST('_EDIT')) {
                     $output .= '<hr />Edit:<br /><br />';
                     foreach ($rec as $field => $value) {
                         $output .= htmlspecialchars($field) . '<br /><input name="record[' . $table . '][' . $uid . '][' . $field . ']" value="' . htmlspecialchars($value) . '" /><br />';
                     }
                     $output .= '<input type="submit" name="_SAVE" value="SAVE" />';
                 } elseif (t3lib_div::_POST('_SAVE')) {
                     $incomingData = t3lib_div::_POST('record');
                     $GLOBALS['TYPO3_DB']->exec_UPDATEquery($table, 'uid=' . intval($uid), $incomingData[$table][$uid]);
                     $output .= '<br />Updated ' . $table . ':' . $uid . '...';
                     $this->updateRefIndex($table, $uid);
                 } else {
                     if (t3lib_div::_POST('_DELETE')) {
                         $GLOBALS['TYPO3_DB']->exec_DELETEquery($table, 'uid=' . intval($uid));
                         $output .= '<br />Deleted ' . $table . ':' . $uid . '...';
                         $this->updateRefIndex($table, $uid);
                     } else {
                         $output .= '<input type="submit" name="_EDIT" value="EDIT" />';
                         $output .= '<input type="submit" name="_DELETE" value="DELETE" onclick="return confirm(\'Are you sure you wish to delete?\');" />';
                         $output .= t3lib_utility_Debug::viewArray($rec);
                         $output .= md5(implode($rec));
                     }
                 }
             } else {
                 $output .= 'No record existed!';
             }
         }
     }
     return $output;
 }
 /**
  * Call this function to update the sys_refindex table for a record (even one just deleted)
  * NOTICE: Currently, references updated for a deleted-flagged record will not include those from within flexform fields in some cases where the data structure is defined by another record since the resolving process ignores deleted records! This will also result in bad cleaning up in tcemain I think... Anyway, thats the story of flexforms; as long as the DS can change, lots of references can get lost in no time.
  *
  * @param	string		Table name
  * @param	integer		UID of record
  * @param	boolean		If set, nothing will be written to the index but the result value will still report statistics on what is added, deleted and kept. Can be used for mere analysis.
  * @return	array		Array with statistics about how many index records were added, deleted and not altered plus the complete reference set for the record.
  */
 function updateRefIndexTable($table, $uid, $testOnly = FALSE)
 {
     // First, secure that the index table is not updated with workspace tainted relations:
     $this->WSOL = FALSE;
     // Init:
     $result = array('keptNodes' => 0, 'deletedNodes' => 0, 'addedNodes' => 0);
     // Get current index from Database:
     $currentRels = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('*', 'sys_refindex', 'tablename=' . $GLOBALS['TYPO3_DB']->fullQuoteStr($table, 'sys_refindex') . ' AND recuid=' . intval($uid), '', '', '', 'hash');
     // First, test to see if the record exists (including deleted-flagged)
     if (t3lib_BEfunc::getRecordRaw($table, 'uid=' . intval($uid), 'uid')) {
         // Then, get relations:
         $relations = $this->generateRefIndexData($table, $uid);
         if (is_array($relations)) {
             // Traverse the generated index:
             foreach ($relations as $k => $datRec) {
                 $relations[$k]['hash'] = md5(implode('///', $relations[$k]) . '///' . $this->hashVersion);
                 // First, check if already indexed and if so, unset that row (so in the end we know which rows to remove!)
                 if (isset($currentRels[$relations[$k]['hash']])) {
                     unset($currentRels[$relations[$k]['hash']]);
                     $result['keptNodes']++;
                     $relations[$k]['_ACTION'] = 'KEPT';
                 } else {
                     // If new, add it:
                     if (!$testOnly) {
                         $GLOBALS['TYPO3_DB']->exec_INSERTquery('sys_refindex', $relations[$k]);
                     }
                     $result['addedNodes']++;
                     $relations[$k]['_ACTION'] = 'ADDED';
                 }
             }
             $result['relations'] = $relations;
         } else {
             return FALSE;
         }
         // Weird mistake I would say...
     }
     // If any old are left, remove them:
     if (count($currentRels)) {
         $hashList = array_keys($currentRels);
         if (count($hashList)) {
             $result['deletedNodes'] = count($hashList);
             $result['deletedNodes_hashList'] = implode(',', $hashList);
             if (!$testOnly) {
                 $GLOBALS['TYPO3_DB']->exec_DELETEquery('sys_refindex', 'hash IN (' . implode(',', $GLOBALS['TYPO3_DB']->fullQuoteArray($hashList, 'sys_refindex')) . ')');
             }
         }
     }
     return $result;
 }
 /**
  * Find relations pointing to non-existing records
  * Fix methods: API in t3lib_refindex that allows to change the value of a reference (or remove it) [Only for managed relations!]
  *
  * @return	array
  */
 function main()
 {
     global $TYPO3_DB;
     // Initialize result array:
     $listExplain = ' Shows the missing record as header and underneath a list of record fields in which the references are found. ' . $this->label_infoString;
     $resultArray = array('message' => $this->cli_help['name'] . LF . LF . $this->cli_help['description'], 'headers' => array('offlineVersionRecords_m' => array('Offline version records (managed)', 'These records are offline versions having a pid=-1 and references should never occur directly to their uids.' . $listExplain, 3), 'deletedRecords_m' => array('Deleted-flagged records (managed)', 'These records are deleted with a flag but references are still pointing at them. Keeping the references is useful if you undelete the referenced records later, otherwise the references are lost completely when the deleted records are flushed at some point. Notice that if those records listed are themselves deleted (marked with "DELETED") it is not a problem.' . $listExplain, 2), 'nonExistingRecords_m' => array('Non-existing records to which there are references (managed)', 'These references can safely be removed since there is no record found in the database at all.' . $listExplain, 3), 'offlineVersionRecords_s' => array('Offline version records (softref)', 'See above.' . $listExplain, 2), 'deletedRecords_s' => array('Deleted-flagged records (softref)', 'See above.' . $listExplain, 2), 'nonExistingRecords_s' => array('Non-existing records to which there are references (softref)', 'See above.' . $listExplain, 2)), 'offlineVersionRecords_m' => array(), 'deletedRecords_m' => array(), 'nonExistingRecords_m' => array(), 'offlineVersionRecords_s' => array(), 'deletedRecords_s' => array(), 'nonExistingRecords_s' => array());
     // Select DB relations from reference table
     $recs = $TYPO3_DB->exec_SELECTgetRows('*', 'sys_refindex', 'ref_table!=' . $TYPO3_DB->fullQuoteStr('_FILE', 'sys_refindex') . ' AND ref_uid>0' . $filterClause, '', 'sorting DESC');
     // Traverse the records
     $tempExists = array();
     if (is_array($recs)) {
         foreach ($recs as $rec) {
             $suffix = $rec['softref_key'] != '' ? '_s' : '_m';
             $idx = $rec['ref_table'] . ':' . $rec['ref_uid'];
             // Get referenced record:
             if (!isset($tempExists[$idx])) {
                 $tempExists[$idx] = t3lib_BEfunc::getRecordRaw($rec['ref_table'], 'uid=' . intval($rec['ref_uid']), 'uid,pid' . ($GLOBALS['TCA'][$rec['ref_table']]['ctrl']['delete'] ? ',' . $GLOBALS['TCA'][$rec['ref_table']]['ctrl']['delete'] : ''));
             }
             // Compile info string for location of reference:
             $infoString = $this->infoStr($rec);
             // Handle missing file:
             if ($tempExists[$idx]['uid']) {
                 if ($tempExists[$idx]['pid'] == -1) {
                     $resultArray['offlineVersionRecords' . $suffix][$idx][$rec['hash']] = $infoString;
                     ksort($resultArray['offlineVersionRecords' . $suffix][$idx]);
                 } elseif ($GLOBALS['TCA'][$rec['ref_table']]['ctrl']['delete'] && $tempExists[$idx][$GLOBALS['TCA'][$rec['ref_table']]['ctrl']['delete']]) {
                     $resultArray['deletedRecords' . $suffix][$idx][$rec['hash']] = $infoString;
                     ksort($resultArray['deletedRecords' . $suffix][$idx]);
                 }
             } else {
                 $resultArray['nonExistingRecords' . $suffix][$idx][$rec['hash']] = $infoString;
                 ksort($resultArray['nonExistingRecords' . $suffix][$idx]);
             }
         }
     }
     ksort($resultArray['offlineVersionRecords_m']);
     ksort($resultArray['deletedRecords_m']);
     ksort($resultArray['nonExistingRecords_m']);
     ksort($resultArray['offlineVersionRecords_s']);
     ksort($resultArray['deletedRecords_s']);
     ksort($resultArray['nonExistingRecords_s']);
     return $resultArray;
 }