Fixed bug #14050: CleanUp - CGL format of t3lib files - t3lib_positionmap
[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
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 Skårhøj <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 $dirArr=array();
461 foreach ($in_dirs as $k => $v) {
462 if (substr($v,0,9)!='typo3_src') {
463 $this->currentUrl = $baseUrl.'/'.$v;
464 $content.= $this->headerSiteDir($v);
465 $content.= $this->processSiteDir($dir.'/'.$v,$dir);
466 }
467 }
468 } else {
469 $content.=$this->error('"'.$dir.'" was not a directory!');
470 }
471 }
472
473 return $content;
474 }
475
476 /**
477 * Creating information array for a specific TYPO3 installation
478 * Information about site is stored in ->globalSiteInfo array
479 *
480 * @param string Absolute path to installation (PATH_site)
481 * @param string Directory of main directory (level under PATH_site)
482 * @return string HTML content with information about the site.
483 * @access private
484 * @see initProcess()
485 */
486 function processSiteDir($path,$dir) {
487 if (@is_dir($path)) {
488 $localconf = $path.'/typo3conf/localconf.php';
489 if (@is_file($localconf)) {
490 $key = md5($localconf);
491 $this->includeLocalconf($localconf);
492
493 $this->mapDBtoKey[$this->globalSiteInfo[$key]['siteInfo']['TYPO3_db']] = $key;
494 $this->globalSiteInfo[$key]['siteInfo']['MAIN_DIR'] = $dir;
495 $this->globalSiteInfo[$key]['siteInfo']['SA_PATH'] = $path;
496 $this->globalSiteInfo[$key]['siteInfo']['URL'] = $this->currentUrl.'/';
497 $this->globalSiteInfo[$key]['siteInfo']['ADMIN_URL'] = $this->currentUrl.'/'.TYPO3_mainDir;
498 $this->globalSiteInfo[$key]['siteInfo']['INSTALL_URL'] = $this->currentUrl.'/'.TYPO3_mainDir.'install/';
499
500 // Connect to database:
501 $conMsg = $this->connectToDatabase($this->globalSiteInfo[$key]['siteInfo']);
502 if (!$conMsg) {
503 $this->getDBInfo($key);
504 $out.='';
505 } else {
506 $out = $conMsg;
507 }
508
509 // Show details:
510 if ($this->full) {
511 $out.=t3lib_div::view_array($this->globalSiteInfo[$key]);
512 } else {
513 $out.=t3lib_div::view_array($this->globalSiteInfo[$key]['siteInfo']);
514 }
515 } else $out = $this->error($localconf.' is not a file!');
516 } else $out = $this->error($path.' is not a directory!');
517 return $out;
518 }
519
520 /**
521 * Includes "localconf" of a TYPO3 installation an loads $this->globalSiteInfo with this information.
522 *
523 * @param string Absolute path to localconf.php file to include.
524 * @return array Array with information about the site.
525 * @access private
526 * @see processSiteDir()
527 */
528 function includeLocalconf($localconf) {
529 $TYPO3_CONF_VARS = array();
530 $typo_db = '';
531 $typo_db_username = '';
532 $typo_db_password = '';
533 $typo_db_host = '';
534
535 include($localconf);
536
537 $siteInfo=array();
538 $siteInfo['sitename'] = $TYPO3_CONF_VARS['SYS']['sitename'];
539 $siteInfo['TYPO3_db'] = $typo_db;
540 $siteInfo['TYPO3_db_username'] = $typo_db_username;
541 $siteInfo['TYPO3_db_password'] = $typo_db_password;
542 $siteInfo['TYPO3_db_host'] = $typo_db_host;
543 $siteInfo['installToolPassword'] = $TYPO3_CONF_VARS['BE']['installToolPassword'];
544 $siteInfo['warningEmailAddress'] = $TYPO3_CONF_VARS['BE']['warning_email_addr'];
545 $siteInfo['warningMode'] = $TYPO3_CONF_VARS['BE']['warning_mode'];
546
547 $this->globalSiteInfo[md5($localconf)] = array('siteInfo'=>$siteInfo,'TYPO3_CONF_VARS'=>$TYPO3_CONF_VARS);
548 return $siteInfo;
549 }
550
551 /**
552 * Connects to a MySQL database with the TYPO3 db host/username/password and database as found in the localconf.php file!
553 * 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
554 *
555 * @param array $siteInfo array, containing username/password/host/database values.
556 * @return string Array message if any
557 */
558 function connectToDatabase($siteInfo) {
559 if (@mysql_pconnect($siteInfo['TYPO3_db_host'], $siteInfo['TYPO3_db_username'], $siteInfo['TYPO3_db_password'])) {
560 if (!$siteInfo['TYPO3_db']) {
561 return $this->error('No database selected');
562 } elseif (!mysql_select_db($siteInfo['TYPO3_db'])) {
563 return $this->error('Cannot connect to the current database, "'.$siteInfo['TYPO3_db'].'"');
564 }
565 } else {
566 return $this->error('The current username, password or host was not accepted when the connection to the database was attempted to be established!');
567 }
568 }
569
570
571 /**
572 * Get database information, assuming standard tables like "be_users"
573 * Adding the information to ->globalSiteInfo
574 *
575 * @param string Key for site in ->globalSiteInfo
576 * @return void
577 * @access private
578 * @see processSiteDir()
579 */
580 function getDBInfo($key) {
581 $DB = $this->globalSiteInfo[$key]['siteInfo']['TYPO3_db'];
582
583 // Non-admin users
584 $query = $GLOBALS['TYPO3_DB']->SELECTquery('count(*)', 'be_users', 'admin=0 AND deleted=0');
585 $res = mysql($DB, $query);
586 $row = mysql_fetch_row($res);
587 $this->globalSiteInfo[$key]['siteInfo']['BE_USERS_NONADMIN'] = $row[0];
588
589 // Admin users
590 $query = $GLOBALS['TYPO3_DB']->SELECTquery('count(*)', 'be_users', 'admin!=0 AND deleted=0');
591 $res = mysql($DB, $query);
592 $row = mysql_fetch_row($res);
593 $this->globalSiteInfo[$key]['siteInfo']['BE_USERS_ADMIN'] = $row[0];
594
595 // Select Admin users
596 $query = $GLOBALS['TYPO3_DB']->SELECTquery('uid,username,password,email,realName,disable', 'be_users', 'admin!=0 AND deleted=0');
597 $res = mysql($DB, $query);
598 while($row = mysql_fetch_assoc($res)) {
599 $this->globalSiteInfo[$key]['siteInfo']['ADMINS'][] = $row;
600 }
601 }
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619 /******************************
620 *
621 * Content: Installation Overview
622 *
623 ******************************/
624
625 /**
626 * Creates big table with information about all installations in ->globalSiteInfo
627 *
628 * @return string HTML table
629 */
630 function makeTable() {
631
632 // Header row
633 $info = array();
634 $info[] = 'Site:';
635 $info[] = 'Path:';
636 $info[] = 'Database:';
637 $info[] = 'Username';
638 $info[] = 'Password';
639 $info[] = 'Host';
640 $info[] = 'Links (new win)';
641 $info[] = '#Users NA/A';
642 $info[] = 'Admin be_users Info';
643 $info[] = 'Install Tool Password';
644 $info[] = 'Warning email address';
645 $info[] = 'W.mode';
646 $mainArrRows[] = '
647 <tr bgcolor="#eeeeee">
648 <td nowrap="nowrap" valign="top">'.implode('</td>
649 <td nowrap="nowrap" valign="top">',$info).'</td>
650 </tr>';
651
652 // Traverse globalSiteInfo for each site:
653 foreach($this->globalSiteInfo as $k => $all) {
654 $info = array();
655
656 // Sitename and Database details:
657 $info[] = htmlspecialchars($all['siteInfo']['sitename']);
658 $info[] = '<span style="color:#666666;">'.htmlspecialchars($all['siteInfo']['MAIN_DIR']).'</span>'.htmlspecialchars(substr($all['siteInfo']['SA_PATH'],strlen($all['siteInfo']['MAIN_DIR'])));
659 $info[] = htmlspecialchars($all['siteInfo']['TYPO3_db']);
660 $info[] = htmlspecialchars($all['siteInfo']['TYPO3_db_username']);
661 $info[] = htmlspecialchars($all['siteInfo']['TYPO3_db_password']);
662 $info[] = htmlspecialchars($all['siteInfo']['TYPO3_db_host']);
663
664 // URL
665 $info[] = '<a href="'.htmlspecialchars($all['siteInfo']['URL']).'" target="'.$this->targetWindow.'">Site</a>'.
666 ' / <a href="'.htmlspecialchars($all['siteInfo']['ADMIN_URL']).'" target="'.$this->targetWindowAdmin.'">Admin</a>'.
667 ' / <a href="'.htmlspecialchars($all['siteInfo']['INSTALL_URL']).'" target="'.$this->targetWindowInstall.'">Install</a>';
668 $info[] = htmlspecialchars($all['siteInfo']['BE_USERS_NONADMIN'].'/'.$all['siteInfo']['BE_USERS_ADMIN']);
669
670 // Admin
671 if (is_array($all['siteInfo']['ADMINS'])) {
672 $lines = array();
673 foreach($all['siteInfo']['ADMINS'] as $vArr) {
674 $lines[] = htmlspecialchars($vArr['password'].' - '.$vArr['username'].' ('.$vArr['realName'].', '.$vArr['email'].')');
675 $this->collectAdminPasswords[$vArr['password']][] = array(
676 'path' => $all['siteInfo']['SA_PATH'],
677 'site' => $all['siteInfo']['sitename'],
678 'database' => $all['siteInfo']['TYPO3_db'],
679 'user' => $vArr['username'],
680 'name_email' => $vArr['realName'].', '.$vArr['email']
681 );
682 $this->changeAdminPasswords[$vArr['password']][] = $all['siteInfo']['TYPO3_db'].':'.$vArr['uid'].':'.$vArr['username'];
683 }
684 $info[] = implode('<br />',$lines);
685 } else {
686 $info[] = $this->error('No DB connection!');
687 }
688 // Install
689 $info[] = htmlspecialchars($all['siteInfo']['installToolPassword']);
690 $this->collectInstallPasswords[$all['siteInfo']['installToolPassword']][] = $all['siteInfo']['SA_PATH'].' - '.$all['siteInfo']['sitename'].' - ('.$all['siteInfo']['TYPO3_db'].')';
691
692 $info[] = htmlspecialchars($all['siteInfo']['warningEmailAddress']);
693 $info[] = htmlspecialchars($all['siteInfo']['warningMode']);
694
695 // compile
696 $mainArrRows[] = '
697 <tr>
698 <td nowrap="nowrap" valign="top">'.implode('</td>
699 <td nowrap="nowrap" valign="top">',$info).'</td>
700 </tr>';
701 }
702
703 // Compile / return table finally:
704 $table = '<table border="1" cellpadding="1" cellspacing="1">'.implode('',$mainArrRows).'</table>';
705 return $table;
706 }
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721 /******************************
722 *
723 * Content: Local extensions
724 *
725 ******************************/
726
727 /**
728 * Based on the globalSiteInfo array, this prints information about local extensions for each site.
729 * In particular version number and most recent mod-time is interesting!
730 *
731 * @return string HTML
732 */
733 function localExtensions() {
734 $this->extensionInfoArray=array();
735
736 // Traverse $this->globalSiteInfo for local extensions:
737 foreach($this->globalSiteInfo as $k => $all) {
738 if ($all['siteInfo']['SA_PATH']) {
739 $extDir = $all['siteInfo']['SA_PATH'].'/typo3conf/ext/';
740 if (@is_dir($extDir)) {
741 $this->extensionInfoArray['site'][$k] = array();
742
743 // Get extensions in local directory
744 $extensions=t3lib_div::get_dirs($extDir);
745 if (is_array($extensions)) {
746 foreach($extensions as $extKey) {
747 // Getting and setting information for extension:
748 $eInfo = $this->getExtensionInfo($extDir,$extKey,$k);
749 $this->extensionInfoArray['site'][$k][$extKey] = $eInfo;
750 $this->extensionInfoArray['ext'][$extKey][$k] = $eInfo;
751 }
752 }
753 }
754 }
755 }
756
757 // Display results:
758 $out='';
759 $headerRow = '
760 <tr bgcolor="#ccccee" style="font-weight:bold;">
761 <td>Extension key</td>
762 <td>Path</td>
763 <td>Title</td>
764 <td>Ver.</td>
765 <td>Files</td>
766 <td><span title="If M, then there is a manual.">M</span></td>
767 <td>Last mod. time</td>
768 <td>Hash off all file mod. times:</td>
769 <td>TYPO3 ver. req.</td>
770 <td>CGL compliance</td>
771 </tr>
772 ';
773
774 // PER EXTENSION:
775 if (is_array($this->extensionInfoArray['ext'])) {
776 $extensionKeysCollect=array();
777
778 ksort($this->extensionInfoArray['ext']);
779 reset($this->extensionInfoArray['ext']);
780 $rows=array(
781 'reg'=>array(),
782 'user'=>array()
783 );
784
785 foreach($this->extensionInfoArray['ext'] as $extKey => $instances) {
786 $mtimes = array();
787
788 // Find most recent mtime of the options:
789 foreach ($instances as $k => $eInfo) {
790 $mtimes[] = $eInfo['mtime'];
791 }
792 // Max mtime:
793 $maxMtime = max($mtimes);
794 $c = 0;
795
796 // So, traverse all sites with the extension present:
797 foreach($instances as $k => $eInfo) {
798 // Set background color if mtime matches
799 if ($maxMtime==$eInfo['mtime']) {
800 $this->extensionInfoArray['site'][$k][$extKey]['_highlight']=1;
801 $bgCol = $eInfo['dirtype']=='link' ? ' bgcolor="#ffcccc"' : ' bgcolor="#eeeeee"';
802 } else {
803 $bgCol = ' style="color: #999999; font-style: italic;"';
804 }
805
806 // Make row:
807 $type = substr($extKey,0,5)!='user_' ? 'reg' : 'user';
808 if ($type=='reg') $extensionKeysCollect[] = $extKey;
809
810 if (!is_array($eInfo)) {
811 // Standard listing:
812 $rows[$type][] = '
813 <tr>
814 '.(!$c?'<td rowspan="'.count($instances).'">'.htmlspecialchars($extKey).'</td>':'').'
815 <td nowrap="nowrap" bgcolor="#ccddcc">'.htmlspecialchars($this->globalSiteInfo[$k]['siteInfo']['SA_PATH']).'</td>
816 <td nowrap="nowrap" bgcolor="#ccddcc" colspan="8"><em>'.htmlspecialchars($eInfo).'</em></td>
817 </tr>
818 ';
819 } else {
820 // Standard listing:
821 $rows[$type][] = '
822 <tr>
823 '.(!$c?'<td rowspan="'.count($instances).'">'.htmlspecialchars($extKey).'</td>':'').'
824 <td nowrap="nowrap"'.$bgCol.'>'.htmlspecialchars($this->globalSiteInfo[$k]['siteInfo']['SA_PATH']).'</td>
825 <td nowrap="nowrap"'.$bgCol.'>'.htmlspecialchars($eInfo['title']).'</td>
826 <td nowrap="nowrap"'.$bgCol.'>'.htmlspecialchars($eInfo['version']).'</td>
827 <td nowrap="nowrap"'.$bgCol.'>'.htmlspecialchars($eInfo['numberfiles']).'</td>
828 <td nowrap="nowrap"'.$bgCol.'>'.htmlspecialchars($eInfo['manual']?'M':'-').'</td>
829 <td nowrap="nowrap"'.$bgCol.'>'.htmlspecialchars($eInfo['mtime']?date('d-m-y H:i:s',$eInfo['mtime']):'').'</td>
830 <td nowrap="nowrap"'.$bgCol.'>'.htmlspecialchars($eInfo['mtime_hash']).'</td>
831
832 <td'.$bgCol.'>'.htmlspecialchars($eInfo['TYPO3_version']).'</td>
833 <td'.$bgCol.'><img src="clear.gif" width="150" height="1" alt="" /><br />'.htmlspecialchars($eInfo['CGLcompliance'].($eInfo['CGLcompliance_note'] ? ' - '.$eInfo['CGLcompliance_note'] : '')).'</td>
834 </tr>
835 ';
836 }
837 $c++;
838 }
839 }
840
841 // Extensions with registered extension keys:
842 $out.='
843 <h3>Registered extensions:</h3>
844 <table border="1">'.$headerRow.implode('',$rows['reg']).'</table>';
845
846 // List of those extension keys in a form field:
847 $extensionKeysCollect = array_unique($extensionKeysCollect);
848 asort($extensionKeysCollect);
849 $out.='<form action=""><textarea cols="80" rows="10">'.implode(LF,$extensionKeysCollect).'</textarea></form>';
850
851 // USER extension (prefixed "user_")
852 $out.='<br />
853 <h3>User extensions:</h3>
854 <table border="1">'.$headerRow.implode('',$rows['user']).'</table>';
855 }
856
857 // PER SITE:
858 if (is_array($this->extensionInfoArray['site'])) {
859 $rows = array();
860 foreach($this->extensionInfoArray['site'] as $k => $extensions) {
861
862 // So, traverse all sites with the extension present:
863 $c = 0;
864 foreach($extensions as $extKey => $eInfo) {
865
866 // Set background color if mtime matches
867 if ($eInfo['_highlight']) {
868 $bgCol = $eInfo['dirtype']=='link' ? ' bgcolor="#ffcccc"' : ' bgcolor="#eeeeee"';
869 } else {
870 $bgCol = ' style="color: #999999; font-style: italic;"';
871 }
872
873 // Make row:
874 $rows[] = '
875 <tr>
876 '.(!$c?'<td rowspan="'.count($extensions).'">'.htmlspecialchars($this->globalSiteInfo[$k]['siteInfo']['SA_PATH']).'</td>':'').'
877 <td nowrap="nowrap"'.$bgCol.'>'.htmlspecialchars($extKey).'</td>
878 <td nowrap="nowrap"'.$bgCol.'>'.htmlspecialchars($eInfo['title']).'</td>
879 <td nowrap="nowrap"'.$bgCol.'>'.htmlspecialchars($eInfo['version']).'</td>
880 <td nowrap="nowrap"'.$bgCol.'>'.htmlspecialchars($eInfo['numberfiles']).'</td>
881 <td nowrap="nowrap"'.$bgCol.'>'.htmlspecialchars($eInfo['mtime']?date('d-m-y H:i:s',$eInfo['mtime']):'').'</td>
882 <td nowrap="nowrap"'.$bgCol.'>'.htmlspecialchars($eInfo['mtime_hash']).'</td>
883 </tr>
884 ';
885 $c++;
886 }
887 }
888 $out.='<br />
889 <h3>Sites:</h3>
890 <table border="1">'.implode('',$rows).'</table>';
891 }
892
893 // Return content
894 return $out;
895 }
896
897 /**
898 * Gets information for an extension, eg. version and most-recently-edited-script
899 *
900 * @param string Path to local extension folder
901 * @param string Extension key
902 * @param string Key to globalSiteInformation array
903 * @return array Information array (unless an error occured)
904 */
905 function getExtensionInfo($path,$extKey,$k) {
906 $file = $path.$extKey.'/ext_emconf.php';
907 if (@is_file($file)) {
908 $_EXTKEY = $extKey;
909 $EM_CONF = array();
910 include($file);
911
912 $eInfo = array();
913 // Info from emconf:
914 $eInfo['title'] = $EM_CONF[$extKey]['title'];
915 $eInfo['version'] = $EM_CONF[$extKey]['version'];
916 $eInfo['CGLcompliance'] = $EM_CONF[$extKey]['CGLcompliance'];
917 $eInfo['CGLcompliance_note'] = $EM_CONF[$extKey]['CGLcompliance_note'];
918 $eInfo['TYPO3_version'] = $EM_CONF[$extKey]['TYPO3_version'];
919 $filesHash = unserialize($EM_CONF[$extKey]['_md5_values_when_last_written']);
920
921 if (!is_array($filesHash) || count($filesHash)<500) {
922
923 // Get all files list (may take LOONG time):
924 $extPath = $path.$extKey.'/';
925 $fileArr = array();
926 $fileArr = $this->removePrefixPathFromList($this->getAllFilesAndFoldersInPath($fileArr,$extPath),$extPath);
927
928 if (!is_array($fileArr)) {
929 debug(array($fileArr,$extKey,$extPath,$this->getAllFilesAndFoldersInPath(array(),$extPath)),'ERROR');
930 }
931
932 // Number of files:
933 $eInfo['numberfiles'] = count($fileArr);
934 $eInfo['dirtype'] = filetype($path.$extKey);
935
936 // Most recent modification:
937 $eInfo['mtime_files'] = $this->findMostRecent($fileArr,$extPath);
938 if (count($eInfo['mtime_files'])) $eInfo['mtime'] = max($eInfo['mtime_files']);
939 $eInfo['mtime_hash'] = md5(implode(',',$eInfo['mtime_files']));
940 } else {
941 $eInfo['mtime_hash'] = 'No calculation done, too many files in extension: '.count($filesHash);
942 }
943
944 $eInfo['manual'] = @is_file($path.$extKey.'/doc/manual.sxw');
945
946 return $eInfo;
947 } else return 'ERROR: No emconf.php file: '.$file;
948 }
949
950 /**
951 * Recursively gather all files and folders of extension path.
952 *
953 * @param array Array of files to which new files are added
954 * @param string Path to look up files in
955 * @param string List of file extensions to include. Blank = all
956 * @param boolean If set, directories are included as well.
957 * @return array $fileArr with new entries added.
958 */
959 function getAllFilesAndFoldersInPath($fileArr,$extPath,$extList='',$regDirs=0) {
960 if ($regDirs) $fileArr[] = $extPath;
961 $fileArr = array_merge($fileArr,t3lib_div::getFilesInDir($extPath,$extList,1,1));
962
963 $dirs = t3lib_div::get_dirs($extPath);
964 if (is_array($dirs)) {
965 foreach($dirs as $subdirs) {
966 if ($subdirs && (strcmp($subdirs,'CVS') || !$this->noCVS)) {
967 $fileArr = $this->getAllFilesAndFoldersInPath($fileArr,$extPath.$subdirs.'/',$extList,$regDirs);
968 }
969 }
970 }
971 return $fileArr;
972 }
973
974 /**
975 * Creates an array with modification times of all files in $fileArr
976 *
977 * @param array Files in extension (rel path)
978 * @param string Abs path prefix for files.
979 * @return array Array with modification times of files (filenames are keys)
980 */
981 function findMostRecent($fileArr,$extPath) {
982 $mtimeArray = array();
983 foreach($fileArr as $fN) {
984 if ($fN!='ext_emconf.php') {
985 $mtime = filemtime($extPath.$fN);
986 $mtimeArray[$fN] = $mtime;
987 }
988 }
989 return $mtimeArray;
990 }
991
992 /**
993 * Removes the absolute part of all files/folders in fileArr
994 *
995 * @param array File array
996 * @param string Prefix to remove
997 * @return array Modified file array (or error string)
998 */
999 function removePrefixPathFromList($fileArr,$extPath) {
1000 foreach ($fileArr as $k => $absFileRef) {
1001 if(t3lib_div::isFirstPartOfStr($absFileRef,$extPath)) {
1002 $fileArr[$k]=substr($absFileRef,strlen($extPath));
1003 } else return 'ERROR: One or more of the files was NOT prefixed with the prefix-path!';
1004 }
1005 return $fileArr;
1006 }
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023 /******************************
1024 *
1025 * Content: Other
1026 *
1027 ******************************/
1028
1029 /**
1030 * Shows detailed information for a single installation of TYPO3
1031 *
1032 * @param string KEY pointing to installation
1033 * @return string HTML content
1034 */
1035 function singleSite($exp) {
1036 $all = $this->globalSiteInfo[$exp];
1037
1038 // General information:
1039 $content = '
1040 <h2>'.htmlspecialchars($all['siteInfo']['sitename'].' (DB: '.$all['siteInfo']['TYPO3_db']).')</h2>
1041 <hr />
1042
1043 <h3>Main details:</h3>
1044
1045 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>
1046 <br /><br />';
1047
1048 // Add all information in globalSiteInfo array:
1049 $content.= t3lib_div::view_array($all);
1050
1051 // Last-login:
1052 $content.= '
1053 <h3>Login-Log for last month:</h3>';
1054 $content.= $this->loginLog($all['siteInfo']['TYPO3_db']);
1055
1056 // Return content
1057 return $content;
1058 }
1059
1060 /**
1061 * Get last-login log for database.
1062 *
1063 * @param string Database
1064 * @return string HTML
1065 */
1066 function loginLog($DB) {
1067 // Non-admin users
1068 //1=login, 2=logout, 3=failed login (+ errorcode 3), 4=failure_warning_email sent
1069 $query = $GLOBALS['TYPO3_DB']->SELECTquery(
1070 'sys_log.*, be_users.username AS username, be_users.admin AS admin',
1071 'sys_log,be_users',
1072 'be_users.uid=sys_log.userid AND sys_log.type=255 AND sys_log.tstamp > ' . ($GLOBALS['EXEC_TIME'] - (60 * 60 * 24 * 30)),
1073 '',
1074 'sys_log.tstamp DESC'
1075 );
1076 $res = mysql($DB,$query);
1077
1078 $dayRef = '';
1079 $lines = array();
1080
1081 while($row = mysql_fetch_assoc($res)) {
1082 $day = date('d-m-Y',$row['tstamp']);
1083 if ($dayRef!=$day) {
1084 $lines[] = '
1085 <h4>'.$day.':</h4>';
1086 $dayRef=$day;
1087 }
1088 $theLine = date('H:i',$row['tstamp']).': '.str_pad(substr($row['username'],0,10),10).' '.$this->log_getDetails($row['details'],unserialize($row['log_data']));
1089 $theLine = htmlspecialchars($theLine);
1090 $lines[]= $row['admin'] ? '<span class="redclass">'.$theLine.'</span>' : $theLine;
1091
1092 // debug($row);
1093 }
1094 return '<pre>'.implode(LF,$lines).'</pre>';
1095 }
1096
1097 /**
1098 * Compile log details into template string
1099 *
1100 * @param string Log message (template)
1101 * @param array Data array to insert in log message
1102 * @return string Log details.
1103 */
1104 function log_getDetails($text,$data) {
1105 // $code is used later on to substitute errormessages with language-corrected values...
1106 if (is_array($data)) {
1107 return sprintf($text, $data[0],$data[1],$data[2],$data[3],$data[4]);
1108 } else return $text;
1109 }
1110
1111
1112 /**
1113 * Removing temp_CACHED files for installation
1114 *
1115 * @param string KEY pointing to installation
1116 * @return string HTML content
1117 */
1118 function rmCachedFiles($exp) {
1119 $all = $this->globalSiteInfo[$exp];
1120 $content = '
1121 <h2>'.htmlspecialchars($all['siteInfo']['sitename'].' (DB: '.$all['siteInfo']['TYPO3_db']).')</h2>
1122 <hr />
1123 <h3>typo3conf/temp_CACHED_* files:</h3>';
1124
1125 $path = $all['siteInfo']['SA_PATH'].'/typo3conf/';
1126 if (@is_dir($path)) {
1127 $filesInDir = t3lib_div::getFilesInDir($path,'php',1);
1128
1129 foreach($filesInDir as $kk => $vv) {
1130 if (t3lib_div::isFirstPartOfStr(basename($vv),'temp_CACHED_')) {
1131 if (strstr(basename($vv),'ext_localconf.php') || strstr(basename($vv),'ext_tables.php')) {
1132 $content.='REMOVED: '.$vv.'<br />';
1133 unlink($vv);
1134 if (file_exists($vv)) $content.= $this->error('ERROR: File still exists, so could not be removed anyways!').'<br />';
1135 }
1136 }
1137 }
1138 } else {
1139 $content.= $this->error('ERROR: '.$path.' was not a directory!');
1140 }
1141
1142 return $content;
1143 }
1144
1145 /**
1146 * Menu for either update/information, showing links for each installation found
1147 *
1148 * @param string Action key "update" or "info"
1149 * @return string HTML output.
1150 */
1151 function menuContent($exp) {
1152 if ($exp) {
1153
1154 // Initialize:
1155 $lines = array();
1156 $head = '';
1157
1158 foreach($this->globalSiteInfo as $k => $all) {
1159
1160 // Setting section header, if needed.
1161 if ($head!=$all['siteInfo']['MAIN_DIR']) {
1162 $lines[] = '
1163 <h4 style="white-space: nowrap;">'.htmlspecialchars(t3lib_div::fixed_lgd_cs($all['siteInfo']['MAIN_DIR'],-18)).'</h4>';
1164 $head = $all['siteInfo']['MAIN_DIR']; // Set new head...
1165 }
1166
1167 // Display mode:
1168 switch($exp) {
1169 case 'update':
1170
1171 // Label:
1172 $label = $all['siteInfo']['sitename'] ? $all['siteInfo']['sitename'] : '(DB: '.$all['siteInfo']['TYPO3_db'].')';
1173 $lines[] = '
1174 <hr />
1175 <strong>'.htmlspecialchars($label).'</strong> ('.htmlspecialchars(substr($all['siteInfo']['SA_PATH'],strlen($all['siteInfo']['MAIN_DIR'])+1)).')<br />';
1176
1177 // To avoid "visited links" display on next hit:
1178 $tempVal='&_someUniqueValue=' . $GLOBALS['EXEC_TIME'];
1179
1180 // Add links for update:
1181 $url = $this->scriptName.'?type=page&show=rmTempCached&exp='.$k.$tempVal;
1182 $lines[] = '<span style="white-space: nowrap;"><a href="'.htmlspecialchars($url).'" target="TSApage">Remove temp_CACHED files</a></span>';
1183
1184 $url = $all['siteInfo']['INSTALL_URL'].'index.php?TYPO3_INSTALL[type]=database&TYPO3_INSTALL[database_type]=import|CURRENT_STATIC'."&presetWholeTable=1".$tempVal.'#bottom';
1185 $lines[] = '<span style="white-space: nowrap;"><a href="'.htmlspecialchars($url).'" target="TSApage">CURRENT_STATIC</a></span>';
1186
1187 $url = $all['siteInfo']['INSTALL_URL'].'index.php?TYPO3_INSTALL[type]=database&TYPO3_INSTALL[database_type]=cmpFile|CURRENT_TABLES'.$tempVal.'#bottom';
1188 $lines[] = '<span style="white-space: nowrap;"><a href="'.htmlspecialchars($url).'" target="TSApage">CURRENT_TABLES</a></span>';
1189
1190 // Cache
1191 $url = $all['siteInfo']['INSTALL_URL'].'index.php?TYPO3_INSTALL[type]=database&TYPO3_INSTALL[database_type]=cache|'.
1192 "&PRESET[database_clearcache][cache_pages]=1".
1193 '&PRESET[database_clearcache][cache_pagesection]=1'.
1194 "&PRESET[database_clearcache][cache_hash]=1".
1195 $tempVal.
1196 '#bottom';
1197 $lines[] = '<span style="white-space: nowrap;"><a href="'.htmlspecialchars($url).'" target="TSApage">Clear cache</a></span>';
1198
1199 // Admin link
1200 $url = $all['siteInfo']['ADMIN_URL'].'index.php';
1201 $lines[] = '<span style="white-space: nowrap;"><a href="'.htmlspecialchars($url).'" target="'.$this->targetWindowAdmin.'">Admin -></a></span>';
1202 break;
1203 case 'info':
1204 // item
1205 $label = $all['siteInfo']['sitename'] ? $all['siteInfo']['sitename'] : '(DB: '.$all['siteInfo']['TYPO3_db'].')';
1206
1207 $url = $this->scriptName.'?type=page&show=info&exp='.$k;
1208 $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>';
1209 break;
1210 }
1211 }
1212
1213 // Return result.
1214 return implode('<br />',$lines).'<br />';
1215 }
1216 }
1217
1218 /**
1219 * Create list of admin logins.
1220 *
1221 * @return string HTML table
1222 */
1223 function makeAdminLogin() {
1224
1225 // Initialize:
1226 $lines = array();
1227 $head = '';
1228
1229 // Traverse installations found:
1230 foreach($this->globalSiteInfo as $k => $all) {
1231
1232 // Setting section header, if needed.
1233 if ($head!=$all['siteInfo']['MAIN_DIR']) {
1234 $lines[] = '
1235 <tr>
1236 <td colspan="2"><br />
1237 <h4>'.htmlspecialchars($all['siteInfo']['MAIN_DIR']).'</h4>
1238 </td>
1239 </tr>';
1240 $head = $all['siteInfo']['MAIN_DIR'];
1241 }
1242
1243 // item
1244 $label = $all['siteInfo']['sitename'] ? $all['siteInfo']['sitename'] : '(DB: '.$all['siteInfo']['TYPO3_db'].')';
1245 $unique = md5(microtime());
1246
1247 $opts = array();
1248 $defUName = '';
1249
1250 if (is_array($all['siteInfo']['ADMINS'])) {
1251
1252 foreach($all['siteInfo']['ADMINS'] as $vArr) {
1253 $chalVal = md5($vArr['username'].':'.$vArr['password'].':'.$unique);
1254 $opts[] = '<option value="'.$chalVal.'">'.htmlspecialchars($vArr['username'].($vArr['disable']?' [DISABLED]':'')).'</option>';
1255 if (!$defUName) { $defUName = $vArr['username']; }
1256 }
1257 }
1258 if (count($opts)>1) {
1259 $userident = '
1260 <select name="userident" onchange="document[\''.$k.'\'].username.value=this.options[this.selectedIndex].text;">
1261 '.implode('
1262 ',$opts).'
1263 </select>
1264 ';
1265 } else {
1266 $userident = '
1267 ('.$defUName.')<br />
1268 <input type="hidden" name="userident" value="'.$chalVal.'" />';
1269 }
1270
1271 $form='
1272 <form name="'.$k.'" action="'.$all['siteInfo']['ADMIN_URL'].'index.php" target="EXTERnalWindow" method="post">
1273 <input type="submit" name="submit" value="Login" />
1274 <input type="hidden" name="username" value="'.$defUName.'" />
1275 <input type="hidden" name="challenge" value="'.$unique.'" />
1276 <input type="hidden" name="redirect_url" value="" />
1277 <input type="hidden" name="login_status" value="login" />
1278 '.trim($userident).'
1279 </form>';
1280
1281 $lines[] = '
1282 <tr>
1283 <td><strong>'.htmlspecialchars($label).'</strong></td>
1284 <td nowrap="nowrap">'.trim($form).'</td>
1285 </tr>';
1286 }
1287
1288 // Return login table:
1289 return '<table border="1" cellpadding="5" cellspacing="1">'.implode('',$lines).'</table>';
1290 }
1291
1292 /**
1293 * For for changing admin passwords
1294 *
1295 * @return string Form content.
1296 */
1297 function changeAdminPasswordsForm() {
1298 $content='';
1299
1300 foreach($this->changeAdminPasswords as $k => $p) {
1301 $content.='
1302 <h3>'.$k.'</h3>';
1303
1304 foreach($p as $kk => $pp) {
1305 $content.= '<span style="white-space: nowrap;">';
1306 $content.= '<input type="checkbox" name="SETFIELDS[]" value="'.$pp.'" /> '.$pp.' - ';
1307 $content.= htmlspecialchars(implode(' - ',$this->collectAdminPasswords[$k][$kk]));
1308 $content.= '</span><br />';
1309 }
1310 }
1311
1312 $content.='New password: <input type="text" name="NEWPASS" /><br />';
1313 $content.='New password (md5): <input type="text" name="NEWPASS_md5" /><br />
1314 (This overrules any plain password above!)
1315 <br />';
1316 $content='
1317 <form action="'.htmlspecialchars($this->scriptName.'?type=page&show=admin').'" method="post">
1318 '.$content.'
1319 <input type="submit" name="Set" />
1320 </form>
1321 ';
1322
1323 return $content;
1324 }
1325
1326 /**
1327 * Setting new passwords
1328 *
1329 * @return string Status
1330 * @see changeAdminPasswordsForm()
1331 */
1332 function setNewPasswords() {
1333 $whichFields = t3lib_div::_POST('SETFIELDS');
1334 $pass = trim(t3lib_div::_POST('NEWPASS'));
1335 $passMD5 = t3lib_div::_POST('NEWPASS_md5');
1336
1337 $updatedFlag = 0;
1338 if (($pass || $passMD5) && is_array($whichFields)) {
1339 $pass = $passMD5 ? $passMD5 : md5($pass);
1340
1341 foreach($whichFields as $values) {
1342 $parts = explode(':',$values);
1343 if (count($parts)>2) {
1344 $key = $this->mapDBtoKey[$parts[0]];
1345 if ($key && isset($this->globalSiteInfo[$key]['siteInfo'])) {
1346 $error = $this->connectToDatabase($this->globalSiteInfo[$key]['siteInfo']);
1347 if (!$error) {
1348 $DB = $this->globalSiteInfo[$key]['siteInfo']['TYPO3_db'];
1349 $content.='<h3>Updating '.$DB.':</h3>';
1350
1351 $query = $GLOBALS['TYPO3_DB']->UPDATEquery(
1352 'be_users',
1353 'uid='.intval($parts[1]).' AND username="'.addslashes($parts[2]).'" AND admin!=0',
1354 array('password' => $pass)
1355 ); // username/admin are added to security. But they are certainly redundant!!
1356 mysql($DB,$query);
1357
1358 $content.= 'Affected rows: '.mysql_affected_rows().'<br /><hr />';
1359 $updatedFlag = '1';
1360 }
1361 }
1362 }
1363 }
1364 }
1365
1366 $this->initProcess();
1367 return $content;
1368 }
1369 }
1370
1371 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_superadmin.php']) {
1372 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_superadmin.php']);
1373 }
1374
1375 ?>