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