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