TYPO3 CMS  TYPO3_6-2
CleanerCommand.php
Go to the documentation of this file.
1 <?php
2 namespace TYPO3\CMS\Lowlevel;
3 
19 
31 
35  public $genTree_traverseDeleted = TRUE;
36 
41 
45  public $label_infoString = 'The list of records is organized as [table]:[uid]:[field]:[flexpointer]:[softref_key]';
46 
50  public $pagetreePlugins = array();
51 
55  public $cleanerModules = array();
56 
60  public $performanceStatistics = array();
61 
62  protected $workspaceIndex = array();
63 
69  public function __construct() {
70  // Running parent class constructor
71  parent::__construct();
72  $this->cleanerModules = (array) $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['lowlevel']['cleanerModules'];
73  // Adding options to help archive:
74  $this->cli_options[] = array('-r', 'Execute this tool, otherwise help is shown');
75  $this->cli_options[] = array('-v level', 'Verbosity level 0-3', 'The value of level can be:
76  0 = all output
77  1 = info and greater (default)
78  2 = warnings and greater
79  3 = errors');
80  $this->cli_options[] = array('--refindex mode', 'Mode for reference index handling for operations that require a clean reference index ("update"/"ignore")', 'Options are "check" (default), "update" and "ignore". By default, the reference index is checked before running analysis that require a clean index. If the check fails, the analysis is not run. You can choose to bypass this completely (using value "ignore") or ask to have the index updated right away before the analysis (using value "update")');
81  $this->cli_options[] = array('--AUTOFIX [testName]', 'Repairs errors that can be automatically fixed.', 'Only add this option after having run the test without it so you know what will happen when you add this option! The optional parameter "[testName]" works for some tool keys to limit the fixing to a particular test.');
82  $this->cli_options[] = array('--dryrun', 'With --AUTOFIX it will only simulate a repair process', 'You may like to use this to see what the --AUTOFIX option will be doing. It will output the whole process like if a fix really occurred but nothing is in fact happening');
83  $this->cli_options[] = array('--YES', 'Implicit YES to all questions', 'Use this with EXTREME care. The option "-i" is not affected by this option.');
84  $this->cli_options[] = array('-i', 'Interactive', 'Will ask you before running the AUTOFIX on each element.');
85  $this->cli_options[] = array('--filterRegex expr', 'Define an expression for preg_match() that must match the element ID in order to auto repair it', 'The element ID is the string in quotation marks when the text \'Cleaning ... in "ELEMENT ID"\'. "expr" is the expression for preg_match(). To match for example "Nature3.JPG" and "Holiday3.JPG" you can use "/.*3.JPG/". To match for example "Image.jpg" and "Image.JPG" you can use "/.*.jpg/i". Try a --dryrun first to see what the matches are!');
86  $this->cli_options[] = array('--showhowto', 'Displays HOWTO file for cleaner script.');
87  // Setting help texts:
88  $this->cli_help['name'] = 'lowlevel_cleaner -- Analysis and clean-up tools for TYPO3 installations';
89  $this->cli_help['synopsis'] = 'toolkey ###OPTIONS###';
90  $this->cli_help['description'] = 'Dispatches to various analysis and clean-up tools which can plug into the API of this script. Typically you can run tests that will take longer than the usual max execution time of PHP. Such tasks could be checking for orphan records in the page tree or flushing all published versions in the system. For the complete list of options, please explore each of the \'toolkey\' keywords below:
91 
92  ' . implode('
93  ', array_keys($this->cleanerModules));
94  $this->cli_help['examples'] = '/.../cli_dispatch.phpsh lowlevel_cleaner missing_files -s -r
95 This will show you missing files in the TYPO3 system and only report back if errors were found.';
96  $this->cli_help['author'] = 'Kasper Skaarhoej, (c) 2006';
97  }
98 
99  /**************************
100  *
101  * CLI functionality
102  *
103  *************************/
111  public function cli_main($argv) {
112 
113  $this->cli_setArguments($argv);
114 
115  // Force user to admin state and set workspace to "Live":
116  $GLOBALS['BE_USER']->user['admin'] = 1;
117  $GLOBALS['BE_USER']->setWorkspace(0);
118  // Print Howto:
119  if ($this->cli_isArg('--showhowto')) {
120  $howto = GeneralUtility::getUrl(\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extPath('lowlevel') . 'HOWTO_clean_up_TYPO3_installations.txt');
121  echo wordwrap($howto, 120) . LF;
122  die;
123  }
124  // Print help
125  $analysisType = (string) $this->cli_args['_DEFAULT'][1];
126  if (!$analysisType) {
127  $this->cli_validateArgs();
128  $this->cli_help();
129  die;
130  }
131 
132  if (is_array($this->cleanerModules[$analysisType])) {
133  $cleanerMode = GeneralUtility::getUserObj($this->cleanerModules[$analysisType][0]);
134  $cleanerMode->cli_validateArgs();
135  // Run it...
136  if ($this->cli_isArg('-r')) {
137  if (!$cleanerMode->checkRefIndex || $this->cli_referenceIndexCheck()) {
138  $res = $cleanerMode->main();
139  $this->cli_printInfo($analysisType, $res);
140  // Autofix...
141  if ($this->cli_isArg('--AUTOFIX')) {
142  if ($this->cli_isArg('--YES') || $this->cli_keyboardInput_yes('
143 
144 NOW Running --AUTOFIX on result. OK?' . ($this->cli_isArg('--dryrun') ? ' (--dryrun simulation)' : ''))) {
145  $cleanerMode->main_autofix($res);
146  } else {
147  $this->cli_echo('ABORTING AutoFix...
148 ', 1);
149  }
150  }
151  }
152  } else {
153  // Help only...
154  $cleanerMode->cli_help();
155  die;
156  }
157  } else {
158  $this->cli_echo('ERROR: Analysis Type \'' . $analysisType . '\' is unknown.
159 ', 1);
160  die;
161  }
162  }
163 
170  public function cli_referenceIndexCheck() {
171  // Reference index option:
172  $refIndexMode = isset($this->cli_args['--refindex']) ? $this->cli_args['--refindex'][0] : 'check';
173  if (!GeneralUtility::inList('update,ignore,check', $refIndexMode)) {
174  $this->cli_echo('ERROR: Wrong value for --refindex argument.
175 ', 1);
176  die;
177  }
178  switch ($refIndexMode) {
179  case 'check':
180 
181  case 'update':
182  $refIndexObj = GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Database\\ReferenceIndex');
183  list($headerContent, $bodyContent, $errorCount) = $refIndexObj->updateIndex($refIndexMode == 'check', $this->cli_echo());
184  if ($errorCount && $refIndexMode == 'check') {
185  $ok = FALSE;
186  $this->cli_echo('ERROR: Reference Index Check failed! (run with \'--refindex update\' to fix)
187 ', 1);
188  } else {
189  $ok = TRUE;
190  }
191  break;
192  case 'ignore':
193  $this->cli_echo('Reference Index Check: Bypassing reference index check...
194 ');
195  $ok = TRUE;
196  break;
197  }
198  return $ok;
199  }
200 
206  public function cli_noExecutionCheck($matchString) {
207  // Check for filter:
208  if ($this->cli_isArg('--filterRegex') && ($regex = $this->cli_argValue('--filterRegex', 0))) {
209  if (!preg_match($regex, $matchString)) {
210  return 'BYPASS: Filter Regex "' . $regex . '" did not match string "' . $matchString . '"';
211  }
212  }
213  // Check for interactive mode
214  if ($this->cli_isArg('-i')) {
215  if (!$this->cli_keyboardInput_yes(' EXECUTE?')) {
216  return 'BYPASS...';
217  }
218  }
219  // Check for
220  if ($this->cli_isArg('--dryrun')) {
221  return 'BYPASS: --dryrun set';
222  }
223  }
224 
233  public function cli_printInfo($header, $res) {
234  $detailLevel = \TYPO3\CMS\Core\Utility\MathUtility::forceIntegerInRange($this->cli_isArg('-v') ? $this->cli_argValue('-v') : 1, 0, 3);
235  $silent = !$this->cli_echo();
236  $severity = array(
237  0 => 'MESSAGE',
238  1 => 'INFO',
239  2 => 'WARNING',
240  3 => 'ERROR'
241  );
242  // Header output:
243  if ($detailLevel <= 1) {
244  $this->cli_echo('*********************************************
245 ' . $header . LF . '*********************************************
246 ');
247  $this->cli_echo(wordwrap(trim($res['message'])) . LF . LF);
248  }
249  // Traverse headers for output:
250  if (is_array($res['headers'])) {
251  foreach ($res['headers'] as $key => $value) {
252  if ($detailLevel <= (int)$value[2]) {
253  if (is_array($res[$key]) && (count($res[$key]) || !$silent)) {
254  // Header and explanaion:
255  $this->cli_echo('---------------------------------------------' . LF, 1);
256  $this->cli_echo('[' . $header . ']' . LF, 1);
257  $this->cli_echo($value[0] . ' [' . $severity[$value[2]] . ']' . LF, 1);
258  $this->cli_echo('---------------------------------------------' . LF, 1);
259  if (trim($value[1])) {
260  $this->cli_echo('Explanation: ' . wordwrap(trim($value[1])) . LF . LF, 1);
261  }
262  }
263  // Content:
264  if (is_array($res[$key])) {
265  if (count($res[$key])) {
266  if ($this->cli_echo('', 1)) {
267  print_r($res[$key]);
268  }
269  } else {
270  $this->cli_echo('(None)' . LF . LF);
271  }
272  } else {
273  $this->cli_echo($res[$key] . LF . LF);
274  }
275  }
276  }
277  }
278  }
279 
280  /**************************
281  *
282  * Page tree traversal
283  *
284  *************************/
296  public function genTree($rootID, $depth = 1000, $echoLevel = 0, $callBack = '') {
298  $this->performanceStatistics['genTree()'] = '';
299  // Initialize:
300  if (\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::isLoaded('workspaces')) {
301  $this->workspaceIndex = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('uid,title', 'sys_workspace', '1=1' . BackendUtility::deleteClause('sys_workspace'), '', '', '', 'uid');
302  }
303  $this->workspaceIndex[-1] = TRUE;
304  $this->workspaceIndex[0] = TRUE;
305  $this->recStats = array(
306  'all' => array(),
307  // All records connected in tree including versions (the reverse are orphans). All Info and Warning categories below are included here (and therefore safe if you delete the reverse of the list)
308  'deleted' => array(),
309  // Subset of "alL" that are deleted-flagged [Info]
310  'versions' => array(),
311  // Subset of "all" which are offline versions (pid=-1). [Info]
312  'versions_published' => array(),
313  // Subset of "versions" that is a count of 1 or more (has been published) [Info]
314  'versions_liveWS' => array(),
315  // Subset of "versions" that exists in live workspace [Info]
316  'versions_lost_workspace' => array(),
317  // Subset of "versions" that doesn't belong to an existing workspace [Warning: Fix by move to live workspace]
318  'versions_inside_versioned_page' => array(),
319  // Subset of "versions" This is versions of elements found inside an already versioned branch / page. In real life this can work out, but is confusing and the backend should prevent this from happening to people. [Warning: Fix by deleting those versions (or publishing them)]
320  'illegal_record_under_versioned_page' => array(),
321  // If a page is "element" or "page" version and records are found attached to it, they might be illegally attached, so this will tell you. [Error: Fix by deleting orphans since they are not registered in "all" category]
322  'misplaced_at_rootlevel' => array(),
323  // Subset of "all": Those that should not be at root level but are. [Warning: Fix by moving record into page tree]
324  'misplaced_inside_tree' => array()
325  );
326  // Start traversal:
328  $this->performanceStatistics['genTree_traverse()'] = '';
329  $this->performanceStatistics['genTree_traverse():TraverseTables'] = '';
330  $this->genTree_traverse($rootID, $depth, $echoLevel, $callBack);
331  $this->performanceStatistics['genTree_traverse()'] = GeneralUtility::milliseconds() - $pt2;
332  // Sort recStats (for diff'able displays)
333  foreach ($this->recStats as $kk => $vv) {
334  foreach ($this->recStats[$kk] as $tables => $recArrays) {
335  ksort($this->recStats[$kk][$tables]);
336  }
337  ksort($this->recStats[$kk]);
338  }
339  if ($echoLevel > 0) {
340  echo LF . LF;
341  }
342  // Processing performance statistics:
343  $this->performanceStatistics['genTree()'] = GeneralUtility::milliseconds() - $pt;
344  // Count records:
345  foreach ($GLOBALS['TCA'] as $tableName => $cfg) {
346  // Select all records belonging to page:
347  $resSub = $GLOBALS['TYPO3_DB']->exec_SELECTquery('count(*)', $tableName, '');
348  $countRow = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($resSub);
349  $this->performanceStatistics['MySQL_count'][$tableName] = $countRow['count(*)'];
350  $this->performanceStatistics['CSV'] .= LF . $tableName . ',' . $this->performanceStatistics['genTree_traverse():TraverseTables:']['MySQL'][$tableName] . ',' . $this->performanceStatistics['genTree_traverse():TraverseTables:']['Proc'][$tableName] . ',' . $this->performanceStatistics['MySQL_count'][$tableName];
351  }
352  $this->performanceStatistics['recStats_size']['(ALL)'] = strlen(serialize($this->recStats));
353  foreach ($this->recStats as $key => $arrcontent) {
354  $this->performanceStatistics['recStats_size'][$key] = strlen(serialize($arrcontent));
355  }
356  }
357 
373  public function genTree_traverse($rootID, $depth, $echoLevel = 0, $callBack = '', $versionSwapmode = '', $rootIsVersion = 0, $accumulatedPath = '') {
374  // Register page:
375  $this->recStats['all']['pages'][$rootID] = $rootID;
376  $pageRecord = BackendUtility::getRecordRaw('pages', 'uid=' . (int)$rootID, 'deleted,title,t3ver_count,t3ver_wsid');
377  $accumulatedPath .= '/' . $pageRecord['title'];
378  // Register if page is deleted:
379  if ($pageRecord['deleted']) {
380  $this->recStats['deleted']['pages'][$rootID] = $rootID;
381  }
382  // 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.
383  if ($rootIsVersion) {
384  $this->recStats['versions']['pages'][$rootID] = $rootID;
385  // If it has been published and is in archive now...
386  if ($pageRecord['t3ver_count'] >= 1 && $pageRecord['t3ver_wsid'] == 0) {
387  $this->recStats['versions_published']['pages'][$rootID] = $rootID;
388  }
389  // If it has been published and is in archive now...
390  if ($pageRecord['t3ver_wsid'] == 0) {
391  $this->recStats['versions_liveWS']['pages'][$rootID] = $rootID;
392  }
393  // If it doesn't belong to a workspace...
394  if (!isset($this->workspaceIndex[$pageRecord['t3ver_wsid']])) {
395  $this->recStats['versions_lost_workspace']['pages'][$rootID] = $rootID;
396  }
397  // In case the rootID is a version inside a versioned page
398  if ($rootIsVersion == 2) {
399  $this->recStats['versions_inside_versioned_page']['pages'][$rootID] = $rootID;
400  }
401  }
402  if ($echoLevel > 0) {
403  echo LF . $accumulatedPath . ' [' . $rootID . ']' . ($pageRecord['deleted'] ? ' (DELETED)' : '') . ($this->recStats['versions_published']['pages'][$rootID] ? ' (PUBLISHED)' : '');
404  }
405  if ($echoLevel > 1 && $this->recStats['versions_lost_workspace']['pages'][$rootID]) {
406  echo LF . ' ERROR! This version belongs to non-existing workspace (' . $pageRecord['t3ver_wsid'] . ')!';
407  }
408  if ($echoLevel > 1 && $this->recStats['versions_inside_versioned_page']['pages'][$rootID]) {
409  echo LF . ' WARNING! This version is inside an already versioned page or branch!';
410  }
411  // Call back:
412  if ($callBack) {
413  $this->{$callBack}('pages', $rootID, $echoLevel, $versionSwapmode, $rootIsVersion);
414  }
416  // Traverse tables of records that belongs to page:
417  foreach ($GLOBALS['TCA'] as $tableName => $cfg) {
418  if ($tableName != 'pages') {
419  // Select all records belonging to page:
421  $resSub = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid' . ($GLOBALS['TCA'][$tableName]['ctrl']['delete'] ? ',' . $GLOBALS['TCA'][$tableName]['ctrl']['delete'] : ''), $tableName, 'pid=' . (int)$rootID . ($this->genTree_traverseDeleted ? '' : BackendUtility::deleteClause($tableName)));
422  $this->performanceStatistics['genTree_traverse():TraverseTables:']['MySQL']['(ALL)'] += GeneralUtility::milliseconds() - $pt4;
423  $this->performanceStatistics['genTree_traverse():TraverseTables:']['MySQL'][$tableName] += GeneralUtility::milliseconds() - $pt4;
425  $count = $GLOBALS['TYPO3_DB']->sql_num_rows($resSub);
426  if ($count) {
427  if ($echoLevel == 2) {
428  echo LF . ' \\-' . $tableName . ' (' . $count . ')';
429  }
430  }
431  while ($rowSub = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($resSub)) {
432  if ($echoLevel == 3) {
433  echo LF . ' \\-' . $tableName . ':' . $rowSub['uid'];
434  }
435  // 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:
436  if ($versionSwapmode == 'SWAPMODE:-1' || $versionSwapmode == 'SWAPMODE:0' && !$GLOBALS['TCA'][$tableName]['ctrl']['versioning_followPages']) {
437  // This is illegal records under a versioned page - therefore not registered in $this->recStats['all'] so they should be orphaned:
438  $this->recStats['illegal_record_under_versioned_page'][$tableName][$rowSub['uid']] = $rowSub['uid'];
439  if ($echoLevel > 1) {
440  echo LF . ' ERROR! Illegal record (' . $tableName . ':' . $rowSub['uid'] . ') under versioned page!';
441  }
442  } else {
443  $this->recStats['all'][$tableName][$rowSub['uid']] = $rowSub['uid'];
444  // Register deleted:
445  if ($GLOBALS['TCA'][$tableName]['ctrl']['delete'] && $rowSub[$GLOBALS['TCA'][$tableName]['ctrl']['delete']]) {
446  $this->recStats['deleted'][$tableName][$rowSub['uid']] = $rowSub['uid'];
447  if ($echoLevel == 3) {
448  echo ' (DELETED)';
449  }
450  }
451  // Check location of records regarding tree root:
452  if (!$GLOBALS['TCA'][$tableName]['ctrl']['rootLevel'] && $rootID == 0) {
453  $this->recStats['misplaced_at_rootlevel'][$tableName][$rowSub['uid']] = $rowSub['uid'];
454  if ($echoLevel > 1) {
455  echo LF . ' ERROR! Misplaced record (' . $tableName . ':' . $rowSub['uid'] . ') on rootlevel!';
456  }
457  }
458  if ($GLOBALS['TCA'][$tableName]['ctrl']['rootLevel'] == 1 && $rootID > 0) {
459  $this->recStats['misplaced_inside_tree'][$tableName][$rowSub['uid']] = $rowSub['uid'];
460  if ($echoLevel > 1) {
461  echo LF . ' ERROR! Misplaced record (' . $tableName . ':' . $rowSub['uid'] . ') inside page tree!';
462  }
463  }
464  // Traverse plugins:
465  if ($callBack) {
466  $this->{$callBack}($tableName, $rowSub['uid'], $echoLevel, $versionSwapmode, $rootIsVersion);
467  }
468  // Add any versions of those records:
469  if ($this->genTree_traverseVersions) {
470  $versions = BackendUtility::selectVersionsOfRecord($tableName, $rowSub['uid'], 'uid,t3ver_wsid,t3ver_count' . ($GLOBALS['TCA'][$tableName]['ctrl']['delete'] ? ',' . $GLOBALS['TCA'][$tableName]['ctrl']['delete'] : ''), NULL, TRUE);
471  if (is_array($versions)) {
472  foreach ($versions as $verRec) {
473  if (!$verRec['_CURRENT_VERSION']) {
474  if ($echoLevel == 3) {
475  echo LF . ' \\-[#OFFLINE VERSION: WS#' . $verRec['t3ver_wsid'] . '/Cnt:' . $verRec['t3ver_count'] . '] ' . $tableName . ':' . $verRec['uid'] . ')';
476  }
477  $this->recStats['all'][$tableName][$verRec['uid']] = $verRec['uid'];
478  // Register deleted:
479  if ($GLOBALS['TCA'][$tableName]['ctrl']['delete'] && $verRec[$GLOBALS['TCA'][$tableName]['ctrl']['delete']]) {
480  $this->recStats['deleted'][$tableName][$verRec['uid']] = $verRec['uid'];
481  if ($echoLevel == 3) {
482  echo ' (DELETED)';
483  }
484  }
485  // Register version:
486  $this->recStats['versions'][$tableName][$verRec['uid']] = $verRec['uid'];
487  if ($verRec['t3ver_count'] >= 1 && $verRec['t3ver_wsid'] == 0) {
488  // Only register published versions in LIVE workspace (published versions in draft workspaces are allowed)
489  $this->recStats['versions_published'][$tableName][$verRec['uid']] = $verRec['uid'];
490  if ($echoLevel == 3) {
491  echo ' (PUBLISHED)';
492  }
493  }
494  if ($verRec['t3ver_wsid'] == 0) {
495  $this->recStats['versions_liveWS'][$tableName][$verRec['uid']] = $verRec['uid'];
496  }
497  if (!isset($this->workspaceIndex[$verRec['t3ver_wsid']])) {
498  $this->recStats['versions_lost_workspace'][$tableName][$verRec['uid']] = $verRec['uid'];
499  if ($echoLevel > 1) {
500  echo LF . ' ERROR! Version (' . $tableName . ':' . $verRec['uid'] . ') belongs to non-existing workspace (' . $verRec['t3ver_wsid'] . ')!';
501  }
502  }
503  // In case we are inside a versioned branch, there should not exists versions inside that "branch".
504  if ($versionSwapmode) {
505  $this->recStats['versions_inside_versioned_page'][$tableName][$verRec['uid']] = $verRec['uid'];
506  if ($echoLevel > 1) {
507  echo LF . ' ERROR! This version (' . $tableName . ':' . $verRec['uid'] . ') is inside an already versioned page or branch!';
508  }
509  }
510  // Traverse plugins:
511  if ($callBack) {
512  $this->{$callBack}($tableName, $verRec['uid'], $echoLevel, $versionSwapmode, $rootIsVersion);
513  }
514  }
515  }
516  }
517  unset($versions);
518  }
519  }
520  }
521  $this->performanceStatistics['genTree_traverse():TraverseTables:']['Proc']['(ALL)'] += GeneralUtility::milliseconds() - $pt5;
522  $this->performanceStatistics['genTree_traverse():TraverseTables:']['Proc'][$tableName] += GeneralUtility::milliseconds() - $pt5;
523  }
524  }
525  unset($resSub);
526  unset($rowSub);
527  $this->performanceStatistics['genTree_traverse():TraverseTables'] += GeneralUtility::milliseconds() - $pt3;
528  // Find subpages to root ID and traverse (only when rootID is not a version or is a branch-version):
529  if (!$versionSwapmode || $versionSwapmode == 'SWAPMODE:1') {
530  if ($depth > 0) {
531  $depth--;
532  $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid', 'pages', 'pid=' . (int)$rootID . ($this->genTree_traverseDeleted ? '' : BackendUtility::deleteClause('pages')), '', 'sorting');
533  while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
534  $this->genTree_traverse($row['uid'], $depth, $echoLevel, $callBack, $versionSwapmode, 0, $accumulatedPath);
535  }
536  }
537  // Add any versions of pages
538  if ($rootID > 0 && $this->genTree_traverseVersions) {
539  $versions = BackendUtility::selectVersionsOfRecord('pages', $rootID, 'uid,t3ver_oid,t3ver_wsid,t3ver_count', NULL, TRUE);
540  if (is_array($versions)) {
541  foreach ($versions as $verRec) {
542  if (!$verRec['_CURRENT_VERSION']) {
543  $this->genTree_traverse($verRec['uid'], $depth, $echoLevel, $callBack, 'SWAPMODE:-1', $versionSwapmode ? 2 : 1, $accumulatedPath . ' [#OFFLINE VERSION: WS#' . $verRec['t3ver_wsid'] . '/Cnt:' . $verRec['t3ver_count'] . ']');
544  }
545  }
546  }
547  }
548  }
549  }
550 
551  /**************************
552  *
553  * Helper functions
554  *
555  *************************/
563  public function infoStr($rec) {
564  return $rec['tablename'] . ':' . $rec['recuid'] . ':' . $rec['field'] . ':' . $rec['flexpointer'] . ':' . $rec['softref_key'] . ($rec['deleted'] ? ' (DELETED)' : '');
565  }
566 
567 }
static forceIntegerInRange($theInt, $min, $max=2000000000, $defaultValue=0)
Definition: MathUtility.php:32
static getUserObj($classRef, $checkPrefix='', $silent=FALSE)
die
Definition: index.php:6
static getUrl($url, $includeHeader=0, $requestHeaders=FALSE, &$report=NULL)
static getRecordRaw($table, $where='', $fields=' *')
static selectVersionsOfRecord($table, $uid, $fields=' *', $workspace=0, $includeDeletedRecords=FALSE, $row=NULL)
genTree($rootID, $depth=1000, $echoLevel=0, $callBack='')
if(!defined('TYPO3_MODE')) $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_userauth.php']['logoff_pre_processing'][]
static deleteClause($table, $tableAlias='')
genTree_traverse($rootID, $depth, $echoLevel=0, $callBack='', $versionSwapmode='', $rootIsVersion=0, $accumulatedPath='')