‪TYPO3CMS  ‪main
DatabaseIntegrityCheck.php
Go to the documentation of this file.
1 <?php
2 
3 /*
4  * This file is part of the TYPO3 CMS project.
5  *
6  * It is free software; you can redistribute it and/or modify it under
7  * the terms of the GNU General Public License, either version 2
8  * of the License, or any later version.
9  *
10  * For the full copyright and license information, please read the
11  * LICENSE.txt file that was distributed with this source code.
12  *
13  * The TYPO3 project - inspiring people to share!
14  */
15 
17 
18 use Doctrine\DBAL\Types\Type;
19 use Doctrine\DBAL\Types\Types;
20 use TYPO3\CMS\Backend\Utility\BackendUtility;
28 
43 {
47  protected ‪$genTreeIncludeDeleted = true;
48 
52  protected ‪$genTreeIncludeVersions = true;
53 
57  protected ‪$genTreeIncludeRecords = false;
58 
62  protected ‪$pageIdArray = [];
63 
67  protected ‪$pageTranslatedPageIDArray = [];
68 
72  protected ‪$recIdArray = [];
73 
77  protected ‪$checkSelectDBRefs = [];
78 
82  protected ‪$checkGroupDBRefs = [];
83 
87  protected ‪$recStats = [
88  'allValid' => [],
89  'published_versions' => [],
90  'deleted' => [],
91  ];
92 
96  protected ‪$lRecords = [];
97 
101  protected ‪$lostPagesList = '';
102 
103  public function ‪getPageTranslatedPageIDArray(): array
104  {
106  }
107 
115  public function ‪genTree($theID, $versions = false)
116  {
117  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('pages');
118  $queryBuilder->getRestrictions()->removeAll();
119  if (!$this->genTreeIncludeDeleted) {
120  $queryBuilder->getRestrictions()->add(GeneralUtility::makeInstance(DeletedRestriction::class));
121  }
122  $queryBuilder->select('uid', 'title', 'doktype', 'deleted', 'hidden', 'sys_language_uid')
123  ->from('pages')
124  ->orderBy('sorting');
125  if ($versions) {
126  $queryBuilder->addSelect('t3ver_wsid');
127  $queryBuilder->where(
128  $queryBuilder->expr()->eq('t3ver_oid', $queryBuilder->createNamedParameter($theID, ‪Connection::PARAM_INT))
129  );
130  } else {
131  $queryBuilder->where(
132  $queryBuilder->expr()->eq('pid', $queryBuilder->createNamedParameter($theID, ‪Connection::PARAM_INT))
133  );
134  }
135  $result = $queryBuilder->executeQuery();
136  // Traverse the records selected
137  while ($row = $result->fetchAssociative()) {
138  $newID = $row['uid'];
139  // Register various data for this item:
140  if ($row['sys_language_uid'] === 0) {
141  $this->pageIdArray[$newID] = $row;
142  } else {
143  $this->pageTranslatedPageIDArray[$newID] = $row;
144  }
145  $this->recStats['all_valid']['pages'][$newID] = $newID;
146  if ($row['deleted']) {
147  $this->recStats['deleted']['pages'][$newID] = $newID;
148  }
149 
150  if (!isset($this->recStats['hidden'])) {
151  $this->recStats['hidden'] = 0;
152  }
153 
154  if ($row['hidden']) {
155  $this->recStats['hidden']++;
156  }
157 
158  $this->recStats['doktype'][$row['doktype']] ??= 0;
159  $this->recStats['doktype'][$row['doktype']]++;
160  // If all records should be shown, do so:
161  if ($this->genTreeIncludeRecords) {
162  foreach (‪$GLOBALS['TCA'] as $tableName => $cfg) {
163  if ($tableName !== 'pages') {
164  $this->‪genTree_records($newID, $tableName);
165  }
166  }
167  }
168  // Add sub pages:
169  $this->‪genTree($newID);
170  // If versions are included in the tree, add those now:
171  if ($this->genTreeIncludeVersions) {
172  $this->‪genTree($newID, true);
173  }
174  }
175  }
176 
182  public function ‪genTree_records($theID, $table, $versions = false): void
183  {
184  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($table);
185  $queryBuilder->getRestrictions()->removeAll();
186  if (!$this->genTreeIncludeDeleted) {
187  $queryBuilder->getRestrictions()->add(GeneralUtility::makeInstance(DeletedRestriction::class));
188  }
189  $queryBuilder
190  ->select(...explode(',', BackendUtility::getCommonSelectFields($table)))
191  ->from($table);
192 
193  // Select all records from table pointing to this page
194  if ($versions) {
195  $queryBuilder->where(
196  $queryBuilder->expr()->eq('t3ver_oid', $queryBuilder->createNamedParameter($theID, ‪Connection::PARAM_INT))
197  );
198  } else {
199  $queryBuilder->where(
200  $queryBuilder->expr()->eq('pid', $queryBuilder->createNamedParameter($theID, ‪Connection::PARAM_INT))
201  );
202  }
203  $queryResult = $queryBuilder->executeQuery();
204  // Traverse selected
205  while ($row = $queryResult->fetchAssociative()) {
206  $newID = $row['uid'];
207  // Register various data for this item:
208  $this->recIdArray[$table][$newID] = $row;
209  $this->recStats['all_valid'][$table][$newID] = $newID;
210  if ($row['deleted']) {
211  $this->recStats['deleted'][$table][$newID] = $newID;
212  }
213  // Select all versions of this record:
214  if ($this->genTreeIncludeVersions && BackendUtility::isTableWorkspaceEnabled($table)) {
215  $this->‪genTree_records($newID, $table, true);
216  }
217  }
218  }
219 
225  public function ‪lostRecords($pid_list): void
226  {
227  $this->lostPagesList = '';
228  $pageIds = ‪GeneralUtility::intExplode(',', $pid_list);
229  if (is_array($pageIds)) {
230  foreach (‪$GLOBALS['TCA'] as $table => $tableConf) {
231  $pageIdsForTable = $pageIds;
232  // Remove preceding "-1," for non-versioned tables
233  if (!BackendUtility::isTableWorkspaceEnabled($table)) {
234  $pageIdsForTable = array_combine($pageIdsForTable, $pageIdsForTable);
235  unset($pageIdsForTable[-1]);
236  }
237  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($table);
238  $queryBuilder->getRestrictions()->removeAll();
239  $selectFields = ['uid', 'pid'];
240  if (!empty(‪$GLOBALS['TCA'][$table]['ctrl']['label'])) {
241  $selectFields[] = ‪$GLOBALS['TCA'][$table]['ctrl']['label'];
242  }
243  $queryResult = $queryBuilder->select(...$selectFields)
244  ->from($table)
245  ->where(
246  $queryBuilder->expr()->notIn(
247  'pid',
248  $queryBuilder->createNamedParameter($pageIdsForTable, ‪Connection::PARAM_INT_ARRAY)
249  )
250  )
251  ->executeQuery();
252  $lostIdList = [];
253  while ($row = $queryResult->fetchAssociative()) {
254  $this->lRecords[$table][$row['uid']] = [
255  'uid' => $row['uid'],
256  'pid' => $row['pid'],
257  'title' => strip_tags(BackendUtility::getRecordTitle($table, $row)),
258  ];
259  $lostIdList[] = $row['uid'];
260  }
261  if ($table === 'pages') {
262  $this->lostPagesList = implode(',', $lostIdList);
263  }
264  }
265  }
266  }
267 
276  public function ‪fixLostRecord($table, ‪$uid): bool
277  {
278  if ($table && ‪$GLOBALS['TCA'][$table] && ‪$uid && is_array($this->lRecords[$table][‪$uid]) && ‪$GLOBALS['BE_USER']->isAdmin()) {
279  $updateFields = [
280  'pid' => 0,
281  ];
282  // If possible a lost record restored is hidden as default
283  if (‪$GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['disabled']) {
284  $updateFields[‪$GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['disabled']] = 1;
285  }
286  GeneralUtility::makeInstance(ConnectionPool::class)
287  ->getConnectionForTable($table)
288  ->update($table, $updateFields, ['uid' => (int)‪$uid]);
289  return true;
290  }
291  return false;
292  }
293 
300  public function ‪countRecords($pid_list): array
301  {
302  $list = [];
303  $list_n = [];
304  $pageIds = ‪GeneralUtility::intExplode(',', $pid_list);
305  if (!empty($pageIds)) {
306  foreach (‪$GLOBALS['TCA'] as $table => $tableConf) {
307  $pageIdsForTable = $pageIds;
308  // Remove preceding "-1," for non-versioned tables
309  if (!BackendUtility::isTableWorkspaceEnabled($table)) {
310  $pageIdsForTable = array_combine($pageIdsForTable, $pageIdsForTable);
311  unset($pageIdsForTable[-1]);
312  }
313  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($table);
314  $queryBuilder->getRestrictions()->removeAll();
315  $count = $queryBuilder->count('uid')
316  ->from($table)
317  ->where(
318  $queryBuilder->expr()->in(
319  'pid',
320  $queryBuilder->createNamedParameter($pageIds, ‪Connection::PARAM_INT_ARRAY)
321  )
322  )
323  ->executeQuery()
324  ->fetchOne();
325  if ($count) {
326  $list[$table] = $count;
327  }
328 
329  // same query excluding all deleted records
330  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($table);
331  $queryBuilder->getRestrictions()
332  ->removeAll()
333  ->add(GeneralUtility::makeInstance(DeletedRestriction::class));
334  $count = $queryBuilder->count('uid')
335  ->from($table)
336  ->where(
337  $queryBuilder->expr()->in(
338  'pid',
339  $queryBuilder->createNamedParameter($pageIdsForTable, ‪Connection::PARAM_INT_ARRAY)
340  )
341  )
342  ->executeQuery()
343  ->fetchOne();
344  if ($count) {
345  $list_n[$table] = $count;
346  }
347  }
348  }
349  return ['all' => $list, 'non_deleted' => $list_n];
350  }
351 
357  public function ‪getGroupFields(): array
358  {
359  $result = [];
360  foreach (‪$GLOBALS['TCA'] as $table => $tableConf) {
361  $cols = ‪$GLOBALS['TCA'][$table]['columns'];
362  foreach ($cols as $field => $config) {
363  $fieldType = $config['config']['type'] ?? '';
364  if ($fieldType === 'group') {
365  $result[$table][] = $field;
366  }
367  if (($fieldType === 'select' || $fieldType === 'category')
368  && ($config['config']['foreign_table'] ?? false)
369  ) {
370  $result[$table][] = $field;
371  }
372  }
373  }
374  return $result;
375  }
376 
382  public function ‪selectNonEmptyRecordsWithFkeys(): void
383  {
384  $fkey_arrays = $this->‪getGroupFields();
385  $connectionPool = GeneralUtility::makeInstance(ConnectionPool::class);
386  foreach ($fkey_arrays as $table => ‪$fields) {
387  $connection = $connectionPool->getConnectionForTable($table);
388  $schemaManager = $connection->createSchemaManager();
389  $tableColumns = $schemaManager->listTableColumns($table);
390 
391  $queryBuilder = $connectionPool->getQueryBuilderForTable($table);
392  $queryBuilder->getRestrictions()->removeAll();
393 
394  $queryBuilder->select('*')
395  ->from($table);
396  $whereClause = [];
397 
398  foreach (‪$fields as $fieldName) {
399  // The array index of $tableColumns is the lowercased column name!
400  // It is quoted for keywords
401  $column = $tableColumns[strtolower($fieldName)]
402  ?? $tableColumns[$connection->quoteIdentifier(strtolower($fieldName))]
403  ?? '';
404  if (empty($column)) {
405  // Throw meaningful exception if field does not exist in DB - 'none' is not filtered here since the
406  // method is only called with type=group fields
407  throw new \RuntimeException(
408  'Field ' . $fieldName . ' for table ' . $table . ' has been defined in TCA, but does not exist in DB',
409  1536248937
410  );
411  }
412  $fieldType = Type::getTypeRegistry()->lookupName($column->getType());
413  if (in_array(
414  $fieldType,
415  [Types::BIGINT, Types::INTEGER, Types::SMALLINT, Types::DECIMAL, Types::FLOAT],
416  true
417  )) {
418  $whereClause[] = $queryBuilder->expr()->and(
419  $queryBuilder->expr()->isNotNull($fieldName),
420  $queryBuilder->expr()->neq(
421  $fieldName,
422  $queryBuilder->createNamedParameter(0, ‪Connection::PARAM_INT)
423  )
424  );
425  } elseif (in_array($fieldType, [Types::STRING, Types::TEXT], true)) {
426  $whereClause[] = $queryBuilder->expr()->and(
427  $queryBuilder->expr()->isNotNull($fieldName),
428  $queryBuilder->expr()->neq(
429  $fieldName,
430  $queryBuilder->createNamedParameter('')
431  )
432  );
433  } elseif ($fieldType === Types::BLOB) {
434  $whereClause[] = $queryBuilder->expr()->and(
435  $queryBuilder->expr()->isNotNull($fieldName),
436  $queryBuilder->expr()
437  ->comparison(
438  $queryBuilder->expr()->length($fieldName),
439  ExpressionBuilder::GT,
440  $queryBuilder->createNamedParameter(0, ‪Connection::PARAM_INT)
441  )
442  );
443  }
444  }
445  $queryResult = $queryBuilder->orWhere(...$whereClause)->executeQuery();
446 
447  while ($row = $queryResult->fetchAssociative()) {
448  foreach (‪$fields as $field) {
449  if (trim($row[$field] ?? '')) {
450  $fieldConf = ‪$GLOBALS['TCA'][$table]['columns'][$field]['config'];
451  if ($fieldConf['type'] === 'group' && !empty($fieldConf['allowed'])) {
452  $dbAnalysis = GeneralUtility::makeInstance(RelationHandler::class);
453  $dbAnalysis->start(
454  $row[$field],
455  $fieldConf['allowed'],
456  $fieldConf['MM'] ?? null,
457  $row['uid'],
458  $table,
459  $fieldConf
460  );
461  foreach ($dbAnalysis->itemArray as $tempArr) {
462  if (!isset($this->checkGroupDBRefs[$tempArr['table']][$tempArr['id']])) {
463  $this->checkGroupDBRefs[$tempArr['table']][$tempArr['id']] = 0;
464  }
465  $this->checkGroupDBRefs[$tempArr['table']][$tempArr['id']] += 1;
466  }
467  }
468  if (($fieldConf['foreign_table'] ?? false)
469  && ($fieldConf['type'] === 'select' || $fieldConf['type'] === 'category')
470  ) {
471  $dbAnalysis = GeneralUtility::makeInstance(RelationHandler::class);
472  $dbAnalysis->start(
473  $row[$field],
474  $fieldConf['foreign_table'],
475  $fieldConf['MM'] ?? null,
476  $row['uid'],
477  $table,
478  $fieldConf
479  );
480  foreach ($dbAnalysis->itemArray as $tempArr) {
481  if ($tempArr['id'] > 0) {
482  if (!isset($this->checkSelectDBRefs[$fieldConf['foreign_table']][$tempArr['id']])) {
483  $this->checkSelectDBRefs[$fieldConf['foreign_table']][$tempArr['id']] = 0;
484  }
485  $this->checkSelectDBRefs[$fieldConf['foreign_table']][$tempArr['id']] += 1;
486  }
487  }
488  }
489  }
490  }
491  }
492  }
493  }
494 
501  public function ‪testDBRefs($theArray): string
502  {
503  $rows = [];
504  foreach ($theArray as $table => $dbArr) {
505  if (‪$GLOBALS['TCA'][$table]) {
506  $ids = array_keys($dbArr);
507  if (!empty($ids)) {
508  $connection = GeneralUtility::makeInstance(ConnectionPool::class)
509  ->getConnectionForTable($table);
510 
511  $maxBindParameters = ‪PlatformInformation::getMaxBindParameters($connection->getDatabasePlatform());
512 
513  foreach (array_chunk($ids, $maxBindParameters, true) as $chunk) {
514  $queryBuilder = $connection->createQueryBuilder();
515  $queryBuilder->getRestrictions()
516  ->removeAll()
517  ->add(GeneralUtility::makeInstance(DeletedRestriction::class));
518  $queryResult = $queryBuilder
519  ->select('uid')
520  ->from($table)
521  ->where(
522  $queryBuilder->expr()->in(
523  'uid',
524  $queryBuilder->createNamedParameter($chunk, ‪Connection::PARAM_INT_ARRAY)
525  )
526  )
527  ->executeQuery();
528  while ($row = $queryResult->fetchAssociative()) {
529  if (isset($dbArr[$row['uid']])) {
530  unset($dbArr[$row['uid']]);
531  } else {
532  $rows[] = 'Strange Error. ...';
533  }
534  }
535  }
536 
537  foreach ($dbArr as $theId => $theC) {
538  $rows[] = 'There are ' . $theC . ' records pointing to this missing or deleted record: <code>[' . $table . '][' . $theId . ']</code>';
539  }
540  }
541  } else {
542  $rows[] = 'Codeerror. Table is not a table...';
543  }
544  }
545 
546  return $rows !== [] ? '<ul class="list-unstyled" role="list">' . implode(LF, array_map(static fn(string $row): string => '<li>' . $row . '</li>', $rows)) . '</ul>' : '';
547  }
548 
549  public function ‪getPageIdArray(): array
550  {
552  }
553 
554  public function ‪getCheckGroupDBRefs(): array
555  {
557  }
558 
559  public function ‪getCheckSelectDBRefs(): array
560  {
562  }
563 
564  public function ‪getRecStats(): array
565  {
567  }
568 
569  public function ‪getLRecords(): array
570  {
571  return ‪$this->lRecords;
572  }
573 
574  public function ‪getLostPagesList(): string
575  {
577  }
578 }
‪TYPO3\CMS\Lowlevel\Integrity
Definition: DatabaseIntegrityCheck.php:16
‪TYPO3\CMS\Core\Database\Connection\PARAM_INT
‪const PARAM_INT
Definition: Connection.php:52
‪TYPO3\CMS\Core\Database\Query\Expression\ExpressionBuilder
Definition: ExpressionBuilder.php:40
‪TYPO3\CMS\Lowlevel\Integrity\DatabaseIntegrityCheck\$pageTranslatedPageIDArray
‪$pageTranslatedPageIDArray
Definition: DatabaseIntegrityCheck.php:65
‪TYPO3\CMS\Core\Database\Platform\PlatformInformation\getMaxBindParameters
‪static getMaxBindParameters(DoctrineAbstractPlatform $platform)
Definition: PlatformInformation.php:106
‪TYPO3\CMS\Lowlevel\Integrity\DatabaseIntegrityCheck\genTree
‪genTree($theID, $versions=false)
Definition: DatabaseIntegrityCheck.php:107
‪TYPO3\CMS\Lowlevel\Integrity\DatabaseIntegrityCheck\getPageIdArray
‪getPageIdArray()
Definition: DatabaseIntegrityCheck.php:541
‪TYPO3\CMS\Lowlevel\Integrity\DatabaseIntegrityCheck\getRecStats
‪getRecStats()
Definition: DatabaseIntegrityCheck.php:556
‪TYPO3\CMS\Core\Database\RelationHandler
Definition: RelationHandler.php:36
‪TYPO3\CMS\Lowlevel\Integrity\DatabaseIntegrityCheck\getLostPagesList
‪getLostPagesList()
Definition: DatabaseIntegrityCheck.php:566
‪TYPO3\CMS\Lowlevel\Integrity\DatabaseIntegrityCheck\getGroupFields
‪array getGroupFields()
Definition: DatabaseIntegrityCheck.php:349
‪$fields
‪$fields
Definition: pages.php:5
‪TYPO3\CMS\Lowlevel\Integrity\DatabaseIntegrityCheck\$lRecords
‪array $lRecords
Definition: DatabaseIntegrityCheck.php:89
‪TYPO3\CMS\Lowlevel\Integrity\DatabaseIntegrityCheck\$genTreeIncludeRecords
‪bool $genTreeIncludeRecords
Definition: DatabaseIntegrityCheck.php:55
‪TYPO3\CMS\Lowlevel\Integrity\DatabaseIntegrityCheck\$checkGroupDBRefs
‪array $checkGroupDBRefs
Definition: DatabaseIntegrityCheck.php:77
‪TYPO3\CMS\Lowlevel\Integrity\DatabaseIntegrityCheck\$pageIdArray
‪$pageIdArray
Definition: DatabaseIntegrityCheck.php:60
‪TYPO3\CMS\Lowlevel\Integrity\DatabaseIntegrityCheck\countRecords
‪array countRecords($pid_list)
Definition: DatabaseIntegrityCheck.php:292
‪TYPO3\CMS\Lowlevel\Integrity\DatabaseIntegrityCheck\fixLostRecord
‪bool fixLostRecord($table, $uid)
Definition: DatabaseIntegrityCheck.php:268
‪TYPO3\CMS\Lowlevel\Integrity\DatabaseIntegrityCheck\$genTreeIncludeDeleted
‪bool $genTreeIncludeDeleted
Definition: DatabaseIntegrityCheck.php:46
‪TYPO3\CMS\Lowlevel\Integrity\DatabaseIntegrityCheck\lostRecords
‪lostRecords($pid_list)
Definition: DatabaseIntegrityCheck.php:217
‪TYPO3\CMS\Lowlevel\Integrity\DatabaseIntegrityCheck\genTree_records
‪genTree_records($theID, $table, $versions=false)
Definition: DatabaseIntegrityCheck.php:174
‪TYPO3\CMS\Lowlevel\Integrity\DatabaseIntegrityCheck\getLRecords
‪getLRecords()
Definition: DatabaseIntegrityCheck.php:561
‪TYPO3\CMS\Lowlevel\Integrity\DatabaseIntegrityCheck\getCheckSelectDBRefs
‪getCheckSelectDBRefs()
Definition: DatabaseIntegrityCheck.php:551
‪TYPO3\CMS\Lowlevel\Integrity\DatabaseIntegrityCheck\$checkSelectDBRefs
‪array $checkSelectDBRefs
Definition: DatabaseIntegrityCheck.php:73
‪TYPO3\CMS\Lowlevel\Integrity\DatabaseIntegrityCheck\selectNonEmptyRecordsWithFkeys
‪selectNonEmptyRecordsWithFkeys()
Definition: DatabaseIntegrityCheck.php:374
‪TYPO3\CMS\Lowlevel\Integrity\DatabaseIntegrityCheck\getCheckGroupDBRefs
‪getCheckGroupDBRefs()
Definition: DatabaseIntegrityCheck.php:546
‪TYPO3\CMS\Lowlevel\Integrity\DatabaseIntegrityCheck\testDBRefs
‪string testDBRefs($theArray)
Definition: DatabaseIntegrityCheck.php:493
‪TYPO3\CMS\Core\Database\Connection
Definition: Connection.php:41
‪TYPO3\CMS\Lowlevel\Integrity\DatabaseIntegrityCheck
Definition: DatabaseIntegrityCheck.php:43
‪TYPO3\CMS\Webhooks\Message\$uid
‪identifier readonly int $uid
Definition: PageModificationMessage.php:35
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction
Definition: DeletedRestriction.php:28
‪TYPO3\CMS\Lowlevel\Integrity\DatabaseIntegrityCheck\$recStats
‪array $recStats
Definition: DatabaseIntegrityCheck.php:81
‪TYPO3\CMS\Core\Database\Platform\PlatformInformation
Definition: PlatformInformation.php:33
‪TYPO3\CMS\Lowlevel\Integrity\DatabaseIntegrityCheck\getPageTranslatedPageIDArray
‪getPageTranslatedPageIDArray()
Definition: DatabaseIntegrityCheck.php:95
‪TYPO3\CMS\Lowlevel\Integrity\DatabaseIntegrityCheck\$lostPagesList
‪string $lostPagesList
Definition: DatabaseIntegrityCheck.php:93
‪TYPO3\CMS\Core\Database\ConnectionPool
Definition: ConnectionPool.php:46
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:52
‪TYPO3\CMS\Core\Utility\GeneralUtility\intExplode
‪static list< int > intExplode(string $delimiter, string $string, bool $removeEmptyValues=false)
Definition: GeneralUtility.php:756
‪TYPO3\CMS\Core\Database\Connection\PARAM_INT_ARRAY
‪const PARAM_INT_ARRAY
Definition: Connection.php:72
‪TYPO3\CMS\Lowlevel\Integrity\DatabaseIntegrityCheck\$genTreeIncludeVersions
‪$genTreeIncludeVersions
Definition: DatabaseIntegrityCheck.php:51
‪TYPO3\CMS\Lowlevel\Integrity\DatabaseIntegrityCheck\$recIdArray
‪array $recIdArray
Definition: DatabaseIntegrityCheck.php:69