class.t3lib_admin.php

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

Generated on Sat Jul 24 04:17:16 2010 for TYPO3 API by  doxygen 1.4.7