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