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