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