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