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