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