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