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