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