2 namespace TYPO3\CMS\Install
;
4 /***************************************************************
7 * (c) 1999-2013 Kasper Skårhøj (kasperYYYY@typo3.com)
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.
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.
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.
27 * This copyright notice MUST APPEAR in all copies of the script!
28 ***************************************************************/
33 * @author Kasper Skårhøj <kasperYYYY@typo3.com>
34 * @author Ingmar Schlecht <ingmar@typo3.org>
39 * @todo Define visibility
41 public $templateFilePath = 'typo3/sysext/install/Resources/Private/Templates/';
44 * @todo Define visibility
49 * @todo Define visibility
54 * @todo Define visibility
59 * @todo Define visibility
61 public $markers = array();
64 * Used to set (error)messages from the executing functions like mail-sending, writing Localconf and such
68 protected $messages = array();
71 * @todo Define visibility
73 public $errorMessages = array();
76 * @todo Define visibility
78 public $mailMessage = '';
81 * @todo Define visibility
85 // The url that calls this script
87 * @todo Define visibility
89 public $scriptSelf = 'index.php';
91 // The url that calls this script
93 * @todo Define visibility
95 public $updateIdentity = 'TYPO3 Install Tool';
98 * @todo Define visibility
100 public $headerStyle = '';
103 * @todo Define visibility
105 public $setAllCheckBoxesByDefault = 0;
108 * @todo Define visibility
110 public $allowFileEditOutsite_typo3conf_dir = 0;
113 * @todo Define visibility
115 public $INSTALL = array();
117 // In constructor: is set to global GET/POST var TYPO3_INSTALL
119 * @todo Define visibility
121 public $checkIMlzw = 0;
123 // If set, lzw capabilities of the available ImageMagick installs are check by actually writing a gif-file and comparing size
125 * @todo Define visibility
129 // If set, ImageMagick is checked.
131 * @todo Define visibility
133 public $dumpImCommands = 1;
135 // If set, the image Magick commands are always outputted in the image processing checker
137 * @todo Define visibility
141 // If set to "123" then only most vital information is displayed.
143 * @todo Define visibility
147 // If set to 1,2,3 or GO it signifies various functions.
149 * @todo Define visibility
151 public $totalSteps = 4;
156 protected $hasAdditionalSteps = FALSE;
158 // Can be changed by hook to define the total steps in 123 mode
161 * @todo Define visibility
163 public $passwordOK = 0;
165 // This is set, if the password check was ok. The function init() will exit if this is not set
167 * @todo Define visibility
171 // If set, the check routines don't add to the message-array
173 * @todo Define visibility
175 public $sections = array();
177 // Used to gather the message information.
179 * @todo Define visibility
181 public $fatalError = 0;
183 // This is set if some error occured that will definitely prevent TYpo3 from running.
185 * @todo Define visibility
187 public $sendNoCacheHeaders = 1;
190 * @todo Define visibility
192 public $config_array = array(
193 // Flags are set in this array if the options are available and checked ok.
194 'dir_typo3temp' => 0,
196 'im_versions' => array(),
198 'sql.safe_mode_user' => '',
204 * @todo Define visibility
206 public $typo3temp_path = '';
209 * the session handling object
211 * @var \TYPO3\CMS\Install\Session
213 protected $session = NULL;
216 * the form protection instance used for creating and verifying form tokens
218 * @var \TYPO3\CMS\Core\FormProtection\InstallToolFormProtection
220 protected $formProtection = NULL;
223 * @todo Define visibility
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/',
236 'logout' => 'Logout from Install Tool'
240 * Backpath (used for icons etc.)
244 protected $backPath = '../';
247 * @var \TYPO3\CMS\Install\Sql\SchemaMigrator Instance of SQL handler
249 protected $sqlHandler = NULL;
252 * Prefix for checkbox fields when updating database.
256 protected $dbUpdateCheckboxPrefix = 'TYPO3_INSTALL[database_update]';
262 * @todo Define visibility
264 public function __construct() {
265 $this->sqlHandler
= \TYPO3\CMS\Core\Utility\GeneralUtility
::makeInstance('TYPO3\\CMS\\Install\\Sql\\SchemaMigrator');
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');
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');
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') {
287 if (\TYPO3\CMS\Core\Utility\GeneralUtility
::_GP('step') === 'go') {
290 $this->step
= intval(\TYPO3\CMS\Core\Utility\GeneralUtility
::_GP('step'));
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);
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.',
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;
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(
333 if (in_array($_GET['TYPO3_INSTALL']['type'], $allowedTypes)) {
334 $this->INSTALL
['type'] = $_GET['TYPO3_INSTALL']['type'];
337 if ($this->step
== 4) {
338 $this->INSTALL
['type'] = 'database';
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);
346 if ($additionalSteps > 0) {
347 $this->hasAdditionalSteps
= TRUE;
350 $this->totalSteps +
= $additionalSteps;
353 if ($this->mode
== '123') {
354 $tempItems = $this->menuitems
;
355 $this->menuitems
= array(
356 'config' => $tempItems['config'],
357 'database' => $tempItems['database']
359 if (!$this->INSTALL
['type'] ||
!isset($this->menuitems
[$this->INSTALL
['type']])) {
360 $this->INSTALL
['type'] = 'config';
363 if (!$this->INSTALL
['type'] ||
!isset($this->menuitems
[$this->INSTALL
['type']])) {
364 $this->INSTALL
['type'] = 'about';
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');
373 $this->session
= \TYPO3\CMS\Core\Utility\GeneralUtility
::makeInstance('tx_install_session');
374 } catch (\Exception
$exception) {
375 $this->outputErrorAndExit($exception->getMessage());
377 // *******************
378 // Check authorization
379 // *******************
380 if (!$this->session
->hasSession()) {
381 $this->session
->startSession();
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);
391 if ($this->redirect_url
) {
392 \TYPO3\CMS\Core\Utility\HttpUtility
::redirect($this->redirect_url
);
394 $this->formProtection
= \TYPO3\CMS\Core\FormProtection\FormProtectionFactory
::get('TYPO3\\CMS\\Core\\FormProtection\\InstallToolFormProtection');
395 $this->formProtection
->injectInstallTool($this);
402 * Returns TRUE if submitted password is ok.
404 * If password is ok, set session as "authorized".
406 * @return boolean TRUE if the submitted password was ok and session was
407 * @todo Define visibility
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'];
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 <>');
422 // Bad password, send warning:
424 $wEmail = $GLOBALS['TYPO3_CONF_VARS']['BE']['warning_email_addr'];
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 <>');
438 * Create the HTML for the login form
440 * Reads and fills the template.
441 * Substitutes subparts when wrong password has been given
442 * or the session has expired
445 * @todo Define visibility
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)
464 // Fill the markers in the subpart
465 $wrongPasswordSubPart = \TYPO3\CMS\Core\Html\HtmlParser
::substituteMarkerArray($wrongPasswordSubPart, $wrongPasswordMarkers, '###|###', TRUE, TRUE);
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'
475 // Fill the markers in the subpart
476 $sessionExpiredSubPart = \TYPO3\CMS\Core\Html\HtmlParser
::substituteMarkerArray($sessionExpiredSubPart, $sessionExpiredMarkers, '###|###', TRUE, TRUE);
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
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',
490 <p class="typo3-message message-information">
491 The Install Tool Password is <em>not</em> the admin password
494 The default password is <em>joh316</em>. Be sure to change it!
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
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));
511 * Calling function that checks system, IM, GD, dirs, database
512 * and lets you alter localconf.php
514 * This method is called from init.php to start the Install Tool.
517 * @todo Define visibility
519 public function init() {
520 // Must be called after inclusion of init.php (or from init.php)
521 if (!defined('PATH_typo3')) {
524 if (!$this->passwordOK
) {
529 $this->setupGeneral();
530 $this->generateConfigForm();
531 if (count($this->messages
)) {
532 \TYPO3\CMS\Core\Utility\DebugUtility
::debug($this->messages
);
535 $this->output($this->outputWrapper($this->stepOutput()));
538 switch ($this->INSTALL
['type']) {
541 $this->checkTheConfig();
543 $this->checkTheImageProcessing();
546 $this->checkTheConfig();
548 $this->checkTheDatabase();
551 $this->checkDatabase();
553 $this->updateWizard();
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>
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!', '
576 You need to specify database username,
577 password and host as one of the first things.
579 Next you\'ll have to select a database to
587 $this->message($ext, 'Fatal error encountered!', '
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
596 You should also check all warnings that may
601 } elseif ($this->mode
== '123') {
602 if (!$this->fatalError
) {
603 $this->message($ext, 'Basic configuration completed', '
605 You have no fatal errors in your basic
607 You may have warnings though. Please pay
609 However you may continue and install the
614 <span style="color:#f00;">Step 2: </span>
616 <a href="' . $this->scriptSelf
. '?TYPO3_INSTALL[type]=database' . ($this->mode ?
'&mode=' . rawurlencode($this->mode
) : '') . '">Click here to install the database.</a>
621 $this->message($ext, 'Very Important: Changing Image Processing settings', '
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!
628 This is especially important to know, if you\'re
629 trying to set up image processing for the very first
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.
636 $this->message($ext, 'Very Important: Changing Encryption Key setting', '
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,
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.
647 $this->message($ext, 'Update configuration', '
649 This form updates the configuration with the
650 suggested values you see below. The values are based
651 on the analysis above.
653 You can change the values in case you have
654 alternatives to the suggested defaults.
656 By this final step you will configure TYPO3 for
657 immediate use provided that you have no fatal errors
659 </p>' . $this->setupGeneral('get_form') . '
661 $this->output($this->outputWrapper($this->printAll()));
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
672 'action' => $this->action
,
673 'content' => $this->printAll(),
674 'write' => 'Write configuration',
675 'notice' => 'NOTICE:',
677 By clicking this button, the configuration is updated
678 with new values for the parameters listed above!
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));
687 $this->checkTheConfig();
689 $this->cleanupManager();
693 $this->phpinformation();
695 case 'systemEnvironment':
697 $this->systemEnvironmentCheck();
699 case 'typo3conf_edit':
701 $this->typo3conf_edit();
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');
708 $this->formProtection
->clean();
709 $this->session
->destroySession();
710 \TYPO3\CMS\Core\Utility\HttpUtility
::redirect($this->scriptSelf
);
716 $this->message('About', 'Warning - very important!', $this->securityRisk() . $this->alterPasswordForm(), 2);
717 $this->message('About', 'Using this script', '
719 There are three primary steps for you to take:
722 <strong>1: Basic Configuration</strong>
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.
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.
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.
738 <strong>2: Database Analyser</strong>
740 In this step you can either install a new database
741 or update the database from any previous TYPO3
744 You can also get an overview of extra/missing
745 fields/tables in the database compared to a raw
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.
754 <strong>3: Upgrade Wizard</strong>
756 Here you will find update methods taking care of
757 changes to the TYPO3 core which are not backwards
760 It is recommended to run this wizard after every
761 update to make sure everything will still work
765 <strong>4: Image Processing</strong>
767 This step is a visual guide to verify your
768 configuration of the image processing software.
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.
776 <strong>5: All Configuration</strong>
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
784 <strong>6: Cleanup</strong>
786 Here you can clean up the temporary files in typo3temp/
787 folder and the tables used for caching of data in
792 $headCode = 'Header legend';
793 $this->message($headCode, 'Notice!', '
795 Indicates that something is important to be aware
798 This does <em>not</em> indicate an error.
801 $this->message($headCode, 'Just information', '
803 This is a simple message with some information about
807 $this->message($headCode, 'Check was successful', '
809 Indicates that something was checked and returned an
813 $this->message($headCode, 'Warning!', '
815 Indicates that something may very well cause trouble
816 and you should definitely look into it before
819 This indicates a <em>potential</em> error.
822 $this->message($headCode, 'Error!', '
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.
828 This indicates an actual error.
831 $this->output($this->outputWrapper($this->printAll()));
838 * Controls the step 1-2-3-go process
840 * @return string The content to output to the screen
841 * @todo Define visibility
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
850 'stepHeader' => $this->stepHeader(),
851 'notice' => 'Skip this wizard (for power users only)',
852 'skip123' => $this->scriptSelf
854 $this->checkTheConfig();
855 $error_missingConnect = '
856 <p class="typo3-message message-error">
858 There is no connection to the database!
861 (Username: <em>' . htmlspecialchars(TYPO3_db_username
) . '</em>,
862 Host: <em>' . htmlspecialchars(TYPO3_db_host
) . '</em>,
865 Go to Step 1 and enter a valid username and password!
869 <p class="typo3-message message-error">
871 There is no access to the database (<em>' . htmlspecialchars(TYPO3_db
) . '</em>)!
874 Go to Step 2 and select a valid database!
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();
883 <p class="typo3-message message-error">
885 The database is still empty. There are no tables!
888 Go to Step 3 and import a database!
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);
898 // Use the default steps when there is no override
899 if (!$markers['header'] && !$markers['step']) {
900 switch (strtolower($this->step
)) {
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' => '
910 TYPO3 is an enterprise content management system
911 that is powerful, yet easy to install.
914 In three simple steps you\'ll be ready to add content to your website.
917 'step' => $this->step +
1,
918 'action' => htmlspecialchars($this->action
),
919 'continue' => 'Continue'
921 // Add step marker for main template
922 $markers['step'] = \TYPO3\CMS\Core\Html\HtmlParser
::substituteMarkerArray($step1SubPart, $step1SubPartMarkers, '###|###', TRUE, FALSE);
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.'
944 // Add step marker for main template
945 $markers['step'] = \TYPO3\CMS\Core\Html\HtmlParser
::substituteMarkerArray($step2SubPart, $step2SubPartMarkers, '###|###', TRUE, FALSE);
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();
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)
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
) {
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!)'
979 // Add the option HTML to an array
980 $step3DatabaseOptions[] = \TYPO3\CMS\Core\Html\HtmlParser
::substituteMarkerArray($step3DatabaseOptionsSubPart, $step3DatabaseOptionMarkers, '###|###', TRUE, TRUE);
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;
993 $formFieldAttributesNew = 'disabled="disabled"';
994 $formFieldAttributesSelect = 'checked="checked"';
995 $llRemark1 = 'You have no permissions to create new databases.';
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###', '');
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'
1017 // Add step marker for main template
1018 $markers['step'] = \TYPO3\CMS\Core\Html\HtmlParser
::substituteMarkerArray($content, $step3SubPartMarkers, '###|###', TRUE, TRUE);
1020 // Add step marker for main template when no connection
1021 $markers['step'] = $error_missingConnect;
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');
1040 $step4DatabaseTypeOptions = array();
1041 foreach ($sFiles as $f) {
1042 if ($f == 'Default TYPO3 Tables') {
1043 $key = 'CURRENT_TABLES+STATIC';
1045 $key = htmlspecialchars($f);
1047 // Define the markers content for database type subpart
1048 $step4DatabaseTypeOptionMarkers = array(
1049 'databaseTypeValue' => 'import|' . $key,
1050 'databaseName' => htmlspecialchars(basename($f))
1052 // Add the option HTML to an array
1053 $step4DatabaseTypeOptions[] = \TYPO3\CMS\Core\Html\HtmlParser
::substituteMarkerArray($step4DatabaseTypeOptionsSubPart, $step4DatabaseTypeOptionMarkers, '###|###', TRUE, FALSE);
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'
1072 // Add step marker for main template
1073 $markers['step'] = \TYPO3\CMS\Core\Html\HtmlParser
::substituteMarkerArray($content, $step4SubPartMarkers, '###|###', TRUE, TRUE);
1075 // Add step marker for main template when no database
1076 $markers['step'] = $error_missingDB;
1079 // Add step marker for main template when no connection
1080 $markers['step'] = $error_missingConnect;
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(),
1100 <a href="' . $this->scriptSelf
. '">
1101 Change the Install Tool password here
1105 // Add step marker for main template
1106 $markers['step'] = \TYPO3\CMS\Core\Html\HtmlParser
::substituteMarkerArray($stepGoSubPart, $stepGoSubPartMarkers, '###|###', TRUE, TRUE);
1108 // Add step marker for main template when empty database
1109 $markers['step'] = $error_emptyDB;
1112 // Add step marker for main template when no database
1113 $markers['step'] = $error_missingDB;
1116 // Add step marker for main template when no connection
1117 $markers['step'] = $error_missingConnect;
1122 // Fill the markers in the template
1123 $content = \TYPO3\CMS\Core\Html\HtmlParser
::substituteMarkerArray($template, $markers, '###|###', TRUE, FALSE);
1128 * Calling the functions that checks the system
1131 * @todo Define visibility
1133 public function checkTheConfig() {
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']));
1144 $paths = array_merge($paths, explode(';', $_SERVER['PATH']));
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']));
1150 $paths = array_unique($paths);
1152 if ($this->INSTALL
['checkIM']['lzw']) {
1153 $this->checkIMlzw
= 1;
1155 if ($this->INSTALL
['checkIM']['path']) {
1156 $paths[] = trim($this->INSTALL
['checkIM']['path']);
1158 if ($this->checkIM
) {
1159 $this->checkImageMagick($paths);
1161 $this->checkDatabase();
1165 * Editing files in typo3conf directory (or elsewhere if enabled)
1168 * @todo Define visibility
1170 public function typo3conf_edit() {
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;
1179 $this->errorMessages
[] = '
1180 \'' . $tmp_path . '\' was not directory
1184 $this->errorMessages
[] = '
1185 Bad directory name (must be like typo3/)
1189 $headCode = 'Edit files in ' . basename($EDIT_path) . '/';
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);
1201 $backupFile = $this->getBackupFilename($save_to_file);
1202 if ($this->INSTALL
['FILE']['backup']) {
1203 if (@is_file
($backupFile)) {
1204 unlink($backupFile);
1206 rename($save_to_file, $backupFile);
1208 Backup written to <strong>' . $backupFile . '</strong>
1212 \TYPO3\CMS\Core\Utility\GeneralUtility
::writeFile($save_to_file, $save_fileContent);
1214 File saved: <strong>' . $save_to_file . '</strong>
1216 MD5-sum: ' . $this->INSTALL
['FILE']['prevMD5'] . ' (prev)
1218 MD5-sum: ' . md5($save_fileContent) . ' (new)
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###');
1232 $typo3conf_files = \TYPO3\CMS\Core\Utility\GeneralUtility
::getFilesInDir($EDIT_path, '', 1, 1);
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)) {
1240 if ($this->INSTALL
['typo3conf_files'] && !strcmp($this->INSTALL
['typo3conf_files'], $file)) {
1243 // Define the markers content for the files subpart
1244 $filesMarkers = array(
1245 'editUrl' => $this->action
. '&TYPO3_INSTALL[typo3conf_files]=' . rawurlencode($file) . ($this->allowFileEditOutsite_typo3conf_dir ?
'&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"' : ''
1250 // Fill the markers in the subpart
1251 $files[] = \TYPO3\CMS\Core\Html\HtmlParser
::substituteMarkerArray($filesSubpart, $filesMarkers, '###|###', TRUE, FALSE);
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###');
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###');
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',
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) . ')'
1290 // Fill the markers in the subpart to edit the files
1291 $fileEditContent = \TYPO3\CMS\Core\Html\HtmlParser
::substituteMarkerArray($fileEditContent, $fileEditMarkers, '###|###', TRUE, FALSE);
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'],
1303 // Fill the markers in the subpart
1304 $allowFileEditOutsideTypo3ConfDirSubPart = \TYPO3\CMS\Core\Html\HtmlParser
::substituteMarkerArray($allowFileEditOutsideTypo3ConfDirSubPart, $allowFileEditOutsideTypo3ConfDirMarkers, '###|###', TRUE, FALSE);
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
. '&TYPO3_INSTALL[delTempCached]=1',
1316 'deleteTempCached' => 'Delete temp_CACHED* files'
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);
1323 $this->output($this->outputWrapper($this->printAll()));
1327 * Show system environment check
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();
1334 $orderedStatus = array(
1336 'warning' => array(),
1338 'information' => array(),
1339 'notice' => array(),
1342 /** @var $statusObject \TYPO3\CMS\Install\SystemEnvironment\AbstractStatus */
1343 foreach ($statusObjects as $statusObject) {
1344 $severityIdentifier = $statusObject->getSeverity();
1346 if (empty($severityIdentifier) ||
!is_array($orderedStatus[$severityIdentifier])) {
1347 throw new \TYPO3\CMS\Install\
Exception('Unknown status severity type', 1362602559);
1349 $orderedStatus[$severityIdentifier][] = $statusObject;
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>' .
1358 '<div class="message-body" >%3s</div>' .
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();
1368 $messageHtmlBoilerPlate,
1369 $severityIdentifier,
1370 $status->getTitle(),
1371 $status->getMessage()
1376 $this->output($this->outputWrapper($html));
1380 * Outputs system information
1383 * @todo Define visibility
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];
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];
1411 '### DEBUG SYSTEM INFORMATION - START ###'
1413 foreach ($sVar as $kkk => $vvv) {
1414 $debugInfo[] = str_pad(substr($kkk, 0, 20), 20) . ': ' . $vvv;
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
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))
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);
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
1445 $contents = explode('<body>', ob_get_contents());
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">
1460 $this->output($this->outputWrapper($this->printAll()));
1463 /*******************************
1467 *******************************/
1469 * Provides a tool cleaning up various tables in the database
1472 * @author Robert Lemke <rl@robertlemke.de>
1473 * @todo Add more functionality ...
1474 * @todo Define visibility
1476 public function cleanupManager() {
1477 $headCode = 'Clean up your TYPO3 installation';
1478 $this->message($headCode, 'Database cache tables', '
1480 <strong>Clear cached image sizes</strong>
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.
1488 You should <em>Clear All Cache</em> in the backend after
1489 clearing this cache.
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');
1497 $cleanupType = array(
1498 'all' => 'Clean up everything'
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'));
1505 $this->message($headCode, 'Table cache_imagesizes does not exist!', '
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.
1512 $cachedImageSizesCounter = 'unknown';
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)
1527 // Fill the markers in the subpart
1528 $cleanUpOptions[] = \TYPO3\CMS\Core\Html\HtmlParser
::substituteMarkerArray($cleanUpOptionsSubpart, $cleanUpMarkers, '###|###', TRUE, FALSE);
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
1534 'numberCached' => 'Number cached image sizes:',
1535 'number' => $cachedImageSizesCounter,
1536 'action' => $this->action
,
1537 'cleanUp' => 'Clean up',
1538 'execute' => 'Execute'
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', '
1546 TYPO3 uses this directory for temporary files, mainly processed
1549 The filenames are very cryptic; They are unique representations
1550 of the file properties made by md5-hashing a serialized array
1553 Anyway this directory may contain many thousand files and a lot
1554 of them may be of no use anymore.
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
1562 if (!$this->config_array
['dir_typo3temp']) {
1563 $this->message('typo3temp/ directory', 'typo3temp/ not writable!', '
1565 You must make typo3temp/ write enabled before you can
1566 proceed with this test.
1569 $this->output($this->outputWrapper($this->printAll()));
1572 // Run through files
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!');
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)) {
1591 if (\TYPO3\CMS\Core\Utility\MathUtility
::canBeInterpretedAsInteger($tt)) {
1592 if (filesize($theFile) > $tt * 1024) {
1596 if (fileatime($theFile) < $GLOBALS['EXEC_TIME'] - intval($tmap[$tt]) * 60 * 60 * 24) {
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) {
1620 $subdirRegistry = array('' => '');
1621 $d = @dir
($this->typo3temp_path
);
1622 if (is_object($d)) {
1623 while ($entry = $d->read()) {
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))) . ')';
1630 $deleteType = array(
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'
1639 $actionType = array(
1640 '0' => 'Don\'t delete, just display statistics',
1641 '100' => 'Delete 100',
1642 '500' => 'Delete 500',
1643 '1000' => 'Delete 1000'
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)
1659 // Fill the markers in the subpart
1660 $deleteOptions[] = \TYPO3\CMS\Core\Html\HtmlParser
::substituteMarkerArray($deleteOptionsSubpart, $deleteMarkers, '###|###', TRUE, FALSE);
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)
1673 // Fill the markers in the subpart
1674 $actionOptions[] = \TYPO3\CMS\Core\Html\HtmlParser
::substituteMarkerArray($actionOptionsSubpart, $actionMarkers, '###|###', TRUE, FALSE);
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)
1688 // Fill the markers in the subpart
1689 $subDirectoryOptions[] = \TYPO3\CMS\Core\Html\HtmlParser
::substituteMarkerArray($subDirectoryOptionsSubpart, $subDirectoryMarkers, '###|###', TRUE, FALSE);
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
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',
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.
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);
1719 $this->output($this->outputWrapper($this->printAll()));
1722 /*******************************
1724 * CONFIGURATION FORM
1726 ********************************/
1728 * Creating the form for editing the TYPO3_CONF_VARS options.
1730 * @param string $type If get_form, display form, otherwise checks and store in localconf.php
1732 * @todo Define visibility
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()
1738 $commentArr = $this->getDefaultConfigArrayComments($default_config_content);
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);
1756 $value = $potentialValue;
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 . ']';
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))
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"' : ''
1787 // Fill the markers in the subpart
1788 $booleanSubpart = \TYPO3\CMS\Core\Html\HtmlParser
::substituteMarkerArray($booleanSubpart, $booleanMarkers, '###|###', TRUE, FALSE);
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)
1798 // Fill the markers in the subpart
1799 $textLineSubpart = \TYPO3\CMS\Core\Html\HtmlParser
::substituteMarkerArray($textLineSubpart, $textLineMarkers, '###|###', TRUE, FALSE);
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
1809 'description' => $description,
1810 'key' => '[' . $k . '][' . $vk . ']',
1811 'label' => htmlspecialchars(\TYPO3\CMS\Core\Utility\GeneralUtility
::fixed_lgd_cs($value, 40))
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);
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])) {
1829 if ($k == 'BE' && $vk == 'installToolPassword') {
1831 if (isset($_POST['installToolPassword_check'])) {
1832 if (!$this->formProtection
->validateToken((string) $_POST['formToken'], 'installToolPassword', 'change')) {
1836 if (!\TYPO3\CMS\Core\Utility\GeneralUtility
::_GP('installToolPassword_check') ||
strcmp(\TYPO3\CMS\Core\Utility\GeneralUtility
::_GP('installToolPassword_check'), $value)) {
1838 $this->errorMessages
[] = 'The two passwords did not ' . 'match! The password was not changed.';
1841 if (\TYPO3\CMS\Core\Utility\GeneralUtility
::_GP('installToolPassword_md5')) {
1842 $value = md5($value);
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);
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') {
1861 } elseif ($GLOBALS['TYPO3_CONF_VARS'][$k][$vk] === TRUE && $value === '1') {
1865 if ($doit && strcmp($GLOBALS['TYPO3_CONF_VARS'][$k][$vk], $value)) {
1866 $configurationPathValuePairs['"' . $k . '"' . '/' . '"' . $vk . '"'] = $value;
1872 $this->setLocalConfigurationValues($configurationPathValuePairs);
1879 * Make an array of the comments in the EXT:core/Configuration/DefaultConfiguration.php file
1881 * @param string $string The contents of the EXT:core/Configuration/DefaultConfiguration.php file
1882 * @param array $mainArray
1883 * @param array $commentArray
1885 * @todo Define visibility
1887 public function getDefaultConfigArrayComments($string, $mainArray = array(), $commentArray = array()) {
1888 $lines = explode(LF
, $string);
1891 foreach ($lines as $lc) {
1894 if (!strcmp($lc, ');')) {
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;
1909 if (!strcmp($lc, 'return array(')) {
1913 return array($mainArray, $commentArray);
1916 /*******************************
1918 * CHECK CONFIGURATION FUNCTIONS
1920 *******************************/
1922 * Checking php.ini configuration and set appropriate messages and flags.
1925 * @todo Define visibility
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);
1932 if (\TYPO3\CMS\Core\Utility\PhpOptionsUtility
::isSqlSafeModeEnabled()) {
1933 $this->config_array
['sql.safe_mode_user'] = get_current_user();
1938 * Check if PHP function mail() works
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
1944 public function check_mail($cmd = '') {
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".
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###');
1962 $template = \TYPO3\CMS\Core\Html\HtmlParser
::substituteSubpart($template, '###MAILSENT###', $mailSentSubpart);
1963 // Define the markers content
1965 'message' => $this->mailMessage
,
1966 'enterEmail' => 'Enter the email address',
1967 'actionUrl' => $this->action
. '#checkMailForm',
1968 'submit' => 'Send test mail'
1971 $out .= \TYPO3\CMS\Core\Html\HtmlParser
::substituteMarkerArray($template, $markers, '###|###', TRUE, TRUE);
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;
1990 * Checking php extensions, specifically GDLib and Freetype
1993 * @todo Define visibility
1995 public function checkExtensions() {
1996 if (\TYPO3\CMS\Core\Utility\GeneralUtility
::_GP('testingTrueTypeSupport')) {
1997 $this->checkTrueTypeSupport();
2000 $this->message($ext);
2001 $this->message($ext, 'FreeType quick-test (as GIF)', '
2003 <img src="' . htmlspecialchars((\TYPO3\CMS\Core\Utility\GeneralUtility
::getIndpEnv('REQUEST_URI') . '&testingTrueTypeSupport=1')) . '" alt="" />
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.
2013 * Checking and testing that the required writable directories are writable.
2016 * @todo Define visibility
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)
2047 foreach ($checkWrite as $relpath => $descr) {
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);
2054 if (!@is_dir
((PATH_site
. $relpath))) {
2057 $this->message($ext, $relpath . ' directory does not exist and could not be created', '
2059 <em>Full path: ' . PATH_site
. $relpath . '</em>
2061 ' . $general_message . '
2064 This error should not occur as ' . $relpath . ' must
2065 always be accessible in the root of a TYPO3 website.
2069 if ($descr[1] == 0) {
2070 $msg = 'This directory does not necessarily have to exist but if it does it must be writable.';
2072 $msg = 'This directory does not necessarily have to exist and if it does it can be writable or not.';
2074 $this->message($ext, $relpath . ' directory does not exist', '
2076 <em>Full path: ' . PATH_site
. $relpath . '</em>
2078 ' . $general_message . '
2086 $file = PATH_site
. $relpath . $uniqueName;
2088 if (@is_file
($file)) {
2091 $this->config_array
[$descr[2]] = 1;
2093 $this->message($ext, $relpath . ' writable', '', -1);
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.';
2101 $this->message($ext, $relpath . ' directory not writable', '
2103 <em>Full path: ' . $file . '</em>
2105 ' . $general_message . '
2108 Tried to write this file (with touch()) but didn\'t
2120 * Checking for existing ImageMagick installs.
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.
2124 * @param array $paths Possible ImageMagick paths
2126 * @todo Define visibility
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)) {
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);
2145 // Assume GraphicsMagick
2146 if ($filename == 'gm') {
2147 $index[$v]['gm'] = $version;
2148 // No need to check for "identify" etc.
2151 // Assume ImageMagick
2152 $index[$v][$filename] = $version;
2157 if (count($index[$v]) >= 3 ||
$index[$v]['gm']) {
2158 $this->config_array
['im'] = 1;
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';
2165 if (isset($index[$v]['convert']) && $this->checkIMlzw
) {
2166 $index[$v]['gif_capability'] = '' . $this->_checkImageMagickGifCapability($v);
2169 $this->config_array
['im_versions'] = $index;
2170 if (!$this->config_array
['im']) {
2171 $this->message($ext, 'No ImageMagick installation available', '
2173 It seems that there is no adequate ImageMagick installation
2174 available at the checked locations (' . implode(', ', $paths) . ')
2176 An \'adequate\' installation for requires \'convert\',
2177 \'combine\'/\'composite\' and \'identify\' to be available
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###');
2186 foreach ($this->config_array
['im_versions'] as $p => $v) {
2189 while (list($ka[]) = each($v)) {
2192 // Define the markers content
2193 $rowsMarkers = array(
2195 'type' => implode('<br />', $ka),
2196 'version' => implode('<br />', $v)
2198 // Fill the markers in the subpart
2199 $rows[] = \TYPO3\CMS\Core\Html\HtmlParser
::substituteMarkerArray($rowsSubPart, $rowsMarkers, '###|###', TRUE, FALSE);
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);
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)',
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);
2225 * Checking GIF-compression capabilities of ImageMagick install
2227 * @param string $path Path of ImageMagick installation
2228 * @return string Type of compression
2229 * @todo Define visibility
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);
2241 die('No typo3/gfx/typo3logo.gif file!');
2244 if (@is_file
($dest)) {
2245 $new_info = @getimagesize
($dest);
2247 $new_size = filesize($dest);
2248 $src_info = @getimagesize
($src);
2250 $src_size = @filesize
($src);
2251 if ($new_info[0] != $src_info[0] ||
$new_info[1] != $src_info[1] ||
!$new_size ||
!$src_size) {
2254 // NONE-LZW ratio was 5.5 in test
2255 if ($new_size / $src_size > 4) {
2257 } elseif ($new_size / $src_size > 1.5) {
2270 * Extracts the version number for ImageMagick
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
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"
2285 // Work-around - GM doesn't like to be executed without any arguments
2286 $parameters = '-version';
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;
2294 $cmd = \TYPO3\CMS\Core\Utility\GeneralUtility
::imageMagickCommand($file, $parameters, $path);
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;
2307 * Checks database username/password/host/database
2310 * @todo Define visibility
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', '
2318 PHP does not feature MySQLi support (which is pretty unusual).
2322 if (!TYPO3_db_host ||
!TYPO3_db_username
) {
2323 $this->message($ext, 'Username, password or host not set', '
2325 You may need to enter data for these values:
2327 Username: <strong>' . htmlspecialchars(TYPO3_db_username
) . '</strong>
2329 Host: <strong>' . htmlspecialchars(TYPO3_db_host
) . '</strong>
2336 if ($result = $GLOBALS['TYPO3_DB']->sql_pconnect()) {
2337 $this->message($ext, 'Connected to SQL database successfully', '
2338 <dl id="t3-install-databaseconnected">
2343 ' . htmlspecialchars(TYPO3_db_username
) . '
2349 ' . htmlspecialchars(TYPO3_db_host
) . '
2353 $this->config_array
['mysqlConnect'] = 1;
2355 $this->message($ext, 'No database selected', '
2357 Currently you have no database selected.
2359 Please select one or create a new database.
2362 $this->config_array
['no_database'] = 1;
2363 } elseif (!$GLOBALS['TYPO3_DB']->sql_select_db()) {
2364 $this->message($ext, 'Database', '
2366 \'' . htmlspecialchars(TYPO3_db
) . '\' could not be selected as database!
2368 Please select another one or create a new database.
2371 $this->config_array
['no_database'] = 1;
2373 $this->message($ext, 'Database', '
2375 <strong>' . htmlspecialchars(TYPO3_db
) . '</strong> is selected as
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'];
2389 $this->message($ext, 'Could not connect to SQL database!', '
2391 Connecting to SQL database failed with these settings:
2393 Username: <strong>' . htmlspecialchars(TYPO3_db_username
) . '</strong>
2395 Host: <strong>' . htmlspecialchars(TYPO3_db_host
) . '</strong>
2398 Make sure you\'re using the correct set of data.
2400 ' . $sqlSafeModeUser . '
2408 * Prints form for updating localconf.php or updates localconf.php depending on $cmd
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
2414 public function setupGeneral($cmd = '') {
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
;
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']
2437 // Fill the markers in the subpart
2438 $sqlSafeModeUserSubpart = \TYPO3\CMS\Core\Html\HtmlParser
::substituteMarkerArray($sqlSafeModeUserSubpart, $sqlSafeModeUserMarkers, '###|###', TRUE, FALSE);
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?'
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();
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)
2470 if ($dbname == TYPO3_db
) {
2471 $databaseItemMarkers['databaseSelected'] = 'selected="selected"';
2473 // Fill the markers in the subpart
2474 $databaseItems[] = \TYPO3\CMS\Core\Html\HtmlParser
::substituteMarkerArray($databaseItemSubpart, $databaseItemMarkers, '###|###', TRUE, FALSE);
2475 if ($dbname == TYPO3_db
) {
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);
2486 // Substitute the subpart for the database tables
2487 $databaseAvailableSubpart = \TYPO3\CMS\Core\Html\HtmlParser
::substituteSubpart($databaseAvailableSubpart, '###DATABASEITEM###', implode(LF
, $databaseItems));
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".)
2499 // Fill the markers in the subpart
2500 $databaseNotAvailableSubpart = \TYPO3\CMS\Core\Html\HtmlParser
::substituteMarkerArray($databaseNotAvailableSubpart, $databaseNotAvailableMarkers, '###|###', TRUE, FALSE);
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'
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);
2537 // Substitute the subpart for the disable exec function
2538 $regularModeSubpart = \TYPO3\CMS\Core\Html\HtmlParser
::substituteSubpart($regularModeSubpart, '###DISABLEEXECFUNCTIONSUBPART###', $disableExecFunctionSubpart);
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);
2550 // Substitute the subpart for the disable gdlib
2551 $regularModeSubpart = \TYPO3\CMS\Core\Html\HtmlParser
::substituteSubpart($regularModeSubpart, '###DISABLEGDLIB###', $gdLibSubpart);
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"';
2571 // Fill the markers in the subpart
2572 $gdLibPngOptions[] = \TYPO3\CMS\Core\Html\HtmlParser
::substituteMarkerArray($gdLibPngOptionSubpart, $gdLibPngMarker, '###|###', TRUE, FALSE);
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);
2579 // Substitute the subpart for the gdlib png
2580 $regularModeSubpart = \TYPO3\CMS\Core\Html\HtmlParser
::substituteSubpart($regularModeSubpart, '###GDLIBPNGSUBPART###', $gdLibPngSubpart);
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);
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']) {
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);
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);
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);
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)
2652 if (!strcmp($GLOBALS['TYPO3_CONF_VARS']['GFX']['im_path_lzw'], $cleanV)) {
2653 $imPathLzwMarker['selected'] = 'selected="selected"';
2655 // Fill the markers in the subpart
2656 $imPathLzwOptions[] = \TYPO3\CMS\Core\Html\HtmlParser
::substituteMarkerArray($imPathOptionSubpart, $imPathLzwMarker, '###|###', TRUE, FALSE);
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);
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);
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);
2694 $out = \TYPO3\CMS\Core\Html\HtmlParser
::substituteMarkerArray($form, $formMarkers, '###|###', TRUE, FALSE);
2697 $localConfigurationPathValuePairs = array();
2698 if (is_array($this->INSTALL
['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';
2709 $this->errorMessages
[] = '
2710 Could not create database \'' . $newDatabaseName . '\' (...not created)
2714 $this->errorMessages
[] = '
2715 Could not connect to database when creating
2716 database \'' . $newDatabaseName . '\' (...not
2721 $this->errorMessages
[] = '
2722 The NEW database name \'' . $newDatabaseName . '\' was