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