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