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