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