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