[TASK] Release installation procedure from LocalConfiguration file
[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 There are three primary steps for you to take:
716 </p>
717 <p>
718 <strong>1: Basic Configuration</strong>
719 <br />
720 In this step your PHP-configuration is checked. If
721 there are any settings that will prevent TYPO3 from
722 running correctly you\'ll get warnings and errors
723 with a description of the problem.
724 <br />
725 You\'ll have to enter a database username, password
726 and hostname. Then you can choose to create a new
727 database or select an existing one.
728 <br />
729 Finally the image processing settings are entered
730 and verified and you can choose to let the script
731 update the configuration with the suggested settings.
732 </p>
733 <p>
734 <strong>2: Database Analyser</strong>
735 <br />
736 In this step you can either install a new database
737 or update the database from any previous TYPO3
738 version.
739 <br />
740 You can also get an overview of extra/missing
741 fields/tables in the database compared to a raw
742 sql-file.
743 <br />
744 The database is also verified against your
745 configuration ($TCA) and you can
746 even see suggestions to entries in $TCA or new
747 fields in the database.
748 </p>
749 <p>
750 <strong>3: Upgrade Wizard</strong>
751 <br />
752 Here you will find update methods taking care of
753 changes to the TYPO3 core which are not backwards
754 compatible.
755 <br />
756 It is recommended to run this wizard after every
757 update to make sure everything will still work
758 flawlessly.
759 </p>
760 <p>
761 <strong>4: Image Processing</strong>
762 <br />
763 This step is a visual guide to verify your
764 configuration of the image processing software.
765 <br />
766 You\'ll be presented to a list of images that should
767 all match in pairs. If some irregularity appears,
768 you\'ll get a warning. Thus you\'re able to track an
769 error before you\'ll discover it on your website.
770 </p>
771 <p>
772 <strong>5: All Configuration</strong>
773 <br />
774 This gives you access to any of the configuration
775 options in the TYPO3_CONF_VARS array. Every option
776 is also presented with a comment explaining what it
777 does.
778 </p>
779 <p>
780 <strong>6: Cleanup</strong>
781 <br />
782 Here you can clean up the temporary files in typo3temp/
783 folder and the tables used for caching of data in
784 your database.
785 </p>
786 ');
787
788 $headCode = 'Header legend';
789 $this->message($headCode, 'Notice!', '
790 <p>
791 Indicates that something is important to be aware
792 of.
793 <br />
794 This does <em>not</em> indicate an error.
795 </p>
796 ', 1);
797 $this->message($headCode, 'Just information', '
798 <p>
799 This is a simple message with some information about
800 something.
801 </p>
802 ');
803 $this->message($headCode, 'Check was successful', '
804 <p>
805 Indicates that something was checked and returned an
806 expected result.
807 </p>
808 ', -1);
809 $this->message($headCode, 'Warning!', '
810 <p>
811 Indicates that something may very well cause trouble
812 and you should definitely look into it before
813 proceeding.
814 <br />
815 This indicates a <em>potential</em> error.
816 </p>
817 ', 2);
818 $this->message($headCode, 'Error!', '
819 <p>
820 Indicates that something is definitely wrong and
821 that TYPO3 will most likely not perform as expected
822 if this problem is not solved.
823 <br />
824 This indicates an actual error.
825 </p>
826 ', 3);
827 $this->output($this->outputWrapper($this->printAll()));
828 break;
829 }
830 }
831 }
832
833 /**
834 * Controls the step 1-2-3-go process
835 *
836 * @return string The content to output to the screen
837 * @todo Define visibility
838 */
839 public function stepOutput() {
840 // Get the template file
841 $templateFile = @file_get_contents((PATH_site . $this->templateFilePath . 'StepOutput.html'));
842 // Get the template part from the file
843 $template = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($templateFile, '###TEMPLATE###');
844 // Define the markers content
845 $markers = array(
846 'stepHeader' => $this->stepHeader(),
847 'notice' => 'Skip this wizard (for power users only)',
848 'skip123' => $this->scriptSelf
849 );
850 $this->checkTheConfig();
851 $error_missingConnect = '
852 <p class="typo3-message message-error">
853 <strong>
854 There is no connection to the database!
855 </strong>
856 <br />
857 (Username: <em>' . htmlspecialchars(TYPO3_db_username) . '</em>,
858 Host: <em>' . htmlspecialchars(TYPO3_db_host) . '</em>,
859 Using Password: YES)
860 <br />
861 Go to Step 1 and enter a valid username and password!
862 </p>
863 ';
864 $error_missingDB = '
865 <p class="typo3-message message-error">
866 <strong>
867 There is no access to the database (<em>' . htmlspecialchars(TYPO3_db) . '</em>)!
868 </strong>
869 <br />
870 Go to Step 2 and select a valid database!
871 </p>
872 ';
873 // only get the number of tables if it is not the first two steps in the 123-installer
874 // (= no DB connection yet)
875 $whichTables = $this->step != 1 && $this->step != 2 ? $this->sqlHandler->getListOfTables() : array();
876 $error_emptyDB = '
877 <p class="typo3-message message-error">
878 <strong>
879 The database is still empty. There are no tables!
880 </strong>
881 <br />
882 Go to Step 3 and import a database!
883 </p>
884 ';
885 // Hook to override and add steps to the 1-2-3 installer
886 if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install/mod/class.tx_install.php']['stepOutput'])) {
887 foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install/mod/class.tx_install.php']['stepOutput'] as $classData) {
888 $hookObject = \TYPO3\CMS\Core\Utility\GeneralUtility::getUserObj($classData);
889 $hookObject->executeStepOutput($markers, $this->step, $this);
890 }
891 }
892 // Use the default steps when there is no override
893 if (!$markers['header'] && !$markers['step']) {
894 switch (strtolower($this->step)) {
895 case 1:
896 // Get the subpart for the first step
897 $step1SubPart = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($templateFile, '###STEP1###');
898 // Add header marker for main template
899 $markers['header'] = 'Welcome to the TYPO3 Install Tool';
900 // Define the markers content for the subpart
901 $step1SubPartMarkers = array(
902 'llIntroduction' => '
903 <p>
904 TYPO3 is an enterprise content management system
905 that is powerful, yet easy to install.
906 </p>
907 <p>
908 In three simple steps you\'ll be ready to add content to your website.
909 </p>
910 ',
911 'step' => $this->step + 1,
912 'action' => htmlspecialchars($this->action),
913 'continue' => 'Continue'
914 );
915 // Add step marker for main template
916 $markers['step'] = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($step1SubPart, $step1SubPartMarkers, '###|###', TRUE, FALSE);
917 break;
918 case 2:
919 // Get the subpart for the second step
920 $step2SubPart = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($templateFile, '###STEP2###');
921 // Add header marker for main template
922 $markers['header'] = 'Connect to your database host';
923 // Define the markers content for the subpart
924 $step2SubPartMarkers = array(
925 'step' => $this->step + 1,
926 'action' => htmlspecialchars($this->action),
927 'encryptionKey' => $this->createEncryptionKey(),
928 'branch' => TYPO3_branch,
929 'labelUsername' => 'Username',
930 'username' => htmlspecialchars(TYPO3_db_username),
931 'labelPassword' => 'Password',
932 'password' => htmlspecialchars(TYPO3_db_password),
933 'labelHost' => 'Host',
934 'host' => TYPO3_db_host ? htmlspecialchars(TYPO3_db_host) : 'localhost',
935 'continue' => 'Continue',
936 '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.'
937 );
938 // Add step marker for main template
939 $markers['step'] = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($step2SubPart, $step2SubPartMarkers, '###|###', TRUE, FALSE);
940 break;
941 case 3:
942 // Add header marker for main template
943 $markers['header'] = 'Select database';
944 // There should be a database host connection at this point
945 if ($result = $GLOBALS['TYPO3_DB']->sql_pconnect(TYPO3_db_host, TYPO3_db_username, TYPO3_db_password)) {
946 // Get the subpart for the third step
947 $step3SubPart = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($templateFile, '###STEP3###');
948 // Get the subpart for the database options
949 $step3DatabaseOptionsSubPart = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($step3SubPart, '###DATABASEOPTIONS###');
950 $dbArr = $this->getDatabaseList();
951 $dbIncluded = 0;
952 $step3DatabaseOptions = array();
953 foreach ($dbArr as $dbname) {
954 // Define the markers content for database options
955 $step3DatabaseOptionMarkers = array(
956 'databaseValue' => htmlspecialchars($dbname),
957 'databaseSelected' => $dbname == TYPO3_db ? 'selected="selected"' : '',
958 'databaseName' => htmlspecialchars($dbname)
959 );
960 // Add the option HTML to an array
961 $step3DatabaseOptions[] = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($step3DatabaseOptionsSubPart, $step3DatabaseOptionMarkers, '###|###', TRUE, TRUE);
962 if ($dbname == TYPO3_db) {
963 $dbIncluded = 1;
964 }
965 }
966 if (!$dbIncluded && TYPO3_db) {
967 // // Define the markers content when no access
968 $step3DatabaseOptionMarkers = array(
969 'databaseValue' => htmlspecialchars(TYPO3_db),
970 'databaseSelected' => 'selected="selected"',
971 'databaseName' => htmlspecialchars(TYPO3_db) . ' (NO ACCESS!)'
972 );
973 // Add the option HTML to an array
974 $step3DatabaseOptions[] = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($step3DatabaseOptionsSubPart, $step3DatabaseOptionMarkers, '###|###', TRUE, TRUE);
975 }
976 $usePatternList = FALSE;
977 $createDatabaseAllowed = $this->checkCreateDatabasePrivileges();
978 if ($createDatabaseAllowed === TRUE) {
979 $formFieldAttributesNew = 'checked="checked"';
980 $llRemark1 = 'Enter a name for your TYPO3 database.';
981 } elseif (is_array($createDatabaseAllowed)) {
982 $llRemark1 = 'Enter a name for your TYPO3 database.';
983 $llDbPatternRemark = 'The name has to match one of these names/patterns (% is a wild card):';
984 $llDbPatternList = '<li>' . implode('</li><li>', $createDatabaseAllowed) . '</li>';
985 $usePatternList = TRUE;
986 } else {
987 $formFieldAttributesNew = 'disabled="disabled"';
988 $formFieldAttributesSelect = 'checked="checked"';
989 $llRemark1 = 'You have no permissions to create new databases.';
990 }
991 // Substitute the subpart for the database options
992 $content = \TYPO3\CMS\Core\Html\HtmlParser::substituteSubpart($step3SubPart, '###DATABASEOPTIONS###', implode(LF, $step3DatabaseOptions));
993 if ($usePatternList === FALSE) {
994 $content = \TYPO3\CMS\Core\Html\HtmlParser::substituteSubpart($content, '###DATABASE_NAME_PATTERNS###', '');
995 }
996 // Define the markers content
997 $step3SubPartMarkers = array(
998 'step' => $this->step + 1,
999 'llOptions' => 'You have two options:',
1000 'action' => htmlspecialchars($this->action),
1001 'llOption1' => 'Create a new database (recommended):',
1002 'llRemark1' => $llRemark1,
1003 'll_Db_Pattern_Remark' => $llDbPatternRemark,
1004 'll_Db_Pattern_List' => $llDbPatternList,
1005 'formFieldAttributesNew' => $formFieldAttributesNew,
1006 'formFieldAttributesSelect' => $formFieldAttributesSelect,
1007 'llOption2' => 'Select an EMPTY existing database:',
1008 'llRemark2' => 'Any tables used by TYPO3 will be overwritten.',
1009 'continue' => 'Continue'
1010 );
1011 // Add step marker for main template
1012 $markers['step'] = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($content, $step3SubPartMarkers, '###|###', TRUE, TRUE);
1013 } else {
1014 // Add step marker for main template when no connection
1015 $markers['step'] = $error_missingConnect;
1016 }
1017 break;
1018 case 4:
1019 // Add header marker for main template
1020 $markers['header'] = 'Import the Database Tables';
1021 // There should be a database host connection at this point
1022 if ($result = $GLOBALS['TYPO3_DB']->sql_pconnect(TYPO3_db_host, TYPO3_db_username, TYPO3_db_password)) {
1023 // The selected database should be accessible
1024 if ($GLOBALS['TYPO3_DB']->sql_select_db(TYPO3_db)) {
1025 // Get the subpart for the fourth step
1026 $step4SubPart = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($templateFile, '###STEP4###');
1027 // Get the subpart for the database type options
1028 $step4DatabaseTypeOptionsSubPart = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($step4SubPart, '###DATABASETYPEOPTIONS###');
1029 $sFiles = \TYPO3\CMS\Core\Utility\GeneralUtility::getFilesInDir(PATH_typo3conf, 'sql', 1, 1);
1030 // Check if default database scheme "database.sql" already exists, otherwise create it
1031 if (!strstr((implode(',', $sFiles) . ','), '/database.sql,')) {
1032 array_unshift($sFiles, 'Default TYPO3 Tables');
1033 }
1034 $step4DatabaseTypeOptions = array();
1035 foreach ($sFiles as $f) {
1036 if ($f == 'Default TYPO3 Tables') {
1037 $key = 'CURRENT_TABLES+STATIC';
1038 } else {
1039 $key = htmlspecialchars($f);
1040 }
1041 // Define the markers content for database type subpart
1042 $step4DatabaseTypeOptionMarkers = array(
1043 'databaseTypeValue' => 'import|' . $key,
1044 'databaseName' => htmlspecialchars(basename($f))
1045 );
1046 // Add the option HTML to an array
1047 $step4DatabaseTypeOptions[] = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($step4DatabaseTypeOptionsSubPart, $step4DatabaseTypeOptionMarkers, '###|###', TRUE, FALSE);
1048 }
1049 // Substitute the subpart for the database type options
1050 $content = \TYPO3\CMS\Core\Html\HtmlParser::substituteSubpart($step4SubPart, '###DATABASETYPEOPTIONS###', implode(LF, $step4DatabaseTypeOptions));
1051 // Define the markers content
1052 $step4SubPartMarkers = array(
1053 'llSummary' => 'Database summary:',
1054 'llUsername' => 'Username:',
1055 'username' => htmlspecialchars(TYPO3_db_username),
1056 'llHost' => 'Host:',
1057 'host' => htmlspecialchars(TYPO3_db_host),
1058 'llDatabase' => 'Database:',
1059 'database' => htmlspecialchars(TYPO3_db),
1060 'llNumberTables' => 'Number of tables:',
1061 'numberTables' => count($whichTables),
1062 'action' => htmlspecialchars($this->action),
1063 'llDatabaseType' => 'Select database contents:',
1064 'label' => 'Import database'
1065 );
1066 // Add step marker for main template
1067 $markers['step'] = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($content, $step4SubPartMarkers, '###|###', TRUE, TRUE);
1068 } else {
1069 // Add step marker for main template when no database
1070 $markers['step'] = $error_missingDB;
1071 }
1072 } else {
1073 // Add step marker for main template when no connection
1074 $markers['step'] = $error_missingConnect;
1075 }
1076 break;
1077 case 'go':
1078 // Add header marker for main template
1079 $markers['header'] = 'Congratulations!';
1080 // There should be a database host connection at this point
1081 if ($result = $GLOBALS['TYPO3_DB']->sql_pconnect(TYPO3_db_host, TYPO3_db_username, TYPO3_db_password)) {
1082 // The selected database should be accessible
1083 if ($GLOBALS['TYPO3_DB']->sql_select_db(TYPO3_db)) {
1084 // The database should contain tables
1085 if (count($whichTables)) {
1086 // Get the subpart for the go step
1087 $stepGoSubPart = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($templateFile, '###STEPGO###');
1088 // Define the markers content
1089 $stepGoSubPartMarkers = array(
1090 'messageBasicFinished' => $this->messageBasicFinished(),
1091 'llImportant' => 'Important Security Warning',
1092 'securityRisk' => $this->securityRisk(),
1093 'llSwitchMode' => '
1094 <a href="' . $this->scriptSelf . '">
1095 Change the Install Tool password here
1096 </a>
1097 '
1098 );
1099 // Add step marker for main template
1100 $markers['step'] = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($stepGoSubPart, $stepGoSubPartMarkers, '###|###', TRUE, TRUE);
1101 } else {
1102 // Add step marker for main template when empty database
1103 $markers['step'] = $error_emptyDB;
1104 }
1105 } else {
1106 // Add step marker for main template when no database
1107 $markers['step'] = $error_missingDB;
1108 }
1109 } else {
1110 // Add step marker for main template when no connection
1111 $markers['step'] = $error_missingConnect;
1112 }
1113 break;
1114 }
1115 }
1116 // Fill the markers in the template
1117 $content = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($template, $markers, '###|###', TRUE, FALSE);
1118 return $content;
1119 }
1120
1121 /**
1122 * Calling the functions that checks the system
1123 *
1124 * @return void
1125 * @todo Define visibility
1126 */
1127 public function checkTheConfig() {
1128 // Order important:
1129 $this->checkDirs();
1130 $this->checkConfiguration();
1131 $this->checkExtensions();
1132 if (TYPO3_OS == 'WIN') {
1133 $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\\');
1134 if (!isset($_SERVER['PATH'])) {
1135 $serverPath = array_change_key_case($_SERVER, CASE_UPPER);
1136 $paths = array_merge($paths, explode(';', $serverPath['PATH']));
1137 } else {
1138 $paths = array_merge($paths, explode(';', $_SERVER['PATH']));
1139 }
1140 } else {
1141 $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/');
1142 $paths = array_merge($paths, explode(':', $_SERVER['PATH']));
1143 }
1144 $paths = array_unique($paths);
1145 asort($paths);
1146 if ($this->INSTALL['checkIM']['lzw']) {
1147 $this->checkIMlzw = 1;
1148 }
1149 if ($this->INSTALL['checkIM']['path']) {
1150 $paths[] = trim($this->INSTALL['checkIM']['path']);
1151 }
1152 if ($this->checkIM) {
1153 $this->checkImageMagick($paths);
1154 }
1155 $this->checkDatabase();
1156 }
1157
1158 /**
1159 * Editing files in typo3conf directory (or elsewhere if enabled)
1160 *
1161 * @return void
1162 * @todo Define visibility
1163 */
1164 public function typo3conf_edit() {
1165 // default:
1166 $EDIT_path = PATH_typo3conf;
1167 if ($this->allowFileEditOutsite_typo3conf_dir && $this->INSTALL['FILE']['EDIT_path']) {
1168 if (\TYPO3\CMS\Core\Utility\GeneralUtility::validPathStr($this->INSTALL['FILE']['EDIT_path']) && substr($this->INSTALL['FILE']['EDIT_path'], -1) == '/') {
1169 $tmp_path = PATH_site . $this->INSTALL['FILE']['EDIT_path'];
1170 if (is_dir($tmp_path)) {
1171 $EDIT_path = $tmp_path;
1172 } else {
1173 $this->errorMessages[] = '
1174 \'' . $tmp_path . '\' was not directory
1175 ';
1176 }
1177 } else {
1178 $this->errorMessages[] = '
1179 Bad directory name (must be like t3lib/ or media/script/)
1180 ';
1181 }
1182 }
1183 $headCode = 'Edit files in ' . basename($EDIT_path) . '/';
1184 $messages = '';
1185 if ($this->INSTALL['SAVE_FILE']) {
1186 $save_to_file = $this->INSTALL['FILE']['name'];
1187 if (@is_file($save_to_file)) {
1188 $save_to_file_md5 = md5($save_to_file);
1189 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')) {
1190 $this->INSTALL['typo3conf_files'] = $save_to_file;
1191 $save_fileContent = $this->INSTALL['FILE'][$save_to_file_md5];
1192 if ($this->INSTALL['FILE']['win_to_unix_br']) {
1193 $save_fileContent = str_replace(CRLF, LF, $save_fileContent);
1194 }
1195 $backupFile = $this->getBackupFilename($save_to_file);
1196 if ($this->INSTALL['FILE']['backup']) {
1197 if (@is_file($backupFile)) {
1198 unlink($backupFile);
1199 }
1200 rename($save_to_file, $backupFile);
1201 $messages .= '
1202 Backup written to <strong>' . $backupFile . '</strong>
1203 <br />
1204 ';
1205 }
1206 \TYPO3\CMS\Core\Utility\GeneralUtility::writeFile($save_to_file, $save_fileContent);
1207 $messages .= '
1208 File saved: <strong>' . $save_to_file . '</strong>
1209 <br />
1210 MD5-sum: ' . $this->INSTALL['FILE']['prevMD5'] . ' (prev)
1211 <br />
1212 MD5-sum: ' . md5($save_fileContent) . ' (new)
1213 <br />
1214 ';
1215 }
1216 }
1217 }
1218 // Filelist:
1219 // Get the template file
1220 $templateFile = @file_get_contents((PATH_site . $this->templateFilePath . 'Typo3ConfEdit.html'));
1221 // Get the template part from the file
1222 $template = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($templateFile, '###TEMPLATE###');
1223 // Get the subpart for the files
1224 $filesSubpart = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($template, '###FILES###');
1225 $files = array();
1226 $typo3conf_files = \TYPO3\CMS\Core\Utility\GeneralUtility::getFilesInDir($EDIT_path, '', 1, 1);
1227 $fileFound = 0;
1228 foreach ($typo3conf_files as $k => $file) {
1229 // Delete temp_CACHED files if option is set
1230 if ($this->INSTALL['delTempCached'] && preg_match('|/temp_CACHED_[a-z0-9_]+\\.php|', $file)) {
1231 unlink($file);
1232 continue;
1233 }
1234 if ($this->INSTALL['typo3conf_files'] && !strcmp($this->INSTALL['typo3conf_files'], $file)) {
1235 $fileFound = 1;
1236 }
1237 // Define the markers content for the files subpart
1238 $filesMarkers = array(
1239 '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',
1240 'fileName' => basename($file),
1241 'fileSize' => \TYPO3\CMS\Core\Utility\GeneralUtility::formatSize(filesize($file)),
1242 'class' => $this->INSTALL['typo3conf_files'] && !strcmp($this->INSTALL['typo3conf_files'], $file) ? 'class="act"' : ''
1243 );
1244 // Fill the markers in the subpart
1245 $files[] = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($filesSubpart, $filesMarkers, '###|###', TRUE, FALSE);
1246 }
1247 if ($fileFound && @is_file($this->INSTALL['typo3conf_files'])) {
1248 $backupFile = $this->getBackupFilename($this->INSTALL['typo3conf_files']);
1249 $fileContent = \TYPO3\CMS\Core\Utility\GeneralUtility::getUrl($this->INSTALL['typo3conf_files']);
1250 // Get the subpart to edit the files
1251 $fileEditTemplate = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($template, '###FILEEDIT###');
1252 $allowFileEditOutsideTypo3ConfDirSubPart = '';
1253 if (substr($this->INSTALL['typo3conf_files'], -1) != '~' && !strstr($this->INSTALL['typo3conf_files'], '_bak')) {
1254 // Get the subpart to show the save button
1255 $showSaveButtonSubPart = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($fileEditTemplate, '###SHOWSAVEBUTTON###');
1256 }
1257 if ($this->allowFileEditOutsite_typo3conf_dir) {
1258 // Get the subpart to show if files are allowed outside the directory typo3conf
1259 $allowFileEditOutsideTypo3ConfDirSubPart = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($fileEditTemplate, '###ALLOWFILEEDITOUTSIDETYPO3CONFDIR###');
1260 }
1261 // Substitute the subpart for the save button
1262 $fileEditContent = \TYPO3\CMS\Core\Html\HtmlParser::substituteSubpart($fileEditTemplate, '###SHOWSAVEBUTTON###', $showSaveButtonSubPart);
1263 // Substitute the subpart to show if files are allowed outside the directory typo3conf
1264 $fileEditContent = \TYPO3\CMS\Core\Html\HtmlParser::substituteSubpart($fileEditContent, '###ALLOWFILEEDITOUTSIDETYPO3CONFDIR###', $allowFileEditOutsideTypo3ConfDirSubPart);
1265 // Define the markers content for subpart to edit the files
1266 $fileEditMarkers = array(
1267 'messages' => !empty($messages) ? '<p class="typo3-message message-warning">' . $messages . '</p>' : '',
1268 'action' => $this->action . '#fileEditHeader',
1269 'saveFile' => 'Save file',
1270 'close' => 'Close',
1271 'llEditing' => 'Editing file:',
1272 'file' => $this->INSTALL['typo3conf_files'],
1273 'md5Sum' => 'MD5-sum: ' . md5($fileContent),
1274 'fileName' => $this->INSTALL['typo3conf_files'],
1275 'fileEditPath' => $this->INSTALL['FILE']['EDIT_path'],
1276 'filePreviousMd5' => md5($fileContent),
1277 'fileMd5' => md5($this->INSTALL['typo3conf_files']),
1278 'fileContent' => \TYPO3\CMS\Core\Utility\GeneralUtility::formatForTextarea($fileContent),
1279 'winToUnixBrChecked' => TYPO3_OS == 'WIN' ? '' : 'checked="checked"',
1280 'winToUnixBr' => 'Convert Windows linebreaks (13-10) to Unix (10)',
1281 'backupChecked' => @is_file($backupFile) ? 'checked="checked"' : '',
1282 'backup' => 'Make backup copy (rename to ' . basename($backupFile) . ')'
1283 );
1284 // Fill the markers in the subpart to edit the files
1285 $fileEditContent = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($fileEditContent, $fileEditMarkers, '###|###', TRUE, FALSE);
1286 }
1287 if ($this->allowFileEditOutsite_typo3conf_dir) {
1288 // Get the subpart to show if files are allowed outside the directory typo3conf
1289 $allowFileEditOutsideTypo3ConfDirSubPart = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($template, '###ALLOWFILEEDITOUTSIDETYPO3CONFDIR###');
1290 // Define the markers content
1291 $allowFileEditOutsideTypo3ConfDirMarkers = array(
1292 'action' => $this->action,
1293 'pathSite' => PATH_site,
1294 'editPath' => $this->INSTALL['FILE']['EDIT_path'],
1295 'set' => 'Set'
1296 );
1297 // Fill the markers in the subpart
1298 $allowFileEditOutsideTypo3ConfDirSubPart = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($allowFileEditOutsideTypo3ConfDirSubPart, $allowFileEditOutsideTypo3ConfDirMarkers, '###|###', TRUE, FALSE);
1299 }
1300 // Substitute the subpart to edit the file
1301 $fileListContent = \TYPO3\CMS\Core\Html\HtmlParser::substituteSubpart($template, '###FILEEDIT###', $fileEditContent);
1302 // Substitute the subpart when files can be edited outside typo3conf directory
1303 $fileListContent = \TYPO3\CMS\Core\Html\HtmlParser::substituteSubpart($fileListContent, '###ALLOWFILEEDITOUTSIDETYPO3CONFDIR###', $allowFileEditOutsideTypo3ConfDirSubPart);
1304 // Substitute the subpart for the files
1305 $fileListContent = \TYPO3\CMS\Core\Html\HtmlParser::substituteSubpart($fileListContent, '###FILES###', implode(LF, $files));
1306 // Define the markers content
1307 $fileListMarkers = array(
1308 'editPath' => '(' . $EDIT_path . ')',
1309 'deleteTempCachedUrl' => $this->action . '&amp;TYPO3_INSTALL[delTempCached]=1',
1310 'deleteTempCached' => 'Delete temp_CACHED* files'
1311 );
1312 // Fill the markers
1313 $fileListContent = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($fileListContent, $fileListMarkers, '###|###', TRUE, FALSE);
1314 // Add the content to the message array
1315 $this->message($headCode, 'Files in folder', $fileListContent);
1316 // Output the page
1317 $this->output($this->outputWrapper($this->printAll()));
1318 }
1319
1320 /**
1321 * Show system environment check
1322 */
1323 protected function systemEnvironmentCheck() {
1324 /** @var $statusCheck \TYPO3\CMS\Install\SystemEnvironment\Check */
1325 $statusCheck = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Install\\SystemEnvironment\\Check');
1326 $statusObjects = $statusCheck->getStatus();
1327
1328 $orderedStatus = array(
1329 'ErrorStatus' => array(),
1330 'WarningStatus' => array(),
1331 'OkStatus' => array(),
1332 'InfoStatus' => array(),
1333 'NoticeStatus' => array(),
1334 );
1335
1336 foreach ($statusObjects as $statusObject) {
1337 $className = get_class($statusObject);
1338 // Last part of class name
1339 $severityIdentifier = array_pop(explode('\\', $className));
1340 if (!is_array($orderedStatus[$severityIdentifier])) {
1341 throw new \TYPO3\CMS\Install\Exception('Unknown status severity type', 1362602559);
1342 }
1343 $orderedStatus[$severityIdentifier][] = $statusObject;
1344 }
1345
1346 $severityToCssClass = array(
1347 'ErrorStatus' => 'error',
1348 'WarningStatus' => 'warning',
1349 'OkStatus' => 'ok',
1350 'InfoStatus' => 'information',
1351 'NoticeStatus' => 'notice',
1352 );
1353
1354 $messageHtmlBoilerPlate =
1355 '<div class="typo3-message message-%1s" >' .
1356 '<div class="header-container" >' .
1357 '<div class="message-header message-left" ><strong>%2s</strong></div>' .
1358 '<div class="message-header message-right" ></div>' .
1359 '</div >' .
1360 '<div class="message-body" >%3s</div>' .
1361 '</div >' .
1362 '<p></p>';
1363
1364 $html = '<h3>System environment check</h3>';
1365 foreach ($orderedStatus as $severity) {
1366 foreach ($severity as $status) {
1367 /** @var $status \TYPO3\CMS\Install\SystemEnvironment\AbstractStatus */
1368 $className = get_class($status);
1369 // Last part of class name
1370 $severityIdentifier = array_pop(explode('\\', $className));
1371 $html .= sprintf(
1372 $messageHtmlBoilerPlate,
1373 $severityToCssClass[$severityIdentifier],
1374 $status->getTitle(),
1375 $status->getMessage()
1376 );
1377 }
1378 }
1379
1380 $this->output($this->outputWrapper($html));
1381 }
1382
1383 /**
1384 * Outputs system information
1385 *
1386 * @return void
1387 * @todo Define visibility
1388 */
1389 public function phpinformation() {
1390 $headCode = 'PHP information';
1391 $sVar = \TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('_ARRAY');
1392 $sVar['CONST: PHP_OS'] = PHP_OS;
1393 $sVar['CONST: TYPO3_OS'] = TYPO3_OS;
1394 $sVar['CONST: PATH_thisScript'] = PATH_thisScript;
1395 $sVar['CONST: php_sapi_name()'] = PHP_SAPI;
1396 $sVar['OTHER: TYPO3_VERSION'] = TYPO3_version;
1397 $sVar['OTHER: PHP_VERSION'] = phpversion();
1398 $sVar['imagecreatefromgif()'] = function_exists('imagecreatefromgif');
1399 $sVar['imagecreatefrompng()'] = function_exists('imagecreatefrompng');
1400 $sVar['imagecreatefromjpeg()'] = function_exists('imagecreatefromjpeg');
1401 $sVar['imagegif()'] = function_exists('imagegif');
1402 $sVar['imagepng()'] = function_exists('imagepng');
1403 $sVar['imagejpeg()'] = function_exists('imagejpeg');
1404 $sVar['imagettftext()'] = function_exists('imagettftext');
1405 $sVar['OTHER: IMAGE_TYPES'] = function_exists('imagetypes') ? imagetypes() : 0;
1406 $gE_keys = explode(',', 'SERVER_PORT,SERVER_SOFTWARE,GATEWAY_INTERFACE,SCRIPT_NAME,PATH_TRANSLATED');
1407 foreach ($gE_keys as $k) {
1408 $sVar['SERVER: ' . $k] = $_SERVER[$k];
1409 }
1410 $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');
1411 foreach ($gE_keys as $k) {
1412 $sVar['T3CV_GFX: ' . $k] = $GLOBALS['TYPO3_CONF_VARS']['GFX'][$k];
1413 }
1414 $debugInfo = array(
1415 '### DEBUG SYSTEM INFORMATION - START ###'
1416 );
1417 foreach ($sVar as $kkk => $vvv) {
1418 $debugInfo[] = str_pad(substr($kkk, 0, 20), 20) . ': ' . $vvv;
1419 }
1420 $debugInfo[] = '### DEBUG SYSTEM INFORMATION - END ###';
1421 // Get the template file
1422 $templateFile = @file_get_contents((PATH_site . $this->templateFilePath . 'PhpInformation.html'));
1423 // Get the template part from the file
1424 $template = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($templateFile, '###TEMPLATE###');
1425 // Define the markers content
1426 $markers = array(
1427 '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!',
1428 'debugInfo' => \TYPO3\CMS\Core\Utility\GeneralUtility::formatForTextarea(implode(LF, $debugInfo))
1429 );
1430 // Fill the markers
1431 $content = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($template, $markers, '###|###', TRUE, FALSE);
1432 // Add the content to the message array
1433 $this->message($headCode, 'DEBUG information', $content);
1434 // Start with various server information
1435 $getEnvArray = array();
1436 $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');
1437 foreach ($gE_keys as $k) {
1438 $getEnvArray[$k] = getenv($k);
1439 }
1440 $this->message($headCode, 'TYPO3\\CMS\\Core\\Utility\\GeneralUtility::getIndpEnv()', $this->viewArray(\TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('_ARRAY')));
1441 $this->message($headCode, 'getenv()', $this->viewArray($getEnvArray));
1442 $this->message($headCode, '_ENV', $this->viewArray($_ENV));
1443 $this->message($headCode, '_SERVER', $this->viewArray($_SERVER));
1444 $this->message($headCode, '_COOKIE', $this->viewArray($_COOKIE));
1445 $this->message($headCode, '_GET', $this->viewArray($_GET));
1446 // Start with the phpinfo() part
1447 ob_start();
1448 phpinfo();
1449 $contents = explode('<body>', ob_get_contents());
1450 ob_end_clean();
1451 $contents = explode('</body>', $contents[1]);
1452 // Do code cleaning: phpinfo() is not XHTML1.1 compliant
1453 $phpinfo = str_replace('<font', '<span', $contents[0]);
1454 $phpinfo = str_replace('</font', '</span', $phpinfo);
1455 $phpinfo = str_replace('<img border="0"', '<img', $phpinfo);
1456 $phpinfo = str_replace('<a name=', '<a id=', $phpinfo);
1457 // Add phpinfo() to the message array
1458 $this->message($headCode, 'phpinfo()', '
1459 <div class="phpinfo">
1460 ' . $phpinfo . '
1461 </div>
1462 ');
1463 // Output the page
1464 $this->output($this->outputWrapper($this->printAll()));
1465 }
1466
1467 /*******************************
1468 *
1469 * cleanup manager
1470 *
1471 *******************************/
1472 /**
1473 * Provides a tool cleaning up various tables in the database
1474 *
1475 * @return void
1476 * @author Robert Lemke <rl@robertlemke.de>
1477 * @todo Add more functionality ...
1478 * @todo Define visibility
1479 */
1480 public function cleanupManager() {
1481 $headCode = 'Clean up your TYPO3 installation';
1482 $this->message($headCode, 'Database cache tables', '
1483 <p>
1484 <strong>Clear cached image sizes</strong>
1485 <br />
1486 Clears the cache used for memorizing sizes of all images used in
1487 your website. This information is cached in order to gain
1488 performance and will be stored each time a new image is being
1489 displayed in the frontend.
1490 </p>
1491 <p>
1492 You should <em>Clear All Cache</em> in the backend after
1493 clearing this cache.
1494 </p>
1495 ');
1496 $tables = $this->sqlHandler->getListOfTables();
1497 $action = $this->INSTALL['cleanup_type'];
1498 if (($action == 'cache_imagesizes' || $action == 'all') && isset($tables['cache_imagesizes'])) {
1499 $GLOBALS['TYPO3_DB']->exec_TRUNCATEquery('cache_imagesizes');
1500 }
1501 $cleanupType = array(
1502 'all' => 'Clean up everything'
1503 );
1504 // Get cache_imagesizes info
1505 if (isset($tables['cache_imagesizes'])) {
1506 $cleanupType['cache_imagesizes'] = 'Clear cached image sizes only';
1507 $cachedImageSizesCounter = intval($GLOBALS['TYPO3_DB']->exec_SELECTcountRows('*', 'cache_imagesizes'));
1508 } else {
1509 $this->message($headCode, 'Table cache_imagesizes does not exist!', '
1510 <p>
1511 The table cache_imagesizes was not found. Please check your
1512 database settings in Basic Configuration and compare your
1513 table definition with the Database Analyzer.
1514 </p>
1515 ', 2);
1516 $cachedImageSizesCounter = 'unknown';
1517 }
1518 // Get the template file
1519 $templateFile = @file_get_contents((PATH_site . $this->templateFilePath . 'CleanUpManager.html'));
1520 // Get the template part from the file
1521 $template = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($templateFile, '###TEMPLATE###');
1522 // Get the subpart for the 'Clean up' dropdown
1523 $cleanUpOptionsSubpart = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($template, '###CLEANUPOPTIONS###');
1524 $cleanUpOptions = array();
1525 foreach ($cleanupType as $cleanUpKey => $cleanUpValue) {
1526 // Define the markers content
1527 $cleanUpMarkers = array(
1528 'value' => htmlspecialchars($cleanUpKey),
1529 'data' => htmlspecialchars($cleanUpValue)
1530 );
1531 // Fill the markers in the subpart
1532 $cleanUpOptions[] = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($cleanUpOptionsSubpart, $cleanUpMarkers, '###|###', TRUE, FALSE);
1533 }
1534 // Substitute the subpart for the 'Clean up' dropdown
1535 $content = \TYPO3\CMS\Core\Html\HtmlParser::substituteSubpart($template, '###CLEANUPOPTIONS###', implode(LF, $cleanUpOptions));
1536 // Define the markers content
1537 $markers = array(
1538 'numberCached' => 'Number cached image sizes:',
1539 'number' => $cachedImageSizesCounter,
1540 'action' => $this->action,
1541 'cleanUp' => 'Clean up',
1542 'execute' => 'Execute'
1543 );
1544 // Fill the markers
1545 $content = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($content, $markers, '###|###', TRUE, FALSE);
1546 // Add the content to the message array
1547 $this->message($headCode, 'Statistics', $content, 1);
1548 $this->message($headCode, 'typo3temp/ folder', '
1549 <p>
1550 TYPO3 uses this directory for temporary files, mainly processed
1551 and cached images.
1552 <br />
1553 The filenames are very cryptic; They are unique representations
1554 of the file properties made by md5-hashing a serialized array
1555 with information.
1556 <br />
1557 Anyway this directory may contain many thousand files and a lot
1558 of them may be of no use anymore.
1559 </p>
1560 <p>
1561 With this test you can delete the files in this folder. When you
1562 do that, you should also clear the cache database tables
1563 afterwards.
1564 </p>
1565 ');
1566 if (!$this->config_array['dir_typo3temp']) {
1567 $this->message('typo3temp/ directory', 'typo3temp/ not writable!', '
1568 <p>
1569 You must make typo3temp/ write enabled before you can
1570 proceed with this test.
1571 </p>
1572 ', 2);
1573 $this->output($this->outputWrapper($this->printAll()));
1574 return;
1575 }
1576 // Run through files
1577 $fileCounter = 0;
1578 $deleteCounter = 0;
1579 $criteriaMatch = 0;
1580 $tmap = array('day' => 1, 'week' => 7, 'month' => 30);
1581 $tt = $this->INSTALL['typo3temp_delete'];
1582 $subdir = $this->INSTALL['typo3temp_subdir'];
1583 if (strlen($subdir) && !preg_match('/^[[:alnum:]_]+\\/$/', $subdir)) {
1584 die('subdir "' . $subdir . '" was not allowed!');
1585 }
1586 $action = $this->INSTALL['typo3temp_action'];
1587 $d = @dir(($this->typo3temp_path . $subdir));
1588 if (is_object($d)) {
1589 while ($entry = $d->read()) {
1590 $theFile = $this->typo3temp_path . $subdir . $entry;
1591 if (@is_file($theFile)) {
1592 $ok = 0;
1593 $fileCounter++;
1594 if ($tt) {
1595 if (\TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($tt)) {
1596 if (filesize($theFile) > $tt * 1024) {
1597 $ok = 1;
1598 }
1599 } else {
1600 if (fileatime($theFile) < $GLOBALS['EXEC_TIME'] - intval($tmap[$tt]) * 60 * 60 * 24) {
1601 $ok = 1;
1602 }
1603 }
1604 } else {
1605 $ok = 1;
1606 }
1607 if ($ok) {
1608 $hashPart = substr(basename($theFile), -14, 10);
1609 // This is a kind of check that the file being deleted has a 10 char hash in it
1610 if (!preg_match('/[^a-f0-9]/', $hashPart) || substr($theFile, -6) === '.cache' || substr($theFile, -4) === '.tbl' || substr(basename($theFile), 0, 8) === 'install_') {
1611 if ($action && $deleteCounter < $action) {
1612 $deleteCounter++;
1613 unlink($theFile);
1614 } else {
1615 $criteriaMatch++;
1616 }
1617 }
1618 }
1619 }
1620 }
1621 $d->close();
1622 }
1623 // Find sub-dirs:
1624 $subdirRegistry = array('' => '');
1625 $d = @dir($this->typo3temp_path);
1626 if (is_object($d)) {
1627 while ($entry = $d->read()) {
1628 $theFile = $entry;
1629 if (@is_dir(($this->typo3temp_path . $theFile)) && $theFile != '..' && $theFile != '.') {
1630 $subdirRegistry[$theFile . '/'] = $theFile . '/ (Files: ' . count(\TYPO3\CMS\Core\Utility\GeneralUtility::getFilesInDir(($this->typo3temp_path . $theFile))) . ')';
1631 }
1632 }
1633 }
1634 $deleteType = array(
1635 '0' => 'All',
1636 'day' => 'Last access more than a day ago',
1637 'week' => 'Last access more than a week ago',
1638 'month' => 'Last access more than a month ago',
1639 '10' => 'Filesize greater than 10KB',
1640 '50' => 'Filesize greater than 50KB',
1641 '100' => 'Filesize greater than 100KB'
1642 );
1643 $actionType = array(
1644 '0' => 'Don\'t delete, just display statistics',
1645 '100' => 'Delete 100',
1646 '500' => 'Delete 500',
1647 '1000' => 'Delete 1000'
1648 );
1649 // Get the template file
1650 $templateFile = @file_get_contents((PATH_site . $this->templateFilePath . 'Typo3TempManager.html'));
1651 // Get the template part from the file
1652 $template = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($templateFile, '###TEMPLATE###');
1653 // Get the subpart for 'Delete files by condition' dropdown
1654 $deleteOptionsSubpart = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($template, '###DELETEOPTIONS###');
1655 $deleteOptions = array();
1656 foreach ($deleteType as $deleteKey => $deleteValue) {
1657 // Define the markers content
1658 $deleteMarkers = array(
1659 'value' => htmlspecialchars($deleteKey),
1660 'selected' => !strcmp($deleteKey, $tt) ? 'selected="selected"' : '',
1661 'data' => htmlspecialchars($deleteValue)
1662 );
1663 // Fill the markers in the subpart
1664 $deleteOptions[] = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($deleteOptionsSubpart, $deleteMarkers, '###|###', TRUE, FALSE);
1665 }
1666 // Substitute the subpart for 'Delete files by condition' dropdown
1667 $content = \TYPO3\CMS\Core\Html\HtmlParser::substituteSubpart($template, '###DELETEOPTIONS###', implode(LF, $deleteOptions));
1668 // Get the subpart for 'Number of files at a time' dropdown
1669 $actionOptionsSubpart = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($template, '###ACTIONOPTIONS###');
1670 $actionOptions = array();
1671 foreach ($actionType as $actionKey => $actionValue) {
1672 // Define the markers content
1673 $actionMarkers = array(
1674 'value' => htmlspecialchars($actionKey),
1675 'data' => htmlspecialchars($actionValue)
1676 );
1677 // Fill the markers in the subpart
1678 $actionOptions[] = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($actionOptionsSubpart, $actionMarkers, '###|###', TRUE, FALSE);
1679 }
1680 // Substitute the subpart for 'Number of files at a time' dropdown
1681 $content = \TYPO3\CMS\Core\Html\HtmlParser::substituteSubpart($content, '###ACTIONOPTIONS###', implode(LF, $actionOptions));
1682 // Get the subpart for 'From sub-directory' dropdown
1683 $subDirectoryOptionsSubpart = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($template, '###SUBDIRECTORYOPTIONS###');
1684 $subDirectoryOptions = array();
1685 foreach ($subdirRegistry as $subDirectoryKey => $subDirectoryValue) {
1686 // Define the markers content
1687 $subDirectoryMarkers = array(
1688 'value' => htmlspecialchars($subDirectoryKey),
1689 'selected' => !strcmp($subDirectoryKey, $this->INSTALL['typo3temp_subdir']) ? 'selected="selected"' : '',
1690 'data' => htmlspecialchars($subDirectoryValue)
1691 );
1692 // Fill the markers in the subpart
1693 $subDirectoryOptions[] = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($subDirectoryOptionsSubpart, $subDirectoryMarkers, '###|###', TRUE, FALSE);
1694 }
1695 // Substitute the subpart for 'From sub-directory' dropdown
1696 $content = \TYPO3\CMS\Core\Html\HtmlParser::substituteSubpart($content, '###SUBDIRECTORYOPTIONS###', implode(LF, $subDirectoryOptions));
1697 // Define the markers content
1698 $markers = array(
1699 'numberTemporary' => 'Number of temporary files:',
1700 'numberMatching' => 'Number matching:',
1701 'numberDeleted' => 'Number deleted:',
1702 'temporary' => $fileCounter - $deleteCounter,
1703 'matching' => $criteriaMatch,
1704 'deleteType' => '<span>' . htmlspecialchars($deleteType[$tt]) . '</span>',
1705 'deleted' => $deleteCounter,
1706 'deleteCondition' => 'Delete files by condition',
1707 'numberFiles' => 'Number of files at a time:',
1708 'fromSubdirectory' => 'From sub-directory:',
1709 'execute' => 'Execute',
1710 'explanation' => '
1711 <p>
1712 This tool will delete files only if the last 10 characters
1713 before the extension (3 chars+\'.\') are hexadecimal valid
1714 ciphers, which are lowercase a-f and 0-9.
1715 </p>
1716 '
1717 );
1718 // Fill the markers
1719 $content = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($content, $markers, '###|###', TRUE, FALSE);
1720 // Add the content to the message array
1721 $this->message($headCode, 'Statistics', $content, 1);
1722 // Output the page
1723 $this->output($this->outputWrapper($this->printAll()));
1724 }
1725
1726 /*******************************
1727 *
1728 * CONFIGURATION FORM
1729 *
1730 ********************************/
1731 /**
1732 * Creating the form for editing the TYPO3_CONF_VARS options.
1733 *
1734 * @param string $type If get_form, display form, otherwise checks and store in localconf.php
1735 * @return void
1736 * @todo Define visibility
1737 */
1738 public function generateConfigForm($type = '') {
1739 $default_config_content = \TYPO3\CMS\Core\Utility\GeneralUtility::getUrl(
1740 \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Configuration\\ConfigurationManager')->getDefaultConfigurationFileLocation()
1741 );
1742 $commentArr = $this->getDefaultConfigArrayComments($default_config_content);
1743 switch ($type) {
1744 case 'get_form':
1745 // Get the template file
1746 $templateFile = @file_get_contents((PATH_site . $this->templateFilePath . 'GenerateConfigForm.html'));
1747 // Get the template part from the file
1748 $template = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($templateFile, '###TEMPLATE###');
1749 foreach ($GLOBALS['TYPO3_CONF_VARS'] as $k => $va) {
1750 $ext = '[' . $k . ']';
1751 $this->message($ext, '$TYPO3_CONF_VARS[\'' . $k . '\']', $commentArr[0][$k], 1);
1752 foreach ($va as $vk => $value) {
1753 if (isset($GLOBALS['TYPO3_CONF_VARS_extensionAdded'][$k][$vk])) {
1754 // Don't allow editing stuff which is added by extensions
1755 // Make sure we fix potentially duplicated entries from older setups
1756 $potentialValue = str_replace(array('\'.chr(10).\'', '\' . LF . \''), array(LF, LF), $value);
1757 while (preg_match('/' . preg_quote($GLOBALS['TYPO3_CONF_VARS_extensionAdded'][$k][$vk], '/') . '$/', '', $potentialValue)) {
1758 $potentialValue = preg_replace('/' . preg_quote($GLOBALS['TYPO3_CONF_VARS_extensionAdded'][$k][$vk], '/') . '$/', '', $potentialValue);
1759 }
1760 $value = $potentialValue;
1761 }
1762 $textAreaSubpart = '';
1763 $booleanSubpart = '';
1764 $textLineSubpart = '';
1765 $description = trim($commentArr[1][$k][$vk]);
1766 $isTextarea = preg_match('/^(<.*?>)?string \\(textarea\\)/i', $description) ? TRUE : FALSE;
1767 $doNotRender = preg_match('/^(<.*?>)?string \\(exclude\\)/i', $description) ? TRUE : FALSE;
1768 if (!is_array($value) && !$doNotRender && (!preg_match('/[' . LF . CR . ']/', $value) || $isTextarea)) {
1769 $k2 = '[' . $vk . ']';
1770 if ($isTextarea) {
1771 // Get the subpart for a textarea
1772 $textAreaSubpart = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($template, '###TEXTAREA###');
1773 // Define the markers content
1774 $textAreaMarkers = array(
1775 'id' => $k . '-' . $vk,
1776 'name' => 'TYPO3_INSTALL[extConfig][' . $k . '][' . $vk . ']',
1777 'value' => htmlspecialchars(str_replace(array('\'.chr(10).\'', '\' . LF . \''), array(LF, LF), $value))
1778 );
1779 // Fill the markers in the subpart
1780 $textAreaSubpart = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($textAreaSubpart, $textAreaMarkers, '###|###', TRUE, FALSE);
1781 } elseif (preg_match('/^(<.*?>)?boolean/i', $description)) {
1782 // Get the subpart for a checkbox
1783 $booleanSubpart = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($template, '###BOOLEAN###');
1784 // Define the markers content
1785 $booleanMarkers = array(
1786 'id' => $k . '-' . $vk,
1787 'name' => 'TYPO3_INSTALL[extConfig][' . $k . '][' . $vk . ']',
1788 'value' => $value && strcmp($value, '0') ? $value : 1,
1789 'checked' => $value ? 'checked="checked"' : ''
1790 );
1791 // Fill the markers in the subpart
1792 $booleanSubpart = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($booleanSubpart, $booleanMarkers, '###|###', TRUE, FALSE);
1793 } else {
1794 // Get the subpart for an input text field
1795 $textLineSubpart = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($template, '###TEXTLINE###');
1796 // Define the markers content
1797 $textLineMarkers = array(
1798 'id' => $k . '-' . $vk,
1799 'name' => 'TYPO3_INSTALL[extConfig][' . $k . '][' . $vk . ']',
1800 'value' => htmlspecialchars($value)
1801 );
1802 // Fill the markers in the subpart
1803 $textLineSubpart = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($textLineSubpart, $textLineMarkers, '###|###', TRUE, FALSE);
1804 }
1805 // Substitute the subpart for a textarea
1806 $content = \TYPO3\CMS\Core\Html\HtmlParser::substituteSubpart($template, '###TEXTAREA###', $textAreaSubpart);
1807 // Substitute the subpart for a checkbox
1808 $content = \TYPO3\CMS\Core\Html\HtmlParser::substituteSubpart($content, '###BOOLEAN###', $booleanSubpart);
1809 // Substitute the subpart for an input text field
1810 $content = \TYPO3\CMS\Core\Html\HtmlParser::substituteSubpart($content, '###TEXTLINE###', $textLineSubpart);
1811 // Define the markers content
1812 $markers = array(
1813 'description' => $description,
1814 'key' => '[' . $k . '][' . $vk . ']',
1815 'label' => htmlspecialchars(\TYPO3\CMS\Core\Utility\GeneralUtility::fixed_lgd_cs($value, 40))
1816 );
1817 // Fill the markers
1818 $content = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($content, $markers, '###|###', TRUE, FALSE);
1819 // Add the content to the message array
1820 $this->message($ext, $k2, $content);
1821 }
1822 }
1823 }
1824 break;
1825 default:
1826 if (is_array($this->INSTALL['extConfig'])) {
1827 $configurationPathValuePairs = array();
1828 foreach ($this->INSTALL['extConfig'] as $k => $va) {
1829 if (is_array($GLOBALS['TYPO3_CONF_VARS'][$k])) {
1830 foreach ($va as $vk => $value) {
1831 if (isset($GLOBALS['TYPO3_CONF_VARS'][$k][$vk])) {
1832 $doit = 1;
1833 if ($k == 'BE' && $vk == 'installToolPassword') {
1834 if ($value) {
1835 if (isset($_POST['installToolPassword_check'])) {
1836 if (!$this->formProtection->validateToken((string) $_POST['formToken'], 'installToolPassword', 'change')) {
1837 $doit = FALSE;
1838 break;
1839 }
1840 if (!\TYPO3\CMS\Core\Utility\GeneralUtility::_GP('installToolPassword_check') || strcmp(\TYPO3\CMS\Core\Utility\GeneralUtility::_GP('installToolPassword_check'), $value)) {
1841 $doit = FALSE;
1842 $this->errorMessages[] = 'The two passwords did not ' . 'match! The password was not changed.';
1843 }
1844 }
1845 if (\TYPO3\CMS\Core\Utility\GeneralUtility::_GP('installToolPassword_md5')) {
1846 $value = md5($value);
1847 }
1848 } else {
1849 $doit = 0;
1850 }
1851 }
1852 $description = trim($commentArr[1][$k][$vk]);
1853 if (preg_match('/^string \\(textarea\\)/i', $description)) {
1854 // Force Unix linebreaks in textareas
1855 $value = str_replace(CR, '', $value);
1856 // Preserve linebreaks
1857 $value = str_replace(LF, '\' . LF . \'', $value);
1858 }
1859 if (preg_match('/^boolean/i', $description)) {
1860 // When submitting settings in the Install Tool, values that default to "FALSE" or "TRUE"
1861 // in EXT:core/Configuration/DefaultConfiguration.php will be sent as "0" resp. "1".
1862 // Therefore, reset the values to their boolean equivalent.
1863 if ($GLOBALS['TYPO3_CONF_VARS'][$k][$vk] === FALSE && $value === '0') {
1864 $value = FALSE;
1865 } elseif ($GLOBALS['TYPO3_CONF_VARS'][$k][$vk] === TRUE && $value === '1') {
1866 $value = TRUE;
1867 }
1868 }
1869 if ($doit && strcmp($GLOBALS['TYPO3_CONF_VARS'][$k][$vk], $value)) {
1870 $configurationPathValuePairs['"' . $k . '"' . '/' . '"' . $vk . '"'] = $value;
1871 }
1872 }
1873 }
1874 }
1875 }
1876 $this->setLocalConfigurationValues($configurationPathValuePairs);
1877 }
1878 break;
1879 }
1880 }
1881
1882 /**
1883 * Make an array of the comments in the EXT:core/Configuration/DefaultConfiguration.php file
1884 *
1885 * @param string $string The contents of the EXT:core/Configuration/DefaultConfiguration.php file
1886 * @param array $mainArray
1887 * @param array $commentArray
1888 * @return array
1889 * @todo Define visibility
1890 */
1891 public function getDefaultConfigArrayComments($string, $mainArray = array(), $commentArray = array()) {
1892 $lines = explode(LF, $string);
1893 $in = 0;
1894 $mainKey = '';
1895 foreach ($lines as $lc) {
1896 $lc = trim($lc);
1897 if ($in) {
1898 if (!strcmp($lc, ');')) {
1899 $in = 0;
1900 } else {
1901 if (preg_match('/["\']([[:alnum:]_-]*)["\'][[:space:]]*=>(.*)/i', $lc, $reg)) {
1902 preg_match('/,[\\t\\s]*\\/\\/(.*)/i', $reg[2], $creg);
1903 $theComment = trim($creg[1]);
1904 if (substr(strtolower(trim($reg[2])), 0, 5) == 'array' && !strcmp($reg[1], strtoupper($reg[1]))) {
1905 $mainKey = trim($reg[1]);
1906 $mainArray[$mainKey] = $theComment;
1907 } elseif ($mainKey) {
1908 $commentArray[$mainKey][$reg[1]] = $theComment;
1909 }
1910 }
1911 }
1912 }
1913 if (!strcmp($lc, 'return array(')) {
1914 $in = 1;
1915 }
1916 }
1917 return array($mainArray, $commentArray);
1918 }
1919
1920 /*******************************
1921 *
1922 * CHECK CONFIGURATION FUNCTIONS
1923 *
1924 *******************************/
1925 /**
1926 * Checking php.ini configuration and set appropriate messages and flags.
1927 *
1928 * @return void
1929 * @todo Define visibility
1930 */
1931 public function checkConfiguration() {
1932 $ext = 'php.ini configuration tests';
1933 $this->message($ext);
1934 $this->message($ext, 'Mail test', $this->check_mail('get_form'), -1);
1935
1936 if (\TYPO3\CMS\Core\Utility\PhpOptionsUtility::isSqlSafeModeEnabled()) {
1937 $this->config_array['sql.safe_mode_user'] = get_current_user();
1938 }
1939 }
1940
1941 /**
1942 * Check if PHP function mail() works
1943 *
1944 * @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.
1945 * @return string The mail form if it is requested with get_form
1946 * @todo Define visibility
1947 */
1948 public function check_mail($cmd = '') {
1949 switch ($cmd) {
1950 case 'get_form':
1951 $out = '
1952 <p id="checkMailForm">
1953 You can check the t3lib_mail functionality by entering your email
1954 address here and press the button. You should then
1955 receive a testmail from "typo3installtool@example.org".
1956 </p>
1957 ';
1958 // Get the template file
1959 $templateFile = @file_get_contents((PATH_site . $this->templateFilePath . 'CheckMail.html'));
1960 // Get the template part from the file
1961 $template = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($templateFile, '###TEMPLATE###');
1962 if (!empty($this->mailMessage)) {
1963 // Get the subpart for the mail is sent message
1964 $mailSentSubpart = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($template, '###MAILSENT###');
1965 }
1966 $template = \TYPO3\CMS\Core\Html\HtmlParser::substituteSubpart($template, '###MAILSENT###', $mailSentSubpart);
1967 // Define the markers content
1968 $markers = array(
1969 'message' => $this->mailMessage,
1970 'enterEmail' => 'Enter the email address',
1971 'actionUrl' => $this->action . '#checkMailForm',
1972 'submit' => 'Send test mail'
1973 );
1974 // Fill the markers
1975 $out .= \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($template, $markers, '###|###', TRUE, TRUE);
1976 break;
1977 default:
1978 if (trim($this->INSTALL['check_mail'])) {
1979 $subject = 'TEST SUBJECT';
1980 $email = trim($this->INSTALL['check_mail']);
1981 /** @var $mailMessage \TYPO3\CMS\Core\Mail\MailMessage */
1982 $mailMessage = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Mail\\MailMessage');
1983 $mailMessage->addTo($email)->addFrom('typo3installtool@example.org', 'TYPO3 Install Tool')->setSubject($subject)->setBody('<html><body>HTML TEST CONTENT</body></html>');
1984 $mailMessage->addPart('TEST CONTENT');
1985 $mailMessage->send();
1986 $this->mailMessage = 'Mail was sent to: ' . $email;
1987 }
1988 break;
1989 }
1990 return $out;
1991 }
1992
1993 /**
1994 * Checking php extensions, specifically GDLib and Freetype
1995 *
1996 * @return void
1997 * @todo Define visibility
1998 */
1999 public function checkExtensions() {
2000 if (\TYPO3\CMS\Core\Utility\GeneralUtility::_GP('testingTrueTypeSupport')) {
2001 $this->checkTrueTypeSupport();
2002 }
2003 $ext = 'GDLib';
2004 $this->message($ext);
2005 $this->message($ext, 'FreeType quick-test (as GIF)', '
2006 <p>
2007 <img src="' . htmlspecialchars((\TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('REQUEST_URI') . '&testingTrueTypeSupport=1')) . '" alt="" />
2008 <br />
2009 If the text is exceeding the image borders you are
2010 using Freetype 2 and need to set
2011 TYPO3_CONF_VARS[GFX][TTFdpi]=96.
2012 </p>
2013 ', -1);
2014 }
2015
2016 /**
2017 * Checking and testing that the required writable directories are writable.
2018 *
2019 * @return void
2020 * @todo Define visibility
2021 */
2022 public function checkDirs() {
2023 // Check typo3/temp/
2024 $ext = 'Directories';
2025 $this->message($ext);
2026 $uniqueName = md5(uniqid(microtime()));
2027 // The requirement level (the integer value, ie. the second value of the value array) has the following meanings:
2028 // -1 = not required, but if it exists may be writable or not
2029 // 0 = not required, if it exists the dir should be writable
2030 // 1 = required, don't has to be writable
2031 // 2 = required, has to be writable
2032 $checkWrite = array(
2033 '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'),
2034 'typo3temp/pics/' => array('This folder is part of the typo3temp/ section. It needs to be writable, too.', 2, 'dir_typo3temp'),
2035 'typo3temp/temp/' => array('This folder is part of the typo3temp/ section. It needs to be writable, too.', 2, 'dir_typo3temp'),
2036 'typo3temp/llxml/' => array('This folder is part of the typo3temp/ section. It needs to be writable, too.', 2, 'dir_typo3temp'),
2037 'typo3temp/cs/' => array('This folder is part of the typo3temp/ section. It needs to be writable, too.', 2, 'dir_typo3temp'),
2038 'typo3temp/GB/' => array('This folder is part of the typo3temp/ section. It needs to be writable, too.', 2, 'dir_typo3temp'),
2039 'typo3temp/locks/' => array('This folder is part of the typo3temp/ section. It needs to be writable, too.', 2, 'dir_typo3temp'),
2040 '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),
2041 'typo3conf/ext/' => array('Location for local extensions. Must be writable if the Extension Manager is supposed to install extensions for this website.', 0),
2042 'typo3conf/l10n/' => array('Location for translations. Must be writable if the Extension Manager is supposed to install translations for extensions.', 0),
2043 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),
2044 'uploads/' => array('Location for uploaded files from RTE, in the subdirectories for uploaded files of content elements.', 2),
2045 'uploads/pics/' => array('Typical location for uploaded files (images especially).', 0),
2046 'uploads/media/' => array('Typical location for uploaded files (non-images especially).', 0),
2047 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileadminDir'] => array('Location for local files such as templates, independent uploads etc.', -1),
2048 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileadminDir'] . '_temp_/' => array('Typical temporary location for default upload of administrative files like import/export data, used by administrators.', 0),
2049 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileadminDir'] . 'user_upload/' => array('Default upload location for images by editors via Rich Text Editor and upload fields in the backend.', 0)
2050 );
2051 foreach ($checkWrite as $relpath => $descr) {
2052 // Check typo3temp/
2053 $general_message = $descr[0];
2054 // If the directory is missing, try to create it
2055 if (!@is_dir((PATH_site . $relpath))) {
2056 \TYPO3\CMS\Core\Utility\GeneralUtility::mkdir(PATH_site . $relpath);
2057 }
2058 if (!@is_dir((PATH_site . $relpath))) {
2059 if ($descr[1]) {
2060 // required...
2061 $this->message($ext, $relpath . ' directory does not exist and could not be created', '
2062 <p>
2063 <em>Full path: ' . PATH_site . $relpath . '</em>
2064 <br />
2065 ' . $general_message . '
2066 </p>
2067 <p>
2068 This error should not occur as ' . $relpath . ' must
2069 always be accessible in the root of a TYPO3 website.
2070 </p>
2071 ', 3);
2072 } else {
2073 if ($descr[1] == 0) {
2074 $msg = 'This directory does not necessarily have to exist but if it does it must be writable.';
2075 } else {
2076 $msg = 'This directory does not necessarily have to exist and if it does it can be writable or not.';
2077 }
2078 $this->message($ext, $relpath . ' directory does not exist', '
2079 <p>
2080 <em>Full path: ' . PATH_site . $relpath . '</em>
2081 <br />
2082 ' . $general_message . '
2083 </p>
2084 <p>
2085 ' . $msg . '
2086 </p>
2087 ', 2);
2088 }
2089 } else {
2090 $file = PATH_site . $relpath . $uniqueName;
2091 @touch($file);
2092 if (@is_file($file)) {
2093 unlink($file);
2094 if ($descr[2]) {
2095 $this->config_array[$descr[2]] = 1;
2096 }
2097 $this->message($ext, $relpath . ' writable', '', -1);
2098 } else {
2099 $severity = $descr[1] == 2 || $descr[1] == 0 ? 3 : 2;
2100 if ($descr[1] == 0 || $descr[1] == 2) {
2101 $msg = 'The directory ' . $relpath . ' must be writable!';
2102 } elseif ($descr[1] == -1 || $descr[1] == 1) {
2103 $msg = 'The directory ' . $relpath . ' does not necessarily have to be writable.';
2104 }
2105 $this->message($ext, $relpath . ' directory not writable', '
2106 <p>
2107 <em>Full path: ' . $file . '</em>
2108 <br />
2109 ' . $general_message . '
2110 </p>
2111 <p>
2112 Tried to write this file (with touch()) but didn\'t
2113 succeed.
2114 <br />
2115 ' . $msg . '
2116 </p>
2117 ', $severity);
2118 }
2119 }
2120 }
2121 }
2122
2123 /**
2124 * Checking for existing ImageMagick installs.
2125 *
2126 * 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.
2127 *
2128 * @param array $paths Possible ImageMagick paths
2129 * @return void
2130 * @todo Define visibility
2131 */
2132 public function checkImageMagick($paths) {
2133 $ext = 'Check Image Magick';
2134 $this->message($ext);
2135 // Get the template file
2136 $templateFile = @file_get_contents((PATH_site . $this->templateFilePath . 'CheckImageMagick.html'));
2137 $paths = array_unique($paths);
2138 $programs = explode(',', 'gm,convert,combine,composite,identify');
2139 $isExt = TYPO3_OS == 'WIN' ? '.exe' : '';
2140 $this->config_array['im_combine_filename'] = 'combine';
2141 foreach ($paths as $k => $v) {
2142 if (!preg_match('/[\\/]$/', $v)) {
2143 $v .= '/';
2144 }
2145 foreach ($programs as $filename) {
2146 if (ini_get('open_basedir') || file_exists($v) && @is_file(($v . $filename . $isExt))) {
2147 $version = $this->_checkImageMagick_getVersion($filename, $v);
2148 if ($version > 0) {
2149 // Assume GraphicsMagick
2150 if ($filename == 'gm') {
2151 $index[$v]['gm'] = $version;
2152 // No need to check for "identify" etc.
2153 continue;
2154 } else {
2155 // Assume ImageMagick
2156 $index[$v][$filename] = $version;
2157 }
2158 }
2159 }
2160 }
2161 if (count($index[$v]) >= 3 || $index[$v]['gm']) {
2162 $this->config_array['im'] = 1;
2163 }
2164 if ($index[$v]['gm'] || !$index[$v]['composite'] && $index[$v]['combine']) {
2165 $this->config_array['im_combine_filename'] = 'combine';
2166 } elseif ($index[$v]['composite'] && !$index[$v]['combine']) {
2167 $this->config_array['im_combine_filename'] = 'composite';
2168 }
2169 if (isset($index[$v]['convert']) && $this->checkIMlzw) {
2170 $index[$v]['gif_capability'] = '' . $this->_checkImageMagickGifCapability($v);
2171 }
2172 }
2173 $this->config_array['im_versions'] = $index;
2174 if (!$this->config_array['im']) {
2175 $this->message($ext, 'No ImageMagick installation available', '
2176 <p>
2177 It seems that there is no adequate ImageMagick installation
2178 available at the checked locations (' . implode(', ', $paths) . ')
2179 <br />
2180 An \'adequate\' installation for requires \'convert\',
2181 \'combine\'/\'composite\' and \'identify\' to be available
2182 </p>
2183 ', 2);
2184 } else {
2185 // Get the subpart for the ImageMagick versions
2186 $theCode = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($templateFile, '###VERSIONS###');
2187 // Get the subpart for each ImageMagick version
2188 $rowsSubPart = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($theCode, '###ROWS###');
2189 $rows = array();
2190 foreach ($this->config_array['im_versions'] as $p => $v) {
2191 $ka = array();
2192 reset($v);
2193 while (list($ka[]) = each($v)) {
2194
2195 }
2196 // Define the markers content
2197 $rowsMarkers = array(
2198 'file' => $p,
2199 'type' => implode('<br />', $ka),
2200 'version' => implode('<br />', $v)
2201 );
2202 // Fill the markers in the subpart
2203 $rows[] = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($rowsSubPart, $rowsMarkers, '###|###', TRUE, FALSE);
2204 }
2205 // Substitute the subpart for the ImageMagick versions
2206 $theCode = \TYPO3\CMS\Core\Html\HtmlParser::substituteSubpart($theCode, '###ROWS###', implode(LF, $rows));
2207 // Add the content to the message array
2208 $this->message($ext, 'Available ImageMagick/GraphicsMagick installations:', $theCode, -1);
2209 }
2210 // Get the template file
2211 $formSubPart = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($templateFile, '###FORM###');
2212 // Define the markers content
2213 $formMarkers = array(
2214 'actionUrl' => $this->action,
2215 'lzwChecked' => $this->INSTALL['checkIM']['lzw'] ? 'checked="checked"' : '',
2216 'lzwLabel' => 'Check LZW capabilities.',
2217 'checkPath' => 'Check this path for ImageMagick installation:',
2218 'imageMagickPath' => htmlspecialchars($this->INSTALL['checkIM']['path']),
2219 'comment' => '(Eg. "D:\\wwwroot\\im537\\ImageMagick\\" for Windows or "/usr/bin/" for Unix)',
2220 'send' => 'Send'
2221 );
2222 // Fill the markers
2223 $formSubPart = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($formSubPart, $formMarkers, '###|###', TRUE, FALSE);
2224 // Add the content to the message array
2225 $this->message($ext, 'Search for ImageMagick:', $formSubPart, 0);
2226 }
2227
2228 /**
2229 * Checking GIF-compression capabilities of ImageMagick install
2230 *
2231 * @param string $path Path of ImageMagick installation
2232 * @return string Type of compression
2233 * @todo Define visibility
2234 */
2235 public function _checkImageMagickGifCapability($path) {
2236 if ($this->config_array['dir_typo3temp']) {
2237 $tempPath = $this->typo3temp_path;
2238 $uniqueName = md5(uniqid(microtime()));
2239 $dest = $tempPath . $uniqueName . '.gif';
2240 $src = $this->backPath . 'gfx/typo3logo.gif';
2241 if (@is_file($src) && !strstr($src, ' ') && !strstr($dest, ' ')) {
2242 $cmd = \TYPO3\CMS\Core\Utility\GeneralUtility::imageMagickCommand('convert', $src . ' ' . $dest, $path);
2243 \TYPO3\CMS\Core\Utility\CommandUtility::exec($cmd);
2244 } else {
2245 die('No typo3/gfx/typo3logo.gif file!');
2246 }
2247 $out = '';
2248 if (@is_file($dest)) {
2249 $new_info = @getimagesize($dest);
2250 clearstatcache();
2251 $new_size = filesize($dest);
2252 $src_info = @getimagesize($src);
2253 clearstatcache();
2254 $src_size = @filesize($src);
2255 if ($new_info[0] != $src_info[0] || $new_info[1] != $src_info[1] || !$new_size || !$src_size) {
2256 $out = 'error';
2257 } else {
2258 // NONE-LZW ratio was 5.5 in test
2259 if ($new_size / $src_size > 4) {
2260 $out = 'NONE';
2261 } elseif ($new_size / $src_size > 1.5) {
2262 $out = 'RLE';
2263 } else {
2264 $out = 'LZW';
2265 }
2266 }
2267 unlink($dest);
2268 }
2269 return $out;
2270 }
2271 }
2272
2273 /**
2274 * Extracts the version number for ImageMagick
2275 *
2276 * @param string $file The program name to execute in order to find out the version number
2277 * @param string $path Path for the above program
2278 * @return string Version number of the found ImageMagick instance
2279 * @todo Define visibility
2280 */
2281 public function _checkImageMagick_getVersion($file, $path) {
2282 // Temporarily override some settings
2283 $im_version = $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_version_5'];
2284 $combine_filename = $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_combine_filename'];
2285 if ($file == 'gm') {
2286 $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_version_5'] = 'gm';
2287 // Work-around, preventing execution of "gm gm"
2288 $file = 'identify';
2289 // Work-around - GM doesn't like to be executed without any arguments
2290 $parameters = '-version';
2291 } else {
2292 $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_version_5'] = 'im5';
2293 // Override the combine_filename setting
2294 if ($file == 'combine' || $file == 'composite') {
2295 $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_combine_filename'] = $file;
2296 }
2297 }
2298 $cmd = \TYPO3\CMS\Core\Utility\GeneralUtility::imageMagickCommand($file, $parameters, $path);
2299 $retVal = FALSE;
2300 \TYPO3\CMS\Core\Utility\CommandUtility::exec($cmd, $retVal);
2301 $string = $retVal[0];
2302 list(, $ver) = explode('Magick', $string);
2303 list($ver) = explode(' ', trim($ver));
2304 // Restore the values
2305 $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_version_5'] = $im_version;
2306 $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_combine_filename'] = $combine_filename;
2307 return trim($ver);
2308 }
2309
2310 /**
2311 * Checks database username/password/host/database
2312 *
2313 * @return void
2314 * @todo Define visibility
2315 */
2316 public function checkDatabase() {
2317 $ext = 'Check database';
2318 $this->message($ext);
2319 if (!extension_loaded('mysqli') && !\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::isLoaded('dbal')) {
2320 $this->message($ext, 'MySQLi not available', '
2321 <p>
2322 PHP does not feature MySQLi support (which is pretty unusual).
2323 </p>
2324 ', 2);
2325 } else {
2326 if (!TYPO3_db_host || !TYPO3_db_username) {
2327 $this->message($ext, 'Username, password or host not set', '
2328 <p>
2329 You may need to enter data for these values:
2330 <br />
2331 Username: <strong>' . htmlspecialchars(TYPO3_db_username) . '</strong>
2332 <br />
2333 Host: <strong>' . htmlspecialchars(TYPO3_db_host) . '</strong>
2334 <br />
2335 <br />
2336 Use the form below.
2337 </p>
2338 ', 2);
2339 }
2340 if ($result = $GLOBALS['TYPO3_DB']->sql_pconnect(TYPO3_db_host, TYPO3_db_username, TYPO3_db_password)) {
2341 $this->message($ext, 'Connected to SQL database successfully', '
2342 <dl id="t3-install-databaseconnected">
2343 <dt>
2344 Username:
2345 </dt>
2346 <dd>
2347 ' . htmlspecialchars(TYPO3_db_username) . '
2348 </dd>
2349 <dt>
2350 Host:
2351 </dt>
2352 <dd>
2353 ' . htmlspecialchars(TYPO3_db_host) . '
2354 </dd>
2355 </dl>
2356 ', -1, 1);
2357 $this->config_array['mysqlConnect'] = 1;
2358 if (!TYPO3_db) {
2359 $this->message($ext, 'No database selected', '
2360 <p>
2361 Currently you have no database selected.
2362 <br />
2363 Please select one or create a new database.
2364 </p>
2365 ', 3);
2366 $this->config_array['no_database'] = 1;
2367 } elseif (!$GLOBALS['TYPO3_DB']->sql_select_db(TYPO3_db)) {
2368 $this->message($ext, 'Database', '
2369 <p>
2370 \'' . htmlspecialchars(TYPO3_db) . '\' could not be selected as database!
2371 <br />
2372 Please select another one or create a new database.
2373 </p>
2374 ', 3, 1);
2375 $this->config_array['no_database'] = 1;
2376 } else {
2377 $this->message($ext, 'Database', '
2378 <p>
2379 <strong>' . htmlspecialchars(TYPO3_db) . '</strong> is selected as
2380 database.
2381 </p>
2382 ', 1, 1);
2383 }
2384 } else {
2385 $sqlSafeModeUser = '';
2386 if ($this->config_array['sql.safe_mode_user']) {
2387 $sqlSafeModeUser = '
2388 <strong>Notice:</strong>
2389 <em>sql.safe_mode</em> is turned on, so apparently your
2390 username to the database is the same as the scriptowner,
2391 which is ' . $this->config_array['sql.safe_mode_user'];
2392 }
2393 $this->message($ext, 'Could not connect to SQL database!', '
2394 <p>
2395 Connecting to SQL database failed with these settings:
2396 <br />
2397 Username: <strong>' . htmlspecialchars(TYPO3_db_username) . '</strong>
2398 <br />
2399 Host: <strong>' . htmlspecialchars(TYPO3_db_host) . '</strong>
2400 </p>
2401 <p>
2402 Make sure you\'re using the correct set of data.
2403 <br />
2404 ' . $sqlSafeModeUser . '
2405 </p>
2406 ', 3);
2407 }
2408 }
2409 }
2410
2411 /**
2412 * Prints form for updating localconf.php or updates localconf.php depending on $cmd
2413 *
2414 * @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
2415 * @return string Form HTML
2416 * @todo Define visibility
2417 */
2418 public function setupGeneral($cmd = '') {
2419 switch ($cmd) {
2420 case 'get_form':
2421 // Get the template file
2422 $templateFile = @file_get_contents((PATH_site . $this->templateFilePath . 'SetupGeneral.html'));
2423 // Get the template part from the file
2424 $form = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($templateFile, '###TEMPLATE###');
2425 // Get the subpart for all modes
2426 $allModesSubpart = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($form, '###ALLMODES###');
2427 // Define the markers content
2428 $formMarkers['actionUrl'] = $this->action;
2429 // Username
2430 if (TYPO3_db_username) {
2431 $username = TYPO3_db_username;
2432 } elseif ($this->config_array['sql.safe_mode_user']) {
2433 $username = $this->config_array['sql.safe_mode_user'];
2434 // Get the subpart for the sql safe mode user
2435 $sqlSafeModeUserSubpart = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($allModesSubpart, '###SQLSAFEMODEUSERSUBPART###');
2436 // Define the markers content
2437 $sqlSafeModeUserMarkers = array(
2438 'labelSqlSafeModeUser' => 'sql.safe_mode_user:',
2439 'sqlSafeModeUser' => $this->config_array['sql.safe_mode_user']
2440 );
2441 // Fill the markers in the subpart
2442 $sqlSafeModeUserSubpart = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($sqlSafeModeUserSubpart, $sqlSafeModeUserMarkers, '###|###', TRUE, FALSE);
2443 }
2444 // Get the subpart for all modes
2445 $allModesSubpart = \TYPO3\CMS\Core\Html\HtmlParser::substituteSubpart($allModesSubpart, '###SQLSAFEMODEUSERSUBPART###', $sqlSafeModeUserSubpart);
2446 // Define the markers content
2447 $allModesMarkers = array(
2448 'labelUsername' => 'Username:',
2449 'username' => htmlspecialchars($username),
2450 'labelPassword' => 'Password:',
2451 'password' => htmlspecialchars(TYPO3_db_password),
2452 'labelHost' => 'Host:',
2453 'host' => htmlspecialchars(TYPO3_db_host),
2454 'labelDatabase' => 'Database:',
2455 'labelCreateDatabase' => 'Create database?'
2456 );
2457 // Get the subpart for the database list
2458 $databasesSubpart = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($allModesSubpart, '###DATABASELIST###');
2459 if ($this->config_array['mysqlConnect']) {
2460 // Get the subpart when database is available
2461 $databaseAvailableSubpart = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($databasesSubpart, '###DATABASEAVAILABLE###');
2462 // Get the subpart for each database table
2463 $databaseItemSubpart = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($databaseAvailableSubpart, '###DATABASEITEM###');
2464 $dbArr = $this->getDatabaseList();
2465 $dbIncluded = 0;
2466 $databaseItems = array();
2467 foreach ($dbArr as $dbname) {
2468 // Define the markers content
2469 $databaseItemMarkers = array(
2470 'databaseSelected' => '',
2471 'databaseName' => htmlspecialchars($dbname),
2472 'databaseValue' => htmlspecialchars($dbname)
2473 );
2474 if ($dbname == TYPO3_db) {
2475 $databaseItemMarkers['databaseSelected'] = 'selected="selected"';
2476 }
2477 // Fill the markers in the subpart
2478 $databaseItems[] = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($databaseItemSubpart, $databaseItemMarkers, '###|###', TRUE, FALSE);
2479 if ($dbname == TYPO3_db) {
2480 $dbIncluded = 1;
2481 }
2482 }
2483 if (!$dbIncluded && TYPO3_db) {
2484 $databaseItemMarkers['databaseName'] = htmlspecialchars(TYPO3_db);
2485 $databaseItemMarkers['databaseSelected'] = 'selected="selected"';
2486 $databaseItemMarkers['databaseValue'] = htmlspecialchars(TYPO3_db) . ' (NO ACCESS!)';
2487 // Fill the markers in the subpart
2488 $databaseItems[] = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($databaseItemSubpart, $databaseItemMarkers, '###|###', TRUE, FALSE);
2489 }
2490 // Substitute the subpart for the database tables
2491 $databaseAvailableSubpart = \TYPO3\CMS\Core\Html\HtmlParser::substituteSubpart($databaseAvailableSubpart, '###DATABASEITEM###', implode(LF, $databaseItems));
2492 } else {
2493 // Get the subpart when the database is not available
2494 $databaseNotAvailableSubpart = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($databasesSubpart, '###DATABASENOTAVAILABLE###');
2495 $databaseNotAvailableMarkers = array(
2496 'typo3Db' => htmlspecialchars(TYPO3_db),
2497 'labelNoDatabase' => '
2498 (Database cannot be selected. Make sure that username, password and host
2499 are set correctly. If MySQL does not allow persistent connections,
2500 check that $TYPO3_CONF_VARS[\'SYS\'][\'no_pconnect\'] is set to "1".)
2501 '
2502 );
2503 // Fill the markers in the subpart
2504 $databaseNotAvailableSubpart = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($databaseNotAvailableSubpart, $databaseNotAvailableMarkers, '###|###', TRUE, FALSE);
2505 }
2506 // Substitute the subpart when database is available
2507 $databasesSubpart = \TYPO3\CMS\Core\Html\HtmlParser::substituteSubpart($databasesSubpart, '###DATABASEAVAILABLE###', $databaseAvailableSubpart);
2508 // Substitute the subpart when database is not available
2509 $databasesSubpart = \TYPO3\CMS\Core\Html\HtmlParser::substituteSubpart($databasesSubpart, '###DATABASENOTAVAILABLE###', $databaseNotAvailableSubpart);
2510 // Substitute the subpart for the databases
2511 $allModesSubpart = \TYPO3\CMS\Core\Html\HtmlParser::substituteSubpart($allModesSubpart, '###DATABASELIST###', $databasesSubpart);
2512 // Fill the markers in the subpart for all modes
2513 $allModesSubpart = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($allModesSubpart, $allModesMarkers, '###|###', TRUE, FALSE);
2514 // Substitute the subpart for all modes
2515 $form = \TYPO3\CMS\Core\Html\HtmlParser::substituteSubpart($form, '###ALLMODES###', $allModesSubpart);
2516 if ($this->mode != '123') {
2517 // Get the subpart for the regular mode
2518 $regularModeSubpart = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($form, '###REGULARMODE###');
2519 // Define the markers content
2520 $regularModeMarkers = array(
2521 'labelSiteName' => 'Site name:',
2522 'siteName' => htmlspecialchars($GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename']),
2523 'labelEncryptionKey' => 'Encryption key:',
2524 'encryptionKey' => htmlspecialchars($GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey']),
2525 'labelGenerateRandomKey' => 'Generate random key'
2526 );
2527 // Other
2528 $fA = $this->setupGeneralCalculate();
2529 $regularModeMarkers['labelCurrentValueIs'] = 'current value is';
2530 // Disable exec function
2531 if (is_array($fA['disable_exec_function'])) {
2532 // Get the subpart for the disable exec function
2533 $disableExecFunctionSubpart = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($regularModeSubpart, '###DISABLEEXECFUNCTIONSUBPART###');
2534 $regularModeMarkers['labelDisableExecFunction'] = '[BE][disable_exec_function]=';
2535 $regularModeMarkers['strongDisableExecFunction'] = (int) current($fA['disable_exec_function']);
2536 $regularModeMarkers['defaultDisableExecFunction'] = (int) $GLOBALS['TYPO3_CONF_VARS']['BE']['disable_exec_function'];
2537 $regularModeMarkers['disableExecFunction'] = (int) current($fA['disable_exec_function']);
2538 // Fill the markers in the subpart
2539 $disableExecFunctionSubpart = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($disableExecFunctionSubpart, $regularModeMarkers, '###|###', TRUE, FALSE);
2540 }
2541 // Substitute the subpart for the disable exec function
2542 $regularModeSubpart = \TYPO3\CMS\Core\Html\HtmlParser::substituteSubpart($regularModeSubpart, '###DISABLEEXECFUNCTIONSUBPART###', $disableExecFunctionSubpart);
2543 // GDlib
2544 if (is_array($fA['gdlib'])) {
2545 // Get the subpart for the disable gd lib
2546 $gdLibSubpart = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($regularModeSubpart, '###DISABLEGDLIB###');
2547 $regularModeMarkers['labelGdLib'] = '[GFX][gdlib]=';
2548 $regularModeMarkers['strongGdLib'] = (int) current($fA['gdlib']);
2549 $regularModeMarkers['defaultGdLib'] = (int) $GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib'];
2550 $regularModeMarkers['gdLib'] = (int) current($fA['gdlib']);
2551 // Fill the markers in the subpart
2552 $gdLibSubpart = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($gdLibSubpart, $regularModeMarkers, '###|###', TRUE, FALSE);
2553 }
2554 // Substitute the subpart for the disable gdlib
2555 $regularModeSubpart = \TYPO3\CMS\Core\Html\HtmlParser::substituteSubpart($regularModeSubpart, '###DISABLEGDLIB###', $gdLibSubpart);
2556 // GDlib PNG
2557 if (is_array($fA['gdlib_png']) && $GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib']) {
2558 // Get the subpart for the gdlib png
2559 $gdLibPngSubpart = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($regularModeSubpart, '###GDLIBPNGSUBPART###');
2560 // Get the subpart for the dropdown options
2561 $gdLibPngOptionSubpart = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($gdLibPngSubpart, '###GDLIBPNGOPTION###');
2562 $gdLibPngLabels = $this->setLabelValueArray($fA['gdlib_png'], 2);
2563 reset($gdLibPngLabels);
2564 $regularModeMarkers['labelGdLibPng'] = '[GFX][gdlib_png]=';
2565 $regularModeMarkers['strongGdLibPng'] = (string) current($gdLibPngLabels);
2566 $regularModeMarkers['defaultGdLibPng'] = (int) $GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib_png'];
2567 $gdLibPngOptions = array();
2568 foreach ($gdLibPngLabels as $k => $v) {
2569 list($cleanV) = explode('|', $fA['gdlib_png'][$k]);
2570 $gdLibPngMarker['value'] = htmlspecialchars($fA['gdlib_png'][$k]);
2571 $gdLibPngMarker['data'] = htmlspecialchars($v);
2572 if (!strcmp($GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib_png'], $cleanV)) {
2573 $gdLibPngMarker['selected'] = 'selected="selected"';
2574 }
2575 // Fill the markers in the subpart
2576 $gdLibPngOptions[] = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($gdLibPngOptionSubpart, $gdLibPngMarker, '###|###', TRUE, FALSE);
2577 }
2578 // Substitute the subpart for the dropdown options
2579 $gdLibPngSubpart = \TYPO3\CMS\Core\Html\HtmlParser::substituteSubpart($gdLibPngSubpart, '###GDLIBPNGOPTION###', implode(LF, $gdLibPngOptions));
2580 // Fill the markers in the subpart
2581 $gdLibPngSubpart = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($gdLibPngSubpart, $regularModeMarkers, '###|###', TRUE, FALSE);
2582 }
2583 // Substitute the subpart for the gdlib png
2584 $regularModeSubpart = \TYPO3\CMS\Core\Html\HtmlParser::substituteSubpart($regularModeSubpart, '###GDLIBPNGSUBPART###', $gdLibPngSubpart);
2585 // ImageMagick
2586 if (is_array($fA['im'])) {
2587 // Get the subpart for ImageMagick
2588 $imageMagickSubpart = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($regularModeSubpart, '###IMAGEMAGICKSUBPART###');
2589 // Define the markers content
2590 $regularModeMarkers['labelImageMagick'] = '[GFX][im]=';
2591 $regularModeMarkers['strongImageMagick'] = (string) current($fA['im']);
2592 $regularModeMarkers['defaultImageMagick'] = (int) $GLOBALS['TYPO3_CONF_VARS']['GFX']['im'];
2593 $regularModeMarkers['imageMagick'] = (int) current($fA['im']);
2594 // Fill the markers in the subpart
2595 $imageMagickSubpart = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($imageMagickSubpart, $regularModeMarkers, '###|###', TRUE, FALSE);
2596 // IM Combine Filename
2597 // Get the subpart for ImageMagick Combine filename
2598 $imCombineFileNameSubpart = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($regularModeSubpart, '###IMCOMBINEFILENAMESUBPART###');
2599 // Define the markers content
2600 $regularModeMarkers['labelImCombineFilename'] = '[GFX][im_combine_filename]';
2601 $regularModeMarkers['strongImCombineFilename'] = htmlspecialchars((string) current($fA['im_combine_filename']));
2602 $regularModeMarkers['defaultImCombineFilename'] = htmlspecialchars((string) $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_combine_filename']);
2603 $regularModeMarkers['imCombineFilename'] = htmlspecialchars((string) ($fA['im_combine_filename'] ? current($fA['im_combine_filename']) : 'combine'));
2604 // Fill the markers in the subpart
2605 $imCombineFileNameSubpart = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($imCombineFileNameSubpart, $regularModeMarkers, '###|###', TRUE, FALSE);
2606 // IM Version 5
2607 // Get the subpart for ImageMagick Version 5
2608 $imVersion5Subpart = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($regularModeSubpart, '###IMVERSION5SUBPART###');
2609 // Define the markers content
2610 $regularModeMarkers['labelImVersion5'] = '[GFX][im_version_5]=';
2611 $regularModeMarkers['strongImVersion5'] = htmlspecialchars((string) current($fA['im_version_5']));
2612 $regularModeMarkers['defaultImVersion5'] = htmlspecialchars((string) $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_version_5']);
2613 $regularModeMarkers['imVersion5'] = htmlspecialchars((string) ($fA['im_version_5'] ? current($fA['im_version_5']) : ''));
2614 // Fill the markers in the subpart
2615 $imVersion5Subpart = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($imVersion5Subpart, $regularModeMarkers, '###|###', TRUE, FALSE);
2616 if ($GLOBALS['TYPO3_CONF_VARS']['GFX']['im']) {
2617 // IM Path
2618 if (is_array($fA['im_path'])) {
2619 // Get the subpart for ImageMagick path
2620 $imPathSubpart = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($regularModeSubpart, '###IMPATHSUBPART###');
2621 $labelImPath = $this->setLabelValueArray($fA['im_path'], 1);
2622 reset($labelImPath);
2623 $imPath = $this->setLabelValueArray($fA['im_path'], 0);
2624 reset($imPath);
2625 // Define the markers content
2626 $regularModeMarkers['labelImPath'] = '[GFX][im_path]=';
2627 $regularModeMarkers['strongImPath'] = htmlspecialchars((string) current($labelImPath));
2628 $regularModeMarkers['defaultImPath'] = htmlspecialchars((string) $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_path']);
2629 $regularModeMarkers['ImPath'] = htmlspecialchars((string) current($imPath));
2630 // Fill the markers in the subpart
2631 $imPathSubpart = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($imPathSubpart, $regularModeMarkers, '###|###', TRUE, FALSE);
2632 }
2633 // IM Path LZW
2634 if (is_array($fA['im_path_lzw'])) {
2635 // Get the subpart for ImageMagick lzw path
2636 $imPathLzwSubpart = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($regularModeSubpart, '###IMPATHLZWSUBPART###');
2637 // Get the subpart for ImageMagick lzw path dropdown options
2638 $imPathOptionSubpart = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($regularModeSubpart, '###IMPATHLZWOPTION###');
2639 $labelImPathLzw = $this->setLabelValueArray($fA['im_path_lzw'], 1);
2640 reset($labelImPathLzw);
2641 $imPathLzw = $this->setLabelValueArray($fA['im_path_lzw'], 0);
2642 reset($imPathLzw);
2643 // Define the markers content
2644 $regularModeMarkers['labelImPathLzw'] = '[GFX][im_path_lzw]=';
2645 $regularModeMarkers['strongImPathLzw'] = htmlspecialchars((string) current($labelImPathLzw));
2646 $regularModeMarkers['defaultImPathLzw'] = htmlspecialchars((string) $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_path_lzw']);
2647 $regularModeMarkers['ImPathLzw'] = htmlspecialchars((string) current($imPathLzw));
2648 $imPathLzwOptions = array();
2649 foreach ($labelImPathLzw as $k => $v) {
2650 list($cleanV) = explode('|', $fA['im_path_lzw'][$k]);
2651 // Define the markers content
2652 $imPathLzwMarker = array(
2653 'value' => htmlspecialchars($fA['im_path_lzw'][$k]),
2654 'data' => htmlspecialchars($v)
2655 );
2656 if (!strcmp($GLOBALS['TYPO3_CONF_VARS']['GFX']['im_path_lzw'], $cleanV)) {
2657 $imPathLzwMarker['selected'] = 'selected="selected"';
2658 }
2659 // Fill the markers in the subpart
2660 $imPathLzwOptions[] = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($imPathOptionSubpart, $imPathLzwMarker, '###|###', TRUE, FALSE);
2661 }
2662 // Substitute the subpart for ImageMagick lzw path dropdown options
2663 $imPathLzwSubpart = \TYPO3\CMS\Core\Html\HtmlParser::substituteSubpart($imPathLzwSubpart, '###IMPATHLZWOPTION###', implode(LF, $imPathLzwOptions));
2664 // Fill the markers in the subpart
2665 $imPathLzwSubpart = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($imPathLzwSubpart, $regularModeMarkers, '###|###', TRUE, FALSE);
2666 }
2667 }
2668 }
2669 // Substitute the subpart for ImageMagick
2670 $regularModeSubpart = \TYPO3\CMS\Core\Html\HtmlParser::substituteSubpart($regularModeSubpart, '###IMAGEMAGICKSUBPART###', $imageMagickSubpart);
2671 // Substitute the subpart for ImageMagick Combine filename
2672 $regularModeSubpart = \TYPO3\CMS\Core\Html\HtmlParser::substituteSubpart($regularModeSubpart, '###IMCOMBINEFILENAMESUBPART###', $imCombineFileNameSubpart);
2673 // Substitute the subpart for ImageMagick Version 5
2674 $regularModeSubpart = \TYPO3\CMS\Core\Html\HtmlParser::substituteSubpart($regularModeSubpart, '###IMVERSION5SUBPART###', $imVersion5Subpart);
2675 // Substitute the subpart for ImageMagick path
2676 $regularModeSubpart = \TYPO3\CMS\Core\Html\HtmlParser::substituteSubpart($regularModeSubpart, '###IMPATHSUBPART###', $imPathSubpart);
2677 // Substitute the subpart for ImageMagick lzw path
2678 $regularModeSubpart = \TYPO3\CMS\Core\Html\HtmlParser::substituteSubpart($regularModeSubpart, '###IMPATHLZWSUBPART###', $imPathLzwSubpart);
2679 // TrueType Font dpi
2680 // Get the subpart for TrueType dpi
2681 $ttfDpiSubpart = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($regularModeSubpart, '###TTFDPISUBPART###');
2682 // Define the markers content
2683 $regularModeMarkers['labelTtfDpi'] = '[GFX][TTFdpi]=';
2684 $regularModeMarkers['ttfDpi'] = htmlspecialchars($GLOBALS['TYPO3_CONF_VARS']['GFX']['TTFdpi']);
2685 // Fill the markers in the subpart
2686 $ttfDpiSubpart = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($ttfDpiSubpart, $regularModeMarkers, '###|###', TRUE, FALSE);
2687 // Substitute the subpart for TrueType dpi
2688 $regularModeSubpart = \TYPO3\CMS\Core\Html\HtmlParser::substituteSubpart($regularModeSubpart, '###TTFDPISUBPART###', $ttfDpiSubpart);
2689 // Fill the markers in the regular mode subpart
2690 $regularModeSubpart = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($regularModeSubpart, $regularModeMarkers, '###|###', TRUE, FALSE);
2691 }
2692 $formMarkers['labelUpdateLocalConf'] = 'Update configuration';
2693 $formMarkers['labelNotice'] = 'NOTICE:';
2694 $formMarkers['labelCommentUpdateLocalConf'] = 'By clicking this button, the configuration is updated with new values for the parameters listed above!';
2695 // Substitute the subpart for regular mode
2696 $form = \TYPO3\CMS\Core\Html\HtmlParser::substituteSubpart($form, '###REGULARMODE###', $regularModeSubpart);
2697 // Fill the markers
2698 $out = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($form, $formMarkers, '###|###', TRUE, FALSE);
2699 break;
2700 default:
2701 $localConfigurationPathValuePairs = array();
2702 if (is_array($this->INSTALL['Database'])) {
2703 // New database?
2704 if (trim($this->INSTALL['Database']['NEW_DATABASE_NAME'])) {
2705 $newDatabaseName = trim($this->INSTALL['Database']['NEW_DATABASE_NAME']);
2706 // Hyphen is not allowed in unquoted database names (at least for MySQL databases)
2707 if (!preg_match('/[^[:alnum:]_]/', $newDatabaseName)) {
2708 if ($result = $GLOBALS['TYPO3_DB']->sql_pconnect(TYPO3_db_host, TYPO3_db_username, TYPO3_db_password)) {
2709 if ($GLOBALS['TYPO3_DB']->admin_query('CREATE DATABASE ' . $newDatabaseName . ' CHARACTER SET utf8')) {
2710 $this->INSTALL['Database']['typo_db'] = $newDatabaseName;
2711 $this->messages[] = 'Database \'' . $newDatabaseName . '\' created';
2712 } else {
2713 $this->errorMessages[] = '
2714 Could not create database \'' . $newDatabaseName . '\' (...not created)
2715 ';
2716 }
2717 } else {
2718 $this->errorMessages[] = '
2719 Could not connect to database when creating
2720 database \'' . $newDatabaseName . '\' (...not
2721 created)
2722 ';
2723 }
2724 } else {
2725 $this->errorMessages[] = '
2726 The NEW database name \'' . $newDatabaseName . '\' was
2727 not alphanumeric, a-zA-Z0-9_ (...not created)
2728 ';
2729 }
2730 }
2731 foreach ($this->INSTALL['Database'] as $key => $value) {
2732 switch ((string) $key) {
2733 case 'typo_db_username':
2734 if (strlen($value) <= 50) {
2735 if (strcmp(TYPO3_db_username, $value)) {
2736 $localConfigurationPathValuePairs['DB/username'] = $value;
2737 }
2738 } else {
2739 $this->errorMessages[] = '
2740 Username \'' . $value . '\' was longer
2741 than 50 chars (...not saved)
2742 ';
2743 }
2744 break;
2745 case 'typo_db_password':
2746 if (strlen($value) <= 50) {
2747 if (strcmp(TYPO3_db_password, $value)) {
2748 $localConfigurationPathValuePairs['DB/password'] = $value;
2749 }
2750 } else {
2751 $this->errorMessages[] = '
2752 Password was longer than 50 chars (...not saved)
2753 ';
2754 }
2755 break;
2756 case 'typo_db_host':
2757 if (preg_match('/^[a-zA-Z0-9_\\.-]+(:.+)?$/', $value) && strlen($value) <= 50) {
2758 if (strcmp(TYPO3_db_host, $value)) {
2759 $localConfigurationPathValuePairs['DB/host'] = $value;
2760 }
2761 } else {
2762 $this->errorMessages[] = '
2763 Host \'' . $value . '\' was not
2764 alphanumeric (a-z, A-Z, 0-9 or _-.), or
2765 longer than 50 chars (...not saved)
2766 ';
2767 }
2768 break;