2 /***************************************************************
5 * (c) 1999-2010 Kasper Skårhøj (kasperYYYY@typo3.com)
8 * This script is part of the TYPO3 project. The TYPO3 project is
9 * free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * The GNU General Public License can be found at
15 * http://www.gnu.org/copyleft/gpl.html.
16 * A copy is found in the textfile GPL.txt and important notices to the license
17 * from the author is found in LICENSE.txt distributed with these scripts.
20 * This script is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * This copyright notice MUST APPEAR in all copies of the script!
26 ***************************************************************/
28 * Contains a class for evaluation of database integrity according to $TCA
29 * Most of these functions are considered obsolete!
32 * Revised for TYPO3 3.6 July/2003 by Kasper Skårhøj
35 * @author Kasper Skårhøj <kasperYYYY@typo3.com>
38 * [CLASS/FUNCTION INDEX of SCRIPT]
42 * 93: class t3lib_admin
43 * 128: function genTree($theID, $depthData, $versions=FALSE)
44 * 217: function genTree_records($theID, $depthData, $table='', $versions=FALSE)
45 * 292: function genTreeStatus()
46 * 315: function lostRecords($pid_list)
47 * 346: function fixLostRecord($table,$uid)
48 * 367: function countRecords($pid_list)
49 * 395: function getGroupFields($mode)
50 * 429: function getFileFields($uploadfolder)
51 * 452: function getDBFields($theSearchTable)
52 * 480: function selectNonEmptyRecordsWithFkeys($fkey_arrays)
53 * 569: function testFileRefs ()
54 * 620: function testDBRefs($theArray)
55 * 658: function whereIsRecordReferenced($searchTable,$id)
56 * 695: function whereIsFileReferenced($uploadfolder,$filename)
59 * (This index is automatically created/updated by the extension "extdeveval")
83 * This class holds functions used by the TYPO3 backend to check the integrity of the database (The DBint module, 'lowlevel' extension)
85 * Depends on: Depends on loaddbgroup from t3lib/
87 * @todo Need to really extend this class when the tcemain library has been updated and the whole API is better defined. There are some known bugs in this library. Further it would be nice with a facility to not only analyze but also clean up!
88 * @see SC_mod_tools_dbint_index::func_relations(), SC_mod_tools_dbint_index::func_records()
89 * @author Kasper Skårhøj <kasperYYYY@typo3.com>
94 var $genTree_includeDeleted = TRUE
; // if set, genTree() includes deleted pages. This is default.
95 var $genTree_includeVersions = TRUE
; // if set, genTree() includes verisonized pages/records. This is default.
96 var $genTree_includeRecords = FALSE
; // if set, genTree() includes records from pages.
97 var $perms_clause = ''; // extra where-clauses for the tree-selection
98 var $genTree_makeHTML = 0; // if set, genTree() generates HTML, that visualizes the tree.
101 var $page_idArray = Array(); // Will hod id/rec pais from genTree()
102 var $rec_idArray = Array();
103 var $getTree_HTML = ''; // Will hold the HTML-code visualising the tree. genTree()
107 var $checkFileRefs = Array();
108 var $checkSelectDBRefs = Array(); // From the select-fields
109 var $checkGroupDBRefs = Array(); // From the group-fields
111 var $recStats = Array(
112 'allValid' => array(),
113 'published_versions' => array(),
114 'deleted' => array(),
116 var $lRecords = Array();
117 var $lostPagesList = '';
121 * Generates a list of Page-uid's that corresponds to the tables in the tree. This list should ideally include all records in the pages-table.
123 * @param integer a pid (page-record id) from which to start making the tree
124 * @param string HTML-code (image-tags) used when this function calls itself recursively.
125 * @param boolean Internal variable, don't set from outside!
128 function genTree($theID, $depthData, $versions=FALSE
) {
131 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
132 'uid,title,doktype,deleted,t3ver_wsid,t3ver_id,t3ver_count,t3ver_swapmode'.(t3lib_extMgm
::isLoaded('cms')?
',hidden':''),
134 'pid=-1 AND t3ver_oid='.intval($theID).' '.((!$this->genTree_includeDeleted
)?
'AND deleted=0':'').$this->perms_clause
,
139 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
140 'uid,title,doktype,deleted'.(t3lib_extMgm
::isLoaded('cms')?
',hidden':''),
142 'pid='.intval($theID).' '.((!$this->genTree_includeDeleted
)?
'AND deleted=0':'').$this->perms_clause
,
148 // Traverse the records selected:
150 $c = $GLOBALS['TYPO3_DB']->sql_num_rows($res);
151 while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
153 // Prepare the additional label used in the HTML output in case of versions:
155 $versionLabel = '[v1.'.$row['t3ver_id'].'; WS#'.$row['t3ver_wsid'].']';
156 } else $versionLabel='';
159 $newID = $row['uid'];
161 // Build HTML output:
162 if ($this->genTree_makeHTML
) {
163 $this->genTree_HTML
.=LF
.'<div><span class="nobr">';
165 $LN = ($a==$c)?
'blank':'line';
166 $BTM = ($a==$c)?
'bottom':'';
167 $this->genTree_HTML
.= $depthData.
168 '<img'.t3lib_iconWorks
::skinImg($this->backPath
,'gfx/ol/'.$PM.$BTM.'.gif','width="18" height="16"').' align="top" alt="" />'.
170 t3lib_iconWorks
::getSpriteIconForRecord('pages', $row) .
171 htmlspecialchars($row['uid'].': '.t3lib_div
::fixed_lgd_cs(strip_tags($row['title']),50)).'</span></div>';
174 // Register various data for this item:
175 $this->page_idArray
[$newID]=$row;
177 $this->recStats
['all_valid']['pages'][$newID] = $newID;
178 # if ($versions) $this->recStats['versions']['pages'][$newID] = $newID;
179 if ($row['deleted']) $this->recStats
['deleted']['pages'][$newID] = $newID;
180 if ($versions && $row['t3ver_count']>=1) {
181 $this->recStats
['published_versions']['pages'][$newID] = $newID;
184 if ($row['deleted']) {$this->recStat
['deleted']++
;}
185 if ($row['hidden']) {$this->recStat
['hidden']++
;}
186 $this->recStat
['doktype'][$row['doktype']]++
;
188 // Create the HTML code prefix for recursive call:
189 $genHTML = $depthData.'<img'.t3lib_iconWorks
::skinImg($this->backPath
,'gfx/ol/'.$LN.'.gif','width="18" height="16"').' align="top" alt="" />'.$versionLabel;
191 // If all records should be shown, do so:
192 if ($this->genTree_includeRecords
) {
193 foreach($GLOBALS['TCA'] as $tableName => $cfg) {
194 if ($tableName!='pages') {
195 $this->genTree_records($newID, $this->genTree_HTML ?
$genHTML : '', $tableName);
201 $this->genTree($newID, $this->genTree_HTML ?
$genHTML : '');
203 // If versions are included in the tree, add those now:
204 if ($this->genTree_includeVersions
) {
205 $this->genTree($newID, $this->genTree_HTML ?
$genHTML : '', TRUE
);
211 * @param [type] $theID: ...
212 * @param [type] $depthData: ...
213 * @param [type] $table: ...
214 * @param [type] $versions: ...
217 function genTree_records($theID, $depthData, $table='', $versions=FALSE
) {
221 // Select all records from table pointing to this page:
222 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
223 t3lib_BEfunc
::getCommonSelectFields($table),
225 'pid=-1 AND t3ver_oid='.intval($theID).
226 (!$this->genTree_includeDeleted?t3lib_BEfunc
::deleteClause($table):'')
229 // Select all records from table pointing to this page:
230 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
231 t3lib_BEfunc
::getCommonSelectFields($table),
233 'pid='.intval($theID).
234 (!$this->genTree_includeDeleted?t3lib_BEfunc
::deleteClause($table):'')
238 // Traverse selected:
240 $c = $GLOBALS['TYPO3_DB']->sql_num_rows($res);
241 while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
243 // Prepare the additional label used in the HTML output in case of versions:
245 $versionLabel = '[v1.'.$row['t3ver_id'].'; WS#'.$row['t3ver_wsid'].']';
246 } else $versionLabel='';
249 $newID = $row['uid'];
251 // Build HTML output:
252 if ($this->genTree_makeHTML
) {
253 $this->genTree_HTML
.=LF
.'<div><span class="nobr">';
255 $LN = ($a==$c)?
'blank':'line';
256 $BTM = ($a==$c)?
'bottom':'';
257 $this->genTree_HTML
.= $depthData.
258 '<img'.t3lib_iconWorks
::skinImg($this->backPath
,'gfx/ol/'.$PM.$BTM.'.gif','width="18" height="16"').' align="top" alt="" />'.
260 t3lib_iconWorks
::getSpriteIconForRecord($table, $row, array('title'=> $table)) . htmlspecialchars($row['uid'] . ': ' . t3lib_BEfunc
::getRecordTitle($table,$row)) . '</span></div>';
263 // Register various data for this item:
264 $this->rec_idArray
[$table][$newID]=$row;
266 $this->recStats
['all_valid'][$table][$newID] = $newID;
267 # $this->recStats[$versions?'versions':'live'][$table][$newID] = $newID;
268 if ($row['deleted']) $this->recStats
['deleted'][$table][$newID] = $newID;
269 if ($versions && $row['t3ver_count']>=1 && $row['t3ver_wsid']==0) {
270 $this->recStats
['published_versions'][$table][$newID] = $newID;
273 # if ($row['deleted']) {$this->recStat['deleted']++;}
274 # if ($row['hidden']) {$this->recStat['hidden']++;}
278 // Select all versions of this record:
279 if ($this->genTree_includeVersions
&& $TCA[$table]['ctrl']['versioningWS']) {
280 $genHTML = $depthData.'<img'.t3lib_iconWorks
::skinImg($this->backPath
,'gfx/ol/'.$LN.'.gif','width="18" height="16"').' align="top" alt="" />';
282 $this->genTree_records($newID, $genHTML, $table, TRUE
);
288 * [Describe function...]
292 function genTreeStatus($root=0) {
293 $this->genTree_includeDeleted
= TRUE
; // if set, genTree() includes deleted pages. This is default.
294 $this->genTree_includeVersions
= TRUE
; // if set, genTree() includes verisonized pages/records. This is default.
295 $this->genTree_includeRecords
= TRUE
; // if set, genTree() includes records from pages.
296 $this->perms_clause
= ''; // extra where-clauses for the tree-selection
297 $this->genTree_makeHTML
= 0; // if set, genTree() generates HTML, that visualizes the tree.
299 $this->genTree($root,'');
301 return $this->recStats
;
310 * Fills $this->lRecords with the records from all tc-tables that are not attached to a PID in the pid-list.
312 * @param string list of pid's (page-record uid's). This list is probably made by genTree()
315 function lostRecords($pid_list) {
317 $this->lostPagesList
='';
319 foreach ($TCA as $table => $tableConf) {
320 t3lib_div
::loadTCA($table);
322 $pid_list_tmp = $pid_list;
323 if (!isset($TCA[$table]['ctrl']['versioningWS']) ||
!$TCA[$table]['ctrl']['versioningWS']) {
324 // Remove preceding "-1," for non-versioned tables
325 $pid_list_tmp = preg_replace('/^\-1,/','',$pid_list_tmp);
328 $garbage = $GLOBALS['TYPO3_DB']->exec_SELECTquery (
329 'uid,pid,'.$TCA[$table]['ctrl']['label'],
331 'pid NOT IN ('.$pid_list_tmp.')'
333 $lostIdList = array();
334 while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($garbage)) {
335 $this->lRecords
[$table][$row['uid']]=Array('uid'=>$row['uid'], 'pid'=>$row['pid'], 'title'=> strip_tags($row[$TCA[$table]['ctrl']['label']]) );
336 $lostIdList[]=$row['uid'];
338 if ($table=='pages') {
339 $this->lostPagesList
=implode(',',$lostIdList);
346 * Fixes lost record from $table with uid $uid by setting the PID to zero. If there is a disabled column for the record that will be set as well.
348 * @param string Database tablename
349 * @param integer The uid of the record which will have the PID value set to 0 (zero)
350 * @return boolean True if done.
352 function fixLostRecord($table,$uid) {
353 if ($table && $GLOBALS['TCA'][$table] && $uid && is_array($this->lRecords
[$table][$uid]) && $GLOBALS['BE_USER']->user
['admin']) {
355 $updateFields = array();
356 $updateFields['pid'] = 0;
357 if ($GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['disabled']) { // If possible a lost record restored is hidden as default
358 $updateFields[$GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['disabled']] = 1;
361 $GLOBALS['TYPO3_DB']->exec_UPDATEquery($table, 'uid='.intval($uid), $updateFields);
368 * Counts records from $TCA-tables that ARE attached to an existing page.
370 * @param string list of pid's (page-record uid's). This list is probably made by genTree()
371 * @return array an array with the number of records from all $TCA-tables that are attached to a PID in the pid-list.
373 function countRecords($pid_list) {
378 foreach ($TCA as $table => $tableConf) {
379 t3lib_div
::loadTCA($table);
381 $pid_list_tmp = $pid_list;
382 if (!isset($TCA[$table]['ctrl']['versioningWS']) ||
!$TCA[$table]['ctrl']['versioningWS']) {
383 // Remove preceding "-1," for non-versioned tables
384 $pid_list_tmp = preg_replace('/^\-1,/','',$pid_list_tmp);
387 $count = $GLOBALS['TYPO3_DB']->exec_SELECTcountRows('uid', $table, 'pid IN ('.$pid_list_tmp.')');
389 $list[$table] = $count;
392 $count = $GLOBALS['TYPO3_DB']->exec_SELECTcountRows('uid', $table, 'pid IN ('.$pid_list_tmp.')' . t3lib_BEfunc
::deleteClause($table));
394 $list_n[$table] = $count;
398 return array('all' => $list, 'non_deleted' => $list_n);
402 * Finding relations in database based on type 'group' (files or database-uid's in a list)
404 * @param string $mode = file, $mode = db, $mode = '' (all...)
405 * @return array An array with all fields listed that somehow are references to other records (foreign-keys) or files
407 function getGroupFields($mode) {
410 foreach ($TCA as $table => $tableConf) {
411 t3lib_div
::loadTCA($table);
412 $cols = $TCA[$table]['columns'];
413 foreach ($cols as $field => $config) {
414 if ($config['config']['type']=='group') {
416 ((!$mode||
$mode=='file') && $config['config']['internal_type']=='file') ||
417 ((!$mode||
$mode=='db') && $config['config']['internal_type']=='db')
419 $result[$table][]=$field;
422 if ( (!$mode||
$mode=='db') && $config['config']['type']=='select' && $config['config']['foreign_table']) {
423 $result[$table][]=$field;
426 if ($result[$table]) {
427 $result[$table] = implode(',',$result[$table]);
434 * Finds all fields that hold filenames from uploadfolder
436 * @param string Path to uploadfolder
437 * @return array An array with all fields listed that have references to files in the $uploadfolder
439 function getFileFields($uploadfolder) {
442 foreach ($TCA as $table => $tableConf) {
443 t3lib_div
::loadTCA($table);
444 $cols = $TCA[$table]['columns'];
445 foreach ($cols as $field => $config) {
446 if ($config['config']['type']=='group' && $config['config']['internal_type']=='file' && $config['config']['uploadfolder']==$uploadfolder) {
447 $result[]=Array($table,$field);
455 * Returns an array with arrays of table/field pairs which are allowed to hold references to the input table name - according to $TCA
457 * @param string Table name
460 function getDBFields($theSearchTable) {
464 foreach ($TCA as $table => $tableConf) {
465 t3lib_div
::loadTCA($table);
466 $cols = $TCA[$table]['columns'];
467 foreach ($cols as $field => $config) {
468 if ($config['config']['type']=='group' && $config['config']['internal_type']=='db') {
469 if (trim($config['config']['allowed'])=='*' ||
strstr($config['config']['allowed'],$theSearchTable)) {
470 $result[]=Array($table,$field);
472 } else if ($config['config']['type']=='select' && $config['config']['foreign_table']==$theSearchTable) {
473 $result[]=Array($table,$field);
481 * This selects non-empty-records from the tables/fields in the fkey_array generated by getGroupFields()
483 * @param array Array with tables/fields generated by getGroupFields()
485 * @see getGroupFields()
487 function selectNonEmptyRecordsWithFkeys($fkey_arrays) {
489 if (is_array($fkey_arrays)) {
490 foreach ($fkey_arrays as $table => $field_list) {
491 if ($TCA[$table] && trim($field_list)) {
492 t3lib_div
::loadTCA($table);
493 $fieldArr = explode(',',$field_list);
495 if(t3lib_extMgm
::isLoaded('dbal')) {
496 $fields = $GLOBALS['TYPO3_DB']->admin_get_fields($table);
497 $field = array_shift($fieldArr);
498 $cl_fl = ($GLOBALS['TYPO3_DB']->MetaType($fields[$field]['type'],$table) == 'I' ||
$GLOBALS['TYPO3_DB']->MetaType($fields[$field]['type'],$table) == 'N' ||
$GLOBALS['TYPO3_DB']->MetaType($fields[$field]['type'],$table) == 'R') ?
499 $field.'!=0' : $field.'!=\'\'';
500 foreach ($fieldArr as $field) {
501 $cl_fl .= ($GLOBALS['TYPO3_DB']->MetaType($fields[$field]['type'],$table) == 'I' ||
$GLOBALS['TYPO3_DB']->MetaType($fields[$field]['type'],$table) == 'N' ||
$GLOBALS['TYPO3_DB']->MetaType($fields[$field]['type'],$table) == 'R') ?
502 ' OR '.$field.'!=0' : ' OR '.$field.'!=\'\'';
507 $cl_fl = implode ('!=\'\' OR ',$fieldArr). '!=\'\'';
510 $mres = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid,'.$field_list, $table, $cl_fl);
511 while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($mres)) {
512 foreach ($fieldArr as $field) {
513 if (trim($row[$field])) {
514 $fieldConf = $TCA[$table]['columns'][$field]['config'];
515 if ($fieldConf['type']=='group') {
516 if ($fieldConf['internal_type']=='file') {
518 if ($fieldConf['MM']) {
520 $dbAnalysis = t3lib_div
::makeInstance('t3lib_loadDBGroup');
521 $dbAnalysis->start('','files',$fieldConf['MM'],$row['uid']);
522 foreach ($dbAnalysis->itemArray
as $somekey => $someval) {
523 if ($someval['id']) {
524 $tempArr[]=$someval['id'];
528 $tempArr = explode(',',trim($row[$field]));
530 foreach ($tempArr as $file) {
533 $this->checkFileRefs
[$fieldConf['uploadfolder']][$file]+
=1;
537 if ($fieldConf['internal_type']=='db') {
539 $dbAnalysis = t3lib_div
::makeInstance('t3lib_loadDBGroup');
540 $dbAnalysis->start($row[$field],$fieldConf['allowed'],$fieldConf['MM'],$row['uid'], $table, $fieldConf);
541 foreach ($dbAnalysis->itemArray
as $tempArr) {
542 $this->checkGroupDBRefs
[$tempArr['table']][$tempArr['id']]+
=1;
546 if ($fieldConf['type']=='select' && $fieldConf['foreign_table']) {
548 $dbAnalysis = t3lib_div
::makeInstance('t3lib_loadDBGroup');
549 $dbAnalysis->start($row[$field],$fieldConf['foreign_table'],$fieldConf['MM'],$row['uid'], $table, $fieldConf);
550 foreach ($dbAnalysis->itemArray
as $tempArr) {
551 if ($tempArr['id']>0) {
552 $this->checkGroupDBRefs
[$fieldConf['foreign_table']][$tempArr['id']]+
=1;
559 $GLOBALS['TYPO3_DB']->sql_free_result($mres);
566 * Depends on selectNonEmpty.... to be executed first!!
568 * @return array Report over files; keys are "moreReferences", "noReferences", "noFile", "error"
570 function testFileRefs () {
572 // handle direct references with upload folder setting (workaround)
573 $newCheckFileRefs = array();
574 foreach ($this->checkFileRefs
as $folder => $files) {
575 // only direct references without a folder setting
576 if ($folder !== '') {
577 $newCheckFileRefs[$folder] = $files;
581 foreach ($files as $file => $references) {
583 // direct file references have often many references (removes occurences in the moreReferences section of the result array)
584 if ($references > 1) {
588 // the directory must be empty (prevents checking of the root directory)
589 $directory = dirname($file);
590 if ($directory !== '') {
591 $newCheckFileRefs[$directory][basename($file)] = $references;
595 $this->checkFileRefs
= $newCheckFileRefs;
597 foreach ($this->checkFileRefs
as $folder => $fileArr) {
598 $path = PATH_site
.$folder;
599 if (@is_dir
($path)) {
601 while($entry=$d->read()) {
602 if (@is_file
($path.'/'.$entry)) {
603 if (isset($fileArr[$entry])) {
604 if ($fileArr[$entry] > 1) {
605 $temp = $this->whereIsFileReferenced($folder,$entry);
607 foreach ($temp as $inf) {
608 $tempList.='['.$inf['table'].']['.$inf['uid'].']['.$inf['field'].'] (pid:'.$inf['pid'].') - ';
610 $output['moreReferences'][] = Array($path,$entry,$fileArr[$entry],$tempList);
612 unset($fileArr[$entry]);
614 // contains workaround for direct references
615 if (!strstr($entry, 'index.htm') && !preg_match('/^' . preg_quote($GLOBALS['TYPO3_CONF_VARS']['BE']['fileadminDir'], '/') . '/', $folder)) {
616 $output['noReferences'][] = Array($path,$entry);
623 foreach ($fileArr as $file => $value) {
624 // workaround for direct file references
625 if (preg_match('/^' . preg_quote($GLOBALS['TYPO3_CONF_VARS']['BE']['fileadminDir'], '/') . '/', $folder)) {
626 $file = $folder . '/' . $file;
628 $path = substr(PATH_site
, 0, - 1);
630 $temp = $this->whereIsFileReferenced($folder,$file);
632 foreach ($temp as $inf) {
633 $tempList.='['.$inf['table'].']['.$inf['uid'].']['.$inf['field'].'] (pid:'.$inf['pid'].') - ';
636 $output['noFile'][substr($path,-3).'_'.substr($file,0,3).'_'.$tempCounter] = Array($path,$file,$tempList);
639 $output['error'][] = Array($path);
646 * Depends on selectNonEmpty.... to be executed first!!
648 * @param array Table with key/value pairs being table names and arrays with uid numbers
649 * @return string HTML Error message
651 function testDBRefs($theArray) {
653 foreach ($theArray as $table => $dbArr) {
655 $idlist = array_keys($dbArr);
657 $theList = implode(',',$idlist);
659 $mres = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid', $table, 'uid IN ('.$theList.')'.t3lib_BEfunc
::deleteClause($table));
660 while($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($mres)) {
661 if (isset($dbArr[$row['uid']])) {
662 unset ($dbArr[$row['uid']]);
664 $result.='Strange Error. ...<br />';
667 foreach ($dbArr as $theId => $theC) {
668 $result.='There are '.$theC.' records pointing to this missing or deleted record; ['.$table.']['.$theId.']<br />';
672 $result.='Codeerror. Table is not a table...<br />';
679 * Finding all references to record based on table/uid
681 * @param string Table name
682 * @param integer Uid of database record
683 * @return array Array with other arrays containing information about where references was found
685 function whereIsRecordReferenced($searchTable,$id) {
687 $fileFields = $this->getDBFields($searchTable); // Gets tables / Fields that reference to files...
688 $theRecordList=Array();
689 foreach ($fileFields as $info) {
690 $table=$info[0]; $field=$info[1];
691 t3lib_div
::loadTCA($table);
692 $mres = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
693 'uid,pid,'.$TCA[$table]['ctrl']['label'].','.$field,
695 $field.' LIKE \'%'.$GLOBALS['TYPO3_DB']->quoteStr($id, $table).'%\''
697 while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($mres)) {
698 // Now this is the field, where the reference COULD come from. But we're not garanteed, so we must carefully examine the data.
699 $fieldConf = $TCA[$table]['columns'][$field]['config'];
700 $allowedTables = ($fieldConf['type']=='group') ?
$fieldConf['allowed'] : $fieldConf['foreign_table'];
702 $dbAnalysis = t3lib_div
::makeInstance('t3lib_loadDBGroup');
703 $dbAnalysis->start($row[$field],$allowedTables,$fieldConf['MM'],$row['uid'], $table, $fieldConf);
704 foreach ($dbAnalysis->itemArray
as $tempArr) {
705 if ($tempArr['table']==$searchTable && $tempArr['id']==$id) {
706 $theRecordList[]=Array('table'=>$table,'uid'=>$row['uid'],'field'=>$field,'pid'=>$row['pid']);
710 $GLOBALS['TYPO3_DB']->sql_free_result($mres);
712 return $theRecordList;
716 * Finding all references to file based on uploadfolder / filename
718 * @param string Upload folder where file is found
719 * @param string Filename to search for
720 * @return array Array with other arrays containing information about where references was found
722 function whereIsFileReferenced($uploadfolder,$filename) {
724 $fileFields = $this->getFileFields($uploadfolder); // Gets tables / Fields that reference to files...
725 $theRecordList=Array();
726 foreach ($fileFields as $info) {
727 $table=$info[0]; $field=$info[1];
728 $mres = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
729 'uid,pid,'.$TCA[$table]['ctrl']['label'].','.$field,
731 $field.' LIKE \'%'.$GLOBALS['TYPO3_DB']->quoteStr($filename, $table).'%\''
733 while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($mres)) {
734 // Now this is the field, where the reference COULD come from. But we're not garanteed, so we must carefully examine the data.
735 $tempArr = explode(',',trim($row[$field]));
736 foreach ($tempArr as $file) {
738 if ($file==$filename) {
739 $theRecordList[]=Array('table'=>$table,'uid'=>$row['uid'],'field'=>$field,'pid'=>$row['pid']);
744 return $theRecordList;
749 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE
]['XCLASS']['t3lib/class.t3lib_admin.php']) {
750 include_once($TYPO3_CONF_VARS[TYPO3_MODE
]['XCLASS']['t3lib/class.t3lib_admin.php']);