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