Fixed bug #17374: implode() issues in Install Tool
[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 $step3DatabaseOptions = array();
1085 foreach ($dbArr as $dbname) {
1086 // Define the markers content for database options
1087 $step3DatabaseOptionMarkers = array(
1088 'databaseValue' => htmlspecialchars($dbname),
1089 'databaseSelected' => $dbname == TYPO3_db ? 'selected="selected"' : '',
1090 'databaseName' => htmlspecialchars($dbname)
1091 );
1092 // Add the option HTML to an array
1093 $step3DatabaseOptions[] = t3lib_parsehtml::substituteMarkerArray(
1094 $step3DatabaseOptionsSubPart,
1095 $step3DatabaseOptionMarkers,
1096 '###|###',
1097 TRUE,
1098 TRUE
1099 );
1100 if ($dbname==TYPO3_db) $dbIncluded=1;
1101 }
1102 if (!$dbIncluded && TYPO3_db) {
1103 // // Define the markers content when no access
1104 $step3DatabaseOptionMarkers = array(
1105 'databaseValue' => htmlspecialchars(TYPO3_db),
1106 'databaseSelected' => 'selected="selected"',
1107 'databaseName' => htmlspecialchars(TYPO3_db) . ' (NO ACCESS!)'
1108 );
1109 // Add the option HTML to an array
1110 $step3DatabaseOptions[] = t3lib_parsehtml::substituteMarkerArray(
1111 $step3DatabaseOptionsSubPart,
1112 $step3DatabaseOptionMarkers,
1113 '###|###',
1114 TRUE,
1115 TRUE
1116 );
1117 }
1118 // Substitute the subpart for the database options
1119 $content = t3lib_parsehtml::substituteSubpart(
1120 $step3SubPart,
1121 '###DATABASEOPTIONS###',
1122 implode(LF, $step3DatabaseOptions)
1123 );
1124 // Define the markers content
1125 $step3SubPartMarkers = array(
1126 'step' => $this->step + 1,
1127 'llOptions' => 'You have two options:',
1128 'action' => htmlspecialchars($this->action),
1129 'llOption1' => 'Create a new database (recommended):',
1130 'llRemark1' => 'Enter a name for your TYPO3 database.',
1131 'llOption2' => 'Select an EMPTY existing database:',
1132 'llRemark2' => 'Any tables used by TYPO3 will be overwritten.',
1133 'continue' => 'Continue'
1134 );
1135 // Add step marker for main template
1136 $markers['step'] = t3lib_parsehtml::substituteMarkerArray(
1137 $content,
1138 $step3SubPartMarkers,
1139 '###|###',
1140 TRUE,
1141 TRUE
1142 );
1143 } else {
1144 // Add step marker for main template when no connection
1145 $markers['step'] = $error_missingConnect;
1146 }
1147 break;
1148 case 4:
1149 // Add header marker for main template
1150 $markers['header'] = 'Import the Database Tables';
1151 // There should be a database host connection at this point
1152 if ($result = $GLOBALS['TYPO3_DB']->sql_pconnect(
1153 TYPO3_db_host, TYPO3_db_username, TYPO3_db_password
1154 )) {
1155 // The selected database should be accessible
1156 if ($GLOBALS['TYPO3_DB']->sql_select_db(TYPO3_db)) {
1157 // Get the subpart for the fourth step
1158 $step4SubPart = t3lib_parsehtml::getSubpart(
1159 $templateFile, '###STEP4###'
1160 );
1161 // Get the subpart for the database type options
1162 $step4DatabaseTypeOptionsSubPart = t3lib_parsehtml::getSubpart(
1163 $step4SubPart, '###DATABASETYPEOPTIONS###'
1164 );
1165
1166 $sFiles = t3lib_div::getFilesInDir(PATH_typo3conf,'sql',1,1);
1167
1168 // Check if default database scheme "database.sql" already exists, otherwise create it
1169 if (!strstr(implode(',',$sFiles).',', '/database.sql,')) {
1170 array_unshift($sFiles,'Default TYPO3 Tables');
1171 }
1172
1173 $step4DatabaseTypeOptions = array();
1174 foreach ($sFiles as $f) {
1175 if ($f=='Default TYPO3 Tables') $key='CURRENT_TABLES+STATIC';
1176 else $key=htmlspecialchars($f);
1177 // Define the markers content for database type subpart
1178 $step4DatabaseTypeOptionMarkers = array(
1179 'databaseTypeValue' => 'import|' . $key,
1180 'databaseName' => htmlspecialchars(basename($f))
1181 );
1182 // Add the option HTML to an array
1183 $step4DatabaseTypeOptions[] = t3lib_parsehtml::substituteMarkerArray(
1184 $step4DatabaseTypeOptionsSubPart,
1185 $step4DatabaseTypeOptionMarkers,
1186 '###|###',
1187 TRUE,
1188 FALSE
1189 );
1190 }
1191 // Substitute the subpart for the database type options
1192 $content = t3lib_parsehtml::substituteSubpart(
1193 $step4SubPart,
1194 '###DATABASETYPEOPTIONS###',
1195 implode(LF, $step4DatabaseTypeOptions)
1196 );
1197 // Define the markers content
1198 $step4SubPartMarkers = array(
1199 'llSummary' => 'Database summary:',
1200 'llUsername' => 'Username:',
1201 'username' => htmlspecialchars(TYPO3_db_username),
1202 'llHost' => 'Host:',
1203 'host' => htmlspecialchars(TYPO3_db_host),
1204 'llDatabase' => 'Database:',
1205 'database' => htmlspecialchars(TYPO3_db),
1206 'llNumberTables' => 'Number of tables:',
1207 'numberTables' => count($whichTables),
1208 'action' => htmlspecialchars($this->action),
1209 'llDatabaseType' => 'Select database contents:',
1210 'label' => 'Import database'
1211 );
1212 // Add step marker for main template
1213 $markers['step'] = t3lib_parsehtml::substituteMarkerArray(
1214 $content,
1215 $step4SubPartMarkers,
1216 '###|###',
1217 TRUE,
1218 TRUE
1219 );
1220 } else {
1221 // Add step marker for main template when no database
1222 $markers['step'] = $error_missingDB;
1223 }
1224 } else {
1225 // Add step marker for main template when no connection
1226 $markers['step'] = $error_missingConnect;
1227 }
1228 break;
1229 case 'go':
1230 // Add header marker for main template
1231 $markers['header'] = 'Congratulations!';
1232 // There should be a database host connection at this point
1233 if ($result = $GLOBALS['TYPO3_DB']->sql_pconnect(
1234 TYPO3_db_host, TYPO3_db_username, TYPO3_db_password
1235 )) {
1236 // The selected database should be accessible
1237 if ($GLOBALS['TYPO3_DB']->sql_select_db(TYPO3_db)) {
1238 // The database should contain tables
1239 if (count($whichTables)) {
1240 // Get the subpart for the go step
1241 $stepGoSubPart = t3lib_parsehtml::getSubpart(
1242 $templateFile, '###STEPGO###'
1243 );
1244 // Define the markers content
1245 $stepGoSubPartMarkers = array(
1246 'messageBasicFinished' => $this->messageBasicFinished(),
1247 'llImportant' => 'Important Security Warning',
1248 'securityRisk' => $this->securityRisk(),
1249 'llSwitchMode' => '
1250 <a href="' . $this->scriptSelf . '">
1251 Change the Install Tool password here
1252 </a>
1253 '
1254 );
1255 // Add step marker for main template
1256 $markers['step'] = t3lib_parsehtml::substituteMarkerArray(
1257 $stepGoSubPart,
1258 $stepGoSubPartMarkers,
1259 '###|###',
1260 TRUE,
1261 TRUE
1262 );
1263 } else {
1264 // Add step marker for main template when empty database
1265 $markers['step'] = $error_emptyDB;
1266 }
1267 } else {
1268 // Add step marker for main template when no database
1269 $markers['step'] = $error_missingDB;
1270 }
1271 } else {
1272 // Add step marker for main template when no connection
1273 $markers['step'] = $error_missingConnect;
1274 }
1275 break;
1276 }
1277 }
1278 // Fill the markers in the template
1279 $content = t3lib_parsehtml::substituteMarkerArray(
1280 $template,
1281 $markers,
1282 '###|###',
1283 TRUE,
1284 FALSE
1285 );
1286
1287 return $content;
1288 }
1289
1290 /**
1291 * Calling the functions that checks the system
1292 *
1293 * @return void
1294 */
1295 function checkTheConfig() {
1296 // Order important:
1297 $this->checkDirs();
1298 $this->checkConfiguration();
1299 $this->checkExtensions();
1300
1301 if (TYPO3_OS=='WIN') {
1302 $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\\');
1303 if (!isset($_SERVER['PATH'])) {
1304 $serverPath = array_change_key_case($_SERVER, CASE_UPPER);
1305 $paths = array_merge($paths, explode(';', $serverPath['PATH']));
1306 } else {
1307 $paths = array_merge($paths, explode(';', $_SERVER['PATH']));
1308 }
1309 } else {
1310 $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/');
1311 $paths = array_merge($paths, explode(':', $_SERVER['PATH']));
1312 }
1313 $paths = array_unique($paths);
1314
1315 asort($paths);
1316 if (t3lib_utility_PhpOptions::isSafeModeEnabled()) {
1317 $paths=array(ini_get('safe_mode_exec_dir'),'/usr/local/php/bin/');
1318 }
1319 if ($this->INSTALL['checkIM']['lzw']) {
1320 $this->checkIMlzw=1;
1321 }
1322 if ($this->INSTALL['checkIM']['path']) {
1323 $paths[]=trim($this->INSTALL['checkIM']['path']);
1324 }
1325 if ($this->checkIM) $this->checkImageMagick($paths);
1326 $this->checkDatabase();
1327 }
1328
1329 /**
1330 * Editing files in typo3conf directory (or elsewhere if enabled)
1331 *
1332 * @return void
1333 */
1334 function typo3conf_edit() {
1335 // default:
1336 $EDIT_path = PATH_typo3conf;
1337 if ($this->allowFileEditOutsite_typo3conf_dir && $this->INSTALL['FILE']['EDIT_path']) {
1338 if (t3lib_div::validPathStr($this->INSTALL['FILE']['EDIT_path']) && substr($this->INSTALL['FILE']['EDIT_path'],-1)=='/') {
1339 $tmp_path = PATH_site.$this->INSTALL['FILE']['EDIT_path'];
1340 if (is_dir($tmp_path)) {
1341 $EDIT_path=$tmp_path;
1342 } else {
1343 $this->errorMessages[] = '
1344 \'' . $tmp_path . '\' was not directory
1345 ';
1346 }
1347 } else {
1348 $this->errorMessages[] = '
1349 Bad directory name (must be like t3lib/ or media/script/)
1350 ';
1351 }
1352 }
1353
1354 $headCode = 'Edit files in '.basename($EDIT_path).'/';
1355 $messages = '';
1356
1357 if ($this->INSTALL['SAVE_FILE']) {
1358 $save_to_file = $this->INSTALL['FILE']['name'];
1359 if (@is_file($save_to_file)) {
1360 $save_to_file_md5 = md5($save_to_file);
1361 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')) {
1362 $this->INSTALL['typo3conf_files'] = $save_to_file;
1363 $save_fileContent = $this->INSTALL['FILE'][$save_to_file_md5];
1364
1365 if ($this->INSTALL['FILE']['win_to_unix_br']) {
1366 $save_fileContent = str_replace(CRLF, LF, $save_fileContent);
1367 }
1368
1369 $backupFile = $this->getBackupFilename($save_to_file);
1370 if ($this->INSTALL['FILE']['backup']) {
1371 if (@is_file($backupFile)) { unlink($backupFile); }
1372 rename($save_to_file,$backupFile);
1373 $messages .= '
1374 Backup written to <strong>' . $backupFile . '</strong>
1375 <br />
1376 ';
1377 }
1378
1379 t3lib_div::writeFile($save_to_file,$save_fileContent);
1380 $messages .= '
1381 File saved: <strong>' . $save_to_file . '</strong>
1382 <br />
1383 MD5-sum: ' . $this->INSTALL['FILE']['prevMD5'] . ' (prev)
1384 <br />
1385 MD5-sum: ' . md5($save_fileContent) . ' (new)
1386 <br />
1387 ';
1388 }
1389 }
1390 }
1391
1392 // Filelist:
1393 // Get the template file
1394 $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'Typo3ConfEdit.html');
1395 // Get the template part from the file
1396 $template = t3lib_parsehtml::getSubpart($templateFile, '###TEMPLATE###');
1397 // Get the subpart for the files
1398 $filesSubpart = t3lib_parsehtml::getSubpart($template, '###FILES###');
1399 $files = array();
1400
1401 $typo3conf_files = t3lib_div::getFilesInDir($EDIT_path,'',1,1);
1402 $fileFound = 0;
1403
1404
1405 foreach ($typo3conf_files as $k => $file) {
1406 // Delete temp_CACHED files if option is set
1407 if ( $this->INSTALL['delTempCached'] && preg_match('|/temp_CACHED_[a-z0-9_]+\.php|', $file)) {
1408 unlink($file);
1409 continue;
1410 }
1411 if ($this->INSTALL['typo3conf_files'] && !strcmp($this->INSTALL['typo3conf_files'],$file)) {
1412 $fileFound = 1;
1413 }
1414 // Define the markers content for the files subpart
1415 $filesMarkers = array(
1416 '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',
1417 'fileName' => basename($file),
1418 'fileSize' => t3lib_div::formatSize(filesize($file)),
1419 'class' => $this->INSTALL['typo3conf_files'] && !strcmp($this->INSTALL['typo3conf_files'], $file) ? 'class="act"' : ''
1420 );
1421 // Fill the markers in the subpart
1422 $files[] = t3lib_parsehtml::substituteMarkerArray(
1423 $filesSubpart,
1424 $filesMarkers,
1425 '###|###',
1426 TRUE,
1427 FALSE
1428 );
1429 }
1430
1431 if ($fileFound && @is_file($this->INSTALL['typo3conf_files'])) {
1432
1433 $backupFile = $this->getBackupFilename($this->INSTALL['typo3conf_files']);
1434 $fileContent = t3lib_div::getUrl($this->INSTALL['typo3conf_files']);
1435 // Get the subpart to edit the files
1436 $fileEditTemplate = t3lib_parsehtml::getSubpart($template, '###FILEEDIT###');
1437 $allowFileEditOutsideTypo3ConfDirSubPart = '';
1438
1439 if (substr($this->INSTALL['typo3conf_files'], -1) != '~' && !strstr($this->INSTALL['typo3conf_files'], '_bak')) {
1440 // Get the subpart to show the save button
1441 $showSaveButtonSubPart = t3lib_parsehtml::getSubpart($fileEditTemplate, '###SHOWSAVEBUTTON###');
1442 }
1443
1444 if ($this->allowFileEditOutsite_typo3conf_dir) {
1445 // Get the subpart to show if files are allowed outside the directory typo3conf
1446 $allowFileEditOutsideTypo3ConfDirSubPart = t3lib_parsehtml::getSubpart($fileEditTemplate, '###ALLOWFILEEDITOUTSIDETYPO3CONFDIR###');
1447 }
1448 // Substitute the subpart for the save button
1449 $fileEditContent = t3lib_parsehtml::substituteSubpart(
1450 $fileEditTemplate,
1451 '###SHOWSAVEBUTTON###',
1452 $showSaveButtonSubPart
1453 );
1454 // Substitute the subpart to show if files are allowed outside the directory typo3conf
1455 $fileEditContent = t3lib_parsehtml::substituteSubpart(
1456 $fileEditContent,
1457 '###ALLOWFILEEDITOUTSIDETYPO3CONFDIR###',
1458 $allowFileEditOutsideTypo3ConfDirSubPart
1459 );
1460 // Define the markers content for subpart to edit the files
1461 $fileEditMarkers = array(
1462 'messages' => !empty($messages) ? '<p class="typo3-message message-warning">' . $messages . '</p>' : '',
1463 'action' => $this->action . '#fileEditHeader',
1464 'saveFile' => 'Save file',
1465 'close' => 'Close',
1466 'llEditing' => 'Editing file:',
1467 'file' => $this->INSTALL['typo3conf_files'],
1468 'md5Sum' => 'MD5-sum: ' . md5($fileContent),
1469 'fileName' => $this->INSTALL['typo3conf_files'],
1470 'fileEditPath' => $this->INSTALL['FILE']['EDIT_path'],
1471 'filePreviousMd5' => md5($fileContent),
1472 'fileMd5' => md5($this->INSTALL['typo3conf_files']),
1473 'fileContent' => t3lib_div::formatForTextarea($fileContent),
1474 'winToUnixBrChecked' => TYPO3_OS == 'WIN' ? '' : 'checked="checked"',
1475 'winToUnixBr' => 'Convert Windows linebreaks (13-10) to Unix (10)',
1476 'backupChecked' => @is_file($backupFile) ? 'checked="checked"' : '',
1477 'backup' => 'Make backup copy (rename to ' . basename($backupFile) . ')'
1478 );
1479 // Fill the markers in the subpart to edit the files
1480 $fileEditContent = t3lib_parsehtml::substituteMarkerArray(
1481 $fileEditContent,
1482 $fileEditMarkers,
1483 '###|###',
1484 TRUE,
1485 FALSE
1486 );
1487 }
1488
1489 if ($this->allowFileEditOutsite_typo3conf_dir) {
1490 // Get the subpart to show if files are allowed outside the directory typo3conf
1491 $allowFileEditOutsideTypo3ConfDirSubPart = t3lib_parsehtml::getSubpart($template, '###ALLOWFILEEDITOUTSIDETYPO3CONFDIR###');
1492 // Define the markers content
1493 $allowFileEditOutsideTypo3ConfDirMarkers = array(
1494 'action' => $this->action,
1495 'pathSite' => PATH_site,
1496 'editPath' => $this->INSTALL['FILE']['EDIT_path'],
1497 'set' => 'Set'
1498 );
1499 // Fill the markers in the subpart
1500 $allowFileEditOutsideTypo3ConfDirSubPart = t3lib_parsehtml::substituteMarkerArray(
1501 $allowFileEditOutsideTypo3ConfDirSubPart,
1502 $allowFileEditOutsideTypo3ConfDirMarkers,
1503 '###|###',
1504 TRUE,
1505 FALSE
1506 );
1507 }
1508 // Substitute the subpart to edit the file
1509 $fileListContent = t3lib_parsehtml::substituteSubpart(
1510 $template,
1511 '###FILEEDIT###',
1512 $fileEditContent
1513 );
1514 // Substitute the subpart when files can be edited outside typo3conf directory
1515 $fileListContent = t3lib_parsehtml::substituteSubpart(
1516 $fileListContent,
1517 '###ALLOWFILEEDITOUTSIDETYPO3CONFDIR###',
1518 $allowFileEditOutsideTypo3ConfDirSubPart
1519 );
1520 // Substitute the subpart for the files
1521 $fileListContent = t3lib_parsehtml::substituteSubpart(
1522 $fileListContent,
1523 '###FILES###',
1524 implode(LF, $files)
1525 );
1526 // Define the markers content
1527 $fileListMarkers = array(
1528 'editPath' => '(' . $EDIT_path . ')',
1529 'deleteTempCachedUrl' => $this->action . '&amp;TYPO3_INSTALL[delTempCached]=1',
1530 'deleteTempCached' => 'Delete temp_CACHED* files'
1531 );
1532 // Fill the markers
1533 $fileListContent = t3lib_parsehtml::substituteMarkerArray(
1534 $fileListContent,
1535 $fileListMarkers,
1536 '###|###',
1537 TRUE,
1538 FALSE
1539 );
1540 // Add the content to the message array
1541 $this->message($headCode, 'Files in folder', $fileListContent);
1542 // Output the page
1543 $this->output($this->outputWrapper($this->printAll()));
1544 }
1545
1546 /**
1547 * Outputs system information
1548 *
1549 * @return void
1550 */
1551 function phpinformation() {
1552 $headCode = 'PHP information';
1553
1554 $sVar = t3lib_div::getIndpEnv('_ARRAY');
1555 $sVar['CONST: PHP_OS']=PHP_OS;
1556 $sVar['CONST: TYPO3_OS']=TYPO3_OS;
1557 $sVar['CONST: PATH_thisScript']=PATH_thisScript;
1558 $sVar['CONST: php_sapi_name()']=PHP_SAPI;
1559 $sVar['OTHER: TYPO3_VERSION']=TYPO3_version;
1560 $sVar['OTHER: PHP_VERSION']=phpversion();
1561 $sVar['imagecreatefromgif()']=function_exists('imagecreatefromgif');
1562 $sVar['imagecreatefrompng()']=function_exists('imagecreatefrompng');
1563 $sVar['imagecreatefromjpeg()']=function_exists('imagecreatefromjpeg');
1564 $sVar['imagegif()']=function_exists('imagegif');
1565 $sVar['imagepng()']=function_exists('imagepng');
1566 $sVar['imagejpeg()']=function_exists('imagejpeg');
1567 $sVar['imagettftext()']=function_exists('imagettftext');
1568 $sVar['OTHER: IMAGE_TYPES']=function_exists('imagetypes') ? imagetypes() : 0;
1569 $sVar['OTHER: memory_limit']=ini_get('memory_limit');
1570
1571 $gE_keys = explode(',','SERVER_PORT,SERVER_SOFTWARE,GATEWAY_INTERFACE,SCRIPT_NAME,PATH_TRANSLATED');
1572 foreach ($gE_keys as $k) {
1573 $sVar['SERVER: '.$k]=$_SERVER[$k];
1574 }
1575
1576 $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');
1577
1578 foreach ($gE_keys as $k) {
1579 $sVar['T3CV_GFX: '.$k]=$GLOBALS['TYPO3_CONF_VARS']['GFX'][$k];
1580 }
1581
1582 $debugInfo = array(
1583 '### DEBUG SYSTEM INFORMATION - START ###'
1584 );
1585 foreach ($sVar as $kkk => $vvv) {
1586 $debugInfo[]=str_pad(substr($kkk,0,20),20).': '.$vvv;
1587 }
1588 $debugInfo[]='### DEBUG SYSTEM INFORMATION - END ###';
1589 // Get the template file
1590 $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'PhpInformation.html');
1591 // Get the template part from the file
1592 $template = t3lib_parsehtml::getSubpart($templateFile, '###TEMPLATE###');
1593 // Define the markers content
1594 $markers = array(
1595 '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!',
1596 'debugInfo' => t3lib_div::formatForTextarea(implode(LF, $debugInfo))
1597 );
1598 // Fill the markers
1599 $content = t3lib_parsehtml::substituteMarkerArray(
1600 $template,
1601 $markers,
1602 '###|###',
1603 TRUE,
1604 FALSE
1605 );
1606 // Add the content to the message array
1607 $this->message($headCode, 'DEBUG information', $content);
1608 // Start with various server information
1609 $getEnvArray = array();
1610 $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');
1611 foreach ($gE_keys as $k) {
1612 $getEnvArray[$k] = getenv($k);
1613 }
1614 $this->message($headCode, 't3lib_div::getIndpEnv()', $this->viewArray(t3lib_div::getIndpEnv('_ARRAY')));
1615 $this->message($headCode, 'getenv()', $this->viewArray($getEnvArray));
1616 $this->message($headCode, '_ENV', $this->viewArray($_ENV));
1617 $this->message($headCode, '_SERVER', $this->viewArray($_SERVER));
1618 $this->message($headCode, '_COOKIE', $this->viewArray($_COOKIE));
1619 $this->message($headCode, '_GET', $this->viewArray($_GET));
1620 // Start with the phpinfo() part
1621 ob_start();
1622 phpinfo();
1623 $contents = explode('<body>',ob_get_contents());
1624 ob_end_clean();
1625 $contents = explode('</body>',$contents[1]);
1626 // Do code cleaning: phpinfo() is not XHTML1.1 compliant
1627 $phpinfo = str_replace('<font', '<span', $contents[0]);
1628 $phpinfo = str_replace('</font', '</span', $phpinfo);
1629 $phpinfo = str_replace('<img border="0"', '<img', $phpinfo);
1630 $phpinfo = str_replace('<a name=', '<a id=', $phpinfo);
1631 // Add phpinfo() to the message array
1632 $this->message($headCode, 'phpinfo()', '
1633 <div class="phpinfo">
1634 ' . $phpinfo . '
1635 </div>
1636 ');
1637 // Output the page
1638 $this->output($this->outputWrapper($this->printAll()));
1639 }
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650 /*******************************
1651 *
1652 * cleanup manager
1653 *
1654 *******************************/
1655
1656 /**
1657 * Provides a tool cleaning up various tables in the database
1658 *
1659 * @return void
1660 * @author Robert Lemke <rl@robertlemke.de>
1661 * @todo Add more functionality ...
1662 */
1663 function cleanupManager() {
1664 $headCode = 'Clean up your TYPO3 installation';
1665 $this->message($headCode, 'Database cache tables', '
1666 <p>
1667 <strong>Clear cached image sizes</strong>
1668 <br />
1669 Clears the cache used for memorizing sizes of all images used in
1670 your website. This information is cached in order to gain
1671 performance and will be stored each time a new image is being
1672 displayed in the frontend.
1673 </p>
1674 <p>
1675 You should <em>Clear All Cache</em> in the backend after
1676 clearing this cache.
1677 </p>
1678 ');
1679
1680 $tables = $this->getListOfTables();
1681 $action = $this->INSTALL['cleanup_type'];
1682
1683 if (($action == 'cache_imagesizes' || $action == 'all') && isset ($tables['cache_imagesizes'])) {
1684 $GLOBALS['TYPO3_DB']->exec_TRUNCATEquery('cache_imagesizes');
1685 }
1686
1687 $cleanupType = array (
1688 'all' => 'Clean up everything',
1689 );
1690
1691 // Get cache_imagesizes info
1692 if (isset ($tables['cache_imagesizes'])) {
1693 $cleanupType['cache_imagesizes'] = 'Clear cached image sizes only';
1694 $cachedImageSizesCounter = intval($GLOBALS['TYPO3_DB']->exec_SELECTcountRows('*', 'cache_imagesizes'));
1695 } else {
1696 $this->message($headCode, 'Table cache_imagesizes does not exist!', '
1697 <p>
1698 The table cache_imagesizes was not found. Please check your
1699 database settings in Basic Configuration and compare your
1700 table definition with the Database Analyzer.
1701 </p>
1702 ', 2);
1703 $cachedImageSizesCounter = 'unknown';
1704 }
1705 // Get the template file
1706 $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'CleanUpManager.html');
1707 // Get the template part from the file
1708 $template = t3lib_parsehtml::getSubpart($templateFile, '###TEMPLATE###');
1709 // Get the subpart for the 'Clean up' dropdown
1710 $cleanUpOptionsSubpart = t3lib_parsehtml::getSubpart($template, '###CLEANUPOPTIONS###');
1711 $cleanUpOptions = array();
1712
1713 foreach ($cleanupType as $cleanUpKey => $cleanUpValue) {
1714 // Define the markers content
1715 $cleanUpMarkers = array(
1716 'value' => htmlspecialchars($cleanUpKey),
1717 'data' => htmlspecialchars($cleanUpValue)
1718 );
1719 // Fill the markers in the subpart
1720 $cleanUpOptions[] = t3lib_parsehtml::substituteMarkerArray(
1721 $cleanUpOptionsSubpart,
1722 $cleanUpMarkers,
1723 '###|###',
1724 TRUE,
1725 FALSE
1726 );
1727 }
1728 // Substitute the subpart for the 'Clean up' dropdown
1729 $content = t3lib_parsehtml::substituteSubpart(
1730 $template,
1731 '###CLEANUPOPTIONS###',
1732 implode(LF, $cleanUpOptions)
1733 );
1734 // Define the markers content
1735 $markers = array(
1736 'numberCached' => 'Number cached image sizes:',
1737 'number' => $cachedImageSizesCounter,
1738 'action' => $this->action,
1739 'cleanUp' => 'Clean up',
1740 'execute' => 'Execute'
1741 );
1742 // Fill the markers
1743 $content = t3lib_parsehtml::substituteMarkerArray(
1744 $content,
1745 $markers,
1746 '###|###',
1747 TRUE,
1748 FALSE
1749 );
1750 // Add the content to the message array
1751 $this->message($headCode, 'Statistics', $content, 1);
1752
1753
1754
1755
1756
1757
1758
1759 $this->message($headCode, 'typo3temp/ folder', '
1760 <p>
1761 TYPO3 uses this directory for temporary files, mainly processed
1762 and cached images.
1763 <br />
1764 The filenames are very cryptic; They are unique representations
1765 of the file properties made by md5-hashing a serialized array
1766 with information.
1767 <br />
1768 Anyway this directory may contain many thousand files and a lot
1769 of them may be of no use anymore.
1770 </p>
1771 <p>
1772 With this test you can delete the files in this folder. When you
1773 do that, you should also clear the cache database tables
1774 afterwards.
1775 </p>
1776 ');
1777
1778 if (!$this->config_array['dir_typo3temp']) {
1779 $this->message('typo3temp/ directory', 'typo3temp/ not writable!', '
1780 <p>
1781 You must make typo3temp/ write enabled before you can
1782 proceed with this test.
1783 </p>
1784 ', 2);
1785 $this->output($this->outputWrapper($this->printAll()));
1786 return;
1787 }
1788
1789 // Run through files
1790 $fileCounter = 0;
1791 $deleteCounter = 0;
1792 $criteriaMatch = 0;
1793 $tmap=array('day'=>1, 'week'=>7, 'month'=>30);
1794 $tt = $this->INSTALL['typo3temp_delete'];
1795 $subdir = $this->INSTALL['typo3temp_subdir'];
1796 if (strlen($subdir) && !preg_match('/^[[:alnum:]_]+\/$/',$subdir)) die('subdir "'.$subdir.'" was not allowed!');
1797 $action = $this->INSTALL['typo3temp_action'];
1798 $d = @dir($this->typo3temp_path.$subdir);
1799 if (is_object($d)) {
1800 while($entry=$d->read()) {
1801 $theFile = $this->typo3temp_path.$subdir.$entry;
1802 if (@is_file($theFile)) {
1803 $ok = 0;
1804 $fileCounter++;
1805 if ($tt) {
1806 if (t3lib_div::testInt($tt)) {
1807 if (filesize($theFile) > $tt*1024) $ok=1;
1808 } else {
1809 if (fileatime($theFile) < $GLOBALS['EXEC_TIME'] - (intval($tmap[$tt]) * 60 * 60 * 24)) {
1810 $ok = 1;
1811 }
1812 }
1813 } else {
1814 $ok = 1;
1815 }
1816 if ($ok) {
1817 $hashPart=substr(basename($theFile),-14,10);
1818 // This is a kind of check that the file being deleted has a 10 char hash in it
1819 if (!preg_match('/[^a-f0-9]/',$hashPart) || substr($theFile,-6)==='.cache' || substr($theFile,-4)==='.tbl' || substr(basename($theFile),0,8)==='install_') {
1820 if ($action && $deleteCounter<$action) {
1821 $deleteCounter++;
1822 unlink($theFile);
1823 } else {
1824 $criteriaMatch++;
1825 }
1826 }
1827 }
1828 }
1829 }
1830 $d->close();
1831 }
1832
1833 // Find sub-dirs:
1834 $subdirRegistry = array(''=>'');
1835 $d = @dir($this->typo3temp_path);
1836 if (is_object($d)) {
1837 while($entry=$d->read()) {
1838 $theFile = $entry;
1839 if (@is_dir($this->typo3temp_path.$theFile) && $theFile!='..' && $theFile!='.') {
1840 $subdirRegistry[$theFile.'/'] = $theFile.'/ (Files: '.count(t3lib_div::getFilesInDir($this->typo3temp_path.$theFile)).')';
1841 }
1842 }
1843 }
1844
1845 $deleteType=array(
1846 '0' => 'All',
1847 'day' => 'Last access more than a day ago',
1848 'week' => 'Last access more than a week ago',
1849 'month' => 'Last access more than a month ago',
1850 '10' => 'Filesize greater than 10KB',
1851 '50' => 'Filesize greater than 50KB',
1852 '100' => 'Filesize greater than 100KB'
1853 );
1854
1855 $actionType=array(
1856 '0' => "Don't delete, just display statistics",
1857 '100' => 'Delete 100',
1858 '500' => 'Delete 500',
1859 '1000' => 'Delete 1000'
1860 );
1861 // Get the template file
1862 $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'Typo3TempManager.html');
1863 // Get the template part from the file
1864 $template = t3lib_parsehtml::getSubpart($templateFile, '###TEMPLATE###');
1865 // Get the subpart for 'Delete files by condition' dropdown
1866 $deleteOptionsSubpart = t3lib_parsehtml::getSubpart($template, '###DELETEOPTIONS###');
1867 $deleteOptions = array();
1868
1869 foreach ($deleteType as $deleteKey => $deleteValue) {
1870 // Define the markers content
1871 $deleteMarkers = array(
1872 'value' => htmlspecialchars($deleteKey),
1873 'selected' => !strcmp($deleteKey, $tt) ? 'selected="selected"' : '',
1874 'data' => htmlspecialchars($deleteValue)
1875 );
1876 // Fill the markers in the subpart
1877 $deleteOptions[] = t3lib_parsehtml::substituteMarkerArray(
1878 $deleteOptionsSubpart,
1879 $deleteMarkers,
1880 '###|###',
1881 TRUE,
1882 FALSE
1883 );
1884 }
1885 // Substitute the subpart for 'Delete files by condition' dropdown
1886 $content = t3lib_parsehtml::substituteSubpart(
1887 $template,
1888 '###DELETEOPTIONS###',
1889 implode(LF, $deleteOptions)
1890 );
1891 // Get the subpart for 'Number of files at a time' dropdown
1892 $actionOptionsSubpart = t3lib_parsehtml::getSubpart($template, '###ACTIONOPTIONS###');
1893 $actionOptions = array();
1894
1895 foreach ($actionType as $actionKey => $actionValue) {
1896 // Define the markers content
1897 $actionMarkers = array(
1898 'value' => htmlspecialchars($actionKey),
1899 'data' => htmlspecialchars($actionValue)
1900 );
1901 // Fill the markers in the subpart
1902 $actionOptions[] = t3lib_parsehtml::substituteMarkerArray(
1903 $actionOptionsSubpart,
1904 $actionMarkers,
1905 '###|###',
1906 TRUE,
1907 FALSE
1908 );
1909 }
1910 // Substitute the subpart for 'Number of files at a time' dropdown
1911 $content = t3lib_parsehtml::substituteSubpart(
1912 $content,
1913 '###ACTIONOPTIONS###',
1914 implode(LF, $actionOptions)
1915 );
1916 // Get the subpart for 'From sub-directory' dropdown
1917 $subDirectoryOptionsSubpart = t3lib_parsehtml::getSubpart($template, '###SUBDIRECTORYOPTIONS###');
1918 $subDirectoryOptions = array();
1919
1920 foreach ($subdirRegistry as $subDirectoryKey => $subDirectoryValue) {
1921 // Define the markers content
1922 $subDirectoryMarkers = array(
1923 'value' => htmlspecialchars($subDirectoryKey),
1924 'selected' => !strcmp($subDirectoryKey, $this->INSTALL['typo3temp_subdir']) ? 'selected="selected"' : '',
1925 'data' => htmlspecialchars($subDirectoryValue)
1926 );
1927 // Fill the markers in the subpart
1928 $subDirectoryOptions[] = t3lib_parsehtml::substituteMarkerArray(
1929 $subDirectoryOptionsSubpart,
1930 $subDirectoryMarkers,
1931 '###|###',
1932 TRUE,
1933 FALSE
1934 );
1935 }
1936 // Substitute the subpart for 'From sub-directory' dropdown
1937 $content = t3lib_parsehtml::substituteSubpart(
1938 $content,
1939 '###SUBDIRECTORYOPTIONS###',
1940 implode(LF, $subDirectoryOptions)
1941 );
1942 // Define the markers content
1943 $markers = array(
1944 'numberTemporary' => 'Number of temporary files:',
1945 'numberMatching' => 'Number matching:',
1946 'numberDeleted' => 'Number deleted:',
1947 'temporary' => ($fileCounter - $deleteCounter),
1948 'matching' => $criteriaMatch,
1949 'deleteType' => '<span>' . htmlspecialchars($deleteType[$tt]) . '</span>',
1950 'deleted' => $deleteCounter,
1951 'deleteCondition' => 'Delete files by condition',
1952 'numberFiles' => 'Number of files at a time:',
1953 'fromSubdirectory' => 'From sub-directory:',
1954 'execute' => 'Execute',
1955 'explanation' => '
1956 <p>
1957 This tool will delete files only if the last 10 characters
1958 before the extension (3 chars+\'.\') are hexadecimal valid
1959 ciphers, which are lowercase a-f and 0-9.
1960 </p>
1961 '
1962 );
1963 // Fill the markers
1964 $content = t3lib_parsehtml::substituteMarkerArray(
1965 $content,
1966 $markers,
1967 '###|###',
1968 TRUE,
1969 FALSE
1970 );
1971 // Add the content to the message array
1972 $this->message($headCode, 'Statistics', $content, 1);
1973
1974
1975 // Output the page
1976 $this->output($this->outputWrapper($this->printAll()));
1977 }
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991 /*******************************
1992 *
1993 * CONFIGURATION FORM
1994 *
1995 ********************************/
1996
1997 /**
1998 * Creating the form for editing the TYPO3_CONF_VARS options.
1999 *
2000 * @param string $type If get_form, display form, otherwise checks and store in localconf.php
2001 * @return void
2002 */
2003 function generateConfigForm($type='') {
2004 $default_config_content = t3lib_div::getUrl(PATH_t3lib.'config_default.php');
2005 $commentArr = $this->getDefaultConfigArrayComments($default_config_content);
2006
2007 switch($type) {
2008 case 'get_form':
2009 // Get the template file
2010 $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'GenerateConfigForm.html');
2011 // Get the template part from the file
2012 $template = t3lib_parsehtml::getSubpart($templateFile, '###TEMPLATE###');
2013
2014 foreach ($GLOBALS['TYPO3_CONF_VARS'] as $k => $va) {
2015 $ext='['.$k.']';
2016 $this->message($ext, '$TYPO3_CONF_VARS[\''.$k.'\']',$commentArr[0][$k],1);
2017
2018 foreach ($va as $vk => $value) {
2019 $textAreaSubpart = '';
2020 $booleanSubpart = '';
2021 $textLineSubpart = '';
2022
2023 $description = trim($commentArr[1][$k][$vk]);
2024 $isTextarea = preg_match('/^(<.*?>)?string \(textarea\)/i', $description) ? TRUE : FALSE;
2025 $doNotRender = preg_match('/^(<.*?>)?string \(exclude\)/i', $description) ? TRUE : FALSE;
2026
2027 if (!is_array($value) && !$doNotRender && ($this->checkForBadString($value) || $isTextarea)) {
2028 $k2 = '['.$vk.']';
2029
2030 if ($isTextarea) {
2031 // Get the subpart for a textarea
2032 $textAreaSubpart = t3lib_parsehtml::getSubpart($template, '###TEXTAREA###');
2033 // Define the markers content
2034 $textAreaMarkers = array(
2035 'id' => $k . '-' . $vk,
2036 'name' => 'TYPO3_INSTALL[extConfig]['.$k.']['.$vk.']',
2037 'value' => str_replace(array("'.chr(10).'", "' . LF . '"), array(LF, LF), $value)
2038 );
2039 $value = str_replace(array("'.chr(10).'", "' . LF . '"), array(' | ', ' | '), $value);
2040 // Fill the markers in the subpart
2041 $textAreaSubpart = t3lib_parsehtml::substituteMarkerArray(
2042 $textAreaSubpart,
2043 $textAreaMarkers,
2044 '###|###',
2045 TRUE,
2046 FALSE
2047 );
2048 } elseif (preg_match('/^(<.*?>)?boolean/i', $description)) {
2049 // Get the subpart for a checkbox
2050 $booleanSubpart = t3lib_parsehtml::getSubpart($template, '###BOOLEAN###');
2051 // Define the markers content
2052 $booleanMarkers = array(
2053 'id' => $k . '-' . $vk,
2054 'name' => 'TYPO3_INSTALL[extConfig]['.$k.']['.$vk.']',
2055 'value' => $value && strcmp($value, '0') ? $value : 1,
2056 'checked' => $value ? 'checked="checked"' : ''
2057 );
2058 // Fill the markers in the subpart
2059 $booleanSubpart = t3lib_parsehtml::substituteMarkerArray(
2060 $booleanSubpart,
2061 $booleanMarkers,
2062 '###|###',
2063 TRUE,
2064 FALSE
2065 );
2066 } else {
2067 // Get the subpart for an input text field
2068 $textLineSubpart = t3lib_parsehtml::getSubpart($template, '###TEXTLINE###');
2069 // Define the markers content
2070 $textLineMarkers = array(
2071 'id' => $k . '-' . $vk,
2072 'name' => 'TYPO3_INSTALL[extConfig]['.$k.']['.$vk.']',
2073 'value' => $value
2074 );
2075 // Fill the markers in the subpart
2076 $textLineSubpart = t3lib_parsehtml::substituteMarkerArray(
2077 $textLineSubpart,
2078 $textLineMarkers,
2079 '###|###',
2080 TRUE,
2081 FALSE
2082 );
2083 }
2084 // Substitute the subpart for a textarea
2085 $content = t3lib_parsehtml::substituteSubpart(
2086 $template,
2087 '###TEXTAREA###',
2088 $textAreaSubpart
2089 );
2090 // Substitute the subpart for a checkbox
2091 $content = t3lib_parsehtml::substituteSubpart(
2092 $content,
2093 '###BOOLEAN###',
2094 $booleanSubpart
2095 );
2096 // Substitute the subpart for an input text field
2097 $content = t3lib_parsehtml::substituteSubpart(
2098 $content,
2099 '###TEXTLINE###',
2100 $textLineSubpart
2101 );
2102 // Define the markers content
2103 $markers = array(
2104 'description' => $description,
2105 'key' => '[' . $k . '][' . $vk . ']',
2106 'label' => htmlspecialchars(t3lib_div::fixed_lgd_cs($value, 40))
2107 );
2108 // Fill the markers
2109 $content = t3lib_parsehtml::substituteMarkerArray(
2110 $content,
2111 $markers,
2112 '###|###',
2113 TRUE,
2114 FALSE
2115 );
2116 // Add the content to the message array
2117 $this->message($ext, $k2, $content);
2118 }
2119 }
2120 }
2121 break;
2122 default:
2123 if (is_array($this->INSTALL['extConfig'])) {
2124 $lines = $this->writeToLocalconf_control();
2125 foreach ($this->INSTALL['extConfig'] as $k => $va) {
2126 if (is_array($GLOBALS['TYPO3_CONF_VARS'][$k])) {
2127 foreach ($va as $vk => $value) {
2128 if (isset($GLOBALS['TYPO3_CONF_VARS'][$k][$vk])) {
2129 $doit=1;
2130 if ($k=='BE' && $vk=='installToolPassword') {
2131 if ($value) {
2132 if (isset($_POST['installToolPassword_check'])) {
2133 if (!$this->formProtection->validateToken(
2134 (string) $_POST['formToken'],
2135 'installToolPassword',
2136 'change'
2137 )) {
2138 $doit = FALSE;
2139 break;
2140 }
2141
2142 if (!t3lib_div::_GP('installToolPassword_check')
2143 || strcmp(t3lib_div::_GP('installToolPassword_check'), $value)
2144 ) {
2145 $doit = FALSE;
2146 $this->errorMessages[]
2147 = 'The two passwords did not ' .
2148 'match! The password was not changed.';
2149 }
2150 }
2151 if (t3lib_div::_GP('installToolPassword_md5')) $value =md5($value);
2152 } else $doit=0;
2153 }
2154
2155 $description = trim($commentArr[1][$k][$vk]);
2156 if (preg_match('/^string \(textarea\)/i', $description)) {
2157 // Force Unix linebreaks in textareas
2158 $value = str_replace(CR, '', $value);
2159 // Preserve linebreaks
2160 $value = str_replace(LF, "' . LF . '", $value);
2161 }
2162 if (preg_match('/^boolean/i', $description)) {
2163 // When submitting settings in the Install Tool, values that default to "false" or "true"
2164 // in config_default.php will be sent as "0" resp. "1". Therefore, reset the values
2165 // to their boolean equivalent.
2166 if ($GLOBALS['TYPO3_CONF_VARS'][$k][$vk] === false && $value === '0') {
2167 $value = false;
2168 } elseif ($GLOBALS['TYPO3_CONF_VARS'][$k][$vk] === true && $value === '1') {
2169 $value = true;
2170 }
2171 }
2172
2173 if ($doit && strcmp($GLOBALS['TYPO3_CONF_VARS'][$k][$vk],$value)) $this->setValueInLocalconfFile($lines, '$TYPO3_CONF_VARS[\''.$k.'\'][\''.$vk.'\']', $value);
2174 }
2175 }
2176 }
2177 }
2178 $this->writeToLocalconf_control($lines);
2179 }
2180 break;
2181 }
2182 }
2183
2184 /**
2185 * Make an array of the comments in the t3lib/config_default.php file
2186 *
2187 * @param string $string The contents of the config_default.php file
2188 * @param array $mainArray
2189 * @param array $commentArray
2190 * @return array
2191 */
2192 function getDefaultConfigArrayComments($string,$mainArray=array(),$commentArray=array()) {
2193 $lines = explode(LF, $string);
2194 $in=0;
2195 $mainKey='';
2196 foreach ($lines as $lc) {
2197 $lc = trim($lc);
2198 if ($in) {
2199 if (!strcmp($lc,');')) {
2200 $in=0;
2201 } else {
2202 if (preg_match('/["\']([[:alnum:]_-]*)["\'][[:space:]]*=>(.*)/i',$lc,$reg)) {
2203 preg_match('/,[\t\s]*\/\/(.*)/i',$reg[2],$creg);
2204 $theComment = trim($creg[1]);
2205 if (substr(strtolower(trim($reg[2])),0,5)=='array' && !strcmp($reg[1],strtoupper($reg[1]))) {
2206 $mainKey=trim($reg[1]);
2207 $mainArray[$mainKey]=$theComment;
2208 } elseif ($mainKey) {
2209 $commentArray[$mainKey][$reg[1]]=$theComment;
2210 }
2211 }
2212 }
2213 }
2214 if (!strcmp($lc, '$TYPO3_CONF_VARS = array(')) {
2215 $in=1;
2216 }
2217 }
2218 return array($mainArray,$commentArray);
2219 }
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233 /*******************************
2234 *
2235 * CHECK CONFIGURATION FUNCTIONS
2236 *
2237 *******************************/
2238
2239 /**
2240 * Checking php.ini configuration and set appropriate messages and flags.
2241 *
2242 * @return void
2243 */
2244 function checkConfiguration() {
2245 $ext='php.ini configuration checked';
2246 $this->message($ext);
2247
2248 // *****************
2249 // Incoming values:
2250 // *****************
2251
2252 // Includepath
2253 $incPaths = t3lib_div::trimExplode(TYPO3_OS=='WIN'?';':':', ini_get('include_path'));
2254 if (!in_array('.',$incPaths)) {
2255 $this->message($ext, 'Current directory (./) is not in include path!', '
2256 <p>
2257 <em>include_path=' . ini_get('include_path') . '</em>
2258 <br />
2259 Normally the current path, \'.\', is included in the
2260 include_path of PHP. Although TYPO3 does not rely on this,
2261 it is an unusual setting that may introduce problems for
2262 some extensions.
2263 </p>
2264 ', 1);
2265 } else $this->message($ext, 'Current directory in include path',"",-1);
2266
2267 // *****************
2268 // File uploads
2269 // *****************
2270 if (!ini_get('file_uploads')) {
2271 $this->message($ext, 'File uploads not allowed', '
2272 <p>
2273 <em>file_uploads=' . ini_get('file_uploads') . '</em>
2274 <br />
2275 TYPO3 uses the ability to upload files from the browser in
2276 various cases.
2277 <br />
2278 As long as this flag is disabled, you\'ll not be able to
2279 upload files.
2280 <br />
2281 But it doesn\'t end here, because not only are files not
2282 accepted by the server - ALL content in the forms are
2283 discarded and therefore nothing at all will be editable
2284 if you don\'t set this flag!
2285 <br />
2286 However if you cannot enable fileupload for some reason
2287 alternatively you change the default form encoding value
2288 with \$TYPO3_CONF_VARS[SYS][form_enctype].
2289 </p>
2290 ', 3);
2291 } else $this->message($ext, 'File uploads allowed',"",-1);
2292
2293 $upload_max_filesize = t3lib_div::getBytesFromSizeMeasurement(ini_get('upload_max_filesize'));
2294 $post_max_size = t3lib_div::getBytesFromSizeMeasurement(ini_get('post_max_size'));
2295 if ($upload_max_filesize<1024*1024*10) {
2296 $this->message($ext, 'Maximum upload filesize too small?', '
2297 <p>
2298 <em>upload_max_filesize=' . ini_get('upload_max_filesize') . '</em>
2299 <br />
2300 By default TYPO3 supports uploading, copying and moving
2301 files of sizes up to 10MB (You can alter the TYPO3 defaults
2302 by the config option TYPO3_CONF_VARS[BE][maxFileSize]).
2303 <br />
2304 Your current value is below this, so at this point, PHP sets
2305 the limits for uploaded filesizes and not TYPO3.
2306 <br />
2307 <strong>Notice:</strong> The limits for filesizes attached
2308 to database records are set in the tables.php configuration
2309 files (\$TCA) for each group/file field. You may override
2310 these values in localconf.php or by page TSconfig settings.
2311 </p>
2312 ', 1);
2313 }
2314 if ($upload_max_filesize > $post_max_size) {
2315 $this->message($ext, 'Maximum size for POST requests is smaller than max. upload filesize', '
2316 <p>
2317 <em>upload_max_filesize=' . ini_get('upload_max_filesize') . '
2318 , post_max_size=' . ini_get('post_max_size') . '</em>
2319 <br />
2320 You have defined a maximum size for file uploads which
2321 exceeds the allowed size for POST requests. Therefore the
2322 file uploads can not be larger than ' . ini_get('post_max_size') . '
2323 </p>
2324 ', 1);
2325 }
2326
2327 // *****************
2328 // Memory and functions
2329 // *****************
2330 $memory_limit_value = t3lib_div::getBytesFromSizeMeasurement(ini_get('memory_limit'));
2331
2332 if ($memory_limit_value && $memory_limit_value < t3lib_div::getBytesFromSizeMeasurement(TYPO3_REQUIREMENTS_MINIMUM_PHP_MEMORY_LIMIT)) {
2333 $this->message($ext, 'Memory limit below ' . TYPO3_REQUIREMENTS_MINIMUM_PHP_MEMORY_LIMIT, '
2334 <p>
2335 <em>memory_limit=' . ini_get('memory_limit') . '</em>
2336 <br />
2337 Your system is configured to enforce a memory limit of PHP
2338 scripts lower than ' . TYPO3_REQUIREMENTS_MINIMUM_PHP_MEMORY_LIMIT . '.
2339 The Extension Manager needs to include more PHP-classes than
2340 will fit into this memory space. There is nothing else to do
2341 than raise the limit. To be safe, ask the system
2342 administrator of the webserver to raise the limit to over
2343 ' . TYPO3_REQUIREMENTS_MINIMUM_PHP_MEMORY_LIMIT . '.
2344 </p>
2345 ', 3);
2346 } elseif(!$memory_limit_value) {
2347 $this->message($ext, 'Memory limit', '
2348 <p>
2349 <em>No memory limit in effect.</em>
2350 </p>
2351 ', -1);
2352 } else {
2353 $this->message($ext, 'Memory limit: ' . ini_get('memory_limit'), '', -1);
2354 }
2355 if (ini_get('max_execution_time')<30) {
2356 $this->message($ext, 'Maximum execution time below 30 seconds', '
2357 <p>
2358 <em>max_execution_time=' . ini_get('max_execution_time') . '</em>
2359 <br />
2360 May impose problems if too low.
2361 </p>
2362 ', 1);
2363 } else {
2364 $this->message($ext, 'Maximum execution time: ' . ini_get('max_execution_time') . ' seconds', '', -1);
2365 }
2366 if (ini_get('disable_functions')) {
2367 $this->message($ext, 'Functions disabled!', '
2368 <p>
2369 <em>disable_functions=' . ini_get('disable_functions') . '</em>
2370 <br />
2371 The above list of functions are disabled. If TYPO3 use any
2372 of these there might be trouble.
2373 <br />
2374 TYPO3 is designed to use the default set of PHP4.3.0+
2375 functions plus the functions of GDLib.
2376 <br />
2377 Possibly these functions are disabled due to security risks
2378 and most likely the list would include a function like
2379 <em>exec()</em> which is use by TYPO3 to access ImageMagick.
2380 </p>
2381 ', 2);
2382 } else {
2383 $this->message($ext, 'Functions disabled: none', '', -1);
2384 }
2385 // Mail tests
2386 if (TYPO3_OS == 'WIN') {
2387 $smtp = ini_get('SMTP');
2388 $bad_smtp = false;
2389 if (!t3lib_div::validIP($smtp)) {
2390 $smtp_addr = @gethostbyname($smtp);
2391 $bad_smtp = ($smtp_addr == $smtp);
2392 }
2393 else {
2394 $smtp_addr = $smtp;
2395 }
2396 if (!$smtp || $bad_smtp || !t3lib_div::testInt(ini_get('smtp_port'))) {
2397 $this->message($ext, 'Mail configuration is not set correctly', '
2398 <p>
2399 Mail configuration is not set
2400 <br />
2401 PHP mail() function requires SMTP and smtp_port to have
2402 correct values on Windows.
2403 </p>
2404 ', 2);
2405 } else {
2406 if (($smtp_addr == '127.0.0.1' || $smtp_addr == '::1') && ($_SERVER['SERVER_ADDR'] == '127.0.0.1' || $_SERVER['SERVER_ADDR'] == '::1')) {
2407 $this->message($ext, 'Mail is configured (potential problem exists!)', '
2408 <p>
2409 <em>SMTP=' . $smtp . '</em> - <strong>Note:</strong>
2410 this server! Are you sure it runs SMTP server?
2411 <br />
2412 <em>smtp_port=' . ini_get('smtp_port') . '</em>
2413 </p>' . $this->check_mail('get_form') . '
2414 ', 1);
2415 } else {
2416 $this->message($ext, 'Mail is configured', '
2417 <p>
2418 <em>SMTP=' . $smtp . '</em>
2419 <br />
2420 <em>smtp_port=' . ini_get('smtp_port') . '</em>
2421 </p>' . $this->check_mail('get_form') .'
2422 ', -1);
2423 }
2424 }
2425 } elseif (!ini_get('sendmail_path')) {
2426 $this->message($ext, 'Sendmail path not defined!', '
2427 <p>
2428 This may be critical to TYPO3\'s use of the mail() function.
2429 Please be sure that the mail() function in your
2430 php-installation works!
2431 </p>' . $this->check_mail('get_form') . '
2432 ', 1);
2433 } else {
2434 list($prg) = explode(' ', ini_get('sendmail_path'));
2435 if (!@is_executable($prg)) {
2436 $this->message($ext, 'Sendmail program not found or not executable?', '
2437 <p>
2438 <em>sendmail_path=' . ini_get('sendmail_path') . '</em>
2439 <br />
2440 This may be critical to TYPO3\'s use of the mail()
2441 function. Please be sure that the mail() function in
2442 your php-installation works!
2443 </p>' . $this->check_mail('get_form') .'
2444 ', 1);
2445 } else {
2446 $this->message($ext, 'Sendmail OK', '
2447 <p>
2448 <em>sendmail_path=' . ini_get('sendmail_path') . '</em>
2449 </p>' . $this->check_mail('get_form') . '
2450 ', -1);
2451 }
2452 }
2453
2454 // *****************
2455 // Safe mode related
2456 // *****************
2457 if (t3lib_utility_PhpOptions::isSafeModeEnabled()) {
2458 $this->message($ext, 'Safe mode turned on', '
2459 <p>
2460 <em>safe_mode=' . ini_get('safe_mode') . '</em>
2461 <br />
2462 In safe_mode PHP is restricted in several ways. This is a
2463 good thing because it adds protection to your (and others)
2464 scripts. But it may also introduce problems. In TYPO3 this
2465 <em>may be</em> a problem in two areas: File administration
2466 and execution of external programs, in particular
2467 ImageMagick.
2468 <br />
2469 If you just ignore this warning, you\'ll most likely find,
2470 that TYPO3 seems to work except from the image-generation.
2471 The problem in that case is that the external ImageMagick
2472 programs are not allowed to be executed from the regular
2473 paths like "/usr/bin/" or "/usr/X11R6/bin/".
2474 <br />
2475 If you use safe_mode with TYPO3, you should disable use of
2476 external programs ([BE][disable_exec_function]=1).
2477 <br />
2478 In safe mode you must ensure that all the php-scripts and
2479 upload folders are owned by the same user.
2480 </p>
2481 <p>
2482 <em>safe_mode_exec_dir=' . ini_get('safe_mode_exec_dir') . '</em>
2483 <br />
2484 If the ImageMagick utilities are located in this directory,
2485 everything is fine. Below on this page, you can see if
2486 ImageMagick is found here. If not, ask you ISP to put the
2487 three ImageMagick programs, \'convert\',
2488 \'combine\'/\'composite\' and \'identify\' there (eg. with
2489 symlinks if Unix server)
2490 </p>
2491 <p>
2492 <strong>Example of safe_mode settings:</strong>
2493 <br />
2494 Set this in the php.ini file:
2495 </p>
2496 <p>
2497 ; Safe Mode
2498 <br />
2499 safe_mode = On
2500 <br />
2501 safe_mode_exec_dir = /usr/bin/
2502 </p>
2503 <p>
2504 ...and the ImageMagick \'/usr/bin/convert\' will be
2505 executable.
2506 <br />
2507 The last slash is important (..../) and you can only specify
2508 one directory.
2509 </p>
2510 <p>
2511 <strong>Notice: </strong>
2512 <br />
2513 ImageMagick 6 or GraphicsMagick is recommended and the binaries are
2514 normally installed in /usr/bin.
2515 <br />
2516 Paths to ImageMagick are defined in localconf.php and may be
2517 something else than /usr/bin/, but this is default for
2518 ImageMagick 6+
2519 </p>
2520 ', 2);
2521 if (ini_get('doc_root')) {
2522 $this->message($ext, 'doc_root set', '
2523 <p>
2524 <em>doc_root=' . ini_get('doc_root') . '</em>
2525 <br />
2526 PHP cannot execute scripts outside this directory. If
2527 that is a problem is please correct it.
2528 </p>
2529 ', 1);
2530 }
2531 $this->config_array['safemode']=1;
2532 } else {
2533 $this->message($ext, 'safe_mode: off',"",-1);
2534 }
2535 if (t3lib_utility_PhpOptions::isSqlSafeModeEnabled()) {
2536 $this->message($ext, 'sql.safe_mode is enabled', '
2537 <p>
2538 <em>sql.safe_mode=' . ini_get('sql.safe_mode') . '</em>
2539 <br />
2540 This means that you can only connect to the database with a
2541 username corresponding to the user of the webserver process
2542 or fileowner. Consult your ISP for information about this.
2543 Also see <a href="http://www.wrox.com/Consumer/Store/Books/2963/29632002.htm">
2544 http://www.wrox.com/Consumer/Store/Books/2963/29632002.htm</a>
2545 <br />
2546 The owner of the current file is:
2547 <strong>' . get_current_user () . '</strong>
2548 </p>
2549 ', 1);
2550 $this->config_array['sql.safe_mode_user'] = get_current_user();
2551 } else {
2552 $this->message($ext, 'sql.safe_mode: off',"",-1);
2553 }
2554 if (ini_get('open_basedir')) {
2555 $this->message($ext, 'open_basedir set', '
2556 <p>
2557 <em>open_basedir=' . ini_get('open_basedir') . '</em>
2558 <br />
2559 This restricts TYPO3 to open and include files only in this
2560 path. Please make sure that this does not prevent TYPO3 from
2561 running.
2562 <br />
2563 <strong>Notice (UNIX):</strong> Before checking a path
2564 according to open_basedir, PHP resolves all symbolic links.
2565 </p>
2566 ', 1);
2567 // ???? If this option was set falsely you probably didn't see this page in the
2568 // first place, but this option <strong>may spoil this configuration test</strong>
2569 // when checking for such as ImageMagick executables.
2570 } else {
2571 $this->message($ext, 'open_basedir: off',"",-1);
2572 }
2573
2574 // Check availability of PHP session support
2575 if (extension_loaded('session')) {
2576 $this->message($ext, 'PHP sessions availiable', '
2577 <p>
2578 <em>PHP Sessions availiabe</em>
2579 <br />
2580 PHP is compiled with session support and session support is
2581 available.
2582 </p>
2583 ', -1);
2584 } else {
2585 $this->message($ext, 'PHP Sessions not availiabe', '
2586 <p>
2587 PHP is not compiled with session support, or session support
2588 is disabled in php.ini.
2589 <br />
2590 TYPO3 needs session support
2591 </p>
2592 ', 3);
2593 }
2594
2595 // Suhosin/Hardened PHP:
2596 $suhosinDescription = '
2597 <p>
2598 Suhosin limits the number of elements that can be submitted in
2599 forms to the server. This will affect for example the
2600 "All configuration" section in the Install Tool or Inline
2601 Relational Record Editing (IRRE) with many child records.
2602 </p>';
2603 if (extension_loaded('suhosin')) {
2604 $suhosinSuggestion = '
2605 <p>
2606 At least a value of 400 is suggested.
2607 </p>
2608 ';
2609
2610 $suhosinRequestMaxVars = ini_get('suhosin.request.max_vars');
2611 $suhosinPostMaxVars = ini_get('suhosin.post.max_vars');
2612 $suhosinRequestMaxVarsType = ($suhosinRequestMaxVars < 400 ? 2 : -1);
2613 $suhosinPostMaxVarsType = ($suhosinPostMaxVars < 400 ? 2 : -1);
2614 $suhosinType = ($suhosinRequestMaxVars < 400 || $suhosinPostMaxVars < 400 ? 2 : -1);
2615
2616 $this->message($ext, 'Suhosin/Hardened PHP is loaded', $suhosinDescription, $suhosinType);
2617 $this->message($ext, 'suhosin.request.max_vars: ' . $suhosinRequestMaxVars, $suhosinSuggestion, $suhosinRequestMaxVarsType);
2618 $this->message($ext, 'suhosin.post.max_vars: ' . $suhosinPostMaxVars, $suhosinSuggestion, $suhosinPostMaxVarsType);
2619 } else {
2620 $this->message($ext, 'Suhosin/Hardened PHP is not loaded', $suhosinDescription, 0);
2621 }
2622
2623 // Check for stripped PHPdoc comments that are required to evaluate annotations:
2624 $method = new ReflectionMethod('tx_install', 'check_mail');
2625 if (strlen($method->getDocComment()) === 0) {
2626 $description = '
2627 <p>
2628 The system extension Extbase evaluates annotations in PHPdoc
2629 comments and thus requires eAccelerator not to strip away
2630 these parts. However, this is currently the only part in the
2631 TYPO3 Core (beside deprecation log and unit tests). If
2632 Extbase is not used, recompiling eAccelerator is not
2633 required at all.
2634 <br/>
2635 <br/>
2636 If you do not want comments to be stripped by eAccelerator,
2637 please recompile with the following configuration setting
2638 (<a href="http://eaccelerator.net/ticket/229" target="_blank">
2639 more details</a>):
2640 <br />
2641 <em>--with-eaccelerator-doc-comment-inclusion</em>
2642 </p>
2643 ';
2644 $this->message($ext, 'PHPdoc comments are stripped', $description, 2);
2645 }
2646 }
2647
2648 /**
2649 * Check if PHP function mail() works
2650 *
2651 * @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.
2652 * @return string The mail form if it is requested with get_form
2653 */
2654 function check_mail($cmd='') {
2655 switch($cmd) {
2656 case 'get_form':
2657 $out = '
2658 <p id="checkMailForm">
2659 You can check the t3lib_mail functionality by entering your email
2660 address here and press the button. You should then
2661 receive a testmail from "typo3installtool@example.org".
2662 </p>
2663 ';
2664 // Get the template file
2665 $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'CheckMail.html');
2666 // Get the template part from the file
2667 $template = t3lib_parsehtml::getSubpart($templateFile, '###TEMPLATE###');
2668
2669 if (!empty($this->mailMessage)) {
2670 // Get the subpart for the mail is sent message
2671 $mailSentSubpart = t3lib_parsehtml::getSubpart($template, '###MAILSENT###');
2672 }
2673 // Substitute the subpart for the mail is sent message
2674 $template = t3lib_parsehtml::substituteSubpart(
2675 $template,
2676 '###MAILSENT###',
2677 $mailSentSubpart
2678 );
2679 // Define the markers content
2680 $markers = array(
2681 'message' => $this->mailMessage,
2682 'enterEmail' => 'Enter the email address',
2683 'actionUrl' => $this->action . '#checkMailForm',
2684 'submit' => 'Send test mail'
2685 );
2686 // Fill the markers
2687 $out .= t3lib_parsehtml::substituteMarkerArray(
2688 $template,
2689 $markers,
2690 '###|###',
2691 TRUE,
2692 TRUE
2693 );
2694 break;
2695 default:
2696 if (trim($this->INSTALL['check_mail'])) {
2697 $subject = 'TEST SUBJECT';
2698 $email = trim($this->INSTALL['check_mail']);
2699
2700 /** @var $mailMessage t3lib_mail_Message */
2701 $mailMessage = t3lib_div::makeInstance('t3lib_mail_Message');
2702 $mailMessage->addTo($email)
2703 ->addFrom('typo3installtool@example.org', 'TYPO3 Install Tool')
2704 ->setSubject($subject)
2705 ->setBody('<html><body>HTML TEST CONTENT</body></html>');
2706 $mailMessage->addPart('TEST CONTENT');
2707 $mailMessage->send();
2708 $this->mailMessage= 'Mail was sent to: ' . $email;
2709 }
2710 break;
2711 }
2712 return $out;
2713 }
2714
2715 /**
2716 * Checking php extensions, specifically GDLib and Freetype
2717 *
2718 * @return void
2719 */
2720 function checkExtensions() {
2721 $ext = 'GDLib';
2722 $this->message($ext);
2723
2724 $software_info=1;
2725 if (extension_loaded('gd') && $this->isGD()) {
2726 $this->config_array['gd']=1;
2727 $this->message($ext, 'GDLib found',"",-1);
2728 if ($this->isPNG()) {
2729 $this->config_array['gd_png']=1;
2730 $this->message($ext, 'PNG supported',"",-1);
2731 }
2732 if ($this->isGIF()) {
2733 $this->config_array['gd_gif']=1;
2734 $this->message($ext, 'GIF supported',"",-1);
2735 }
2736 if ($this->isJPG()) {
2737 $this->config_array['gd_jpg']=1;
2738 $this->message($ext, 'JPG supported (not used by TYPO3)','');
2739 }
2740 if (!$this->config_array['gd_gif'] && !$this->config_array['gd_png']) {
2741 $this->message($ext, 'PNG or GIF not supported', '
2742 <p>
2743 Your GDLib supports either GIF nor PNG. It must support
2744 either one of them.
2745 </p>
2746 ', 2);
2747 } else {
2748 $msg=array();
2749 if ($this->config_array['gd_gif'] && $this->config_array['gd_png']) {
2750 $msg[] = '
2751 <p>
2752 You can choose between generating GIF or PNG files,
2753 as your GDLib supports both.
2754 </p>
2755 ';
2756 }
2757 if ($this->config_array['gd_gif']) {
2758 $msg[] = '
2759 <p>
2760 You should watch out for the generated size of the
2761 GIF-files because some versions of the GD library do
2762 not compress them with LZW, but RLE and ImageMagick
2763 is subsequently used to compress with LZW. But in
2764 the case of ImageMagick failing this task (eg. not
2765 being compiled with LZW which is the case with some
2766 versions) you\'ll end up with GIF-filesizes all too
2767 big!
2768 <br />
2769 This Install Tool tests what kinds of GIF
2770 compression are available in the ImageMagick
2771 installations by a physical test. You can also check
2772 it manually by opening a TYPO3 generated gif-file
2773 with Photoshop and save it in a new file. If the
2774 file sizes of the original and the new file are
2775 almost the same, you\'re having LZW compression and
2776 everything is fine.
2777 </p>
2778 ';
2779 }
2780 if ($this->config_array['gd_png']) {
2781 $msg[] = '
2782 <p>
2783 TYPO3 prefers the use of GIF-files and most likely
2784 your visitors on your website does too as not all
2785 browsers support PNG yet.
2786 </p>
2787 ';
2788 }
2789 $this->message($ext, 'GIF / PNG issues', implode(LF, $msg), 1);
2790 }
2791 if (!$this->isTTF()) {
2792 $this->message($ext, 'FreeType is apparently not installed', '
2793 <p>
2794 It looks like the FreeType library is not compiled into
2795 GDLib. This is required when TYPO3 uses GDLib and
2796 you\'ll most likely get errors like \'ImageTTFBBox is
2797 not a function\' or \'ImageTTFText is not a function\'.
2798 </p>
2799 ', 2);
2800 } else {
2801 $this->message($ext, 'FreeType quick-test (' . ($this->isGIF() ? 'as GIF' : 'as PNG') . ')', '
2802 <p>
2803 <img src="' . htmlspecialchars(t3lib_div::getIndpEnv('REQUEST_URI') . '&testingTrueTypeSupport=1') . '" alt="" />
2804 <br />
2805 (If the text is exceeding the image borders you are
2806 using Freetype 2 and need to set
2807 TYPO3_CONF_VARS[GFX][TTFdpi]=96.
2808 <br />
2809 If there is no image at all Freetype is most likely NOT
2810 available and you can just as well disable GDlib for
2811 TYPO3...)
2812 </p>
2813 ', -1);
2814 $this->config_array['freetype']=1;
2815 }
2816 } else {
2817 $this->message($ext, 'GDLib2 not found', '
2818 <p>
2819 GDLib2 is required if you want to use the GIFBUILDER object
2820 in TypoScript. GIFBUILDER is in charge of all advanced image
2821 generation in TypoScript, including graphical menuitems.
2822 <br />
2823 GDLib2 is also used in the TYPO3 Backend (TBE) to generate
2824 record icons and new module tabs.
2825 <br />
2826 It\'s highly recommended to install this library. Remember
2827 to compile GD with FreeType which is also required.
2828 <br />
2829 If you choose not to install GDLib, you can disable it in
2830 the configuration with [GFX][gdlib]=0;.
2831 </p>
2832 ', 2);
2833 }
2834 $this->message($ext, 'GDLib software information', $this->getGDSoftwareInfo());
2835 }
2836
2837 /**
2838 * Checking and testing that the required writable directories are writable.
2839 *
2840 * @return void
2841 */
2842 function checkDirs() {
2843 // Check typo3/temp/
2844 $ext='Directories';
2845 $this->message($ext);
2846
2847 $uniqueName = md5(uniqid(microtime()));
2848
2849 // The requirement level (the integer value, ie. the second value of the value array) has the following meanings:
2850 // -1 = not required, but if it exists may be writable or not
2851 // 0 = not required, if it exists the dir should be writable
2852 // 1 = required, don't has to be writable
2853 // 2 = required, has to be writable
2854
2855 $checkWrite=array(
2856 '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'),
2857 'typo3temp/pics/' => array('This folder is part of the typo3temp/ section. It needs to be writable, too.',2,'dir_typo3temp'),
2858 'typo3temp/temp/' => array('This folder is part of the typo3temp/ section. It needs to be writable, too.',2,'dir_typo3temp'),
2859 'typo3temp/llxml/' => array('This folder is part of the typo3temp/ section. It needs to be writable, too.',2,'dir_typo3temp'),
2860 'typo3temp/cs/' => array('This folder is part of the typo3temp/ section. It needs to be writable, too.',2,'dir_typo3temp'),
2861 'typo3temp/GB/' => array('This folder is part of the typo3temp/ section. It needs to be writable, too.',2,'dir_typo3temp'),
2862 'typo3temp/locks/' => array('This folder is part of the typo3temp/ section. It needs to be writable, too.',2,'dir_typo3temp'),
2863 '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),
2864 'typo3conf/ext/' => array('Location for local extensions. Must be writable if the Extension Manager is supposed to install extensions for this website.',0),
2865 'typo3conf/l10n/' => array('Location for translations. Must be writable if the Extension Manager is supposed to install translations for extensions.',0),
2866 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),
2867 'uploads/' => array('Location for uploaded files from RTE, in the subdirectories for uploaded files of content elements.',2),
2868 'uploads/pics/' => array('Typical location for uploaded files (images especially).',0),
2869 'uploads/media/' => array('Typical location for uploaded files (non-images especially).',0),
2870 'uploads/tf/' => array('Typical location for uploaded files (TS template resources).',0),
2871 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileadminDir'] => array('Location for local files such as templates, independent uploads etc.',-1),
2872 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileadminDir'] . '_temp_/' => array('Typical temporary location for default upload of files by administrators.',0),
2873 );
2874
2875 foreach ($checkWrite as $relpath => $descr) {
2876
2877 // Check typo3temp/
2878 $general_message = $descr[0];
2879
2880 // If the directory is missing, try to create it
2881 if (!@is_dir(PATH_site.$relpath)) {
2882 t3lib_div::mkdir(PATH_site.$relpath);
2883 }
2884
2885 if (!@is_dir(PATH_site.$relpath)) {
2886 if ($descr[1]) { // required...
2887 $this->message($ext, $relpath.' directory does not exist and could not be created', '
2888 <p>
2889 <em>Full path: ' . PATH_site . $relpath . '</em>
2890 <br />
2891 ' . $general_message . '
2892 </p>
2893 <p>
2894 This error should not occur as ' . $relpath . ' must
2895 always be accessible in the root of a TYPO3 website.
2896 </p>
2897 ', 3);
2898 } else {
2899 if ($descr[1] == 0) {
2900 $msg = 'This directory does not necessarily have to exist but if it does it must be writable.';
2901 } else {
2902 $msg = 'This directory does not necessarily have to exist and if it does it can be writable or not.';
2903 }
2904 $this->message($ext, $relpath.' directory does not exist', '
2905 <p>
2906 <em>Full path: ' . PATH_site . $relpath . '</em>
2907 <br />
2908 ' . $general_message . '
2909 </p>
2910 <p>
2911 ' . $msg . '
2912 </p>
2913 ', 2);
2914 }
2915 } else {
2916 $file = PATH_site.$relpath.$uniqueName;
2917 @touch($file);
2918 if (@is_file($file)) {
2919 unlink($file);
2920 if ($descr[2]) { $this->config_array[$descr[2]]=1; }
2921 $this->message($ext, $relpath.' writable','',-1);
2922 } else {
2923 $severity = ($descr[1]==2 || $descr[1]==0) ? 3 : 2;
2924 if ($descr[1] == 0 || $descr[1] == 2) {
2925 $msg = 'The directory '.$relpath.' must be writable!';
2926 } elseif ($descr[1] == -1 || $descr[1] == 1) {
2927 $msg = 'The directory '.$relpath.' does not neccesarily have to be writable.';
2928 }
2929 $this->message($ext, $relpath .' directory not writable', '
2930 <p>
2931 <em>Full path: ' . $file . '</em>
2932 <br />
2933 ' . $general_message . '
2934 </p>
2935 <p>
2936 Tried to write this file (with touch()) but didn\'t
2937 succeed.
2938 <br />
2939 ' . $msg . '
2940 </p>
2941 ', $severity);
2942 }
2943 }
2944 }
2945 }
2946
2947 /**
2948 * Checking for existing ImageMagick installs.
2949 *
2950 * 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.
2951 *
2952 * @param array $paths Possible ImageMagick paths
2953 * @return void
2954 */
2955 function checkImageMagick($paths) {
2956 $ext='Check Image Magick';
2957 $this->message($ext);
2958 // Get the template file
2959 $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'CheckImageMagick.html');
2960
2961 $paths = array_unique($paths);
2962
2963 $programs = explode(',','gm,convert,combine,composite,identify');
2964 $isExt = TYPO3_OS=="WIN" ? ".exe" : "";
2965 $this->config_array['im_combine_filename']='combine';
2966 foreach ($paths as $k => $v) {
2967 if (!preg_match('/[\\/]$/',$v)) $v.='/';
2968 foreach ($programs as $filename) {
2969 if (ini_get('open_basedir') || (file_exists($v)&&@is_file($v.$filename.$isExt))) {
2970 $version = $this->_checkImageMagick_getVersion($filename,$v);
2971 if($version > 0) {
2972 // Assume GraphicsMagick
2973 if($filename=='gm') {
2974 $index[$v]['gm']=$version;
2975 // No need to check for "identify" etc.
2976 continue;
2977 } else {
2978 // Assume ImageMagick
2979 $index[$v][$filename]=$version;
2980 }
2981 }
2982 }
2983 }
2984 if (count($index[$v])>=3 || $index[$v]['gm']) {
2985 $this->config_array['im'] = 1;
2986 }
2987
2988 if ($index[$v]['gm'] || (!$index[$v]['composite'] && $index[$v]['combine'])) {
2989 $this->config_array['im_combine_filename']='combine';
2990 } elseif ($index[$v]['composite'] && !$index[$v]['combine']) {
2991 $this->config_array['im_combine_filename']='composite';
2992 }
2993