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