Documentation TYPO3 par Ameos |
00001 <?php 00002 /*************************************************************** 00003 * Copyright notice 00004 * 00005 * (c) 1999-2004 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 ***************************************************************/ 00099 // ******************************* 00100 // Set error reporting 00101 // ******************************* 00102 error_reporting (E_ALL ^ E_NOTICE); 00103 define('TYPO3_mainDir', 'typo3/'); // This is the directory of the backend administration for the sites of this TYPO3 installation. 00104 00105 00106 // Dependency: 00107 include_once('./typo3_src/t3lib/class.t3lib_div.php'); 00108 include_once('./typo3_src/t3lib/class.t3lib_db.php'); 00109 $TYPO3_DB = t3lib_div::makeInstance('t3lib_DB'); 00110 00111 00119 function debug($p1,$p2='') { 00120 t3lib_div::debug($p1,$p2); 00121 } 00122 00123 00124 00133 class t3lib_superadmin { 00134 00135 // External, static: 00136 var $targetWindow = 'superAdminWindow'; 00137 var $targetWindowAdmin = 'superAdminWindowAdmin'; 00138 var $targetWindowInstall = 'superAdminWindowInstall'; 00139 var $scriptName = 'superadmin.php'; 00140 00141 // GP vars: 00142 var $show; // "menu", "all", "admin", "info", "rmTempCached", "localext" 00143 var $type; // "phpinfo", "page" - default renders a frameset 00144 var $exp; // Additional parameter, typically a md5-hash pointing to an installation of TYPO3 00145 00146 // Internal, static: 00147 var $parentDirs = array(); // Configured directories to search 00148 var $globalSiteInfo = array(); // Array with information about found TYPO3 installations 00149 00150 var $currentUrl = ''; 00151 var $mapDBtoKey = array(); 00152 var $collectAdminPasswords = array(); 00153 var $changeAdminPasswords = array(); 00154 var $collectInstallPasswords = array(); 00155 00156 // Control: 00157 var $full = 0; // If set, the full information array per site is printed. 00158 00159 var $noCVS = 0; // See tools/em/index.php.... 00160 00161 00162 00163 00164 00165 00166 00167 00168 /********************************** 00169 * 00170 * Initialize stuff 00171 * 00172 **********************************/ 00173 00179 function t3lib_superadmin() { 00180 $this->show = t3lib_div::_GP('show'); 00181 $this->type = t3lib_div::_GP('type'); 00182 $this->exp = t3lib_div::_GP('exp'); 00183 } 00184 00191 function init($parentDirs) { 00192 $this->parentDirs = $parentDirs; 00193 } 00194 00195 00196 00197 00198 00199 00200 00201 00202 /************************** 00203 * 00204 * Main functions 00205 * 00206 **************************/ 00207 00214 function defaultSet() { 00215 00216 // Creating content based on "type" variable: 00217 switch($this->type) { 00218 case 'phpinfo': 00219 phpinfo(); 00220 break; 00221 case 'page': 00222 ?> 00223 <!DOCTYPE html 00224 PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 00225 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 00226 <html> 00227 <head> 00228 <style type="text/css"> 00229 .redclass {color: red;} 00230 P {font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 11px} 00231 BODY {font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 10px} 00232 H1 {font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 20px; color: #000066;} 00233 H2 {font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 17px; color: #000066;} 00234 H3 {font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 14px; color: #000066;} 00235 H4 {font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 11px; color: maroon;} 00236 TD {font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 10px} 00237 </style> 00238 <title>TYPO3 Super Admin</title> 00239 </head> 00240 <body> 00241 <?php 00242 echo $this->make(); 00243 ?> 00244 </body> 00245 </html> 00246 <?php 00247 break; 00248 default: 00249 ?> 00250 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> 00251 <html> 00252 <head> 00253 <title>TYPO3 Super Admin</title> 00254 </head> 00255 <frameset cols="250,*"> 00256 <frame name="TSAmenu" src="superadmin.php?type=page&show=menu" marginwidth="10" marginheight="10" scrolling="auto" frameborder="0"> 00257 <frame name="TSApage" src="superadmin.php?type=page" marginwidth="10" marginheight="10" scrolling="auto" frameborder="0"> 00258 </frameset> 00259 </html> 00260 <?php 00261 break; 00262 } 00263 } 00264 00270 function make() { 00271 00272 // Creating information about the sites found: 00273 $content = $this->initProcess(); 00274 00275 // Output mode: 00276 switch($this->show) { 00277 case 'menu': 00278 $lines=array(); 00279 $lines[]=$this->setMenuItem('info','INFO'); 00280 $lines[]=$this->setMenuItem('update','UPDATE'); 00281 $lines[]=''; 00282 $lines[]='<a href="'.htmlspecialchars($this->scriptName.'?type=page').'" target="TSApage">Default</a>'; 00283 $lines[]='<a href="'.htmlspecialchars($this->scriptName.'?type=page&show=all').'" target="TSApage">All details</a>'; 00284 $lines[]='<a href="'.htmlspecialchars($this->scriptName.'?type=page&show=admin').'" target="TSApage">Admin logins</a>'; 00285 $lines[]='<a href="'.htmlspecialchars($this->scriptName.'?type=phpinfo').'" target="TSApage">phpinfo()</a>'; 00286 $lines[]='<a href="'.htmlspecialchars($this->scriptName.'?type=page&show=localext').'" target="TSApage">Local extensions</a>'; 00287 $lines[]=''; 00288 $content = implode('<br />',$lines); 00289 $content.= '<hr />'; 00290 $content.=$this->menuContent($this->exp); 00291 return '<h2 align="center">TYPO3<br />Super Admin</h2>'.$content; 00292 break; 00293 case 'all': 00294 return ' 00295 <h1>All details:</h1> 00296 <h2>Overview:</h2> 00297 '.$this->makeTable().' 00298 <br /><hr /><br /> 00299 <h1>Details per site:</h1> 00300 '.$content; 00301 break; 00302 case 'admin': 00303 $content = $this->setNewPasswords(); 00304 $this->makeTable(); 00305 return $content.' 00306 <h1>Admin options:</h1> 00307 00308 <h2>Admin logins:</h2> 00309 '.$this->makeAdminLogin().' 00310 <br /><hr /><br /> 00311 00312 <h2>TBE Admin Passwords:</h2> 00313 '.t3lib_div::view_array($this->collectAdminPasswords).' 00314 <br /><hr /><br /> 00315 00316 <h2>Install Tool Passwords:</h2> 00317 '.t3lib_div::view_array($this->collectInstallPasswords).' 00318 <br /><hr /><br /> 00319 00320 <h2>Change TBE Admin Passwords:</h2> 00321 '.$this->changeAdminPasswordsForm().' 00322 <br /><hr /><br />'; 00323 break; 00324 case 'info': 00325 return ' 00326 <h1>Single site details</h1> 00327 '.$this->singleSite($this->exp). 00328 '<br />'; 00329 break; 00330 case 'rmTempCached': 00331 return ' 00332 <h1>Removing temp_CACHED_*.php files</h1> 00333 '.$this->rmCachedFiles($this->exp). 00334 '<br />'; 00335 break; 00336 case 'localext': 00337 return ' 00338 <h1>Local Extensions Found:</h1> 00339 '.$this->localExtensions(). 00340 '<br />'; 00341 break; 00342 default: 00343 return ' 00344 <h1>Default info:</h1>'. 00345 $content; 00346 break; 00347 } 00348 } 00349 00350 00351 00352 00353 00354 00355 00356 00357 00358 00359 /******************************** 00360 * 00361 * Output preparation 00362 * 00363 *******************************/ 00364 00372 function setMenuItem($code,$label) { 00373 $out = '<a href="'.htmlspecialchars($this->scriptName.'?type=page&show=menu&exp='.$code).'" target="TSAmenu">'.htmlspecialchars($label).'</a>'; 00374 if ($code==$this->exp) { 00375 $out = '<span style="color:red;">>></span>'.$out; 00376 } 00377 return $out; 00378 } 00379 00386 function error($str) { 00387 $out = '<span style="color:red; font-size: 14px; font-weight: bold;">'.htmlspecialchars($str).'</span>'; 00388 return $out; 00389 } 00390 00397 function headerParentDir($str) { 00398 $out = '<h2>'.htmlspecialchars($str).'</h2>'; 00399 return $out; 00400 } 00401 00408 function headerSiteDir($str) { 00409 $out = '<h3>'.htmlspecialchars($str).'</h3>'; 00410 return $out; 00411 } 00412 00413 00414 00415 00416 00417 00418 00419 00420 00421 00422 00423 00424 00425 00426 00427 00428 00429 /******************************** 00430 * 00431 * Collection information 00432 * 00433 *******************************/ 00434 00440 function initProcess() { 00441 $content = ''; 00442 00443 foreach($this->parentDirs as $k => $v) { 00444 $dir = ereg_replace('/$','',$v['dir']); 00445 $baseUrl=ereg_replace('/$','',$v['url']); 00446 $content.='<br /><br /><br />'; 00447 $content.=$this->headerParentDir($dir); 00448 if (@is_dir($dir)) { 00449 $in_dirs = t3lib_div::get_dirs($dir); 00450 asort($in_dirs); 00451 reset($in_dirs); 00452 $dirArr=array(); 00453 while(list($k,$v)=each($in_dirs)) { 00454 if (substr($v,0,9)!='typo3_src') { 00455 $this->currentUrl = $baseUrl.'/'.$v; 00456 $content.= $this->headerSiteDir($v); 00457 $content.= $this->processSiteDir($dir.'/'.$v,$dir); 00458 } 00459 } 00460 } else { 00461 $content.=$this->error('"'.$dir.'" was not a directory!'); 00462 } 00463 } 00464 00465 return $content; 00466 } 00467 00478 function processSiteDir($path,$dir) { 00479 if (@is_dir($path)) { 00480 $localconf = $path.'/typo3conf/localconf.php'; 00481 if (@is_file($localconf)) { 00482 $key = md5($localconf); 00483 $this->includeLocalconf($localconf); 00484 00485 $this->mapDBtoKey[$this->globalSiteInfo[$key]['siteInfo']['TYPO3_db']] = $key; 00486 $this->globalSiteInfo[$key]['siteInfo']['MAIN_DIR'] = $dir; 00487 $this->globalSiteInfo[$key]['siteInfo']['SA_PATH'] = $path; 00488 $this->globalSiteInfo[$key]['siteInfo']['URL'] = $this->currentUrl.'/'; 00489 $this->globalSiteInfo[$key]['siteInfo']['ADMIN_URL'] = $this->currentUrl.'/'.TYPO3_mainDir; 00490 $this->globalSiteInfo[$key]['siteInfo']['INSTALL_URL'] = $this->currentUrl.'/'.TYPO3_mainDir.'install/'; 00491 00492 // Connect to database: 00493 $conMsg = $this->connectToDatabase($this->globalSiteInfo[$key]['siteInfo']); 00494 if (!$conMsg) { 00495 $this->getDBInfo($key); 00496 $out.=''; 00497 } else { 00498 $out = $conMsg; 00499 } 00500 00501 // Show details: 00502 if ($this->full) { 00503 $out.=t3lib_div::view_array($this->globalSiteInfo[$key]); 00504 } else { 00505 $out.=t3lib_div::view_array($this->globalSiteInfo[$key]['siteInfo']); 00506 } 00507 } else $out = $this->error($localconf.' is not a file!'); 00508 } else $out = $this->error($path.' is not a directory!'); 00509 return $out; 00510 } 00511 00520 function includeLocalconf($localconf) { 00521 include($localconf); 00522 00523 $siteInfo=array(); 00524 $siteInfo['sitename'] = $TYPO3_CONF_VARS['SYS']['sitename']; 00525 $siteInfo['TYPO3_db'] = $typo_db; 00526 $siteInfo['TYPO3_db_username'] = $typo_db_username; 00527 $siteInfo['TYPO3_db_password'] = $typo_db_password; 00528 $siteInfo['TYPO3_db_host'] = $typo_db_host; 00529 $siteInfo['installToolPassword'] = $TYPO3_CONF_VARS['BE']['installToolPassword']; 00530 $siteInfo['warningEmailAddress'] = $TYPO3_CONF_VARS['BE']['warning_email_addr']; 00531 $siteInfo['warningMode'] = $TYPO3_CONF_VARS['BE']['warning_mode']; 00532 00533 $this->globalSiteInfo[md5($localconf)] = array('siteInfo'=>$siteInfo,'TYPO3_CONF_VARS'=>$TYPO3_CONF_VARS); 00534 return $siteInfo; 00535 } 00536 00544 function connectToDatabase($siteInfo) { 00545 if (@mysql_pconnect($siteInfo['TYPO3_db_host'], $siteInfo['TYPO3_db_username'], $siteInfo['TYPO3_db_password'])) { 00546 if (!$siteInfo['TYPO3_db']) { 00547 return $this->error('No database selected'); 00548 } elseif (!mysql_select_db($siteInfo['TYPO3_db'])) { 00549 return $this->error('Cannot connect to the current database, "'.$siteInfo['TYPO3_db'].'"'); 00550 } 00551 } else { 00552 return $this->error('The current username, password or host was not accepted when the connection to the database was attempted to be established!'); 00553 } 00554 } 00555 00556 00566 function getDBInfo($key) { 00567 $DB = $this->globalSiteInfo[$key]['siteInfo']['TYPO3_db']; 00568 00569 // Non-admin users 00570 $query = $GLOBALS['TYPO3_DB']->SELECTquery('count(*)', 'be_users', 'admin=0 AND NOT deleted'); 00571 $res = mysql($DB, $query); 00572 $row = mysql_fetch_row($res); 00573 $this->globalSiteInfo[$key]['siteInfo']['BE_USERS_NONADMIN'] = $row[0]; 00574 00575 // Admin users 00576 $query = $GLOBALS['TYPO3_DB']->SELECTquery('count(*)', 'be_users', 'admin!=0 AND NOT deleted'); 00577 $res = mysql($DB, $query); 00578 $row = mysql_fetch_row($res); 00579 $this->globalSiteInfo[$key]['siteInfo']['BE_USERS_ADMIN'] = $row[0]; 00580 00581 // Select Admin users 00582 $query = $GLOBALS['TYPO3_DB']->SELECTquery('uid,username,password,email,realName,disable', 'be_users', 'admin!=0 AND NOT deleted'); 00583 $res = mysql($DB, $query); 00584 while($row = mysql_fetch_assoc($res)) { 00585 $this->globalSiteInfo[$key]['siteInfo']['ADMINS'][] = $row; 00586 } 00587 } 00588 00589 00590 00591 00592 00593 00594 00595 00596 00597 00598 00599 00600 00601 00602 00603 00604 00605 /****************************** 00606 * 00607 * Content: Installation Overview 00608 * 00609 ******************************/ 00610 00616 function makeTable() { 00617 00618 // Header row 00619 $info = array(); 00620 $info[] = 'Site:'; 00621 $info[] = 'Path:'; 00622 $info[] = 'Database:'; 00623 $info[] = 'Username'; 00624 $info[] = 'Password'; 00625 $info[] = 'Host'; 00626 $info[] = 'Links (new win)'; 00627 $info[] = '#Users NA/A'; 00628 $info[] = 'Admin be_users Info'; 00629 $info[] = 'Install Tool Password'; 00630 $info[] = 'Warning email address'; 00631 $info[] = 'W.mode'; 00632 $mainArrRows[] = ' 00633 <tr bgcolor="#eeeeee"> 00634 <td nowrap="nowrap" valign="top">'.implode('</td> 00635 <td nowrap="nowrap" valign="top">',$info).'</td> 00636 </tr>'; 00637 00638 // Traverse globalSiteInfo for each site: 00639 foreach($this->globalSiteInfo as $k => $all) { 00640 $info = array(); 00641 00642 // Sitename and Database details: 00643 $info[] = htmlspecialchars($all['siteInfo']['sitename']); 00644 $info[] = '<span style="color:#666666;">'.htmlspecialchars($all['siteInfo']['MAIN_DIR']).'</span>'.htmlspecialchars(substr($all['siteInfo']['SA_PATH'],strlen($all['siteInfo']['MAIN_DIR']))); 00645 $info[] = htmlspecialchars($all['siteInfo']['TYPO3_db']); 00646 $info[] = htmlspecialchars($all['siteInfo']['TYPO3_db_username']); 00647 $info[] = htmlspecialchars($all['siteInfo']['TYPO3_db_password']); 00648 $info[] = htmlspecialchars($all['siteInfo']['TYPO3_db_host']); 00649 00650 // URL 00651 $info[] = '<a href="'.htmlspecialchars($all['siteInfo']['URL']).'" target="'.$this->targetWindow.'">Site</a>'. 00652 ' / <a href="'.htmlspecialchars($all['siteInfo']['ADMIN_URL']).'" target="'.$this->targetWindowAdmin.'">Admin</a>'. 00653 ' / <a href="'.htmlspecialchars($all['siteInfo']['INSTALL_URL']).'" target="'.$this->targetWindowInstall.'">Install</a>'; 00654 $info[] = htmlspecialchars($all['siteInfo']['BE_USERS_NONADMIN'].'/'.$all['siteInfo']['BE_USERS_ADMIN']); 00655 00656 // Admin 00657 if (is_array($all['siteInfo']['ADMINS'])) { 00658 $lines = array(); 00659 foreach($all['siteInfo']['ADMINS'] as $vArr) { 00660 $lines[] = htmlspecialchars($vArr['password'].' - '.$vArr['username'].' ('.$vArr['realName'].', '.$vArr['email'].')'); 00661 $this->collectAdminPasswords[$vArr['password']][] = array( 00662 'path' => $all['siteInfo']['SA_PATH'], 00663 'site' => $all['siteInfo']['sitename'], 00664 'database' => $all['siteInfo']['TYPO3_db'], 00665 'user' => $vArr['username'], 00666 'name_email' => $vArr['realName'].', '.$vArr['email'] 00667 ); 00668 $this->changeAdminPasswords[$vArr['password']][] = $all['siteInfo']['TYPO3_db'].':'.$vArr['uid'].':'.$vArr['username']; 00669 } 00670 $info[] = implode('<br />',$lines); 00671 } else { 00672 $info[] = $this->error('No DB connection!'); 00673 } 00674 // Install 00675 $info[] = htmlspecialchars($all['siteInfo']['installToolPassword']); 00676 $this->collectInstallPasswords[$all['siteInfo']['installToolPassword']][] = $all['siteInfo']['SA_PATH'].' - '.$all['siteInfo']['sitename'].' - ('.$all['siteInfo']['TYPO3_db'].')'; 00677 00678 $info[] = htmlspecialchars($all['siteInfo']['warningEmailAddress']); 00679 $info[] = htmlspecialchars($all['siteInfo']['warningMode']); 00680 00681 // compile 00682 $mainArrRows[] = ' 00683 <tr> 00684 <td nowrap="nowrap" valign="top">'.implode('</td> 00685 <td nowrap="nowrap" valign="top">',$info).'</td> 00686 </tr>'; 00687 } 00688 00689 // Compile / return table finally: 00690 $table = '<table border="1" cellpadding="1" cellspacing="1">'.implode('',$mainArrRows).'</table>'; 00691 return $table; 00692 } 00693 00694 00695 00696 00697 00698 00699 00700 00701 00702 00703 00704 00705 00706 00707 /****************************** 00708 * 00709 * Content: Local extensions 00710 * 00711 ******************************/ 00712 00719 function localExtensions() { 00720 $this->extensionInfoArray=array(); 00721 00722 // Traverse $this->globalSiteInfo for local extensions: 00723 foreach($this->globalSiteInfo as $k => $all) { 00724 if ($all['siteInfo']['SA_PATH']) { 00725 $extDir = $all['siteInfo']['SA_PATH'].'/typo3conf/ext/'; 00726 if (@is_dir($extDir)) { 00727 $this->extensionInfoArray['site'][$k] = array(); 00728 00729 // Get extensions in local directory 00730 $extensions=t3lib_div::get_dirs($extDir); 00731 if (is_array($extensions)) { 00732 foreach($extensions as $extKey) { 00733 // Getting and setting information for extension: 00734 $eInfo = $this->getExtensionInfo($extDir,$extKey,$k); 00735 $this->extensionInfoArray['site'][$k][$extKey] = $eInfo; 00736 $this->extensionInfoArray['ext'][$extKey][$k] = $eInfo; 00737 } 00738 } 00739 } 00740 } 00741 } 00742 00743 // Display results: 00744 $out=''; 00745 $headerRow = ' 00746 <tr bgcolor="#ccccee" style="font-weight:bold;"> 00747 <td>Extension key</td> 00748 <td>Path</td> 00749 <td>Title</td> 00750 <td>Ver.</td> 00751 <td>Files</td> 00752 <td><span title="If M, then there is a manual.">M</span></td> 00753 <td>Last mod. time</td> 00754 <td>Hash off all file mod. times:</td> 00755 <td>TYPO3 ver. req.</td> 00756 <td>CGL compliance</td> 00757 </tr> 00758 '; 00759 00760 // PER EXTENSION: 00761 if (is_array($this->extensionInfoArray['ext'])) { 00762 $extensionKeysCollect=array(); 00763 00764 ksort($this->extensionInfoArray['ext']); 00765 reset($this->extensionInfoArray['ext']); 00766 $rows=array( 00767 'reg'=>array(), 00768 'user'=>array() 00769 ); 00770 00771 foreach($this->extensionInfoArray['ext'] as $extKey => $instances) { 00772 $mtimes = array(); 00773 00774 // Find most recent mtime of the options: 00775 reset($instances); 00776 while(list($k,$eInfo)=each($instances)) { 00777 $mtimes[] = $eInfo['mtime']; 00778 } 00779 // Max mtime: 00780 $maxMtime = max($mtimes); 00781 $c = 0; 00782 00783 // So, traverse all sites with the extension present: 00784 foreach($instances as $k => $eInfo) { 00785 // Set background color if mtime matches 00786 if ($maxMtime==$eInfo['mtime']) { 00787 $this->extensionInfoArray['site'][$k][$extKey]['_highlight']=1; 00788 $bgCol = $eInfo['dirtype']=='link' ? ' bgcolor="#ffcccc"' : ' bgcolor="#eeeeee"'; 00789 } else { 00790 $bgCol = ' style="color: #999999; font-style: italic;"'; 00791 } 00792 00793 // Make row: 00794 $type = substr($extKey,0,5)!='user_' ? 'reg' : 'user'; 00795 if ($type=='reg') $extensionKeysCollect[] = $extKey; 00796 00797 if (!is_array($eInfo)) { 00798 // Standard listing: 00799 $rows[$type][] = ' 00800 <tr> 00801 '.(!$c?'<td rowspan="'.count($instances).'">'.htmlspecialchars($extKey).'</td>':'').' 00802 <td nowrap="nowrap" bgcolor="#ccddcc">'.htmlspecialchars($this->globalSiteInfo[$k]['siteInfo']['SA_PATH']).'</td> 00803 <td nowrap="nowrap" bgcolor="#ccddcc" colspan="8"><em>'.htmlspecialchars($eInfo).'</em></td> 00804 </tr> 00805 '; 00806 } else { 00807 // Standard listing: 00808 $rows[$type][] = ' 00809 <tr> 00810 '.(!$c?'<td rowspan="'.count($instances).'">'.htmlspecialchars($extKey).'</td>':'').' 00811 <td nowrap="nowrap"'.$bgCol.'>'.htmlspecialchars($this->globalSiteInfo[$k]['siteInfo']['SA_PATH']).'</td> 00812 <td nowrap="nowrap"'.$bgCol.'>'.htmlspecialchars($eInfo['title']).'</td> 00813 <td nowrap="nowrap"'.$bgCol.'>'.htmlspecialchars($eInfo['version']).'</td> 00814 <td nowrap="nowrap"'.$bgCol.'>'.htmlspecialchars($eInfo['numberfiles']).'</td> 00815 <td nowrap="nowrap"'.$bgCol.'>'.htmlspecialchars($eInfo['manual']?'M':'-').'</td> 00816 <td nowrap="nowrap"'.$bgCol.'>'.htmlspecialchars($eInfo['mtime']?date('d-m-y H:i:s',$eInfo['mtime']):'').'</td> 00817 <td nowrap="nowrap"'.$bgCol.'>'.htmlspecialchars($eInfo['mtime_hash']).'</td> 00818 00819 <td'.$bgCol.'>'.htmlspecialchars($eInfo['TYPO3_version']).'</td> 00820 <td'.$bgCol.'><img src="clear.gif" width="150" height="1" alt="" /><br />'.htmlspecialchars($eInfo['CGLcompliance'].($eInfo['CGLcompliance_note'] ? ' - '.$eInfo['CGLcompliance_note'] : '')).'</td> 00821 </tr> 00822 '; 00823 } 00824 $c++; 00825 } 00826 } 00827 00828 // Extensions with registered extension keys: 00829 $out.=' 00830 <h3>Registered extensions:</h3> 00831 <table border="1">'.$headerRow.implode('',$rows['reg']).'</table>'; 00832 00833 // List of those extension keys in a form field: 00834 $extensionKeysCollect = array_unique($extensionKeysCollect); 00835 asort($extensionKeysCollect); 00836 $out.='<form action=""><textarea cols="80" rows="10">'.implode(chr(10),$extensionKeysCollect).'</textarea></form>'; 00837 00838 // USER extension (prefixed "user_") 00839 $out.='<br /> 00840 <h3>User extensions:</h3> 00841 <table border="1">'.$headerRow.implode('',$rows['user']).'</table>'; 00842 } 00843 00844 // PER SITE: 00845 if (is_array($this->extensionInfoArray['site'])) { 00846 $rows = array(); 00847 foreach($this->extensionInfoArray['site'] as $k => $extensions) { 00848 00849 // So, traverse all sites with the extension present: 00850 $c = 0; 00851 foreach($extensions as $extKey => $eInfo) { 00852 00853 // Set background color if mtime matches 00854 if ($eInfo['_highlight']) { 00855 $bgCol = $eInfo['dirtype']=='link' ? ' bgcolor="#ffcccc"' : ' bgcolor="#eeeeee"'; 00856 } else { 00857 $bgCol = ' style="color: #999999; font-style: italic;"'; 00858 } 00859 00860 // Make row: 00861 $rows[] = ' 00862 <tr> 00863 '.(!$c?'<td rowspan="'.count($extensions).'">'.htmlspecialchars($this->globalSiteInfo[$k]['siteInfo']['SA_PATH']).'</td>':'').' 00864 <td nowrap="nowrap"'.$bgCol.'>'.htmlspecialchars($extKey).'</td> 00865 <td nowrap="nowrap"'.$bgCol.'>'.htmlspecialchars($eInfo['title']).'</td> 00866 <td nowrap="nowrap"'.$bgCol.'>'.htmlspecialchars($eInfo['version']).'</td> 00867 <td nowrap="nowrap"'.$bgCol.'>'.htmlspecialchars($eInfo['numberfiles']).'</td> 00868 <td nowrap="nowrap"'.$bgCol.'>'.htmlspecialchars($eInfo['mtime']?date('d-m-y H:i:s',$eInfo['mtime']):'').'</td> 00869 <td nowrap="nowrap"'.$bgCol.'>'.htmlspecialchars($eInfo['mtime_hash']).'</td> 00870 </tr> 00871 '; 00872 $c++; 00873 } 00874 } 00875 $out.='<br /> 00876 <h3>Sites:</h3> 00877 <table border="1">'.implode('',$rows).'</table>'; 00878 } 00879 00880 // Return content 00881 return $out; 00882 } 00883 00892 function getExtensionInfo($path,$extKey,$k) { 00893 $file = $path.$extKey.'/ext_emconf.php'; 00894 if (@is_file($file)) { 00895 $_EXTKEY = $extKey; 00896 include($file); 00897 00898 $eInfo = array(); 00899 // Info from emconf: 00900 $eInfo['title'] = $EM_CONF[$extKey]['title']; 00901 $eInfo['version'] = $EM_CONF[$extKey]['version']; 00902 $eInfo['CGLcompliance'] = $EM_CONF[$extKey]['CGLcompliance']; 00903 $eInfo['CGLcompliance_note'] = $EM_CONF[$extKey]['CGLcompliance_note']; 00904 $eInfo['TYPO3_version'] = $EM_CONF[$extKey]['TYPO3_version']; 00905 $filesHash = unserialize($EM_CONF[$extKey]['_md5_values_when_last_written']); 00906 00907 if (!is_array($filesHash) || count($filesHash)<500) { 00908 00909 // Get all files list (may take LOONG time): 00910 $extPath = $path.$extKey.'/'; 00911 $fileArr = array(); 00912 $fileArr = $this->removePrefixPathFromList($this->getAllFilesAndFoldersInPath($fileArr,$extPath),$extPath); 00913 00914 if (!is_array($fileArr)) { 00915 debug(array($fileArr,$extKey,$extPath,$this->getAllFilesAndFoldersInPath(array(),$extPath)),'ERROR'); 00916 } 00917 00918 // Number of files: 00919 $eInfo['numberfiles'] = count($fileArr); 00920 $eInfo['dirtype'] = filetype($path.$extKey); 00921 00922 // Most recent modification: 00923 $eInfo['mtime_files'] = $this->findMostRecent($fileArr,$extPath); 00924 if (count($eInfo['mtime_files'])) $eInfo['mtime'] = max($eInfo['mtime_files']); 00925 $eInfo['mtime_hash'] = md5(implode(',',$eInfo['mtime_files'])); 00926 } else { 00927 $eInfo['mtime_hash'] = 'No calculation done, too many files in extension: '.count($filesHash); 00928 } 00929 00930 $eInfo['manual'] = @is_file($path.$extKey.'/doc/manual.sxw'); 00931 00932 return $eInfo; 00933 } else return 'ERROR: No emconf.php file: '.$file; 00934 } 00935 00945 function getAllFilesAndFoldersInPath($fileArr,$extPath,$extList='',$regDirs=0) { 00946 if ($regDirs) $fileArr[] = $extPath; 00947 $fileArr = array_merge($fileArr,t3lib_div::getFilesInDir($extPath,$extList,1,1)); 00948 00949 $dirs = t3lib_div::get_dirs($extPath); 00950 if (is_array($dirs)) { 00951 foreach($dirs as $subdirs) { 00952 if ($subdirs && (strcmp($subdirs,'CVS') || !$this->noCVS)) { 00953 $fileArr = $this->getAllFilesAndFoldersInPath($fileArr,$extPath.$subdirs.'/',$extList,$regDirs); 00954 } 00955 } 00956 } 00957 return $fileArr; 00958 } 00959 00967 function findMostRecent($fileArr,$extPath) { 00968 $mtimeArray = array(); 00969 foreach($fileArr as $fN) { 00970 if ($fN!='ext_emconf.php') { 00971 $mtime = filemtime($extPath.$fN); 00972 $mtimeArray[$fN] = $mtime; 00973 } 00974 } 00975 return $mtimeArray; 00976 } 00977 00985 function removePrefixPathFromList($fileArr,$extPath) { 00986 reset($fileArr); 00987 while(list($k,$absFileRef)=each($fileArr)) { 00988 if(t3lib_div::isFirstPartOfStr($absFileRef,$extPath)) { 00989 $fileArr[$k]=substr($absFileRef,strlen($extPath)); 00990 } else return 'ERROR: One or more of the files was NOT prefixed with the prefix-path!'; 00991 } 00992 return $fileArr; 00993 } 00994 00995 00996 00997 00998 00999 01000 01001 01002 01003 01004 01005 01006 01007 01008 01009 01010 /****************************** 01011 * 01012 * Content: Other 01013 * 01014 ******************************/ 01015 01022 function singleSite($exp) { 01023 $all = $this->globalSiteInfo[$exp]; 01024 01025 // General information: 01026 $content = ' 01027 <h2>'.htmlspecialchars($all['siteInfo']['sitename'].' (DB: '.$all['siteInfo']['TYPO3_db']).')</h2> 01028 <hr /> 01029 01030 <h3>Main details:</h3> 01031 01032 LINKS: <a href="'.htmlspecialchars($all['siteInfo']['URL']).'" target="'.$this->targetWindow.'">Site</a> / <a href="'.htmlspecialchars($all['siteInfo']['ADMIN_URL']).'" target="'.$this->targetWindowAdmin.'">Admin</a> / <a href="'.htmlspecialchars($all['siteInfo']['INSTALL_URL']).'" target="'.$this->targetWindowInstall.'">Install</a> 01033 <br /><br />'; 01034 01035 // Add all information in globalSiteInfo array: 01036 $content.= t3lib_div::view_array($all); 01037 01038 // Last-login: 01039 $content.= ' 01040 <h3>Login-Log for last month:</h3>'; 01041 $content.= $this->loginLog($all['siteInfo']['TYPO3_db']); 01042 01043 // Return content 01044 return $content; 01045 } 01046 01053 function loginLog($DB) { 01054 // Non-admin users 01055 //1=login, 2=logout, 3=failed login (+ errorcode 3), 4=failure_warning_email sent 01056 $query = $GLOBALS['TYPO3_DB']->SELECTquery( 01057 'sys_log.*, be_users.username AS username, be_users.admin AS admin', 01058 'sys_log,be_users', 01059 'be_users.uid=sys_log.userid AND sys_log.type=255 AND sys_log.tstamp > '.(time()-(60*60*24*30)), 01060 '', 01061 'sys_log.tstamp DESC' 01062 ); 01063 $res = mysql($DB,$query); 01064 01065 $dayRef = ''; 01066 $lines = array(); 01067 01068 while($row = mysql_fetch_assoc($res)) { 01069 $day = date('d-m-Y',$row['tstamp']); 01070 if ($dayRef!=$day) { 01071 $lines[] = ' 01072 <h4>'.$day.':</h4>'; 01073 $dayRef=$day; 01074 } 01075 $theLine = date('H:i',$row['tstamp']).': '.str_pad(substr($row['username'],0,10),10).' '.$this->log_getDetails($row['details'],unserialize($row['log_data'])); 01076 $theLine = htmlspecialchars($theLine); 01077 $lines[]= $row['admin'] ? '<span class="redclass">'.$theLine.'</span>' : $theLine; 01078 01079 // debug($row); 01080 } 01081 return '<pre>'.implode(chr(10),$lines).'</pre>'; 01082 } 01083 01091 function log_getDetails($text,$data) { 01092 // $code is used later on to substitute errormessages with language-corrected values... 01093 if (is_array($data)) { 01094 return sprintf($text, $data[0],$data[1],$data[2],$data[3],$data[4]); 01095 } else return $text; 01096 } 01097 01098 01105 function rmCachedFiles($exp) { 01106 $all = $this->globalSiteInfo[$exp]; 01107 $content = ' 01108 <h2>'.htmlspecialchars($all['siteInfo']['sitename'].' (DB: '.$all['siteInfo']['TYPO3_db']).')</h2> 01109 <hr /> 01110 <h3>typo3conf/temp_CACHED_* files:</h3>'; 01111 01112 $path = $all['siteInfo']['SA_PATH'].'/typo3conf/'; 01113 if (@is_dir($path)) { 01114 $filesInDir = t3lib_div::getFilesInDir($path,'php',1); 01115 01116 foreach($filesInDir as $kk => $vv) { 01117 if (t3lib_div::isFirstPartOfStr(basename($vv),'temp_CACHED_')) { 01118 if (strstr(basename($vv),'ext_localconf.php') || strstr(basename($vv),'ext_tables.php')) { 01119 $content.='REMOVED: '.$vv.'<br />'; 01120 unlink($vv); 01121 if (file_exists($vv)) $content.= $this->error('ERROR: File still exists, so could not be removed anyways!').'<br />'; 01122 } 01123 } 01124 } 01125 } else { 01126 $content.= $this->error('ERROR: '.$path.' was not a directory!'); 01127 } 01128 01129 return $content; 01130 } 01131 01138 function menuContent($exp) { 01139 if ($exp) { 01140 01141 // Initialize: 01142 $lines = array(); 01143 $head = ''; 01144 01145 foreach($this->globalSiteInfo as $k => $all) { 01146 01147 // Setting section header, if needed. 01148 if ($head!=$all['siteInfo']['MAIN_DIR']) { 01149 $lines[] = ' 01150 <h4 style="white-space: nowrap;">'.htmlspecialchars(t3lib_div::fixed_lgd_pre($all['siteInfo']['MAIN_DIR'],18)).'</h4>'; 01151 $head = $all['siteInfo']['MAIN_DIR']; // Set new head... 01152 } 01153 01154 // Display mode: 01155 switch($exp) { 01156 case 'update': 01157 01158 // Label: 01159 $label = $all['siteInfo']['sitename'] ? $all['siteInfo']['sitename'] : '(DB: '.$all['siteInfo']['TYPO3_db'].')'; 01160 $lines[] = ' 01161 <hr /> 01162 <b>'.htmlspecialchars($label).'</b> ('.htmlspecialchars(substr($all['siteInfo']['SA_PATH'],strlen($all['siteInfo']['MAIN_DIR'])+1)).')<br />'; 01163 01164 // To avoid "visited links" display on next hit: 01165 $tempVal='&_someUniqueValue='.time(); 01166 01167 // Add links for update: 01168 $url = $this->scriptName.'?type=page&show=rmTempCached&exp='.$k.$tempVal; 01169 $lines[] = '<span style="white-space: nowrap;"><a href="'.htmlspecialchars($url).'" target="TSApage">Remove temp_CACHED files</a></span>'; 01170 01171 $url = $all['siteInfo']['INSTALL_URL'].'index.php?TYPO3_INSTALL[type]=database&TYPO3_INSTALL[database_type]=import|CURRENT_STATIC'."&presetWholeTable=1".$tempVal.'#bottom'; 01172 $lines[] = '<span style="white-space: nowrap;"><a href="'.htmlspecialchars($url).'" target="TSApage">CURRENT_STATIC</a></span>'; 01173 01174 $url = $all['siteInfo']['INSTALL_URL'].'index.php?TYPO3_INSTALL[type]=database&TYPO3_INSTALL[database_type]=cmpFile|CURRENT_TABLES'.$tempVal.'#bottom'; 01175 $lines[] = '<span style="white-space: nowrap;"><a href="'.htmlspecialchars($url).'" target="TSApage">CURRENT_TABLES</a></span>'; 01176 01177 // Cache 01178 $url = $all['siteInfo']['INSTALL_URL'].'index.php?TYPO3_INSTALL[type]=database&TYPO3_INSTALL[database_type]=cache|'. 01179 "&PRESET[database_clearcache][cache_pages]=1". 01180 '&PRESET[database_clearcache][cache_pagesection]=1'. 01181 "&PRESET[database_clearcache][cache_hash]=1". 01182 $tempVal. 01183 '#bottom'; 01184 $lines[] = '<span style="white-space: nowrap;"><a href="'.htmlspecialchars($url).'" target="TSApage">Clear cache</a></span>'; 01185 01186 // Admin link 01187 $url = $all['siteInfo']['ADMIN_URL'].'index.php'; 01188 $lines[] = '<span style="white-space: nowrap;"><a href="'.htmlspecialchars($url).'" target="'.$this->targetWindowAdmin.'">Admin -></a></span>'; 01189 break; 01190 case 'info': 01191 // item 01192 $label = $all['siteInfo']['sitename'] ? $all['siteInfo']['sitename'] : '(DB: '.$all['siteInfo']['TYPO3_db'].')'; 01193 01194 $url = $this->scriptName.'?type=page&show=info&exp='.$k; 01195 $lines[] = '<span style="white-space: nowrap;"><a href="'.htmlspecialchars($url).'" target="TSApage">'.htmlspecialchars($label).'</a> ('.htmlspecialchars(substr($all['siteInfo']['SA_PATH'],strlen($all['siteInfo']['MAIN_DIR'])+1)).'/)</span>'; 01196 break; 01197 } 01198 } 01199 01200 // Return result. 01201 return implode('<br />',$lines).'<br />'; 01202 } 01203 } 01204 01210 function makeAdminLogin() { 01211 01212 // Initialize: 01213 $lines = array(); 01214 $head = ''; 01215 01216 // Traverse installations found: 01217 foreach($this->globalSiteInfo as $k => $all) { 01218 01219 // Setting section header, if needed. 01220 if ($head!=$all['siteInfo']['MAIN_DIR']) { 01221 $lines[] = ' 01222 <tr> 01223 <td colspan="2"><br /> 01224 <h4>'.htmlspecialchars($all['siteInfo']['MAIN_DIR']).'</h4> 01225 </td> 01226 </tr>'; 01227 $head = $all['siteInfo']['MAIN_DIR']; 01228 } 01229 01230 // item 01231 $label = $all['siteInfo']['sitename'] ? $all['siteInfo']['sitename'] : '(DB: '.$all['siteInfo']['TYPO3_db'].')'; 01232 $unique = md5(microtime()); 01233 01234 $opts = array(); 01235 $defUName = ''; 01236 01237 if (is_array($all['siteInfo']['ADMINS'])) { 01238 01239 foreach($all['siteInfo']['ADMINS'] as $vArr) { 01240 $chalVal = md5($vArr['username'].':'.$vArr['password'].':'.$unique); 01241 $opts[] = '<option value="'.$chalVal.'">'.htmlspecialchars($vArr['username'].($vArr['disable']?' [DISABLED]':'')).'</option>'; 01242 if (!$defUName) { $defUName = $vArr['username']; } 01243 } 01244 } 01245 if (count($opts)>1) { 01246 $userident = ' 01247 <select name="userident" onchange="document[\''.$k.'\'].username.value=this.options[this.selectedIndex].text;"> 01248 '.implode(' 01249 ',$opts).' 01250 </select> 01251 '; 01252 } else { 01253 $userident = ' 01254 ('.$defUName.')<br /> 01255 <input type="hidden" name="userident" value="'.$chalVal.'" />'; 01256 } 01257 01258 $form=' 01259 <form name="'.$k.'" action="'.$all['siteInfo']['ADMIN_URL'].'index.php" target="EXTERnalWindow" method="post"> 01260 <input type="submit" name="submit" value="Login" /> 01261 <input type="hidden" name="username" value="'.$defUName.'" /> 01262 <input type="hidden" name="challenge" value="'.$unique.'" /> 01263 <input type="hidden" name="redirect_url" value="" /> 01264 <input type="hidden" name="login_status" value="login" /> 01265 '.trim($userident).' 01266 </form>'; 01267 01268 $lines[] = ' 01269 <tr> 01270 <td><strong>'.htmlspecialchars($label).'</strong></td> 01271 <td nowrap="nowrap">'.trim($form).'</td> 01272 </tr>'; 01273 } 01274 01275 // Return login table: 01276 return '<table border="1" cellpadding="5" cellspacing="1">'.implode('',$lines).'</table>'; 01277 } 01278 01284 function changeAdminPasswordsForm() { 01285 $content=''; 01286 01287 foreach($this->changeAdminPasswords as $k => $p) { 01288 $content.=' 01289 <h3>'.$k.'</h3>'; 01290 01291 foreach($p as $kk => $pp) { 01292 $content.= '<span style="white-space: nowrap;">'; 01293 $content.= '<input type="checkbox" name="SETFIELDS[]" value="'.$pp.'" /> '.$pp.' - '; 01294 $content.= htmlspecialchars(implode(' - ',$this->collectAdminPasswords[$k][$kk])); 01295 $content.= '</span><br />'; 01296 } 01297 } 01298 01299 $content.='New password: <input type="text" name="NEWPASS" /><br />'; 01300 $content.='New password (md5): <input type="text" name="NEWPASS_md5" /><br /> 01301 (This overrules any plain password above!) 01302 <br />'; 01303 $content=' 01304 <form action="'.htmlspecialchars($this->scriptName.'?type=page&show=admin').'" method="post"> 01305 '.$content.' 01306 <input type="submit" name="Set" /> 01307 </form> 01308 '; 01309 01310 return $content; 01311 } 01312 01319 function setNewPasswords() { 01320 $whichFields = t3lib_div::_POST('SETFIELDS'); 01321 $pass = trim(t3lib_div::_POST('NEWPASS')); 01322 $passMD5 = t3lib_div::_POST('NEWPASS_md5'); 01323 01324 $updatedFlag = 0; 01325 if (($pass || $passMD5) && is_array($whichFields)) { 01326 $pass = $passMD5 ? $passMD5 : md5($pass); 01327 01328 foreach($whichFields as $values) { 01329 $parts = explode(':',$values); 01330 if (count($parts)>2) { 01331 $key = $this->mapDBtoKey[$parts[0]]; 01332 if ($key && isset($this->globalSiteInfo[$key]['siteInfo'])) { 01333 $error = $this->connectToDatabase($this->globalSiteInfo[$key]['siteInfo']); 01334 if (!$error) { 01335 $DB = $this->globalSiteInfo[$key]['siteInfo']['TYPO3_db']; 01336 $content.='<h3>Updating '.$DB.':</h3>'; 01337 01338 $query = $GLOBALS['TYPO3_DB']->UPDATEquery( 01339 'be_users', 01340 'uid='.intval($parts[1]).' AND username="'.addslashes($parts[2]).'" AND admin!=0', 01341 array('password' => $pass) 01342 ); // username/admin are added to security. But they are certainly redundant!! 01343 mysql($DB,$query); 01344 01345 $content.= 'Affected rows: '.mysql_affected_rows().'<br /><hr />'; 01346 $updatedFlag = '1'; 01347 } 01348 } 01349 } 01350 } 01351 } 01352 01353 $this->initProcess(); 01354 return $content; 01355 } 01356 } 01357 01358 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_superadmin.php']) { 01359 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_superadmin.php']); 01360 } 01361 ?>