Fixed bug #14402: XSS in Install tool (thanks to Benjamin Mack)
[Packages/TYPO3.CMS.git] / typo3 / sysext / install / mod / class.tx_install.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 1999-2010 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 * $Id$
31 *
32 * @author Kasper Skårhøj <kasperYYYY@typo3.com>
33 * @author Ingmar Schlecht <ingmar@typo3.org>
34 */
35 /**
36 * [CLASS/FUNCTION INDEX of SCRIPT]
37 *
38 *
39 *
40 * 162: class tx_install extends t3lib_install
41 * 234: function tx_install()
42 * 318: function checkPassword()
43 * 362: function loginForm()
44 * 396: function init()
45 * 574: function stepOutput()
46 * 836: function checkTheConfig()
47 * 867: function typo3conf_edit()
48 * 976: function phpinformation()
49 *
50 * SECTION: typo3temp/ manager
51 * 1079: function typo3TempManager()
52 * 1199: function getSelectorOptions($deleteType,$tt='')
53 *
54 * SECTION: cleanup manager
55 * 1231: function cleanupManager()
56 *
57 * SECTION: CONFIGURATION FORM
58 * 1299: function generateConfigForm($type='')
59 * 1367: function getDefaultConfigArrayComments($string,$mainArray=array(),$commentArray=array())
60 *
61 * SECTION: CHECK CONFIGURATION FUNCTIONS
62 * 1419: function checkConfiguration()
63 * 1572: function check_mail($cmd='')
64 * 1611: function checkExtensions()
65 * 1673: function checkDirs()
66 * 1762: function checkImageMagick($paths)
67 * 1837: function _checkImageMagickGifCapability($path)
68 * 1880: function _checkImageMagick_getVersion($file, $path)
69 * 1915: function checkDatabase()
70 * 1977: function setupGeneral($cmd='')
71 * 2166: function writeToLocalconf_control($lines="", $showOutput=1)
72 * 2190: function outputExitBasedOnStep($content)
73 * 2206: function setLabelValueArray($arr,$type)
74 * 2246: function getFormElement($labels,$values,$fieldName,$default,$msg='')
75 * 2266: function getDatabaseList()
76 * 2290: function setupGeneralCalculate()
77 * 2387: function isTTF()
78 *
79 * SECTION: ABOUT the isXXX functions.
80 * 2436: function isGD()
81 * 2447: function isGIF()
82 * 2459: function isJPG()
83 * 2470: function isPNG()
84 * 2482: function ImageTypes()
85 * 2493: function getGDSoftwareInfo()
86 * 2505: function generallyAboutConfiguration()
87 *
88 * SECTION: IMAGE processing
89 * 2565: function checkTheImageProcessing()
90 * 3046: function isExtensionEnabled($ext, $headCode, $short)
91 * 3062: function displayTwinImage ($imageFile, $IMcommands=array(), $note='')
92 * 3130: function getTwinImageMessage($message, $label_1="", $label_2='')
93 * 3146: function formatImCmds($arr)
94 * 3167: function imagemenu()
95 *
96 * SECTION: DATABASE analysing
97 * 3209: function checkTheDatabase()
98 * 3849: function updateWizard()
99 * 3873: function updateWizard_parts($action)
100 * 3987: function getUpgradeObjInstance($className, $identifier)
101 * 4000: function isBackendAdminUser()
102 * 4023: function isBasicComplete($tLabel)
103 * 4063: function generateUpdateDatabaseForm($type, $arr_update, $arr_remove, $action_type)
104 * 4094: function getUpdateDbFormWrap($action_type, $content, $label='Write to database')
105 * 4107: function displayFields($arr, $pre=0, $label='')
106 * 4132: function displayFieldComp($arr, $arr_db)
107 * 4174: function displaySuggestions($arr, $excludeList='')
108 * 4204: function compareDatabaseAndTCA($FDsrc, $TCA, $onlyFields=0)
109 * 4262: function compareTCAandDatabase($TCA, $FDcomp)
110 * 4296: function suggestFieldDefinition($fieldInfo)
111 * 4373: function getItemArrayType($arr)
112 * 4401: function getItemBlobSize($len)
113 * 4412: function suggestTCAFieldDefinition($fieldName,$fieldInfo)
114 * 4555: function includeTCA()
115 *
116 * SECTION: GENERAL FUNCTIONS
117 * 4597: function linkIt($url,$link='')
118 * 4611: function message($head, $short_string='', $long_string='', $type=0, $force=0)
119 * 4632: function printSection($head, $short_string, $long_string, $type)
120 * 4673: function fw($str,$size=1)
121 * 4696: function fwheader($str)
122 * 4707: function wrapInCells($label,$content)
123 * 4716: function printAll()
124 * 4735: function outputWrapper($content)
125 * 4801: function menu()
126 * 4823: function stepHeader()
127 * 4865: function note123()
128 * 4879: function endNotes()
129 * 4912: function securityRisk()
130 * 4930: function alterPasswordForm()
131 * 4946: function messageBasicFinished()
132 * 4968: function setScriptName($type)
133 * 4981: function formWidth($size=48,$textarea=0,$styleOverride='')
134 * 5002: function formWidthText($size=48,$styleOverride='',$wrap='')
135 * 5018: function getBackupFilename($filename)
136 *
137 * TOTAL FUNCTIONS: 82
138 * (This index is automatically created/updated by the extension "extdeveval")
139 *
140 */
141
142 // include requirements definition:
143 require_once(t3lib_extMgm::extPath('install') . 'requirements.php');
144
145 // include update classes
146 require_once(t3lib_extMgm::extPath('install') . 'updates/class.tx_coreupdates_charsetdefaults.php');
147 require_once(t3lib_extMgm::extPath('install').'updates/class.tx_coreupdates_compatversion.php');
148 require_once(t3lib_extMgm::extPath('install').'updates/class.tx_coreupdates_cscsplit.php');
149 require_once(t3lib_extMgm::extPath('install').'updates/class.tx_coreupdates_notinmenu.php');
150 require_once(t3lib_extMgm::extPath('install').'updates/class.tx_coreupdates_mergeadvanced.php');
151 require_once(t3lib_extMgm::extPath('install').'updates/class.tx_coreupdates_installsysexts.php');
152 require_once(t3lib_extMgm::extPath('install').'updates/class.tx_coreupdates_imagescols.php');
153 require_once(t3lib_extMgm::extPath('install').'updates/class.tx_coreupdates_installversioning.php');
154 require_once(t3lib_extMgm::extPath('install').'updates/class.tx_coreupdates_installnewsysexts.php');
155 require_once(t3lib_extMgm::extPath('install') . 'mod/class.tx_install_session.php');
156 require_once(t3lib_extMgm::extPath('install') . 'updates/class.tx_coreupdates_statictemplates.php');
157 require_once(t3lib_extMgm::extPath('install') . 'updates/class.tx_coreupdates_t3skin.php');
158 require_once(t3lib_extMgm::extPath('install') . 'updates/class.tx_coreupdates_compressionlevel.php');
159 require_once(t3lib_extMgm::extPath('install') . 'updates/class.tx_coreupdates_migrateworkspaces.php');
160 require_once(t3lib_extMgm::extPath('install') . 'updates/class.tx_coreupdates_flagsfromsprite.php');
161
162 /**
163 * Install Tool module
164 *
165 * $Id$
166 *
167 * @author Kasper Skårhøj <kasperYYYY@typo3.com>
168 * @author Ingmar Schlecht <ingmar@typo3.org>
169 * @package TYPO3
170 * @subpackage tx_install
171 */
172 class tx_install extends t3lib_install {
173 var $templateFilePath = 'typo3/sysext/install/Resources/Private/Templates/';
174 var $template;
175 var $javascript;
176 var $stylesheets;
177 var $markers = array();
178 var $messages = array();
179 var $errorMessages = array();
180 var $mailMessage = '';
181 var $action = ''; // The url that calls this script
182 var $scriptSelf = 'index.php'; // The url that calls this script
183 var $updateIdentity = 'TYPO3 Install Tool';
184 var $headerStyle ='';
185 var $setAllCheckBoxesByDefault=0;
186
187 var $allowFileEditOutsite_typo3conf_dir=0;
188
189 var $INSTALL =array(); // In constructor: is set to global GET/POST var TYPO3_INSTALL
190 var $checkIMlzw = 0; // If set, lzw capabilities of the available ImageMagick installs are check by actually writing a gif-file and comparing size
191 var $checkIM = 0; // If set, ImageMagick is checked.
192 var $dumpImCommands=1; // If set, the image Magick commands are always outputted in the image processing checker
193 var $mode = ''; // If set to "123" then only most vital information is displayed.
194 var $step = 0; // If set to 1,2,3 or GO it signifies various functions.
195 var $totalSteps = 4; // Can be changed by hook to define the total steps in 123 mode
196
197 // internal
198 var $passwordOK=0; // This is set, if the password check was ok. The function init() will exit if this is not set
199 var $silent=1; // If set, the check routines don't add to the message-array
200 var $sections=array(); // Used to gather the message information.
201 var $fatalError=0; // This is set if some error occured that will definitely prevent TYpo3 from running.
202 var $sendNoCacheHeaders=1;
203 var $config_array = array( // Flags are set in this array if the options are available and checked ok.
204 'gd'=>0,
205 'gd_gif'=>0,
206 'gd_png'=>0,
207 'gd_jpg'=>0,
208 'freetype' => 0,
209 'safemode' => 0,
210 'dir_typo3temp' => 0,
211 'dir_temp' => 0,
212 'im_versions' => array(),
213 'im' => 0,
214 'sql.safe_mode_user' => '',
215 'mysqlConnect' => 0,
216 'no_database' => 0
217 );
218 var $typo3temp_path='';
219 /**
220 * the session handling object
221 *
222 * @var tx_install_session
223 */
224 protected $session = NULL;
225
226 /**
227 * the form protection instance used for creating and verifying form tokens
228 *
229 * @var t3lib_formprotection_InstallToolFormProtection
230 */
231 protected $formProtection = NULL;
232
233 var $menuitems = array(
234 'config' => 'Basic Configuration',
235 'database' => 'Database Analyser',
236 'update' => 'Update Wizard',
237 'images' => 'Image Processing',
238 'extConfig' => 'All Configuration',
239 'cleanup' => 'Clean up',
240 'phpinfo' => 'phpinfo()',
241 'typo3conf_edit' => 'Edit files in typo3conf/',
242 'about' => 'About',
243 'logout' => 'Logout from Install Tool',
244 );
245
246 // PHP modules which are required. Can be changed by hook in getMissingPhpModules()
247 protected $requiredPhpModules = array(
248 'filter',
249 'gd',
250 'json',
251 'mysql',
252 'pcre',
253 'session',
254 'SPL',
255 'standard',
256 'xml',
257 'zlib'
258 );
259
260
261
262
263
264 /**
265 * Constructor
266 *
267 * @return void
268 */
269 function tx_install() {
270 parent::t3lib_install();
271
272 if (!$GLOBALS['TYPO3_CONF_VARS']['BE']['installToolPassword']) {
273 $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');
274 }
275
276 if ($this->sendNoCacheHeaders) {
277 header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
278 header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
279 header('Expires: 0');
280 header('Cache-Control: no-cache, must-revalidate');
281 header('Pragma: no-cache');
282 }
283
284 // ****************************
285 // Initializing incoming vars.
286 // ****************************
287 $this->INSTALL = t3lib_div::_GP('TYPO3_INSTALL');
288 $this->mode = t3lib_div::_GP('mode');
289 if ($this->mode !== '123') {
290 $this->mode = '';
291 }
292 if (t3lib_div::_GP('step') === 'go') {
293 $this->step = 'go';
294 } else {
295 $this->step = intval(t3lib_div::_GP('step'));
296 }
297
298 // Let DBAL decide whether to load itself
299 $dbalLoaderFile = $this->backPath . 'sysext/dbal/class.tx_dbal_autoloader.php';
300 if (@is_file($dbalLoaderFile)) {
301 include($dbalLoaderFile);
302 }
303
304 if ($this->mode === '123') {
305 // Check for mandatory PHP modules
306 $missingPhpModules = $this->getMissingPhpModules();
307 if (count($missingPhpModules) > 0) {
308 throw new RuntimeException('TYPO3 Installation Error: The following PHP module(s) is/are missing: <em>' .
309 implode(', ', $missingPhpModules) .
310 '</em><br /><br />You need to install and enable these modules first to be able to install TYPO3.'
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 $this->message(
606 'System Information',
607 'Your system has the following configuration',
608 '
609 <dl id="systemInformation">
610 <dt>OS detected:</dt>
611 <dd>' . (TYPO3_OS == 'WIN' ? 'WIN' : 'UNIX') .'</dd>
612 <dt>UNIX/CGI detected:</dt>
613 <dd>' . (PHP_SAPI == 'cgi' ? 'YES' : 'NO') . '</dd>
614 <dt>PATH_thisScript:</dt>
615 <dd>' . PATH_thisScript . '</dd>
616 </dl>
617 '
618 );
619 $this->checkTheConfig();
620
621 $ext = 'Write config to localconf.php';
622 if ($this->fatalError) {
623 if (
624 $this->config_array['no_database'] ||
625 !$this->config_array['mysqlConnect']
626 ) {
627 $this->message($ext, 'Database not configured yet!', '
628 <p>
629 You need to specify database username,
630 password and host as one of the first things.
631 <br />
632 Next you\'ll have to select a database to
633 use with TYPO3.
634 </p>
635 <p>
636 Use the form below.
637 </p>
638 ', 2);
639 } else {
640 $this->message($ext, 'Fatal error encountered!', '
641 <p>
642 Somewhere above a fatal configuration
643 problem is encountered.
644 Please make sure that you\'ve fixed this
645 error before you submit the configuration.
646 TYPO3 will not run if this problem is not
647 fixed!
648 <br />
649 You should also check all warnings that may
650 appear.
651 </p>
652 ', 2);
653 }
654 } elseif ($this->mode=='123') {
655 if (!$this->fatalError) {
656 $this->message($ext, 'Basic configuration completed', '
657 <p>
658 You have no fatal errors in your basic
659 configuration.
660 You may have warnings though. Please pay
661 attention to them!
662 However you may continue and install the
663 database.
664 </p>
665 <p>
666 <strong>
667 <span style="color:#f00;">Step 2: </span>
668 </strong>
669 <a href="' . $this->scriptSelf .
670 '?TYPO3_INSTALL[type]=database' .
671 ($this->mode ? '&mode=' . rawurlencode($this->mode) : '') .
672 '">Click here to install the database.</a>
673 </p>
674 ', -1, 1);
675 }
676 }
677 $this->message($ext, 'Very Important: Changing Image Processing settings', '
678 <p>
679 When you change the settings for Image Processing
680 you <em>must</em> take into account
681 that <em>old images</em> may still be in typo3temp/
682 folder and prevent new files from being generated!
683 <br />
684 This is especially important to know, if you\'re
685 trying to set up image processing for the very first
686 time.
687 <br />
688 The problem is solved by <a href="' .
689 htmlspecialchars($this->setScriptName('cleanup')) .
690 '">clearing the typo3temp/ folder</a>.
691 Also make sure to clear the cache_pages table.
692 </p>
693 ', 1, 1);
694 $this->message($ext, 'Very Important: Changing Encryption Key setting', '
695 <p>
696 When you change the setting for the Encryption Key
697 you <em>must</em> take into account that a change to
698 this value might invalidate temporary information,
699 URLs etc.
700 <br />
701 The problem is solved by <a href="' .
702 htmlspecialchars($this->setScriptName('cleanup')) .
703 '">clearing the typo3temp/ folder</a>.
704 Also make sure to clear the cache_pages table.
705 </p>
706 ', 1, 1);
707 $this->message($ext, 'Update localconf.php', '
708 <p>
709 This form updates the localconf.php file with the
710 suggested values you see below. The values are based
711 on the analysis above.
712 <br />
713 You can change the values in case you have
714 alternatives to the suggested defaults.
715 <br />
716 By this final step you will configure TYPO3 for
717 immediate use provided that you have no fatal errors
718 left above.
719 </p>' . $this->setupGeneral('get_form') . '
720 ', 0, 1);
721
722 $this->output($this->outputWrapper($this->printAll()));
723
724 break;
725 case 'extConfig':
726 $this->silent=0;
727 $this->generateConfigForm('get_form');
728 // Get the template file
729 $templateFile = @file_get_contents(
730 PATH_site . $this->templateFilePath . 'InitExtConfig.html'
731 );
732 // Get the template part from the file
733 $template = t3lib_parsehtml::getSubpart(
734 $templateFile, '###TEMPLATE###'
735 );
736 // Define the markers content
737 $markers = array(
738 'action' => $this->action,
739 'content' => $this->printAll(),
740 'write' => 'Write to localconf.php',
741 'notice' => 'NOTICE:',
742 'explanation' => '
743 By clicking this button, localconf.php is updated
744 with new values for the parameters listed above!
745 '
746 );
747 // Fill the markers in the template
748 $content = t3lib_parsehtml::substituteMarkerArray(
749 $template,
750 $markers,
751 '###|###',
752 TRUE,
753 FALSE
754 );
755 // Send content to the page wrapper function
756 $this->output($this->outputWrapper($content));
757 break;
758 case 'cleanup':
759 $this->checkTheConfig();
760 $this->silent=0;
761 $this->cleanupManager();
762 break;
763 case 'phpinfo':
764 $this->silent=0;
765 $this->phpinformation();
766 break;
767 case 'typo3conf_edit':
768 $this->silent=0;
769 $this->typo3conf_edit();
770 break;
771 case 'logout':
772 $enableInstallToolFile = PATH_site . 'typo3conf/ENABLE_INSTALL_TOOL';
773 if (is_file($enableInstallToolFile) && trim(file_get_contents($enableInstallToolFile)) !== 'KEEP_FILE') {
774 unlink(PATH_typo3conf . 'ENABLE_INSTALL_TOOL');
775 }
776 $this->formProtection->clean();
777 $this->session->destroySession();
778 t3lib_utility_Http::redirect($this->scriptSelf);
779 break;
780 case 'about':
781 default:
782 $this->silent=0;
783 $this->message('About', 'Warning - very important!', $this->securityRisk().$this->alterPasswordForm(),2);
784
785 $this->message('About', 'Using this script', '
786 <p>
787 Installing TYPO3 has always been a hot topic on the
788 mailing list and forums. Therefore we\'ve developed
789 this tool which will help you through configuration
790 and testing.
791 <br />
792 There are three primary steps for you to take:
793 </p>
794 <p>
795 <strong>1: Basic Configuration</strong>
796 <br />
797 In this step your PHP-configuration is checked. If
798 there are any settings that will prevent TYPO3 from
799 running correctly you\'ll get warnings and errors
800 with a description of the problem.
801 <br />
802 You\'ll have to enter a database username, password
803 and hostname. Then you can choose to create a new
804 database or select an existing one.
805 <br />
806 Finally the image processing settings are entered
807 and verified and you can choose to let the script
808 update the configuration file,
809 typo3conf/localconf.php with the suggested settings.
810 </p>
811 <p>
812 <strong>2: Database Analyser</strong>
813 <br />
814 In this step you can either install a new database
815 or update the database from any previous TYPO3
816 version.
817 <br />
818 You can also get an overview of extra/missing
819 fields/tables in the database compared to a raw
820 sql-file.
821 <br />
822 The database is also verified against your
823 \'tables.php\' configuration ($TCA) and you can
824 even see suggestions to entries in $TCA or new
825 fields in the database.
826 </p>
827 <p>
828 <strong>3: Update Wizard</strong>
829 <br />
830 Here you will find update methods taking care of
831 changes to the TYPO3 core which are not backwards
832 compatible.
833 <br />
834 It is recommended to run this wizard after every
835 update to make sure everything will still work
836 flawlessly.
837 </p>
838 <p>
839 <strong>4: Image Processing</strong>
840 <br />
841 This step is a visual guide to verify your
842 configuration of the image processing software.
843 <br />
844 You\'ll be presented to a list of images that should
845 all match in pairs. If some irregularity appears,
846 you\'ll get a warning. Thus you\'re able to track an
847 error before you\'ll discover it on your website.
848 </p>
849 <p>
850 <strong>5: All Configuration</strong>
851 <br />
852 This gives you access to any of the configuration
853 options in the TYPO3_CONF_VARS array. Every option
854 is also presented with a comment explaining what it
855 does.
856 </p>
857 <p>
858 <strong>6: Cleanup</strong>
859 <br />
860 Here you can clean up the temporary files in typo3temp/
861 folder and the tables used for caching of data in
862 your database.
863 </p>
864 ');
865
866 $this->message('About', 'Why is this script stand-alone?', '
867 <p>
868 You would think that this script should rather be a
869 module in the backend and access-controlled to only
870 admin-users from the database. But that\'s not how
871 it works.
872 <br />
873 The reason is, that this script must not be
874 depending on the success of the configuration of
875 TYPO3 and whether or not there is a working database
876 behind. Therefore the script is invoked from the
877 backend init.php file, which allows access if the
878 constant \'TYPO3_enterInstallScript\' has been
879 defined and is not false. That is and should be the
880 case <em>only</em> when calling the script
881 \'typo3/install/index.php\' - this script!
882 </p>
883 ');
884
885
886 $headCode='Header legend';
887 $this->message($headCode, 'Notice!', '
888 <p>
889 Indicates that something is important to be aware
890 of.
891 <br />
892 This does <em>not</em> indicate an error.
893 </p>
894 ', 1);
895 $this->message($headCode, 'Just information', '
896 <p>
897 This is a simple message with some information about
898 something.
899 </p>
900 ');
901 $this->message($headCode, 'Check was successful', '
902 <p>
903 Indicates that something was checked and returned an
904 expected result.
905 </p>
906 ', -1);
907 $this->message($headCode, 'Warning!', '
908 <p>
909 Indicates that something may very well cause trouble
910 and you should definitely look into it before
911 proceeding.
912 <br />
913 This indicates a <em>potential</em> error.
914 </p>
915 ', 2);
916 $this->message($headCode, 'Error!', '
917 <p>
918 Indicates that something is definitely wrong and
919 that TYPO3 will most likely not perform as expected
920 if this problem is not solved.
921 <br />
922 This indicates an actual error.
923 </p>
924 ', 3);
925
926 $this->output($this->outputWrapper($this->printAll()));
927 break;
928 }
929 }
930
931 $this->formProtection->persistTokens();
932 }
933
934 /**
935 * Controls the step 1-2-3-go process
936 *
937 * @return string The content to output to the screen
938 */
939 function stepOutput() {
940 // Get the template file
941 $templateFile = @file_get_contents(
942 PATH_site . $this->templateFilePath . 'StepOutput.html'
943 );
944 // Get the template part from the file
945 $template = t3lib_parsehtml::getSubpart(
946 $templateFile, '###TEMPLATE###'
947 );
948 // Define the markers content
949 $markers = array(
950 'stepHeader' => $this->stepHeader(),
951 'notice' => 'Skip this wizard (for power users only)',
952 'skip123' => $this->scriptSelf
953 );
954
955 $this->checkTheConfig();
956 $error_missingConnect = '
957 <p class="typo3-message message-error">
958 <strong>
959 There is no connection to the database!
960 </strong>
961 <br />
962 (Username: <em>' . htmlspecialchars(TYPO3_db_username) . '</em>,
963 Host: <em>' . htmlspecialchars(TYPO3_db_host) . '</em>,
964 Using Password: YES)
965 <br />
966 Go to Step 1 and enter a valid username and password!
967 </p>
968 ';
969 $error_missingDB = '
970 <p class="typo3-message message-error">
971 <strong>
972 There is no access to the database (<em>' . htmlspecialchars(TYPO3_db) . '</em>)!
973 </strong>
974 <br />
975 Go to Step 2 and select a valid database!
976 </p>
977 ';
978
979 // only get the number of tables if it is not the first two steps in the 123-installer
980 // (= no DB connection yet)
981 $whichTables = ($this->step != 1 && $this->step != 2 ? $this->getListOfTables() : array());
982
983 $error_emptyDB = '
984 <p class="typo3-message message-error">
985 <strong>
986 The database is still empty. There are no tables!
987 </strong>
988 <br />
989 Go to Step 3 and import a database!
990 </p>
991 ';
992
993 // Hook to override and add steps to the 1-2-3 installer
994 if (is_array ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install/mod/class.tx_install.php']['stepOutput'])) {
995 foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install/mod/class.tx_install.php']['stepOutput'] as $classData) {
996 $hookObject = t3lib_div::getUserObj($classData);
997 $hookObject->executeStepOutput($markers, $this->step, $this);
998 }
999 }
1000 // Use the default steps when there is no override
1001 if (!$markers['header'] && !$markers['step']) {
1002 switch(strtolower($this->step)) {
1003 case 1:
1004 // Get the subpart for the first step
1005 $step1SubPart = t3lib_parsehtml::getSubpart(
1006 $templateFile, '###STEP1###'
1007 );
1008 // Add header marker for main template
1009 $markers['header'] = 'Welcome to the TYPO3 Install Tool';
1010 // Define the markers content for the subpart
1011 $step1SubPartMarkers = array(
1012 'llIntroduction' => '
1013 <p>
1014 TYPO3 is an enterprise content management system
1015 that is powerful, yet easy to install.
1016 </p>
1017 <p>
1018 In three simple steps you\'ll be ready to add content to your website.
1019 </p>
1020 ',
1021 'step' => $this->step + 1,
1022 'action' => htmlspecialchars($this->action),
1023 'continue' => 'Continue'
1024 );
1025 // Add step marker for main template
1026 $markers['step'] = t3lib_parsehtml::substituteMarkerArray(
1027 $step1SubPart,
1028 $step1SubPartMarkers,
1029 '###|###',
1030 TRUE,
1031 FALSE
1032 );
1033 break;
1034 case 2:
1035 // Get the subpart for the second step
1036 $step2SubPart = t3lib_parsehtml::getSubpart(
1037 $templateFile, '###STEP2###'
1038 );
1039 // Add header marker for main template
1040 $markers['header'] = 'Connect to your database host';
1041 // Define the markers content for the subpart
1042 $step2SubPartMarkers = array(
1043 'step' => $this->step + 1,
1044 'action' => htmlspecialchars($this->action),
1045 'encryptionKey' => $this->createEncryptionKey(),
1046 'branch' => TYPO3_branch,
1047 'labelUsername' => 'Username',
1048 'username' => htmlspecialchars(TYPO3_db_username),
1049 'labelPassword' => 'Password',
1050 'password' => htmlspecialchars(TYPO3_db_password),
1051 'labelHost' => 'Host',
1052 'host' => TYPO3_db_host ? htmlspecialchars(TYPO3_db_host) : 'localhost',
1053 'continue' => 'Continue',
1054 '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.'
1055 );
1056 // Add step marker for main template
1057 $markers['step'] = t3lib_parsehtml::substituteMarkerArray(
1058 $step2SubPart,
1059 $step2SubPartMarkers,
1060 '###|###',
1061 TRUE,
1062 FALSE
1063 );
1064 break;
1065 case 3:
1066 // Add header marker for main template
1067 $markers['header'] = 'Select database';
1068 // There should be a database host connection at this point
1069 if ($result = $GLOBALS['TYPO3_DB']->sql_pconnect(
1070 TYPO3_db_host, TYPO3_db_username, TYPO3_db_password
1071 )) {
1072 // Get the subpart for the third step
1073 $step3SubPart = t3lib_parsehtml::getSubpart(
1074 $templateFile, '###STEP3###'
1075 );
1076 // Get the subpart for the database options
1077 $step3DatabaseOptionsSubPart = t3lib_parsehtml::getSubpart(
1078 $step3SubPart, '###DATABASEOPTIONS###'
1079 );
1080
1081 $dbArr = $this->getDatabaseList();
1082 $dbIncluded = 0;
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(chr(10), $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 $opt='';
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(chr(10), $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(chr(13).chr(10),chr(10),$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(chr(10), $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(chr(10), $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(chr(10), $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(chr(10), $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(chr(10), $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(chr(10), $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(chr(13), '', $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(chr(10),$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 availiable', '
2575 <p>
2576 <em>PHP Sessions availiabe</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 availiabe', '
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 mail() function by entering your email
2658 address here and press the button. You should then
2659 receive a testmail from test@test.test.
2660 <br />
2661 Since almost all mails in TYPO3 are sent using the
2662 t3lib_htmlmail class, sending with this class can be
2663 tested by checking the box
2664 <strong>Test t3lib_htmlmail</strong> below.
2665 The return-path of the mail is set to null@' . t3lib_div::getIndpEnv('HTTP_HOST') . '.
2666 Some mail servers won\'t send the mail if the host of
2667 the return-path is not resolved correctly.
2668 </p>
2669 ';
2670 // Get the template file
2671 $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'CheckMail.html');
2672 // Get the template part from the file
2673 $template = t3lib_parsehtml::getSubpart($templateFile, '###TEMPLATE###');
2674
2675 if (!empty($this->mailMessage)) {
2676 // Get the subpart for the mail is sent message
2677 $mailSentSubpart = t3lib_parsehtml::getSubpart($template, '###MAILSENT###');
2678 }
2679 // Substitute the subpart for the mail is sent message
2680 $template = t3lib_parsehtml::substituteSubpart(
2681 $template,
2682 '###MAILSENT###',
2683 $mailSentSubpart
2684 );
2685 // Define the markers content
2686 $markers = array(
2687 'message' => $this->mailMessage,
2688 'enterEmail' => 'Enter the email address',
2689 'actionUrl' => $this->action . '#checkMailForm',
2690 'useHtmlMailLabel' => 'Test t3lib_htmlmail',
2691 'submit' => 'Send test mail'
2692 );
2693 // Fill the markers
2694 $out .= t3lib_parsehtml::substituteMarkerArray(
2695 $template,
2696 $markers,
2697 '###|###',
2698 TRUE,
2699 TRUE
2700 );
2701 break;
2702 default:
2703 if (trim($this->INSTALL['check_mail'])) {
2704 $subject = 'TEST SUBJECT';
2705 $email = trim($this->INSTALL['check_mail']);
2706
2707 if($this->INSTALL['use_htmlmail']) {
2708 $emailObj = t3lib_div::makeInstance('t3lib_htmlmail');
2709 /* @var $emailObj t3lib_htmlmail */
2710 $emailObj->start();
2711 $emailObj->subject = $subject;
2712 $emailObj->from_email = 'test@test.test';
2713 $emailObj->from_name = 'TYPO3 Install Tool';
2714 $emailObj->returnPath = 'null@'.t3lib_div::getIndpEnv('HTTP_HOST');
2715 $emailObj->addPlain('TEST CONTENT');
2716 $emailObj->setHTML($emailObj->encodeMsg('<html><body>HTML TEST CONTENT</body></html>'));
2717 $emailObj->send($email);
2718 } else {
2719 t3lib_div::plainMailEncoded($email,$subject,'TEST CONTENT','From: test@test.test');
2720 }
2721 $this->mailMessage= 'Mail was sent to: ' . $email;
2722 }
2723 break;
2724 }
2725 return $out;
2726 }
2727
2728 /**
2729 * Checking php extensions, specifically GDLib and Freetype
2730 *
2731 * @return void
2732 */
2733 function checkExtensions() {
2734 $ext = 'GDLib';
2735 $this->message($ext);
2736
2737 $software_info=1;
2738 if (extension_loaded('gd') && $this->isGD()) {
2739 $this->config_array['gd']=1;
2740 $this->message($ext, 'GDLib found',"",-1);
2741 if ($this->isPNG()) {
2742 $this->config_array['gd_png']=1;
2743 $this->message($ext, 'PNG supported',"",-1);
2744 }
2745 if ($this->isGIF()) {
2746 $this->config_array['gd_gif']=1;
2747 $this->message($ext, 'GIF supported',"",-1);
2748 }
2749 if ($this->isJPG()) {
2750 $this->config_array['gd_jpg']=1;
2751 $this->message($ext, 'JPG supported (not used by TYPO3)','');
2752 }
2753 if (!$this->config_array['gd_gif'] && !$this->config_array['gd_png']) {
2754 $this->message($ext, 'PNG or GIF not supported', '
2755 <p>
2756 Your GDLib supports either GIF nor PNG. It must support
2757 either one of them.
2758 </p>
2759 ', 2);
2760 } else {
2761 $msg=array();
2762 if ($this->config_array['gd_gif'] && $this->config_array['gd_png']) {
2763 $msg[] = '
2764 <p>
2765 You can choose between generating GIF or PNG files,
2766 as your GDLib supports both.
2767 </p>
2768 ';
2769 }
2770 if ($this->config_array['gd_gif']) {
2771 $msg[] = '
2772 <p>
2773 You should watch out for the generated size of the
2774 GIF-files because some versions of the GD library do
2775 not compress them with LZW, but RLE and ImageMagick
2776 is subsequently used to compress with LZW. But in
2777 the case of ImageMagick failing this task (eg. not
2778 being compiled with LZW which is the case with some
2779 versions) you\'ll end up with GIF-filesizes all too
2780 big!
2781 <br />
2782 This Install Tool tests what kinds of GIF
2783 compression are available in the ImageMagick
2784 installations by a physical test. You can also check
2785 it manually by opening a TYPO3 generated gif-file
2786 with Photoshop and save it in a new file. If the
2787 file sizes of the original and the new file are
2788 almost the same, you\'re having LZW compression and
2789 everything is fine.
2790 </p>
2791 ';
2792 }
2793 if ($this->config_array['gd_png']) {
2794 $msg[] = '
2795 <p>
2796 TYPO3 prefers the use of GIF-files and most likely
2797 your visitors on your website does too as not all
2798 browsers support PNG yet.
2799 </p>
2800 ';
2801 }
2802 $this->message($ext, 'GIF / PNG issues', implode($msg, chr(10)), 1);
2803 }
2804 if (!$this->isTTF()) {
2805 $this->message($ext, 'FreeType is apparently not installed', '
2806 <p>
2807 It looks like the FreeType library is not compiled into
2808 GDLib. This is required when TYPO3 uses GDLib and
2809 you\'ll most likely get errors like \'ImageTTFBBox is
2810 not a function\' or \'ImageTTFText is not a function\'.
2811 </p>
2812 ', 2);
2813 } else {
2814 $this->message($ext, 'FreeType quick-test (' . ($this->isGIF() ? 'as GIF' : 'as PNG') . ')', '
2815 <p>
2816 <img src="' . htmlspecialchars(t3lib_div::getIndpEnv('REQUEST_URI') . '&testingTrueTypeSupport=1') . '" alt="" />
2817 <br />
2818 (If the text is exceeding the image borders you are
2819 using Freetype 2 and need to set
2820 TYPO3_CONF_VARS[GFX][TTFdpi]=96.
2821 <br />
2822 If there is no image at all Freetype is most likely NOT
2823 available and you can just as well disable GDlib for
2824 TYPO3...)
2825 </p>
2826 ', -1);
2827 $this->config_array['freetype']=1;
2828 }
2829 } else {
2830 $this->message($ext, 'GDLib2 not found', '
2831 <p>
2832 GDLib2 is required if you want to use the GIFBUILDER object
2833 in TypoScript. GIFBUILDER is in charge of all advanced image
2834 generation in TypoScript, including graphical menuitems.
2835 <br />
2836 GDLib2 is also used in the TYPO3 Backend (TBE) to generate
2837 record icons and new module tabs.
2838 <br />
2839 It\'s highly recommended to install this library. Remember
2840 to compile GD with FreeType which is also required.
2841 <br />
2842 If you choose not to install GDLib, you can disable it in
2843 the configuration with [GFX][gdlib]=0;.
2844 </p>
2845 ', 2);
2846 }
2847 $this->message($ext, 'GDLib software information', $this->getGDSoftwareInfo());
2848 }
2849
2850 /**
2851 * Checking and testing that the required writable directories are writable.
2852 *
2853 * @return void
2854 */
2855 function checkDirs() {
2856 // Check typo3/temp/
2857 $ext='Directories';
2858 $this->message($ext);
2859
2860 $uniqueName = md5(uniqid(microtime()));
2861
2862 // The requirement level (the integer value, ie. the second value of the value array) has the following meanings:
2863 // -1 = not required, but if it exists may be writable or not
2864 // 0 = not required, if it exists the dir should be writable
2865 // 1 = required, don't has to be writable
2866 // 2 = required, has to be writable
2867
2868 $checkWrite=array(
2869 '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'),
2870 'typo3temp/pics/' => array('This folder is part of the typo3temp/ section. It needs to be writable, too.',2,'dir_typo3temp'),
2871 'typo3temp/temp/' => array('This folder is part of the typo3temp/ section. It needs to be writable, too.',2,'dir_typo3temp'),
2872 'typo3temp/llxml/' => array('This folder is part of the typo3temp/ section. It needs to be writable, too.',2,'dir_typo3temp'),
2873 'typo3temp/cs/' => array('This folder is part of the typo3temp/ section. It needs to be writable, too.',2,'dir_typo3temp'),
2874 'typo3temp/GB/' => array('This folder is part of the typo3temp/ section. It needs to be writable, too.',2,'dir_typo3temp'),
2875 'typo3temp/locks/' => array('This folder is part of the typo3temp/ section. It needs to be writable, too.',2,'dir_typo3temp'),
2876 '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),
2877 'typo3conf/ext/' => array('Location for local extensions. Must be writable if the Extension Manager is supposed to install extensions for this website.',0),
2878 'typo3conf/l10n/' => array('Location for translations. Must be writable if the Extension Manager is supposed to install translations for extensions.',0),
2879 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),
2880 'uploads/' => array('Location for uploaded files from RTE, in the subdirectories for uploaded files of content elements.',2),
2881 'uploads/pics/' => array('Typical location for uploaded files (images especially).',0),
2882 'uploads/media/' => array('Typical location for uploaded files (non-images especially).',0),
2883 'uploads/tf/' => array('Typical location for uploaded files (TS template resources).',0),
2884 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileadminDir'] => array('Location for local files such as templates, independent uploads etc.',-1),
2885 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileadminDir'] . '_temp_/' => array('Typical temporary location for default upload of files by administrators.',0),
2886 );
2887
2888 foreach ($checkWrite as $relpath => $descr) {
2889
2890 // Check typo3temp/
2891 $general_message = $descr[0];
2892
2893 // If the directory is missing, try to create it
2894 if (!@is_dir(PATH_site.$relpath)) {
2895 t3lib_div::mkdir(PATH_site.$relpath);
2896 }
2897
2898 if (!@is_dir(PATH_site.$relpath)) {
2899 if ($descr[1]) { // required...
2900 $this->message($ext, $relpath.' directory does not exist and could not be created', '
2901 <p>
2902 <em>Full path: ' . PATH_site . $relpath . '</em>
2903 <br />
2904 ' . $general_message . '
2905 </p>
2906 <p>
2907 This error should not occur as ' . $relpath . ' must
2908 always be accessible in the root of a TYPO3 website.
2909 </p>
2910 ', 3);
2911 } else {
2912 if ($descr[1] == 0) {
2913 $msg = 'This directory does not necessarily have to exist but if it does it must be writable.';
2914 } else {
2915 $msg = 'This directory does not necessarily have to exist and if it does it can be writable or not.';
2916 }
2917 $this->message($ext, $relpath.' directory does not exist', '
2918 <p>
2919 <em>Full path: ' . PATH_site . $relpath . '</em>
2920 <br />
2921 ' . $general_message . '
2922 </p>
2923 <p>
2924 ' . $msg . '
2925 </p>
2926 ', 2);
2927 }
2928 } else {
2929 $file = PATH_site.$relpath.$uniqueName;
2930 @touch($file);
2931 if (@is_file($file)) {
2932 unlink($file);
2933 if ($descr[2]) { $this->config_array[$descr[2]]=1; }
2934 $this->message($ext, $relpath.' writable','',-1);
2935 } else {
2936 $severity = ($descr[1]==2 || $descr[1]==0) ? 3 : 2;
2937 if ($descr[1] == 0 || $descr[1] == 2) {
2938 $msg = 'The directory '.$relpath.' must be writable!';
2939 } elseif ($descr[1] == -1 || $descr[1] == 1) {
2940 $msg = 'The directory '.$relpath.' does not neccesarily have to be writable.';
2941 }
2942 $this->message($ext, $relpath .' directory not writable', '
2943 <p>
2944 <em>Full path: ' . $file . '</em>
2945 <br />
2946 ' . $general_message . '
2947 </p>
2948 <p>
2949 Tried to write this file (with touch()) but didn\'t
2950 succeed.
2951 <br />
2952 ' . $msg . '
2953 </p>
2954 ', $severity);
2955 }
2956 }
2957 }
2958 }
2959
2960 /**
2961 * Checking for existing ImageMagick installs.
2962 *
2963 * 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.
2964 *
2965 * @param array $paths Possible ImageMagick paths
2966 * @return void
2967 */
2968 function checkImageMagick($paths) {
2969 $ext='Check Image Magick';
2970 $this->message($ext);
2971 // Get the template file
2972 $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'CheckImageMagick.html');
2973
2974 $paths = array_unique($paths);
2975
2976 $programs = explode(',','gm,convert,combine,composite,identify');
2977 $isExt = TYPO3_OS=="WIN" ? ".exe" : "";
2978 $this->config_array['im_combine_filename']='combine';
2979 foreach ($paths as $k => $v) {
2980 if (!preg_match('/[\\/]$/',$v)) $v.='/';
2981 foreach ($programs as $filename) {
2982 if (ini_get('open_basedir') || (file_exists($v)&&@is_file($v.$filename.$isExt))) {
2983 $version = $this->_checkImageMagick_getVersion($filename,$v);
2984 if($version > 0) {
2985 // Assume GraphicsMagick
2986 if($filename=='gm') {
2987 $index[$v]['gm']=$version;
2988 // No need to check for "identify" etc.
2989 continue;
2990 } else {
2991