‪TYPO3CMS  9.5
DatabaseIntegrityCheck.php
Go to the documentation of this file.
1 <?php
3 
4 /*
5  * This file is part of the TYPO3 CMS project.
6  *
7  * It is free software; you can redistribute it and/or modify it under
8  * the terms of the GNU General Public License, either version 2
9  * of the License, or any later version.
10  *
11  * For the full copyright and license information, please read the
12  * LICENSE.txt file that was distributed with this source code.
13  *
14  * The TYPO3 project - inspiring people to share!
15  */
16 
17 use Doctrine\DBAL\Types\Types;
27 
41 {
45  protected ‪$genTreeIncludeDeleted = true;
46 
50  protected ‪$genTreeIncludeVersions = true;
51 
55  protected ‪$genTreeIncludeRecords = false;
56 
60  protected ‪$pageIdArray = [];
61 
65  protected ‪$pageTranslatedPageIDArray = [];
66 
70  protected ‪$recIdArray = [];
71 
75  protected ‪$checkFileRefs = [];
76 
80  protected ‪$checkSelectDBRefs = [];
81 
85  protected ‪$checkGroupDBRefs = [];
86 
90  protected ‪$recStats = [
91  'allValid' => [],
92  'published_versions' => [],
93  'deleted' => []
94  ];
95 
99  protected ‪$lRecords = [];
100 
104  protected ‪$lostPagesList = '';
105 
109  public function ‪getPageTranslatedPageIDArray(): array
110  {
112  }
113 
122  public function ‪genTree($theID, $depthData = '', $versions = false)
123  {
124  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('pages');
125  $queryBuilder->getRestrictions()->removeAll();
126  if (!$this->genTreeIncludeDeleted) {
127  $queryBuilder->getRestrictions()->add(GeneralUtility::makeInstance(DeletedRestriction::class));
128  }
129  $queryBuilder->select('uid', 'title', 'doktype', 'deleted', 'hidden', 'sys_language_uid')
130  ->from('pages')
131  ->orderBy('sorting');
132  if ($versions) {
133  $queryBuilder->addSelect('t3ver_wsid', 't3ver_id', 't3ver_count');
134  $queryBuilder->where(
135  $queryBuilder->expr()->eq('pid', $queryBuilder->createNamedParameter(-1, \PDO::PARAM_INT)),
136  $queryBuilder->expr()->eq('t3ver_oid', $queryBuilder->createNamedParameter($theID, \PDO::PARAM_INT))
137  );
138  } else {
139  $queryBuilder->where(
140  $queryBuilder->expr()->eq('pid', $queryBuilder->createNamedParameter($theID, \PDO::PARAM_INT))
141  );
142  }
143  $result = $queryBuilder->execute();
144  // Traverse the records selected
145  while ($row = $result->fetch()) {
146  $newID = $row['uid'];
147  // Register various data for this item:
148  if ($row['sys_language_uid'] === 0) {
149  $this->pageIdArray[$newID] = $row;
150  } else {
151  $this->pageTranslatedPageIDArray[$newID] = $row;
152  }
153  $this->recStats['all_valid']['pages'][$newID] = $newID;
154  if ($row['deleted']) {
155  $this->recStats['deleted']['pages'][$newID] = $newID;
156  }
157  if ($versions && $row['t3ver_count'] >= 1) {
158  $this->recStats['published_versions']['pages'][$newID] = $newID;
159  }
160  if ($row['deleted']) {
161  $this->recStats['deleted']++;
162  }
163  if ($row['hidden']) {
164  $this->recStats['hidden']++;
165  }
166  $this->recStats['doktype'][$row['doktype']]++;
167  // If all records should be shown, do so:
168  if ($this->genTreeIncludeRecords) {
169  foreach (‪$GLOBALS['TCA'] as $tableName => $cfg) {
170  if ($tableName !== 'pages') {
171  $this->‪genTree_records($newID, '', $tableName);
172  }
173  }
174  }
175  // Add sub pages:
176  $this->‪genTree($newID);
177  // If versions are included in the tree, add those now:
178  if ($this->genTreeIncludeVersions) {
179  $this->‪genTree($newID, '', true);
180  }
181  }
182  }
183 
190  public function ‪genTree_records($theID, $_ = '', $table = '', $versions = false): void
191  {
192  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($table);
193  $queryBuilder->getRestrictions()->removeAll();
194  if (!$this->genTreeIncludeDeleted) {
195  $queryBuilder->getRestrictions()->add(GeneralUtility::makeInstance(DeletedRestriction::class));
196  }
197  $queryBuilder
198  ->select(...explode(',', ‪BackendUtility::getCommonSelectFields($table)))
199  ->from($table);
200 
201  // Select all records from table pointing to this page
202  if ($versions) {
203  $queryBuilder->where(
204  $queryBuilder->expr()->eq('pid', $queryBuilder->createNamedParameter(-1, \PDO::PARAM_INT)),
205  $queryBuilder->expr()->eq('t3ver_oid', $queryBuilder->createNamedParameter($theID, \PDO::PARAM_INT))
206  );
207  } else {
208  $queryBuilder->where(
209  $queryBuilder->expr()->eq('pid', $queryBuilder->createNamedParameter($theID, \PDO::PARAM_INT))
210  );
211  }
212  $queryResult = $queryBuilder->execute();
213  // Traverse selected
214  while ($row = $queryResult->fetch()) {
215  $newID = $row['uid'];
216  // Register various data for this item:
217  $this->recIdArray[$table][$newID] = $row;
218  $this->recStats['all_valid'][$table][$newID] = $newID;
219  if ($row['deleted']) {
220  $this->recStats['deleted'][$table][$newID] = $newID;
221  }
222  if ($versions && $row['t3ver_count'] >= 1 && $row['t3ver_wsid'] == 0) {
223  $this->recStats['published_versions'][$table][$newID] = $newID;
224  }
225  // Select all versions of this record:
226  if ($this->genTreeIncludeVersions && ‪$GLOBALS['TCA'][$table]['ctrl']['versioningWS']) {
227  $this->‪genTree_records($newID, '', $table, true);
228  }
229  }
230  }
231 
237  public function ‪lostRecords($pid_list): void
238  {
239  $this->lostPagesList = '';
240  $pageIds = GeneralUtility::intExplode(',', $pid_list);
241  if (is_array($pageIds)) {
242  foreach (‪$GLOBALS['TCA'] as $table => $tableConf) {
243  $pageIdsForTable = $pageIds;
244  // Remove preceding "-1," for non-versioned tables
246  $pageIdsForTable = array_combine($pageIdsForTable, $pageIdsForTable);
247  unset($pageIdsForTable[-1]);
248  }
249  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($table);
250  $queryBuilder->getRestrictions()->removeAll();
251  $selectFields = ['uid', 'pid'];
252  if (!empty(‪$GLOBALS['TCA'][$table]['ctrl']['label'])) {
253  $selectFields[] = ‪$GLOBALS['TCA'][$table]['ctrl']['label'];
254  }
255  $queryResult = $queryBuilder->select(...$selectFields)
256  ->from($table)
257  ->where(
258  $queryBuilder->expr()->notIn(
259  'pid',
260  $queryBuilder->createNamedParameter($pageIdsForTable, Connection::PARAM_INT_ARRAY)
261  )
262  )
263  ->execute();
264  $lostIdList = [];
265  while ($row = $queryResult->fetch()) {
266  $this->lRecords[$table][$row['uid']] = [
267  'uid' => $row['uid'],
268  'pid' => $row['pid'],
269  'title' => strip_tags(‪BackendUtility::getRecordTitle($table, $row))
270  ];
271  $lostIdList[] = $row['uid'];
272  }
273  if ($table === 'pages') {
274  $this->lostPagesList = implode(',', $lostIdList);
275  }
276  }
277  }
278  }
279 
288  public function ‪fixLostRecord($table, $uid): bool
289  {
290  if ($table && ‪$GLOBALS['TCA'][$table] && $uid && is_array($this->lRecords[$table][$uid]) && ‪$GLOBALS['BE_USER']->isAdmin()) {
291  $updateFields = [
292  'pid' => 0
293  ];
294  // If possible a lost record restored is hidden as default
295  if (‪$GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['disabled']) {
296  $updateFields[‪$GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['disabled']] = 1;
297  }
298  GeneralUtility::makeInstance(ConnectionPool::class)
299  ->getConnectionForTable($table)
300  ->update($table, $updateFields, ['uid' => (int)$uid]);
301  return true;
302  }
303  return false;
304  }
305 
312  public function ‪countRecords($pid_list): array
313  {
314  $list = [];
315  $list_n = [];
316  $pageIds = GeneralUtility::intExplode(',', $pid_list);
317  if (!empty($pageIds)) {
318  foreach (‪$GLOBALS['TCA'] as $table => $tableConf) {
319  $pageIdsForTable = $pageIds;
320  // Remove preceding "-1," for non-versioned tables
322  $pageIdsForTable = array_combine($pageIdsForTable, $pageIdsForTable);
323  unset($pageIdsForTable[-1]);
324  }
325  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($table);
326  $queryBuilder->getRestrictions()->removeAll();
327  $count = $queryBuilder->count('uid')
328  ->from($table)
329  ->where(
330  $queryBuilder->expr()->in(
331  'pid',
332  $queryBuilder->createNamedParameter($pageIds, Connection::PARAM_INT_ARRAY)
333  )
334  )
335  ->execute()
336  ->fetchColumn(0);
337  if ($count) {
338  $list[$table] = $count;
339  }
340 
341  // same query excluding all deleted records
342  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($table);
343  $queryBuilder->getRestrictions()
344  ->removeAll()
345  ->add(GeneralUtility::makeInstance(DeletedRestriction::class));
346  $count = $queryBuilder->count('uid')
347  ->from($table)
348  ->where(
349  $queryBuilder->expr()->in(
350  'pid',
351  $queryBuilder->createNamedParameter($pageIdsForTable, Connection::PARAM_INT_ARRAY)
352  )
353  )
354  ->execute()
355  ->fetchColumn(0);
356  if ($count) {
357  $list_n[$table] = $count;
358  }
359  }
360  }
361  return ['all' => $list, 'non_deleted' => $list_n];
362  }
363 
370  public function ‪getGroupFields($mode): array
371  {
372  $result = [];
373  foreach (‪$GLOBALS['TCA'] as $table => $tableConf) {
374  $cols = ‪$GLOBALS['TCA'][$table]['columns'];
375  foreach ($cols as $field => $config) {
376  if ($config['config']['type'] === 'group') {
377  if ((!$mode || $mode === 'file') && $config['config']['internal_type'] === 'file' || (!$mode || $mode === 'db') && $config['config']['internal_type'] === 'db') {
378  $result[$table][] = $field;
379  }
380  }
381  if ((!$mode || $mode === 'db') && $config['config']['type'] === 'select' && $config['config']['foreign_table']) {
382  $result[$table][] = $field;
383  }
384  }
385  if ($result[$table]) {
386  $result[$table] = implode(',', $result[$table]);
387  }
388  }
389  return $result;
390  }
391 
398  public function ‪getFileFields($uploadfolder): array
399  {
400  $result = [];
401  foreach (‪$GLOBALS['TCA'] as $table => $tableConf) {
402  $cols = ‪$GLOBALS['TCA'][$table]['columns'];
403  foreach ($cols as $field => $config) {
404  if ($config['config']['type'] === 'group' && $config['config']['internal_type'] === 'file' && $config['config']['uploadfolder'] == $uploadfolder) {
405  $result[] = [$table, $field];
406  }
407  }
408  }
409  return $result;
410  }
411 
418  public function ‪getDBFields($theSearchTable): array
419  {
420  $result = [];
421  foreach (‪$GLOBALS['TCA'] as $table => $tableConf) {
422  $cols = ‪$GLOBALS['TCA'][$table]['columns'];
423  foreach ($cols as $field => $config) {
424  if ($config['config']['type'] === 'group' && $config['config']['internal_type'] === 'db') {
425  if (trim($config['config']['allowed']) === '*' || strstr($config['config']['allowed'], $theSearchTable)) {
426  $result[] = [$table, $field];
427  }
428  } elseif ($config['config']['type'] === 'select' && $config['config']['foreign_table'] == $theSearchTable) {
429  $result[] = [$table, $field];
430  }
431  }
432  }
433  return $result;
434  }
435 
442  public function ‪selectNonEmptyRecordsWithFkeys($fkey_arrays): void
443  {
444  if (is_array($fkey_arrays)) {
445  $connectionPool = GeneralUtility::makeInstance(ConnectionPool::class);
446  foreach ($fkey_arrays as $table => $field_list) {
447  if (‪$GLOBALS['TCA'][$table] && trim($field_list)) {
448  $connection = $connectionPool->getConnectionForTable($table);
449  $schemaManager = $connection->getSchemaManager();
450  $tableColumns = $schemaManager->listTableColumns($table);
451 
452  $queryBuilder = $connectionPool->getQueryBuilderForTable($table);
453  $queryBuilder->getRestrictions()->removeAll();
454 
455  ‪$fields = GeneralUtility::trimExplode(',', $field_list, true);
456 
457  $queryBuilder->select('uid')
458  ->from($table);
459  $whereClause = [];
460 
461  foreach (‪$fields as $fieldName) {
462  // The array index of $tableColumns is the lowercased column name!
463  // It is quoted for keywords
464  $column = $tableColumns[strtolower($fieldName)]
465  ?? $tableColumns[$connection->quoteIdentifier(strtolower($fieldName))];
466  if (!$column) {
467  // Throw meaningful exception if field does not exist in DB - 'none' is not filtered here since the
468  // method is only called with type=group fields
469  throw new \RuntimeException(
470  'Field ' . $fieldName . ' for table ' . $table . ' has been defined in TCA, but does not exist in DB',
471  1536248937
472  );
473  }
474  $fieldType = $column->getType()->getName();
475  if (in_array(
476  $fieldType,
477  [Types::BIGINT, Types::INTEGER, Types::SMALLINT, Types::DECIMAL, Types::FLOAT],
478  true
479  )) {
480  $whereClause[] = $queryBuilder->expr()->andX(
481  $queryBuilder->expr()->isNotNull($fieldName),
482  $queryBuilder->expr()->neq(
483  $fieldName,
484  $queryBuilder->createNamedParameter(0, \PDO::PARAM_INT)
485  )
486  );
487  } elseif (in_array($fieldType, [Types::STRING, Types::TEXT], true)) {
488  $whereClause[] = $queryBuilder->expr()->andX(
489  $queryBuilder->expr()->isNotNull($fieldName),
490  $queryBuilder->expr()->neq(
491  $fieldName,
492  $queryBuilder->createNamedParameter('', \PDO::PARAM_STR)
493  )
494  );
495  } elseif ($fieldType === Types::BLOB) {
496  $whereClause[] = $queryBuilder->expr()->andX(
497  $queryBuilder->expr()->isNotNull($fieldName),
498  $queryBuilder->expr()
499  ->comparison(
500  $queryBuilder->expr()->length($fieldName),
502  $queryBuilder->createNamedParameter(0, \PDO::PARAM_INT)
503  )
504  );
505  }
506  }
507  $queryResult = $queryBuilder->orWhere(...$whereClause)->execute();
508 
509  while ($row = $queryResult->fetch()) {
510  foreach (‪$fields as $field) {
511  if (trim($row[$field])) {
512  $fieldConf = ‪$GLOBALS['TCA'][$table]['columns'][$field]['config'];
513  if ($fieldConf['type'] === 'group') {
514  if ($fieldConf['internal_type'] === 'file') {
515  // Files...
516  if ($fieldConf['MM']) {
517  $tempArr = [];
518  $dbAnalysis = GeneralUtility::makeInstance(RelationHandler::class);
519  $dbAnalysis->start('', 'files', $fieldConf['MM'], $row['uid']);
520  foreach ($dbAnalysis->itemArray as $somekey => $someval) {
521  if ($someval['id']) {
522  $tempArr[] = $someval['id'];
523  }
524  }
525  } else {
526  $tempArr = explode(',', trim($row[$field]));
527  }
528  foreach ($tempArr as $file) {
529  $file = trim($file);
530  if ($file) {
531  $this->checkFileRefs[$fieldConf['uploadfolder']][$file] += 1;
532  }
533  }
534  }
535  if ($fieldConf['internal_type'] === 'db') {
536  $dbAnalysis = GeneralUtility::makeInstance(RelationHandler::class);
537  $dbAnalysis->start(
538  $row[$field],
539  $fieldConf['allowed'],
540  $fieldConf['MM'],
541  $row['uid'],
542  $table,
543  $fieldConf
544  );
545  foreach ($dbAnalysis->itemArray as $tempArr) {
546  $this->checkGroupDBRefs[$tempArr['table']][$tempArr['id']] += 1;
547  }
548  }
549  }
550  if ($fieldConf['type'] === 'select' && $fieldConf['foreign_table']) {
551  $dbAnalysis = GeneralUtility::makeInstance(RelationHandler::class);
552  $dbAnalysis->start(
553  $row[$field],
554  $fieldConf['foreign_table'],
555  $fieldConf['MM'],
556  $row['uid'],
557  $table,
558  $fieldConf
559  );
560  foreach ($dbAnalysis->itemArray as $tempArr) {
561  if ($tempArr['id'] > 0) {
562  $this->checkGroupDBRefs[$fieldConf['foreign_table']][$tempArr['id']] += 1;
563  }
564  }
565  }
566  }
567  }
568  }
569  }
570  }
571  }
572  }
573 
579  public function ‪testFileRefs(): array
580  {
581  ‪$output = [];
582  // Handle direct references with upload folder setting (workaround)
583  $newCheckFileRefs = [];
584  foreach ($this->checkFileRefs as $folder => $files) {
585  // Only direct references without a folder setting
586  if ($folder !== '') {
587  $newCheckFileRefs[$folder] = $files;
588  continue;
589  }
590  foreach ($files as $file => $references) {
591  // Direct file references have often many references (removes occurrences in the moreReferences section of the result array)
592  if ($references > 1) {
593  $references = 1;
594  }
595  // The directory must be empty (prevents checking of the root directory)
596  $directory = ‪PathUtility::dirname($file);
597  if ($directory !== '') {
598  $newCheckFileRefs[$directory][‪PathUtility::basename($file)] = $references;
599  }
600  }
601  }
602  $this->checkFileRefs = $newCheckFileRefs;
603  foreach ($this->checkFileRefs as $folder => $fileArr) {
604  $path = ‪Environment::getPublicPath() . '/' . $folder;
605  if (@is_dir($path) && @is_readable($path)) {
606  $d = dir($path);
607  while ($entry = $d->read()) {
608  if (@is_file($path . '/' . $entry)) {
609  if (isset($fileArr[$entry])) {
610  if ($fileArr[$entry] > 1) {
611  $temp = $this->‪whereIsFileReferenced($folder, $entry);
612  $tempList = '';
613  foreach ($temp as $inf) {
614  $tempList .= '[' . $inf['table'] . '][' . $inf['uid'] . '][' . $inf['field'] . '] (pid:' . $inf['pid'] . ') - ';
615  }
616  ‪$output['moreReferences'][] = [$path, $entry, $fileArr[$entry], $tempList];
617  }
618  unset($fileArr[$entry]);
619  } else {
620  // Contains workaround for direct references
621  if (!strstr($entry, 'index.htm') && !preg_match('/^' . preg_quote(‪$GLOBALS['TYPO3_CONF_VARS']['BE']['fileadminDir'], '/') . '/', $folder)) {
622  ‪$output['noReferences'][] = [$path, $entry];
623  }
624  }
625  }
626  }
627  $d->close();
628  $tempCounter = 0;
629  foreach ($fileArr as $file => $value) {
630  // Workaround for direct file references
631  if (preg_match('/^' . preg_quote(‪$GLOBALS['TYPO3_CONF_VARS']['BE']['fileadminDir'], '/') . '/', $folder)) {
632  $file = $folder . '/' . $file;
633  $folder = '';
635  }
636  $temp = $this->‪whereIsFileReferenced($folder, $file);
637  $tempList = '';
638  foreach ($temp as $inf) {
639  $tempList .= '[' . $inf['table'] . '][' . $inf['uid'] . '][' . $inf['field'] . '] (pid:' . $inf['pid'] . ') - ';
640  }
641  $tempCounter++;
642  ‪$output['noFile'][substr($path, -3) . '_' . substr($file, 0, 3) . '_' . $tempCounter] = [$path, $file, $tempList];
643  }
644  } else {
645  ‪$output['error'][] = [$path];
646  }
647  }
648  return ‪$output;
649  }
650 
657  public function ‪testDBRefs($theArray): string
658  {
659  $result = '';
660  foreach ($theArray as $table => $dbArr) {
661  if (‪$GLOBALS['TCA'][$table]) {
662  $ids = array_keys($dbArr);
663  if (!empty($ids)) {
664  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
665  ->getQueryBuilderForTable($table);
666  $queryBuilder->getRestrictions()
667  ->removeAll()
668  ->add(GeneralUtility::makeInstance(DeletedRestriction::class));
669  $queryResult = $queryBuilder
670  ->select('uid')
671  ->from($table)
672  ->where(
673  $queryBuilder->expr()->in(
674  'uid',
675  $queryBuilder->createNamedParameter($ids, Connection::PARAM_INT_ARRAY)
676  )
677  )
678  ->execute();
679  while ($row = $queryResult->fetch()) {
680  if (isset($dbArr[$row['uid']])) {
681  unset($dbArr[$row['uid']]);
682  } else {
683  $result .= 'Strange Error. ...<br />';
684  }
685  }
686  foreach ($dbArr as $theId => $theC) {
687  $result .= 'There are ' . $theC . ' records pointing to this missing or deleted record; [' . $table . '][' . $theId . ']<br />';
688  }
689  }
690  } else {
691  $result .= 'Codeerror. Table is not a table...<br />';
692  }
693  }
694  return $result;
695  }
696 
704  public function ‪whereIsRecordReferenced($searchTable, $id): array
705  {
706  // Gets tables / Fields that reference to files
707  $fileFields = $this->‪getDBFields($searchTable);
708  $theRecordList = [];
709  foreach ($fileFields as $info) {
710  list($table, $field) = $info;
711  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($table);
712  $queryBuilder->getRestrictions()->removeAll();
713  $queryResult = $queryBuilder
714  ->select('uid', 'pid', ‪$GLOBALS['TCA'][$table]['ctrl']['label'], $field)
715  ->from($table)
716  ->where(
717  $queryBuilder->expr()->like(
718  $field,
719  $queryBuilder->createNamedParameter('%' . $queryBuilder->escapeLikeWildcards($id) . '%')
720  )
721  )
722  ->execute();
723 
724  while ($row = $queryResult->fetch()) {
725  // Now this is the field, where the reference COULD come from.
726  // But we're not guaranteed, so we must carefully examine the data.
727  $fieldConf = ‪$GLOBALS['TCA'][$table]['columns'][$field]['config'];
728  $allowedTables = $fieldConf['type'] === 'group' ? $fieldConf['allowed'] : $fieldConf['foreign_table'];
729  $dbAnalysis = GeneralUtility::makeInstance(RelationHandler::class);
730  $dbAnalysis->start($row[$field], $allowedTables, $fieldConf['MM'], $row['uid'], $table, $fieldConf);
731  foreach ($dbAnalysis->itemArray as $tempArr) {
732  if ($tempArr['table'] == $searchTable && $tempArr['id'] == $id) {
733  $theRecordList[] = [
734  'table' => $table,
735  'uid' => $row['uid'],
736  'field' => $field,
737  'pid' => $row['pid']
738  ];
739  }
740  }
741  }
742  }
743  return $theRecordList;
744  }
745 
753  public function ‪whereIsFileReferenced($uploadFolder, $filename): array
754  {
755  // Gets tables / Fields that reference to files
756  $fileFields = $this->‪getFileFields($uploadFolder);
757  $theRecordList = [];
758  foreach ($fileFields as $info) {
759  list($table, $field) = $info;
760  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($table);
761  $queryBuilder->getRestrictions()->removeAll();
762  $queryResult = $queryBuilder
763  ->select('uid', 'pid', ‪$GLOBALS['TCA'][$table]['ctrl']['label'], $field)
764  ->from($table)
765  ->where(
766  $queryBuilder->expr()->like(
767  $field,
768  $queryBuilder->createNamedParameter('%' . $queryBuilder->escapeLikeWildcards($filename) . '%')
769  )
770  )
771  ->execute();
772  while ($row = $queryResult->fetch()) {
773  // Now this is the field, where the reference COULD come from.
774  // But we're not guaranteed, so we must carefully examine the data.
775  $tempArr = explode(',', trim($row[$field]));
776  foreach ($tempArr as $file) {
777  $file = trim($file);
778  if ($file == $filename) {
779  $theRecordList[] = [
780  'table' => $table,
781  'uid' => $row['uid'],
782  'field' => $field,
783  'pid' => $row['pid']
784  ];
785  }
786  }
787  }
788  }
789  return $theRecordList;
790  }
791 
795  public function ‪getPageIdArray(): array
796  {
797  return ‪$this->pageIdArray;
798  }
799 
803  public function ‪getCheckGroupDBRefs(): array
804  {
806  }
807 
811  public function ‪getCheckSelectDBRefs(): array
812  {
814  }
815 
819  public function ‪getRecStats(): array
820  {
821  return ‪$this->recStats;
822  }
823 
827  public function ‪getLRecords(): array
828  {
829  return ‪$this->lRecords;
830  }
831 
835  public function ‪getLostPagesList(): string
836  {
838  }
839 }
‪TYPO3\CMS\Lowlevel\Integrity\DatabaseIntegrityCheck\getCheckGroupDBRefs
‪array getCheckGroupDBRefs()
Definition: DatabaseIntegrityCheck.php:794
‪TYPO3\CMS\Lowlevel\Integrity
Definition: DatabaseIntegrityCheck.php:2
‪TYPO3\CMS\Core\Utility\PathUtility
Definition: PathUtility.php:23
‪TYPO3\CMS\Core\Database\Query\Expression\ExpressionBuilder
Definition: ExpressionBuilder.php:33
‪TYPO3\CMS\Lowlevel\Integrity\DatabaseIntegrityCheck\$pageTranslatedPageIDArray
‪$pageTranslatedPageIDArray
Definition: DatabaseIntegrityCheck.php:63
‪TYPO3\CMS\Core\Core\Environment\getPublicPath
‪static string getPublicPath()
Definition: Environment.php:153
‪TYPO3\CMS\Core\Utility\PathUtility\dirname
‪static string dirname($path)
Definition: PathUtility.php:185
‪TYPO3\CMS\Lowlevel\Integrity\DatabaseIntegrityCheck\getPageTranslatedPageIDArray
‪array getPageTranslatedPageIDArray()
Definition: DatabaseIntegrityCheck.php:100
‪TYPO3\CMS\Lowlevel\Integrity\DatabaseIntegrityCheck\selectNonEmptyRecordsWithFkeys
‪selectNonEmptyRecordsWithFkeys($fkey_arrays)
Definition: DatabaseIntegrityCheck.php:433
‪TYPO3\CMS\Lowlevel\Integrity\DatabaseIntegrityCheck\genTree_records
‪genTree_records($theID, $_='', $table='', $versions=false)
Definition: DatabaseIntegrityCheck.php:181
‪TYPO3\CMS\Core\Database\RelationHandler
Definition: RelationHandler.php:32
‪TYPO3\CMS\Backend\Utility\BackendUtility\getCommonSelectFields
‪static string getCommonSelectFields($table, $prefix='', $fields=[])
Definition: BackendUtility.php:2397
‪TYPO3\CMS\Lowlevel\Integrity\DatabaseIntegrityCheck\getLostPagesList
‪string getLostPagesList()
Definition: DatabaseIntegrityCheck.php:826
‪$fields
‪$fields
Definition: pages.php:4
‪TYPO3\CMS\Lowlevel\Integrity\DatabaseIntegrityCheck\whereIsRecordReferenced
‪array whereIsRecordReferenced($searchTable, $id)
Definition: DatabaseIntegrityCheck.php:695
‪TYPO3\CMS\Lowlevel\Integrity\DatabaseIntegrityCheck\$lRecords
‪array $lRecords
Definition: DatabaseIntegrityCheck.php:91
‪TYPO3\CMS\Lowlevel\Integrity\DatabaseIntegrityCheck\getRecStats
‪array getRecStats()
Definition: DatabaseIntegrityCheck.php:810
‪TYPO3\CMS\Lowlevel\Integrity\DatabaseIntegrityCheck\$genTreeIncludeRecords
‪bool $genTreeIncludeRecords
Definition: DatabaseIntegrityCheck.php:53
‪TYPO3\CMS\Lowlevel\Integrity\DatabaseIntegrityCheck\$checkGroupDBRefs
‪array $checkGroupDBRefs
Definition: DatabaseIntegrityCheck.php:79
‪TYPO3\CMS\Core\Utility\PathUtility\basename
‪static string basename($path)
Definition: PathUtility.php:164
‪TYPO3\CMS\Lowlevel\Integrity\DatabaseIntegrityCheck\whereIsFileReferenced
‪array whereIsFileReferenced($uploadFolder, $filename)
Definition: DatabaseIntegrityCheck.php:744
‪TYPO3\CMS\Lowlevel\Integrity\DatabaseIntegrityCheck\$pageIdArray
‪$pageIdArray
Definition: DatabaseIntegrityCheck.php:58
‪TYPO3\CMS\Lowlevel\Integrity\DatabaseIntegrityCheck\countRecords
‪array countRecords($pid_list)
Definition: DatabaseIntegrityCheck.php:303
‪TYPO3\CMS\Lowlevel\Integrity\DatabaseIntegrityCheck\fixLostRecord
‪bool fixLostRecord($table, $uid)
Definition: DatabaseIntegrityCheck.php:279
‪TYPO3\CMS\Lowlevel\Integrity\DatabaseIntegrityCheck\$genTreeIncludeDeleted
‪bool $genTreeIncludeDeleted
Definition: DatabaseIntegrityCheck.php:44
‪TYPO3\CMS\Backend\Utility\BackendUtility\isTableWorkspaceEnabled
‪static bool isTableWorkspaceEnabled($table)
Definition: BackendUtility.php:4493
‪TYPO3\CMS\Lowlevel\Integrity\DatabaseIntegrityCheck\lostRecords
‪lostRecords($pid_list)
Definition: DatabaseIntegrityCheck.php:228
‪TYPO3\CMS\Lowlevel\Integrity\DatabaseIntegrityCheck\$checkFileRefs
‪array $checkFileRefs
Definition: DatabaseIntegrityCheck.php:71
‪TYPO3\CMS\Core\Database\Query\Expression\ExpressionBuilder\GT
‪const GT
Definition: ExpressionBuilder.php:38
‪TYPO3\CMS\Lowlevel\Integrity\DatabaseIntegrityCheck\getGroupFields
‪array getGroupFields($mode)
Definition: DatabaseIntegrityCheck.php:361
‪TYPO3\CMS\Lowlevel\Integrity\DatabaseIntegrityCheck\$checkSelectDBRefs
‪array $checkSelectDBRefs
Definition: DatabaseIntegrityCheck.php:75
‪TYPO3\CMS\Backend\Utility\BackendUtility\getRecordTitle
‪static string getRecordTitle($table, $row, $prep=false, $forceResult=true)
Definition: BackendUtility.php:1811
‪TYPO3\CMS\Lowlevel\Integrity\DatabaseIntegrityCheck\getDBFields
‪array getDBFields($theSearchTable)
Definition: DatabaseIntegrityCheck.php:409
‪TYPO3\CMS\Backend\Utility\BackendUtility
Definition: BackendUtility.php:72
‪TYPO3\CMS\Lowlevel\Integrity\DatabaseIntegrityCheck\testDBRefs
‪string testDBRefs($theArray)
Definition: DatabaseIntegrityCheck.php:648
‪$output
‪$output
Definition: annotationChecker.php:113
‪TYPO3\CMS\Core\Database\Connection
Definition: Connection.php:31
‪TYPO3\CMS\Lowlevel\Integrity\DatabaseIntegrityCheck\getCheckSelectDBRefs
‪array getCheckSelectDBRefs()
Definition: DatabaseIntegrityCheck.php:802
‪TYPO3\CMS\Lowlevel\Integrity\DatabaseIntegrityCheck
Definition: DatabaseIntegrityCheck.php:41
‪TYPO3\CMS\Lowlevel\Integrity\DatabaseIntegrityCheck\getFileFields
‪array getFileFields($uploadfolder)
Definition: DatabaseIntegrityCheck.php:389
‪TYPO3\CMS\Lowlevel\Integrity\DatabaseIntegrityCheck\testFileRefs
‪array testFileRefs()
Definition: DatabaseIntegrityCheck.php:570
‪TYPO3\CMS\Lowlevel\Integrity\DatabaseIntegrityCheck\genTree
‪genTree($theID, $depthData='', $versions=false)
Definition: DatabaseIntegrityCheck.php:113
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:5
‪TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction
Definition: DeletedRestriction.php:26
‪TYPO3\CMS\Core\Core\Environment
Definition: Environment.php:39
‪TYPO3\CMS\Lowlevel\Integrity\DatabaseIntegrityCheck\$recStats
‪array $recStats
Definition: DatabaseIntegrityCheck.php:83
‪TYPO3\CMS\Lowlevel\Integrity\DatabaseIntegrityCheck\getLRecords
‪array getLRecords()
Definition: DatabaseIntegrityCheck.php:818
‪TYPO3\CMS\Lowlevel\Integrity\DatabaseIntegrityCheck\getPageIdArray
‪array getPageIdArray()
Definition: DatabaseIntegrityCheck.php:786
‪TYPO3\CMS\Lowlevel\Integrity\DatabaseIntegrityCheck\$lostPagesList
‪string $lostPagesList
Definition: DatabaseIntegrityCheck.php:95
‪TYPO3\CMS\Core\Database\ConnectionPool
Definition: ConnectionPool.php:44
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:45
‪TYPO3\CMS\Lowlevel\Integrity\DatabaseIntegrityCheck\$genTreeIncludeVersions
‪$genTreeIncludeVersions
Definition: DatabaseIntegrityCheck.php:49
‪TYPO3\CMS\Lowlevel\Integrity\DatabaseIntegrityCheck\$recIdArray
‪array $recIdArray
Definition: DatabaseIntegrityCheck.php:67