TYPO3 API  SVNRelease
class.t3lib_superadmin.php
Go to the documentation of this file.
00001 <?php
00002 /***************************************************************
00003  *  Copyright notice
00004  *
00005  *  (c) 1999-2011 Kasper Skårhøj (kasperYYYY@typo3.com)
00006  *  All rights reserved
00007  *
00008  *  This script is part of the TYPO3 project. The TYPO3 project is
00009  *  free software; you can redistribute it and/or modify
00010  *  it under the terms of the GNU General Public License as published by
00011  *  the Free Software Foundation; either version 2 of the License, or
00012  *  (at your option) any later version.
00013  *
00014  *  The GNU General Public License can be found at
00015  *  http://www.gnu.org/copyleft/gpl.html.
00016  *  A copy is found in the textfile GPL.txt and important notices to the license
00017  *  from the author is found in LICENSE.txt distributed with these scripts.
00018  *
00019  *
00020  *  This script is distributed in the hope that it will be useful,
00021  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00022  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00023  *  GNU General Public License for more details.
00024  *
00025  *  This copyright notice MUST APPEAR in all copies of the script!
00026  ***************************************************************/
00027 /**
00028  * Super Admin class has functions for the administration of multiple TYPO3 sites in folders
00029  * See 'misc/superadmin.php' for details on how to use!
00030  *
00031  * $Id: class.t3lib_superadmin.php 10121 2011-01-18 20:15:30Z ohader $
00032  * Revised for TYPO3 3.6 February/2004 by Kasper Skårhøj
00033  * XHTML Compliant
00034  *
00035  * @author  Kasper Skårhøj <kasperYYYY@typo3.com>
00036  */
00037 /**
00038  * [CLASS/FUNCTION INDEX of SCRIPT]
00039  *
00040  *  120: function debug($p1,$p2='')
00041  *
00042  *
00043  *  134: class t3lib_superadmin
00044  *
00045  *            SECTION: Initialize stuff
00046  *  180:     function t3lib_superadmin()
00047  *  192:     function init($parentDirs)
00048  *
00049  *            SECTION: Main functions
00050  *  215:     function defaultSet()
00051  *  271:     function make()
00052  *
00053  *            SECTION: Output preparation
00054  *  376:     function setMenuItem($code,$label)
00055  *  390:     function error($str)
00056  *  401:     function headerParentDir($str)
00057  *  412:     function headerSiteDir($str)
00058  *
00059  *            SECTION: Collection information
00060  *  444:     function initProcess()
00061  *  482:     function processSiteDir($path,$dir)
00062  *  524:     function includeLocalconf($localconf)
00063  *  554:     function connectToDatabase($siteInfo)
00064  *  576:     function getDBInfo($key)
00065  *
00066  *            SECTION: Content: Installation Overview
00067  *  626:     function makeTable()
00068  *
00069  *            SECTION: Content: Local extensions
00070  *  729:     function localExtensions()
00071  *  902:     function getExtensionInfo($path,$extKey,$k)
00072  *  956:     function getAllFilesAndFoldersInPath($fileArr,$extPath,$extList='',$regDirs=0)
00073  *  978:     function findMostRecent($fileArr,$extPath)
00074  *  996:     function removePrefixPathFromList($fileArr,$extPath)
00075  *
00076  *            SECTION: Content: Other
00077  * 1033:     function singleSite($exp)
00078  * 1064:     function loginLog($DB)
00079  * 1102:     function log_getDetails($text,$data)
00080  * 1116:     function rmCachedFiles($exp)
00081  * 1149:     function menuContent($exp)
00082  * 1221:     function makeAdminLogin()
00083  * 1295:     function changeAdminPasswordsForm()
00084  * 1330:     function setNewPasswords()
00085  *
00086  * TOTAL FUNCTIONS: 28
00087  * (This index is automatically created/updated by the extension "extdeveval")
00088  *
00089  */
00090 
00091 
00092     // *******************************
00093     // Set error reporting
00094     // *******************************
00095 if (defined('E_DEPRECATED')) {
00096     error_reporting(E_ALL ^ E_NOTICE ^ E_DEPRECATED);
00097 } else {
00098     error_reporting(E_ALL ^ E_NOTICE);
00099 }
00100 
00101 define('TYPO3_mainDir', 'typo3/'); // This is the directory of the backend administration for the sites of this TYPO3 installation.
00102 
00103 
00104     // Dependency:
00105 $path_t3lib = './typo3_src/t3lib/';
00106 include_once($path_t3lib . 'class.t3lib_div.php');
00107 include_once($path_t3lib . 'class.t3lib_db.php');
00108 $TYPO3_DB = t3lib_div::makeInstance('t3lib_DB');
00109 
00110 
00111 t3lib_div::deprecationLog('class.t3lib_superadmin.php is deprecated since TYPO3 4.5, this file will be removed in TYPO3 4.7.');
00112 
00113 
00114 /**
00115  * Debug function. Substitute since no config_default.php file is included anywhere
00116  *
00117  * @param   mixed       Debug var
00118  * @param   string      Header string
00119  * @return  void
00120  */
00121 function debug($p1, $p2 = '') {
00122     t3lib_div::debug($p1, $p2);
00123 }
00124 
00125 
00126 /**
00127  * Super Admin class has functions for the administration of multiple TYPO3 sites in folders
00128  * NOTICE: Only compliant with single MySQL database usage per installation!
00129  *
00130  * @author  Kasper Skårhøj <kasperYYYY@typo3.com>
00131  * @package TYPO3
00132  * @subpackage t3lib
00133  */
00134 class t3lib_superadmin {
00135 
00136         // External, static:
00137     var $targetWindow = 'superAdminWindow';
00138     var $targetWindowAdmin = 'superAdminWindowAdmin';
00139     var $targetWindowInstall = 'superAdminWindowInstall';
00140     var $scriptName = 'superadmin.php';
00141 
00142         // GP vars:
00143     var $show; // "menu", "all", "admin", "info", "rmTempCached", "localext"
00144     var $type; // "phpinfo", "page" - default renders a frameset
00145     var $exp; // Additional parameter, typically a md5-hash pointing to an installation of TYPO3
00146 
00147         // Internal, static:
00148     var $parentDirs = array(); // Configured directories to search
00149     var $globalSiteInfo = array(); // Array with information about found TYPO3 installations
00150 
00151     var $currentUrl = '';
00152     var $mapDBtoKey = array();
00153     var $collectAdminPasswords = array();
00154     var $changeAdminPasswords = array();
00155     var $collectInstallPasswords = array();
00156 
00157         // Control:
00158     var $full = 0; // If set, the full information array per site is printed.
00159 
00160     var $noCVS = 0; // See tools/em/index.php....
00161 
00162 
00163     /**********************************
00164      *
00165      * Initialize stuff
00166      *
00167      **********************************/
00168 
00169     /**
00170      * Constructor, setting GP vars
00171      *
00172      * @return  void
00173      */
00174     function t3lib_superadmin() {
00175         $this->show = t3lib_div::_GP('show');
00176         $this->type = t3lib_div::_GP('type');
00177         $this->exp = t3lib_div::_GP('exp');
00178     }
00179 
00180     /**
00181      * Initialize with configuration - from the 'superadmin.php' script. See misc/superadmin.php for example.
00182      *
00183      * @param   array       Numerical array with arrays having two keys, 'dir' and 'url' where 'dir' is the absolute path to a directory with TYPO3 installations inside.
00184      * @return  void
00185      */
00186     function init($parentDirs) {
00187         $this->parentDirs = $parentDirs;
00188     }
00189 
00190 
00191     /**************************
00192      *
00193      * Main functions
00194      *
00195      **************************/
00196 
00197     /**
00198      * Main function, creating HTML content; frameset, menu, content frames.
00199      * Outputs the full HTML to browser.
00200      *
00201      * @return  void
00202      */
00203     function defaultSet() {
00204 
00205             // Creating content based on "type" variable:
00206         switch ($this->type) {
00207             case 'phpinfo':
00208                 phpinfo();
00209             break;
00210             case 'page':
00211                 ?>
00212                 <!DOCTYPE html
00213                         PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
00214                         "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
00215                 <html>
00216                 <head>
00217                     <style type="text/css">
00218                         .redclass {
00219                             color: red;
00220                         }
00221 
00222                         P {
00223                             font-family: Verdana, Arial, Helvetica, sans-serif;
00224                             font-size: 11px
00225                         }
00226 
00227                         BODY {
00228                             font-family: Verdana, Arial, Helvetica, sans-serif;
00229                             font-size: 10px
00230                         }
00231 
00232                         H1 {
00233                             font-family: Verdana, Arial, Helvetica, sans-serif;
00234                             font-size: 20px;
00235                             color: #000066;
00236                         }
00237 
00238                         H2 {
00239                             font-family: Verdana, Arial, Helvetica, sans-serif;
00240                             font-size: 17px;
00241                             color: #000066;
00242                         }
00243 
00244                         H3 {
00245                             font-family: Verdana, Arial, Helvetica, sans-serif;
00246                             font-size: 14px;
00247                             color: #000066;
00248                         }
00249 
00250                         H4 {
00251                             font-family: Verdana, Arial, Helvetica, sans-serif;
00252                             font-size: 11px;
00253                             color: maroon;
00254                         }
00255 
00256                         TD {
00257                             font-family: Verdana, Arial, Helvetica, sans-serif;
00258                             font-size: 10px
00259                         }
00260                     </style>
00261                     <title>TYPO3 Super Admin</title>
00262                 </head>
00263                 <body>
00264                     <?php
00265         echo $this->make();
00266                 ?>
00267                 </body>
00268                 </html>
00269                     <?php
00270             break;
00271             default:
00272                 ?>
00273                 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
00274                 <html>
00275                 <head>
00276                     <title>TYPO3 Super Admin</title>
00277                 </head>
00278                 <frameset cols="250,*">
00279                     <frame name="TSAmenu" src="superadmin.php?type=page&show=menu" marginwidth="10" marginheight="10"
00280                            scrolling="auto" frameborder="0">
00281                     <frame name="TSApage" src="superadmin.php?type=page" marginwidth="10" marginheight="10"
00282                            scrolling="auto" frameborder="0">
00283                 </frameset>
00284                 </html>
00285                 <?php
00286             break;
00287         }
00288     }
00289 
00290     /**
00291      * Main function, creating page content.
00292      *
00293      * @return  string      HTML content.
00294      */
00295     function make() {
00296 
00297         $retVal = '';
00298 
00299             // Creating information about the sites found:
00300         $content = $this->initProcess();
00301 
00302             // Output mode:
00303         switch ($this->show) {
00304             case 'menu':
00305                 $lines = array();
00306                 $lines[] = $this->setMenuItem('info', 'INFO');
00307                 $lines[] = $this->setMenuItem('update', 'UPDATE');
00308                 $lines[] = '';
00309                 $lines[] = '<a href="' . htmlspecialchars($this->scriptName . '?type=page') . '" target="TSApage">Default</a>';
00310                 $lines[] = '<a href="' . htmlspecialchars($this->scriptName . '?type=page&show=all') . '" target="TSApage">All details</a>';
00311                 $lines[] = '<a href="' . htmlspecialchars($this->scriptName . '?type=page&show=admin') . '" target="TSApage">Admin logins</a>';
00312                 $lines[] = '<a href="' . htmlspecialchars($this->scriptName . '?type=phpinfo') . '" target="TSApage">phpinfo()</a>';
00313                 $lines[] = '<a href="' . htmlspecialchars($this->scriptName . '?type=page&show=localext') . '" target="TSApage">Local extensions</a>';
00314                 $lines[] = '';
00315                 $content = implode('<br />', $lines);
00316                 $content .= '<hr />';
00317                 $content .= $this->menuContent($this->exp);
00318                 $retVal = '<h2 align="center">TYPO3<br />Super Admin</h2>' . $content;
00319             break;
00320             case 'all':
00321                 $retVal = '
00322                     <h1>All details:</h1>
00323                     <h2>Overview:</h2>
00324                     ' . $this->makeTable() . '
00325                     <br /><hr /><br />
00326                     <h1>Details per site:</h1>
00327                     ' . $content;
00328             break;
00329             case 'admin':
00330                 $content = $this->setNewPasswords();
00331                 $this->makeTable();
00332                 $retVal = $content . '
00333                     <h1>Admin options:</h1>
00334 
00335                     <h2>Admin logins:</h2>
00336                     ' . $this->makeAdminLogin() . '
00337                     <br /><hr /><br />
00338 
00339                     <h2>TBE Admin Passwords:</h2>
00340                     ' . t3lib_div::view_array($this->collectAdminPasswords) . '
00341                     <br /><hr /><br />
00342 
00343                     <h2>Install Tool Passwords:</h2>
00344                     ' . t3lib_div::view_array($this->collectInstallPasswords) . '
00345                     <br /><hr /><br />
00346 
00347                     <h2>Change TBE Admin Passwords:</h2>
00348                     ' . $this->changeAdminPasswordsForm() . '
00349                     <br /><hr /><br />';
00350             break;
00351             case 'info':
00352                 $retVal = '
00353                     <h1>Single site details</h1>
00354                     ' . $this->singleSite($this->exp) .
00355                           '<br />';
00356             break;
00357             case 'rmTempCached':
00358                 $retVal = '
00359                     <h1>Removing temp_CACHED_*.php files</h1>
00360                     ' . $this->rmCachedFiles($this->exp) .
00361                           '<br />';
00362             break;
00363             case 'localext':
00364                 $retVal = '
00365                     <h1>Local Extensions Found:</h1>
00366                     ' . $this->localExtensions() .
00367                           '<br />';
00368             break;
00369             default:
00370                 $retVal = '
00371                     <h1>Default info:</h1>' .
00372                           $content;
00373             break;
00374         }
00375         return $retVal;
00376     }
00377 
00378 
00379     /********************************
00380      *
00381      * Output preparation
00382      *
00383      *******************************/
00384 
00385     /**
00386      * Creates menu item from input.
00387      *
00388      * @param   string      Value for "&exp" parameter
00389      * @param   string      The label
00390      * @return  string      Wrapped value
00391      */
00392     function setMenuItem($code, $label) {
00393         $out = '<a href="' . htmlspecialchars($this->scriptName . '?type=page&show=menu&exp=' . $code) . '" target="TSAmenu">' . htmlspecialchars($label) . '</a>';
00394         if ($code == $this->exp) {
00395             $out = '<span style="color:red;">&gt;&gt;</span>' . $out;
00396         }
00397         return $out;
00398     }
00399 
00400     /**
00401      * Wrap string in red span tag (for errors)
00402      *
00403      * @param   string      Input string
00404      * @return  string      Output string
00405      */
00406     function error($str) {
00407         $out = '<span style="color:red; font-size: 14px; font-weight: bold;">' . htmlspecialchars($str) . '</span>';
00408         return $out;
00409     }
00410 
00411     /**
00412      * Wraps input string in <h2>
00413      *
00414      * @param   string      Input string
00415      * @return  string      Output string, wrapped in <h2>
00416      */
00417     function headerParentDir($str) {
00418         $out = '<h2>' . htmlspecialchars($str) . '</h2>';
00419         return $out;
00420     }
00421 
00422     /**
00423      * Wraps input string in <h3>
00424      *
00425      * @param   string      Input string
00426      * @return  string      Output string, wrapped in <h3>
00427      */
00428     function headerSiteDir($str) {
00429         $out = '<h3>' . htmlspecialchars($str) . '</h3>';
00430         return $out;
00431     }
00432 
00433 
00434     /********************************
00435      *
00436      * Collection information
00437      *
00438      *******************************/
00439 
00440     /**
00441      * Traverses the parent dirs, collecting the list of TYPO3 installations into $this->globalSiteInfo
00442      *
00443      * @return  string      HTML content (The default view seen when starting the superadmin.php script)
00444      */
00445     function initProcess() {
00446         $content = '';
00447 
00448         foreach ($this->parentDirs as $k => $v) {
00449             $dir = rtrim($v['dir'], '/');
00450             $baseUrl = rtrim($v['url'], '/');
00451             $content .= '<br /><br /><br />';
00452             $content .= $this->headerParentDir($dir);
00453             if (@is_dir($dir)) {
00454                 $in_dirs = t3lib_div::get_dirs($dir);
00455                 asort($in_dirs);
00456                 $dirArr = array();
00457                 foreach ($in_dirs as $k => $v) {
00458                     if (substr($v, 0, 9) != 'typo3_src') {
00459                         $this->currentUrl = $baseUrl . '/' . $v;
00460                         $content .= $this->headerSiteDir($v);
00461                         $content .= $this->processSiteDir($dir . '/' . $v, $dir);
00462                     }
00463                 }
00464             } else {
00465                 $content .= $this->error('"' . $dir . '" was not a directory!');
00466             }
00467         }
00468 
00469         return $content;
00470     }
00471 
00472     /**
00473      * Creating information array for a specific TYPO3 installation
00474      * Information about site is stored in ->globalSiteInfo array
00475      *
00476      * @param   string      Absolute path to installation (PATH_site)
00477      * @param   string      Directory of main directory (level under PATH_site)
00478      * @return  string      HTML content with information about the site.
00479      * @access private
00480      * @see initProcess()
00481      */
00482     function processSiteDir($path, $dir) {
00483         if (@is_dir($path)) {
00484             $localconf = $path . '/typo3conf/localconf.php';
00485             if (@is_file($localconf)) {
00486                 $key = md5($localconf);
00487                 $this->includeLocalconf($localconf);
00488 
00489                 $this->mapDBtoKey[$this->globalSiteInfo[$key]['siteInfo']['TYPO3_db']] = $key;
00490                 $this->globalSiteInfo[$key]['siteInfo']['MAIN_DIR'] = $dir;
00491                 $this->globalSiteInfo[$key]['siteInfo']['SA_PATH'] = $path;
00492                 $this->globalSiteInfo[$key]['siteInfo']['URL'] = $this->currentUrl . '/';
00493                 $this->globalSiteInfo[$key]['siteInfo']['ADMIN_URL'] = $this->currentUrl . '/' . TYPO3_mainDir;
00494                 $this->globalSiteInfo[$key]['siteInfo']['INSTALL_URL'] = $this->currentUrl . '/' . TYPO3_mainDir . 'install/';
00495 
00496                     // Connect to database:
00497                 $conMsg = $this->connectToDatabase($this->globalSiteInfo[$key]['siteInfo']);
00498                 if (!$conMsg) {
00499                     $this->getDBInfo($key);
00500                     $out .= '';
00501                 } else {
00502                     $out = $conMsg;
00503                 }
00504 
00505                     // Show details:
00506                 if ($this->full) {
00507                     $out .= t3lib_div::view_array($this->globalSiteInfo[$key]);
00508                 } else {
00509                     $out .= t3lib_div::view_array($this->globalSiteInfo[$key]['siteInfo']);
00510                 }
00511             } else {
00512                 $out = $this->error($localconf . ' is not a file!');
00513             }
00514         } else {
00515             $out = $this->error($path . ' is not a directory!');
00516         }
00517         return $out;
00518     }
00519 
00520     /**
00521      * Includes "localconf" of a TYPO3 installation an loads $this->globalSiteInfo with this information.
00522      *
00523      * @param   string      Absolute path to localconf.php file to include.
00524      * @return  array       Array with information about the site.
00525      * @access private
00526      * @see processSiteDir()
00527      */
00528     function includeLocalconf($localconf) {
00529         $TYPO3_CONF_VARS = array();
00530         $typo_db = '';
00531         $typo_db_username = '';
00532         $typo_db_password = '';
00533         $typo_db_host = '';
00534 
00535         include($localconf);
00536 
00537         $siteInfo = array();
00538         $siteInfo['sitename'] = $TYPO3_CONF_VARS['SYS']['sitename'];
00539         $siteInfo['TYPO3_db'] = $typo_db;
00540         $siteInfo['TYPO3_db_username'] = $typo_db_username;
00541         $siteInfo['TYPO3_db_password'] = $typo_db_password;
00542         $siteInfo['TYPO3_db_host'] = $typo_db_host;
00543         $siteInfo['installToolPassword'] = $TYPO3_CONF_VARS['BE']['installToolPassword'];
00544         $siteInfo['warningEmailAddress'] = $TYPO3_CONF_VARS['BE']['warning_email_addr'];
00545         $siteInfo['warningMode'] = $TYPO3_CONF_VARS['BE']['warning_mode'];
00546 
00547         $this->globalSiteInfo[md5($localconf)] = array('siteInfo' => $siteInfo, 'TYPO3_CONF_VARS' => $TYPO3_CONF_VARS);
00548         return $siteInfo;
00549     }
00550 
00551     /**
00552      * Connects to a MySQL database with the TYPO3 db host/username/password and database as found in the localconf.php file!
00553      * This is NOT compatible with DBAL and connection will obviously just fail with an error message if it turns out that the _DEFAULT handler of a site is not in a MySQL database
00554      *
00555      * @param   array       $siteInfo array, containing username/password/host/database values.
00556      * @return  string      Array message if any
00557      */
00558     function connectToDatabase($siteInfo) {
00559         if (@mysql_pconnect($siteInfo['TYPO3_db_host'], $siteInfo['TYPO3_db_username'], $siteInfo['TYPO3_db_password'])) {
00560             if (!$siteInfo['TYPO3_db']) {
00561                 return $this->error('No database selected');
00562             } elseif (!mysql_select_db($siteInfo['TYPO3_db'])) {
00563                 return $this->error('Cannot connect to the current database, "' . $siteInfo['TYPO3_db'] . '"');
00564             }
00565         } else {
00566             return $this->error('The current username, password or host was not accepted when the connection to the database was attempted to be established!');
00567         }
00568     }
00569 
00570 
00571     /**
00572      * Get database information, assuming standard tables like "be_users"
00573      * Adding the information to ->globalSiteInfo
00574      *
00575      * @param   string      Key for site in ->globalSiteInfo
00576      * @return  void
00577      * @access private
00578      * @see processSiteDir()
00579      */
00580     function getDBInfo($key) {
00581         $DB = $this->globalSiteInfo[$key]['siteInfo']['TYPO3_db'];
00582 
00583             // Non-admin users
00584         $query = $GLOBALS['TYPO3_DB']->SELECTquery('count(*)', 'be_users', 'admin=0 AND deleted=0');
00585         $res = mysql($DB, $query);
00586         $row = mysql_fetch_row($res);
00587         $this->globalSiteInfo[$key]['siteInfo']['BE_USERS_NONADMIN'] = $row[0];
00588 
00589             // Admin users
00590         $query = $GLOBALS['TYPO3_DB']->SELECTquery('count(*)', 'be_users', 'admin!=0 AND deleted=0');
00591         $res = mysql($DB, $query);
00592         $row = mysql_fetch_row($res);
00593         $this->globalSiteInfo[$key]['siteInfo']['BE_USERS_ADMIN'] = $row[0];
00594 
00595             // Select Admin users
00596         $query = $GLOBALS['TYPO3_DB']->SELECTquery('uid,username,password,email,realName,disable', 'be_users', 'admin!=0 AND deleted=0');
00597         $res = mysql($DB, $query);
00598         while ($row = mysql_fetch_assoc($res)) {
00599             $this->globalSiteInfo[$key]['siteInfo']['ADMINS'][] = $row;
00600         }
00601     }
00602 
00603 
00604     /******************************
00605      *
00606      * Content: Installation Overview
00607      *
00608      ******************************/
00609 
00610     /**
00611      * Creates big table with information about all installations in ->globalSiteInfo
00612      *
00613      * @return  string      HTML table
00614      */
00615     function makeTable() {
00616 
00617             // Header row
00618         $info = array();
00619         $info[] = 'Site:';
00620         $info[] = 'Path:';
00621         $info[] = 'Database:';
00622         $info[] = 'Username';
00623         $info[] = 'Password';
00624         $info[] = 'Host';
00625         $info[] = 'Links (new win)';
00626         $info[] = '#Users NA/A';
00627         $info[] = 'Admin be_users Info';
00628         $info[] = 'Install Tool Password';
00629         $info[] = 'Warning email address';
00630         $info[] = 'W.mode';
00631         $mainArrRows[] = '
00632             <tr bgcolor="#eeeeee">
00633                 <td nowrap="nowrap" valign="top">' . implode('</td>
00634                 <td nowrap="nowrap" valign="top">', $info) . '</td>
00635             </tr>';
00636 
00637             // Traverse globalSiteInfo for each site:
00638         foreach ($this->globalSiteInfo as $k => $all) {
00639             $info = array();
00640 
00641                 // Sitename and Database details:
00642             $info[] = htmlspecialchars($all['siteInfo']['sitename']);
00643             $info[] = '<span style="color:#666666;">' . htmlspecialchars($all['siteInfo']['MAIN_DIR']) . '</span>' . htmlspecialchars(substr($all['siteInfo']['SA_PATH'], strlen($all['siteInfo']['MAIN_DIR'])));
00644             $info[] = htmlspecialchars($all['siteInfo']['TYPO3_db']);
00645             $info[] = htmlspecialchars($all['siteInfo']['TYPO3_db_username']);
00646             $info[] = htmlspecialchars($all['siteInfo']['TYPO3_db_password']);
00647             $info[] = htmlspecialchars($all['siteInfo']['TYPO3_db_host']);
00648 
00649                 // URL
00650             $info[] = '<a href="' . htmlspecialchars($all['siteInfo']['URL']) . '" target="' . $this->targetWindow . '">Site</a>' .
00651                       ' / <a href="' . htmlspecialchars($all['siteInfo']['ADMIN_URL']) . '" target="' . $this->targetWindowAdmin . '">Admin</a>' .
00652                       ' / <a href="' . htmlspecialchars($all['siteInfo']['INSTALL_URL']) . '" target="' . $this->targetWindowInstall . '">Install</a>';
00653             $info[] = htmlspecialchars($all['siteInfo']['BE_USERS_NONADMIN'] . '/' . $all['siteInfo']['BE_USERS_ADMIN']);
00654 
00655                 // Admin
00656             if (is_array($all['siteInfo']['ADMINS'])) {
00657                 $lines = array();
00658                 foreach ($all['siteInfo']['ADMINS'] as $vArr) {
00659                     $lines[] = htmlspecialchars($vArr['password'] . ' - ' . $vArr['username'] . ' (' . $vArr['realName'] . ', ' . $vArr['email'] . ')');
00660                     $this->collectAdminPasswords[$vArr['password']][] = array(
00661                         'path' => $all['siteInfo']['SA_PATH'],
00662                         'site' => $all['siteInfo']['sitename'],
00663                         'database' => $all['siteInfo']['TYPO3_db'],
00664                         'user' => $vArr['username'],
00665                         'name_email' => $vArr['realName'] . ', ' . $vArr['email']
00666                     );
00667                     $this->changeAdminPasswords[$vArr['password']][] = $all['siteInfo']['TYPO3_db'] . ':' . $vArr['uid'] . ':' . $vArr['username'];
00668                 }
00669                 $info[] = implode('<br />', $lines);
00670             } else {
00671                 $info[] = $this->error('No DB connection!');
00672             }
00673                 // Install
00674             $info[] = htmlspecialchars($all['siteInfo']['installToolPassword']);
00675             $this->collectInstallPasswords[$all['siteInfo']['installToolPassword']][] = $all['siteInfo']['SA_PATH'] . ' - ' . $all['siteInfo']['sitename'] . ' - (' . $all['siteInfo']['TYPO3_db'] . ')';
00676 
00677             $info[] = htmlspecialchars($all['siteInfo']['warningEmailAddress']);
00678             $info[] = htmlspecialchars($all['siteInfo']['warningMode']);
00679 
00680                 // compile
00681             $mainArrRows[] = '
00682                 <tr>
00683                     <td nowrap="nowrap" valign="top">' . implode('</td>
00684                     <td nowrap="nowrap" valign="top">', $info) . '</td>
00685                 </tr>';
00686         }
00687 
00688             // Compile / return table finally:
00689         $table = '<table border="1" cellpadding="1" cellspacing="1">' . implode('', $mainArrRows) . '</table>';
00690         return $table;
00691     }
00692 
00693 
00694     /******************************
00695      *
00696      * Content: Local extensions
00697      *
00698      ******************************/
00699 
00700     /**
00701      * Based on the globalSiteInfo array, this prints information about local extensions for each site.
00702      * In particular version number and most recent mod-time is interesting!
00703      *
00704      * @return  string      HTML
00705      */
00706     function localExtensions() {
00707         $this->extensionInfoArray = array();
00708 
00709             // Traverse $this->globalSiteInfo for local extensions:
00710         foreach ($this->globalSiteInfo as $k => $all) {
00711             if ($all['siteInfo']['SA_PATH']) {
00712                 $extDir = $all['siteInfo']['SA_PATH'] . '/typo3conf/ext/';
00713                 if (@is_dir($extDir)) {
00714                     $this->extensionInfoArray['site'][$k] = array();
00715 
00716                         // Get extensions in local directory
00717                     $extensions = t3lib_div::get_dirs($extDir);
00718                     if (is_array($extensions)) {
00719                         foreach ($extensions as $extKey) {
00720                                 // Getting and setting information for extension:
00721                             $eInfo = $this->getExtensionInfo($extDir, $extKey, $k);
00722                             $this->extensionInfoArray['site'][$k][$extKey] = $eInfo;
00723                             $this->extensionInfoArray['ext'][$extKey][$k] = $eInfo;
00724                         }
00725                     }
00726                 }
00727             }
00728         }
00729 
00730             // Display results:
00731         $out = '';
00732         $headerRow = '
00733                     <tr bgcolor="#ccccee" style="font-weight:bold;">
00734                         <td>Extension key</td>
00735                         <td>Path</td>
00736                         <td>Title</td>
00737                         <td>Ver.</td>
00738                         <td>Files</td>
00739                         <td><span title="If M, then there is a manual.">M</span></td>
00740                         <td>Last mod. time</td>
00741                         <td>Hash off all file mod. times:</td>
00742                         <td>TYPO3 ver. req.</td>
00743                         <td>CGL compliance</td>
00744                     </tr>
00745                     ';
00746 
00747             // PER EXTENSION:
00748         if (is_array($this->extensionInfoArray['ext'])) {
00749             $extensionKeysCollect = array();
00750 
00751             ksort($this->extensionInfoArray['ext']);
00752             reset($this->extensionInfoArray['ext']);
00753             $rows = array(
00754                 'reg' => array(),
00755                 'user' => array()
00756             );
00757 
00758             foreach ($this->extensionInfoArray['ext'] as $extKey => $instances) {
00759                 $mtimes = array();
00760 
00761                     // Find most recent mtime of the options:
00762                 foreach ($instances as $k => $eInfo) {
00763                     $mtimes[] = $eInfo['mtime'];
00764                 }
00765                     // Max mtime:
00766                 $maxMtime = max($mtimes);
00767                 $c = 0;
00768 
00769                     // So, traverse all sites with the extension present:
00770                 foreach ($instances as $k => $eInfo) {
00771                         // Set background color if mtime matches
00772                     if ($maxMtime == $eInfo['mtime']) {
00773                         $this->extensionInfoArray['site'][$k][$extKey]['_highlight'] = 1;
00774                         $bgCol = $eInfo['dirtype'] == 'link' ? ' bgcolor="#ffcccc"' : ' bgcolor="#eeeeee"';
00775                     } else {
00776                         $bgCol = ' style="color: #999999; font-style: italic;"';
00777                     }
00778 
00779                         // Make row:
00780                     $type = substr($extKey, 0, 5) != 'user_' ? 'reg' : 'user';
00781                     if ($type == 'reg') {
00782                         $extensionKeysCollect[] = $extKey;
00783                     }
00784 
00785                     if (!is_array($eInfo)) {
00786                             // Standard listing:
00787                         $rows[$type][] = '
00788                         <tr>
00789                             ' . (!$c ? '<td rowspan="' . count($instances) . '">' . htmlspecialchars($extKey) . '</td>' : '') . '
00790                             <td nowrap="nowrap" bgcolor="#ccddcc">' . htmlspecialchars($this->globalSiteInfo[$k]['siteInfo']['SA_PATH']) . '</td>
00791                             <td nowrap="nowrap" bgcolor="#ccddcc" colspan="8"><em>' . htmlspecialchars($eInfo) . '</em></td>
00792                         </tr>
00793                         ';
00794                     } else {
00795                             // Standard listing:
00796                         $rows[$type][] = '
00797                         <tr>
00798                             ' . (!$c ? '<td rowspan="' . count($instances) . '">' . htmlspecialchars($extKey) . '</td>' : '') . '
00799                             <td nowrap="nowrap"' . $bgCol . '>' . htmlspecialchars($this->globalSiteInfo[$k]['siteInfo']['SA_PATH']) . '</td>
00800                             <td nowrap="nowrap"' . $bgCol . '>' . htmlspecialchars($eInfo['title']) . '</td>
00801                             <td nowrap="nowrap"' . $bgCol . '>' . htmlspecialchars($eInfo['version']) . '</td>
00802                             <td nowrap="nowrap"' . $bgCol . '>' . htmlspecialchars($eInfo['numberfiles']) . '</td>
00803                             <td nowrap="nowrap"' . $bgCol . '>' . htmlspecialchars($eInfo['manual'] ? 'M' : '-') . '</td>
00804                             <td nowrap="nowrap"' . $bgCol . '>' . htmlspecialchars($eInfo['mtime'] ? date('d-m-y H:i:s', $eInfo['mtime']) : '') . '</td>
00805                             <td nowrap="nowrap"' . $bgCol . '>' . htmlspecialchars($eInfo['mtime_hash']) . '</td>
00806 
00807                             <td' . $bgCol . '>' . htmlspecialchars($eInfo['TYPO3_version']) . '</td>
00808                             <td' . $bgCol . '><img src="clear.gif" width="150" height="1" alt="" /><br />' . htmlspecialchars($eInfo['CGLcompliance'] . ($eInfo['CGLcompliance_note'] ? ' - ' . $eInfo['CGLcompliance_note'] : '')) . '</td>
00809                         </tr>
00810                         ';
00811                     }
00812                     $c++;
00813                 }
00814             }
00815 
00816                 // Extensions with registered extension keys:
00817             $out .= '
00818                 <h3>Registered extensions:</h3>
00819                 <table border="1">' . $headerRow . implode('', $rows['reg']) . '</table>';
00820 
00821                 // List of those extension keys in a form field:
00822             $extensionKeysCollect = array_unique($extensionKeysCollect);
00823             asort($extensionKeysCollect);
00824             $out .= '<form action=""><textarea cols="80" rows="10">' . implode(LF, $extensionKeysCollect) . '</textarea></form>';
00825 
00826                 // USER extension (prefixed "user_")
00827             $out .= '<br />
00828                 <h3>User extensions:</h3>
00829                 <table border="1">' . $headerRow . implode('', $rows['user']) . '</table>';
00830         }
00831 
00832             // PER SITE:
00833         if (is_array($this->extensionInfoArray['site'])) {
00834             $rows = array();
00835             foreach ($this->extensionInfoArray['site'] as $k => $extensions) {
00836 
00837                     // So, traverse all sites with the extension present:
00838                 $c = 0;
00839                 foreach ($extensions as $extKey => $eInfo) {
00840 
00841                         // Set background color if mtime matches
00842                     if ($eInfo['_highlight']) {
00843                         $bgCol = $eInfo['dirtype'] == 'link' ? ' bgcolor="#ffcccc"' : ' bgcolor="#eeeeee"';
00844                     } else {
00845                         $bgCol = ' style="color: #999999; font-style: italic;"';
00846                     }
00847 
00848                         // Make row:
00849                     $rows[] = '
00850                     <tr>
00851                         ' . (!$c ? '<td rowspan="' . count($extensions) . '">' . htmlspecialchars($this->globalSiteInfo[$k]['siteInfo']['SA_PATH']) . '</td>' : '') . '
00852                         <td nowrap="nowrap"' . $bgCol . '>' . htmlspecialchars($extKey) . '</td>
00853                         <td nowrap="nowrap"' . $bgCol . '>' . htmlspecialchars($eInfo['title']) . '</td>
00854                         <td nowrap="nowrap"' . $bgCol . '>' . htmlspecialchars($eInfo['version']) . '</td>
00855                         <td nowrap="nowrap"' . $bgCol . '>' . htmlspecialchars($eInfo['numberfiles']) . '</td>
00856                         <td nowrap="nowrap"' . $bgCol . '>' . htmlspecialchars($eInfo['mtime'] ? date('d-m-y H:i:s', $eInfo['mtime']) : '') . '</td>
00857                         <td nowrap="nowrap"' . $bgCol . '>' . htmlspecialchars($eInfo['mtime_hash']) . '</td>
00858                     </tr>
00859                     ';
00860                     $c++;
00861                 }
00862             }
00863             $out .= '<br />
00864                 <h3>Sites:</h3>
00865                 <table border="1">' . implode('', $rows) . '</table>';
00866         }
00867 
00868             // Return content
00869         return $out;
00870     }
00871 
00872     /**
00873      * Gets information for an extension, eg. version and most-recently-edited-script
00874      *
00875      * @param   string      Path to local extension folder
00876      * @param   string      Extension key
00877      * @param   string      Key to globalSiteInformation array
00878      * @return  array       Information array (unless an error occured)
00879      */
00880     function getExtensionInfo($path, $extKey, $k) {
00881         $file = $path . $extKey . '/ext_emconf.php';
00882         if (@is_file($file)) {
00883             $_EXTKEY = $extKey;
00884             $EM_CONF = array();
00885             include($file);
00886 
00887             $eInfo = array();
00888                 // Info from emconf:
00889             $eInfo['title'] = $EM_CONF[$extKey]['title'];
00890             $eInfo['version'] = $EM_CONF[$extKey]['version'];
00891             $eInfo['CGLcompliance'] = $EM_CONF[$extKey]['CGLcompliance'];
00892             $eInfo['CGLcompliance_note'] = $EM_CONF[$extKey]['CGLcompliance_note'];
00893             $eInfo['TYPO3_version'] = $EM_CONF[$extKey]['TYPO3_version'];
00894             $filesHash = unserialize($EM_CONF[$extKey]['_md5_values_when_last_written']);
00895 
00896             if (!is_array($filesHash) || count($filesHash) < 500) {
00897 
00898                     // Get all files list (may take LOONG time):
00899                 $extPath = $path . $extKey . '/';
00900                 $fileArr = array();
00901                 $fileArr = $this->removePrefixPathFromList($this->getAllFilesAndFoldersInPath($fileArr, $extPath), $extPath);
00902 
00903                 if (!is_array($fileArr)) {
00904                     debug(array($fileArr, $extKey, $extPath, $this->getAllFilesAndFoldersInPath(array(), $extPath)), 'ERROR');
00905                 }
00906 
00907                     // Number of files:
00908                 $eInfo['numberfiles'] = count($fileArr);
00909                 $eInfo['dirtype'] = filetype($path . $extKey);
00910 
00911                     // Most recent modification:
00912                 $eInfo['mtime_files'] = $this->findMostRecent($fileArr, $extPath);
00913                 if (count($eInfo['mtime_files'])) {
00914                     $eInfo['mtime'] = max($eInfo['mtime_files']);
00915                 }
00916                 $eInfo['mtime_hash'] = md5(implode(',', $eInfo['mtime_files']));
00917             } else {
00918                 $eInfo['mtime_hash'] = 'No calculation done, too many files in extension: ' . count($filesHash);
00919             }
00920 
00921             $eInfo['manual'] = @is_file($path . $extKey . '/doc/manual.sxw');
00922 
00923             return $eInfo;
00924         } else {
00925             return 'ERROR: No emconf.php file: ' . $file;
00926         }
00927     }
00928 
00929     /**
00930      * Recursively gather all files and folders of extension path.
00931      *
00932      * @param   array       Array of files to which new files are added
00933      * @param   string      Path to look up files in
00934      * @param   string      List of file extensions to include. Blank = all
00935      * @param   boolean     If set, directories are included as well.
00936      * @return  array       $fileArr with new entries added.
00937      */
00938     function getAllFilesAndFoldersInPath($fileArr, $extPath, $extList = '', $regDirs = 0) {
00939         if ($regDirs) {
00940             $fileArr[] = $extPath;
00941         }
00942         $fileArr = array_merge($fileArr, t3lib_div::getFilesInDir($extPath, $extList, 1, 1));
00943 
00944         $dirs = t3lib_div::get_dirs($extPath);
00945         if (is_array($dirs)) {
00946             foreach ($dirs as $subdirs) {
00947                 if ($subdirs && (strcmp($subdirs, 'CVS') || !$this->noCVS)) {
00948                     $fileArr = $this->getAllFilesAndFoldersInPath($fileArr, $extPath . $subdirs . '/', $extList, $regDirs);
00949                 }
00950             }
00951         }
00952         return $fileArr;
00953     }
00954 
00955     /**
00956      * Creates an array with modification times of all files in $fileArr
00957      *
00958      * @param   array       Files in extension (rel path)
00959      * @param   string      Abs path prefix for files.
00960      * @return  array       Array with modification times of files (filenames are keys)
00961      */
00962     function findMostRecent($fileArr, $extPath) {
00963         $mtimeArray = array();
00964         foreach ($fileArr as $fN) {
00965             if ($fN != 'ext_emconf.php') {
00966                 $mtime = filemtime($extPath . $fN);
00967                 $mtimeArray[$fN] = $mtime;
00968             }
00969         }
00970         return $mtimeArray;
00971     }
00972 
00973     /**
00974      * Removes the absolute part of all files/folders in fileArr
00975      *
00976      * @param   array       File array
00977      * @param   string      Prefix to remove
00978      * @return  array       Modified file array (or error string)
00979      */
00980     function removePrefixPathFromList($fileArr, $extPath) {
00981         foreach ($fileArr as $k => $absFileRef) {
00982             if (t3lib_div::isFirstPartOfStr($absFileRef, $extPath)) {
00983                 $fileArr[$k] = substr($absFileRef, strlen($extPath));
00984             } else {
00985                 return 'ERROR: One or more of the files was NOT prefixed with the prefix-path!';
00986             }
00987         }
00988         return $fileArr;
00989     }
00990 
00991 
00992     /******************************
00993      *
00994      * Content: Other
00995      *
00996      ******************************/
00997 
00998     /**
00999      * Shows detailed information for a single installation of TYPO3
01000      *
01001      * @param   string      KEY pointing to installation
01002      * @return  string      HTML content
01003      */
01004     function singleSite($exp) {
01005         $all = $this->globalSiteInfo[$exp];
01006 
01007             // General information:
01008         $content = '
01009             <h2>' . htmlspecialchars($all['siteInfo']['sitename'] . ' (DB: ' . $all['siteInfo']['TYPO3_db']) . ')</h2>
01010             <hr />
01011 
01012             <h3>Main details:</h3>
01013 
01014             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>
01015             <br /><br />';
01016 
01017             // Add all information in globalSiteInfo array:
01018         $content .= t3lib_div::view_array($all);
01019 
01020             // Last-login:
01021         $content .= '
01022             <h3>Login-Log for last month:</h3>';
01023         $content .= $this->loginLog($all['siteInfo']['TYPO3_db']);
01024 
01025             // Return content
01026         return $content;
01027     }
01028 
01029     /**
01030      * Get last-login log for database.
01031      *
01032      * @param   string      Database
01033      * @return  string      HTML
01034      */
01035     function loginLog($DB) {
01036             // Non-admin users
01037             //1=login, 2=logout, 3=failed login (+ errorcode 3), 4=failure_warning_email sent
01038         $query = $GLOBALS['TYPO3_DB']->SELECTquery(
01039             'sys_log.*, be_users.username  AS username, be_users.admin AS admin',
01040             'sys_log,be_users',
01041             'be_users.uid=sys_log.userid AND sys_log.type=255 AND sys_log.tstamp > ' . ($GLOBALS['EXEC_TIME'] - (60 * 60 * 24 * 30)),
01042             '',
01043             'sys_log.tstamp DESC'
01044         );
01045         $res = mysql($DB, $query);
01046 
01047         $dayRef = '';
01048         $lines = array();
01049 
01050         while ($row = mysql_fetch_assoc($res)) {
01051             $day = date('d-m-Y', $row['tstamp']);
01052             if ($dayRef != $day) {
01053                 $lines[] = '
01054                 <h4>' . $day . ':</h4>';
01055                 $dayRef = $day;
01056             }
01057             $theLine = date('H:i', $row['tstamp']) . ':   ' . str_pad(substr($row['username'], 0, 10), 10) . '    ' . $this->log_getDetails($row['details'], unserialize($row['log_data']));
01058             $theLine = htmlspecialchars($theLine);
01059             $lines[] = $row['admin'] ? '<span class="redclass">' . $theLine . '</span>' : $theLine;
01060         }
01061         return '<pre>' . implode(LF, $lines) . '</pre>';
01062     }
01063 
01064     /**
01065      * Compile log details into template string
01066      *
01067      * @param   string      Log message (template)
01068      * @param   array       Data array to insert in log message
01069      * @return  string      Log details.
01070      */
01071     function log_getDetails($text, $data) {
01072             // $code is used later on to substitute errormessages with language-corrected values...
01073         if (is_array($data)) {
01074             return sprintf($text, $data[0], $data[1], $data[2], $data[3], $data[4]);
01075         } else {
01076             return $text;
01077         }
01078     }
01079 
01080 
01081     /**
01082      * Removing temp_CACHED files for installation
01083      *
01084      * @param   string      KEY pointing to installation
01085      * @return  string      HTML content
01086      */
01087     function rmCachedFiles($exp) {
01088         $all = $this->globalSiteInfo[$exp];
01089         $content = '
01090             <h2>' . htmlspecialchars($all['siteInfo']['sitename'] . ' (DB: ' . $all['siteInfo']['TYPO3_db']) . ')</h2>
01091             <hr />
01092             <h3>typo3conf/temp_CACHED_* files:</h3>';
01093 
01094         $path = $all['siteInfo']['SA_PATH'] . '/typo3conf/';
01095         if (@is_dir($path)) {
01096             $filesInDir = t3lib_div::getFilesInDir($path, 'php', 1);
01097 
01098             foreach ($filesInDir as $kk => $vv) {
01099                 if (t3lib_div::isFirstPartOfStr(basename($vv), 'temp_CACHED_')) {
01100                     if (strstr(basename($vv), 'ext_localconf.php') || strstr(basename($vv), 'ext_tables.php')) {
01101                         $content .= 'REMOVED: ' . $vv . '<br />';
01102                         unlink($vv);
01103                         if (file_exists($vv)) {
01104                             $content .= $this->error('ERROR: File still exists, so could not be removed anyways!') . '<br />';
01105                         }
01106                     }
01107                 }
01108             }
01109         } else {
01110             $content .= $this->error('ERROR: ' . $path . ' was not a directory!');
01111         }
01112 
01113         return $content;
01114     }
01115 
01116     /**
01117      * Menu for either update/information, showing links for each installation found
01118      *
01119      * @param   string      Action key "update" or "info"
01120      * @return  string      HTML output.
01121      */
01122     function menuContent($exp) {
01123         if ($exp) {
01124 
01125                 // Initialize:
01126             $lines = array();
01127             $head = '';
01128 
01129             foreach ($this->globalSiteInfo as $k => $all) {
01130 
01131                     // Setting section header, if needed.
01132                 if ($head != $all['siteInfo']['MAIN_DIR']) {
01133                     $lines[] = '
01134                         <h4 style="white-space: nowrap;">' . htmlspecialchars(t3lib_div::fixed_lgd_cs($all['siteInfo']['MAIN_DIR'], -18)) . '</h4>';
01135                     $head = $all['siteInfo']['MAIN_DIR']; // Set new head...
01136                 }
01137 
01138                     // Display mode:
01139                 switch ($exp) {
01140                     case 'update':
01141 
01142                             // Label:
01143                         $label = $all['siteInfo']['sitename'] ? $all['siteInfo']['sitename'] : '(DB: ' . $all['siteInfo']['TYPO3_db'] . ')';
01144                         $lines[] = '
01145                             <hr />
01146                             <strong>' . htmlspecialchars($label) . '</strong> (' . htmlspecialchars(substr($all['siteInfo']['SA_PATH'], strlen($all['siteInfo']['MAIN_DIR']) + 1)) . ')<br />';
01147 
01148                             // To avoid "visited links" display on next hit:
01149                         $tempVal = '&_someUniqueValue=' . $GLOBALS['EXEC_TIME'];
01150 
01151                             // Add links for update:
01152                         $url = $this->scriptName . '?type=page&show=rmTempCached&exp=' . $k . $tempVal;
01153                         $lines[] = '<span style="white-space: nowrap;"><a href="' . htmlspecialchars($url) . '" target="TSApage">Remove temp_CACHED files</a></span>';
01154 
01155                         $url = $all['siteInfo']['INSTALL_URL'] . 'index.php?TYPO3_INSTALL[type]=database&TYPO3_INSTALL[database_type]=import|CURRENT_STATIC' . "&presetWholeTable=1" . $tempVal . '#bottom';
01156                         $lines[] = '<span style="white-space: nowrap;"><a href="' . htmlspecialchars($url) . '" target="TSApage">CURRENT_STATIC</a></span>';
01157 
01158                         $url = $all['siteInfo']['INSTALL_URL'] . 'index.php?TYPO3_INSTALL[type]=database&TYPO3_INSTALL[database_type]=cmpFile|CURRENT_TABLES' . $tempVal . '#bottom';
01159                         $lines[] = '<span style="white-space: nowrap;"><a href="' . htmlspecialchars($url) . '" target="TSApage">CURRENT_TABLES</a></span>';
01160 
01161                             // Cache
01162                         $url = $all['siteInfo']['INSTALL_URL'] . 'index.php?TYPO3_INSTALL[type]=database&TYPO3_INSTALL[database_type]=cache|' .
01163                                "&PRESET[database_clearcache][cache_pages]=1" .
01164                                '&PRESET[database_clearcache][cache_pagesection]=1' .
01165                                "&PRESET[database_clearcache][cache_hash]=1" .
01166                                $tempVal .
01167                                '#bottom';
01168                         $lines[] = '<span style="white-space: nowrap;"><a href="' . htmlspecialchars($url) . '" target="TSApage">Clear cache</a></span>';
01169 
01170                             // Admin link
01171                         $url = $all['siteInfo']['ADMIN_URL'] . 'index.php';
01172                         $lines[] = '<span style="white-space: nowrap;"><a href="' . htmlspecialchars($url) . '" target="' . $this->targetWindowAdmin . '">Admin -></a></span>';
01173                     break;
01174                     case 'info':
01175                             // item
01176                         $label = $all['siteInfo']['sitename'] ? $all['siteInfo']['sitename'] : '(DB: ' . $all['siteInfo']['TYPO3_db'] . ')';
01177 
01178                         $url = $this->scriptName . '?type=page&show=info&exp=' . $k;
01179                         $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>';
01180                     break;
01181                 }
01182             }
01183 
01184                 // Return result.
01185             return implode('<br />', $lines) . '<br />';
01186         }
01187     }
01188 
01189     /**
01190      * Create list of admin logins.
01191      *
01192      * @return  string      HTML table
01193      */
01194     function makeAdminLogin() {
01195 
01196             // Initialize:
01197         $lines = array();
01198         $head = '';
01199 
01200             // Traverse installations found:
01201         foreach ($this->globalSiteInfo as $k => $all) {
01202 
01203                 // Setting section header, if needed.
01204             if ($head != $all['siteInfo']['MAIN_DIR']) {
01205                 $lines[] = '
01206                     <tr>
01207                         <td colspan="2"><br />
01208                         <h4>' . htmlspecialchars($all['siteInfo']['MAIN_DIR']) . '</h4>
01209                         </td>
01210                     </tr>';
01211                 $head = $all['siteInfo']['MAIN_DIR'];
01212             }
01213 
01214                 // item
01215             $label = $all['siteInfo']['sitename'] ? $all['siteInfo']['sitename'] : '(DB: ' . $all['siteInfo']['TYPO3_db'] . ')';
01216             $unique = md5(microtime());
01217 
01218             $opts = array();
01219             $defUName = '';
01220 
01221             if (is_array($all['siteInfo']['ADMINS'])) {
01222 
01223                 foreach ($all['siteInfo']['ADMINS'] as $vArr) {
01224                     $chalVal = md5($vArr['username'] . ':' . $vArr['password'] . ':' . $unique);
01225                     $opts[] = '<option value="' . $chalVal . '">' . htmlspecialchars($vArr['username'] . ($vArr['disable'] ? ' [DISABLED]' : '')) . '</option>';
01226                     if (!$defUName) {
01227                         $defUName = $vArr['username'];
01228                     }
01229                 }
01230             }
01231             if (count($opts) > 1) {
01232                 $userident = '
01233                     <select name="userident" onchange="document[\'' . $k . '\'].username.value=this.options[this.selectedIndex].text;">
01234                         ' . implode('
01235                         ', $opts) . '
01236                     </select>
01237                 ';
01238             } else {
01239                 $userident = '
01240                     (' . $defUName . ')<br />
01241                     <input type="hidden" name="userident" value="' . $chalVal . '" />';
01242             }
01243 
01244             $form = '
01245             <form name="' . $k . '" action="' . $all['siteInfo']['ADMIN_URL'] . 'index.php" target="EXTERnalWindow" method="post">
01246                 <input type="submit" name="submit" value="Login" />
01247                 <input type="hidden" name="username" value="' . $defUName . '" />
01248                 <input type="hidden" name="challenge" value="' . $unique . '" />
01249                 <input type="hidden" name="redirect_url" value="" />
01250                 <input type="hidden" name="login_status" value="login" />
01251                 ' . trim($userident) . '
01252             </form>';
01253 
01254             $lines[] = '
01255                 <tr>
01256                     <td><strong>' . htmlspecialchars($label) . '</strong></td>
01257                     <td nowrap="nowrap">' . trim($form) . '</td>
01258                 </tr>';
01259         }
01260 
01261             // Return login table:
01262         return '<table border="1" cellpadding="5" cellspacing="1">' . implode('', $lines) . '</table>';
01263     }
01264 
01265     /**
01266      * For for changing admin passwords
01267      *
01268      * @return  string      Form content.
01269      */
01270     function changeAdminPasswordsForm() {
01271         $content = '';
01272 
01273         foreach ($this->changeAdminPasswords as $k => $p) {
01274             $content .= '
01275                 <h3>' . $k . '</h3>';
01276 
01277             foreach ($p as $kk => $pp) {
01278                 $content .= '<span style="white-space: nowrap;">';
01279                 $content .= '<input type="checkbox" name="SETFIELDS[]" value="' . $pp . '" /> ' . $pp . ' - ';
01280                 $content .= htmlspecialchars(implode(' - ', $this->collectAdminPasswords[$k][$kk]));
01281                 $content .= '</span><br />';
01282             }
01283         }
01284 
01285         $content .= 'New password: <input type="text" name="NEWPASS" /><br />';
01286         $content .= 'New password (md5): <input type="text" name="NEWPASS_md5" /><br />
01287             (This overrules any plain password above!)
01288         <br />';
01289         $content = '
01290         <form action="' . htmlspecialchars($this->scriptName . '?type=page&show=admin') . '" method="post">
01291         ' . $content . '
01292         <input type="submit" name="Set" />
01293         </form>
01294         ';
01295 
01296         return $content;
01297     }
01298 
01299     /**
01300      * Setting new passwords
01301      *
01302      * @return  string      Status
01303      * @see changeAdminPasswordsForm()
01304      */
01305     function setNewPasswords() {
01306         $whichFields = t3lib_div::_POST('SETFIELDS');
01307         $pass = trim(t3lib_div::_POST('NEWPASS'));
01308         $passMD5 = t3lib_div::_POST('NEWPASS_md5');
01309 
01310         $updatedFlag = 0;
01311         if (($pass || $passMD5) && is_array($whichFields)) {
01312             $pass = $passMD5 ? $passMD5 : md5($pass);
01313 
01314             foreach ($whichFields as $values) {
01315                 $parts = explode(':', $values);
01316                 if (count($parts) > 2) {
01317                     $key = $this->mapDBtoKey[$parts[0]];
01318                     if ($key && isset($this->globalSiteInfo[$key]['siteInfo'])) {
01319                         $error = $this->connectToDatabase($this->globalSiteInfo[$key]['siteInfo']);
01320                         if (!$error) {
01321                             $DB = $this->globalSiteInfo[$key]['siteInfo']['TYPO3_db'];
01322                             $content .= '<h3>Updating ' . $DB . ':</h3>';
01323 
01324                             $query = $GLOBALS['TYPO3_DB']->UPDATEquery(
01325                                 'be_users',
01326                                 'uid=' . intval($parts[1]) . ' AND username="' . addslashes($parts[2]) . '" AND admin!=0',
01327                                 array('password' => $pass)
01328                             ); // username/admin are added to security. But they are certainly redundant!!
01329                             mysql($DB, $query);
01330 
01331                             $content .= 'Affected rows: ' . mysql_affected_rows() . '<br /><hr />';
01332                             $updatedFlag = '1';
01333                         }
01334                     }
01335                 }
01336             }
01337         }
01338 
01339         $this->initProcess();
01340         return $content;
01341     }
01342 }
01343 
01344 if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_superadmin.php'])) {
01345     include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_superadmin.php']);
01346 }
01347 
01348 ?>