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