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