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