[BUGFIX] Avoid logout when changing the encryption key
[Packages/TYPO3.CMS.git] / typo3 / sysext / install / mod / class.tx_install.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 1999-2011 Kasper Skårhøj (kasperYYYY@typo3.com)
6 * All rights reserved
7 *
8 * This script is part of the TYPO3 project. The TYPO3 project is
9 * free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * The GNU General Public License can be found at
15 * http://www.gnu.org/copyleft/gpl.html.
16 * A copy is found in the textfile GPL.txt and important notices to the license
17 * from the author is found in LICENSE.txt distributed with these scripts.
18 *
19 *
20 * This script is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * This copyright notice MUST APPEAR in all copies of the script!
26 ***************************************************************/
27 /**
28 * Contains the class for the Install Tool
29 *
30 * @author Kasper Skårhøj <kasperYYYY@typo3.com>
31 * @author Ingmar Schlecht <ingmar@typo3.org>
32 */
33
34 // include requirements definition:
35 require_once(t3lib_extMgm::extPath('install') . 'requirements.php');
36
37 // include session handling
38 require_once(t3lib_extMgm::extPath('install') . 'mod/class.tx_install_session.php');
39
40 // include update classes
41 require_once(t3lib_extMgm::extPath('install') . 'updates/class.tx_coreupdates_charsetdefaults.php');
42 require_once(t3lib_extMgm::extPath('install') . 'updates/class.tx_coreupdates_compatversion.php');
43 require_once(t3lib_extMgm::extPath('install') . 'updates/class.tx_coreupdates_cscsplit.php');
44 require_once(t3lib_extMgm::extPath('install') . 'updates/class.tx_coreupdates_notinmenu.php');
45 require_once(t3lib_extMgm::extPath('install') . 'updates/class.tx_coreupdates_mergeadvanced.php');
46 require_once(t3lib_extMgm::extPath('install') . 'updates/class.tx_coreupdates_installsysexts.php');
47 require_once(t3lib_extMgm::extPath('install') . 'updates/class.tx_coreupdates_imagescols.php');
48 require_once(t3lib_extMgm::extPath('install') . 'updates/class.tx_coreupdates_installnewsysexts.php');
49 require_once(t3lib_extMgm::extPath('install') . 'updates/class.tx_coreupdates_statictemplates.php');
50 require_once(t3lib_extMgm::extPath('install') . 'updates/class.tx_coreupdates_t3skin.php');
51 require_once(t3lib_extMgm::extPath('install') . 'updates/class.tx_coreupdates_compressionlevel.php');
52 require_once(t3lib_extMgm::extPath('install') . 'updates/class.tx_coreupdates_migrateworkspaces.php');
53 require_once(t3lib_extMgm::extPath('install') . 'updates/class.tx_coreupdates_flagsfromsprite.php');
54 require_once(t3lib_extMgm::extPath('install') . 'updates/class.tx_coreupdates_addflexformstoacl.php');
55 require_once(t3lib_extMgm::extPath('install') . 'updates/class.tx_coreupdates_imagelink.php');
56 require_once(t3lib_extMgm::extPath('install') . 'updates/class.tx_coreupdates_mediaflexform.php');
57 require_once(t3lib_extMgm::extPath('install') . 'updates/class.tx_coreupdates_localconfiguration.php');
58
59 /**
60 * Install Tool module
61 *
62 * @author Kasper Skårhøj <kasperYYYY@typo3.com>
63 * @author Ingmar Schlecht <ingmar@typo3.org>
64 * @package TYPO3
65 * @subpackage tx_install
66 */
67 class tx_install extends t3lib_install {
68 var $templateFilePath = 'typo3/sysext/install/Resources/Private/Templates/';
69 var $template;
70 var $javascript;
71 var $stylesheets;
72 var $markers = array();
73 var $messages = array();
74 var $errorMessages = array();
75 var $mailMessage = '';
76 var $action = ''; // The url that calls this script
77 var $scriptSelf = 'index.php'; // The url that calls this script
78 var $updateIdentity = 'TYPO3 Install Tool';
79 var $headerStyle ='';
80 var $setAllCheckBoxesByDefault=0;
81
82 var $allowFileEditOutsite_typo3conf_dir=0;
83
84 var $INSTALL =array(); // In constructor: is set to global GET/POST var TYPO3_INSTALL
85 var $checkIMlzw = 0; // If set, lzw capabilities of the available ImageMagick installs are check by actually writing a gif-file and comparing size
86 var $checkIM = 0; // If set, ImageMagick is checked.
87 var $dumpImCommands=1; // If set, the image Magick commands are always outputted in the image processing checker
88 var $mode = ''; // If set to "123" then only most vital information is displayed.
89 var $step = 0; // If set to 1,2,3 or GO it signifies various functions.
90 var $totalSteps = 4; // Can be changed by hook to define the total steps in 123 mode
91
92 // internal
93 var $passwordOK=0; // This is set, if the password check was ok. The function init() will exit if this is not set
94 var $silent=1; // If set, the check routines don't add to the message-array
95 var $sections=array(); // Used to gather the message information.
96 var $fatalError=0; // This is set if some error occured that will definitely prevent TYpo3 from running.
97 var $sendNoCacheHeaders=1;
98 var $config_array = array( // Flags are set in this array if the options are available and checked ok.
99 'gd'=>0,
100 'gd_gif'=>0,
101 'gd_png'=>0,
102 'gd_jpg'=>0,
103 'freetype' => 0,
104 'safemode' => 0,
105 'dir_typo3temp' => 0,
106 'dir_temp' => 0,
107 'im_versions' => array(),
108 'im' => 0,
109 'sql.safe_mode_user' => '',
110 'mysqlConnect' => 0,
111 'no_database' => 0
112 );
113 var $typo3temp_path='';
114 /**
115 * the session handling object
116 *
117 * @var tx_install_session
118 */
119 protected $session = NULL;
120
121 /**
122 * the form protection instance used for creating and verifying form tokens
123 *
124 * @var t3lib_formprotection_InstallToolFormProtection
125 */
126 protected $formProtection = NULL;
127
128 var $menuitems = array(
129 'config' => 'Basic Configuration',
130 'database' => 'Database Analyser',
131 'update' => 'Upgrade Wizard',
132 'images' => 'Image Processing',
133 'extConfig' => 'All Configuration',
134 'cleanup' => 'Clean up',
135 'phpinfo' => 'phpinfo()',
136 'typo3conf_edit' => 'Edit files in typo3conf/',
137 'about' => 'About',
138 'logout' => 'Logout from Install Tool',
139 );
140
141 // PHP modules which are required. Can be changed by hook in getMissingPhpModules()
142 protected $requiredPhpModules = array(
143 'fileinfo',
144 'filter',
145 'gd',
146 'json',
147 'mysql',
148 'pcre',
149 'session',
150 'SPL',
151 'standard',
152 'openssl',
153 'xml',
154 'zlib'
155 );
156
157
158
159
160
161 /**
162 * Constructor
163 *
164 * @return void
165 */
166 function __construct() {
167 parent::__construct();
168
169 if (!$GLOBALS['TYPO3_CONF_VARS']['BE']['installToolPassword']) {
170 $this->outputErrorAndExit(
171 'Install Tool deactivated.<br />
172 You must enable it by setting a password in typo3conf/LocalConfiguration.php. If you insert the value below at array position \'EXT\' \'installToolPassword\', the password will be \'joh316\':<br /><br />
173 \'bacb98acf97e0b6112b1d1b650b84971\'',
174 'Fatal error'
175 );
176 }
177
178 if ($this->sendNoCacheHeaders) {
179 header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
180 header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
181 header('Expires: 0');
182 header('Cache-Control: no-cache, must-revalidate');
183 header('Pragma: no-cache');
184 }
185
186 // ****************************
187 // Initializing incoming vars.
188 // ****************************
189 $this->INSTALL = t3lib_div::_GP('TYPO3_INSTALL');
190 $this->mode = t3lib_div::_GP('mode');
191 if ($this->mode !== '123') {
192 $this->mode = '';
193 }
194 if (t3lib_div::_GP('step') === 'go') {
195 $this->step = 'go';
196 } else {
197 $this->step = intval(t3lib_div::_GP('step'));
198 }
199
200 // Let DBAL decide whether to load itself
201 $dbalLoaderFile = $this->backPath . 'sysext/dbal/class.tx_dbal_autoloader.php';
202 if (@is_file($dbalLoaderFile)) {
203 include($dbalLoaderFile);
204 }
205
206 if ($this->mode === '123') {
207 // Check for mandatory PHP modules
208 $missingPhpModules = $this->getMissingPhpModules();
209 if (count($missingPhpModules) > 0) {
210 throw new RuntimeException('TYPO3 Installation Error: The following PHP module(s) is/are missing: <em>' .
211 implode(', ', $missingPhpModules) .
212 '</em><br /><br />You need to install and enable these modules first to be able to install TYPO3.',
213 1294587482
214 );
215 }
216 // Load saltedpasswords if possible
217 $saltedpasswordsLoaderFile = $this->backPath . 'sysext/saltedpasswords/classes/class.tx_saltedpasswords_autoloader.php';
218 if (@is_file($saltedpasswordsLoaderFile)) {
219 include($saltedpasswordsLoaderFile);
220 }
221 }
222 $this->redirect_url = t3lib_div::sanitizeLocalUrl(t3lib_div::_GP('redirect_url'));
223
224 $this->INSTALL['type'] = '';
225 if ($_GET['TYPO3_INSTALL']['type']) {
226 $allowedTypes = array(
227 'config', 'database', 'update', 'images', 'extConfig',
228 'cleanup', 'phpinfo', 'typo3conf_edit', 'about', 'logout'
229 );
230
231 if (in_array($_GET['TYPO3_INSTALL']['type'], $allowedTypes)) {
232 $this->INSTALL['type'] = $_GET['TYPO3_INSTALL']['type'];
233 }
234 }
235
236 if ($this->step == 4) {
237 $this->INSTALL['type'] = 'database';
238 }
239
240 // Hook to raise the counter for the total steps in the 1-2-3 installer
241 if (is_array ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install/mod/class.tx_install.php']['additionalSteps'])) {
242 foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install/mod/class.tx_install.php']['additionalSteps'] as $classData) {
243 $hookObject = t3lib_div::getUserObj($classData);
244 $this->totalSteps += (integer) $hookObject->executeAdditionalSteps($this);
245 }
246 }
247
248 if ($this->mode=='123') {
249 $tempItems = $this->menuitems;
250 $this->menuitems = array(
251 'config' => $tempItems['config'],
252 'database' => $tempItems['database']
253 );
254 if (!$this->INSTALL['type'] || !isset($this->menuitems[$this->INSTALL['type']])) {
255 $this->INSTALL['type'] = 'config';
256 }
257 } else {
258 if (!$this->INSTALL['type'] || !isset($this->menuitems[$this->INSTALL['type']])) {
259 $this->INSTALL['type'] = 'about';
260 }
261 }
262
263 $this->action = $this->scriptSelf .
264 '?TYPO3_INSTALL[type]=' . $this->INSTALL['type'] .
265 ($this->mode? '&mode=' . $this->mode : '') .
266 ($this->step? '&step=' . $this->step : '');
267 $this->typo3temp_path = PATH_site.'typo3temp/';
268 if (!is_dir($this->typo3temp_path) || !is_writeable($this->typo3temp_path)) {
269 $this->outputErrorAndExit('Install Tool needs to write to typo3temp/. Make sure this directory is writeable by your webserver: ' . htmlspecialchars($this->typo3temp_path), 'Fatal error');
270 }
271
272 try {
273 $this->session = t3lib_div::makeInstance('tx_install_session');
274 } catch (Exception $exception) {
275 $this->outputErrorAndExit($exception->getMessage());
276 }
277
278 // *******************
279 // Check authorization
280 // *******************
281 if (!$this->session->hasSession()) {
282 $this->session->startSession();
283 }
284
285 if ($this->session->isAuthorized() || $this->checkPassword()) {
286 $this->passwordOK=1;
287 $this->session->refreshSession();
288
289 $enableInstallToolFile = PATH_typo3conf . 'ENABLE_INSTALL_TOOL';
290 if (is_file ($enableInstallToolFile)) {
291 // Extend the age of the ENABLE_INSTALL_TOOL file by one hour
292 @touch($enableInstallToolFile);
293 }
294
295 if($this->redirect_url) {
296 t3lib_utility_Http::redirect($this->redirect_url);
297 }
298
299 $this->formProtection = t3lib_formProtection_Factory::get(
300 't3lib_formprotection_InstallToolFormProtection'
301 );
302 $this->formProtection->injectInstallTool($this);
303 } else {
304 $this->loginForm();
305 }
306 }
307
308 /**
309 * Returns TRUE if submitted password is ok.
310 *
311 * If password is ok, set session as "authorized".
312 *
313 * @return boolean TRUE if the submitted password was ok and session was
314 * authorized, FALSE otherwise
315 */
316 function checkPassword() {
317 $p = t3lib_div::_GP('password');
318
319 if ($p && md5($p) === $GLOBALS['TYPO3_CONF_VARS']['BE']['installToolPassword']) {
320 $this->session->setAuthorized();
321
322 // Sending warning email
323 $wEmail = $GLOBALS['TYPO3_CONF_VARS']['BE']['warning_email_addr'];
324 if ($wEmail) {
325 $subject = 'Install Tool Login at "' . $GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'] . '"';
326 $email_body = 'There has been an Install Tool login at TYPO3 site "' . $GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'] . '" (' . t3lib_div::getIndpEnv('HTTP_HOST') . ') from remote address "' . t3lib_div::getIndpEnv('REMOTE_ADDR') . '" (' . t3lib_div::getIndpEnv('REMOTE_HOST') . ')';
327 mail($wEmail,
328 $subject,
329 $email_body,
330 'From: TYPO3 Install Tool WARNING <>'
331 );
332 }
333 return TRUE;
334 } else {
335 // Bad password, send warning:
336 if ($p) {
337 $wEmail = $GLOBALS['TYPO3_CONF_VARS']['BE']['warning_email_addr'];
338 if ($wEmail) {
339 $subject="Install Tool Login ATTEMPT at '".$GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename']."'";
340 $email_body="There has been an Install Tool login attempt at TYPO3 site '".$GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename']."' (".t3lib_div::getIndpEnv('HTTP_HOST').").
341 The MD5 hash of the last 5 characters of the password tried was '".substr(md5($p), -5)."'
342 REMOTE_ADDR was '".t3lib_div::getIndpEnv('REMOTE_ADDR')."' (".t3lib_div::getIndpEnv('REMOTE_HOST').')';
343 mail($wEmail,
344 $subject,
345 $email_body,
346 'From: TYPO3 Install Tool WARNING <>'
347 );
348 }
349 }
350 return FALSE;
351 }
352 }
353
354 /**
355 * Create the HTML for the login form
356 *
357 * Reads and fills the template.
358 * Substitutes subparts when wrong password has been given
359 * or the session has expired
360 *
361 * @return void
362 */
363 function loginForm() {
364 $password = t3lib_div::_GP('password');
365 $redirect_url = $this->redirect_url ? $this->redirect_url : $this->action;
366 // Get the template file
367 $templateFile = @file_get_contents(
368 PATH_site . $this->templateFilePath . 'LoginForm.html'
369 );
370 // Get the template part from the file
371 $template = t3lib_parsehtml::getSubpart(
372 $templateFile, '###TEMPLATE###'
373 );
374 // Password has been given, but this form is rendered again.
375 // This means the given password was wrong
376 if (!empty($password)) {
377 // Get the subpart for the wrong password
378 $wrongPasswordSubPart = t3lib_parsehtml::getSubpart(
379 $template, '###WRONGPASSWORD###'
380 );
381 // Define the markers content
382 $wrongPasswordMarkers = array(
383 'passwordMessage' => 'The password you just tried has this md5-value:',
384 'password' => md5($password)
385 );
386 // Fill the markers in the subpart
387 $wrongPasswordSubPart = t3lib_parsehtml::substituteMarkerArray(
388 $wrongPasswordSubPart,
389 $wrongPasswordMarkers,
390 '###|###',
391 TRUE,
392 TRUE
393 );
394 }
395 // Session has expired
396 if (!$this->session->isAuthorized() && $this->session->isExpired()) {
397 // Get the subpart for the expired session message
398 $sessionExpiredSubPart = t3lib_parsehtml::getSubpart(
399 $template, '###SESSIONEXPIRED###'
400 );
401 // Define the markers content
402 $sessionExpiredMarkers = array(
403 'message' => 'Your Install Tool session has expired'
404 );
405 // Fill the markers in the subpart
406 $sessionExpiredSubPart = t3lib_parsehtml::substituteMarkerArray(
407 $sessionExpiredSubPart,
408 $sessionExpiredMarkers,
409 '###|###',
410 TRUE,
411 TRUE
412 );
413 }
414 // Substitute the subpart for the expired session in the template
415 $template = t3lib_parsehtml::substituteSubpart(
416 $template,
417 '###SESSIONEXPIRED###',
418 $sessionExpiredSubPart
419 );
420 // Substitute the subpart for the wrong password in the template
421 $template = t3lib_parsehtml::substituteSubpart(
422 $template,
423 '###WRONGPASSWORD###',
424 $wrongPasswordSubPart
425 );
426 // Define the markers content
427 $markers = array(
428 'siteName' => 'Site: ' .
429 htmlspecialchars($GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename']),
430 'headTitle' => 'Login to TYPO3 ' . TYPO3_version . ' Install Tool',
431 'redirectUrl' => htmlspecialchars($redirect_url),
432 'enterPassword' => 'Password',
433 'login' => 'Login',
434 'message' => '
435 <p class="typo3-message message-information">
436 The Install Tool Password is <em>not</em> the admin password
437 of TYPO3.
438 <br />
439 The default password is <em>joh316</em>. Be sure to change it!
440 <br /><br />
441 If you don\'t know the current password, you can set a new
442 one by setting the value of
443 $TYPO3_CONF_VARS[\'BE\'][\'installToolPassword\'] in
444 typo3conf/localconf.php to the md5() hash value of the
445 password you desire.
446 </p>
447 '
448 );
449 // Fill the markers in the template
450 $content = t3lib_parsehtml::substituteMarkerArray(
451 $template,
452 $markers,
453 '###|###',
454 TRUE,
455 TRUE
456 );
457
458 // Send content to the page wrapper function
459 $this->output($this->outputWrapper($content));
460 }
461
462 /**
463 * Calling function that checks system, IM, GD, dirs, database
464 * and lets you alter localconf.php
465 *
466 * This method is called from init.php to start the Install Tool.
467 *
468 * @return void
469 */
470 function init() {
471 // Must be called after inclusion of init.php (or from init.php)
472 if (!defined('PATH_typo3')) {
473 exit;
474 }
475 if (!$this->passwordOK) {
476 exit;
477 }
478
479 // Setting stuff...
480 $this->check_mail();
481 $this->setupGeneral();
482 $this->generateConfigForm();
483 if (count($this->messages)) {
484 t3lib_utility_Debug::debug($this->messages);
485 }
486
487 if ($this->step) {
488 $this->output($this->outputWrapper($this->stepOutput()));
489 } else {
490
491 // Menu...
492 switch($this->INSTALL['type']) {
493 case 'images':
494 $this->checkIM=1;
495 $this->checkTheConfig();
496 $this->silent=0;
497 $this->checkTheImageProcessing();
498 break;
499 case 'database':
500 $this->checkTheConfig();
501 $this->silent=0;
502 $this->checkTheDatabase();
503 break;
504 case 'update':
505 $this->checkDatabase();
506 $this->silent=0;
507 $this->updateWizard();
508 break;
509 case 'config':
510 $this->silent=0;
511 $this->checkIM=1;
512 $this->message(
513 'About configuration',
514 'How to configure TYPO3',
515 $this->generallyAboutConfiguration()
516 );
517 $isPhpCgi = (PHP_SAPI == 'fpm-fcgi' || PHP_SAPI == 'cgi' || PHP_SAPI == 'isapi' || PHP_SAPI == 'cgi-fcgi');
518 $this->message(
519 'System Information',
520 'Your system has the following configuration',
521 '
522 <dl id="systemInformation">
523 <dt>OS detected:</dt>
524 <dd>' . (TYPO3_OS == 'WIN' ? 'WIN' : 'UNIX') .'</dd>
525 <dt>CGI detected:</dt>
526 <dd>' . ($isPhpCgi ? 'YES' : 'NO') . '</dd>
527 <dt>PATH_thisScript:</dt>
528 <dd>' . PATH_thisScript . '</dd>
529 </dl>
530 '
531 );
532 $this->checkTheConfig();
533
534 $ext = 'Write configuration';
535 if ($this->fatalError) {
536 if (
537 $this->config_array['no_database'] ||
538 !$this->config_array['mysqlConnect']
539 ) {
540 $this->message($ext, 'Database not configured yet!', '
541 <p>
542 You need to specify database username,
543 password and host as one of the first things.
544 <br />
545 Next you\'ll have to select a database to
546 use with TYPO3.
547 </p>
548 <p>
549 Use the form below.
550 </p>
551 ', 2);
552 } else {
553 $this->message($ext, 'Fatal error encountered!', '
554 <p>
555 Somewhere above a fatal configuration
556 problem is encountered.
557 Please make sure that you\'ve fixed this
558 error before you submit the configuration.
559 TYPO3 will not run if this problem is not
560 fixed!
561 <br />
562 You should also check all warnings that may
563 appear.
564 </p>
565 ', 2);
566 }
567 } elseif ($this->mode=='123') {
568 if (!$this->fatalError) {
569 $this->message($ext, 'Basic configuration completed', '
570 <p>
571 You have no fatal errors in your basic
572 configuration.
573 You may have warnings though. Please pay
574 attention to them!
575 However you may continue and install the
576 database.
577 </p>
578 <p>
579 <strong>
580 <span style="color:#f00;">Step 2: </span>
581 </strong>
582 <a href="' . $this->scriptSelf .
583 '?TYPO3_INSTALL[type]=database' .
584 ($this->mode ? '&mode=' . rawurlencode($this->mode) : '') .
585 '">Click here to install the database.</a>
586 </p>
587 ', -1, 1);
588 }
589 }
590 $this->message($ext, 'Very Important: Changing Image Processing settings', '
591 <p>
592 When you change the settings for Image Processing
593 you <em>must</em> take into account
594 that <em>old images</em> may still be in typo3temp/
595 folder and prevent new files from being generated!
596 <br />
597 This is especially important to know, if you\'re
598 trying to set up image processing for the very first
599 time.
600 <br />
601 The problem is solved by <a href="' .
602 htmlspecialchars($this->setScriptName('cleanup')) .
603 '">clearing the typo3temp/ folder</a>.
604 Also make sure to clear the cache_pages table.
605 </p>
606 ', 1, 1);
607 $this->message($ext, 'Very Important: Changing Encryption Key setting', '
608 <p>
609 When you change the setting for the Encryption Key
610 you <em>must</em> take into account that a change to
611 this value might invalidate temporary information,
612 URLs etc.
613 <br />
614 The problem is solved by <a href="' .
615 htmlspecialchars($this->setScriptName('cleanup')) .
616 '">clearing the typo3temp/ folder</a>.
617 Also make sure to clear the cache_pages table.
618 </p>
619 ', 1, 1);
620 $this->message($ext, 'Update configuration', '
621 <p>
622 This form updates the configuration with the
623 suggested values you see below. The values are based
624 on the analysis above.
625 <br />
626 You can change the values in case you have
627 alternatives to the suggested defaults.
628 <br />
629 By this final step you will configure TYPO3 for
630 immediate use provided that you have no fatal errors
631 left above.
632 </p>' . $this->setupGeneral('get_form') . '
633 ', 0, 1);
634
635 $this->output($this->outputWrapper($this->printAll()));
636
637 break;
638 case 'extConfig':
639 $this->silent=0;
640 $this->generateConfigForm('get_form');
641 // Get the template file
642 $templateFile = @file_get_contents(
643 PATH_site . $this->templateFilePath . 'InitExtConfig.html'
644 );
645 // Get the template part from the file
646 $template = t3lib_parsehtml::getSubpart(
647 $templateFile, '###TEMPLATE###'
648 );
649 // Define the markers content
650 $markers = array(
651 'action' => $this->action,
652 'content' => $this->printAll(),
653 'write' => 'Write configuration',
654 'notice' => 'NOTICE:',
655 'explanation' => '
656 By clicking this button, the configuration is updated
657 with new values for the parameters listed above!
658 '
659 );
660 // Fill the markers in the template
661 $content = t3lib_parsehtml::substituteMarkerArray(
662 $template,
663 $markers,
664 '###|###',
665 TRUE,
666 FALSE
667 );
668 // Send content to the page wrapper function
669 $this->output($this->outputWrapper($content));
670 break;
671 case 'cleanup':
672 $this->checkTheConfig();
673 $this->silent=0;
674 $this->cleanupManager();
675 break;
676 case 'phpinfo':
677 $this->silent=0;
678 $this->phpinformation();
679 break;
680 case 'typo3conf_edit':
681 $this->silent=0;
682 $this->typo3conf_edit();
683 break;
684 case 'logout':
685 $enableInstallToolFile = PATH_site . 'typo3conf/ENABLE_INSTALL_TOOL';
686 if (is_file($enableInstallToolFile) && trim(file_get_contents($enableInstallToolFile)) !== 'KEEP_FILE') {
687 unlink(PATH_typo3conf . 'ENABLE_INSTALL_TOOL');
688 }
689 $this->formProtection->clean();
690 $this->session->destroySession();
691 t3lib_utility_Http::redirect($this->scriptSelf);
692 break;
693 case 'about':
694 default:
695 $this->silent=0;
696 $this->message('About', 'Warning - very important!', $this->securityRisk().$this->alterPasswordForm(), 2);
697
698 $this->message('About', 'Using this script', '
699 <p>
700 Installing TYPO3 has always been a hot topic on the
701 mailing list and forums. Therefore we\'ve developed
702 this tool which will help you through configuration
703 and testing.
704 <br />
705 There are three primary steps for you to take:
706 </p>
707 <p>
708 <strong>1: Basic Configuration</strong>
709 <br />
710 In this step your PHP-configuration is checked. If
711 there are any settings that will prevent TYPO3 from
712 running correctly you\'ll get warnings and errors
713 with a description of the problem.
714 <br />
715 You\'ll have to enter a database username, password
716 and hostname. Then you can choose to create a new
717 database or select an existing one.
718 <br />
719 Finally the image processing settings are entered
720 and verified and you can choose to let the script
721 update the configuration with the suggested settings.
722 </p>
723 <p>
724 <strong>2: Database Analyser</strong>
725 <br />
726 In this step you can either install a new database
727 or update the database from any previous TYPO3
728 version.
729 <br />
730 You can also get an overview of extra/missing
731 fields/tables in the database compared to a raw
732 sql-file.
733 <br />
734 The database is also verified against your
735 \'tables.php\' configuration ($TCA) and you can
736 even see suggestions to entries in $TCA or new
737 fields in the database.
738 </p>
739 <p>
740 <strong>3: Upgrade Wizard</strong>
741 <br />
742 Here you will find update methods taking care of
743 changes to the TYPO3 core which are not backwards
744 compatible.
745 <br />
746 It is recommended to run this wizard after every
747 update to make sure everything will still work
748 flawlessly.
749 </p>
750 <p>
751 <strong>4: Image Processing</strong>
752 <br />
753 This step is a visual guide to verify your
754 configuration of the image processing software.
755 <br />
756 You\'ll be presented to a list of images that should
757 all match in pairs. If some irregularity appears,
758 you\'ll get a warning. Thus you\'re able to track an
759 error before you\'ll discover it on your website.
760 </p>
761 <p>
762 <strong>5: All Configuration</strong>
763 <br />
764 This gives you access to any of the configuration
765 options in the TYPO3_CONF_VARS array. Every option
766 is also presented with a comment explaining what it
767 does.
768 </p>
769 <p>
770 <strong>6: Cleanup</strong>
771 <br />
772 Here you can clean up the temporary files in typo3temp/
773 folder and the tables used for caching of data in
774 your database.
775 </p>
776 ');
777
778 $this->message('About', 'Why is this script stand-alone?', '
779 <p>
780 You would think that this script should rather be a
781 module in the backend and access-controlled to only
782 admin-users from the database. But that\'s not how
783 it works.
784 <br />
785 The reason is, that this script must not be
786 depending on the success of the configuration of
787 TYPO3 and whether or not there is a working database
788 behind. Therefore the script is invoked from the
789 backend init.php file, which allows access if the
790 constant \'TYPO3_enterInstallScript\' has been
791 defined and is not FALSE. That is and should be the
792 case <em>only</em> when calling the script
793 \'typo3/install/index.php\' - this script!
794 </p>
795 ');
796
797 $headCode='Header legend';
798 $this->message($headCode, 'Notice!', '
799 <p>
800 Indicates that something is important to be aware
801 of.
802 <br />
803 This does <em>not</em> indicate an error.
804 </p>
805 ', 1);
806 $this->message($headCode, 'Just information', '
807 <p>
808 This is a simple message with some information about
809 something.
810 </p>
811 ');
812 $this->message($headCode, 'Check was successful', '
813 <p>
814 Indicates that something was checked and returned an
815 expected result.
816 </p>
817 ', -1);
818 $this->message($headCode, 'Warning!', '
819 <p>
820 Indicates that something may very well cause trouble
821 and you should definitely look into it before
822 proceeding.
823 <br />
824 This indicates a <em>potential</em> error.
825 </p>
826 ', 2);
827 $this->message($headCode, 'Error!', '
828 <p>
829 Indicates that something is definitely wrong and
830 that TYPO3 will most likely not perform as expected
831 if this problem is not solved.
832 <br />
833 This indicates an actual error.
834 </p>
835 ', 3);
836
837 $this->output($this->outputWrapper($this->printAll()));
838 break;
839 }
840 }
841 }
842
843 /**
844 * Controls the step 1-2-3-go process
845 *
846 * @return string The content to output to the screen
847 */
848 function stepOutput() {
849 // Get the template file
850 $templateFile = @file_get_contents(
851 PATH_site . $this->templateFilePath . 'StepOutput.html'
852 );
853 // Get the template part from the file
854 $template = t3lib_parsehtml::getSubpart(
855 $templateFile, '###TEMPLATE###'
856 );
857 // Define the markers content
858 $markers = array(
859 'stepHeader' => $this->stepHeader(),
860 'notice' => 'Skip this wizard (for power users only)',
861 'skip123' => $this->scriptSelf
862 );
863
864 $this->checkTheConfig();
865 $error_missingConnect = '
866 <p class="typo3-message message-error">
867 <strong>
868 There is no connection to the database!
869 </strong>
870 <br />
871 (Username: <em>' . htmlspecialchars(TYPO3_db_username) . '</em>,
872 Host: <em>' . htmlspecialchars(TYPO3_db_host) . '</em>,
873 Using Password: YES)
874 <br />
875 Go to Step 1 and enter a valid username and password!
876 </p>
877 ';
878 $error_missingDB = '
879 <p class="typo3-message message-error">
880 <strong>
881 There is no access to the database (<em>' . htmlspecialchars(TYPO3_db) . '</em>)!
882 </strong>
883 <br />
884 Go to Step 2 and select a valid database!
885 </p>
886 ';
887
888 // only get the number of tables if it is not the first two steps in the 123-installer
889 // (= no DB connection yet)
890 $whichTables = ($this->step != 1 && $this->step != 2 ? $this->sqlHandler->getListOfTables() : array());
891
892 $error_emptyDB = '
893 <p class="typo3-message message-error">
894 <strong>
895 The database is still empty. There are no tables!
896 </strong>
897 <br />
898 Go to Step 3 and import a database!
899 </p>
900 ';
901
902 // Hook to override and add steps to the 1-2-3 installer
903 if (is_array ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install/mod/class.tx_install.php']['stepOutput'])) {
904 foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install/mod/class.tx_install.php']['stepOutput'] as $classData) {
905 $hookObject = t3lib_div::getUserObj($classData);
906 $hookObject->executeStepOutput($markers, $this->step, $this);
907 }
908 }
909 // Use the default steps when there is no override
910 if (!$markers['header'] && !$markers['step']) {
911 switch(strtolower($this->step)) {
912 case 1:
913 // Get the subpart for the first step
914 $step1SubPart = t3lib_parsehtml::getSubpart(
915 $templateFile, '###STEP1###'
916 );
917 // Add header marker for main template
918 $markers['header'] = 'Welcome to the TYPO3 Install Tool';
919 // Define the markers content for the subpart
920 $step1SubPartMarkers = array(
921 'llIntroduction' => '
922 <p>
923 TYPO3 is an enterprise content management system
924 that is powerful, yet easy to install.
925 </p>
926 <p>
927 In three simple steps you\'ll be ready to add content to your website.
928 </p>
929 ',
930 'step' => $this->step + 1,
931 'action' => htmlspecialchars($this->action),
932 'continue' => 'Continue'
933 );
934 // Add step marker for main template
935 $markers['step'] = t3lib_parsehtml::substituteMarkerArray(
936 $step1SubPart,
937 $step1SubPartMarkers,
938 '###|###',
939 TRUE,
940 FALSE
941 );
942 break;
943 case 2:
944 // Get the subpart for the second step
945 $step2SubPart = t3lib_parsehtml::getSubpart(
946 $templateFile, '###STEP2###'
947 );
948 // Add header marker for main template
949 $markers['header'] = 'Connect to your database host';
950 // Define the markers content for the subpart
951 $step2SubPartMarkers = array(
952 'step' => $this->step + 1,
953 'action' => htmlspecialchars($this->action),
954 'encryptionKey' => $this->createEncryptionKey(),
955 'branch' => TYPO3_branch,
956 'labelUsername' => 'Username',
957 'username' => htmlspecialchars(TYPO3_db_username),
958 'labelPassword' => 'Password',
959 'password' => htmlspecialchars(TYPO3_db_password),
960 'labelHost' => 'Host',
961 'host' => TYPO3_db_host ? htmlspecialchars(TYPO3_db_host) : 'localhost',
962 'continue' => 'Continue',
963 'llDescription' => 'If you have not already created a username and password to access the database, please do so now. This can be done using tools provided by your host.'
964 );
965 // Add step marker for main template
966 $markers['step'] = t3lib_parsehtml::substituteMarkerArray(
967 $step2SubPart,
968 $step2SubPartMarkers,
969 '###|###',
970 TRUE,
971 FALSE
972 );
973 break;
974 case 3:
975 // Add header marker for main template
976 $markers['header'] = 'Select database';
977 // There should be a database host connection at this point
978 if ($result = $GLOBALS['TYPO3_DB']->sql_pconnect(
979 TYPO3_db_host, TYPO3_db_username, TYPO3_db_password
980 )) {
981 // Get the subpart for the third step
982 $step3SubPart = t3lib_parsehtml::getSubpart(
983 $templateFile, '###STEP3###'
984 );
985 // Get the subpart for the database options
986 $step3DatabaseOptionsSubPart = t3lib_parsehtml::getSubpart(
987 $step3SubPart, '###DATABASEOPTIONS###'
988 );
989
990 $dbArr = $this->getDatabaseList();
991 $dbIncluded = 0;
992 $step3DatabaseOptions = array();
993 foreach ($dbArr as $dbname) {
994 // Define the markers content for database options
995 $step3DatabaseOptionMarkers = array(
996 'databaseValue' => htmlspecialchars($dbname),
997 'databaseSelected' => $dbname == TYPO3_db ? 'selected="selected"' : '',
998 'databaseName' => htmlspecialchars($dbname)
999 );
1000 // Add the option HTML to an array
1001 $step3DatabaseOptions[] = t3lib_parsehtml::substituteMarkerArray(
1002 $step3DatabaseOptionsSubPart,
1003 $step3DatabaseOptionMarkers,
1004 '###|###',
1005 TRUE,
1006 TRUE
1007 );
1008 if ($dbname == TYPO3_db) {
1009 $dbIncluded = 1;
1010 }
1011 }
1012 if (!$dbIncluded && TYPO3_db) {
1013 // // Define the markers content when no access
1014 $step3DatabaseOptionMarkers = array(
1015 'databaseValue' => htmlspecialchars(TYPO3_db),
1016 'databaseSelected' => 'selected="selected"',
1017 'databaseName' => htmlspecialchars(TYPO3_db) . ' (NO ACCESS!)'
1018 );
1019 // Add the option HTML to an array
1020 $step3DatabaseOptions[] = t3lib_parsehtml::substituteMarkerArray(
1021 $step3DatabaseOptionsSubPart,
1022 $step3DatabaseOptionMarkers,
1023 '###|###',
1024 TRUE,
1025 TRUE
1026 );
1027 }
1028
1029 $usePatternList = FALSE;
1030 $createDatabaseAllowed = $this->checkCreateDatabasePrivileges();
1031 if ($createDatabaseAllowed === TRUE) {
1032 $formFieldAttributesNew = 'checked="checked"';
1033 $llRemark1 = 'Enter a name for your TYPO3 database.';
1034 } elseif (is_array($createDatabaseAllowed)) {
1035 $llRemark1 = 'Enter a name for your TYPO3 database.';
1036 $llDbPatternRemark = 'The name has to match one of these names/patterns (% is a wild card):';
1037 $llDbPatternList = '<li>' . implode('</li><li>', $createDatabaseAllowed) . '</li>';
1038 $usePatternList = TRUE;
1039 } else {
1040 $formFieldAttributesNew = 'disabled="disabled"';
1041 $formFieldAttributesSelect = 'checked="checked"';
1042 $llRemark1 = 'You have no permissions to create new databases.';
1043 }
1044
1045 // Substitute the subpart for the database options
1046 $content = t3lib_parsehtml::substituteSubpart(
1047 $step3SubPart,
1048 '###DATABASEOPTIONS###',
1049 implode(LF, $step3DatabaseOptions)
1050 );
1051 if ($usePatternList === FALSE) {
1052 $content = t3lib_parsehtml::substituteSubpart(
1053 $content,
1054 '###DATABASE_NAME_PATTERNS###',
1055 ''
1056 );
1057 }
1058 // Define the markers content
1059 $step3SubPartMarkers = array(
1060 'step' => $this->step + 1,
1061 'llOptions' => 'You have two options:',
1062 'action' => htmlspecialchars($this->action),
1063 'llOption1' => 'Create a new database (recommended):',
1064 'llRemark1' => $llRemark1,
1065 'll_Db_Pattern_Remark' => $llDbPatternRemark,
1066 'll_Db_Pattern_List' => $llDbPatternList,
1067 'formFieldAttributesNew' => $formFieldAttributesNew,
1068 'formFieldAttributesSelect' => $formFieldAttributesSelect,
1069 'llOption2' => 'Select an EMPTY existing database:',
1070 'llRemark2' => 'Any tables used by TYPO3 will be overwritten.',
1071 'continue' => 'Continue'
1072 );
1073 // Add step marker for main template
1074 $markers['step'] = t3lib_parsehtml::substituteMarkerArray(
1075 $content,
1076 $step3SubPartMarkers,
1077 '###|###',
1078 TRUE,
1079 TRUE
1080 );
1081 } else {
1082 // Add step marker for main template when no connection
1083 $markers['step'] = $error_missingConnect;
1084 }
1085 break;
1086 case 4:
1087 // Add header marker for main template
1088 $markers['header'] = 'Import the Database Tables';
1089 // There should be a database host connection at this point
1090 if ($result = $GLOBALS['TYPO3_DB']->sql_pconnect(
1091 TYPO3_db_host, TYPO3_db_username, TYPO3_db_password
1092 )) {
1093 // The selected database should be accessible
1094 if ($GLOBALS['TYPO3_DB']->sql_select_db(TYPO3_db)) {
1095 // Get the subpart for the fourth step
1096 $step4SubPart = t3lib_parsehtml::getSubpart(
1097 $templateFile, '###STEP4###'
1098 );
1099 // Get the subpart for the database type options
1100 $step4DatabaseTypeOptionsSubPart = t3lib_parsehtml::getSubpart(
1101 $step4SubPart, '###DATABASETYPEOPTIONS###'
1102 );
1103
1104 $sFiles = t3lib_div::getFilesInDir(PATH_typo3conf, 'sql', 1, 1);
1105
1106 // Check if default database scheme "database.sql" already exists, otherwise create it
1107 if (!strstr(implode(',', $sFiles).',', '/database.sql,')) {
1108 array_unshift($sFiles, 'Default TYPO3 Tables');
1109 }
1110
1111 $step4DatabaseTypeOptions = array();
1112 foreach ($sFiles as $f) {
1113 if ($f == 'Default TYPO3 Tables') {
1114 $key = 'CURRENT_TABLES+STATIC';
1115 } else {
1116 $key = htmlspecialchars($f);
1117 }
1118 // Define the markers content for database type subpart
1119 $step4DatabaseTypeOptionMarkers = array(
1120 'databaseTypeValue' => 'import|' . $key,
1121 'databaseName' => htmlspecialchars(basename($f))
1122 );
1123 // Add the option HTML to an array
1124 $step4DatabaseTypeOptions[] = t3lib_parsehtml::substituteMarkerArray(
1125 $step4DatabaseTypeOptionsSubPart,
1126 $step4DatabaseTypeOptionMarkers,
1127 '###|###',
1128 TRUE,
1129 FALSE
1130 );
1131 }
1132 // Substitute the subpart for the database type options
1133 $content = t3lib_parsehtml::substituteSubpart(
1134 $step4SubPart,
1135 '###DATABASETYPEOPTIONS###',
1136 implode(LF, $step4DatabaseTypeOptions)
1137 );
1138 // Define the markers content
1139 $step4SubPartMarkers = array(
1140 'llSummary' => 'Database summary:',
1141 'llUsername' => 'Username:',
1142 'username' => htmlspecialchars(TYPO3_db_username),
1143 'llHost' => 'Host:',
1144 'host' => htmlspecialchars(TYPO3_db_host),
1145 'llDatabase' => 'Database:',
1146 'database' => htmlspecialchars(TYPO3_db),
1147 'llNumberTables' => 'Number of tables:',
1148 'numberTables' => count($whichTables),
1149 'action' => htmlspecialchars($this->action),
1150 'llDatabaseType' => 'Select database contents:',
1151 'label' => 'Import database'
1152 );
1153 // Add step marker for main template
1154 $markers['step'] = t3lib_parsehtml::substituteMarkerArray(
1155 $content,
1156 $step4SubPartMarkers,
1157 '###|###',
1158 TRUE,
1159 TRUE
1160 );
1161 } else {
1162 // Add step marker for main template when no database
1163 $markers['step'] = $error_missingDB;
1164 }
1165 } else {
1166 // Add step marker for main template when no connection
1167 $markers['step'] = $error_missingConnect;
1168 }
1169 break;
1170 case 'go':
1171 // Add header marker for main template
1172 $markers['header'] = 'Congratulations!';
1173 // There should be a database host connection at this point
1174 if ($result = $GLOBALS['TYPO3_DB']->sql_pconnect(
1175 TYPO3_db_host, TYPO3_db_username, TYPO3_db_password
1176 )) {
1177 // The selected database should be accessible
1178 if ($GLOBALS['TYPO3_DB']->sql_select_db(TYPO3_db)) {
1179 // The database should contain tables
1180 if (count($whichTables)) {
1181 // Get the subpart for the go step
1182 $stepGoSubPart = t3lib_parsehtml::getSubpart(
1183 $templateFile, '###STEPGO###'
1184 );
1185 // Define the markers content
1186 $stepGoSubPartMarkers = array(
1187 'messageBasicFinished' => $this->messageBasicFinished(),
1188 'llImportant' => 'Important Security Warning',
1189 'securityRisk' => $this->securityRisk(),
1190 'llSwitchMode' => '
1191 <a href="' . $this->scriptSelf . '">
1192 Change the Install Tool password here
1193 </a>
1194 '
1195 );
1196 // Add step marker for main template
1197 $markers['step'] = t3lib_parsehtml::substituteMarkerArray(
1198 $stepGoSubPart,
1199 $stepGoSubPartMarkers,
1200 '###|###',
1201 TRUE,
1202 TRUE
1203 );
1204 } else {
1205 // Add step marker for main template when empty database
1206 $markers['step'] = $error_emptyDB;
1207 }
1208 } else {
1209 // Add step marker for main template when no database
1210 $markers['step'] = $error_missingDB;
1211 }
1212 } else {
1213 // Add step marker for main template when no connection
1214 $markers['step'] = $error_missingConnect;
1215 }
1216 break;
1217 }
1218 }
1219 // Fill the markers in the template
1220 $content = t3lib_parsehtml::substituteMarkerArray(
1221 $template,
1222 $markers,
1223 '###|###',
1224 TRUE,
1225 FALSE
1226 );
1227
1228 return $content;
1229 }
1230
1231 /**
1232 * Calling the functions that checks the system
1233 *
1234 * @return void
1235 */
1236 function checkTheConfig() {
1237 // Order important:
1238 $this->checkDirs();
1239 $this->checkConfiguration();
1240 $this->checkExtensions();
1241
1242 if (TYPO3_OS=='WIN') {
1243 $paths=array($GLOBALS['TYPO3_CONF_VARS']['GFX']['im_path_lzw'], $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_path'], 'c:\\php\\imagemagick\\', 'c:\\php\\GraphicsMagick\\', 'c:\\apache\\ImageMagick\\', 'c:\\apache\\GraphicsMagick\\');
1244 if (!isset($_SERVER['PATH'])) {
1245 $serverPath = array_change_key_case($_SERVER, CASE_UPPER);
1246 $paths = array_merge($paths, explode(';', $serverPath['PATH']));
1247 } else {
1248 $paths = array_merge($paths, explode(';', $_SERVER['PATH']));
1249 }
1250 } else {
1251 $paths=array($GLOBALS['TYPO3_CONF_VARS']['GFX']['im_path_lzw'], $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_path'], '/usr/local/bin/', '/usr/bin/', '/usr/X11R6/bin/', '/opt/local/bin/');
1252 $paths = array_merge($paths, explode(':', $_SERVER['PATH']));
1253 }
1254 $paths = array_unique($paths);
1255
1256 asort($paths);
1257 if (t3lib_utility_PhpOptions::isSafeModeEnabled()) {
1258 $paths=array(ini_get('safe_mode_exec_dir'), '/usr/local/php/bin/');
1259 }
1260 if ($this->INSTALL['checkIM']['lzw']) {
1261 $this->checkIMlzw = 1;
1262 }
1263 if ($this->INSTALL['checkIM']['path']) {
1264 $paths[]=trim($this->INSTALL['checkIM']['path']);
1265 }
1266 if ($this->checkIM) {
1267 $this->checkImageMagick($paths);
1268 }
1269 $this->checkDatabase();
1270 }
1271
1272 /**
1273 * Editing files in typo3conf directory (or elsewhere if enabled)
1274 *
1275 * @return void
1276 */
1277 function typo3conf_edit() {
1278 // default:
1279 $EDIT_path = PATH_typo3conf;
1280 if ($this->allowFileEditOutsite_typo3conf_dir && $this->INSTALL['FILE']['EDIT_path']) {
1281 if (t3lib_div::validPathStr($this->INSTALL['FILE']['EDIT_path']) && substr($this->INSTALL['FILE']['EDIT_path'], -1)=='/') {
1282 $tmp_path = PATH_site.$this->INSTALL['FILE']['EDIT_path'];
1283 if (is_dir($tmp_path)) {
1284 $EDIT_path=$tmp_path;
1285 } else {
1286 $this->errorMessages[] = '
1287 \'' . $tmp_path . '\' was not directory
1288 ';
1289 }
1290 } else {
1291 $this->errorMessages[] = '
1292 Bad directory name (must be like t3lib/ or media/script/)
1293 ';
1294 }
1295 }
1296
1297 $headCode = 'Edit files in '.basename($EDIT_path).'/';
1298 $messages = '';
1299
1300 if ($this->INSTALL['SAVE_FILE']) {
1301 $save_to_file = $this->INSTALL['FILE']['name'];
1302 if (@is_file($save_to_file)) {
1303 $save_to_file_md5 = md5($save_to_file);
1304 if (isset($this->INSTALL['FILE'][$save_to_file_md5]) && t3lib_div::isFirstPartOfStr($save_to_file, $EDIT_path.'') && substr($save_to_file, -1)!='~' && !strstr($save_to_file, '_bak')) {
1305 $this->INSTALL['typo3conf_files'] = $save_to_file;
1306 $save_fileContent = $this->INSTALL['FILE'][$save_to_file_md5];
1307
1308 if ($this->INSTALL['FILE']['win_to_unix_br']) {
1309 $save_fileContent = str_replace(CRLF, LF, $save_fileContent);
1310 }
1311
1312 $backupFile = $this->getBackupFilename($save_to_file);
1313 if ($this->INSTALL['FILE']['backup']) {
1314 if (@is_file($backupFile)) { unlink($backupFile); }
1315 rename($save_to_file, $backupFile);
1316 $messages .= '
1317 Backup written to <strong>' . $backupFile . '</strong>
1318 <br />
1319 ';
1320 }
1321
1322 t3lib_div::writeFile($save_to_file, $save_fileContent);
1323 $messages .= '
1324 File saved: <strong>' . $save_to_file . '</strong>
1325 <br />
1326 MD5-sum: ' . $this->INSTALL['FILE']['prevMD5'] . ' (prev)
1327 <br />
1328 MD5-sum: ' . md5($save_fileContent) . ' (new)
1329 <br />
1330 ';
1331 }
1332 }
1333 }
1334
1335 // Filelist:
1336 // Get the template file
1337 $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'Typo3ConfEdit.html');
1338 // Get the template part from the file
1339 $template = t3lib_parsehtml::getSubpart($templateFile, '###TEMPLATE###');
1340 // Get the subpart for the files
1341 $filesSubpart = t3lib_parsehtml::getSubpart($template, '###FILES###');
1342 $files = array();
1343
1344 $typo3conf_files = t3lib_div::getFilesInDir($EDIT_path, '', 1, 1);
1345 $fileFound = 0;
1346
1347 foreach ($typo3conf_files as $k => $file) {
1348 // Delete temp_CACHED files if option is set
1349 if ( $this->INSTALL['delTempCached'] && preg_match('|/temp_CACHED_[a-z0-9_]+\.php|', $file)) {
1350 unlink($file);
1351 continue;
1352 }
1353 if ($this->INSTALL['typo3conf_files'] && !strcmp($this->INSTALL['typo3conf_files'], $file)) {
1354 $fileFound = 1;
1355 }
1356 // Define the markers content for the files subpart
1357 $filesMarkers = array(
1358 'editUrl' => $this->action . '&amp;TYPO3_INSTALL[typo3conf_files]=' . rawurlencode($file) . ($this->allowFileEditOutsite_typo3conf_dir ? '&amp;TYPO3_INSTALL[FILE][EDIT_path]=' . rawurlencode($this->INSTALL['FILE']['EDIT_path']) : '') . '#confEditFileList',
1359 'fileName' => basename($file),
1360 'fileSize' => t3lib_div::formatSize(filesize($file)),
1361 'class' => $this->INSTALL['typo3conf_files'] && !strcmp($this->INSTALL['typo3conf_files'], $file) ? 'class="act"' : ''
1362 );
1363 // Fill the markers in the subpart
1364 $files[] = t3lib_parsehtml::substituteMarkerArray(
1365 $filesSubpart,
1366 $filesMarkers,
1367 '###|###',
1368 TRUE,
1369 FALSE
1370 );
1371 }
1372
1373 if ($fileFound && @is_file($this->INSTALL['typo3conf_files'])) {
1374
1375 $backupFile = $this->getBackupFilename($this->INSTALL['typo3conf_files']);
1376 $fileContent = t3lib_div::getUrl($this->INSTALL['typo3conf_files']);
1377 // Get the subpart to edit the files
1378 $fileEditTemplate = t3lib_parsehtml::getSubpart($template, '###FILEEDIT###');
1379 $allowFileEditOutsideTypo3ConfDirSubPart = '';
1380
1381 if (substr($this->INSTALL['typo3conf_files'], -1) != '~' && !strstr($this->INSTALL['typo3conf_files'], '_bak')) {
1382 // Get the subpart to show the save button
1383 $showSaveButtonSubPart = t3lib_parsehtml::getSubpart($fileEditTemplate, '###SHOWSAVEBUTTON###');
1384 }
1385
1386 if ($this->allowFileEditOutsite_typo3conf_dir) {
1387 // Get the subpart to show if files are allowed outside the directory typo3conf
1388 $allowFileEditOutsideTypo3ConfDirSubPart = t3lib_parsehtml::getSubpart($fileEditTemplate, '###ALLOWFILEEDITOUTSIDETYPO3CONFDIR###');
1389 }
1390 // Substitute the subpart for the save button
1391 $fileEditContent = t3lib_parsehtml::substituteSubpart(
1392 $fileEditTemplate,
1393 '###SHOWSAVEBUTTON###',
1394 $showSaveButtonSubPart
1395 );
1396 // Substitute the subpart to show if files are allowed outside the directory typo3conf
1397 $fileEditContent = t3lib_parsehtml::substituteSubpart(
1398 $fileEditContent,
1399 '###ALLOWFILEEDITOUTSIDETYPO3CONFDIR###',
1400 $allowFileEditOutsideTypo3ConfDirSubPart
1401 );
1402 // Define the markers content for subpart to edit the files
1403 $fileEditMarkers = array(
1404 'messages' => !empty($messages) ? '<p class="typo3-message message-warning">' . $messages . '</p>' : '',
1405 'action' => $this->action . '#fileEditHeader',
1406 'saveFile' => 'Save file',
1407 'close' => 'Close',
1408 'llEditing' => 'Editing file:',
1409 'file' => $this->INSTALL['typo3conf_files'],
1410 'md5Sum' => 'MD5-sum: ' . md5($fileContent),
1411 'fileName' => $this->INSTALL['typo3conf_files'],
1412 'fileEditPath' => $this->INSTALL['FILE']['EDIT_path'],
1413 'filePreviousMd5' => md5($fileContent),
1414 'fileMd5' => md5($this->INSTALL['typo3conf_files']),
1415 'fileContent' => t3lib_div::formatForTextarea($fileContent),
1416 'winToUnixBrChecked' => TYPO3_OS == 'WIN' ? '' : 'checked="checked"',
1417 'winToUnixBr' => 'Convert Windows linebreaks (13-10) to Unix (10)',
1418 'backupChecked' => @is_file($backupFile) ? 'checked="checked"' : '',
1419 'backup' => 'Make backup copy (rename to ' . basename($backupFile) . ')'
1420 );
1421 // Fill the markers in the subpart to edit the files
1422 $fileEditContent = t3lib_parsehtml::substituteMarkerArray(
1423 $fileEditContent,
1424 $fileEditMarkers,
1425 '###|###',
1426 TRUE,
1427 FALSE
1428 );
1429 }
1430
1431 if ($this->allowFileEditOutsite_typo3conf_dir) {
1432 // Get the subpart to show if files are allowed outside the directory typo3conf
1433 $allowFileEditOutsideTypo3ConfDirSubPart = t3lib_parsehtml::getSubpart($template, '###ALLOWFILEEDITOUTSIDETYPO3CONFDIR###');
1434 // Define the markers content
1435 $allowFileEditOutsideTypo3ConfDirMarkers = array(
1436 'action' => $this->action,
1437 'pathSite' => PATH_site,
1438 'editPath' => $this->INSTALL['FILE']['EDIT_path'],
1439 'set' => 'Set'
1440 );
1441 // Fill the markers in the subpart
1442 $allowFileEditOutsideTypo3ConfDirSubPart = t3lib_parsehtml::substituteMarkerArray(
1443 $allowFileEditOutsideTypo3ConfDirSubPart,
1444 $allowFileEditOutsideTypo3ConfDirMarkers,
1445 '###|###',
1446 TRUE,
1447 FALSE
1448 );
1449 }
1450 // Substitute the subpart to edit the file
1451 $fileListContent = t3lib_parsehtml::substituteSubpart(
1452 $template,
1453 '###FILEEDIT###',
1454 $fileEditContent
1455 );
1456 // Substitute the subpart when files can be edited outside typo3conf directory
1457 $fileListContent = t3lib_parsehtml::substituteSubpart(
1458 $fileListContent,
1459 '###ALLOWFILEEDITOUTSIDETYPO3CONFDIR###',
1460 $allowFileEditOutsideTypo3ConfDirSubPart
1461 );
1462 // Substitute the subpart for the files
1463 $fileListContent = t3lib_parsehtml::substituteSubpart(
1464 $fileListContent,
1465 '###FILES###',
1466 implode(LF, $files)
1467 );
1468 // Define the markers content
1469 $fileListMarkers = array(
1470 'editPath' => '(' . $EDIT_path . ')',
1471 'deleteTempCachedUrl' => $this->action . '&amp;TYPO3_INSTALL[delTempCached]=1',
1472 'deleteTempCached' => 'Delete temp_CACHED* files'
1473 );
1474 // Fill the markers
1475 $fileListContent = t3lib_parsehtml::substituteMarkerArray(
1476 $fileListContent,
1477 $fileListMarkers,
1478 '###|###',
1479 TRUE,
1480 FALSE
1481 );
1482 // Add the content to the message array
1483 $this->message($headCode, 'Files in folder', $fileListContent);
1484 // Output the page
1485 $this->output($this->outputWrapper($this->printAll()));
1486 }
1487
1488 /**
1489 * Outputs system information
1490 *
1491 * @return void
1492 */
1493 function phpinformation() {
1494 $headCode = 'PHP information';
1495
1496 $sVar = t3lib_div::getIndpEnv('_ARRAY');
1497 $sVar['CONST: PHP_OS']=PHP_OS;
1498 $sVar['CONST: TYPO3_OS']=TYPO3_OS;
1499 $sVar['CONST: PATH_thisScript']=PATH_thisScript;
1500 $sVar['CONST: php_sapi_name()']=PHP_SAPI;
1501 $sVar['OTHER: TYPO3_VERSION']=TYPO3_version;
1502 $sVar['OTHER: PHP_VERSION']=phpversion();
1503 $sVar['imagecreatefromgif()']=function_exists('imagecreatefromgif');
1504 $sVar['imagecreatefrompng()']=function_exists('imagecreatefrompng');
1505 $sVar['imagecreatefromjpeg()']=function_exists('imagecreatefromjpeg');
1506 $sVar['imagegif()']=function_exists('imagegif');
1507 $sVar['imagepng()']=function_exists('imagepng');
1508 $sVar['imagejpeg()']=function_exists('imagejpeg');
1509 $sVar['imagettftext()']=function_exists('imagettftext');
1510 $sVar['OTHER: IMAGE_TYPES']=function_exists('imagetypes') ? imagetypes() : 0;
1511 $sVar['OTHER: memory_limit']=ini_get('memory_limit');
1512
1513 $gE_keys = explode(',', 'SERVER_PORT,SERVER_SOFTWARE,GATEWAY_INTERFACE,SCRIPT_NAME,PATH_TRANSLATED');
1514 foreach ($gE_keys as $k) {
1515 $sVar['SERVER: '.$k]=$_SERVER[$k];
1516 }
1517
1518 $gE_keys = explode(',', 'image_processing,gdlib,gdlib_png,im,im_path,im_path_lzw,im_version_5,im_negate_mask,im_imvMaskState,im_combine_filename');
1519
1520 foreach ($gE_keys as $k) {
1521 $sVar['T3CV_GFX: '.$k]=$GLOBALS['TYPO3_CONF_VARS']['GFX'][$k];
1522 }
1523
1524 $debugInfo = array(
1525 '### DEBUG SYSTEM INFORMATION - START ###'
1526 );
1527 foreach ($sVar as $kkk => $vvv) {
1528 $debugInfo[]=str_pad(substr($kkk, 0, 20), 20).': '.$vvv;
1529 }
1530 $debugInfo[]='### DEBUG SYSTEM INFORMATION - END ###';
1531 // Get the template file
1532 $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'PhpInformation.html');
1533 // Get the template part from the file
1534 $template = t3lib_parsehtml::getSubpart($templateFile, '###TEMPLATE###');
1535 // Define the markers content
1536 $markers = array(
1537 'explanation' => 'Please copy/paste the information from this text field into an email or bug-report as "Debug System Information" whenever you wish to get support or report problems. This information helps others to check if your system has some obvious misconfiguration and you\'ll get your help faster!',
1538 'debugInfo' => t3lib_div::formatForTextarea(implode(LF, $debugInfo))
1539 );
1540 // Fill the markers
1541 $content = t3lib_parsehtml::substituteMarkerArray(
1542 $template,
1543 $markers,
1544 '###|###',
1545 TRUE,
1546 FALSE
1547 );
1548 // Add the content to the message array
1549 $this->message($headCode, 'DEBUG information', $content);
1550 // Start with various server information
1551 $getEnvArray = array();
1552 $gE_keys = explode(',', 'QUERY_STRING,HTTP_ACCEPT,HTTP_ACCEPT_ENCODING,HTTP_ACCEPT_LANGUAGE,HTTP_CONNECTION,HTTP_COOKIE,HTTP_HOST,HTTP_USER_AGENT,REMOTE_ADDR,REMOTE_HOST,REMOTE_PORT,SERVER_ADDR,SERVER_ADMIN,SERVER_NAME,SERVER_PORT,SERVER_SIGNATURE,SERVER_SOFTWARE,GATEWAY_INTERFACE,SERVER_PROTOCOL,REQUEST_METHOD,SCRIPT_NAME,PATH_TRANSLATED,HTTP_REFERER,PATH_INFO');
1553 foreach ($gE_keys as $k) {
1554 $getEnvArray[$k] = getenv($k);
1555 }
1556 $this->message($headCode, 't3lib_div::getIndpEnv()', $this->viewArray(t3lib_div::getIndpEnv('_ARRAY')));
1557 $this->message($headCode, 'getenv()', $this->viewArray($getEnvArray));
1558 $this->message($headCode, '_ENV', $this->viewArray($_ENV));
1559 $this->message($headCode, '_SERVER', $this->viewArray($_SERVER));
1560 $this->message($headCode, '_COOKIE', $this->viewArray($_COOKIE));
1561 $this->message($headCode, '_GET', $this->viewArray($_GET));
1562 // Start with the phpinfo() part
1563 ob_start();
1564 phpinfo();
1565 $contents = explode('<body>', ob_get_contents());
1566 ob_end_clean();
1567 $contents = explode('</body>', $contents[1]);
1568 // Do code cleaning: phpinfo() is not XHTML1.1 compliant
1569 $phpinfo = str_replace('<font', '<span', $contents[0]);
1570 $phpinfo = str_replace('</font', '</span', $phpinfo);
1571 $phpinfo = str_replace('<img border="0"', '<img', $phpinfo);
1572 $phpinfo = str_replace('<a name=', '<a id=', $phpinfo);
1573 // Add phpinfo() to the message array
1574 $this->message($headCode, 'phpinfo()', '
1575 <div class="phpinfo">
1576 ' . $phpinfo . '
1577 </div>
1578 ');
1579 // Output the page
1580 $this->output($this->outputWrapper($this->printAll()));
1581 }
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592 /*******************************
1593 *
1594 * cleanup manager
1595 *
1596 *******************************/
1597
1598 /**
1599 * Provides a tool cleaning up various tables in the database
1600 *
1601 * @return void
1602 * @author Robert Lemke <rl@robertlemke.de>
1603 * @todo Add more functionality ...
1604 */
1605 function cleanupManager() {
1606 $headCode = 'Clean up your TYPO3 installation';
1607 $this->message($headCode, 'Database cache tables', '
1608 <p>
1609 <strong>Clear cached image sizes</strong>
1610 <br />
1611 Clears the cache used for memorizing sizes of all images used in
1612 your website. This information is cached in order to gain
1613 performance and will be stored each time a new image is being
1614 displayed in the frontend.
1615 </p>
1616 <p>
1617 You should <em>Clear All Cache</em> in the backend after
1618 clearing this cache.
1619 </p>
1620 ');
1621
1622 $tables = $this->sqlHandler->getListOfTables();
1623 $action = $this->INSTALL['cleanup_type'];
1624
1625 if (($action == 'cache_imagesizes' || $action == 'all') && isset ($tables['cache_imagesizes'])) {
1626 $GLOBALS['TYPO3_DB']->exec_TRUNCATEquery('cache_imagesizes');
1627 }
1628
1629 $cleanupType = array (
1630 'all' => 'Clean up everything',
1631 );
1632
1633 // Get cache_imagesizes info
1634 if (isset ($tables['cache_imagesizes'])) {
1635 $cleanupType['cache_imagesizes'] = 'Clear cached image sizes only';
1636 $cachedImageSizesCounter = intval($GLOBALS['TYPO3_DB']->exec_SELECTcountRows('*', 'cache_imagesizes'));
1637 } else {
1638 $this->message($headCode, 'Table cache_imagesizes does not exist!', '
1639 <p>
1640 The table cache_imagesizes was not found. Please check your
1641 database settings in Basic Configuration and compare your
1642 table definition with the Database Analyzer.
1643 </p>
1644 ', 2);
1645 $cachedImageSizesCounter = 'unknown';
1646 }
1647 // Get the template file
1648 $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'CleanUpManager.html');
1649 // Get the template part from the file
1650 $template = t3lib_parsehtml::getSubpart($templateFile, '###TEMPLATE###');
1651 // Get the subpart for the 'Clean up' dropdown
1652 $cleanUpOptionsSubpart = t3lib_parsehtml::getSubpart($template, '###CLEANUPOPTIONS###');
1653 $cleanUpOptions = array();
1654
1655 foreach ($cleanupType as $cleanUpKey => $cleanUpValue) {
1656 // Define the markers content
1657 $cleanUpMarkers = array(
1658 'value' => htmlspecialchars($cleanUpKey),
1659 'data' => htmlspecialchars($cleanUpValue)
1660 );
1661 // Fill the markers in the subpart
1662 $cleanUpOptions[] = t3lib_parsehtml::substituteMarkerArray(
1663 $cleanUpOptionsSubpart,
1664 $cleanUpMarkers,
1665 '###|###',
1666 TRUE,
1667 FALSE
1668 );
1669 }
1670 // Substitute the subpart for the 'Clean up' dropdown
1671 $content = t3lib_parsehtml::substituteSubpart(
1672 $template,
1673 '###CLEANUPOPTIONS###',
1674 implode(LF, $cleanUpOptions)
1675 );
1676 // Define the markers content
1677 $markers = array(
1678 'numberCached' => 'Number cached image sizes:',
1679 'number' => $cachedImageSizesCounter,
1680 'action' => $this->action,
1681 'cleanUp' => 'Clean up',
1682 'execute' => 'Execute'
1683 );
1684 // Fill the markers
1685 $content = t3lib_parsehtml::substituteMarkerArray(
1686 $content,
1687 $markers,
1688 '###|###',
1689 TRUE,
1690 FALSE
1691 );
1692 // Add the content to the message array
1693 $this->message($headCode, 'Statistics', $content, 1);
1694
1695 $this->message($headCode, 'typo3temp/ folder', '
1696 <p>
1697 TYPO3 uses this directory for temporary files, mainly processed
1698 and cached images.
1699 <br />
1700 The filenames are very cryptic; They are unique representations
1701 of the file properties made by md5-hashing a serialized array
1702 with information.
1703 <br />
1704 Anyway this directory may contain many thousand files and a lot
1705 of them may be of no use anymore.
1706 </p>
1707 <p>
1708 With this test you can delete the files in this folder. When you
1709 do that, you should also clear the cache database tables
1710 afterwards.
1711 </p>
1712 ');
1713
1714 if (!$this->config_array['dir_typo3temp']) {
1715 $this->message('typo3temp/ directory', 'typo3temp/ not writable!', '
1716 <p>
1717 You must make typo3temp/ write enabled before you can
1718 proceed with this test.
1719 </p>
1720 ', 2);
1721 $this->output($this->outputWrapper($this->printAll()));
1722 return;
1723 }
1724
1725 // Run through files
1726 $fileCounter = 0;
1727 $deleteCounter = 0;
1728 $criteriaMatch = 0;
1729 $tmap = array('day'=>1, 'week'=>7, 'month'=>30);
1730 $tt = $this->INSTALL['typo3temp_delete'];
1731 $subdir = $this->INSTALL['typo3temp_subdir'];
1732 if (strlen($subdir) && !preg_match('/^[[:alnum:]_]+\/$/', $subdir)) {
1733 die('subdir "'.$subdir.'" was not allowed!');
1734 }
1735 $action = $this->INSTALL['typo3temp_action'];
1736 $d = @dir($this->typo3temp_path.$subdir);
1737 if (is_object($d)) {
1738 while ($entry = $d->read()) {
1739 $theFile = $this->typo3temp_path.$subdir.$entry;
1740 if (@is_file($theFile)) {
1741 $ok = 0;
1742 $fileCounter++;
1743 if ($tt) {
1744 if (t3lib_utility_Math::canBeInterpretedAsInteger($tt)) {
1745 if (filesize($theFile) > $tt*1024) $ok=1;
1746 } else {
1747 if (fileatime($theFile) < $GLOBALS['EXEC_TIME'] - (intval($tmap[$tt]) * 60 * 60 * 24)) {
1748 $ok = 1;
1749 }
1750 }
1751 } else {
1752 $ok = 1;
1753 }
1754 if ($ok) {
1755 $hashPart=substr(basename($theFile), -14, 10);
1756 // This is a kind of check that the file being deleted has a 10 char hash in it
1757 if (!preg_match('/[^a-f0-9]/', $hashPart) || substr($theFile, -6)==='.cache' || substr($theFile, -4)==='.tbl' || substr(basename($theFile), 0, 8)==='install_') {
1758 if ($action && $deleteCounter<$action) {
1759 $deleteCounter++;
1760 unlink($theFile);
1761 } else {
1762 $criteriaMatch++;
1763 }
1764 }
1765 }
1766 }
1767 }
1768 $d->close();
1769 }
1770
1771 // Find sub-dirs:
1772 $subdirRegistry = array(''=>'');
1773 $d = @dir($this->typo3temp_path);
1774 if (is_object($d)) {
1775 while($entry=$d->read()) {
1776 $theFile = $entry;
1777 if (@is_dir($this->typo3temp_path.$theFile) && $theFile!='..' && $theFile!='.') {
1778 $subdirRegistry[$theFile.'/'] = $theFile.'/ (Files: '.count(t3lib_div::getFilesInDir($this->typo3temp_path.$theFile)).')';
1779 }
1780 }
1781 }
1782
1783 $deleteType=array(
1784 '0' => 'All',
1785 'day' => 'Last access more than a day ago',
1786 'week' => 'Last access more than a week ago',
1787 'month' => 'Last access more than a month ago',
1788 '10' => 'Filesize greater than 10KB',
1789 '50' => 'Filesize greater than 50KB',
1790 '100' => 'Filesize greater than 100KB'
1791 );
1792
1793 $actionType=array(
1794 '0' => "Don't delete, just display statistics",
1795 '100' => 'Delete 100',
1796 '500' => 'Delete 500',
1797 '1000' => 'Delete 1000'
1798 );
1799 // Get the template file
1800 $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'Typo3TempManager.html');
1801 // Get the template part from the file
1802 $template = t3lib_parsehtml::getSubpart($templateFile, '###TEMPLATE###');
1803 // Get the subpart for 'Delete files by condition' dropdown
1804 $deleteOptionsSubpart = t3lib_parsehtml::getSubpart($template, '###DELETEOPTIONS###');
1805 $deleteOptions = array();
1806
1807 foreach ($deleteType as $deleteKey => $deleteValue) {
1808 // Define the markers content
1809 $deleteMarkers = array(
1810 'value' => htmlspecialchars($deleteKey),
1811 'selected' => !strcmp($deleteKey, $tt) ? 'selected="selected"' : '',
1812 'data' => htmlspecialchars($deleteValue)
1813 );
1814 // Fill the markers in the subpart
1815 $deleteOptions[] = t3lib_parsehtml::substituteMarkerArray(
1816 $deleteOptionsSubpart,
1817 $deleteMarkers,
1818 '###|###',
1819 TRUE,
1820 FALSE
1821 );
1822 }
1823 // Substitute the subpart for 'Delete files by condition' dropdown
1824 $content = t3lib_parsehtml::substituteSubpart(
1825 $template,
1826 '###DELETEOPTIONS###',
1827 implode(LF, $deleteOptions)
1828 );
1829 // Get the subpart for 'Number of files at a time' dropdown
1830 $actionOptionsSubpart = t3lib_parsehtml::getSubpart($template, '###ACTIONOPTIONS###');
1831 $actionOptions = array();
1832
1833 foreach ($actionType as $actionKey => $actionValue) {
1834 // Define the markers content
1835 $actionMarkers = array(
1836 'value' => htmlspecialchars($actionKey),
1837 'data' => htmlspecialchars($actionValue)
1838 );
1839 // Fill the markers in the subpart
1840 $actionOptions[] = t3lib_parsehtml::substituteMarkerArray(
1841 $actionOptionsSubpart,
1842 $actionMarkers,
1843 '###|###',
1844 TRUE,
1845 FALSE
1846 );
1847 }
1848 // Substitute the subpart for 'Number of files at a time' dropdown
1849 $content = t3lib_parsehtml::substituteSubpart(
1850 $content,
1851 '###ACTIONOPTIONS###',
1852 implode(LF, $actionOptions)
1853 );
1854 // Get the subpart for 'From sub-directory' dropdown
1855 $subDirectoryOptionsSubpart = t3lib_parsehtml::getSubpart($template, '###SUBDIRECTORYOPTIONS###');
1856 $subDirectoryOptions = array();
1857
1858 foreach ($subdirRegistry as $subDirectoryKey => $subDirectoryValue) {
1859 // Define the markers content
1860 $subDirectoryMarkers = array(
1861 'value' => htmlspecialchars($subDirectoryKey),
1862 'selected' => !strcmp($subDirectoryKey, $this->INSTALL['typo3temp_subdir']) ? 'selected="selected"' : '',
1863 'data' => htmlspecialchars($subDirectoryValue)
1864 );
1865 // Fill the markers in the subpart
1866 $subDirectoryOptions[] = t3lib_parsehtml::substituteMarkerArray(
1867 $subDirectoryOptionsSubpart,
1868 $subDirectoryMarkers,
1869 '###|###',
1870 TRUE,
1871 FALSE
1872 );
1873 }
1874 // Substitute the subpart for 'From sub-directory' dropdown
1875 $content = t3lib_parsehtml::substituteSubpart(
1876 $content,
1877 '###SUBDIRECTORYOPTIONS###',
1878 implode(LF, $subDirectoryOptions)
1879 );
1880 // Define the markers content
1881 $markers = array(
1882 'numberTemporary' => 'Number of temporary files:',
1883 'numberMatching' => 'Number matching:',
1884 'numberDeleted' => 'Number deleted:',
1885 'temporary' => ($fileCounter - $deleteCounter),
1886 'matching' => $criteriaMatch,
1887 'deleteType' => '<span>' . htmlspecialchars($deleteType[$tt]) . '</span>',
1888 'deleted' => $deleteCounter,
1889 'deleteCondition' => 'Delete files by condition',
1890 'numberFiles' => 'Number of files at a time:',
1891 'fromSubdirectory' => 'From sub-directory:',
1892 'execute' => 'Execute',
1893 'explanation' => '
1894 <p>
1895 This tool will delete files only if the last 10 characters
1896 before the extension (3 chars+\'.\') are hexadecimal valid
1897 ciphers, which are lowercase a-f and 0-9.
1898 </p>
1899 '
1900 );
1901 // Fill the markers
1902 $content = t3lib_parsehtml::substituteMarkerArray(
1903 $content,
1904 $markers,
1905 '###|###',
1906 TRUE,
1907 FALSE
1908 );
1909 // Add the content to the message array
1910 $this->message($headCode, 'Statistics', $content, 1);
1911
1912 // Output the page
1913 $this->output($this->outputWrapper($this->printAll()));
1914 }
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928 /*******************************
1929 *
1930 * CONFIGURATION FORM
1931 *
1932 ********************************/
1933
1934 /**
1935 * Creating the form for editing the TYPO3_CONF_VARS options.
1936 *
1937 * @param string $type If get_form, display form, otherwise checks and store in localconf.php
1938 * @return void
1939 */
1940 function generateConfigForm($type='') {
1941 $default_config_content = t3lib_div::getUrl(PATH_site . t3lib_Configuration::DEFAULT_CONFIGURATION_FILE);
1942 $commentArr = $this->getDefaultConfigArrayComments($default_config_content);
1943
1944 switch($type) {
1945 case 'get_form':
1946 // Get the template file
1947 $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'GenerateConfigForm.html');
1948 // Get the template part from the file
1949 $template = t3lib_parsehtml::getSubpart($templateFile, '###TEMPLATE###');
1950
1951 foreach ($GLOBALS['TYPO3_CONF_VARS'] as $k => $va) {
1952 $ext='['.$k.']';
1953 $this->message($ext, '$TYPO3_CONF_VARS[\''.$k.'\']', $commentArr[0][$k], 1);
1954
1955 foreach ($va as $vk => $value) {
1956 if (isset($GLOBALS['TYPO3_CONF_VARS_extensionAdded'][$k][$vk])) {
1957 // Don't allow editing stuff which is added by extensions
1958 // Make sure we fix potentially duplicated entries from older setups
1959 $potentialValue = str_replace(array("'.chr(10).'", "' . LF . '"), array(LF, LF), $value);
1960 while (preg_match('/' . preg_quote($GLOBALS['TYPO3_CONF_VARS_extensionAdded'][$k][$vk], '/') . '$/', '', $potentialValue)) {
1961 $potentialValue = preg_replace(
1962 '/' . preg_quote($GLOBALS['TYPO3_CONF_VARS_extensionAdded'][$k][$vk], '/') . '$/',
1963 '',
1964 $potentialValue
1965 );
1966 }
1967 $value = $potentialValue;
1968 }
1969 $textAreaSubpart = '';
1970 $booleanSubpart = '';
1971 $textLineSubpart = '';
1972
1973 $description = trim($commentArr[1][$k][$vk]);
1974 $isTextarea = preg_match('/^(<.*?>)?string \(textarea\)/i', $description) ? TRUE : FALSE;
1975 $doNotRender = preg_match('/^(<.*?>)?string \(exclude\)/i', $description) ? TRUE : FALSE;
1976
1977 if (!is_array($value) && !$doNotRender && ($this->checkForBadString($value) || $isTextarea)) {
1978 $k2 = '['.$vk.']';
1979
1980 if ($isTextarea) {
1981 // Get the subpart for a textarea
1982 $textAreaSubpart = t3lib_parsehtml::getSubpart($template, '###TEXTAREA###');
1983 // Define the markers content
1984 $textAreaMarkers = array(
1985 'id' => $k . '-' . $vk,
1986 'name' => 'TYPO3_INSTALL[extConfig]['.$k.']['.$vk.']',
1987 'value' => str_replace(array("'.chr(10).'", "' . LF . '"), array(LF, LF), $value)
1988 );
1989 $value = str_replace(array("'.chr(10).'", "' . LF . '"), array(' | ', ' | '), $value);
1990 // Fill the markers in the subpart
1991 $textAreaSubpart = t3lib_parsehtml::substituteMarkerArray(
1992 $textAreaSubpart,
1993 $textAreaMarkers,
1994 '###|###',
1995 TRUE,
1996 FALSE
1997 );
1998 } elseif (preg_match('/^(<.*?>)?boolean/i', $description)) {
1999 // Get the subpart for a checkbox
2000 $booleanSubpart = t3lib_parsehtml::getSubpart($template, '###BOOLEAN###');
2001 // Define the markers content
2002 $booleanMarkers = array(
2003 'id' => $k . '-' . $vk,
2004 'name' => 'TYPO3_INSTALL[extConfig]['.$k.']['.$vk.']',
2005 'value' => $value && strcmp($value, '0') ? $value : 1,
2006 'checked' => $value ? 'checked="checked"' : ''
2007 );
2008 // Fill the markers in the subpart
2009 $booleanSubpart = t3lib_parsehtml::substituteMarkerArray(
2010 $booleanSubpart,
2011 $booleanMarkers,
2012 '###|###',
2013 TRUE,
2014 FALSE
2015 );
2016 } else {
2017 // Get the subpart for an input text field
2018 $textLineSubpart = t3lib_parsehtml::getSubpart($template, '###TEXTLINE###');
2019 // Define the markers content
2020 $textLineMarkers = array(
2021 'id' => $k . '-' . $vk,
2022 'name' => 'TYPO3_INSTALL[extConfig]['.$k.']['.$vk.']',
2023 'value' => $value
2024 );
2025 // Fill the markers in the subpart
2026 $textLineSubpart = t3lib_parsehtml::substituteMarkerArray(
2027 $textLineSubpart,
2028 $textLineMarkers,
2029 '###|###',
2030 TRUE,
2031 FALSE
2032 );
2033 }
2034 // Substitute the subpart for a textarea
2035 $content = t3lib_parsehtml::substituteSubpart(
2036 $template,
2037 '###TEXTAREA###',
2038 $textAreaSubpart
2039 );
2040 // Substitute the subpart for a checkbox
2041 $content = t3lib_parsehtml::substituteSubpart(
2042 $content,
2043 '###BOOLEAN###',
2044 $booleanSubpart
2045 );
2046 // Substitute the subpart for an input text field
2047 $content = t3lib_parsehtml::substituteSubpart(
2048 $content,
2049 '###TEXTLINE###',
2050 $textLineSubpart
2051 );
2052 // Define the markers content
2053 $markers = array(
2054 'description' => $description,
2055 'key' => '[' . $k . '][' . $vk . ']',
2056 'label' => htmlspecialchars(t3lib_div::fixed_lgd_cs($value, 40))
2057 );
2058 // Fill the markers
2059 $content = t3lib_parsehtml::substituteMarkerArray(
2060 $content,
2061 $markers,
2062 '###|###',
2063 TRUE,
2064 FALSE
2065 );
2066 // Add the content to the message array
2067 $this->message($ext, $k2, $content);
2068 }
2069 }
2070 }
2071 break;
2072 default:
2073 if (is_array($this->INSTALL['extConfig'])) {
2074
2075 $configurationPathValuePairs = array();
2076
2077 foreach ($this->INSTALL['extConfig'] as $k => $va) {
2078 if (is_array($GLOBALS['TYPO3_CONF_VARS'][$k])) {
2079 foreach ($va as $vk => $value) {
2080 if (isset($GLOBALS['TYPO3_CONF_VARS'][$k][$vk])) {
2081 $doit=1;
2082 if ($k=='BE' && $vk=='installToolPassword') {
2083 if ($value) {
2084 if (isset($_POST['installToolPassword_check'])) {
2085 if (!$this->formProtection->validateToken(
2086 (string) $_POST['formToken'],
2087 'installToolPassword',
2088 'change'
2089 )) {
2090 $doit = FALSE;
2091 break;
2092 }
2093
2094 if (!t3lib_div::_GP('installToolPassword_check')
2095 || strcmp(t3lib_div::_GP('installToolPassword_check'), $value)
2096 ) {
2097 $doit = FALSE;
2098 $this->errorMessages[]
2099 = 'The two passwords did not ' .
2100 'match! The password was not changed.';
2101 }
2102 }
2103 if (t3lib_div::_GP('installToolPassword_md5')) {
2104 $value =md5($value);
2105 }
2106 } else {
2107 $doit=0;
2108 }
2109 }
2110
2111 $description = trim($commentArr[1][$k][$vk]);
2112 if (preg_match('/^string \(textarea\)/i', $description)) {
2113 // Force Unix linebreaks in textareas
2114 $value = str_replace(CR, '', $value);
2115 // Preserve linebreaks
2116 $value = str_replace(LF, "' . LF . '", $value);
2117 }
2118 if (preg_match('/^boolean/i', $description)) {
2119 // When submitting settings in the Install Tool, values that default to "FALSE" or "TRUE"
2120 // in t3lib/stddb/DefaultConfiguration.php will be sent as "0" resp. "1". Therefore, reset the values
2121 // to their boolean equivalent.
2122 if ($GLOBALS['TYPO3_CONF_VARS'][$k][$vk] === FALSE && $value === '0') {
2123 $value = FALSE;
2124 } elseif ($GLOBALS['TYPO3_CONF_VARS'][$k][$vk] === TRUE && $value === '1') {
2125 $value = TRUE;
2126 }
2127 }
2128
2129 if ($doit && strcmp($GLOBALS['TYPO3_CONF_VARS'][$k][$vk], $value)) {
2130 $configurationPathValuePairs['"' . $k . '"' . '/' . '"' . $vk . '"'] = $value;
2131 }
2132 }
2133 }
2134 }
2135 }
2136 $this->setLocalConfigurationValues($configurationPathValuePairs);
2137 }
2138 break;
2139 }
2140 }
2141
2142 /**
2143 * Make an array of the comments in the t3lib/stddb/DefaultConfiguration.php file
2144 *
2145 * @param string $string The contents of the t3lib/stddb/DefaultConfiguration.php file
2146 * @param array $mainArray
2147 * @param array $commentArray
2148 * @return array
2149 */
2150 function getDefaultConfigArrayComments($string, $mainArray=array(), $commentArray=array()) {
2151 $lines = explode(LF, $string);
2152 $in=0;
2153 $mainKey='';
2154 foreach ($lines as $lc) {
2155 $lc = trim($lc);
2156 if ($in) {
2157 if (!strcmp($lc, ');')) {
2158 $in=0;
2159 } else {
2160 if (preg_match('/["\']([[:alnum:]_-]*)["\'][[:space:]]*=>(.*)/i', $lc, $reg)) {
2161 preg_match('/,[\t\s]*\/\/(.*)/i', $reg[2], $creg);
2162 $theComment = trim($creg[1]);
2163 if (substr(strtolower(trim($reg[2])), 0, 5)=='array' && !strcmp($reg[1], strtoupper($reg[1]))) {
2164 $mainKey=trim($reg[1]);
2165 $mainArray[$mainKey]=$theComment;
2166 } elseif ($mainKey) {
2167 $commentArray[$mainKey][$reg[1]]=$theComment;
2168 }
2169 }
2170 }
2171 }
2172 if (!strcmp($lc, 'return array(')) {
2173 $in=1;
2174 }
2175 }
2176 return array($mainArray, $commentArray);
2177 }
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191 /*******************************
2192 *
2193 * CHECK CONFIGURATION FUNCTIONS
2194 *
2195 *******************************/
2196
2197 /**
2198 * Checking php.ini configuration and set appropriate messages and flags.
2199 *
2200 * @return void
2201 */
2202 function checkConfiguration() {
2203 $ext='php.ini configuration checked';
2204 $this->message($ext);
2205
2206 // *****************
2207 // Incoming values:
2208 // *****************
2209
2210 // Includepath
2211 $incPaths = t3lib_div::trimExplode(TYPO3_OS=='WIN'?';':':', ini_get('include_path'));
2212 if (!in_array('.', $incPaths)) {
2213 $this->message($ext, 'Current directory (./) is not in include path!', '
2214 <p>
2215 <em>include_path=' . ini_get('include_path') . '</em>
2216 <br />
2217 Normally the current path, \'.\', is included in the
2218 include_path of PHP. Although TYPO3 does not rely on this,
2219 it is an unusual setting that may introduce problems for
2220 some extensions.
2221 </p>
2222 ', 1);
2223 } else {
2224 $this->message($ext, 'Current directory in include path', '', -1);
2225 }
2226
2227 // *****************
2228 // File uploads
2229 // *****************
2230 if (!ini_get('file_uploads')) {
2231 $this->message($ext, 'File uploads not allowed', '
2232 <p>
2233 <em>file_uploads=' . ini_get('file_uploads') . '</em>
2234 <br />
2235 TYPO3 uses the ability to upload files from the browser in
2236 various cases.
2237 <br />
2238 As long as this flag is disabled, you\'ll not be able to
2239 upload files.
2240 <br />
2241 But it doesn\'t end here, because not only are files not
2242 accepted by the server - ALL content in the forms are
2243 discarded and therefore nothing at all will be editable
2244 if you don\'t set this flag!
2245 <br />
2246 However if you cannot enable fileupload for some reason
2247 alternatively you change the default form encoding value
2248 with \$TYPO3_CONF_VARS[SYS][form_enctype].
2249 </p>
2250 ', 3);
2251 } else {
2252 $this->message($ext, 'File uploads allowed', '', -1);
2253 }
2254
2255 $upload_max_filesize = t3lib_div::getBytesFromSizeMeasurement(ini_get('upload_max_filesize'));
2256 $post_max_size = t3lib_div::getBytesFromSizeMeasurement(ini_get('post_max_size'));
2257 if ($upload_max_filesize<1024*1024*10) {
2258 $this->message($ext, 'Maximum upload filesize too small?', '
2259 <p>
2260 <em>upload_max_filesize=' . ini_get('upload_max_filesize') . '</em>
2261 <br />
2262 By default TYPO3 supports uploading, copying and moving
2263 files of sizes up to 10MB (You can alter the TYPO3 defaults
2264 by the config option TYPO3_CONF_VARS[BE][maxFileSize]).
2265 <br />
2266 Your current value is below this, so at this point, PHP sets
2267 the limits for uploaded filesizes and not TYPO3.
2268 <br />
2269 <strong>Notice:</strong> The limits for filesizes attached
2270 to database records are set in the tables.php configuration
2271 files (\$TCA) for each group/file field. You may override
2272 these values in the local configuration or by page TSconfig settings.
2273 </p>
2274 ', 1);
2275 }
2276 if ($upload_max_filesize > $post_max_size) {
2277 $this->message($ext, 'Maximum size for POST requests is smaller than max. upload filesize', '
2278 <p>
2279 <em>upload_max_filesize=' . ini_get('upload_max_filesize') . '
2280 , post_max_size=' . ini_get('post_max_size') . '</em>
2281 <br />
2282 You have defined a maximum size for file uploads which
2283 exceeds the allowed size for POST requests. Therefore the
2284 file uploads can not be larger than ' . ini_get('post_max_size') . '
2285 </p>
2286 ', 1);
2287 }
2288
2289 // *****************
2290 // Memory and functions
2291 // *****************
2292 $memory_limit_value = t3lib_div::getBytesFromSizeMeasurement(ini_get('memory_limit'));
2293
2294 if ($memory_limit_value <= 0) {
2295 $this->message(
2296 $ext,
2297 'Unlimited memory limit!',
2298 '<p>Your webserver is configured to not limit PHP memory usage at all. This is a risk
2299 and should be avoided in production setup. In general it\'s best practice to limit this
2300 in the configuration of your webserver. To be safe, ask the system administrator of the
2301 webserver to raise the limit to something over ' . TYPO3_REQUIREMENTS_MINIMUM_PHP_MEMORY_LIMIT .
2302 '.</p>',
2303 2
2304 );
2305 } elseif ($memory_limit_value < t3lib_div::getBytesFromSizeMeasurement(TYPO3_REQUIREMENTS_MINIMUM_PHP_MEMORY_LIMIT)) {
2306 $this->message($ext, 'Memory limit below ' . TYPO3_REQUIREMENTS_MINIMUM_PHP_MEMORY_LIMIT, '
2307 <p>
2308 <em>memory_limit=' . ini_get('memory_limit') . '</em>
2309 <br />
2310 Your system is configured to enforce a memory limit of PHP
2311 scripts lower than ' . TYPO3_REQUIREMENTS_MINIMUM_PHP_MEMORY_LIMIT . '.
2312 The Extension Manager needs to include more PHP-classes than
2313 will fit into this memory space. There is nothing else to do
2314 than raise the limit. To be safe, ask the system
2315 administrator of the webserver to raise the limit to over
2316 ' . TYPO3_REQUIREMENTS_MINIMUM_PHP_MEMORY_LIMIT . '.
2317 </p>
2318 ', 3);
2319 } else {
2320 $this->message($ext, 'Memory limit: ' . ini_get('memory_limit'), '', -1);
2321 }
2322
2323 if (ini_get('max_execution_time')<30) {
2324 $this->message($ext, 'Maximum execution time below 30 seconds', '
2325 <p>
2326 <em>max_execution_time=' . ini_get('max_execution_time') . '</em>
2327 <br />
2328 May impose problems if too low.
2329 </p>
2330 ', 1);
2331 } else {
2332 $this->message($ext, 'Maximum execution time: ' . ini_get('max_execution_time') . ' seconds', '', -1);
2333 }
2334 if (ini_get('disable_functions')) {
2335 $this->message($ext, 'Functions disabled!', '
2336 <p>
2337 <em>disable_functions=' . ini_get('disable_functions') . '</em>
2338 <br />
2339 The above list of functions are disabled. If TYPO3 use any
2340 of these there might be trouble.
2341 <br />
2342 TYPO3 is designed to use the default set of PHP4.3.0+
2343 functions plus the functions of GDLib.
2344 <br />
2345 Possibly these functions are disabled due to security risks
2346 and most likely the list would include a function like
2347 <em>exec()</em> which is use by TYPO3 to access ImageMagick.
2348 </p>
2349 ', 2);
2350 } else {
2351 $this->message($ext, 'Functions disabled: none', '', -1);
2352 }
2353 // Mail tests
2354 if (TYPO3_OS == 'WIN') {
2355 $smtp = ini_get('SMTP');
2356 $bad_smtp = FALSE;
2357 if (!t3lib_div::validIP($smtp)) {
2358 $smtp_addr = @gethostbyname($smtp);
2359 $bad_smtp = ($smtp_addr == $smtp);
2360 }
2361 else {
2362 $smtp_addr = $smtp;
2363 }
2364 if (!$smtp || $bad_smtp || !t3lib_utility_Math::canBeInterpretedAsInteger(ini_get('smtp_port'))) {
2365 $this->message($ext, 'Mail configuration is not set correctly', '
2366 <p>
2367 Mail configuration is not set
2368 <br />
2369 PHP mail() function requires SMTP and smtp_port to have
2370 correct values on Windows.
2371 </p>
2372 ', 2);
2373 } else {
2374 if (($smtp_addr == '127.0.0.1' || $smtp_addr == '::1') && ($_SERVER['SERVER_ADDR'] == '127.0.0.1' || $_SERVER['SERVER_ADDR'] == '::1')) {
2375 $this->message($ext, 'Mail is configured (potential problem exists!)', '
2376 <p>
2377 <em>SMTP=' . $smtp . '</em> - <strong>Note:</strong>
2378 this server! Are you sure it runs SMTP server?
2379 <br />
2380 <em>smtp_port=' . ini_get('smtp_port') . '</em>
2381 </p>' . $this->check_mail('get_form') . '
2382 ', 1);
2383 } else {
2384 $this->message($ext, 'Mail is configured', '
2385 <p>
2386 <em>SMTP=' . $smtp . '</em>
2387 <br />
2388 <em>smtp_port=' . ini_get('smtp_port') . '</em>
2389 </p>' . $this->check_mail('get_form') .'
2390 ', -1);
2391 }
2392 }
2393 } elseif (!ini_get('sendmail_path')) {
2394 $this->message($ext, 'Sendmail path not defined!', '
2395 <p>
2396 This may be critical to TYPO3\'s use of the mail() function.
2397 Please be sure that the mail() function in your
2398 php-installation works!
2399 </p>' . $this->check_mail('get_form') . '
2400 ', 1);
2401 } else {
2402 list($prg) = explode(' ', ini_get('sendmail_path'));
2403 if (!@is_executable($prg)) {
2404 $this->message($ext, 'Sendmail program not found or not executable?', '
2405 <p>
2406 <em>sendmail_path=' . ini_get('sendmail_path') . '</em>
2407 <br />
2408 This may be critical to TYPO3\'s use of the mail()
2409 function. Please be sure that the mail() function in
2410 your php-installation works!
2411 </p>' . $this->check_mail('get_form') .'
2412 ', 1);
2413 } else {
2414 $this->message($ext, 'Sendmail OK', '
2415 <p>
2416 <em>sendmail_path=' . ini_get('sendmail_path') . '</em>
2417 </p>' . $this->check_mail('get_form') . '
2418 ', -1);
2419 }
2420 }
2421
2422 // *****************
2423 // Safe mode related
2424 // *****************
2425 if (t3lib_utility_PhpOptions::isSafeModeEnabled()) {
2426 $this->message($ext, 'Safe mode turned on', '
2427 <p>
2428 <em>safe_mode=' . ini_get('safe_mode') . '</em>
2429 <br />
2430 In safe_mode PHP is restricted in several ways. This is a
2431 good thing because it adds protection to your (and others)
2432 scripts. But it may also introduce problems. In TYPO3 this
2433 <em>may be</em> a problem in two areas: File administration
2434 and execution of external programs, in particular
2435 ImageMagick.
2436 <br />
2437 If you just ignore this warning, you\'ll most likely find,
2438 that TYPO3 seems to work except from the image-generation.
2439 The problem in that case is that the external ImageMagick
2440 programs are not allowed to be executed from the regular
2441 paths like "/usr/bin/" or "/usr/X11R6/bin/".
2442 <br />
2443 If you use safe_mode with TYPO3, you should disable use of
2444 external programs ([BE][disable_exec_function]=1).
2445 <br />
2446 In safe mode you must ensure that all the php-scripts and
2447 upload folders are owned by the same user.
2448 </p>
2449 <p>
2450 <em>safe_mode_exec_dir=' . ini_get('safe_mode_exec_dir') . '</em>
2451 <br />
2452 If the ImageMagick utilities are located in this directory,
2453 everything is fine. Below on this page, you can see if
2454 ImageMagick is found here. If not, ask you ISP to put the
2455 three ImageMagick programs, \'convert\',
2456 \'combine\'/\'composite\' and \'identify\' there (eg. with
2457 symlinks if Unix server)
2458 </p>
2459 <p>
2460 <strong>Example of safe_mode settings:</strong>
2461 <br />
2462 Set this in the php.ini file:
2463 </p>
2464 <p>
2465 ; Safe Mode
2466 <br />
2467 safe_mode = On
2468 <br />
2469 safe_mode_exec_dir = /usr/bin/
2470 </p>
2471 <p>
2472 ...and the ImageMagick \'/usr/bin/convert\' will be
2473 executable.
2474 <br />
2475 The last slash is important (..../) and you can only specify
2476 one directory.
2477 </p>
2478 <p>
2479 <strong>Notice: </strong>
2480 <br />
2481 ImageMagick 6 or GraphicsMagick is recommended and the binaries are
2482 normally installed in /usr/bin.
2483 <br />
2484 Paths to ImageMagick are defined in local configuration and may be
2485 something else than /usr/bin/, but this is default for
2486 ImageMagick 6+
2487 </p>
2488 ', 2);
2489 if (ini_get('doc_root')) {
2490 $this->message($ext, 'doc_root set', '
2491 <p>
2492 <em>doc_root=' . ini_get('doc_root') . '</em>
2493 <br />
2494 PHP cannot execute scripts outside this directory. If
2495 that is a problem is please correct it.
2496 </p>
2497 ', 1);
2498 }
2499 $this->config_array['safemode']=1;
2500 } else {
2501 $this->message($ext, 'safe_mode: off', '', -1);
2502 }
2503 if (t3lib_utility_PhpOptions::isSqlSafeModeEnabled()) {
2504 $this->message($ext, 'sql.safe_mode is enabled', '
2505 <p>
2506 <em>sql.safe_mode=' . ini_get('sql.safe_mode') . '</em>
2507 <br />
2508 This means that you can only connect to the database with a
2509 username corresponding to the user of the webserver process
2510 or fileowner. Consult your ISP for information about this.
2511 Also see <a href="http://www.wrox.com/Consumer/Store/Books/2963/29632002.htm">
2512 http://www.wrox.com/Consumer/Store/Books/2963/29632002.htm</a>
2513 <br />
2514 The owner of the current file is:
2515 <strong>' . get_current_user () . '</strong>
2516 </p>
2517 ', 1);
2518 $this->config_array['sql.safe_mode_user'] = get_current_user();
2519 } else {
2520 $this->message($ext, 'sql.safe_mode: off', '', -1);
2521 }
2522 if (ini_get('open_basedir')) {
2523 $this->message($ext, 'open_basedir set', '
2524 <p>
2525 <em>open_basedir=' . ini_get('open_basedir') . '</em>
2526 <br />
2527 This restricts TYPO3 to open and include files only in this
2528 path. Please make sure that this does not prevent TYPO3 from
2529 running.
2530 <br />
2531 <strong>Notice (UNIX):</strong> Before checking a path
2532 according to open_basedir, PHP resolves all symbolic links.
2533 </p>
2534 ', 1);
2535 // ???? If this option was set falsely you probably didn't see this page in the
2536 // first place, but this option <strong>may spoil this configuration test</strong>
2537 // when checking for such as ImageMagick executables.
2538 } else {
2539 $this->message($ext, 'open_basedir: off', '', -1);
2540 }
2541
2542 // Check availability of PHP session support
2543 if (extension_loaded('session')) {
2544 $this->message($ext, 'PHP sessions available', '
2545 <p>
2546 <em>PHP Sessions available</em>
2547 <br />
2548 PHP is compiled with session support and session support is
2549 available.
2550 </p>
2551 ', -1);
2552 } else {
2553 $this->message($ext, 'PHP Sessions not available', '
2554 <p>
2555 PHP is not compiled with session support, or session support
2556 is disabled in php.ini.
2557 <br />
2558 TYPO3 needs session support.
2559 </p>
2560 ', 3);
2561 }
2562
2563 // Suhosin/Hardened PHP:
2564 $suhosinDescription = '
2565 <p>
2566 Suhosin limits the number of elements that can be submitted in
2567 forms to the server. This will affect for example the
2568 "All configuration" section in the Install Tool or Inline
2569 Relational Record Editing (IRRE) with many child records.
2570 </p>';
2571 if (extension_loaded('suhosin')) {
2572 $suhosinSuggestion = '
2573 <p>
2574 At least a value of 400 is suggested.
2575 </p>
2576 ';
2577
2578 $suhosinRequestMaxVars = ini_get('suhosin.request.max_vars');
2579 $suhosinPostMaxVars = ini_get('suhosin.post.max_vars');
2580 $suhosinRequestMaxVarsType = ($suhosinRequestMaxVars < 400 ? 2 : -1);
2581 $suhosinPostMaxVarsType = ($suhosinPostMaxVars < 400 ? 2 : -1);
2582 $suhosinType = ($suhosinRequestMaxVars < 400 || $suhosinPostMaxVars < 400 ? 2 : -1);
2583
2584 $this->message($ext, 'Suhosin/Hardened PHP is loaded', $suhosinDescription, $suhosinType);
2585 $this->message($ext, 'suhosin.request.max_vars: ' . $suhosinRequestMaxVars, $suhosinSuggestion, $suhosinRequestMaxVarsType);
2586 $this->message($ext, 'suhosin.post.max_vars: ' . $suhosinPostMaxVars, $suhosinSuggestion, $suhosinPostMaxVarsType);
2587 } else {
2588 $this->message($ext, 'Suhosin/Hardened PHP is not loaded', $suhosinDescription, 0);
2589 }
2590
2591 // Check for stripped PHPdoc comments that are required to evaluate annotations:
2592 $method = new ReflectionMethod('tx_install', 'check_mail');
2593 if (strlen($method->getDocComment()) === 0) {
2594 $description = '
2595 <p>
2596 The system extension Extbase evaluates annotations in PHPdoc
2597 comments and thus requires eAccelerator not to strip away
2598 these parts. However, this is currently the only part in the
2599 TYPO3 Core (beside deprecation log and unit tests). If
2600 Extbase is not used, recompiling eAccelerator is not
2601 required at all.
2602 <br/>
2603 <br/>
2604 If you do not want comments to be stripped by eAccelerator,
2605 please recompile with the following configuration setting
2606 (<a href="http://eaccelerator.net/ticket/229" target="_blank">
2607 more details</a>):
2608 <br />
2609 <em>--with-eaccelerator-doc-comment-inclusion</em>
2610 </p>
2611 ';
2612 $this->message($ext, 'PHPdoc comments are stripped', $description, 2);
2613 }
2614 }
2615
2616 /**
2617 * Check if PHP function mail() works
2618 *
2619 * @param string $cmd If "get_form" then a formfield for the mail-address is shown. If not, it's checked if "check_mail" was in the INSTALL array and if so a test mail is sent to the recipient given.
2620 * @return string The mail form if it is requested with get_form
2621 */
2622 function check_mail($cmd='') {
2623 switch($cmd) {
2624 case 'get_form':
2625 $out = '
2626 <p id="checkMailForm">
2627 You can check the t3lib_mail functionality by entering your email
2628 address here and press the button. You should then
2629 receive a testmail from "typo3installtool@example.org".
2630 </p>
2631 ';
2632 // Get the template file
2633 $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'CheckMail.html');
2634 // Get the template part from the file
2635 $template = t3lib_parsehtml::getSubpart($templateFile, '###TEMPLATE###');
2636
2637 if (!empty($this->mailMessage)) {
2638 // Get the subpart for the mail is sent message
2639 $mailSentSubpart = t3lib_parsehtml::getSubpart($template, '###MAILSENT###');
2640 }
2641 $template = t3lib_parsehtml::substituteSubpart(
2642 $template,
2643 '###MAILSENT###',
2644 $mailSentSubpart
2645 );
2646 // Define the markers content
2647 $markers = array(
2648 'message' => $this->mailMessage,
2649 'enterEmail' => 'Enter the email address',
2650 'actionUrl' => $this->action . '#checkMailForm',
2651 'submit' => 'Send test mail'
2652 );
2653 // Fill the markers
2654 $out .= t3lib_parsehtml::substituteMarkerArray(
2655 $template,
2656 $markers,
2657 '###|###',
2658 TRUE,
2659 TRUE
2660 );
2661 break;
2662 default:
2663 if (trim($this->INSTALL['check_mail'])) {
2664 $subject = 'TEST SUBJECT';
2665 $email = trim($this->INSTALL['check_mail']);
2666
2667 /** @var $mailMessage t3lib_mail_Message */
2668 $mailMessage = t3lib_div::makeInstance('t3lib_mail_Message');
2669 $mailMessage->addTo($email)
2670 ->addFrom('typo3installtool@example.org', 'TYPO3 Install Tool')
2671 ->setSubject($subject)
2672 ->setBody('<html><body>HTML TEST CONTENT</body></html>');
2673 $mailMessage->addPart('TEST CONTENT');
2674 $mailMessage->send();
2675 $this->mailMessage= 'Mail was sent to: ' . $email;
2676 }
2677 break;
2678 }
2679 return $out;
2680 }
2681
2682 /**
2683 * Checking php extensions, specifically GDLib and Freetype
2684 *
2685 * @return void
2686 */
2687 function checkExtensions() {
2688 $ext = 'GDLib';
2689 $this->message($ext);
2690
2691 $software_info=1;
2692 if (extension_loaded('gd') && $this->isGD()) {
2693 $this->config_array['gd']=1;
2694 $this->message($ext, 'GDLib found', '', -1);
2695 if ($this->isPNG()) {
2696 $this->config_array['gd_png']=1;
2697 $this->message($ext, 'PNG supported', '', -1);
2698 }
2699 if ($this->isGIF()) {
2700 $this->config_array['gd_gif']=1;
2701 $this->message($ext, 'GIF supported', '', -1);
2702 }
2703 if ($this->isJPG()) {
2704 $this->config_array['gd_jpg']=1;
2705 $this->message($ext, 'JPG supported (not used by TYPO3)', '');
2706 }
2707 if (!$this->config_array['gd_gif'] && !$this->config_array['gd_png']) {
2708 $this->message($ext, 'PNG or GIF not supported', '
2709 <p>
2710 Your GDLib supports either GIF nor PNG. It must support
2711 either one of them.
2712 </p>
2713 ', 2);
2714 } else {
2715 $msg=array();
2716 if ($this->config_array['gd_gif'] && $this->config_array['gd_png']) {
2717 $msg[] = '
2718 <p>
2719 You can choose between generating GIF or PNG files,
2720 as your GDLib supports both.
2721 </p>
2722 ';
2723 }
2724 if ($this->config_array['gd_gif']) {
2725 $msg[] = '
2726 <p>
2727 You should watch out for the generated size of the
2728 GIF-files because some versions of the GD library do
2729 not compress them with LZW, but RLE and ImageMagick
2730 is subsequently used to compress with LZW. But in
2731 the case of ImageMagick failing this task (eg. not
2732 being compiled with LZW which is the case with some
2733 versions) you\'ll end up with GIF-filesizes all too
2734 big!
2735 <br />
2736 This Install Tool tests what kinds of GIF
2737 compression are available in the ImageMagick
2738 installations by a physical test. You can also check
2739 it manually by opening a TYPO3 generated gif-file
2740 with Photoshop and save it in a new file. If the
2741 file sizes of the original and the new file are
2742 almost the same, you\'re having LZW compression and
2743 everything is fine.
2744 </p>
2745 ';
2746 }
2747 if ($this->config_array['gd_png']) {
2748 $msg[] = '
2749 <p>
2750 TYPO3 prefers the use of GIF-files and most likely
2751 your visitors on your website does too as not all
2752 browsers support PNG yet.
2753 </p>
2754 ';
2755 }
2756 $this->message($ext, 'GIF / PNG issues', implode(LF, $msg), 1);
2757 }
2758 if (!$this->isTTF()) {
2759 $this->message($ext, 'FreeType is apparently not installed', '
2760 <p>
2761 It looks like the FreeType library is not compiled into
2762 GDLib. This is required when TYPO3 uses GDLib and
2763 you\'ll most likely get errors like \'ImageTTFBBox is
2764 not a function\' or \'ImageTTFText is not a function\'.
2765 </p>
2766 ', 2);
2767 } else {
2768 $this->message($ext, 'FreeType quick-test (' . ($this->isGIF() ? 'as GIF' : 'as PNG') . ')', '
2769 <p>
2770 <img src="' . htmlspecialchars(t3lib_div::getIndpEnv('REQUEST_URI') . '&testingTrueTypeSupport=1') . '" alt="" />
2771 <br />
2772 (If the text is exceeding the image borders you are
2773 using Freetype 2 and need to set
2774 TYPO3_CONF_VARS[GFX][TTFdpi]=96.
2775 <br />
2776 If there is no image at all Freetype is most likely NOT
2777 available and you can just as well disable GDlib for
2778 TYPO3...)
2779 </p>
2780 ', -1);
2781 $this->config_array['freetype']=1;
2782 }
2783 } else {
2784 $this->message($ext, 'GDLib2 not found', '
2785 <p>
2786 GDLib2 is required if you want to use the GIFBUILDER object
2787 in TypoScript. GIFBUILDER is in charge of all advanced image
2788 generation in TypoScript, including graphical menuitems.
2789 <br />
2790 GDLib2 is also used in the TYPO3 Backend (TBE) to generate
2791 record icons and new module tabs.
2792 <br />
2793 It\'s highly recommended to install this library. Remember
2794 to compile GD with FreeType which is also required.
2795 <br />
2796 If you choose not to install GDLib, you can disable it in
2797 the configuration with [GFX][gdlib]=0;.
2798 </p>
2799 ', 2);
2800 }
2801 $this->message($ext, 'GDLib software information', $this->getGDSoftwareInfo());
2802 }
2803
2804 /**
2805 * Checking and testing that the required writable directories are writable.
2806 *
2807 * @return void
2808 */
2809 function checkDirs() {
2810 // Check typo3/temp/
2811 $ext='Directories';
2812 $this->message($ext);
2813
2814 $uniqueName = md5(uniqid(microtime()));
2815
2816 // The requirement level (the integer value, ie. the second value of the value array) has the following meanings:
2817 // -1 = not required, but if it exists may be writable or not
2818 // 0 = not required, if it exists the dir should be writable
2819 // 1 = required, don't has to be writable
2820 // 2 = required, has to be writable
2821
2822 $checkWrite=array(
2823 'typo3temp/' => array('This folder is used by both the frontend (FE) and backend (BE) interface for all kind of temporary and cached files.', 2, 'dir_typo3temp'),
2824 'typo3temp/pics/' => array('This folder is part of the typo3temp/ section. It needs to be writable, too.', 2, 'dir_typo3temp'),
2825 'typo3temp/temp/' => array('This folder is part of the typo3temp/ section. It needs to be writable, too.', 2, 'dir_typo3temp'),
2826 'typo3temp/llxml/' => array('This folder is part of the typo3temp/ section. It needs to be writable, too.', 2, 'dir_typo3temp'),
2827 'typo3temp/cs/' => array('This folder is part of the typo3temp/ section. It needs to be writable, too.', 2, 'dir_typo3temp'),
2828 'typo3temp/GB/' => array('This folder is part of the typo3temp/ section. It needs to be writable, too.', 2, 'dir_typo3temp'),
2829 'typo3temp/locks/' => array('This folder is part of the typo3temp/ section. It needs to be writable, too.', 2, 'dir_typo3temp'),
2830 'typo3conf/' => array('This directory contains the local configuration files of your website. TYPO3 must be able to write to these configuration files during setup and when the Extension Manager (EM) installs extensions.', 2),
2831 'typo3conf/ext/' => array('Location for local extensions. Must be writable if the Extension Manager is supposed to install extensions for this website.', 0),
2832 'typo3conf/l10n/' => array('Location for translations. Must be writable if the Extension Manager is supposed to install translations for extensions.', 0),
2833 TYPO3_mainDir.'ext/' => array('Location for global extensions. Must be writable if the Extension Manager is supposed to install extensions globally in the source.', -1),
2834 'uploads/' => array('Location for uploaded files from RTE, in the subdirectories for uploaded files of content elements.', 2),
2835 'uploads/pics/' => array('Typical location for uploaded files (images especially).', 0),
2836 'uploads/media/' => array('Typical location for uploaded files (non-images especially).', 0),
2837 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileadminDir'] => array('Location for local files such as templates, independent uploads etc.', -1),
2838 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileadminDir'] . '_temp_/' => array('Typical temporary location for default upload of files by administrators.', 0),
2839 );
2840
2841 foreach ($checkWrite as $relpath => $descr) {
2842
2843 // Check typo3temp/
2844 $general_message = $descr[0];
2845
2846 // If the directory is missing, try to create it
2847 if (!@is_dir(PATH_site.$relpath)) {
2848 t3lib_div::mkdir(PATH_site.$relpath);
2849 }
2850
2851 if (!@is_dir(PATH_site.$relpath)) {
2852 if ($descr[1]) { // required...
2853 $this->message($ext, $relpath.' directory does not exist and could not be created', '
2854 <p>
2855 <em>Full path: ' . PATH_site . $relpath . '</em>
2856 <br />
2857 ' . $general_message . '
2858 </p>
2859 <p>
2860 This error should not occur as ' . $relpath . ' must
2861 always be accessible in the root of a TYPO3 website.
2862 </p>
2863 ', 3);
2864 } else {
2865 if ($descr[1] == 0) {
2866 $msg = 'This directory does not necessarily have to exist but if it does it must be writable.';
2867 } else {
2868 $msg = 'This directory does not necessarily have to exist and if it does it can be writable or not.';
2869 }
2870 $this->message($ext, $relpath.' directory does not exist', '
2871 <p>
2872 <em>Full path: ' . PATH_site . $relpath . '</em>
2873 <br />
2874 ' . $general_message . '
2875 </p>
2876 <p>
2877 ' . $msg . '
2878 </p>
2879 ', 2);
2880 }
2881 } else {
2882 $file = PATH_site.$relpath.$uniqueName;
2883 @touch($file);
2884 if (@is_file($file)) {
2885 unlink($file);
2886 if ($descr[2]) { $this->config_array[$descr[2]]=1; }
2887 $this->message($ext, $relpath.' writable', '', -1);
2888 } else {
2889 $severity = ($descr[1]==2 || $descr[1]==0) ? 3 : 2;
2890 if ($descr[1] == 0 || $descr[1] == 2) {
2891 $msg = 'The directory '.$relpath.' must be writable!';
2892 } elseif ($descr[1] == -1 || $descr[1] == 1) {
2893 $msg = 'The directory '.$relpath.' does not necessarily have to be writable.';
2894 }
2895 $this->message($ext, $relpath .' directory not writable', '
2896 <p>
2897 <em>Full path: ' . $file . '</em>
2898 <br />
2899 ' . $general_message . '
2900 </p>
2901 <p>
2902 Tried to write this file (with touch()) but didn\'t
2903 succeed.
2904 <br />
2905 ' . $msg . '
2906 </p>
2907 ', $severity);
2908 }
2909 }
2910 }
2911 }
2912
2913 /**
2914 * Checking for existing ImageMagick installs.
2915 *
2916 * This tries to find available ImageMagick installations and tries to find the version numbers by executing "convert" without parameters. If the ->checkIMlzw is set, LZW capabilities of the IM installs are check also.
2917 *
2918 * @param array $paths Possible ImageMagick paths
2919 * @return void
2920 */
2921 function checkImageMagick($paths) {
2922 $ext='Check Image Magick';
2923 $this->message($ext);
2924 // Get the template file
2925 $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'CheckImageMagick.html');
2926
2927 $paths = array_unique($paths);
2928
2929 $programs = explode(',', 'gm,convert,combine,composite,identify');
2930 $isExt = TYPO3_OS=='WIN' ? '.exe' : '';
2931 $this->config_array['im_combine_filename']='combine';
2932 foreach ($paths as $k => $v) {
2933 if (!preg_match('/[\\/]$/', $v)) {
2934 $v .= '/';
2935 }
2936 foreach ($programs as $filename) {
2937 if (ini_get('open_basedir') || (file_exists($v) && @is_file($v.$filename.$isExt))) {
2938 $version = $this->_checkImageMagick_getVersion($filename, $v);
2939 if($version > 0) {
2940 // Assume GraphicsMagick
2941 if($filename=='gm') {
2942 $index[$v]['gm']=$version;
2943 // No need to check for "identify" etc.
2944 continue;
2945 } else {
2946 // Assume ImageMagick
2947 $index[$v][$filename]=$version;
2948 }
2949 }
2950 }
2951 }
2952 if (count($index[$v])>=3 || $index[$v]['gm']) {
2953 $this->config_array['im'] = 1;
2954 }
2955
2956 if ($index[$v]['gm'] || (!$index[$v]['composite'] && $index[$v]['combine'])) {
2957 $this->config_array['im_combine_filename']='combine';
2958 } elseif ($index[$v]['composite'] && !$index[$v]['combine']) {
2959 $this->config_array['im_combine_filename']='composite';
2960 }
2961
2962 if (isset($index[$v]['convert']) && $this->checkIMlzw) {
2963 $index[$v][