83ca9dde1f60c8d80705f9debe8b25d0e1e8a80b
[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(\TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Configuration\\ConfigurationManager')->getDefaultConfigurationFileResource());
1740 $commentArr = $this->getDefaultConfigArrayComments($default_config_content);
1741 switch ($type) {
1742 case 'get_form':
1743 // Get the template file
1744 $templateFile = @file_get_contents((PATH_site . $this->templateFilePath . 'GenerateConfigForm.html'));
1745 // Get the template part from the file
1746 $template = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($templateFile, '###TEMPLATE###');
1747 foreach ($GLOBALS['TYPO3_CONF_VARS'] as $k => $va) {
1748 $ext = '[' . $k . ']';
1749 $this->message($ext, '$TYPO3_CONF_VARS[\'' . $k . '\']', $commentArr[0][$k], 1);
1750 foreach ($va as $vk => $value) {
1751 if (isset($GLOBALS['TYPO3_CONF_VARS_extensionAdded'][$k][$vk])) {
1752 // Don't allow editing stuff which is added by extensions
1753 // Make sure we fix potentially duplicated entries from older setups
1754 $potentialValue = str_replace(array('\'.chr(10).\'', '\' . LF . \''), array(LF, LF), $value);
1755 while (preg_match('/' . preg_quote($GLOBALS['TYPO3_CONF_VARS_extensionAdded'][$k][$vk], '/') . '$/', '', $potentialValue)) {
1756 $potentialValue = preg_replace('/' . preg_quote($GLOBALS['TYPO3_CONF_VARS_extensionAdded'][$k][$vk], '/') . '$/', '', $potentialValue);
1757 }
1758 $value = $potentialValue;
1759 }
1760 $textAreaSubpart = '';
1761 $booleanSubpart = '';
1762 $textLineSubpart = '';
1763 $description = trim($commentArr[1][$k][$vk]);
1764 $isTextarea = preg_match('/^(<.*?>)?string \\(textarea\\)/i', $description) ? TRUE : FALSE;
1765 $doNotRender = preg_match('/^(<.*?>)?string \\(exclude\\)/i', $description) ? TRUE : FALSE;
1766 if (!is_array($value) && !$doNotRender && (!preg_match('/[' . LF . CR . ']/', $value) || $isTextarea)) {
1767 $k2 = '[' . $vk . ']';
1768 if ($isTextarea) {
1769 // Get the subpart for a textarea
1770 $textAreaSubpart = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($template, '###TEXTAREA###');
1771 // Define the markers content
1772 $textAreaMarkers = array(
1773 'id' => $k . '-' . $vk,
1774 'name' => 'TYPO3_INSTALL[extConfig][' . $k . '][' . $vk . ']',
1775 'value' => htmlspecialchars(str_replace(array('\'.chr(10).\'', '\' . LF . \''), array(LF, LF), $value))
1776 );
1777 // Fill the markers in the subpart
1778 $textAreaSubpart = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($textAreaSubpart, $textAreaMarkers, '###|###', TRUE, FALSE);
1779 } elseif (preg_match('/^(<.*?>)?boolean/i', $description)) {
1780 // Get the subpart for a checkbox
1781 $booleanSubpart = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($template, '###BOOLEAN###');
1782 // Define the markers content
1783 $booleanMarkers = array(
1784 'id' => $k . '-' . $vk,
1785 'name' => 'TYPO3_INSTALL[extConfig][' . $k . '][' . $vk . ']',
1786 'value' => $value && strcmp($value, '0') ? $value : 1,
1787 'checked' => $value ? 'checked="checked"' : ''
1788 );
1789 // Fill the markers in the subpart
1790 $booleanSubpart = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($booleanSubpart, $booleanMarkers, '###|###', TRUE, FALSE);
1791 } else {
1792 // Get the subpart for an input text field
1793 $textLineSubpart = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($template, '###TEXTLINE###');
1794 // Define the markers content
1795 $textLineMarkers = array(
1796 'id' => $k . '-' . $vk,
1797 'name' => 'TYPO3_INSTALL[extConfig][' . $k . '][' . $vk . ']',
1798 'value' => htmlspecialchars($value)
1799 );
1800 // Fill the markers in the subpart
1801 $textLineSubpart = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($textLineSubpart, $textLineMarkers, '###|###', TRUE, FALSE);
1802 }
1803 // Substitute the subpart for a textarea
1804 $content = \TYPO3\CMS\Core\Html\HtmlParser::substituteSubpart($template, '###TEXTAREA###', $textAreaSubpart);
1805 // Substitute the subpart for a checkbox
1806 $content = \TYPO3\CMS\Core\Html\HtmlParser::substituteSubpart($content, '###BOOLEAN###', $booleanSubpart);
1807 // Substitute the subpart for an input text field
1808 $content = \TYPO3\CMS\Core\Html\HtmlParser::substituteSubpart($content, '###TEXTLINE###', $textLineSubpart);
1809 // Define the markers content
1810 $markers = array(
1811 'description' => $description,
1812 'key' => '[' . $k . '][' . $vk . ']',
1813 'label' => htmlspecialchars(\TYPO3\CMS\Core\Utility\GeneralUtility::fixed_lgd_cs($value, 40))
1814 );
1815 // Fill the markers
1816 $content = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($content, $markers, '###|###', TRUE, FALSE);
1817 // Add the content to the message array
1818 $this->message($ext, $k2, $content);
1819 }
1820 }
1821 }
1822 break;
1823 default:
1824 if (is_array($this->INSTALL['extConfig'])) {
1825 $configurationPathValuePairs = array();
1826 foreach ($this->INSTALL['extConfig'] as $k => $va) {
1827 if (is_array($GLOBALS['TYPO3_CONF_VARS'][$k])) {
1828 foreach ($va as $vk => $value) {
1829 if (isset($GLOBALS['TYPO3_CONF_VARS'][$k][$vk])) {
1830 $doit = 1;
1831 if ($k == 'BE' && $vk == 'installToolPassword') {
1832 if ($value) {
1833 if (isset($_POST['installToolPassword_check'])) {
1834 if (!$this->formProtection->validateToken((string) $_POST['formToken'], 'installToolPassword', 'change')) {
1835 $doit = FALSE;
1836 break;
1837 }
1838 if (!\TYPO3\CMS\Core\Utility\GeneralUtility::_GP('installToolPassword_check') || strcmp(\TYPO3\CMS\Core\Utility\GeneralUtility::_GP('installToolPassword_check'), $value)) {
1839 $doit = FALSE;
1840 $this->errorMessages[] = 'The two passwords did not ' . 'match! The password was not changed.';
1841 }
1842 }
1843 if (\TYPO3\CMS\Core\Utility\GeneralUtility::_GP('installToolPassword_md5')) {
1844 $value = md5($value);
1845 }
1846 } else {
1847 $doit = 0;
1848 }
1849 }
1850 $description = trim($commentArr[1][$k][$vk]);
1851 if (preg_match('/^string \\(textarea\\)/i', $description)) {
1852 // Force Unix linebreaks in textareas
1853 $value = str_replace(CR, '', $value);
1854 // Preserve linebreaks
1855 $value = str_replace(LF, '\' . LF . \'', $value);
1856 }
1857 if (preg_match('/^boolean/i', $description)) {
1858 // When submitting settings in the Install Tool, values that default to "FALSE" or "TRUE"
1859 // in EXT:core/Configuration/DefaultConfiguration.php will be sent as "0" resp. "1".
1860 // Therefore, reset the values to their boolean equivalent.
1861 if ($GLOBALS['TYPO3_CONF_VARS'][$k][$vk] === FALSE && $value === '0') {
1862 $value = FALSE;
1863 } elseif ($GLOBALS['TYPO3_CONF_VARS'][$k][$vk] === TRUE && $value === '1') {
1864 $value = TRUE;
1865 }
1866 }
1867 if ($doit && strcmp($GLOBALS['TYPO3_CONF_VARS'][$k][$vk], $value)) {
1868 $configurationPathValuePairs['"' . $k . '"' . '/' . '"' . $vk . '"'] = $value;
1869 }
1870 }
1871 }
1872 }
1873 }
1874 $this->setLocalConfigurationValues($configurationPathValuePairs);
1875 }
1876 break;
1877 }
1878 }
1879
1880 /**
1881 * Make an array of the comments in the EXT:core/Configuration/DefaultConfiguration.php file
1882 *
1883 * @param string $string The contents of the EXT:core/Configuration/DefaultConfiguration.php file
1884 * @param array $mainArray
1885 * @param array $commentArray
1886 * @return array
1887 * @todo Define visibility
1888 */
1889 public function getDefaultConfigArrayComments($string, $mainArray = array(), $commentArray = array()) {
1890 $lines = explode(LF, $string);
1891 $in = 0;
1892 $mainKey = '';
1893 foreach ($lines as $lc) {
1894 $lc = trim($lc);
1895 if ($in) {
1896 if (!strcmp($lc, ');')) {
1897 $in = 0;
1898 } else {
1899 if (preg_match('/["\']([[:alnum:]_-]*)["\'][[:space:]]*=>(.*)/i', $lc, $reg)) {
1900 preg_match('/,[\\t\\s]*\\/\\/(.*)/i', $reg[2], $creg);
1901 $theComment = trim($creg[1]);
1902 if (substr(strtolower(trim($reg[2])), 0, 5) == 'array' && !strcmp($reg[1], strtoupper($reg[1]))) {
1903 $mainKey = trim($reg[1]);
1904 $mainArray[$mainKey] = $theComment;
1905 } elseif ($mainKey) {
1906 $commentArray[$mainKey][$reg[1]] = $theComment;
1907 }
1908 }
1909 }
1910 }
1911 if (!strcmp($lc, 'return array(')) {
1912 $in = 1;
1913 }
1914 }
1915 return array($mainArray, $commentArray);
1916 }
1917
1918 /*******************************
1919 *
1920 * CHECK CONFIGURATION FUNCTIONS
1921 *
1922 *******************************/
1923 /**
1924 * Checking php.ini configuration and set appropriate messages and flags.
1925 *
1926 * @return void
1927 * @todo Define visibility
1928 */
1929 public function checkConfiguration() {
1930 $ext = 'php.ini configuration tests';
1931 $this->message($ext);
1932 $this->message($ext, 'Mail test', $this->check_mail('get_form'), -1);
1933
1934 if (\TYPO3\CMS\Core\Utility\PhpOptionsUtility::isSqlSafeModeEnabled()) {
1935 $this->config_array['sql.safe_mode_user'] = get_current_user();
1936 }
1937 }
1938
1939 /**
1940 * Check if PHP function mail() works
1941 *
1942 * @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.
1943 * @return string The mail form if it is requested with get_form
1944 * @todo Define visibility
1945 */
1946 public function check_mail($cmd = '') {
1947 switch ($cmd) {
1948 case 'get_form':
1949 $out = '
1950 <p id="checkMailForm">
1951 You can check the t3lib_mail functionality by entering your email
1952 address here and press the button. You should then
1953 receive a testmail from "typo3installtool@example.org".
1954 </p>
1955 ';
1956 // Get the template file
1957 $templateFile = @file_get_contents((PATH_site . $this->templateFilePath . 'CheckMail.html'));
1958 // Get the template part from the file
1959 $template = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($templateFile, '###TEMPLATE###');
1960 if (!empty($this->mailMessage)) {
1961 // Get the subpart for the mail is sent message
1962 $mailSentSubpart = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($template, '###MAILSENT###');
1963 }
1964 $template = \TYPO3\CMS\Core\Html\HtmlParser::substituteSubpart($template, '###MAILSENT###', $mailSentSubpart);
1965 // Define the markers content
1966 $markers = array(
1967 'message' => $this->mailMessage,
1968 'enterEmail' => 'Enter the email address',
1969 'actionUrl' => $this->action . '#checkMailForm',
1970 'submit' => 'Send test mail'
1971 );
1972 // Fill the markers
1973 $out .= \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($template, $markers, '###|###', TRUE, TRUE);
1974 break;
1975 default:
1976 if (trim($this->INSTALL['check_mail'])) {
1977 $subject = 'TEST SUBJECT';
1978 $email = trim($this->INSTALL['check_mail']);
1979 /** @var $mailMessage \TYPO3\CMS\Core\Mail\MailMessage */
1980 $mailMessage = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Mail\\MailMessage');
1981 $mailMessage->addTo($email)->addFrom('typo3installtool@example.org', 'TYPO3 Install Tool')->setSubject($subject)->setBody('<html><body>HTML TEST CONTENT</body></html>');
1982 $mailMessage->addPart('TEST CONTENT');
1983 $mailMessage->send();
1984 $this->mailMessage = 'Mail was sent to: ' . $email;
1985 }
1986 break;
1987 }
1988 return $out;
1989 }
1990
1991 /**
1992 * Checking php extensions, specifically GDLib and Freetype
1993 *
1994 * @return void
1995 * @todo Define visibility
1996 */
1997 public function checkExtensions() {
1998 if (\TYPO3\CMS\Core\Utility\GeneralUtility::_GP('testingTrueTypeSupport')) {
1999 $this->checkTrueTypeSupport();
2000 }
2001 $ext = 'GDLib';
2002 $this->message($ext);
2003 $this->message($ext, 'FreeType quick-test (as GIF)', '
2004 <p>
2005 <img src="' . htmlspecialchars((\TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('REQUEST_URI') . '&testingTrueTypeSupport=1')) . '" alt="" />
2006 <br />
2007 If the text is exceeding the image borders you are
2008 using Freetype 2 and need to set
2009 TYPO3_CONF_VARS[GFX][TTFdpi]=96.
2010 </p>
2011 ', -1);
2012 }
2013
2014 /**
2015 * Checking and testing that the required writable directories are writable.
2016 *
2017 * @return void
2018 * @todo Define visibility
2019 */
2020 public function checkDirs() {
2021 // Check typo3/temp/
2022 $ext = 'Directories';
2023 $this->message($ext);
2024 $uniqueName = md5(uniqid(microtime()));
2025 // The requirement level (the integer value, ie. the second value of the value array) has the following meanings:
2026 // -1 = not required, but if it exists may be writable or not
2027 // 0 = not required, if it exists the dir should be writable
2028 // 1 = required, don't has to be writable
2029 // 2 = required, has to be writable
2030 $checkWrite = array(
2031 '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'),
2032 'typo3temp/pics/' => array('This folder is part of the typo3temp/ section. It needs to be writable, too.', 2, 'dir_typo3temp'),
2033 'typo3temp/temp/' => array('This folder is part of the typo3temp/ section. It needs to be writable, too.', 2, 'dir_typo3temp'),
2034 'typo3temp/llxml/' => array('This folder is part of the typo3temp/ section. It needs to be writable, too.', 2, 'dir_typo3temp'),
2035 'typo3temp/cs/' => array('This folder is part of the typo3temp/ section. It needs to be writable, too.', 2, 'dir_typo3temp'),
2036 'typo3temp/GB/' => array('This folder is part of the typo3temp/ section. It needs to be writable, too.', 2, 'dir_typo3temp'),
2037 'typo3temp/locks/' => array('This folder is part of the typo3temp/ section. It needs to be writable, too.', 2, 'dir_typo3temp'),
2038 '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),
2039 'typo3conf/ext/' => array('Location for local extensions. Must be writable if the Extension Manager is supposed to install extensions for this website.', 0),
2040 'typo3conf/l10n/' => array('Location for translations. Must be writable if the Extension Manager is supposed to install translations for extensions.', 0),
2041 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),
2042 'uploads/' => array('Location for uploaded files from RTE, in the subdirectories for uploaded files of content elements.', 2),
2043 'uploads/pics/' => array('Typical location for uploaded files (images especially).', 0),
2044 'uploads/media/' => array('Typical location for uploaded files (non-images especially).', 0),
2045 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileadminDir'] => array('Location for local files such as templates, independent uploads etc.', -1),
2046 $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),
2047 $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)
2048 );
2049 foreach ($checkWrite as $relpath => $descr) {
2050 // Check typo3temp/
2051 $general_message = $descr[0];
2052 // If the directory is missing, try to create it
2053 if (!@is_dir((PATH_site . $relpath))) {
2054 \TYPO3\CMS\Core\Utility\GeneralUtility::mkdir(PATH_site . $relpath);
2055 }
2056 if (!@is_dir((PATH_site . $relpath))) {
2057 if ($descr[1]) {
2058 // required...
2059 $this->message($ext, $relpath . ' directory does not exist and could not be created', '
2060 <p>
2061 <em>Full path: ' . PATH_site . $relpath . '</em>
2062 <br />
2063 ' . $general_message . '
2064 </p>
2065 <p>
2066 This error should not occur as ' . $relpath . ' must
2067 always be accessible in the root of a TYPO3 website.
2068 </p>
2069 ', 3);
2070 } else {
2071 if ($descr[1] == 0) {
2072 $msg = 'This directory does not necessarily have to exist but if it does it must be writable.';
2073 } else {
2074 $msg = 'This directory does not necessarily have to exist and if it does it can be writable or not.';
2075 }
2076 $this->message($ext, $relpath . ' directory does not exist', '
2077 <p>
2078 <em>Full path: ' . PATH_site . $relpath . '</em>
2079 <br />
2080 ' . $general_message . '
2081 </p>
2082 <p>
2083 ' . $msg . '
2084 </p>
2085 ', 2);
2086 }
2087 } else {
2088 $file = PATH_site . $relpath . $uniqueName;
2089 @touch($file);
2090 if (@is_file($file)) {
2091 unlink($file);
2092 if ($descr[2]) {
2093 $this->config_array[$descr[2]] = 1;
2094 }
2095 $this->message($ext, $relpath . ' writable', '', -1);
2096 } else {
2097 $severity = $descr[1] == 2 || $descr[1] == 0 ? 3 : 2;
2098 if ($descr[1] == 0 || $descr[1] == 2) {
2099 $msg = 'The directory ' . $relpath . ' must be writable!';
2100 } elseif ($descr[1] == -1 || $descr[1] == 1) {
2101 $msg = 'The directory ' . $relpath . ' does not necessarily have to be writable.';
2102 }
2103 $this->message($ext, $relpath . ' directory not writable', '
2104 <p>
2105 <em>Full path: ' . $file . '</em>
2106 <br />
2107 ' . $general_message . '
2108 </p>
2109 <p>
2110 Tried to write this file (with touch()) but didn\'t
2111 succeed.
2112 <br />
2113 ' . $msg . '
2114 </p>
2115 ', $severity);
2116 }
2117 }
2118 }
2119 }
2120
2121 /**
2122 * Checking for existing ImageMagick installs.
2123 *
2124 * 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.
2125 *
2126 * @param array $paths Possible ImageMagick paths
2127 * @return void
2128 * @todo Define visibility
2129 */
2130 public function checkImageMagick($paths) {
2131 $ext = 'Check Image Magick';
2132 $this->message($ext);
2133 // Get the template file
2134 $templateFile = @file_get_contents((PATH_site . $this->templateFilePath . 'CheckImageMagick.html'));
2135 $paths = array_unique($paths);
2136 $programs = explode(',', 'gm,convert,combine,composite,identify');
2137 $isExt = TYPO3_OS == 'WIN' ? '.exe' : '';
2138 $this->config_array['im_combine_filename'] = 'combine';
2139 foreach ($paths as $k => $v) {
2140 if (!preg_match('/[\\/]$/', $v)) {
2141 $v .= '/';
2142 }
2143 foreach ($programs as $filename) {
2144 if (ini_get('open_basedir') || file_exists($v) && @is_file(($v . $filename . $isExt))) {
2145 $version = $this->_checkImageMagick_getVersion($filename, $v);
2146 if ($version > 0) {
2147 // Assume GraphicsMagick
2148 if ($filename == 'gm') {
2149 $index[$v]['gm'] = $version;
2150 // No need to check for "identify" etc.
2151 continue;
2152 } else {
2153 // Assume ImageMagick
2154 $index[$v][$filename] = $version;
2155 }
2156 }
2157 }
2158 }
2159 if (count($index[$v]) >= 3 || $index[$v]['gm']) {
2160 $this->config_array['im'] = 1;
2161 }
2162 if ($index[$v]['gm'] || !$index[$v]['composite'] && $index[$v]['combine']) {
2163 $this->config_array['im_combine_filename'] = 'combine';
2164 } elseif ($index[$v]['composite'] && !$index[$v]['combine']) {
2165 $this->config_array['im_combine_filename'] = 'composite';
2166 }
2167 if (isset($index[$v]['convert']) && $this->checkIMlzw) {
2168 $index[$v]['gif_capability'] = '' . $this->_checkImageMagickGifCapability($v);
2169 }
2170 }
2171 $this->config_array['im_versions'] = $index;
2172 if (!$this->config_array['im']) {
2173 $this->message($ext, 'No ImageMagick installation available', '
2174 <p>
2175 It seems that there is no adequate ImageMagick installation
2176 available at the checked locations (' . implode(', ', $paths) . ')
2177 <br />
2178 An \'adequate\' installation for requires \'convert\',
2179 \'combine\'/\'composite\' and \'identify\' to be available
2180 </p>
2181 ', 2);
2182 } else {
2183 // Get the subpart for the ImageMagick versions
2184 $theCode = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($templateFile, '###VERSIONS###');
2185 // Get the subpart for each ImageMagick version
2186 $rowsSubPart = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($theCode, '###ROWS###');
2187 $rows = array();
2188 foreach ($this->config_array['im_versions'] as $p => $v) {
2189 $ka = array();
2190 reset($v);
2191 while (list($ka[]) = each($v)) {
2192
2193 }
2194 // Define the markers content
2195 $rowsMarkers = array(
2196 'file' => $p,
2197 'type' => implode('<br />', $ka),
2198 'version' => implode('<br />', $v)
2199 );
2200 // Fill the markers in the subpart
2201 $rows[] = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($rowsSubPart, $rowsMarkers, '###|###', TRUE, FALSE);
2202 }
2203 // Substitute the subpart for the ImageMagick versions
2204 $theCode = \TYPO3\CMS\Core\Html\HtmlParser::substituteSubpart($theCode, '###ROWS###', implode(LF, $rows));
2205 // Add the content to the message array
2206 $this->message($ext, 'Available ImageMagick/GraphicsMagick installations:', $theCode, -1);
2207 }
2208 // Get the template file
2209 $formSubPart = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($templateFile, '###FORM###');
2210 // Define the markers content
2211 $formMarkers = array(
2212 'actionUrl' => $this->action,
2213 'lzwChecked' => $this->INSTALL['checkIM']['lzw'] ? 'checked="checked"' : '',
2214 'lzwLabel' => 'Check LZW capabilities.',
2215 'checkPath' => 'Check this path for ImageMagick installation:',
2216 'imageMagickPath' => htmlspecialchars($this->INSTALL['checkIM']['path']),
2217 'comment' => '(Eg. "D:\\wwwroot\\im537\\ImageMagick\\" for Windows or "/usr/bin/" for Unix)',
2218 'send' => 'Send'
2219 );
2220 // Fill the markers
2221 $formSubPart = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($formSubPart, $formMarkers, '###|###', TRUE, FALSE);
2222 // Add the content to the message array
2223 $this->message($ext, 'Search for ImageMagick:', $formSubPart, 0);
2224 }
2225
2226 /**
2227 * Checking GIF-compression capabilities of ImageMagick install
2228 *
2229 * @param string $path Path of ImageMagick installation
2230 * @return string Type of compression
2231 * @todo Define visibility
2232 */
2233 public function _checkImageMagickGifCapability($path) {
2234 if ($this->config_array['dir_typo3temp']) {
2235 $tempPath = $this->typo3temp_path;
2236 $uniqueName = md5(uniqid(microtime()));
2237 $dest = $tempPath . $uniqueName . '.gif';
2238 $src = $this->backPath . 'gfx/typo3logo.gif';
2239 if (@is_file($src) && !strstr($src, ' ') && !strstr($dest, ' ')) {
2240 $cmd = \TYPO3\CMS\Core\Utility\GeneralUtility::imageMagickCommand('convert', $src . ' ' . $dest, $path);
2241 \TYPO3\CMS\Core\Utility\CommandUtility::exec($cmd);
2242 } else {
2243 die('No typo3/gfx/typo3logo.gif file!');
2244 }
2245 $out = '';
2246 if (@is_file($dest)) {
2247 $new_info = @getimagesize($dest);
2248 clearstatcache();
2249 $new_size = filesize($dest);
2250 $src_info = @getimagesize($src);
2251 clearstatcache();
2252 $src_size = @filesize($src);
2253 if ($new_info[0] != $src_info[0] || $new_info[1] != $src_info[1] || !$new_size || !$src_size) {
2254 $out = 'error';
2255 } else {
2256 // NONE-LZW ratio was 5.5 in test
2257 if ($new_size / $src_size > 4) {
2258 $out = 'NONE';
2259 } elseif ($new_size / $src_size > 1.5) {
2260 $out = 'RLE';
2261 } else {
2262 $out = 'LZW';
2263 }
2264 }
2265 unlink($dest);
2266 }
2267 return $out;
2268 }
2269 }
2270
2271 /**
2272 * Extracts the version number for ImageMagick
2273 *
2274 * @param string $file The program name to execute in order to find out the version number
2275 * @param string $path Path for the above program
2276 * @return string Version number of the found ImageMagick instance
2277 * @todo Define visibility
2278 */
2279 public function _checkImageMagick_getVersion($file, $path) {
2280 // Temporarily override some settings
2281 $im_version = $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_version_5'];
2282 $combine_filename = $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_combine_filename'];
2283 if ($file == 'gm') {
2284 $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_version_5'] = 'gm';
2285 // Work-around, preventing execution of "gm gm"
2286 $file = 'identify';
2287 // Work-around - GM doesn't like to be executed without any arguments
2288 $parameters = '-version';
2289 } else {
2290 $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_version_5'] = 'im5';
2291 // Override the combine_filename setting
2292 if ($file == 'combine' || $file == 'composite') {
2293 $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_combine_filename'] = $file;
2294 }
2295 }
2296 $cmd = \TYPO3\CMS\Core\Utility\GeneralUtility::imageMagickCommand($file, $parameters, $path);
2297 $retVal = FALSE;
2298 \TYPO3\CMS\Core\Utility\CommandUtility::exec($cmd, $retVal);
2299 $string = $retVal[0];
2300 list(, $ver) = explode('Magick', $string);
2301 list($ver) = explode(' ', trim($ver));
2302 // Restore the values
2303 $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_version_5'] = $im_version;
2304 $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_combine_filename'] = $combine_filename;
2305 return trim($ver);
2306 }
2307
2308 /**
2309 * Checks database username/password/host/database
2310 *
2311 * @return void
2312 * @todo Define visibility
2313 */
2314 public function checkDatabase() {
2315 $ext = 'Check database';
2316 $this->message($ext);
2317 if (!extension_loaded('mysqli') && !\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::isLoaded('dbal')) {
2318 $this->message($ext, 'MySQLi not available', '
2319 <p>
2320 PHP does not feature MySQLi support (which is pretty unusual).
2321 </p>
2322 ', 2);
2323 } else {
2324 if (!TYPO3_db_host || !TYPO3_db_username) {
2325 $this->message($ext, 'Username, password or host not set', '
2326 <p>
2327 You may need to enter data for these values:
2328 <br />
2329 Username: <strong>' . htmlspecialchars(TYPO3_db_username) . '</strong>
2330 <br />
2331 Host: <strong>' . htmlspecialchars(TYPO3_db_host) . '</strong>
2332 <br />
2333 <br />
2334 Use the form below.
2335 </p>
2336 ', 2);
2337 }
2338 if ($result = $GLOBALS['TYPO3_DB']->sql_pconnect(TYPO3_db_host, TYPO3_db_username, TYPO3_db_password)) {
2339 $this->message($ext, 'Connected to SQL database successfully', '
2340 <dl id="t3-install-databaseconnected">
2341 <dt>
2342 Username:
2343 </dt>
2344 <dd>
2345 ' . htmlspecialchars(TYPO3_db_username) . '
2346 </dd>
2347 <dt>
2348 Host:
2349 </dt>
2350 <dd>
2351 ' . htmlspecialchars(TYPO3_db_host) . '
2352 </dd>
2353 </dl>
2354 ', -1, 1);
2355 $this->config_array['mysqlConnect'] = 1;
2356 if (!TYPO3_db) {
2357 $this->message($ext, 'No database selected', '
2358 <p>
2359 Currently you have no database selected.
2360 <br />
2361 Please select one or create a new database.
2362 </p>
2363 ', 3);
2364 $this->config_array['no_database'] = 1;
2365 } elseif (!$GLOBALS['TYPO3_DB']->sql_select_db(TYPO3_db)) {
2366 $this->message($ext, 'Database', '
2367 <p>
2368 \'' . htmlspecialchars(TYPO3_db) . '\' could not be selected as database!
2369 <br />
2370 Please select another one or create a new database.
2371 </p>
2372 ', 3, 1);
2373 $this->config_array['no_database'] = 1;
2374 } else {
2375 $this->message($ext, 'Database', '
2376 <p>
2377 <strong>' . htmlspecialchars(TYPO3_db) . '</strong> is selected as
2378 database.
2379 </p>
2380 ', 1, 1);
2381 }
2382 } else {
2383 $sqlSafeModeUser = '';
2384 if ($this->config_array['sql.safe_mode_user']) {
2385 $sqlSafeModeUser = '
2386 <strong>Notice:</strong>
2387 <em>sql.safe_mode</em> is turned on, so apparently your
2388 username to the database is the same as the scriptowner,
2389 which is ' . $this->config_array['sql.safe_mode_user'];
2390 }
2391 $this->message($ext, 'Could not connect to SQL database!', '
2392 <p>
2393 Connecting to SQL database failed with these settings:
2394 <br />
2395 Username: <strong>' . htmlspecialchars(TYPO3_db_username) . '</strong>
2396 <br />
2397 Host: <strong>' . htmlspecialchars(TYPO3_db_host) . '</strong>
2398 </p>
2399 <p>
2400 Make sure you\'re using the correct set of data.
2401 <br />
2402 ' . $sqlSafeModeUser . '
2403 </p>
2404 ', 3);
2405 }
2406 }
2407 }
2408
2409 /**
2410 * Prints form for updating localconf.php or updates localconf.php depending on $cmd
2411 *
2412 * @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
2413 * @return string Form HTML
2414 * @todo Define visibility
2415 */
2416 public function setupGeneral($cmd = '') {
2417 switch ($cmd) {
2418 case 'get_form':
2419 // Get the template file
2420 $templateFile = @file_get_contents((PATH_site . $this->templateFilePath . 'SetupGeneral.html'));
2421 // Get the template part from the file
2422 $form = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($templateFile, '###TEMPLATE###');
2423 // Get the subpart for all modes
2424 $allModesSubpart = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($form, '###ALLMODES###');
2425 // Define the markers content
2426 $formMarkers['actionUrl'] = $this->action;
2427 // Username
2428 if (TYPO3_db_username) {
2429 $username = TYPO3_db_username;
2430 } elseif ($this->config_array['sql.safe_mode_user']) {
2431 $username = $this->config_array['sql.safe_mode_user'];
2432 // Get the subpart for the sql safe mode user
2433 $sqlSafeModeUserSubpart = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($allModesSubpart, '###SQLSAFEMODEUSERSUBPART###');
2434 // Define the markers content
2435 $sqlSafeModeUserMarkers = array(
2436 'labelSqlSafeModeUser' => 'sql.safe_mode_user:',
2437 'sqlSafeModeUser' => $this->config_array['sql.safe_mode_user']
2438 );
2439 // Fill the markers in the subpart
2440 $sqlSafeModeUserSubpart = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($sqlSafeModeUserSubpart, $sqlSafeModeUserMarkers, '###|###', TRUE, FALSE);
2441 }
2442 // Get the subpart for all modes
2443 $allModesSubpart = \TYPO3\CMS\Core\Html\HtmlParser::substituteSubpart($allModesSubpart, '###SQLSAFEMODEUSERSUBPART###', $sqlSafeModeUserSubpart);
2444 // Define the markers content
2445 $allModesMarkers = array(
2446 'labelUsername' => 'Username:',
2447 'username' => htmlspecialchars($username),
2448 'labelPassword' => 'Password:',
2449 'password' => htmlspecialchars(TYPO3_db_password),
2450 'labelHost' => 'Host:',
2451 'host' => htmlspecialchars(TYPO3_db_host),
2452 'labelDatabase' => 'Database:',
2453 'labelCreateDatabase' => 'Create database?'
2454 );
2455 // Get the subpart for the database list
2456 $databasesSubpart = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($allModesSubpart, '###DATABASELIST###');
2457 if ($this->config_array['mysqlConnect']) {
2458 // Get the subpart when database is available
2459 $databaseAvailableSubpart = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($databasesSubpart, '###DATABASEAVAILABLE###');
2460 // Get the subpart for each database table
2461 $databaseItemSubpart = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($databaseAvailableSubpart, '###DATABASEITEM###');
2462 $dbArr = $this->getDatabaseList();
2463 $dbIncluded = 0;
2464 $databaseItems = array();
2465 foreach ($dbArr as $dbname) {
2466 // Define the markers content
2467 $databaseItemMarkers = array(
2468 'databaseSelected' => '',
2469 'databaseName' => htmlspecialchars($dbname),
2470 'databaseValue' => htmlspecialchars($dbname)
2471 );
2472 if ($dbname == TYPO3_db) {
2473 $databaseItemMarkers['databaseSelected'] = 'selected="selected"';
2474 }
2475 // Fill the markers in the subpart
2476 $databaseItems[] = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($databaseItemSubpart, $databaseItemMarkers, '###|###', TRUE, FALSE);
2477 if ($dbname == TYPO3_db) {
2478 $dbIncluded = 1;
2479 }
2480 }
2481 if (!$dbIncluded && TYPO3_db) {
2482 $databaseItemMarkers['databaseName'] = htmlspecialchars(TYPO3_db);
2483 $databaseItemMarkers['databaseSelected'] = 'selected="selected"';
2484 $databaseItemMarkers['databaseValue'] = htmlspecialchars(TYPO3_db) . ' (NO ACCESS!)';
2485 // Fill the markers in the subpart
2486 $databaseItems[] = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($databaseItemSubpart, $databaseItemMarkers, '###|###', TRUE, FALSE);
2487 }
2488 // Substitute the subpart for the database tables
2489 $databaseAvailableSubpart = \TYPO3\CMS\Core\Html\HtmlParser::substituteSubpart($databaseAvailableSubpart, '###DATABASEITEM###', implode(LF, $databaseItems));
2490 } else {
2491 // Get the subpart when the database is not available
2492 $databaseNotAvailableSubpart = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($databasesSubpart, '###DATABASENOTAVAILABLE###');
2493 $databaseNotAvailableMarkers = array(
2494 'typo3Db' => htmlspecialchars(TYPO3_db),
2495 'labelNoDatabase' => '
2496 (Database cannot be selected. Make sure that username, password and host
2497 are set correctly. If MySQL does not allow persistent connections,
2498 check that $TYPO3_CONF_VARS[\'SYS\'][\'no_pconnect\'] is set to "1".)
2499 '
2500 );
2501 // Fill the markers in the subpart
2502 $databaseNotAvailableSubpart = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($databaseNotAvailableSubpart, $databaseNotAvailableMarkers, '###|###', TRUE, FALSE);
2503 }
2504 // Substitute the subpart when database is available
2505 $databasesSubpart = \TYPO3\CMS\Core\Html\HtmlParser::substituteSubpart($databasesSubpart, '###DATABASEAVAILABLE###', $databaseAvailableSubpart);
2506 // Substitute the subpart when database is not available
2507 $databasesSubpart = \TYPO3\CMS\Core\Html\HtmlParser::substituteSubpart($databasesSubpart, '###DATABASENOTAVAILABLE###', $databaseNotAvailableSubpart);
2508 // Substitute the subpart for the databases
2509 $allModesSubpart = \TYPO3\CMS\Core\Html\HtmlParser::substituteSubpart($allModesSubpart, '###DATABASELIST###', $databasesSubpart);
2510 // Fill the markers in the subpart for all modes
2511 $allModesSubpart = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($allModesSubpart, $allModesMarkers, '###|###', TRUE, FALSE);
2512 // Substitute the subpart for all modes
2513 $form = \TYPO3\CMS\Core\Html\HtmlParser::substituteSubpart($form, '###ALLMODES###', $allModesSubpart);
2514 if ($this->mode != '123') {
2515 // Get the subpart for the regular mode
2516 $regularModeSubpart = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($form, '###REGULARMODE###');
2517 // Define the markers content
2518 $regularModeMarkers = array(
2519 'labelSiteName' => 'Site name:',
2520 'siteName' => htmlspecialchars($GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename']),
2521 'labelEncryptionKey' => 'Encryption key:',
2522 'encryptionKey' => htmlspecialchars($GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey']),
2523 'labelGenerateRandomKey' => 'Generate random key'
2524 );
2525 // Other
2526 $fA = $this->setupGeneralCalculate();
2527 $regularModeMarkers['labelCurrentValueIs'] = 'current value is';
2528 // Disable exec function
2529 if (is_array($fA['disable_exec_function'])) {
2530 // Get the subpart for the disable exec function
2531 $disableExecFunctionSubpart = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($regularModeSubpart, '###DISABLEEXECFUNCTIONSUBPART###');
2532 $regularModeMarkers['labelDisableExecFunction'] = '[BE][disable_exec_function]=';
2533 $regularModeMarkers['strongDisableExecFunction'] = (int) current($fA['disable_exec_function']);
2534 $regularModeMarkers['defaultDisableExecFunction'] = (int) $GLOBALS['TYPO3_CONF_VARS']['BE']['disable_exec_function'];
2535 $regularModeMarkers['disableExecFunction'] = (int) current($fA['disable_exec_function']);
2536 // Fill the markers in the subpart
2537 $disableExecFunctionSubpart = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($disableExecFunctionSubpart, $regularModeMarkers, '###|###', TRUE, FALSE);
2538 }
2539 // Substitute the subpart for the disable exec function
2540 $regularModeSubpart = \TYPO3\CMS\Core\Html\HtmlParser::substituteSubpart($regularModeSubpart, '###DISABLEEXECFUNCTIONSUBPART###', $disableExecFunctionSubpart);
2541 // GDlib
2542 if (is_array($fA['gdlib'])) {
2543 // Get the subpart for the disable gd lib
2544 $gdLibSubpart = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($regularModeSubpart, '###DISABLEGDLIB###');
2545 $regularModeMarkers['labelGdLib'] = '[GFX][gdlib]=';
2546 $regularModeMarkers['strongGdLib'] = (int) current($fA['gdlib']);
2547 $regularModeMarkers['defaultGdLib'] = (int) $GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib'];
2548 $regularModeMarkers['gdLib'] = (int) current($fA['gdlib']);
2549 // Fill the markers in the subpart
2550 $gdLibSubpart = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($gdLibSubpart, $regularModeMarkers, '###|###', TRUE, FALSE);
2551 }
2552 // Substitute the subpart for the disable gdlib
2553 $regularModeSubpart = \TYPO3\CMS\Core\Html\HtmlParser::substituteSubpart($regularModeSubpart, '###DISABLEGDLIB###', $gdLibSubpart);
2554 // GDlib PNG
2555 if (is_array($fA['gdlib_png']) && $GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib']) {
2556 // Get the subpart for the gdlib png
2557 $gdLibPngSubpart = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($regularModeSubpart, '###GDLIBPNGSUBPART###');
2558 // Get the subpart for the dropdown options
2559 $gdLibPngOptionSubpart = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($gdLibPngSubpart, '###GDLIBPNGOPTION###');
2560 $gdLibPngLabels = $this->setLabelValueArray($fA['gdlib_png'], 2);
2561 reset($gdLibPngLabels);
2562 $regularModeMarkers['labelGdLibPng'] = '[GFX][gdlib_png]=';
2563 $regularModeMarkers['strongGdLibPng'] = (string) current($gdLibPngLabels);
2564 $regularModeMarkers['defaultGdLibPng'] = (int) $GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib_png'];
2565 $gdLibPngOptions = array();
2566 foreach ($gdLibPngLabels as $k => $v) {
2567 list($cleanV) = explode('|', $fA['gdlib_png'][$k]);
2568 $gdLibPngMarker['value'] = htmlspecialchars($fA['gdlib_png'][$k]);
2569 $gdLibPngMarker['data'] = htmlspecialchars($v);
2570 if (!strcmp($GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib_png'], $cleanV)) {
2571 $gdLibPngMarker['selected'] = 'selected="selected"';
2572 }
2573 // Fill the markers in the subpart
2574 $gdLibPngOptions[] = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($gdLibPngOptionSubpart, $gdLibPngMarker, '###|###', TRUE, FALSE);
2575 }
2576 // Substitute the subpart for the dropdown options
2577 $gdLibPngSubpart = \TYPO3\CMS\Core\Html\HtmlParser::substituteSubpart($gdLibPngSubpart, '###GDLIBPNGOPTION###', implode(LF, $gdLibPngOptions));
2578 // Fill the markers in the subpart
2579 $gdLibPngSubpart = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($gdLibPngSubpart, $regularModeMarkers, '###|###', TRUE, FALSE);
2580 }
2581 // Substitute the subpart for the gdlib png
2582 $regularModeSubpart = \TYPO3\CMS\Core\Html\HtmlParser::substituteSubpart($regularModeSubpart, '###GDLIBPNGSUBPART###', $gdLibPngSubpart);
2583 // ImageMagick
2584 if (is_array($fA['im'])) {
2585 // Get the subpart for ImageMagick
2586 $imageMagickSubpart = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($regularModeSubpart, '###IMAGEMAGICKSUBPART###');
2587 // Define the markers content
2588 $regularModeMarkers['labelImageMagick'] = '[GFX][im]=';
2589 $regularModeMarkers['strongImageMagick'] = (string) current($fA['im']);
2590 $regularModeMarkers['defaultImageMagick'] = (int) $GLOBALS['TYPO3_CONF_VARS']['GFX']['im'];
2591 $regularModeMarkers['imageMagick'] = (int) current($fA['im']);
2592 // Fill the markers in the subpart
2593 $imageMagickSubpart = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($imageMagickSubpart, $regularModeMarkers, '###|###', TRUE, FALSE);
2594 // IM Combine Filename
2595 // Get the subpart for ImageMagick Combine filename
2596 $imCombineFileNameSubpart = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($regularModeSubpart, '###IMCOMBINEFILENAMESUBPART###');
2597 // Define the markers content
2598 $regularModeMarkers['labelImCombineFilename'] = '[GFX][im_combine_filename]';
2599 $regularModeMarkers['strongImCombineFilename'] = htmlspecialchars((string) current($fA['im_combine_filename']));
2600 $regularModeMarkers['defaultImCombineFilename'] = htmlspecialchars((string) $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_combine_filename']);
2601 $regularModeMarkers['imCombineFilename'] = htmlspecialchars((string) ($fA['im_combine_filename'] ? current($fA['im_combine_filename']) : 'combine'));
2602 // Fill the markers in the subpart
2603 $imCombineFileNameSubpart = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($imCombineFileNameSubpart, $regularModeMarkers, '###|###', TRUE, FALSE);
2604 // IM Version 5
2605 // Get the subpart for ImageMagick Version 5
2606 $imVersion5Subpart = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($regularModeSubpart, '###IMVERSION5SUBPART###');
2607 // Define the markers content
2608 $regularModeMarkers['labelImVersion5'] = '[GFX][im_version_5]=';
2609 $regularModeMarkers['strongImVersion5'] = htmlspecialchars((string) current($fA['im_version_5']));
2610 $regularModeMarkers['defaultImVersion5'] = htmlspecialchars((string) $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_version_5']);
2611 $regularModeMarkers['imVersion5'] = htmlspecialchars((string) ($fA['im_version_5'] ? current($fA['im_version_5']) : ''));
2612 // Fill the markers in the subpart
2613 $imVersion5Subpart = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($imVersion5Subpart, $regularModeMarkers, '###|###', TRUE, FALSE);
2614 if ($GLOBALS['TYPO3_CONF_VARS']['GFX']['im']) {
2615 // IM Path
2616 if (is_array($fA['im_path'])) {
2617 // Get the subpart for ImageMagick path
2618 $imPathSubpart = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($regularModeSubpart, '###IMPATHSUBPART###');
2619 $labelImPath = $this->setLabelValueArray($fA['im_path'], 1);
2620 reset($labelImPath);
2621 $imPath = $this->setLabelValueArray($fA['im_path'], 0);
2622 reset($imPath);
2623 // Define the markers content
2624 $regularModeMarkers['labelImPath'] = '[GFX][im_path]=';
2625 $regularModeMarkers['strongImPath'] = htmlspecialchars((string) current($labelImPath));
2626 $regularModeMarkers['defaultImPath'] = htmlspecialchars((string) $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_path']);
2627 $regularModeMarkers['ImPath'] = htmlspecialchars((string) current($imPath));
2628 // Fill the markers in the subpart
2629 $imPathSubpart = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($imPathSubpart, $regularModeMarkers, '###|###', TRUE, FALSE);
2630 }
2631 // IM Path LZW
2632 if (is_array($fA['im_path_lzw'])) {
2633 // Get the subpart for ImageMagick lzw path
2634 $imPathLzwSubpart = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($regularModeSubpart, '###IMPATHLZWSUBPART###');
2635 // Get the subpart for ImageMagick lzw path dropdown options
2636 $imPathOptionSubpart = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($regularModeSubpart, '###IMPATHLZWOPTION###');
2637 $labelImPathLzw = $this->setLabelValueArray($fA['im_path_lzw'], 1);
2638 reset($labelImPathLzw);
2639 $imPathLzw = $this->setLabelValueArray($fA['im_path_lzw'], 0);
2640 reset($imPathLzw);
2641 // Define the markers content
2642 $regularModeMarkers['labelImPathLzw'] = '[GFX][im_path_lzw]=';
2643 $regularModeMarkers['strongImPathLzw'] = htmlspecialchars((string) current($labelImPathLzw));
2644 $regularModeMarkers['defaultImPathLzw'] = htmlspecialchars((string) $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_path_lzw']);
2645 $regularModeMarkers['ImPathLzw'] = htmlspecialchars((string) current($imPathLzw));
2646 $imPathLzwOptions = array();
2647 foreach ($labelImPathLzw as $k => $v) {
2648 list($cleanV) = explode('|', $fA['im_path_lzw'][$k]);
2649 // Define the markers content
2650 $imPathLzwMarker = array(
2651 'value' => htmlspecialchars($fA['im_path_lzw'][$k]),
2652 'data' => htmlspecialchars($v)
2653 );
2654 if (!strcmp($GLOBALS['TYPO3_CONF_VARS']['GFX']['im_path_lzw'], $cleanV)) {
2655 $imPathLzwMarker['selected'] = 'selected="selected"';
2656 }
2657 // Fill the markers in the subpart
2658 $imPathLzwOptions[] = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($imPathOptionSubpart, $imPathLzwMarker, '###|###', TRUE, FALSE);
2659 }
2660 // Substitute the subpart for ImageMagick lzw path dropdown options
2661 $imPathLzwSubpart = \TYPO3\CMS\Core\Html\HtmlParser::substituteSubpart($imPathLzwSubpart, '###IMPATHLZWOPTION###', implode(LF, $imPathLzwOptions));
2662 // Fill the markers in the subpart
2663 $imPathLzwSubpart = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($imPathLzwSubpart, $regularModeMarkers, '###|###', TRUE, FALSE);
2664 }
2665 }
2666 }
2667 // Substitute the subpart for ImageMagick
2668 $regularModeSubpart = \TYPO3\CMS\Core\Html\HtmlParser::substituteSubpart($regularModeSubpart, '###IMAGEMAGICKSUBPART###', $imageMagickSubpart);
2669 // Substitute the subpart for ImageMagick Combine filename
2670 $regularModeSubpart = \TYPO3\CMS\Core\Html\HtmlParser::substituteSubpart($regularModeSubpart, '###IMCOMBINEFILENAMESUBPART###', $imCombineFileNameSubpart);
2671 // Substitute the subpart for ImageMagick Version 5
2672 $regularModeSubpart = \TYPO3\CMS\Core\Html\HtmlParser::substituteSubpart($regularModeSubpart, '###IMVERSION5SUBPART###', $imVersion5Subpart);
2673 // Substitute the subpart for ImageMagick path
2674 $regularModeSubpart = \TYPO3\CMS\Core\Html\HtmlParser::substituteSubpart($regularModeSubpart, '###IMPATHSUBPART###', $imPathSubpart);
2675 // Substitute the subpart for ImageMagick lzw path
2676 $regularModeSubpart = \TYPO3\CMS\Core\Html\HtmlParser::substituteSubpart($regularModeSubpart, '###IMPATHLZWSUBPART###', $imPathLzwSubpart);
2677 // TrueType Font dpi
2678 // Get the subpart for TrueType dpi
2679 $ttfDpiSubpart = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($regularModeSubpart, '###TTFDPISUBPART###');
2680 // Define the markers content
2681 $regularModeMarkers['labelTtfDpi'] = '[GFX][TTFdpi]=';
2682 $regularModeMarkers['ttfDpi'] = htmlspecialchars($GLOBALS['TYPO3_CONF_VARS']['GFX']['TTFdpi']);
2683 // Fill the markers in the subpart
2684 $ttfDpiSubpart = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($ttfDpiSubpart, $regularModeMarkers, '###|###', TRUE, FALSE);
2685 // Substitute the subpart for TrueType dpi
2686 $regularModeSubpart = \TYPO3\CMS\Core\Html\HtmlParser::substituteSubpart($regularModeSubpart, '###TTFDPISUBPART###', $ttfDpiSubpart);
2687 // Fill the markers in the regular mode subpart
2688 $regularModeSubpart = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($regularModeSubpart, $regularModeMarkers, '###|###', TRUE, FALSE);
2689 }
2690 $formMarkers['labelUpdateLocalConf'] = 'Update configuration';
2691 $formMarkers['labelNotice'] = 'NOTICE:';
2692 $formMarkers['labelCommentUpdateLocalConf'] = 'By clicking this button, the configuration is updated with new values for the parameters listed above!';
2693 // Substitute the subpart for regular mode
2694 $form = \TYPO3\CMS\Core\Html\HtmlParser::substituteSubpart($form, '###REGULARMODE###', $regularModeSubpart);
2695 // Fill the markers
2696 $out = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($form, $formMarkers, '###|###', TRUE, FALSE);
2697 break;
2698 default:
2699 $localConfigurationPathValuePairs = array();
2700 if (is_array($this->INSTALL['Database'])) {
2701 // New database?
2702 if (trim($this->INSTALL['Database']['NEW_DATABASE_NAME'])) {
2703 $newDatabaseName = trim($this->INSTALL['Database']['NEW_DATABASE_NAME']);
2704 // Hyphen is not allowed in unquoted database names (at least for MySQL databases)
2705 if (!preg_match('/[^[:alnum:]_]/', $newDatabaseName)) {
2706 if ($result = $GLOBALS['TYPO3_DB']->sql_pconnect(TYPO3_db_host, TYPO3_db_username, TYPO3_db_password)) {
2707 if ($GLOBALS['TYPO3_DB']->admin_query('CREATE DATABASE ' . $newDatabaseName . ' CHARACTER SET utf8')) {
2708 $this->INSTALL['Database']['typo_db'] = $newDatabaseName;
2709 $this->messages[] = 'Database \'' . $newDatabaseName . '\' created';
2710 } else {
2711 $this->errorMessages[] = '
2712 Could not create database \'' . $newDatabaseName . '\' (...not created)
2713 ';
2714 }
2715 } else {
2716 $this->errorMessages[] = '
2717 Could not connect to database when creating
2718 database \'' . $newDatabaseName . '\' (...not
2719 created)
2720 ';
2721 }
2722 } else {
2723 $this->errorMessages[] = '
2724 The NEW database name \'' . $newDatabaseName . '\' was
2725 not alphanumeric, a-zA-Z0-9_ (...not created)
2726 ';
2727 }
2728 }
2729 foreach ($this->INSTALL['Database'] as $key => $value) {
2730 switch ((string) $key) {
2731 case 'typo_db_username':
2732 if (strlen($value) <= 50) {
2733 if (strcmp(TYPO3_db_username, $value)) {
2734 $localConfigurationPathValuePairs['DB/username'] = $value;
2735 }
2736 } else {
2737 $this->errorMessages[] = '
2738 Username \'' . $value . '\' was longer
2739 than 50 chars (...not saved)
2740 ';
2741 }
2742 break;
2743 case 'typo_db_password':
2744 if (strlen($value) <= 50) {
2745 if (strcmp(TYPO3_db_password, $value)) {
2746 $localConfigurationPathValuePairs['DB/password'] = $value;
2747 }
2748 } else {
2749 $this->errorMessages[] = '
2750 Password was longer than 50 chars (...not saved)
2751 ';
2752 }
2753 break;
2754 case 'typo_db_host':
2755 if (preg_match('/^[a-zA-Z0-9_\\.-]+(:.+)?$/', $value) && strlen($value) <= 50) {
2756 if (strcmp(TYPO3_db_host, $value)) {
2757 $localConfigurationPathValuePairs['DB/host'] = $value;
2758 }
2759 } else {
2760 $this->errorMessages[] = '
2761 Host \'' . $value . '\' was not
2762 alphanumeric (a-z, A-Z, 0-9 or _-.), or
2763