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