Fixed bug #16445: Performance Tuning: Replace exec_SELECTgetRows with exec_SELECTgetS...
[Packages/TYPO3.CMS.git] / t3lib / class.t3lib_superadmin.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 1999-2010 Kasper Skårhøj (kasperYYYY@typo3.com)
6 * All rights reserved
7 *
8 * This script is part of the TYPO3 project. The TYPO3 project is
9 * free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * The GNU General Public License can be found at
15 * http://www.gnu.org/copyleft/gpl.html.
16 * A copy is found in the textfile GPL.txt and important notices to the license
17 * from the author is found in LICENSE.txt distributed with these scripts.
18 *
19 *
20 * This script is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * This copyright notice MUST APPEAR in all copies of the script!
26 ***************************************************************/
27 /**
28 * Super Admin class has functions for the administration of multiple TYPO3 sites in folders
29 * See 'misc/superadmin.php' for details on how to use!
30 *
31 * $Id$
32 * Revised for TYPO3 3.6 February/2004 by Kasper Skårhøj
33 * XHTML Compliant
34 *
35 * @author Kasper Skårhøj <kasperYYYY@typo3.com>
36 */
37 /**
38 * [CLASS/FUNCTION INDEX of SCRIPT]
39 *
40 * 120: function debug($p1,$p2='')
41 *
42 *
43 * 134: class t3lib_superadmin
44 *
45 * SECTION: Initialize stuff
46 * 180: function t3lib_superadmin()
47 * 192: function init($parentDirs)
48 *
49 * SECTION: Main functions
50 * 215: function defaultSet()
51 * 271: function make()
52 *
53 * SECTION: Output preparation
54 * 376: function setMenuItem($code,$label)
55 * 390: function error($str)
56 * 401: function headerParentDir($str)
57 * 412: function headerSiteDir($str)
58 *
59 * SECTION: Collection information
60 * 444: function initProcess()
61 * 482: function processSiteDir($path,$dir)
62 * 524: function includeLocalconf($localconf)
63 * 554: function connectToDatabase($siteInfo)
64 * 576: function getDBInfo($key)
65 *
66 * SECTION: Content: Installation Overview
67 * 626: function makeTable()
68 *
69 * SECTION: Content: Local extensions
70 * 729: function localExtensions()
71 * 902: function getExtensionInfo($path,$extKey,$k)
72 * 956: function getAllFilesAndFoldersInPath($fileArr,$extPath,$extList='',$regDirs=0)
73 * 978: function findMostRecent($fileArr,$extPath)
74 * 996: function removePrefixPathFromList($fileArr,$extPath)
75 *
76 * SECTION: Content: Other
77 * 1033: function singleSite($exp)
78 * 1064: function loginLog($DB)
79 * 1102: function log_getDetails($text,$data)
80 * 1116: function rmCachedFiles($exp)
81 * 1149: function menuContent($exp)
82 * 1221: function makeAdminLogin()
83 * 1295: function changeAdminPasswordsForm()
84 * 1330: function setNewPasswords()
85 *
86 * TOTAL FUNCTIONS: 28
87 * (This index is automatically created/updated by the extension "extdeveval")
88 *
89 */
90
91
92 // *******************************
93 // Set error reporting
94 // *******************************
95 if (defined('E_DEPRECATED')) {
96 error_reporting(E_ALL ^ E_NOTICE ^ E_DEPRECATED);
97 } else {
98 error_reporting(E_ALL ^ E_NOTICE);
99 }
100
101 define('TYPO3_mainDir', 'typo3/'); // This is the directory of the backend administration for the sites of this TYPO3 installation.
102
103
104 // Dependency:
105 $path_t3lib = './typo3_src/t3lib/';
106 include_once($path_t3lib . 'class.t3lib_div.php');
107 include_once($path_t3lib . 'class.t3lib_db.php');
108 $TYPO3_DB = t3lib_div::makeInstance('t3lib_DB');
109
110
111 /**
112 * Debug function. Substitute since no config_default.php file is included anywhere
113 *
114 * @param mixed Debug var
115 * @param string Header string
116 * @return void
117 */
118 function debug($p1, $p2 = '') {
119 t3lib_div::debug($p1, $p2);
120 }
121
122
123 /**
124 * Super Admin class has functions for the administration of multiple TYPO3 sites in folders
125 * NOTICE: Only compliant with single MySQL database usage per installation!
126 *
127 * @author Kasper Skårhøj <kasperYYYY@typo3.com>
128 * @package TYPO3
129 * @subpackage t3lib
130 */
131 class t3lib_superadmin {
132
133 // External, static:
134 var $targetWindow = 'superAdminWindow';
135 var $targetWindowAdmin = 'superAdminWindowAdmin';
136 var $targetWindowInstall = 'superAdminWindowInstall';
137 var $scriptName = 'superadmin.php';
138
139 // GP vars:
140 var $show; // "menu", "all", "admin", "info", "rmTempCached", "localext"
141 var $type; // "phpinfo", "page" - default renders a frameset
142 var $exp; // Additional parameter, typically a md5-hash pointing to an installation of TYPO3
143
144 // Internal, static:
145 var $parentDirs = array(); // Configured directories to search
146 var $globalSiteInfo = array(); // Array with information about found TYPO3 installations
147
148 var $currentUrl = '';
149 var $mapDBtoKey = array();
150 var $collectAdminPasswords = array();
151 var $changeAdminPasswords = array();
152 var $collectInstallPasswords = array();
153
154 // Control:
155 var $full = 0; // If set, the full information array per site is printed.
156
157 var $noCVS = 0; // See tools/em/index.php....
158
159
160 /**********************************
161 *
162 * Initialize stuff
163 *
164 **********************************/
165
166 /**
167 * Constructor, setting GP vars
168 *
169 * @return void
170 */
171 function t3lib_superadmin() {
172 $this->show = t3lib_div::_GP('show');
173 $this->type = t3lib_div::_GP('type');
174 $this->exp = t3lib_div::_GP('exp');
175 }
176
177 /**
178 * Initialize with configuration - from the 'superadmin.php' script. See misc/superadmin.php for example.
179 *
180 * @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.
181 * @return void
182 */
183 function init($parentDirs) {
184 $this->parentDirs = $parentDirs;
185 }
186
187
188 /**************************
189 *
190 * Main functions
191 *
192 **************************/
193
194 /**
195 * Main function, creating HTML content; frameset, menu, content frames.
196 * Outputs the full HTML to browser.
197 *
198 * @return void
199 */
200 function defaultSet() {
201
202 // Creating content based on "type" variable:
203 switch ($this->type) {
204 case 'phpinfo':
205 phpinfo();
206 break;
207 case 'page':
208 ?>
209 <!DOCTYPE html
210 PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
211 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
212 <html>
213 <head>
214 <style type="text/css">
215 .redclass {
216 color: red;
217 }
218
219 P {
220 font-family: Verdana, Arial, Helvetica, sans-serif;
221 font-size: 11px
222 }
223
224 BODY {
225 font-family: Verdana, Arial, Helvetica, sans-serif;
226 font-size: 10px
227 }
228
229 H1 {
230 font-family: Verdana, Arial, Helvetica, sans-serif;
231 font-size: 20px;
232 color: #000066;
233 }
234
235 H2 {
236 font-family: Verdana, Arial, Helvetica, sans-serif;
237 font-size: 17px;
238 color: #000066;
239 }
240
241 H3 {
242 font-family: Verdana, Arial, Helvetica, sans-serif;
243 font-size: 14px;
244 color: #000066;
245 }
246
247 H4 {
248 font-family: Verdana, Arial, Helvetica, sans-serif;
249 font-size: 11px;
250 color: maroon;
251 }
252
253 TD {
254 font-family: Verdana, Arial, Helvetica, sans-serif;
255 font-size: 10px
256 }
257 </style>
258 <title>TYPO3 Super Admin</title>
259 </head>
260 <body>
261 <?php
262 echo $this->make();
263 ?>
264 </body>
265 </html>
266 <?php
267 break;
268 default:
269 ?>
270 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
271 <html>
272 <head>
273 <title>TYPO3 Super Admin</title>
274 </head>
275 <frameset cols="250,*">
276 <frame name="TSAmenu" src="superadmin.php?type=page&show=menu" marginwidth="10" marginheight="10"
277 scrolling="auto" frameborder="0">
278 <frame name="TSApage" src="superadmin.php?type=page" marginwidth="10" marginheight="10"
279 scrolling="auto" frameborder="0">
280 </frameset>
281 </html>
282 <?php
283 break;
284 }
285 }
286
287 /**
288 * Main function, creating page content.
289 *
290 * @return string HTML content.
291 */
292 function make() {
293
294 $retVal = '';
295
296 // Creating information about the sites found:
297 $content = $this->initProcess();
298
299 // Output mode:
300 switch ($this->show) {
301 case 'menu':
302 $lines = array();
303 $lines[] = $this->setMenuItem('info', 'INFO');
304 $lines[] = $this->setMenuItem('update', 'UPDATE');
305 $lines[] = '';
306 $lines[] = '<a href="' . htmlspecialchars($this->scriptName . '?type=page') . '" target="TSApage">Default</a>';
307 $lines[] = '<a href="' . htmlspecialchars($this->scriptName . '?type=page&show=all') . '" target="TSApage">All details</a>';
308 $lines[] = '<a href="' . htmlspecialchars($this->scriptName . '?type=page&show=admin') . '" target="TSApage">Admin logins</a>';
309 $lines[] = '<a href="' . htmlspecialchars($this->scriptName . '?type=phpinfo') . '" target="TSApage">phpinfo()</a>';
310 $lines[] = '<a href="' . htmlspecialchars($this->scriptName . '?type=page&show=localext') . '" target="TSApage">Local extensions</a>';
311 $lines[] = '';
312 $content = implode('<br />', $lines);
313 $content .= '<hr />';
314 $content .= $this->menuContent($this->exp);
315 $retVal = '<h2 align="center">TYPO3<br />Super Admin</h2>' . $content;
316 break;
317 case 'all':
318 $retVal = '
319 <h1>All details:</h1>
320 <h2>Overview:</h2>
321 ' . $this->makeTable() . '
322 <br /><hr /><br />
323 <h1>Details per site:</h1>
324 ' . $content;
325 break;
326 case 'admin':
327 $content = $this->setNewPasswords();
328 $this->makeTable();
329 $retVal = $content . '
330 <h1>Admin options:</h1>
331
332 <h2>Admin logins:</h2>
333 ' . $this->makeAdminLogin() . '
334 <br /><hr /><br />
335
336 <h2>TBE Admin Passwords:</h2>
337 ' . t3lib_div::view_array($this->collectAdminPasswords) . '
338 <br /><hr /><br />
339
340 <h2>Install Tool Passwords:</h2>
341 ' . t3lib_div::view_array($this->collectInstallPasswords) . '
342 <br /><hr /><br />
343
344 <h2>Change TBE Admin Passwords:</h2>
345 ' . $this->changeAdminPasswordsForm() . '
346 <br /><hr /><br />';
347 break;
348 case 'info':
349 $retVal = '
350 <h1>Single site details</h1>
351 ' . $this->singleSite($this->exp) .
352 '<br />';
353 break;
354 case 'rmTempCached':
355 $retVal = '
356 <h1>Removing temp_CACHED_*.php files</h1>
357 ' . $this->rmCachedFiles($this->exp) .
358 '<br />';
359 break;
360 case 'localext':
361 $retVal = '
362 <h1>Local Extensions Found:</h1>
363 ' . $this->localExtensions() .
364 '<br />';
365 break;
366 default:
367 $retVal = '
368 <h1>Default info:</h1>' .
369 $content;
370 break;
371 }
372 return $retVal;
373 }
374
375
376 /********************************
377 *
378 * Output preparation
379 *
380 *******************************/
381
382 /**
383 * Creates menu item from input.
384 *
385 * @param string Value for "&exp" parameter
386 * @param string The label
387 * @return string Wrapped value
388 */
389 function setMenuItem($code, $label) {
390 $out = '<a href="' . htmlspecialchars($this->scriptName . '?type=page&show=menu&exp=' . $code) . '" target="TSAmenu">' . htmlspecialchars($label) . '</a>';
391 if ($code == $this->exp) {
392 $out = '<span style="color:red;">&gt;&gt;</span>' . $out;
393 }
394 return $out;
395 }
396
397 /**
398 * Wrap string in red span tag (for errors)
399 *
400 * @param string Input string
401 * @return string Output string
402 */
403 function error($str) {
404 $out = '<span style="color:red; font-size: 14px; font-weight: bold;">' . htmlspecialchars($str) . '</span>';
405 return $out;
406 }
407
408 /**
409 * Wraps input string in <h2>
410 *
411 * @param string Input string
412 * @return string Output string, wrapped in <h2>
413 */
414 function headerParentDir($str) {
415 $out = '<h2>' . htmlspecialchars($str) . '</h2>';
416 return $out;
417 }
418
419 /**
420 * Wraps input string in <h3>
421 *
422 * @param string Input string
423 * @return string Output string, wrapped in <h3>
424 */
425 function headerSiteDir($str) {
426 $out = '<h3>' . htmlspecialchars($str) . '</h3>';
427 return $out;
428 }
429
430
431 /********************************
432 *
433 * Collection information
434 *
435 *******************************/
436
437 /**
438 * Traverses the parent dirs, collecting the list of TYPO3 installations into $this->globalSiteInfo
439 *
440 * @return string HTML content (The default view seen when starting the superadmin.php script)
441 */
442 function initProcess() {
443 $content = '';
444
445 foreach ($this->parentDirs as $k => $v) {
446 $dir = rtrim($v['dir'], '/');
447 $baseUrl = rtrim($v['url'], '/');
448 $content .= '<br /><br /><br />';
449 $content .= $this->headerParentDir($dir);
450 if (@is_dir($dir)) {
451 $in_dirs = t3lib_div::get_dirs($dir);
452 asort($in_dirs);
453 $dirArr = array();
454 foreach ($in_dirs as $k => $v) {
455 if (substr($v, 0, 9) != 'typo3_src') {
456 $this->currentUrl = $baseUrl . '/' . $v;
457 $content .= $this->headerSiteDir($v);
458 $content .= $this->processSiteDir($dir . '/' . $v, $dir);
459 }
460 }
461 } else {
462 $content .= $this->error('"' . $dir . '" was not a directory!');
463 }
464 }
465
466 return $content;
467 }
468
469 /**
470 * Creating information array for a specific TYPO3 installation
471 * Information about site is stored in ->globalSiteInfo array
472 *
473 * @param string Absolute path to installation (PATH_site)
474 * @param string Directory of main directory (level under PATH_site)
475 * @return string HTML content with information about the site.
476 * @access private
477 * @see initProcess()
478 */
479 function processSiteDir($path, $dir) {
480 if (@is_dir($path)) {
481 $localconf = $path . '/typo3conf/localconf.php';
482 if (@is_file($localconf)) {
483 $key = md5($localconf);
484 $this->includeLocalconf($localconf);
485
486 $this->mapDBtoKey[$this->globalSiteInfo[$key]['siteInfo']['TYPO3_db']] = $key;
487 $this->globalSiteInfo[$key]['siteInfo']['MAIN_DIR'] = $dir;
488 $this->globalSiteInfo[$key]['siteInfo']['SA_PATH'] = $path;
489 $this->globalSiteInfo[$key]['siteInfo']['URL'] = $this->currentUrl . '/';
490 $this->globalSiteInfo[$key]['siteInfo']['ADMIN_URL'] = $this->currentUrl . '/' . TYPO3_mainDir;
491 $this->globalSiteInfo[$key]['siteInfo']['INSTALL_URL'] = $this->currentUrl . '/' . TYPO3_mainDir . 'install/';
492
493 // Connect to database:
494 $conMsg = $this->connectToDatabase($this->globalSiteInfo[$key]['siteInfo']);
495 if (!$conMsg) {
496 $this->getDBInfo($key);
497 $out .= '';
498 } else {
499 $out = $conMsg;
500 }
501
502 // Show details:
503 if ($this->full) {
504 $out .= t3lib_div::view_array($this->globalSiteInfo[$key]);
505 } else {
506 $out .= t3lib_div::view_array($this->globalSiteInfo[$key]['siteInfo']);
507 }
508 } else {
509 $out = $this->error($localconf . ' is not a file!');
510 }
511 } else {
512 $out = $this->error($path . ' is not a directory!');
513 }
514 return $out;
515 }
516
517 /**
518 * Includes "localconf" of a TYPO3 installation an loads $this->globalSiteInfo with this information.
519 *
520 * @param string Absolute path to localconf.php file to include.
521 * @return array Array with information about the site.
522 * @access private
523 * @see processSiteDir()
524 */
525 function includeLocalconf($localconf) {
526 $TYPO3_CONF_VARS = array();
527 $typo_db = '';
528 $typo_db_username = '';
529 $typo_db_password = '';
530 $typo_db_host = '';
531
532 include($localconf);
533
534 $siteInfo = array();
535 $siteInfo['sitename'] = $TYPO3_CONF_VARS['SYS']['sitename'];
536 $siteInfo['TYPO3_db'] = $typo_db;
537 $siteInfo['TYPO3_db_username'] = $typo_db_username;
538 $siteInfo['TYPO3_db_password'] = $typo_db_password;
539 $siteInfo['TYPO3_db_host'] = $typo_db_host;
540 $siteInfo['installToolPassword'] = $TYPO3_CONF_VARS['BE']['installToolPassword'];
541 $siteInfo['warningEmailAddress'] = $TYPO3_CONF_VARS['BE']['warning_email_addr'];
542 $siteInfo['warningMode'] = $TYPO3_CONF_VARS['BE']['warning_mode'];
543
544 $this->globalSiteInfo[md5($localconf)] = array('siteInfo' => $siteInfo, 'TYPO3_CONF_VARS' => $TYPO3_CONF_VARS);
545 return $siteInfo;
546 }
547
548 /**
549 * Connects to a MySQL database with the TYPO3 db host/username/password and database as found in the localconf.php file!
550 * 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
551 *
552 * @param array $siteInfo array, containing username/password/host/database values.
553 * @return string Array message if any
554 */
555 function connectToDatabase($siteInfo) {
556 if (@mysql_pconnect($siteInfo['TYPO3_db_host'], $siteInfo['TYPO3_db_username'], $siteInfo['TYPO3_db_password'])) {
557 if (!$siteInfo['TYPO3_db']) {
558 return $this->error('No database selected');
559 } elseif (!mysql_select_db($siteInfo['TYPO3_db'])) {
560 return $this->error('Cannot connect to the current database, "' . $siteInfo['TYPO3_db'] . '"');
561 }
562 } else {
563 return $this->error('The current username, password or host was not accepted when the connection to the database was attempted to be established!');
564 }
565 }
566
567
568 /**
569 * Get database information, assuming standard tables like "be_users"
570 * Adding the information to ->globalSiteInfo
571 *
572 * @param string Key for site in ->globalSiteInfo
573 * @return void
574 * @access private
575 * @see processSiteDir()
576 */
577 function getDBInfo($key) {
578 $DB = $this->globalSiteInfo[$key]['siteInfo']['TYPO3_db'];
579
580 // Non-admin users
581 $query = $GLOBALS['TYPO3_DB']->SELECTquery('count(*)', 'be_users', 'admin=0 AND deleted=0');
582 $res = mysql($DB, $query);
583 $row = mysql_fetch_row($res);
584 $this->globalSiteInfo[$key]['siteInfo']['BE_USERS_NONADMIN'] = $row[0];
585
586 // Admin users
587 $query = $GLOBALS['TYPO3_DB']->SELECTquery('count(*)', 'be_users', 'admin!=0 AND deleted=0');
588 $res = mysql($DB, $query);
589 $row = mysql_fetch_row($res);
590 $this->globalSiteInfo[$key]['siteInfo']['BE_USERS_ADMIN'] = $row[0];
591
592 // Select Admin users
593 $query = $GLOBALS['TYPO3_DB']->SELECTquery('uid,username,password,email,realName,disable', 'be_users', 'admin!=0 AND deleted=0');
594 $res = mysql($DB, $query);
595 while ($row = mysql_fetch_assoc($res)) {
596 $this->globalSiteInfo[$key]['siteInfo']['ADMINS'][] = $row;
597 }
598 }
599
600
601 /******************************
602 *
603 * Content: Installation Overview
604 *
605 ******************************/
606
607 /**
608 * Creates big table with information about all installations in ->globalSiteInfo
609 *
610 * @return string HTML table
611 */
612 function makeTable() {
613
614 // Header row
615 $info = array();
616 $info[] = 'Site:';
617 $info[] = 'Path:';
618 $info[] = 'Database:';
619 $info[] = 'Username';
620 $info[] = 'Password';
621 $info[] = 'Host';
622 $info[] = 'Links (new win)';
623 $info[] = '#Users NA/A';
624 $info[] = 'Admin be_users Info';
625 $info[] = 'Install Tool Password';
626 $info[] = 'Warning email address';
627 $info[] = 'W.mode';
628 $mainArrRows[] = '
629 <tr bgcolor="#eeeeee">
630 <td nowrap="nowrap" valign="top">' . implode('</td>
631 <td nowrap="nowrap" valign="top">', $info) . '</td>
632 </tr>';
633
634 // Traverse globalSiteInfo for each site:
635 foreach ($this->globalSiteInfo as $k => $all) {
636 $info = array();
637
638 // Sitename and Database details:
639 $info[] = htmlspecialchars($all['siteInfo']['sitename']);
640 $info[] = '<span style="color:#666666;">' . htmlspecialchars($all['siteInfo']['MAIN_DIR']) . '</span>' . htmlspecialchars(substr($all['siteInfo']['SA_PATH'], strlen($all['siteInfo']['MAIN_DIR'])));
641 $info[] = htmlspecialchars($all['siteInfo']['TYPO3_db']);
642 $info[] = htmlspecialchars($all['siteInfo']['TYPO3_db_username']);
643 $info[] = htmlspecialchars($all['siteInfo']['TYPO3_db_password']);
644 $info[] = htmlspecialchars($all['siteInfo']['TYPO3_db_host']);
645
646 // URL
647 $info[] = '<a href="' . htmlspecialchars($all['siteInfo']['URL']) . '" target="' . $this->targetWindow . '">Site</a>' .
648 ' / <a href="' . htmlspecialchars($all['siteInfo']['ADMIN_URL']) . '" target="' . $this->targetWindowAdmin . '">Admin</a>' .
649 ' / <a href="' . htmlspecialchars($all['siteInfo']['INSTALL_URL']) . '" target="' . $this->targetWindowInstall . '">Install</a>';
650 $info[] = htmlspecialchars($all['siteInfo']['BE_USERS_NONADMIN'] . '/' . $all['siteInfo']['BE_USERS_ADMIN']);
651
652 // Admin
653 if (is_array($all['siteInfo']['ADMINS'])) {
654 $lines = array();
655 foreach ($all['siteInfo']['ADMINS'] as $vArr) {
656 $lines[] = htmlspecialchars($vArr['password'] . ' - ' . $vArr['username'] . ' (' . $vArr['realName'] . ', ' . $vArr['email'] . ')');
657 $this->collectAdminPasswords[$vArr['password']][] = array(
658 'path' => $all['siteInfo']['SA_PATH'],
659 'site' => $all['siteInfo']['sitename'],
660 'database' => $all['siteInfo']['TYPO3_db'],
661 'user' => $vArr['username'],
662 'name_email' => $vArr['realName'] . ', ' . $vArr['email']
663 );
664 $this->changeAdminPasswords[$vArr['password']][] = $all['siteInfo']['TYPO3_db'] . ':' . $vArr['uid'] . ':' . $vArr['username'];
665 }
666 $info[] = implode('<br />', $lines);
667 } else {
668 $info[] = $this->error('No DB connection!');
669 }
670 // Install
671 $info[] = htmlspecialchars($all['siteInfo']['installToolPassword']);
672 $this->collectInstallPasswords[$all['siteInfo']['installToolPassword']][] = $all['siteInfo']['SA_PATH'] . ' - ' . $all['siteInfo']['sitename'] . ' - (' . $all['siteInfo']['TYPO3_db'] . ')';
673
674 $info[] = htmlspecialchars($all['siteInfo']['warningEmailAddress']);
675 $info[] = htmlspecialchars($all['siteInfo']['warningMode']);
676
677 // compile
678 $mainArrRows[] = '
679 <tr>
680 <td nowrap="nowrap" valign="top">' . implode('</td>
681 <td nowrap="nowrap" valign="top">', $info) . '</td>
682 </tr>';
683 }
684
685 // Compile / return table finally:
686 $table = '<table border="1" cellpadding="1" cellspacing="1">' . implode('', $mainArrRows) . '</table>';
687 return $table;
688 }
689
690
691 /******************************
692 *
693 * Content: Local extensions
694 *
695 ******************************/
696
697 /**
698 * Based on the globalSiteInfo array, this prints information about local extensions for each site.
699 * In particular version number and most recent mod-time is interesting!
700 *
701 * @return string HTML
702 */
703 function localExtensions() {
704 $this->extensionInfoArray = array();
705
706 // Traverse $this->globalSiteInfo for local extensions:
707 foreach ($this->globalSiteInfo as $k => $all) {
708 if ($all['siteInfo']['SA_PATH']) {
709 $extDir = $all['siteInfo']['SA_PATH'] . '/typo3conf/ext/';
710 if (@is_dir($extDir)) {
711 $this->extensionInfoArray['site'][$k] = array();
712
713 // Get extensions in local directory
714 $extensions = t3lib_div::get_dirs($extDir);
715 if (is_array($extensions)) {
716 foreach ($extensions as $extKey) {
717 // Getting and setting information for extension:
718 $eInfo = $this->getExtensionInfo($extDir, $extKey, $k);
719 $this->extensionInfoArray['site'][$k][$extKey] = $eInfo;
720 $this->extensionInfoArray['ext'][$extKey][$k] = $eInfo;
721 }
722 }
723 }
724 }
725 }
726
727 // Display results:
728 $out = '';
729 $headerRow = '
730 <tr bgcolor="#ccccee" style="font-weight:bold;">
731 <td>Extension key</td>
732 <td>Path</td>
733 <td>Title</td>
734 <td>Ver.</td>
735 <td>Files</td>
736 <td><span title="If M, then there is a manual.">M</span></td>
737 <td>Last mod. time</td>
738 <td>Hash off all file mod. times:</td>
739 <td>TYPO3 ver. req.</td>
740 <td>CGL compliance</td>
741 </tr>
742 ';
743
744 // PER EXTENSION:
745 if (is_array($this->extensionInfoArray['ext'])) {
746 $extensionKeysCollect = array();
747
748 ksort($this->extensionInfoArray['ext']);
749 reset($this->extensionInfoArray['ext']);
750 $rows = array(
751 'reg' => array(),
752 'user' => array()
753 );
754
755 foreach ($this->extensionInfoArray['ext'] as $extKey => $instances) {
756 $mtimes = array();
757
758 // Find most recent mtime of the options:
759 foreach ($instances as $k => $eInfo) {
760 $mtimes[] = $eInfo['mtime'];
761 }
762 // Max mtime:
763 $maxMtime = max($mtimes);
764 $c = 0;
765
766 // So, traverse all sites with the extension present:
767 foreach ($instances as $k => $eInfo) {
768 // Set background color if mtime matches
769 if ($maxMtime == $eInfo['mtime']) {
770 $this->extensionInfoArray['site'][$k][$extKey]['_highlight'] = 1;
771 $bgCol = $eInfo['dirtype'] == 'link' ? ' bgcolor="#ffcccc"' : ' bgcolor="#eeeeee"';
772 } else {
773 $bgCol = ' style="color: #999999; font-style: italic;"';
774 }
775
776 // Make row:
777 $type = substr($extKey, 0, 5) != 'user_' ? 'reg' : 'user';
778 if ($type == 'reg') {
779 $extensionKeysCollect[] = $extKey;
780 }
781
782 if (!is_array($eInfo)) {
783 // Standard listing:
784 $rows[$type][] = '
785 <tr>
786 ' . (!$c ? '<td rowspan="' . count($instances) . '">' . htmlspecialchars($extKey) . '</td>' : '') . '
787 <td nowrap="nowrap" bgcolor="#ccddcc">' . htmlspecialchars($this->globalSiteInfo[$k]['siteInfo']['SA_PATH']) . '</td>
788 <td nowrap="nowrap" bgcolor="#ccddcc" colspan="8"><em>' . htmlspecialchars($eInfo) . '</em></td>
789 </tr>
790 ';
791 } else {
792 // Standard listing:
793 $rows[$type][] = '
794 <tr>
795 ' . (!$c ? '<td rowspan="' . count($instances) . '">' . htmlspecialchars($extKey) . '</td>' : '') . '
796 <td nowrap="nowrap"' . $bgCol . '>' . htmlspecialchars($this->globalSiteInfo[$k]['siteInfo']['SA_PATH']) . '</td>
797 <td nowrap="nowrap"' . $bgCol . '>' . htmlspecialchars($eInfo['title']) . '</td>
798 <td nowrap="nowrap"' . $bgCol . '>' . htmlspecialchars($eInfo['version']) . '</td>
799 <td nowrap="nowrap"' . $bgCol . '>' . htmlspecialchars($eInfo['numberfiles']) . '</td>
800 <td nowrap="nowrap"' . $bgCol . '>' . htmlspecialchars($eInfo['manual'] ? 'M' : '-') . '</td>
801 <td nowrap="nowrap"' . $bgCol . '>' . htmlspecialchars($eInfo['mtime'] ? date('d-m-y H:i:s', $eInfo['mtime']) : '') . '</td>
802 <td nowrap="nowrap"' . $bgCol . '>' . htmlspecialchars($eInfo['mtime_hash']) . '</td>
803
804 <td' . $bgCol . '>' . htmlspecialchars($eInfo['TYPO3_version']) . '</td>
805 <td' . $bgCol . '><img src="clear.gif" width="150" height="1" alt="" /><br />' . htmlspecialchars($eInfo['CGLcompliance'] . ($eInfo['CGLcompliance_note'] ? ' - ' . $eInfo['CGLcompliance_note'] : '')) . '</td>
806 </tr>
807 ';
808 }
809 $c++;
810 }
811 }
812
813 // Extensions with registered extension keys:
814 $out .= '
815 <h3>Registered extensions:</h3>
816 <table border="1">' . $headerRow . implode('', $rows['reg']) . '</table>';
817
818 // List of those extension keys in a form field:
819 $extensionKeysCollect = array_unique($extensionKeysCollect);
820 asort($extensionKeysCollect);
821 $out .= '<form action=""><textarea cols="80" rows="10">' . implode(LF, $extensionKeysCollect) . '</textarea></form>';
822
823 // USER extension (prefixed "user_")
824 $out .= '<br />
825 <h3>User extensions:</h3>
826 <table border="1">' . $headerRow . implode('', $rows['user']) . '</table>';
827 }
828
829 // PER SITE:
830 if (is_array($this->extensionInfoArray['site'])) {
831 $rows = array();
832 foreach ($this->extensionInfoArray['site'] as $k => $extensions) {
833
834 // So, traverse all sites with the extension present:
835 $c = 0;
836 foreach ($extensions as $extKey => $eInfo) {
837
838 // Set background color if mtime matches
839 if ($eInfo['_highlight']) {
840 $bgCol = $eInfo['dirtype'] == 'link' ? ' bgcolor="#ffcccc"' : ' bgcolor="#eeeeee"';
841 } else {
842 $bgCol = ' style="color: #999999; font-style: italic;"';
843 }
844
845 // Make row:
846 $rows[] = '
847 <tr>
848 ' . (!$c ? '<td rowspan="' . count($extensions) . '">' . htmlspecialchars($this->globalSiteInfo[$k]['siteInfo']['SA_PATH']) . '</td>' : '') . '
849 <td nowrap="nowrap"' . $bgCol . '>' . htmlspecialchars($extKey) . '</td>
850 <td nowrap="nowrap"' . $bgCol . '>' . htmlspecialchars($eInfo['title']) . '</td>
851 <td nowrap="nowrap"' . $bgCol . '>' . htmlspecialchars($eInfo['version']) . '</td>
852 <td nowrap="nowrap"' . $bgCol . '>' . htmlspecialchars($eInfo['numberfiles']) . '</td>
853 <td nowrap="nowrap"' . $bgCol . '>' . htmlspecialchars($eInfo['mtime'] ? date('d-m-y H:i:s', $eInfo['mtime']) : '') . '</td>
854 <td nowrap="nowrap"' . $bgCol . '>' . htmlspecialchars($eInfo['mtime_hash']) . '</td>
855 </tr>
856 ';
857 $c++;
858 }
859 }
860 $out .= '<br />
861 <h3>Sites:</h3>
862 <table border="1">' . implode('', $rows) . '</table>';
863 }
864
865 // Return content
866 return $out;
867 }
868
869 /**
870 * Gets information for an extension, eg. version and most-recently-edited-script
871 *
872 * @param string Path to local extension folder
873 * @param string Extension key
874 * @param string Key to globalSiteInformation array
875 * @return array Information array (unless an error occured)
876 */
877 function getExtensionInfo($path, $extKey, $k) {
878 $file = $path . $extKey . '/ext_emconf.php';
879 if (@is_file($file)) {
880 $_EXTKEY = $extKey;
881 $EM_CONF = array();
882 include($file);
883
884 $eInfo = array();
885 // Info from emconf:
886 $eInfo['title'] = $EM_CONF[$extKey]['title'];
887 $eInfo['version'] = $EM_CONF[$extKey]['version'];
888 $eInfo['CGLcompliance'] = $EM_CONF[$extKey]['CGLcompliance'];
889 $eInfo['CGLcompliance_note'] = $EM_CONF[$extKey]['CGLcompliance_note'];
890 $eInfo['TYPO3_version'] = $EM_CONF[$extKey]['TYPO3_version'];
891 $filesHash = unserialize($EM_CONF[$extKey]['_md5_values_when_last_written']);
892
893 if (!is_array($filesHash) || count($filesHash) < 500) {
894
895 // Get all files list (may take LOONG time):
896 $extPath = $path . $extKey . '/';
897 $fileArr = array();
898 $fileArr = $this->removePrefixPathFromList($this->getAllFilesAndFoldersInPath($fileArr, $extPath), $extPath);
899
900 if (!is_array($fileArr)) {
901 debug(array($fileArr, $extKey, $extPath, $this->getAllFilesAndFoldersInPath(array(), $extPath)), 'ERROR');
902 }
903
904 // Number of files:
905 $eInfo['numberfiles'] = count($fileArr);
906 $eInfo['dirtype'] = filetype($path . $extKey);
907
908 // Most recent modification:
909 $eInfo['mtime_files'] = $this->findMostRecent($fileArr, $extPath);
910 if (count($eInfo['mtime_files'])) {
911 $eInfo['mtime'] = max($eInfo['mtime_files']);
912 }
913 $eInfo['mtime_hash'] = md5(implode(',', $eInfo['mtime_files']));
914 } else {
915 $eInfo['mtime_hash'] = 'No calculation done, too many files in extension: ' . count($filesHash);
916 }
917
918 $eInfo['manual'] = @is_file($path . $extKey . '/doc/manual.sxw');
919
920 return $eInfo;
921 } else {
922 return 'ERROR: No emconf.php file: ' . $file;
923 }
924 }
925
926 /**
927 * Recursively gather all files and folders of extension path.
928 *
929 * @param array Array of files to which new files are added
930 * @param string Path to look up files in
931 * @param string List of file extensions to include. Blank = all
932 * @param boolean If set, directories are included as well.
933 * @return array $fileArr with new entries added.
934 */
935 function getAllFilesAndFoldersInPath($fileArr, $extPath, $extList = '', $regDirs = 0) {
936 if ($regDirs) {
937 $fileArr[] = $extPath;
938 }
939 $fileArr = array_merge($fileArr, t3lib_div::getFilesInDir($extPath, $extList, 1, 1));
940
941 $dirs = t3lib_div::get_dirs($extPath);
942 if (is_array($dirs)) {
943 foreach ($dirs as $subdirs) {
944 if ($subdirs && (strcmp($subdirs, 'CVS') || !$this->noCVS)) {
945 $fileArr = $this->getAllFilesAndFoldersInPath($fileArr, $extPath . $subdirs . '/', $extList, $regDirs);
946 }
947 }
948 }
949 return $fileArr;
950 }
951
952 /**
953 * Creates an array with modification times of all files in $fileArr
954 *
955 * @param array Files in extension (rel path)
956 * @param string Abs path prefix for files.
957 * @return array Array with modification times of files (filenames are keys)
958 */
959 function findMostRecent($fileArr, $extPath) {
960 $mtimeArray = array();
961 foreach ($fileArr as $fN) {
962 if ($fN != 'ext_emconf.php') {
963 $mtime = filemtime($extPath . $fN);
964 $mtimeArray[$fN] = $mtime;
965 }
966 }
967 return $mtimeArray;
968 }
969
970 /**
971 * Removes the absolute part of all files/folders in fileArr
972 *
973 * @param array File array
974 * @param string Prefix to remove
975 * @return array Modified file array (or error string)
976 */
977 function removePrefixPathFromList($fileArr, $extPath) {
978 foreach ($fileArr as $k => $absFileRef) {
979 if (t3lib_div::isFirstPartOfStr($absFileRef, $extPath)) {
980 $fileArr[$k] = substr($absFileRef, strlen($extPath));
981 } else {
982 return 'ERROR: One or more of the files was NOT prefixed with the prefix-path!';
983 }
984 }
985 return $fileArr;
986 }
987
988
989 /******************************
990 *
991 * Content: Other
992 *
993 ******************************/
994
995 /**
996 * Shows detailed information for a single installation of TYPO3
997 *
998 * @param string KEY pointing to installation
999 * @return string HTML content
1000 */
1001 function singleSite($exp) {
1002 $all = $this->globalSiteInfo[$exp];
1003
1004 // General information:
1005 $content = '
1006 <h2>' . htmlspecialchars($all['siteInfo']['sitename'] . ' (DB: ' . $all['siteInfo']['TYPO3_db']) . ')</h2>
1007 <hr />
1008
1009 <h3>Main details:</h3>
1010
1011 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>
1012 <br /><br />';
1013
1014 // Add all information in globalSiteInfo array:
1015 $content .= t3lib_div::view_array($all);
1016
1017 // Last-login:
1018 $content .= '
1019 <h3>Login-Log for last month:</h3>';
1020 $content .= $this->loginLog($all['siteInfo']['TYPO3_db']);
1021
1022 // Return content
1023 return $content;
1024 }
1025
1026 /**
1027 * Get last-login log for database.
1028 *
1029 * @param string Database
1030 * @return string HTML
1031 */
1032 function loginLog($DB) {
1033 // Non-admin users
1034 //1=login, 2=logout, 3=failed login (+ errorcode 3), 4=failure_warning_email sent
1035 $query = $GLOBALS['TYPO3_DB']->SELECTquery(
1036 'sys_log.*, be_users.username AS username, be_users.admin AS admin',
1037 'sys_log,be_users',
1038 'be_users.uid=sys_log.userid AND sys_log.type=255 AND sys_log.tstamp > ' . ($GLOBALS['EXEC_TIME'] - (60 * 60 * 24 * 30)),
1039 '',
1040 'sys_log.tstamp DESC'
1041 );
1042 $res = mysql($DB, $query);
1043
1044 $dayRef = '';
1045 $lines = array();
1046
1047 while ($row = mysql_fetch_assoc($res)) {
1048 $day = date('d-m-Y', $row['tstamp']);
1049 if ($dayRef != $day) {
1050 $lines[] = '
1051 <h4>' . $day . ':</h4>';
1052 $dayRef = $day;
1053 }
1054 $theLine = date('H:i', $row['tstamp']) . ': ' . str_pad(substr($row['username'], 0, 10), 10) . ' ' . $this->log_getDetails($row['details'], unserialize($row['log_data']));
1055 $theLine = htmlspecialchars($theLine);
1056 $lines[] = $row['admin'] ? '<span class="redclass">' . $theLine . '</span>' : $theLine;
1057 }
1058 return '<pre>' . implode(LF, $lines) . '</pre>';
1059 }
1060
1061 /**
1062 * Compile log details into template string
1063 *
1064 * @param string Log message (template)
1065 * @param array Data array to insert in log message
1066 * @return string Log details.
1067 */
1068 function log_getDetails($text, $data) {
1069 // $code is used later on to substitute errormessages with language-corrected values...
1070 if (is_array($data)) {
1071 return sprintf($text, $data[0], $data[1], $data[2], $data[3], $data[4]);
1072 } else {
1073 return $text;
1074 }
1075 }
1076
1077
1078 /**
1079 * Removing temp_CACHED files for installation
1080 *
1081 * @param string KEY pointing to installation
1082 * @return string HTML content
1083 */
1084 function rmCachedFiles($exp) {
1085 $all = $this->globalSiteInfo[$exp];
1086 $content = '
1087 <h2>' . htmlspecialchars($all['siteInfo']['sitename'] . ' (DB: ' . $all['siteInfo']['TYPO3_db']) . ')</h2>
1088 <hr />
1089 <h3>typo3conf/temp_CACHED_* files:</h3>';
1090
1091 $path = $all['siteInfo']['SA_PATH'] . '/typo3conf/';
1092 if (@is_dir($path)) {
1093 $filesInDir = t3lib_div::getFilesInDir($path, 'php', 1);
1094
1095 foreach ($filesInDir as $kk => $vv) {
1096 if (t3lib_div::isFirstPartOfStr(basename($vv), 'temp_CACHED_')) {
1097 if (strstr(basename($vv), 'ext_localconf.php') || strstr(basename($vv), 'ext_tables.php')) {
1098 $content .= 'REMOVED: ' . $vv . '<br />';
1099 unlink($vv);
1100 if (file_exists($vv)) {
1101 $content .= $this->error('ERROR: File still exists, so could not be removed anyways!') . '<br />';
1102 }
1103 }
1104 }
1105 }
1106 } else {
1107 $content .= $this->error('ERROR: ' . $path . ' was not a directory!');
1108 }
1109
1110 return $content;
1111 }
1112
1113 /**
1114 * Menu for either update/information, showing links for each installation found
1115 *
1116 * @param string Action key "update" or "info"
1117 * @return string HTML output.
1118 */
1119 function menuContent($exp) {
1120 if ($exp) {
1121
1122 // Initialize:
1123 $lines = array();
1124 $head = '';
1125
1126 foreach ($this->globalSiteInfo as $k => $all) {
1127
1128 // Setting section header, if needed.
1129 if ($head != $all['siteInfo']['MAIN_DIR']) {
1130 $lines[] = '
1131 <h4 style="white-space: nowrap;">' . htmlspecialchars(t3lib_div::fixed_lgd_cs($all['siteInfo']['MAIN_DIR'], -18)) . '</h4>';
1132 $head = $all['siteInfo']['MAIN_DIR']; // Set new head...
1133 }
1134
1135 // Display mode:
1136 switch ($exp) {
1137 case 'update':
1138
1139 // Label:
1140 $label = $all['siteInfo']['sitename'] ? $all['siteInfo']['sitename'] : '(DB: ' . $all['siteInfo']['TYPO3_db'] . ')';
1141 $lines[] = '
1142 <hr />
1143 <strong>' . htmlspecialchars($label) . '</strong> (' . htmlspecialchars(substr($all['siteInfo']['SA_PATH'], strlen($all['siteInfo']['MAIN_DIR']) + 1)) . ')<br />';
1144
1145 // To avoid "visited links" display on next hit:
1146 $tempVal = '&_someUniqueValue=' . $GLOBALS['EXEC_TIME'];
1147
1148 // Add links for update:
1149 $url = $this->scriptName . '?type=page&show=rmTempCached&exp=' . $k . $tempVal;
1150 $lines[] = '<span style="white-space: nowrap;"><a href="' . htmlspecialchars($url) . '" target="TSApage">Remove temp_CACHED files</a></span>';
1151
1152 $url = $all['siteInfo']['INSTALL_URL'] . 'index.php?TYPO3_INSTALL[type]=database&TYPO3_INSTALL[database_type]=import|CURRENT_STATIC' . "&presetWholeTable=1" . $tempVal . '#bottom';
1153 $lines[] = '<span style="white-space: nowrap;"><a href="' . htmlspecialchars($url) . '" target="TSApage">CURRENT_STATIC</a></span>';
1154
1155 $url = $all['siteInfo']['INSTALL_URL'] . 'index.php?TYPO3_INSTALL[type]=database&TYPO3_INSTALL[database_type]=cmpFile|CURRENT_TABLES' . $tempVal . '#bottom';
1156 $lines[] = '<span style="white-space: nowrap;"><a href="' . htmlspecialchars($url) . '" target="TSApage">CURRENT_TABLES</a></span>';
1157
1158 // Cache
1159 $url = $all['siteInfo']['INSTALL_URL'] . 'index.php?TYPO3_INSTALL[type]=database&TYPO3_INSTALL[database_type]=cache|' .
1160 "&PRESET[database_clearcache][cache_pages]=1" .
1161 '&PRESET[database_clearcache][cache_pagesection]=1' .
1162 "&PRESET[database_clearcache][cache_hash]=1" .
1163 $tempVal .
1164 '#bottom';
1165 $lines[] = '<span style="white-space: nowrap;"><a href="' . htmlspecialchars($url) . '" target="TSApage">Clear cache</a></span>';
1166
1167 // Admin link
1168 $url = $all['siteInfo']['ADMIN_URL'] . 'index.php';
1169 $lines[] = '<span style="white-space: nowrap;"><a href="' . htmlspecialchars($url) . '" target="' . $this->targetWindowAdmin . '">Admin -></a></span>';
1170 break;
1171 case 'info':
1172 // item
1173 $label = $all['siteInfo']['sitename'] ? $all['siteInfo']['sitename'] : '(DB: ' . $all['siteInfo']['TYPO3_db'] . ')';
1174
1175 $url = $this->scriptName . '?type=page&show=info&exp=' . $k;
1176 $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>';
1177 break;
1178 }
1179 }
1180
1181 // Return result.
1182 return implode('<br />', $lines) . '<br />';
1183 }
1184 }
1185
1186 /**
1187 * Create list of admin logins.
1188 *
1189 * @return string HTML table
1190 */
1191 function makeAdminLogin() {
1192
1193 // Initialize:
1194 $lines = array();
1195 $head = '';
1196
1197 // Traverse installations found:
1198 foreach ($this->globalSiteInfo as $k => $all) {
1199
1200 // Setting section header, if needed.
1201 if ($head != $all['siteInfo']['MAIN_DIR']) {
1202 $lines[] = '
1203 <tr>
1204 <td colspan="2"><br />
1205 <h4>' . htmlspecialchars($all['siteInfo']['MAIN_DIR']) . '</h4>
1206 </td>
1207 </tr>';
1208 $head = $all['siteInfo']['MAIN_DIR'];
1209 }
1210
1211 // item
1212 $label = $all['siteInfo']['sitename'] ? $all['siteInfo']['sitename'] : '(DB: ' . $all['siteInfo']['TYPO3_db'] . ')';
1213 $unique = md5(microtime());
1214
1215 $opts = array();
1216 $defUName = '';
1217
1218 if (is_array($all['siteInfo']['ADMINS'])) {
1219
1220 foreach ($all['siteInfo']['ADMINS'] as $vArr) {
1221 $chalVal = md5($vArr['username'] . ':' . $vArr['password'] . ':' . $unique);
1222 $opts[] = '<option value="' . $chalVal . '">' . htmlspecialchars($vArr['username'] . ($vArr['disable'] ? ' [DISABLED]' : '')) . '</option>';
1223 if (!$defUName) {
1224 $defUName = $vArr['username'];
1225 }
1226 }
1227 }
1228 if (count($opts) > 1) {
1229 $userident = '
1230 <select name="userident" onchange="document[\'' . $k . '\'].username.value=this.options[this.selectedIndex].text;">
1231 ' . implode('
1232 ', $opts) . '
1233 </select>
1234 ';
1235 } else {
1236 $userident = '
1237 (' . $defUName . ')<br />
1238 <input type="hidden" name="userident" value="' . $chalVal . '" />';
1239 }
1240
1241 $form = '
1242 <form name="' . $k . '" action="' . $all['siteInfo']['ADMIN_URL'] . 'index.php" target="EXTERnalWindow" method="post">
1243 <input type="submit" name="submit" value="Login" />
1244 <input type="hidden" name="username" value="' . $defUName . '" />
1245 <input type="hidden" name="challenge" value="' . $unique . '" />
1246 <input type="hidden" name="redirect_url" value="" />
1247 <input type="hidden" name="login_status" value="login" />
1248 ' . trim($userident) . '
1249 </form>';
1250
1251 $lines[] = '
1252 <tr>
1253 <td><strong>' . htmlspecialchars($label) . '</strong></td>
1254 <td nowrap="nowrap">' . trim($form) . '</td>
1255 </tr>';
1256 }
1257
1258 // Return login table:
1259 return '<table border="1" cellpadding="5" cellspacing="1">' . implode('', $lines) . '</table>';
1260 }
1261
1262 /**
1263 * For for changing admin passwords
1264 *
1265 * @return string Form content.
1266 */
1267 function changeAdminPasswordsForm() {
1268 $content = '';
1269
1270 foreach ($this->changeAdminPasswords as $k => $p) {
1271 $content .= '
1272 <h3>' . $k . '</h3>';
1273
1274 foreach ($p as $kk => $pp) {
1275 $content .= '<span style="white-space: nowrap;">';
1276 $content .= '<input type="checkbox" name="SETFIELDS[]" value="' . $pp . '" /> ' . $pp . ' - ';
1277 $content .= htmlspecialchars(implode(' - ', $this->collectAdminPasswords[$k][$kk]));
1278 $content .= '</span><br />';
1279 }
1280 }
1281
1282 $content .= 'New password: <input type="text" name="NEWPASS" /><br />';
1283 $content .= 'New password (md5): <input type="text" name="NEWPASS_md5" /><br />
1284 (This overrules any plain password above!)
1285 <br />';
1286 $content = '
1287 <form action="' . htmlspecialchars($this->scriptName . '?type=page&show=admin') . '" method="post">
1288 ' . $content . '
1289 <input type="submit" name="Set" />
1290 </form>
1291 ';
1292
1293 return $content;
1294 }
1295
1296 /**
1297 * Setting new passwords
1298 *
1299 * @return string Status
1300 * @see changeAdminPasswordsForm()
1301 */
1302 function setNewPasswords() {
1303 $whichFields = t3lib_div::_POST('SETFIELDS');
1304 $pass = trim(t3lib_div::_POST('NEWPASS'));
1305 $passMD5 = t3lib_div::_POST('NEWPASS_md5');
1306
1307 $updatedFlag = 0;
1308 if (($pass || $passMD5) && is_array($whichFields)) {
1309 $pass = $passMD5 ? $passMD5 : md5($pass);
1310
1311 foreach ($whichFields as $values) {
1312 $parts = explode(':', $values);
1313 if (count($parts) > 2) {
1314 $key = $this->mapDBtoKey[$parts[0]];
1315 if ($key && isset($this->globalSiteInfo[$key]['siteInfo'])) {
1316 $error = $this->connectToDatabase($this->globalSiteInfo[$key]['siteInfo']);
1317 if (!$error) {
1318 $DB = $this->globalSiteInfo[$key]['siteInfo']['TYPO3_db'];
1319 $content .= '<h3>Updating ' . $DB . ':</h3>';
1320
1321 $query = $GLOBALS['TYPO3_DB']->UPDATEquery(
1322 'be_users',
1323 'uid=' . intval($parts[1]) . ' AND username="' . addslashes($parts[2]) . '" AND admin!=0',
1324 array('password' => $pass)
1325 ); // username/admin are added to security. But they are certainly redundant!!
1326 mysql($DB, $query);
1327
1328 $content .= 'Affected rows: ' . mysql_affected_rows() . '<br /><hr />';
1329 $updatedFlag = '1';
1330 }
1331 }
1332 }
1333 }
1334 }
1335
1336 $this->initProcess();
1337 return $content;
1338 }
1339 }
1340
1341 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_superadmin.php']) {
1342 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_superadmin.php']);
1343 }
1344
1345 ?>