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