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