TYPO3 API  SVNRelease
class.t3lib_admin.php
Go to the documentation of this file.
00001 <?php
00002 /***************************************************************
00003  *  Copyright notice
00004  *
00005  *  (c) 1999-2011 Kasper Skårhøj (kasperYYYY@typo3.com)
00006  *  All rights reserved
00007  *
00008  *  This script is part of the TYPO3 project. The TYPO3 project is
00009  *  free software; you can redistribute it and/or modify
00010  *  it under the terms of the GNU General Public License as published by
00011  *  the Free Software Foundation; either version 2 of the License, or
00012  *  (at your option) any later version.
00013  *
00014  *  The GNU General Public License can be found at
00015  *  http://www.gnu.org/copyleft/gpl.html.
00016  *  A copy is found in the textfile GPL.txt and important notices to the license
00017  *  from the author is found in LICENSE.txt distributed with these scripts.
00018  *
00019  *
00020  *  This script is distributed in the hope that it will be useful,
00021  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00022  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00023  *  GNU General Public License for more details.
00024  *
00025  *  This copyright notice MUST APPEAR in all copies of the script!
00026  ***************************************************************/
00027 /**
00028  * Contains a class for evaluation of database integrity according to $TCA
00029  * Most of these functions are considered obsolete!
00030  *
00031  * $Id: class.t3lib_admin.php 10121 2011-01-18 20:15:30Z ohader $
00032  * Revised for TYPO3 3.6 July/2003 by Kasper Skårhøj
00033  * XHTML compliant
00034  *
00035  * @author  Kasper Skårhøj <kasperYYYY@typo3.com>
00036  */
00037 /**
00038  * [CLASS/FUNCTION INDEX of SCRIPT]
00039  *
00040  *
00041  *
00042  *   93: class t3lib_admin
00043  *  128:     function genTree($theID, $depthData, $versions=FALSE)
00044  *  217:     function genTree_records($theID, $depthData, $table='', $versions=FALSE)
00045  *  292:     function genTreeStatus()
00046  *  315:     function lostRecords($pid_list)
00047  *  346:     function fixLostRecord($table,$uid)
00048  *  367:     function countRecords($pid_list)
00049  *  395:     function getGroupFields($mode)
00050  *  429:     function getFileFields($uploadfolder)
00051  *  452:     function getDBFields($theSearchTable)
00052  *  480:     function selectNonEmptyRecordsWithFkeys($fkey_arrays)
00053  *  569:     function testFileRefs ()
00054  *  620:     function testDBRefs($theArray)
00055  *  658:     function whereIsRecordReferenced($searchTable,$id)
00056  *  695:     function whereIsFileReferenced($uploadfolder,$filename)
00057  *
00058  * TOTAL FUNCTIONS: 14
00059  * (This index is automatically created/updated by the extension "extdeveval")
00060  *
00061  */
00062 
00063 
00064 /**
00065  * This class holds functions used by the TYPO3 backend to check the integrity of the database (The DBint module, 'lowlevel' extension)
00066  *
00067  * Depends on:      Depends on loaddbgroup from t3lib/
00068  *
00069  * @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!
00070  * @see SC_mod_tools_dbint_index::func_relations(), SC_mod_tools_dbint_index::func_records()
00071  * @author  Kasper Skårhøj <kasperYYYY@typo3.com>
00072  * @package TYPO3
00073  * @subpackage t3lib
00074  */
00075 class t3lib_admin {
00076     /** @var bool If set, genTree() includes deleted pages. This is default.*/
00077     var $genTree_includeDeleted = TRUE;
00078 
00079     /** @var bool  If set, genTree() includes versionized pages/records. This is default.*/
00080     var $genTree_includeVersions = TRUE;
00081 
00082     /** @var bool  If set, genTree() includes records from pages. */
00083     var $genTree_includeRecords = FALSE;
00084 
00085     /** @var string  Extra where-clauses for the tree-selection */
00086     var $perms_clause = '';
00087 
00088     /** @var int  If set, genTree() generates HTML, that visualizes the tree. */
00089     var $genTree_makeHTML = 0;
00090 
00091         // internal
00092     /** @var array Will hold id/rec pairs from genTree() */
00093     var $page_idArray = array();
00094 
00095     /** @var array */
00096     var $rec_idArray = array();
00097 
00098     /** @var string  Will hold the HTML-code visualising the tree. genTree() */
00099     var $genTree_HTML = '';
00100 
00101     /** @var string */
00102     var $backPath = '';
00103 
00104         // internal
00105     /** @var array */
00106     var $checkFileRefs = array();
00107 
00108     /** @var array From the select-fields */
00109     var $checkSelectDBRefs = array();
00110 
00111     /** @var array From the group-fields */
00112     var $checkGroupDBRefs = array();
00113 
00114     /** @var array Statistics */
00115     var $recStats = array(
00116         'allValid' => array(),
00117         'published_versions' => array(),
00118         'deleted' => array(),
00119     );
00120 
00121     /** @var array */
00122     var $lRecords = array();
00123 
00124     /** @var string */
00125     var $lostPagesList = '';
00126 
00127 
00128     /**
00129      * 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.
00130      *
00131      * @param   integer     a pid (page-record id) from which to start making the tree
00132      * @param   string      HTML-code (image-tags) used when this function calls itself recursively.
00133      * @param   boolean     Internal variable, don't set from outside!
00134      * @return  void
00135      */
00136     function genTree($theID, $depthData, $versions = FALSE) {
00137 
00138         if ($versions) {
00139             $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
00140                 'uid,title,doktype,deleted,t3ver_wsid,t3ver_id,t3ver_count,t3ver_swapmode' . (t3lib_extMgm::isLoaded('cms') ? ',hidden' : ''),
00141                 'pages',
00142                 'pid=-1 AND t3ver_oid=' . intval($theID) . ' ' . ((!$this->genTree_includeDeleted) ? 'AND deleted=0' : '') . $this->perms_clause,
00143                 '',
00144                 'sorting'
00145             );
00146         } else {
00147             $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
00148                 'uid,title,doktype,deleted' . (t3lib_extMgm::isLoaded('cms') ? ',hidden' : ''),
00149                 'pages',
00150                 'pid=' . intval($theID) . ' ' . ((!$this->genTree_includeDeleted) ? 'AND deleted=0' : '') . $this->perms_clause,
00151                 '',
00152                 'sorting'
00153             );
00154         }
00155 
00156             // Traverse the records selected:
00157         $a = 0;
00158         $c = $GLOBALS['TYPO3_DB']->sql_num_rows($res);
00159         while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
00160 
00161                 // Prepare the additional label used in the HTML output in case of versions:
00162             if ($versions) {
00163                 $versionLabel = '[v1.' . $row['t3ver_id'] . '; WS#' . $row['t3ver_wsid'] . ']';
00164             } else {
00165                 $versionLabel = '';
00166             }
00167 
00168             $a++;
00169             $newID = $row['uid'];
00170 
00171                 // Build HTML output:
00172             if ($this->genTree_makeHTML) {
00173                 $this->genTree_HTML .= LF . '<div><span class="nobr">';
00174                 $PM = 'join';
00175                 $LN = ($a == $c) ? 'blank' : 'line';
00176                 $BTM = ($a == $c) ? 'bottom' : '';
00177                 $this->genTree_HTML .= $depthData .
00178                         '<img' . t3lib_iconWorks::skinImg($this->backPath, 'gfx/ol/' . $PM . $BTM . '.gif', 'width="18" height="16"') . ' align="top" alt="" />' .
00179                         $versionLabel .
00180                         t3lib_iconWorks::getSpriteIconForRecord('pages', $row) .
00181                         htmlspecialchars($row['uid'] . ': ' . t3lib_div::fixed_lgd_cs(strip_tags($row['title']), 50)) . '</span></div>';
00182             }
00183 
00184                 // Register various data for this item:
00185             $this->page_idArray[$newID] = $row;
00186 
00187             $this->recStats['all_valid']['pages'][$newID] = $newID;
00188             #           if ($versions)  $this->recStats['versions']['pages'][$newID] = $newID;
00189             if ($row['deleted']) {
00190                 $this->recStats['deleted']['pages'][$newID] = $newID;
00191             }
00192             if ($versions && $row['t3ver_count'] >= 1) {
00193                 $this->recStats['published_versions']['pages'][$newID] = $newID;
00194             }
00195 
00196             if ($row['deleted']) {
00197                 $this->recStats['deleted']++;
00198             }
00199             if ($row['hidden']) {
00200                 $this->recStats['hidden']++;
00201             }
00202             $this->recStats['doktype'][$row['doktype']]++;
00203 
00204                 // Create the HTML code prefix for recursive call:
00205             $genHTML = $depthData . '<img' . t3lib_iconWorks::skinImg($this->backPath, 'gfx/ol/' . $LN . '.gif', 'width="18" height="16"') . ' align="top" alt="" />' . $versionLabel;
00206 
00207                 // If all records should be shown, do so:
00208             if ($this->genTree_includeRecords) {
00209                 foreach ($GLOBALS['TCA'] as $tableName => $cfg) {
00210                     if ($tableName != 'pages') {
00211                         $this->genTree_records($newID, $this->genTree_HTML ? $genHTML : '', $tableName);
00212                     }
00213                 }
00214             }
00215 
00216                 // Add sub pages:
00217             $this->genTree($newID, $this->genTree_HTML ? $genHTML : '');
00218 
00219                 // If versions are included in the tree, add those now:
00220             if ($this->genTree_includeVersions) {
00221                 $this->genTree($newID, $this->genTree_HTML ? $genHTML : '', TRUE);
00222             }
00223         }
00224     }
00225 
00226     /**
00227      * @param   integer     a pid (page-record id) from which to start making the tree
00228      * @param   string      HTML-code used when this function calls itself recursively.
00229      * @param   string      Table to get the records from
00230      * @param   bool        Internal variable, don't set from outside!
00231      * @return  void
00232      */
00233     function genTree_records($theID, $depthData, $table = '', $versions = FALSE) {
00234         global $TCA;
00235 
00236         if ($versions) {
00237                 // Select all records from table pointing to this page:
00238             $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
00239                 t3lib_BEfunc::getCommonSelectFields($table),
00240                 $table,
00241                 'pid=-1 AND t3ver_oid=' . intval($theID) .
00242                         (!$this->genTree_includeDeleted ? t3lib_BEfunc::deleteClause($table) : '')
00243             );
00244         } else {
00245                 // Select all records from table pointing to this page:
00246             $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
00247                 t3lib_BEfunc::getCommonSelectFields($table),
00248                 $table,
00249                 'pid=' . intval($theID) .
00250                         (!$this->genTree_includeDeleted ? t3lib_BEfunc::deleteClause($table) : '')
00251             );
00252         }
00253 
00254             // Traverse selected:
00255         $a = 0;
00256         $c = $GLOBALS['TYPO3_DB']->sql_num_rows($res);
00257         while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
00258 
00259                 // Prepare the additional label used in the HTML output in case of versions:
00260             if ($versions) {
00261                 $versionLabel = '[v1.' . $row['t3ver_id'] . '; WS#' . $row['t3ver_wsid'] . ']';
00262             } else {
00263                 $versionLabel = '';
00264             }
00265 
00266             $a++;
00267             $newID = $row['uid'];
00268 
00269                 // Build HTML output:
00270             if ($this->genTree_makeHTML) {
00271                 $this->genTree_HTML .= LF . '<div><span class="nobr">';
00272                 $PM = 'join';
00273                 $LN = ($a == $c) ? 'blank' : 'line';
00274                 $BTM = ($a == $c) ? 'bottom' : '';
00275                 $this->genTree_HTML .= $depthData .
00276                         '<img' . t3lib_iconWorks::skinImg($this->backPath, 'gfx/ol/' . $PM . $BTM . '.gif', 'width="18" height="16"') . ' align="top" alt="" />' .
00277                         $versionLabel .
00278                         t3lib_iconWorks::getSpriteIconForRecord($table, $row, array('title' => $table)) . htmlspecialchars($row['uid'] . ': ' . t3lib_BEfunc::getRecordTitle($table, $row)) . '</span></div>';
00279             }
00280 
00281                 // Register various data for this item:
00282             $this->rec_idArray[$table][$newID] = $row;
00283 
00284             $this->recStats['all_valid'][$table][$newID] = $newID;
00285             #           $this->recStats[$versions?'versions':'live'][$table][$newID] = $newID;
00286             if ($row['deleted']) {
00287                 $this->recStats['deleted'][$table][$newID] = $newID;
00288             }
00289             if ($versions && $row['t3ver_count'] >= 1 && $row['t3ver_wsid'] == 0) {
00290                 $this->recStats['published_versions'][$table][$newID] = $newID;
00291             }
00292 
00293             #           if ($row['deleted']) {$this->recStat['deleted']++;}
00294             #           if ($row['hidden']) {$this->recStat['hidden']++;}
00295 
00296 
00297                 // Select all versions of this record:
00298             if ($this->genTree_includeVersions && $TCA[$table]['ctrl']['versioningWS']) {
00299                 $genHTML = $depthData . '<img' . t3lib_iconWorks::skinImg($this->backPath, 'gfx/ol/' . $LN . '.gif', 'width="18" height="16"') . ' align="top" alt="" />';
00300 
00301                 $this->genTree_records($newID, $genHTML, $table, TRUE);
00302             }
00303         }
00304     }
00305 
00306     /**
00307      * Generates tree and returns statistics
00308      *
00309      * @return  array       Record statistics
00310      */
00311     function genTreeStatus($root = 0) {
00312         $this->genTree_includeDeleted = TRUE; // if set, genTree() includes deleted pages. This is default.
00313         $this->genTree_includeVersions = TRUE; // if set, genTree() includes verisonized pages/records. This is default.
00314         $this->genTree_includeRecords = TRUE; // if set, genTree() includes records from pages.
00315         $this->perms_clause = ''; // extra where-clauses for the tree-selection
00316         $this->genTree_makeHTML = 0; // if set, genTree() generates HTML, that visualizes the tree.
00317 
00318         $this->genTree($root, '');
00319 
00320         return $this->recStats;
00321     }
00322 
00323 
00324     /**
00325      * Fills $this->lRecords with the records from all tc-tables that are not attached to a PID in the pid-list.
00326      *
00327      * @param   string      list of pid's (page-record uid's). This list is probably made by genTree()
00328      * @return  void
00329      */
00330     function lostRecords($pid_list) {
00331         global $TCA;
00332         $this->lostPagesList = '';
00333         if ($pid_list) {
00334             foreach ($TCA as $table => $tableConf) {
00335                 t3lib_div::loadTCA($table);
00336 
00337                 $pid_list_tmp = $pid_list;
00338                 if (!isset($TCA[$table]['ctrl']['versioningWS']) || !$TCA[$table]['ctrl']['versioningWS']) {
00339                         // Remove preceding "-1," for non-versioned tables
00340                     $pid_list_tmp = preg_replace('/^\-1,/', '', $pid_list_tmp);
00341                 }
00342 
00343                 $garbage = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
00344                     'uid,pid,' . $TCA[$table]['ctrl']['label'],
00345                     $table,
00346                         'pid NOT IN (' . $pid_list_tmp . ')'
00347                 );
00348                 $lostIdList = array();
00349                 while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($garbage)) {
00350                     $this->lRecords[$table][$row['uid']] = array('uid' => $row['uid'], 'pid' => $row['pid'], 'title' => strip_tags($row[$TCA[$table]['ctrl']['label']]));
00351                     $lostIdList[] = $row['uid'];
00352                 }
00353                 if ($table == 'pages') {
00354                     $this->lostPagesList = implode(',', $lostIdList);
00355                 }
00356             }
00357         }
00358     }
00359 
00360     /**
00361      * 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.
00362      *
00363      * @param   string      Database tablename
00364      * @param   integer     The uid of the record which will have the PID value set to 0 (zero)
00365      * @return  boolean     True if done.
00366      */
00367     function fixLostRecord($table, $uid) {
00368         if ($table && $GLOBALS['TCA'][$table] && $uid && is_array($this->lRecords[$table][$uid]) && $GLOBALS['BE_USER']->user['admin']) {
00369 
00370             $updateFields = array();
00371             $updateFields['pid'] = 0;
00372             if ($GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['disabled']) { // If possible a lost record restored is hidden as default
00373                 $updateFields[$GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['disabled']] = 1;
00374             }
00375 
00376             $GLOBALS['TYPO3_DB']->exec_UPDATEquery($table, 'uid=' . intval($uid), $updateFields);
00377 
00378             return TRUE;
00379         } else {
00380             return FALSE;
00381         }
00382     }
00383 
00384     /**
00385      * Counts records from $TCA-tables that ARE attached to an existing page.
00386      *
00387      * @param   string      list of pid's (page-record uid's). This list is probably made by genTree()
00388      * @return  array       an array with the number of records from all $TCA-tables that are attached to a PID in the pid-list.
00389      */
00390     function countRecords($pid_list) {
00391         global $TCA;
00392         $list = array();
00393         $list_n = array();
00394         if ($pid_list) {
00395             foreach ($TCA as $table => $tableConf) {
00396                 t3lib_div::loadTCA($table);
00397 
00398                 $pid_list_tmp = $pid_list;
00399                 if (!isset($TCA[$table]['ctrl']['versioningWS']) || !$TCA[$table]['ctrl']['versioningWS']) {
00400                         // Remove preceding "-1," for non-versioned tables
00401                     $pid_list_tmp = preg_replace('/^\-1,/', '', $pid_list_tmp);
00402                 }
00403 
00404                 $count = $GLOBALS['TYPO3_DB']->exec_SELECTcountRows('uid', $table, 'pid IN (' . $pid_list_tmp . ')');
00405                 if ($count) {
00406                     $list[$table] = $count;
00407                 }
00408 
00409                 $count = $GLOBALS['TYPO3_DB']->exec_SELECTcountRows('uid', $table, 'pid IN (' . $pid_list_tmp . ')' . t3lib_BEfunc::deleteClause($table));
00410                 if ($count) {
00411                     $list_n[$table] = $count;
00412                 }
00413             }
00414         }
00415         return array('all' => $list, 'non_deleted' => $list_n);
00416     }
00417 
00418     /**
00419      * Finding relations in database based on type 'group' (files or database-uid's in a list)
00420      *
00421      * @param   string      $mode = file, $mode = db, $mode = '' (all...)
00422      * @return  array       An array with all fields listed that somehow are references to other records (foreign-keys) or files
00423      */
00424     function getGroupFields($mode) {
00425         global $TCA;
00426         $result = array();
00427         foreach ($TCA as $table => $tableConf) {
00428             t3lib_div::loadTCA($table);
00429             $cols = $TCA[$table]['columns'];
00430             foreach ($cols as $field => $config) {
00431                 if ($config['config']['type'] == 'group') {
00432                     if (
00433                         ((!$mode || $mode == 'file') && $config['config']['internal_type'] == 'file') ||
00434                         ((!$mode || $mode == 'db') && $config['config']['internal_type'] == 'db')
00435                     ) {
00436                         $result[$table][] = $field;
00437                     }
00438                 }
00439                 if ((!$mode || $mode == 'db') && $config['config']['type'] == 'select' && $config['config']['foreign_table']) {
00440                     $result[$table][] = $field;
00441                 }
00442             }
00443             if ($result[$table]) {
00444                 $result[$table] = implode(',', $result[$table]);
00445             }
00446         }
00447         return $result;
00448     }
00449 
00450     /**
00451      * Finds all fields that hold filenames from uploadfolder
00452      *
00453      * @param   string      Path to uploadfolder
00454      * @return  array       An array with all fields listed that have references to files in the $uploadfolder
00455      */
00456     function getFileFields($uploadfolder) {
00457         global $TCA;
00458         $result = array();
00459         foreach ($TCA as $table => $tableConf) {
00460             t3lib_div::loadTCA($table);
00461             $cols = $TCA[$table]['columns'];
00462             foreach ($cols as $field => $config) {
00463                 if ($config['config']['type'] == 'group' && $config['config']['internal_type'] == 'file' && $config['config']['uploadfolder'] == $uploadfolder) {
00464                     $result[] = array($table, $field);
00465                 }
00466             }
00467         }
00468         return $result;
00469     }
00470 
00471     /**
00472      * Returns an array with arrays of table/field pairs which are allowed to hold references to the input table name - according to $TCA
00473      *
00474      * @param   string      Table name
00475      * @return  array
00476      */
00477     function getDBFields($theSearchTable) {
00478         global $TCA;
00479         $result = array();
00480         reset($TCA);
00481         foreach ($TCA as $table => $tableConf) {
00482             t3lib_div::loadTCA($table);
00483             $cols = $TCA[$table]['columns'];
00484             foreach ($cols as $field => $config) {
00485                 if ($config['config']['type'] == 'group' && $config['config']['internal_type'] == 'db') {
00486                     if (trim($config['config']['allowed']) == '*' || strstr($config['config']['allowed'], $theSearchTable)) {
00487                         $result[] = array($table, $field);
00488                     }
00489                 } elseif ($config['config']['type'] == 'select' && $config['config']['foreign_table'] == $theSearchTable) {
00490                     $result[] = array($table, $field);
00491                 }
00492             }
00493         }
00494         return $result;
00495     }
00496 
00497     /**
00498      * This selects non-empty-records from the tables/fields in the fkey_array generated by getGroupFields()
00499      *
00500      * @param   array       Array with tables/fields generated by getGroupFields()
00501      * @return  void
00502      * @see getGroupFields()
00503      */
00504     function selectNonEmptyRecordsWithFkeys($fkey_arrays) {
00505         global $TCA;
00506         if (is_array($fkey_arrays)) {
00507             foreach ($fkey_arrays as $table => $field_list) {
00508                 if ($TCA[$table] && trim($field_list)) {
00509                     t3lib_div::loadTCA($table);
00510                     $fieldArr = explode(',', $field_list);
00511 
00512                     if (t3lib_extMgm::isLoaded('dbal')) {
00513                         $fields = $GLOBALS['TYPO3_DB']->admin_get_fields($table);
00514                         $field = array_shift($fieldArr);
00515                         $cl_fl = ($GLOBALS['TYPO3_DB']->MetaType($fields[$field]['type'], $table) == 'I'
00516                                     || $GLOBALS['TYPO3_DB']->MetaType($fields[$field]['type'], $table) == 'N'
00517                                     || $GLOBALS['TYPO3_DB']->MetaType($fields[$field]['type'], $table) == 'R')
00518                                 ? $field . '!=0'
00519                                 : $field . '!=\'\'';
00520                         foreach ($fieldArr as $field) {
00521                             $cl_fl .= ($GLOBALS['TYPO3_DB']->MetaType($fields[$field]['type'], $table) == 'I'
00522                                         || $GLOBALS['TYPO3_DB']->MetaType($fields[$field]['type'], $table) == 'N'
00523                                         || $GLOBALS['TYPO3_DB']->MetaType($fields[$field]['type'], $table) == 'R')
00524                                     ? ' OR ' . $field . '!=0'
00525                                     : ' OR ' . $field . '!=\'\'';
00526                         }
00527                         unset($fields);
00528                     }
00529                     else {
00530                         $cl_fl = implode('!=\'\' OR ', $fieldArr) . '!=\'\'';
00531                     }
00532 
00533                     $mres = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid,' . $field_list, $table, $cl_fl);
00534                     while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($mres)) {
00535                         foreach ($fieldArr as $field) {
00536                             if (trim($row[$field])) {
00537                                 $fieldConf = $TCA[$table]['columns'][$field]['config'];
00538                                 if ($fieldConf['type'] == 'group') {
00539                                     if ($fieldConf['internal_type'] == 'file') {
00540                                             // files...
00541                                         if ($fieldConf['MM']) {
00542                                             $tempArr = array();
00543                                             /** @var $dbAnalysis t3lib_loadDBGroup */
00544                                             $dbAnalysis = t3lib_div::makeInstance('t3lib_loadDBGroup');
00545                                             $dbAnalysis->start('', 'files', $fieldConf['MM'], $row['uid']);
00546                                             foreach ($dbAnalysis->itemArray as $somekey => $someval) {
00547                                                 if ($someval['id']) {
00548                                                     $tempArr[] = $someval['id'];
00549                                                 }
00550                                             }
00551                                         } else {
00552                                             $tempArr = explode(',', trim($row[$field]));
00553                                         }
00554                                         foreach ($tempArr as $file) {
00555                                             $file = trim($file);
00556                                             if ($file) {
00557                                                 $this->checkFileRefs[$fieldConf['uploadfolder']][$file] += 1;
00558                                             }
00559                                         }
00560                                     }
00561                                     if ($fieldConf['internal_type'] == 'db') {
00562                                         /** @var $dbAnalysis t3lib_loadDBGroup */
00563                                         $dbAnalysis = t3lib_div::makeInstance('t3lib_loadDBGroup');
00564                                         $dbAnalysis->start($row[$field], $fieldConf['allowed'], $fieldConf['MM'], $row['uid'], $table, $fieldConf);
00565                                         foreach ($dbAnalysis->itemArray as $tempArr) {
00566                                             $this->checkGroupDBRefs[$tempArr['table']][$tempArr['id']] += 1;
00567                                         }
00568                                     }
00569                                 }
00570                                 if ($fieldConf['type'] == 'select' && $fieldConf['foreign_table']) {
00571                                     /** @var $dbAnalysis t3lib_loadDBGroup */
00572                                     $dbAnalysis = t3lib_div::makeInstance('t3lib_loadDBGroup');
00573                                     $dbAnalysis->start($row[$field], $fieldConf['foreign_table'], $fieldConf['MM'], $row['uid'], $table, $fieldConf);
00574                                     foreach ($dbAnalysis->itemArray as $tempArr) {
00575                                         if ($tempArr['id'] > 0) {
00576                                             $this->checkGroupDBRefs[$fieldConf['foreign_table']][$tempArr['id']] += 1;
00577                                         }
00578                                     }
00579                                 }
00580                             }
00581                         }
00582                     }
00583                     $GLOBALS['TYPO3_DB']->sql_free_result($mres);
00584                 }
00585             }
00586         }
00587     }
00588 
00589     /**
00590      * Depends on selectNonEmpty.... to be executed first!!
00591      *
00592      * @return  array       Report over files; keys are "moreReferences", "noReferences", "noFile", "error"
00593      */
00594     function testFileRefs() {
00595         $output = array();
00596             // handle direct references with upload folder setting (workaround)
00597         $newCheckFileRefs = array();
00598         foreach ($this->checkFileRefs as $folder => $files) {
00599                 // only direct references without a folder setting
00600             if ($folder !== '') {
00601                 $newCheckFileRefs[$folder] = $files;
00602                 continue;
00603             }
00604 
00605             foreach ($files as $file => $references) {
00606 
00607                     // direct file references have often many references (removes occurences in the moreReferences section of the result array)
00608                 if ($references > 1) {
00609                     $references = 1;
00610                 }
00611 
00612                     // the directory must be empty (prevents checking of the root directory)
00613                 $directory = dirname($file);
00614                 if ($directory !== '') {
00615                     $newCheckFileRefs[$directory][basename($file)] = $references;
00616                 }
00617             }
00618         }
00619         $this->checkFileRefs = $newCheckFileRefs;
00620 
00621         foreach ($this->checkFileRefs as $folder => $fileArr) {
00622             $path = PATH_site . $folder;
00623             if (@is_dir($path)) {
00624                 $d = dir($path);
00625                 while ($entry = $d->read()) {
00626                     if (@is_file($path . '/' . $entry)) {
00627                         if (isset($fileArr[$entry])) {
00628                             if ($fileArr[$entry] > 1) {
00629                                 $temp = $this->whereIsFileReferenced($folder, $entry);
00630                                 $tempList = '';
00631                                 foreach ($temp as $inf) {
00632                                     $tempList .= '[' . $inf['table'] . '][' . $inf['uid'] . '][' . $inf['field'] . '] (pid:' . $inf['pid'] . ') - ';
00633                                 }
00634                                 $output['moreReferences'][] = array($path, $entry, $fileArr[$entry], $tempList);
00635                             }
00636                             unset($fileArr[$entry]);
00637                         } else {
00638                                 // contains workaround for direct references
00639                             if (!strstr($entry, 'index.htm') && !preg_match('/^' . preg_quote($GLOBALS['TYPO3_CONF_VARS']['BE']['fileadminDir'], '/') . '/', $folder)) {
00640                                 $output['noReferences'][] = array($path, $entry);
00641                             }
00642                         }
00643                     }
00644                 }
00645                 $d->close();
00646                 $tempCounter = 0;
00647                 foreach ($fileArr as $file => $value) {
00648                         // workaround for direct file references
00649                     if (preg_match('/^' . preg_quote($GLOBALS['TYPO3_CONF_VARS']['BE']['fileadminDir'], '/') . '/', $folder)) {
00650                         $file = $folder . '/' . $file;
00651                         $folder = '';
00652                         $path = substr(PATH_site, 0, -1);
00653                     }
00654                     $temp = $this->whereIsFileReferenced($folder, $file);
00655                     $tempList = '';
00656                     foreach ($temp as $inf) {
00657                         $tempList .= '[' . $inf['table'] . '][' . $inf['uid'] . '][' . $inf['field'] . '] (pid:' . $inf['pid'] . ') - ';
00658                     }
00659                     $tempCounter++;
00660                     $output['noFile'][substr($path, -3) . '_' . substr($file, 0, 3) . '_' . $tempCounter] = array($path, $file, $tempList);
00661                 }
00662             } else {
00663                 $output['error'][] = array($path);
00664             }
00665         }
00666         return $output;
00667     }
00668 
00669     /**
00670      * Depends on selectNonEmpty.... to be executed first!!
00671      *
00672      * @param   array       Table with key/value pairs being table names and arrays with uid numbers
00673      * @return  string      HTML Error message
00674      */
00675     function testDBRefs($theArray) {
00676         global $TCA;
00677         foreach ($theArray as $table => $dbArr) {
00678             if ($TCA[$table]) {
00679                 $idlist = array_keys($dbArr);
00680 
00681                 $theList = implode(',', $idlist);
00682                 if ($theList) {
00683                     $mres = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid', $table, 'uid IN (' . $theList . ')' . t3lib_BEfunc::deleteClause($table));
00684                     while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($mres)) {
00685                         if (isset($dbArr[$row['uid']])) {
00686                             unset ($dbArr[$row['uid']]);
00687                         } else {
00688                             $result .= 'Strange Error. ...<br />';
00689                         }
00690                     }
00691                     foreach ($dbArr as $theId => $theC) {
00692                         $result .= 'There are ' . $theC . ' records pointing to this missing or deleted record; [' . $table . '][' . $theId . ']<br />';
00693                     }
00694                 }
00695             } else {
00696                 $result .= 'Codeerror. Table is not a table...<br />';
00697             }
00698         }
00699         return $result;
00700     }
00701 
00702     /**
00703      * Finding all references to record based on table/uid
00704      *
00705      * @param   string      Table name
00706      * @param   integer     Uid of database record
00707      * @return  array       Array with other arrays containing information about where references was found
00708      */
00709     function whereIsRecordReferenced($searchTable, $id) {
00710         global $TCA;
00711         $fileFields = $this->getDBFields($searchTable); // Gets tables / Fields that reference to files...
00712         $theRecordList = array();
00713         foreach ($fileFields as $info) {
00714             $table = $info[0];
00715             $field = $info[1];
00716             t3lib_div::loadTCA($table);
00717             $mres = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
00718                 'uid,pid,' . $TCA[$table]['ctrl']['label'] . ',' . $field,
00719                 $table,
00720                     $field . ' LIKE \'%' . $GLOBALS['TYPO3_DB']->quoteStr($id, $table) . '%\''
00721             );
00722             while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($mres)) {
00723                     // Now this is the field, where the reference COULD come from. But we're not garanteed, so we must carefully examine the data.
00724                 $fieldConf = $TCA[$table]['columns'][$field]['config'];
00725                 $allowedTables = ($fieldConf['type'] == 'group') ? $fieldConf['allowed'] : $fieldConf['foreign_table'];
00726                 /** @var $dbAnalysis t3lib_loadDBGroup */
00727                 $dbAnalysis = t3lib_div::makeInstance('t3lib_loadDBGroup');
00728                 $dbAnalysis->start($row[$field], $allowedTables, $fieldConf['MM'], $row['uid'], $table, $fieldConf);
00729                 foreach ($dbAnalysis->itemArray as $tempArr) {
00730                     if ($tempArr['table'] == $searchTable && $tempArr['id'] == $id) {
00731                         $theRecordList[] = array('table' => $table, 'uid' => $row['uid'], 'field' => $field, 'pid' => $row['pid']);
00732                     }
00733                 }
00734             }
00735             $GLOBALS['TYPO3_DB']->sql_free_result($mres);
00736         }
00737         return $theRecordList;
00738     }
00739 
00740     /**
00741      * Finding all references to file based on uploadfolder / filename
00742      *
00743      * @param   string      Upload folder where file is found
00744      * @param   string      Filename to search for
00745      * @return  array       Array with other arrays containing information about where references was found
00746      */
00747     function whereIsFileReferenced($uploadfolder, $filename) {
00748         global $TCA;
00749         $fileFields = $this->getFileFields($uploadfolder); // Gets tables / Fields that reference to files...
00750         $theRecordList = array();
00751         foreach ($fileFields as $info) {
00752             $table = $info[0];
00753             $field = $info[1];
00754             $mres = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
00755                 'uid,pid,' . $TCA[$table]['ctrl']['label'] . ',' . $field,
00756                 $table,
00757                     $field . ' LIKE \'%' . $GLOBALS['TYPO3_DB']->quoteStr($filename, $table) . '%\''
00758             );
00759             while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($mres)) {
00760                     // Now this is the field, where the reference COULD come from. But we're not guaranteed, so we must carefully examine the data.
00761                 $tempArr = explode(',', trim($row[$field]));
00762                 foreach ($tempArr as $file) {
00763                     $file = trim($file);
00764                     if ($file == $filename) {
00765                         $theRecordList[] = array('table' => $table, 'uid' => $row['uid'], 'field' => $field, 'pid' => $row['pid']);
00766                     }
00767                 }
00768             }
00769         }
00770         return $theRecordList;
00771     }
00772 }
00773 
00774 
00775 if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_admin.php'])) {
00776     include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_admin.php']);
00777 }
00778 ?>