00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00036 unset($MCONF);
00037 require ("conf.php");
00038 require ($BACK_PATH."init.php");
00039 require ($BACK_PATH."template.php");
00040 require_once (PATH_t3lib."class.t3lib_admin.php");
00041 require_once (PATH_t3lib."class.t3lib_loaddbgroup.php");
00042 require_once (PATH_t3lib."class.t3lib_querygenerator.php");
00043 require_once (PATH_t3lib."class.t3lib_xml.php");
00044 require_once (PATH_t3lib."class.t3lib_fullsearch.php");
00045
00046 $BE_USER->modAccess($MCONF,1);
00047
00048
00049
00050
00051
00052
00053 $LOCAL_LANG = Array (
00054 "default" => Array (
00055 "tables" => "Tables:",
00056 "fixLostRecord" => "Click to move this lost record to rootlevel (pid=0)",
00057
00058 "doktype" => "Document types:",
00059 "pages" => "Pages:",
00060 "total_pages" => "Total number of pages:",
00061 "deleted_pages" => "Marked-deleted pages:",
00062 "hidden_pages" => "Hidden pages:",
00063 "relations" => "Relations:",
00064 "relations_description" => "This will analyse the content of the tables and check if there are 'empty' relations between records or if files are missing from their expected position.",
00065
00066 "files_many_ref" => "Files referenced from more than one record:",
00067 "files_no_ref" => "Files with no references at all (delete them!):",
00068 "files_no_file" => "Missing files:",
00069 "select_db" => "Select fields:",
00070 "group_db" => "Group fields:",
00071
00072 "tree" => "The Page Tree:",
00073 "tree_description" => "This shows all pages in the system in one large tree. Beware that this will probably result in a very long document which will also take some time for the server to compute!",
00074 "records" => "Records Statistics:",
00075 "records_description" => "This shows some statistics for the records in the database. This runs through the entire page-tree and therefore it will also load the server heavily!",
00076 "search" => "Search Whole Database",
00077 "search_description" => "This searches through all database tables and records for a text string.",
00078 "filesearch" => "Search all filenames for pattern",
00079 "filesearch_description" => "Will search recursively for filenames in the PATH_site (subdirs to the website path) matching a certain regex pattern.",
00080 "title" => "Database integrity check"
00081 )
00082 );
00083
00084
00085
00086
00087
00088
00089
00090
00091 class SC_mod_tools_dbint_index {
00092 var $MCONF=array();
00093 var $MOD_MENU=array();
00094 var $MOD_SETTINGS=array();
00095 var $doc;
00096
00097 var $content;
00098 var $menu;
00099
00103 function init() {
00104 global $BE_USER,$LANG,$BACK_PATH,$TCA_DESCR,$TCA,$CLIENT,$TYPO3_CONF_VARS;
00105 $this->MCONF = $GLOBALS["MCONF"];
00106
00107 $this->menuConfig();
00108
00109 $this->doc = t3lib_div::makeInstance("mediumDoc");
00110 $this->doc->form='<form action="" method="POST">';
00111 $this->doc->backPath = $BACK_PATH;
00112
00113 $this->doc->JScode = '
00114 <script language="javascript" type="text/javascript">
00115 script_ended = 0;
00116 function jumpToUrl(URL) {
00117 document.location = URL;
00118 }
00119 </script>
00120 ';
00121 $this->doc->tableLayout = Array (
00122 "defRow" => Array (
00123 "0" => Array('<TD valign="top">','</td>'),
00124 "1" => Array('<TD valign="top">','</td>'),
00125 "defCol" => Array('<TD><img src="'.$this->doc->backPath.'clear.gif" width=15 height=1></td><td valign="top">','</td>')
00126 )
00127 );
00128 }
00129
00133 function menuConfig() {
00134 global $BE_USER,$LANG,$BACK_PATH,$TCA_DESCR,$TCA,$CLIENT,$TYPO3_CONF_VARS;
00135
00136
00137
00138
00139
00140 $this->MOD_MENU = array(
00141 "function" => array(
00142 0 => "[ MENU ]",
00143 "records" => "Record Statistics",
00144 "tree" => "Total Page Tree",
00145 "relations" => "Database Relations",
00146 "search" => "Full search",
00147 "filesearch" => "Find filename"
00148 ),
00149 "search" => array(
00150 "raw" => "Raw search in all fields",
00151 "query" => "Advanced query"
00152 ),
00153
00154 "search_query_smallparts" => "",
00155
00156 "queryConfig" => "",
00157 "queryTable" => "",
00158 "queryFields" => "",
00159 "queryLimit" => "",
00160 "queryOrder" => "",
00161 "queryOrderDesc" => "",
00162 "queryOrder2" => "",
00163 "queryOrder2Desc" => "",
00164 "queryGroup" => "",
00165
00166 "storeArray" => "",
00167 "storeQueryConfigs" => "",
00168
00169 "search_query_makeQuery" => array(
00170 "all" => "Select records",
00171 "count" => "Count results",
00172 "explain" => "Explain query",
00173 "csv" => "CSV Export",
00174 "xml" => "XML Export"
00175 ),
00176
00177
00178 "sword" => ""
00179 );
00180
00181 $this->MOD_SETTINGS = t3lib_BEfunc::getModuleData($this->MOD_MENU, t3lib_div::_GP("SET"), $this->MCONF["name"], "ses");
00182
00183 if (t3lib_div::_GP("queryConfig")) {
00184 $qA = t3lib_div::_GP("queryConfig");
00185 $this->MOD_SETTINGS = t3lib_BEfunc::getModuleData($this->MOD_MENU, array("queryConfig"=>serialize($qA)), $this->MCONF["name"], "ses");
00186 }
00187 }
00188
00192 function main() {
00193 global $BE_USER,$LANG,$BACK_PATH,$TCA_DESCR,$TCA,$CLIENT,$TYPO3_CONF_VARS;
00194
00195
00196
00197
00198 $this->content.=$this->doc->startPage($LANG->getLL("title"));
00199 $this->menu=t3lib_BEfunc::getFuncMenu(0,"SET[function]",$this->MOD_SETTINGS["function"],$this->MOD_MENU["function"]);
00200
00201 switch($this->MOD_SETTINGS["function"]) {
00202 case "search":
00203 $this->func_search();
00204 break;
00205 case "tree":
00206 $this->func_tree();
00207 break;
00208 case "records":
00209 $this->func_records();
00210 break;
00211 case "relations":
00212 $this->func_relations();
00213 break;
00214 case "filesearch":
00215 $this->func_filesearch();
00216 break;
00217 default:
00218 $this->func_default();
00219 break;
00220 }
00221
00222 if ($BE_USER->mayMakeShortcut()) {
00223 $this->content.=$this->doc->spacer(20).
00224 $this->doc->section('',$this->doc->makeShortcutIcon("","function,search,search_query_makeQuery",$this->MCONF["name"]));
00225 }
00226 }
00227
00231 function printContent() {
00232
00233 $this->content.=$this->doc->endPage();
00234 echo $this->content;
00235 }
00236
00240 function func_search() {
00241 global $BE_USER,$LANG,$BACK_PATH,$TCA_DESCR,$TCA,$CLIENT,$TYPO3_CONF_VARS;
00242
00243 $fullsearch = t3lib_div::makeInstance("t3lib_fullsearch");
00244 $this->content.=$this->doc->header($LANG->getLL("search"));
00245 $this->content.=$this->doc->spacer(5);
00246
00247 $menu2=t3lib_BEfunc::getFuncMenu(0,"SET[search]",$this->MOD_SETTINGS["search"],$this->MOD_MENU["search"]);
00248 if ($this->MOD_SETTINGS["search"]=="query") {
00249 $menu2.=t3lib_BEfunc::getFuncMenu(0,"SET[search_query_makeQuery]",$this->MOD_SETTINGS["search_query_makeQuery"],$this->MOD_MENU["search_query_makeQuery"]).
00250 " ".t3lib_BEfunc::getFuncCheck($GLOBALS["SOBE"]->id,"SET[search_query_smallparts]",$this->MOD_SETTINGS["search_query_smallparts"])." Show SQL parts";
00251 }
00252 $this->content.=$this->doc->section('',$this->menu);
00253 $this->content.=$this->doc->section('',$menu2).$this->doc->spacer(10);
00254
00255 switch($this->MOD_SETTINGS["search"]) {
00256 case "query":
00257 $this->content.=$fullsearch->queryMaker();
00258 break;
00259 case "raw":
00260 default:
00261 $this->content.=$this->doc->section('Search options:',$fullsearch->form(),0,1);
00262 $this->content.=$this->doc->section('Result:',$fullsearch->search(),0,1);
00263 break;
00264 }
00265 }
00266
00270 function func_tree() {
00271 global $BE_USER,$LANG,$BACK_PATH,$TCA_DESCR,$TCA,$CLIENT,$TYPO3_CONF_VARS;
00272
00273 $startID=0;
00274 $admin = t3lib_div::makeInstance("t3lib_admin");
00275 $admin->genTree_makeHTML=1;
00276 $admin->backPath = $BACK_PATH;
00277 $admin->genTree(intval($startID),'<img src="'.$BACK_PATH.'clear.gif" width=1 height=1 align=top>');
00278
00279 $this->content.=$this->doc->header($LANG->getLL("tree"));
00280 $this->content.=$this->doc->spacer(5);
00281 $this->content.=$this->doc->section('',$this->menu).$this->doc->divider(5);
00282 $this->content.=$this->doc->sectionEnd();
00283
00284 $this->content.=$admin->genTree_HTML;
00285 $this->content.=$admin->lostRecords($admin->genTree_idlist."0");
00286 }
00287
00291 function func_records() {
00292 global $BE_USER,$LANG,$BACK_PATH,$TCA_DESCR,$TCA,$CLIENT,$TYPO3_CONF_VARS;
00293 global $PAGES_TYPES;
00294
00295 $admin = t3lib_div::makeInstance("t3lib_admin");
00296 $admin->genTree_makeHTML=0;
00297 $admin->backPath = $BACK_PATH;
00298 $admin->genTree(0,'');
00299
00300 $this->content.=$this->doc->header($LANG->getLL("records"));
00301 $this->content.=$this->doc->spacer(5);
00302 $this->content.=$this->doc->section('',$this->menu);
00303
00304
00305 $codeArr=Array();
00306 $i++;
00307 $codeArr[$i][]='<img'.t3lib_iconWorks::skinImg($BACK_PATH,'gfx/i/pages.gif','width="18" height="16"').' hspace=4 align="top">';
00308 $codeArr[$i][]=$LANG->getLL("total_pages");
00309 $codeArr[$i][]=count($admin->page_idArray);
00310 $i++;
00311 if (t3lib_extMgm::isLoaded("cms")) {
00312 $codeArr[$i][]='<img'.t3lib_iconWorks::skinImg($BACK_PATH,'gfx/hidden_page.gif','width="18" height="16"').' hspace=4 align="top">';
00313 $codeArr[$i][]=$LANG->getLL("hidden_pages");
00314 $codeArr[$i][]=$admin->recStat["hidden"];
00315 $i++;
00316 }
00317 $codeArr[$i][]='<img'.t3lib_iconWorks::skinImg($BACK_PATH,'gfx/deleted_page.gif','width="18" height="16"').' hspace=4 align="top">';
00318 $codeArr[$i][]=$LANG->getLL("deleted_pages");
00319 $codeArr[$i][]=$admin->recStat["deleted"];
00320
00321 $this->content.=$this->doc->section($LANG->getLL("pages"),$this->doc->table($codeArr),0,1);
00322
00323
00324 $codeArr=Array();
00325 $doktype=$TCA["pages"]["columns"]["doktype"]["config"]["items"];
00326 if (is_array($doktype)) {
00327 reset($doktype);
00328 while(list($n,$setup)=each($doktype)) {
00329 if ($setup[1]!="--div--") {
00330 $codeArr[$n][]='<img'.t3lib_iconWorks::skinImg($BACK_PATH,'gfx/i/'.($PAGES_TYPES[$setup[1]]['icon'] ? $PAGES_TYPES[$setup[1]]['icon'] : $PAGES_TYPES["default"]['icon']),'width="18" height="16"').' hspace="4" align="top">';
00331 $codeArr[$n][]=$LANG->sL($setup[0]).' ('.$setup[1].')';
00332 $codeArr[$n][]=intval($admin->recStat[doktype][$setup[1]]);
00333 }
00334 }
00335 $this->content.=$this->doc->section($LANG->getLL("doktype"),$this->doc->table($codeArr),0,1);
00336 }
00337
00338
00339 $id_list="0,".implode($admin->page_idArray,",");
00340 $id_list = t3lib_div::rm_endcomma($id_list);
00341 $admin->lostRecords($id_list);
00342 if ($admin->fixLostRecord(t3lib_div::_GET('fixLostRecords_table'),t3lib_div::_GET('fixLostRecords_uid'))) {
00343 $admin = t3lib_div::makeInstance("admin_int");
00344 $admin->backPath = $BACK_PATH;
00345 $admin->genTree(0,'');
00346 $id_list="0,".implode($admin->page_idArray,",");
00347 $id_list = t3lib_div::rm_endcomma($id_list);
00348 $admin->lostRecords($id_list);
00349 }
00350
00351 $codeArr=Array();
00352 $countArr=$admin->countRecords($id_list);
00353 if (is_array($TCA)) {
00354 reset($TCA);
00355 while(list($t)=each($TCA)) {
00356 $codeArr[$t][]=t3lib_iconWorks::getIconImage($t,array(),$BACK_PATH,'hspace="4" align="top"');
00357 $codeArr[$t][]=$LANG->sL($TCA[$t]["ctrl"]["title"]);
00358 $codeArr[$t][]=$t;
00359
00360 if ($countArr["all"][$t]) {
00361 $theNumberOfRe = intval($countArr["non_deleted"][$t])."/".(intval($countArr["all"][$t])-intval($countArr["non_deleted"][$t]));
00362 } else {
00363 $theNumberOfRe ="";
00364 }
00365 $codeArr[$t][]=$theNumberOfRe;
00366
00367 $lr="";
00368 if (is_array($admin->lRecords[$t])) {
00369 reset($admin->lRecords[$t]);
00370 while(list(,$data)=each($admin->lRecords[$t])) {
00371 if (!t3lib_div::inList($admin->lostPagesList,$data[pid])) {
00372 $lr.='<NOBR><b><A HREF="index.php?SET[function]=records&fixLostRecords_table='.$t.'&fixLostRecords_uid='.$data[uid].'"><img src="'.$BACK_PATH.'gfx/required_h.gif" width=10 hspace=3 height=10 border=0 align="top" title="'.$LANG->getLL("fixLostRecord").'"></a>uid:'.$data[uid].', pid:'.$data[pid].', '.t3lib_div::fixed_lgd(strip_tags($data[title]),20).'</b></NOBR><BR>';
00373 } else {
00374 $lr.='<NOBR><img src="'.$BACK_PATH.'clear.gif" width=16 height=1 border=0><font color="Gray">uid:'.$data[uid].', pid:'.$data[pid].', '.t3lib_div::fixed_lgd(strip_tags($data[title]),20).'</font></NOBR><BR>';
00375 }
00376 }
00377 }
00378 $codeArr[$t][]=$lr;
00379 }
00380 $this->content.=$this->doc->section($LANG->getLL("tables"),$this->doc->table($codeArr),0,1);
00381 }
00382 }
00383
00387 function func_relations() {
00388 global $BE_USER,$LANG,$BACK_PATH,$TCA_DESCR,$TCA,$CLIENT,$TYPO3_CONF_VARS;
00389
00390 $this->content.=$this->doc->header($LANG->getLL("relations"));
00391 $this->content.=$this->doc->spacer(5);
00392 $this->content.=$this->doc->section('',$this->menu);
00393
00394 $admin = t3lib_div::makeInstance("t3lib_admin");
00395 $admin->genTree_makeHTML=0;
00396 $admin->backPath = $BACK_PATH;
00397
00398 $fkey_arrays = $admin->getGroupFields("");
00399 $admin->selectNonEmptyRecordsWithFkeys($fkey_arrays);
00400
00401
00402 $fileTest=$admin->testFileRefs();
00403
00404 $code="";
00405 if (is_array($fileTest["noReferences"])) {
00406 while(list(,$val)=each($fileTest["noReferences"])) {
00407 $code.="<NOBR>".$val[0]."/<b>".$val[1]."</b></NOBR><BR>";
00408 }
00409 }
00410 $this->content.=$this->doc->section($LANG->getLL("files_no_ref"),$code,1,1);
00411
00412 $code="";
00413 if (is_array($fileTest[moreReferences])) {
00414 while(list(,$val)=each($fileTest["moreReferences"])) {
00415 $code.="<NOBR>".$val[0]."/<b>".$val[1]."</b>: ".$val[2]." references:</NOBR><BR>".$val[3]."<BR><BR>";
00416 }
00417 }
00418 $this->content.=$this->doc->section($LANG->getLL("files_many_ref"),$code,1,1);
00419
00420 $code="";
00421 if (is_array($fileTest["noFile"])) {
00422 ksort($fileTest["noFile"]);
00423 reset($fileTest["noFile"]);
00424 while(list(,$val)=each($fileTest["noFile"])) {
00425 $code.="<NOBR>".$val[0]."/<b>".$val[1]."</b> is missing! </NOBR><BR>Referenced from: ".$val[2]."<BR><BR>";
00426 }
00427 }
00428 $this->content.=$this->doc->section($LANG->getLL("files_no_file"),$code,1,1);
00429 $this->content.=$this->doc->section($LANG->getLL("select_db"),$admin->testDBRefs($admin->checkSelectDBRefs),1,1);
00430 $this->content.=$this->doc->section($LANG->getLL("group_db"),$admin->testDBRefs($admin->checkGroupDBRefs),1,1);
00431 }
00432
00436 function func_filesearch() {
00437 global $BE_USER,$LANG,$BACK_PATH,$TCA_DESCR,$TCA,$CLIENT,$TYPO3_CONF_VARS;
00438
00439 $this->content.=$this->doc->header($LANG->getLL("relations"));
00440 $this->content.=$this->doc->spacer(5);
00441 $this->content.=$this->doc->section('',$this->menu);
00442
00443
00444 $pattern = t3lib_div::_GP("pattern");
00445 $pcontent='Enter regex pattern: <input type="text" name="pattern" value="'.htmlspecialchars($pattern?$pattern:$GLOBALS["TYPO3_CONF_VARS"]["BE"]["fileDenyPattern"]).'"> <input type="submit" name="Search">';
00446 $this->content.=$this->doc->section('Pattern',$pcontent,0,1);
00447
00448 if (strcmp($pattern,"")) {
00449 $dirs = t3lib_div::get_dirs(PATH_site);
00450 # debug($dirs);
00451 $lines=array();
00452 $depth=10;
00453
00454 foreach ($dirs as $key => $value) {
00455 $matching_files=array();
00456 $info="";
00457 if (!t3lib_div::inList("typo3,typo3conf,tslib,media,t3lib",$value)) {
00458 $info = $this->findFile(PATH_site.$value."/",$pattern,$matching_files,$depth);
00459 }
00460 if (is_array($info)) {
00461 $lines[]='<hr><b>'.$value.'/</b> being checked...';
00462 $lines[]='Dirs: '.$info[0];
00463 if ($info[2]) $lines[]='<span class="typo3-red">ERROR: Directories deeper than '.$depth.' levels</span>';
00464 $lines[]='Files: '.$info[1];
00465 $lines[]='Matching files:<br><nobr><span class="typo3-red">'.implode("<br>",$matching_files).'</span></nobr>';
00466 } else {
00467 $lines[]=$GLOBALS["TBE_TEMPLATE"]->dfw('<hr><b>'.$value.'/</b> not checked.');
00468 }
00469 }
00470
00471 $this->content.=$this->doc->section('Searching for filenames:',implode("<BR>",$lines),0,1);
00472 }
00473 }
00474
00478 function findFile($basedir,$pattern,&$matching_files,$depth) {
00479 $files_searched=0;
00480 $dirs_searched=0;
00481 $dirs_error=0;
00482
00483
00484 $files = t3lib_div::getFilesInDir($basedir,"",1);
00485 if (is_array($files)) {
00486 $files_searched+=count($files);
00487 foreach ($files as $value) {
00488 if (eregi($pattern,basename($value))) $matching_files[]=substr($value,strlen(PATH_site));
00489 }
00490 }
00491
00492
00493
00494 if ($depth>0) {
00495 $dirs = t3lib_div::get_dirs($basedir);
00496 if (is_array($dirs)) {
00497 $dirs_searched+=count($dirs);
00498
00499 foreach ($dirs as $value) {
00500 $inf= $this->findFile($basedir.$value."/",$pattern,$matching_files,$depth-1);
00501 $dirs_searched+=$inf[0];
00502 $files_searched+=$inf[1];
00503 $dirs_error=$inf[2];
00504 }
00505 }
00506 } else {
00507 $dirs = t3lib_div::get_dirs($basedir);
00508 if (is_array($dirs) && count($dirs)) {
00509 $dirs_error=1;
00510 }
00511 }
00512
00513 return array($dirs_searched,$files_searched,$dirs_error);
00514 }
00515
00519 function func_default() {
00520 global $BE_USER,$LANG,$BACK_PATH,$TCA_DESCR,$TCA,$CLIENT,$TYPO3_CONF_VARS;
00521
00522 $this->content.=$this->doc->header($LANG->getLL("title"));
00523 $this->content.=$this->doc->spacer(5);
00524 $this->content.=$this->doc->section('',$this->menu);
00525 $this->content.=$this->doc->section('<A HREF="index.php?SET[function]=records">'.$LANG->getLL("records").'</a>',$LANG->getLL("records_description"),1,1,0,1);
00526 $this->content.=$this->doc->section('<A HREF="index.php?SET[function]=tree">'.$LANG->getLL("tree").'</a>',$LANG->getLL("tree_description"),1,1,0,1);
00527 $this->content.=$this->doc->section('<A HREF="index.php?SET[function]=relations">'.$LANG->getLL("relations").'</a>',$LANG->getLL("relations_description"),1,1,0,1);
00528 $this->content.=$this->doc->section('<A HREF="index.php?SET[function]=search">'.$LANG->getLL("search").'</a>',$LANG->getLL("search_description"),1,1,0,1);
00529 $this->content.=$this->doc->section('<A HREF="index.php?SET[function]=filesearch">'.$LANG->getLL("filesearch").'</a>',$LANG->getLL("filesearch_description"),1,1,0,1);
00530 $this->content.=$this->doc->spacer(50);
00531 }
00532 }
00533
00534
00535 if (defined("TYPO3_MODE") && $TYPO3_CONF_VARS[TYPO3_MODE]["XCLASS"]["ext/lowlevel/dbint/index.php"]) {
00536 include_once($TYPO3_CONF_VARS[TYPO3_MODE]["XCLASS"]["ext/lowlevel/dbint/index.php"]);
00537 }
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548 $SOBE = t3lib_div::makeInstance("SC_mod_tools_dbint_index");
00549 $SOBE->init();
00550 $SOBE->main();
00551 $SOBE->printContent();
00552 ?>