Fixed #11430: Performance improvement: use $GLOBALS['EXEC_TIME'] instead of time...
[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($uKey)
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 * 4898: function convertByteSize($bytes)
132 * 4912: function securityRisk()
133 * 4930: function alterPasswordForm()
134 * 4946: function messageBasicFinished()
135 * 4968: function setScriptName($type)
136 * 4981: function formWidth($size=48,$textarea=0,$styleOverride='')
137 * 5002: function formWidthText($size=48,$styleOverride='',$wrap='')
138 * 5018: function getBackupFilename($filename)
139 *
140 * TOTAL FUNCTIONS: 82
141 * (This index is automatically created/updated by the extension "extdeveval")
142 *
143 */
144
145 // include update classes
146 require_once(t3lib_extMgm::extPath('install').'updates/class.tx_coreupdates_compatversion.php');
147 require_once(t3lib_extMgm::extPath('install').'updates/class.tx_coreupdates_cscsplit.php');
148 require_once(t3lib_extMgm::extPath('install').'updates/class.tx_coreupdates_notinmenu.php');
149 require_once(t3lib_extMgm::extPath('install').'updates/class.tx_coreupdates_mergeadvanced.php');
150 require_once(t3lib_extMgm::extPath('install').'updates/class.tx_coreupdates_installsysexts.php');
151 require_once(t3lib_extMgm::extPath('install').'updates/class.tx_coreupdates_imagescols.php');
152
153 /**
154 * Install Tool module
155 *
156 * @author Kasper Skaarhoj <kasperYYYY@typo3.com>
157 * @author Ingmar Schlecht <ingmar@typo3.org>
158 * @package TYPO3
159 * @subpackage tx_install
160 */
161 class tx_install extends t3lib_install {
162 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()
163 var $getGD_end_string = '</table>'; // Used to identify the end of the GD section (found with getGD_start_string) in the output from phpinfo()
164 var $getTTF_string = 'with TTF library'; // Used to identify whether TTF-lib is included with GD
165 var $getTTF_string_alt = 'with freetype'; // Used to identify whether TTF-lib is included with GD
166 var $action = ''; // The url that calls this script
167 var $scriptSelf = 'index.php'; // The url that calls this script
168 var $fontTag2='<div class="bodytext">';
169 var $fontTag1='<div class="smalltext">';
170 var $updateIdentity = 'TYPO3 Install Tool';
171 var $headerStyle ='';
172 var $contentBeforeTable='';
173 var $setAllCheckBoxesByDefault=0;
174
175 var $allowFileEditOutsite_typo3conf_dir=0;
176
177 var $INSTALL =array(); // In constructor: is set to global GET/POST var TYPO3_INSTALL
178 var $checkIMlzw = 0; // If set, lzw capabilities of the available ImageMagick installs are check by actually writing a gif-file and comparing size
179 var $checkIM = 0; // If set, ImageMagick is checked.
180 var $dumpImCommands=1; // If set, the image Magick commands are always outputted in the image processing checker
181 var $mode = ''; // If set to "123" then only most vital information is displayed.
182 var $step = 0; // If set to 1,2,3 or GO it signifies various functions.
183
184 // internal
185 var $passwordOK=0; // This is set, if the password check was ok. The function init() will exit if this is not set
186 var $silent=1; // If set, the check routines don't add to the message-array
187 var $messageFunc_nl2br=1;
188 var $sections=array(); // Used to gather the message information.
189 var $fatalError=0; // This is set if some error occured that will definitely prevent TYpo3 from running.
190 var $sendNoCacheHeaders=1;
191 var $config_array = array( // Flags are set in this array if the options are available and checked ok.
192 'gd'=>0,
193 'gd_gif'=>0,
194 'gd_png'=>0,
195 'gd_jpg'=>0,
196 'freetype' => 0,
197 'safemode' => 0,
198 'dir_typo3temp' => 0,
199 'dir_temp' => 0,
200 'im_versions' => array(),
201 'im' => 0,
202 'sql.safe_mode_user' => '',
203 'mysqlConnect' => 0,
204 'no_database' => 0
205 );
206 var $typo3temp_path='';
207
208 var $menuitems = array(
209 'config' => 'Basic Configuration',
210 'database' => 'Database Analyser',
211 'update' => 'Update Wizard',
212 'images' => 'Image Processing',
213 'extConfig' => 'All Configuration',
214 'typo3temp' => 'typo3temp/',
215 'cleanup' => 'Clean up database',
216 'phpinfo' => 'phpinfo()',
217 'typo3conf_edit' => 'Edit files in typo3conf/',
218 'about' => 'About'
219 );
220 var $cookie_name = 'Typo3InstallTool';
221 var $JSmessage = '';
222
223
224
225
226
227
228 /**
229 * Constructor
230 *
231 * @return [type] ...
232 */
233 function tx_install() {
234 parent::t3lib_install();
235
236 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';");
237
238 if ($this->sendNoCacheHeaders) {
239 header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
240 header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
241 header('Expires: 0');
242 header('Cache-Control: no-cache, must-revalidate');
243 header('Pragma: no-cache');
244 }
245
246 // ****************************
247 // Initializing incoming vars.
248 // ****************************
249 $this->INSTALL = t3lib_div::_GP('TYPO3_INSTALL');
250 $this->mode = t3lib_div::_GP('mode');
251 $this->step = t3lib_div::_GP('step');
252 $this->redirect_url = t3lib_div::_GP('redirect_url');
253
254 if ($_GET['TYPO3_INSTALL']['type']) {
255 $this->INSTALL['type'] = $_GET['TYPO3_INSTALL']['type'];
256 }
257
258 if ($this->step == 3) {
259 $this->INSTALL['type'] = 'database';
260 }
261
262 if ($this->mode=='123') {
263 $tempItems = $this->menuitems;
264 $this->menuitems = array(
265 'config' => $tempItems['config'],
266 'database' => $tempItems['database']
267 );
268 if (!$this->INSTALL['type'] || !isset($this->menuitems[$this->INSTALL['type']])) {
269 $this->INSTALL['type'] = 'config';
270 }
271 } else {
272 if (!$this->INSTALL['type'] || !isset($this->menuitems[$this->INSTALL['type']])) {
273 $this->INSTALL['type'] = 'about';
274 }
275 }
276
277 $this->action = $this->scriptSelf.'?TYPO3_INSTALL[type]='.$this->INSTALL['type'].($this->mode?'&mode='.rawurlencode($this->mode):'').($this->step?'&step='.rawurlencode($this->step):'');
278 $this->typo3temp_path = PATH_site.'typo3temp/';
279
280
281 // ****************
282 // Check password
283 // ****************
284 // Getting a unique session key, used to encode the session-access cookie later...
285 $uKey = $_COOKIE[$this->cookie_name.'_key'];
286 if (!$uKey) {
287 $uKey = md5(uniqid(microtime()));
288 SetCookie($this->cookie_name.'_key', $uKey, 0, t3lib_div::getIndpEnv('TYPO3_SITE_PATH')); // Cookie is set
289
290 $this->JSmessage='SECURITY:
291 Make sure to protect the Install Tool with another password than "joh316".
292 Better yet you can add a die() function call to typo3/install/index.php after usage.
293
294 IF THE INSTALL TOOL CRASHES...
295 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.
296 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.
297 On behalf of PHP we regret this inconvenience.
298
299 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.
300 ';
301
302 }
303 // Check if the password from TYPO3_CONF_VARS combined with uKey matches the sKey cookie. If not, ask for password.
304 $sKey = $_COOKIE[$this->cookie_name];
305
306 if (md5($GLOBALS['TYPO3_CONF_VARS']['BE']['installToolPassword'].'|'.$uKey) == $sKey || $this->checkPassword($uKey)) {
307 $this->passwordOK=1;
308
309 $enableInstallToolFile = PATH_typo3conf . 'ENABLE_INSTALL_TOOL';
310 if (is_file ($enableInstallToolFile)) {
311 // Extend the age of the ENABLE_INSTALL_TOOL file by one hour
312 touch ($enableInstallToolFile);
313 }
314
315 if($this->redirect_url) {
316 header('Location: '.$this->redirect_url);
317 }
318 } else {
319 $this->loginForm();
320 }
321 }
322
323 /**
324 * Returns true if submitted password is ok. Else displays a form in which to enter password.
325 *
326 * @param [type] $uKey: ...
327 * @return bool whether the submitted password is ok
328 */
329 function checkPassword($uKey) {
330 $p = t3lib_div::_GP('password');
331
332 if ($p && md5($p)==$GLOBALS['TYPO3_CONF_VARS']['BE']['installToolPassword']) {
333 $sKey = md5($GLOBALS['TYPO3_CONF_VARS']['BE']['installToolPassword'].'|'.$uKey);
334 SetCookie($this->cookie_name, $sKey, 0, t3lib_div::getIndpEnv('TYPO3_SITE_PATH'));
335
336 // Sending warning email
337 $wEmail = $GLOBALS['TYPO3_CONF_VARS']['BE']['warning_email_addr'];
338 if ($wEmail) {
339 $subject="Install Tool Login at '".$GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename']."'";
340 $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').')';
341 mail($wEmail,
342 $subject,
343 $email_body,
344 'From: TYPO3 Install Tool WARNING <>'
345 );
346 }
347 return true;
348 } else {
349 // Bad password, send warning:
350 if ($p) {
351 $wEmail = $GLOBALS['TYPO3_CONF_VARS']['BE']['warning_email_addr'];
352 if ($wEmail) {
353 $subject="Install Tool Login ATTEMPT at '".$GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename']."'";
354 $email_body="There has been an Install Tool login attempt at TYPO3 site '".$GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename']."' (".t3lib_div::getIndpEnv('HTTP_HOST').").
355 The MD5 hash of the last 5 characters of the password tried was '".substr(md5($p), -5)."'
356 REMOTE_ADDR was '".t3lib_div::getIndpEnv('REMOTE_ADDR')."' (".t3lib_div::getIndpEnv('REMOTE_HOST').')';
357 mail($wEmail,
358 $subject,
359 $email_body,
360 'From: TYPO3 Install Tool WARNING <>'
361 );
362 }
363 }
364 return false;
365 }
366 }
367
368 /**
369 * [Describe function...]
370 *
371 * @return [type] ...
372 */
373 function loginForm() {
374 $p = t3lib_div::_GP('password');
375 $redirect_url = $this->redirect_url ? $this->redirect_url : $this->action;
376
377 $this->messageFunc_nl2br=0;
378 $this->silent=0;
379
380 $content = '<form action="index.php" method="post" name="passwordForm">
381 <input type="password" name="password"><br />
382 <input type="hidden" name="redirect_url" value="'.$redirect_url.'">
383 <input type="submit" value="Log in"><br />
384 <br />
385
386 '.$this->fw('The Install Tool Password is <i>not</i> the admin password of TYPO3.<br />
387 If you don\'t know the current password, you can set a new one by setting the value of $TYPO3_CONF_VARS[\'BE\'][\'installToolPassword\'] in typo3conf/localconf.php to the md5() hash value of the password you desire.'.
388 ($p ? '<br /><br />The password you just tried has this md5-value: <br /><br />'.md5($p) : '')
389 ).'
390 </form>
391 <script type="text/javascript">
392 <!--
393 document.passwordForm.password.focus();
394 //-->
395 </script>';
396
397 $this->message('Password', 'Enter the Install Tool Password', $content,3);
398 $this->output($this->outputWrapper($this->printAll()));
399 }
400
401 /**
402 * Calling function that checks system, IM, GD, dirs, database and lets you alter localconf.php
403 * This method is called from init.php to start the install Tool.
404 *
405 * @return void
406 */
407 function init() {
408 if (!defined('PATH_typo3')) exit; // Must be called after inclusion of init.php (or from init.php)
409 if (!$this->passwordOK) exit;
410
411 // Setting stuff...
412 $this->check_mail();
413 $this->setupGeneral();
414 $this->generateConfigForm();
415 if (count($this->messages)) t3lib_div::debug($this->messages);
416
417 if ($this->step) {
418 $this->output($this->outputWrapper($this->stepOutput()));
419 } else {
420 // Menu...
421 switch($this->INSTALL['type']) {
422 case 'images':
423 $this->checkIM=1;
424 $this->checkTheConfig();
425 $this->silent=0;
426 $this->checkTheImageProcessing();
427 break;
428 case 'database':
429 $this->checkTheConfig();
430 $this->silent=0;
431 $this->checkTheDatabase();
432 break;
433 case 'update':
434 $this->checkDatabase();
435 $this->silent=0;
436 $this->updateWizard();
437 break;
438 case 'config':
439 $this->silent=0;
440 $this->checkIM=1;
441 $this->message('About configuration','How to configure TYPO3',$this->generallyAboutConfiguration());
442 $this->checkTheConfig();
443
444 $ext = 'Write config to localconf.php';
445 if ($this->fatalError) {
446 if ($this->config_array['no_database'] || !$this->config_array['mysqlConnect']) {
447 $this->message($ext, 'Database not configured yet!', '
448 You need to specify database username, password and host as one of the first things.
449 Next you\'ll have to select a database to use with TYPO3.
450 Use the form below:
451 ',2);
452 } else {
453 $this->message($ext, 'Fatal error encountered!', '
454 Somewhere above a fatal configuration problem is encountered. Please make sure that you\'ve fixed this error before you submit the configuration. TYPO3 will not run if this problem is not fixed!
455 You should also check all warnings that may appear.
456 ',2);
457 }
458 } elseif ($this->mode=='123') {
459 if (!$this->fatalError) {
460 $this->message($ext, 'Basic configuration completed', '
461 You have no fatal errors in your basic configuration. You may have warnings though. Please pay attention to them! However you may continue and install the database.
462
463 <strong><span style="color:#f00;">Step 2:</span></strong> <a href="'.$this->scriptSelf.'?TYPO3_INSTALL[type]=database'.($this->mode?'&mode='.rawurlencode($this->mode):'').'">Click here to install the database.</a>
464 ',-1,1);
465 }
466 }
467 $this->message($ext, 'Very Important: Changing Image Processing settings', "
468 When you change the settings for Image Processing you <i>must</i> take into account that <u>old images</u> may still be in typo3temp/ folder and prevent new files from being generated! This is especially important to know, if you're trying to set up image processing for the very first time.
469 The problem is solved by <a href=\"".htmlspecialchars($this->setScriptName('typo3temp'))."\">clearing the typo3temp/ folder</a>. Also make sure to clear the cache_pages table.
470 ",1,1);
471 $this->message($ext, 'Very Important: Changing Encryption Key setting', "
472 When you change the setting for the Encryption Key you <i>must</i> take into account that a change to this value might invalidate temporary information, URLs etc.
473 The problem is solved by <a href=\"".htmlspecialchars($this->setScriptName('typo3temp'))."\">clearing the typo3temp/ folder</a>. Also make sure to clear the cache_pages table.
474 ",1,1);
475 $this->message($ext, 'Update localconf.php', "
476 This form updates the localconf.php file with the suggested values you see below. The values are based on the analysis above.
477 You can change the values in case you have alternatives to the suggested defaults.
478 By this final step you will configure TYPO3 for immediate use provided that you have no fatal errors left above."
479 .$this->setupGeneral('get_form'),0,1);
480
481 $this->output($this->outputWrapper($this->printAll()));
482
483 break;
484 case 'extConfig':
485 $this->silent=0;
486
487 $this->generateConfigForm('get_form');
488
489 $content = $this->printAll();
490 $content = '<form action="'.$this->action.'" method="post">'.$content.'<input type="submit" value="Write to localconf.php"><br /><br />
491 '.$this->fw('<strong>NOTICE: </strong>By clicking this button, localconf.php is updated with new values for the parameters listed above!<br />').'
492 </form>';
493 $this->output($this->outputWrapper($content));
494 break;
495 case 'typo3temp':
496 $this->checkTheConfig();
497 $this->silent=0;
498 $this->typo3TempManager();
499 break;
500 case 'cleanup':
501 $this->checkTheConfig();
502 $this->silent=0;
503 $this->cleanupManager();
504 break;
505 case 'phpinfo':
506 $this->silent=0;
507 $this->phpinformation();
508 break;
509 case 'typo3conf_edit':
510 $this->silent=0;
511 $this->typo3conf_edit();
512 break;
513 case 'about':
514 default:
515 $this->silent=0;
516 $this->message('About', 'Warning - very important!', $this->securityRisk().$this->alterPasswordForm(),2);
517
518 $this->message('About', 'Using this script', "
519 Installing TYPO3 has always been a hot topic on the mailing list and forums. Therefore we've developed this tool which will help you through configuration and testing.
520 There are three primary steps for you to take:
521
522 <strong>1: Basic Configuration</strong>
523 In this step your PHP-configuration is checked. If there are any settings that will prevent TYPO3 from running correctly you'll get warnings and errors with a description of the problem.
524 You'll have to enter a database username, password and hostname. Then you can choose to create a new database or select an existing one.
525 Finally the image processing settings are entered and verified and you can choose to let the script update the configuration file, typo3conf/localconf.php with the suggested settings.
526
527 <strong>2: Database Analyser</strong>
528 In this step you can either install a new database or update the database from any previous TYPO3 version.
529 You can also get an overview of extra/missing fields/tables in the database compared to a raw sql-file.
530 The database is also verified agains your 'tables.php' configuration (\$TCA) and you can even see suggestions to entries in \$TCA or new fields in the database.
531
532 <strong>3: Update Wizard</strong>
533 Here you will find update methods taking care of changes to the TYPO3 core which are not backwards compatible.
534 It is recommended to run this wizard after every update to make sure everything will still work flawlessly.
535
536 <strong>4: Image Processing</strong>
537 This step is a visual guide to verify your configuration of the image processing software.
538 You'll be presented to a list of images that should all match in pairs. If some irregularity appears, you'll get a warning. Thus you're able to track an error before you'll discover it on your website.
539
540 <strong>5: All Configuration</strong>
541 This gives you access to any of the configuration options in the TYPO3_CONF_VARS array. Every option is also presented with a comment explaining what it does.
542
543 <strong>6: typo3temp/</strong>
544 Here you can manage the files in typo3temp/ folder in a simple manner. typo3temp/ contains temporary files, which may still be used by the website, but some may not. By searching for files with old access-dates, you can possibly manage to delete unused files rather than files still used. However if you delete a temporary file still in use, it's just regenerated as long as you make sure to clear the cache tables afterwards.
545 ");
546
547 $this->message('About', 'Why is this script stand-alone?', "
548 You would think that this script should rather be a module in the backend and access-controlled to only admin-users from the database. But that's not how it works.
549 The reason is, that this script must not be depending on the success of the configuration of TYPO3 and whether or not there is a working database behind. Therefore the script is invoked from the backend init.php file, which allows access if the constant 'TYPO3_enterInstallScript' has been defined and is not false. That is and should be the case <i>only</i> when calling the script 'typo3/install/index.php' - this script!
550 ");
551
552
553 $headCode='Header legend';
554 $this->message($headCode, 'Just information', '
555 This is a simple message with some information about something.
556 ');
557 $this->message($headCode, 'Check was successful', '
558 Indicates that something was checked and returned an expected result.
559 ',-1);
560 $this->message($headCode, 'Notice!', '
561 Indicates that something is important to be aware of.
562 This does <em>not</em> indicate an error.
563 ',1);
564 $this->message($headCode, 'Warning!', '
565 Indicates that something may very well cause trouble and you should definitely look into it before proceeding.
566 This indicates a <em>potential</em> error.
567 ',2);
568 $this->message($headCode, 'Error!', '
569 Indicates that something is definitely wrong and that TYPO3 will most likely not perform as expected if this problem is not solved.
570 This indicates an actual error.
571 ',3);
572
573 $this->output($this->outputWrapper($this->printAll()));
574 break;
575 }
576 }
577 }
578
579 /**
580 * Controls the step 1-2-3-go process
581 *
582 * @return string the content to output to the screen
583 */
584 function stepOutput() {
585 $this->checkTheConfig();
586 $error_missingConnect='<br />
587 '.$this->fontTag2.'<img src="'.$this->backPath.'gfx/icon_fatalerror.gif" width="18" height="16" class="absmiddle">
588 There is no connection to the database!<br />
589 (Username: <i>' . TYPO3_db_username . '</i>, Host: <i>' . TYPO3_db_host . '</i>, Using Password: YES) . <br />
590 <br />
591 <strong>Go to Step 1</strong> and enter a proper username/password!</span>
592 <br />
593 <br />
594 ';
595 $error_missingDB='<br />
596 '.$this->fontTag2.'<img src="'.$this->backPath.'gfx/icon_fatalerror.gif" width="18" height="16" class="absmiddle">
597 There is no access to the database (<i>'.TYPO3_db.'</i>)!<br />
598 <br />
599 <strong>Go to Step 2</strong> and select an accessible database!</span>
600 <br />
601 <br />
602 ';
603
604 // only get the number of tables if it is not the first step in the 123-installer
605 // (= no DB connection yet)
606 $whichTables = ($this->step != 1 ? $this->getListOfTables() : array());
607 $dbInfo='
608 <table border="0" cellpadding="1" cellspacing="0">
609 <tr>
610 <td valign="top" nowrap="nowrap" colspan="2" align="center">'.$this->fontTag2.'<strong><img src="'.$this->backPath.'gfx/icon_note.gif" hspace="5" width="18" height="16" class="absmiddle">Database summary:</strong></span></td>
611 </tr>
612 <tr>
613 <td valign="top" nowrap="nowrap">'.$this->fontTag1.'Username:</span></td>
614 <td valign="top" nowrap="nowrap"><strong>'.$this->fontTag1.''.TYPO3_db_username.'</span></strong></td>
615 </tr>
616 <tr>
617 <td valign="top" nowrap="nowrap">'.$this->fontTag1.'Host:</span></td>
618 <td valign="top" nowrap="nowrap"><strong>'.$this->fontTag1.''.TYPO3_db_host.'</span></strong></td>
619 </tr>
620 <tr>
621 <td valign="top" nowrap="nowrap">'.$this->fontTag1.'Database:</span></td>
622 <td valign="top" nowrap="nowrap"><strong>'.$this->fontTag1.''.TYPO3_db.'</span></strong></td>
623 </tr>
624 <tr>
625 <td valign="top" nowrap="nowrap">'.$this->fontTag1.'# of tables:</span></td>
626 <td valign="top" nowrap="nowrap"><strong>'.$this->fontTag1.''.(count($whichTables)?'<span style="color:#f00;">'.count($whichTables).'</span>':count($whichTables)).'</span></strong></td>
627 </tr>
628 </table>
629 ';
630 $error_emptyDB='<br />
631 '.$this->fontTag2.'<img src="'.$this->backPath.'gfx/icon_fatalerror.gif" width="18" height="16" class="absmiddle">
632 The database is still empty. There are no tables!<br />
633 <br />
634 <strong>Go to Step 3</strong> and import a database!</span>
635 <br />
636 <br />
637 ';
638
639 switch(strtolower($this->step)) {
640 case 1:
641 $msg='
642 <br />
643 <br />
644 <table border="0">
645 <form action="'.$this->action.'" method="post">
646 <tr>
647 <td valign="top" nowrap="nowrap"><strong>
648 '.$this->fontTag2.'Username:</span></strong>
649 </td>
650 <td> &nbsp;
651 </td>
652 <td valign="top">
653 '.$this->fontTag2.'
654 <input type="text" name="TYPO3_INSTALL[localconf.php][typo_db_username]" value="'.TYPO3_db_username.'"></span><br />
655 </td>
656 </tr>
657 <tr>
658 <td valign="top" nowrap="nowrap"><strong>
659 '.$this->fontTag2.'Password:</span></strong>
660 </td>
661 <td> &nbsp;
662 </td>
663 <td valign="top">
664 '.$this->fontTag2.'
665 <input type="password" name="TYPO3_INSTALL[localconf.php][typo_db_password]" value="'.TYPO3_db_password.'"></span><br />
666 </td>
667 </tr>
668 <tr>
669 <td valign="top" nowrap="nowrap"><strong>
670 '.$this->fontTag2.'Host:</span></strong>
671 </td>
672 <td> &nbsp;
673 </td>
674 <td valign="top">
675 '.$this->fontTag2.'
676 <input type="text" name="TYPO3_INSTALL[localconf.php][typo_db_host]" value="'.(TYPO3_db_host?TYPO3_db_host:'localhost').'"></span><br />
677 </td>
678 </tr>
679 <tr>
680 <td valign="top" nowrap="nowrap"><strong>
681 '.$this->fontTag1.'</span></strong>
682 </td>
683 <td> &nbsp;
684 </td>
685 <td valign="top">
686 '.$this->fontTag1.'<br />
687 <input type="hidden" name="step" value="2">
688 <input type="hidden" name="TYPO3_INSTALL[localconf.php][encryptionKey]" value="'.md5(uniqid(rand(),true)).'">
689 <input type="hidden" name="TYPO3_INSTALL[localconf.php][compat_version]" value="'.TYPO3_branch.'">
690 <input type="submit" value="Continue"><br /><br /><strong>NOTICE: </strong>By clicking this button, typo3conf/localconf.php is updated with new values for the parameters listed above!</span><br />
691 </td>
692 </tr>
693 </form>
694 </table>
695 <br />
696 <br />';
697 break;
698 case 2:
699 if ($result = $GLOBALS['TYPO3_DB']->sql_pconnect(TYPO3_db_host, TYPO3_db_username, TYPO3_db_password)) {
700 $dbArr = $this->getDatabaseList();
701 $options = '<option value="">[ SELECT DATABASE ]</option>';
702 $dbIncluded = 0;
703 foreach ($dbArr as $dbname) {
704 $options.='<option value="'.htmlspecialchars($dbname).'"'.($dbname==TYPO3_db?' selected="selected"':'').'>'.htmlspecialchars($dbname).'</option>';
705 if ($dbname==TYPO3_db) $dbIncluded=1;
706 }
707 if (!$dbIncluded && TYPO3_db) {
708 $options.='<option value="'.htmlspecialchars(TYPO3_db).'" selected="selected">'.htmlspecialchars(TYPO3_db).' (NO ACCESS!)</option>';
709 }
710 $select='<select name="TYPO3_INSTALL[localconf.php][typo_db]">'.$options.'</select>';
711 $msg='
712 <br />
713 <br />
714 <table border="0">
715 <form action="'.$this->action.'" method="post">
716 <tr>
717 <td valign="top" nowrap="nowrap"><strong>
718 '.$this->fontTag2.'
719 You have two options:<br />
720 <br /><br />
721
722 1: Select an existing <u>EMPTY</u> database:</span></strong>
723 </td>
724 </tr>
725 <tr>
726 <td valign="top">
727 '.$this->fontTag1.'Any existing tables which are used by TYPO3 will be overwritten in Step 3. So make sure this database is empty:<br />'.$select.'</span><br />
728 </td>
729 </tr>
730 <tr>
731 <td valign="top" nowrap="nowrap"><br />
732 <br />
733 <strong>
734 '.$this->fontTag2.'2: Create new database (recommended):</span></strong>
735 </td>
736 </tr>
737 <tr>
738 <td valign="top">
739 '.$this->fontTag1.'Enter the desired name of the database here:<br /><input type="text" name="TYPO3_INSTALL[localconf.php][NEW_DATABASE_NAME]" value=""></span><br />
740 </td>
741 </tr>
742 <tr>
743 <td valign="top"> <br />
744
745 '.$this->fontTag1.'<br />
746 <input type="hidden" name="step" value="3">
747 <input type="submit" value="Continue"><br /><br /><strong>NOTICE: </strong>By clicking this button, typo3conf/localconf.php is updated with new values for the parameters listed above!</span><br />
748 </td>
749 </tr>
750 </form>
751 </table>
752 <br />
753 <br />
754 ';
755 } else {
756 $msg=$error_missingConnect;
757 }
758 break;
759 case 3:
760 if ($result = $GLOBALS['TYPO3_DB']->sql_pconnect(TYPO3_db_host, TYPO3_db_username, TYPO3_db_password)) {
761 if ($GLOBALS['TYPO3_DB']->sql_select_db(TYPO3_db)) {
762 $sFiles = t3lib_div::getFilesInDir(PATH_typo3conf,'sql',1,1);
763
764 // Check if default database scheme "database.sql" already exists, otherwise create it
765 if (!strstr(implode(',',$sFiles).',', '/database.sql,')) {
766 array_unshift($sFiles,'Create default database tables');
767 }
768
769 $opt='';
770 foreach ($sFiles as $f) {
771 if ($f=='Create default database tables') $key='CURRENT_TABLES+STATIC';
772 else $key=htmlspecialchars($f);
773
774 $opt.='<option value="import|'.$key.'">'.htmlspecialchars(basename($f)).'</option>';
775 }
776
777
778 $content='
779 '.$this->fontTag2.'Please select a database dump:</span><br />
780 <input type="hidden" name="TYPO3_INSTALL[database_import_all]" value=1>
781 <input type="hidden" name="step" value="">
782 <input type="hidden" name="goto_step" value="go">
783 <select name="TYPO3_INSTALL[database_type]">'.$opt.'</select><br />';
784
785 $content = $this->getUpdateDbFormWrap('import', $content, 'Import database');
786
787 $msg='
788 <br />
789 '.$dbInfo.'<br />
790 <br />
791 '.$content.'
792
793 ';
794
795 } else {
796 $msg=$error_missingDB;
797 }
798 } else {
799 $msg=$error_missingConnect;
800 }
801 break;
802 case 'go':
803 if ($result = $GLOBALS['TYPO3_DB']->sql_pconnect(TYPO3_db_host, TYPO3_db_username, TYPO3_db_password)) {
804 if ($GLOBALS['TYPO3_DB']->sql_select_db(TYPO3_db)) {
805 if (count($whichTables)) {
806 $msg='
807 <br />
808 '.$this->fontTag2.'
809 '.nl2br($this->messageBasicFinished()).'
810 <br />
811 <hr />
812 <div align="center"><strong><img src="'.$this->backPath.'gfx/icon_warning.gif" hspace="5" width="18" height="16" class="absmiddle">IMPORTANT</strong></div><br />
813 <span class="smalltext">'.nl2br($this->securityRisk()).'
814 <br />
815 <strong>Enter <a href="'.$this->scriptSelf.'">"Normal" mode for the Install Tool</a> to change this!</strong><br />
816
817 </span>
818 </span><br />
819 ';
820 } else {
821 $msg=$error_emptyDB;
822 }
823 } else {
824 $msg=$error_missingDB;
825 }
826 } else {
827 $msg=$error_missingConnect;
828 }
829 break;
830 }
831 return $msg;
832 }
833
834 /**
835 * Calling the functions that checks the system
836 *
837 * @return [type] ...
838 */
839 function checkTheConfig() {
840 // Order important:
841 $this->checkDirs();
842 $this->checkConfiguration();
843 $this->checkExtensions();
844
845 if (TYPO3_OS=='WIN') {
846 $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\\');
847 } else {
848 $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/');
849 }
850
851 asort($paths);
852 if (ini_get('safe_mode')) {
853 $paths=array(ini_get('safe_mode_exec_dir'),'/usr/local/php/bin/');
854 }
855 if ($this->INSTALL['checkIM']['lzw']) {
856 $this->checkIMlzw=1;
857 }
858 if ($this->INSTALL['checkIM']['path']) {
859 $paths[]=trim($this->INSTALL['checkIM']['path']);
860 }
861 if ($this->checkIM) $this->checkImageMagick($paths);
862 $this->checkDatabase();
863 }
864
865 /**
866 * Editing files in typo3conf directory (or elsewhere if enabled)
867 *
868 * @return [type] ...
869 */
870 function typo3conf_edit() {
871 $EDIT_path = PATH_typo3conf; // default:
872 if ($this->allowFileEditOutsite_typo3conf_dir && $this->INSTALL['FILE']['EDIT_path']) {
873 if (t3lib_div::validPathStr($this->INSTALL['FILE']['EDIT_path']) && substr($this->INSTALL['FILE']['EDIT_path'],-1)=='/') {
874 $tmp_path = PATH_site.$this->INSTALL['FILE']['EDIT_path'];
875 if (is_dir($tmp_path)) {
876 $EDIT_path=$tmp_path;
877 } else {debug("'".$tmp_path."' was not dir");}
878 } else {
879 debug('BAD DIR_NAME (must be like t3lib/ or media/script/)');
880 }
881 }
882
883 $headCode = 'Edit files in '.basename($EDIT_path).'/';
884 $this->contentBeforeTable='';
885
886 if ($this->INSTALL['SAVE_FILE']) {
887 $save_to_file = $this->INSTALL['FILE']['name'];
888 if (@is_file($save_to_file)) {
889 $save_to_file_md5 = md5($save_to_file);
890 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')) {
891 $this->INSTALL['typo3conf_files'] = $save_to_file;
892 $save_fileContent = $this->INSTALL['FILE'][$save_to_file_md5];
893
894 if ($this->INSTALL['FILE']['win_to_unix_br']) {
895 $save_fileContent = str_replace(chr(13).chr(10),chr(10),$save_fileContent);
896 }
897
898 $backupFile = $this->getBackupFilename($save_to_file);
899 if ($this->INSTALL['FILE']['backup']) {
900 if (@is_file($backupFile)) { unlink($backupFile); }
901 rename($save_to_file,$backupFile);
902 $this->contentBeforeTable.='Backup written to <strong>'.$backupFile.'</strong><br />';
903 }
904
905 t3lib_div::writeFile($save_to_file,$save_fileContent);
906 $this->contentBeforeTable.='
907 File saved: <strong>'.$save_to_file.'</strong><br />
908 MD5-sum: '.$this->INSTALL['FILE']['prevMD5'].' (prev)<br />
909 MD5-sum: '.md5($save_fileContent).' (new)<br />
910 ';
911 }
912 }
913 }
914
915 // Filelist:
916 $typo3conf_files = t3lib_div::getFilesInDir($EDIT_path,'',1,1);
917 reset($typo3conf_files);
918 $lines=array();
919 $fileFound = 0;
920 while(list($k,$file)=each($typo3conf_files)) {
921 // Delete temp_CACHED files if option is set
922 if ( $this->INSTALL['delTempCached'] && preg_match('|/temp_CACHED_[a-z0-9_]+\.php|', $file)) {
923 unlink($file);
924 continue;
925 }
926 if ($this->INSTALL['typo3conf_files'] && !strcmp($this->INSTALL['typo3conf_files'],$file)) {
927 $wrap=array('<strong><span style="color:navy;">','</span></strong>');
928 $fileFound = 1;
929 } else {$wrap=array();}
930 $lines[]='<tr><td nowrap="nowrap"><a href="'.$this->action.'&TYPO3_INSTALL[typo3conf_files]='.rawurlencode($file).($this->allowFileEditOutsite_typo3conf_dir?'&TYPO3_INSTALL[FILE][EDIT_path]='.rawurlencode($this->INSTALL['FILE']['EDIT_path']):"").'">'.$this->fw($wrap[0].basename($file).$wrap[1].'&nbsp;&nbsp;&nbsp;').'</a></td><td>'.$this->fw(t3lib_div::formatSize(filesize($file))).'</td></tr>';
931 }
932 $fileList='<table border="0" cellpadding="0" cellspacing="0">'.implode('',$lines).'</table>';
933 $fileList.='<br />('.$EDIT_path.')';
934
935 if ($this->allowFileEditOutsite_typo3conf_dir) {
936 $fileList.='<br /><form action="'.$this->action.'" method="post">
937 '.PATH_site.'<input type="text" name="TYPO3_INSTALL[FILE][EDIT_path]" value="'.$this->INSTALL['FILE']['EDIT_path'].'"><input type="submit" name="" value="Set">
938 </form>';
939 }
940
941 // create link for deleting temp_CACHED files
942 $fileList .= '<br /><br /><a href="'.$this->action.'&TYPO3_INSTALL[delTempCached]=1">Delete temp_CACHED* files</a>';
943
944 if ($fileFound && @is_file($this->INSTALL['typo3conf_files'])) {
945
946 $backupFile = $this->getBackupFilename($this->INSTALL['typo3conf_files']);
947 $fileContent = t3lib_div::getUrl($this->INSTALL['typo3conf_files']);
948 $this->contentBeforeTable.= '<div class="editFile"><form action="'.$this->action.'" method="post">'.(substr($this->INSTALL['typo3conf_files'],-1)!='~' && !strstr($this->INSTALL['typo3conf_files'],'_bak') ? '
949 <input type="submit" name="TYPO3_INSTALL[SAVE_FILE]" value="Save file">&nbsp;' : '').'
950 <input type="submit" name="_close" value="Close">
951 <br />File: '.$this->INSTALL['typo3conf_files'].'
952 <br />MD5-sum: '.md5($fileContent).'
953 <br />
954
955 <input type="hidden" name="TYPO3_INSTALL[FILE][name]" value="'.$this->INSTALL['typo3conf_files'].'">
956 '.($this->allowFileEditOutsite_typo3conf_dir?'<input type="hidden" name="TYPO3_INSTALL[FILE][EDIT_path]" value="'.$this->INSTALL['FILE']['EDIT_path'].'">':'').'
957 <input type="hidden" name="TYPO3_INSTALL[FILE][prevMD5]" value="'.md5($fileContent).'">
958 <textarea rows="30" name="TYPO3_INSTALL[FILE]['.md5($this->INSTALL['typo3conf_files']).']" wrap="off"'.$this->formWidthText(48,'width:98%;height:80%','off').' class="fixed-font enable-tab">'.t3lib_div::formatForTextarea($fileContent).'</textarea><br />
959 <input type="checkbox" name="TYPO3_INSTALL[FILE][win_to_unix_br]" id="win_to_unix_br" value="1"'.(TYPO3_OS=='WIN'?'':' checked="checked"').'> <label for="win_to_unix_br">Convert Windows linebreaks (13-10) to Unix (10)</label><br />
960 <input type="checkbox" name="TYPO3_INSTALL[FILE][backup]" id="backup" value="1"'.(@is_file($backupFile) ? ' checked="checked"' : '').'> <label for="backup">Make backup copy (rename to '.basename($backupFile).')</label><br />
961 '.
962 '</form></div>';
963 }
964
965 if ($this->contentBeforeTable) {
966 $this->contentBeforeTable = $this->fw($this->contentBeforeTable);
967 }
968
969 $this->message($headCode,'Files in folder',$fileList);
970
971 $this->output($this->outputWrapper($this->printAll()));
972 }
973
974 /**
975 * Outputs system information
976 *
977 * @return [type] ...
978 */
979 function phpinformation() {
980 $headCode = 'PHP information';
981
982 $sVar = t3lib_div::getIndpEnv('_ARRAY');
983 $sVar['CONST: PHP_OS']=PHP_OS;
984 $sVar['CONST: TYPO3_OS']=TYPO3_OS;
985 $sVar['CONST: PATH_thisScript']=PATH_thisScript;
986 $sVar['CONST: php_sapi_name()']=PHP_SAPI;
987 $sVar['OTHER: TYPO3_VERSION']=TYPO3_version;
988 $sVar['OTHER: PHP_VERSION']=phpversion();
989 $sVar['imagecreatefromgif()']=function_exists('imagecreatefromgif');
990 $sVar['imagecreatefrompng()']=function_exists('imagecreatefrompng');
991 $sVar['imagecreatefromjpeg()']=function_exists('imagecreatefromjpeg');
992 $sVar['imagegif()']=function_exists('imagegif');
993 $sVar['imagepng()']=function_exists('imagepng');
994 $sVar['imagejpeg()']=function_exists('imagejpeg');
995 $sVar['imagettftext()']=function_exists('imagettftext');
996 $sVar['OTHER: IMAGE_TYPES']=function_exists('imagetypes') ? imagetypes() : 0;
997 $sVar['OTHER: memory_limit']=ini_get('memory_limit');
998
999 $gE_keys = explode(',','SERVER_PORT,SERVER_SOFTWARE,GATEWAY_INTERFACE,SCRIPT_NAME,PATH_TRANSLATED');
1000 while(list(,$k)=each($gE_keys)) {
1001 $sVar['SERVER: '.$k]=$_SERVER[$k];
1002 }
1003
1004 $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');
1005 while(list(,$k)=each($gE_keys)) {
1006 $sVar['T3CV_GFX: '.$k]=$GLOBALS['TYPO3_CONF_VARS']['GFX'][$k];
1007 }
1008
1009 $debugInfo=array();
1010 $debugInfo[]='### DEBUG SYSTEM INFORMATION - START ###';
1011 reset($sVar);
1012 while(list($kkk,$vvv)=each($sVar)) {
1013 $debugInfo[]=str_pad(substr($kkk,0,20),20).': '.$vvv;
1014 }
1015 $debugInfo[]='### DEBUG SYSTEM INFORMATION - END ###';
1016
1017 $buf=$this->messageFunc_nl2br;
1018 $this->messageFunc_nl2br=0;
1019 $this->message($headCode,'DEBUG information','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!<br />
1020 <form action=""><textarea rows="10" '.$this->formWidthText(80,'width:100%; height:500px;','off').' wrap="off" class="fixed-font">'.t3lib_div::formatForTextarea(implode(chr(10),$debugInfo)).'</textarea></form>');
1021 $this->messageFunc_nl2br=$buf;
1022
1023 $getEnvArray = array();
1024 $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');
1025 while(list(,$k)=each($gE_keys)) {
1026 $getEnvArray[$k] = getenv($k);
1027 }
1028 $this->message($headCode,'t3lib_div::getIndpEnv()',t3lib_div::view_array(t3lib_div::getIndpEnv('_ARRAY')));
1029 $this->message($headCode,'getenv()',t3lib_div::view_array($getEnvArray));
1030 $this->message($headCode,'_ENV',t3lib_div::view_array($_ENV));
1031 $this->message($headCode,'_SERVER',t3lib_div::view_array($_SERVER));
1032 $this->message($headCode,'_COOKIE',t3lib_div::view_array($_COOKIE));
1033 $this->message($headCode,'_GET',t3lib_div::view_array($_GET));
1034
1035 ob_start();
1036 phpinfo();
1037 $contents = explode('<body>',ob_get_contents());
1038 ob_end_clean();
1039 $contents = explode('</body>',$contents[1]);
1040
1041 $this->message($headCode,'phpinfo()','<div class="phpinfo">' . $contents[0] . '</div>');
1042
1043 $this->output($this->outputWrapper($this->printAll()));
1044 }
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058 /*******************************
1059 *
1060 * typo3temp/ manager
1061 *
1062 *******************************/
1063
1064 /**
1065 * Provides a tool for deleting temporary files located in typo3temp/
1066 *
1067 * @return string HTML output
1068 */
1069 function typo3TempManager() {
1070 $headCode = 'typo3temp/ directory';
1071 $this->message($headCode,'What is it?','
1072 TYPO3 uses this directory for temporary files, mainly processed and cached images.
1073 The filenames are very cryptic; They are unique representations of the file properties made by md5-hashing a serialized array with information.
1074 Anyway this directory may contain many thousand files and a lot of them may be of no use anymore.
1075
1076 With this test you can delete the files in this folder. When you do that, you should also clear the cache database tables afterwards.
1077 ');
1078
1079 if (!$this->config_array['dir_typo3temp']) {
1080 $this->message('typo3temp/ directory','typo3temp/ not writable!',"
1081 You must make typo3temp/ write enabled before you can proceed with this test.
1082 ",2);
1083 $this->output($this->outputWrapper($this->printAll()));
1084 return;
1085 }
1086
1087 // Run through files
1088 $fileCounter = 0;
1089 $deleteCounter = 0;
1090 $criteriaMatch = 0;
1091 $tmap=array('day'=>1, 'week'=>7, 'month'=>30);
1092 $tt = $this->INSTALL['typo3temp_delete'];
1093 $subdir = $this->INSTALL['typo3temp_subdir'];
1094 if (strlen($subdir) && !preg_match('/^[[:alnum:]_]+\/$/',$subdir)) die('subdir "'.$subdir.'" was not allowed!');
1095 $action = $this->INSTALL['typo3temp_action'];
1096 $d = @dir($this->typo3temp_path.$subdir);
1097 if (is_object($d)) {
1098 while($entry=$d->read()) {
1099 $theFile = $this->typo3temp_path.$subdir.$entry;
1100 if (@is_file($theFile)) {
1101 $ok = 0;
1102 $fileCounter++;
1103 if ($tt) {
1104 if (t3lib_div::testInt($tt)) {
1105 if (filesize($theFile) > $tt*1024) $ok=1;
1106 } else {
1107 if (fileatime($theFile) < $GLOBALS['EXEC_TIME'] - (intval($tmap[$tt]) * 60 * 60 * 24)) {
1108 $ok = 1;
1109 }
1110 }
1111 } else {
1112 $ok = 1;
1113 }
1114 if ($ok) {
1115 $hashPart=substr(basename($theFile),-14,10);
1116 if (!preg_match('/[^a-f0-9]/',$hashPart) || substr($theFile,-6)==='.cache' || substr($theFile,-4)==='.tbl' || substr(basename($theFile),0,8)==='install_') { // This is a kind of check that the file being deleted has a 10 char hash in it
1117 if ($action && $deleteCounter<$action) {
1118 $deleteCounter++;
1119 unlink($theFile);
1120 } else {
1121 $criteriaMatch++;
1122 }
1123 }
1124 }
1125 }
1126 }
1127 $d->close();
1128 }
1129
1130 // Find sub-dirs:
1131 $subdirRegistry = array(''=>'');
1132 $d = @dir($this->typo3temp_path);
1133 if (is_object($d)) {
1134 while($entry=$d->read()) {
1135 $theFile = $entry;
1136 if (@is_dir($this->typo3temp_path.$theFile) && $theFile!='..' && $theFile!='.') {
1137 $subdirRegistry[$theFile.'/'] = $theFile.'/ (Files: '.count(t3lib_div::getFilesInDir($this->typo3temp_path.$theFile)).')';
1138 }
1139 }
1140 }
1141
1142 $deleteType=array(
1143 '0' => 'All',
1144 'day' => 'Last access more than a day ago',
1145 'week' => 'Last access more than a week ago',
1146 'month' => 'Last access more than a month ago',
1147 '10' => 'Filesize greater than 10KB',
1148 '50' => 'Filesize greater than 50KB',
1149 '100' => 'Filesize greater than 100KB'
1150 );
1151
1152 $actionType=array(
1153 '0' => "Don't delete, just display statistics",
1154 '100' => 'Delete 100',
1155 '500' => 'Delete 500',
1156 '1000' => 'Delete 1000'
1157 );
1158
1159 $content='<select name="TYPO3_INSTALL[typo3temp_delete]">'.$this->getSelectorOptions($deleteType,$tt).'</select>
1160 <br />
1161 Number of files at a time:
1162 <select name="TYPO3_INSTALL[typo3temp_action]">'.$this->getSelectorOptions($actionType).'</select>
1163
1164 From sub-directory:
1165 <select name="TYPO3_INSTALL[typo3temp_subdir]">'.$this->getSelectorOptions($subdirRegistry, $this->INSTALL['typo3temp_subdir']).'</select>
1166 ';
1167
1168 $form = '<form action="'.$this->action.'" method="post">'.$content.'
1169
1170 <input type="submit" value="Execute">
1171 </form>
1172 This tool will delete files only if the last 10 characters before the extension (3 chars+\'.\') are hexadecimal valid ciphers, which are lowercase a-f and 0-9.';
1173
1174 $this->message($headCode,'Statistics','
1175 Number of temporary files: <strong>'.($fileCounter-$deleteCounter)."</strong>
1176 Number matching '".htmlspecialchars($deleteType[$tt])."': <strong>".$criteriaMatch.'</strong>
1177 Number deleted: <strong>'.$deleteCounter.'</strong>
1178 <br />
1179 '.$form,1);
1180
1181 $this->output($this->outputWrapper($this->printAll()));
1182 }
1183
1184 /**
1185 * [Describe function...]
1186 *
1187 * @param [type] $deleteType: ...
1188 * @param [type] $tt: ...
1189 * @return [type] ...
1190 */
1191 function getSelectorOptions($deleteType,$tt='') {
1192 $out='';
1193 if (is_array($deleteType)) {
1194 reset($deleteType);
1195 while(list($v,$l)=each($deleteType)) {
1196 $out.='<option value="'.htmlspecialchars($v).'"'.(!strcmp($v,$tt)?' selected="selected"':'').'>'.htmlspecialchars($l).'</option>';
1197 }
1198 }
1199 return $out;
1200 }
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210 /*******************************
1211 *
1212 * cleanup manager
1213 *
1214 *******************************/
1215
1216 /**
1217 * Provides a tool cleaning up various tables in the database
1218 *
1219 * @return string HTML output
1220 * @author Robert Lemke <rl@robertlemke.de>
1221 * @todo Add more functionality ...
1222 */
1223 function cleanupManager() {
1224 $headCode = 'Clean up database';
1225 $this->message($headCode,'What is it?','
1226 This function will become a general clean up manager for various tables used by TYPO3. By now you can only empty the cache which is used for storing image sizes of all pictures used in TYPO3.
1227
1228 <strong>Clear cached image sizes</strong>
1229 Clears the cache used for memorizing sizes of all images used in your website. This information is cached in order to gain performance and will be stored each time a new image is being displayed in the frontend.
1230
1231 You should <em>Clear All Cache</em> in the backend after clearing this cache.
1232 ');
1233
1234 $tables = $this->getListOfTables();
1235 $action = $this->INSTALL['cleanup_type'];
1236
1237 if (($action == 'cache_imagesizes' || $action == 'all') && isset ($tables['cache_imagesizes'])) {
1238 $GLOBALS['TYPO3_DB']->exec_DELETEquery ('cache_imagesizes','');
1239 }
1240
1241 $cleanupType = array (
1242 'all' => 'Clean up everything',
1243 );
1244
1245 // Get cache_imagesizes info
1246 if (isset ($tables['cache_imagesizes'])) {
1247 $cleanupType['cache_imagesizes'] = 'Clear cached image sizes only';
1248 $cachedImageSizesCounter = intval($GLOBALS['TYPO3_DB']->exec_SELECTcountRows('*', 'cache_imagesizes'));
1249 } else {
1250 $this->message($headCode,'Table cache_imagesizes does not exist!',"
1251 The table cache_imagesizes was not found. Please check your database settings in Basic Configuration and compare your table definition with the Database Analyzer.
1252 ",2);
1253 $cachedImageSizesCounter = 'unknown';
1254 }
1255
1256 $content = '<select name="TYPO3_INSTALL[cleanup_type]">'.$this->getSelectorOptions($cleanupType).'</select> ';
1257 $form = '<form action="'.$this->action.'" method="post">'.$content.'<input type="submit" value="Execute"></form>';
1258 $this->message($headCode,'Statistics','
1259 Number cached image sizes: <strong>'.$cachedImageSizesCounter.'</strong><br />
1260 '.$form,1);
1261
1262 $this->output($this->outputWrapper($this->printAll()));
1263 }
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277 /*******************************
1278 *
1279 * CONFIGURATION FORM
1280 *
1281 ********************************/
1282
1283 /**
1284 * Creating the form for editing the TYPO3_CONF_VARS options.
1285 *
1286 * @param [type] $type: ...
1287 * @return [type] ...
1288 */
1289 function generateConfigForm($type='') {
1290 $default_config_content = t3lib_div::getUrl(PATH_t3lib.'config_default.php');
1291 $commentArr = $this->getDefaultConfigArrayComments($default_config_content);
1292
1293 switch($type) {
1294 case 'get_form':
1295 reset($GLOBALS['TYPO3_CONF_VARS']);
1296 $this->messageFunc_nl2br=0;
1297 while(list($k,$va)=each($GLOBALS['TYPO3_CONF_VARS'])) {
1298 $ext='['.$k.']';
1299 $this->message($ext, '$TYPO3_CONF_VARS[\''.$k.'\']',$commentArr[0][$k],1);
1300
1301 while(list($vk,$value)=each($va)) {
1302 $description = trim($commentArr[1][$k][$vk]);
1303 $isTextarea = preg_match('/^string \(textarea\)/i',$description) ? TRUE : FALSE;
1304
1305 if (!is_array($value) && ($this->checkForBadString($value) || $isTextarea)) {
1306 $k2 = '['.$vk.']';
1307 $msg = htmlspecialchars($description).'<br /><br /><em>'.$ext.$k2.' = '.htmlspecialchars(t3lib_div::fixed_lgd_cs($value,60)).'</em><br />';
1308
1309 if ($isTextarea) {
1310 $form = '<textarea name="TYPO3_INSTALL[extConfig]['.$k.']['.$vk.']" cols="60" rows="5" wrap="off">'.htmlspecialchars($value).'</textarea>';
1311 } elseif (preg_match('/^boolean/i',$description)) {
1312 $form = '<input type="hidden" name="TYPO3_INSTALL[extConfig]['.$k.']['.$vk.']" value="0">';
1313 $form.= '<input type="checkbox" name="TYPO3_INSTALL[extConfig]['.$k.']['.$vk.']"'.($value?' checked="checked"':'').' value="'.($value&&strcmp($value,'0')?htmlspecialchars($value):1).'">';
1314 } else {
1315 $form = '<input type="text" size="40" name="TYPO3_INSTALL[extConfig]['.$k.']['.$vk.']" value="'.htmlspecialchars($value).'">';
1316 }
1317 $this->message($ext, $k2,$msg.$form);
1318 }
1319 }
1320 }
1321 break;
1322 default:
1323 if (is_array($this->INSTALL['extConfig'])) {
1324 reset($this->INSTALL['extConfig']);
1325 $lines = $this->writeToLocalconf_control();
1326 while(list($k,$va)=each($this->INSTALL['extConfig'])) {
1327 if (is_array($GLOBALS['TYPO3_CONF_VARS'][$k])) {
1328 while(list($vk,$value)=each($va)) {
1329 if (isset($GLOBALS['TYPO3_CONF_VARS'][$k][$vk])) {
1330 $doit=1;
1331 if ($k=='BE' && $vk=='installToolPassword') {
1332 if ($value) {
1333 if (isset($_POST['installToolPassword_check']) && (!t3lib_div::_GP('installToolPassword_check') || strcmp(t3lib_div::_GP('installToolPassword_check'),$value))) {
1334 $doit=0;
1335 t3lib_div::debug('ERROR: The two passwords did not match! The password was not changed.');
1336 }
1337 if (t3lib_div::_GP('installToolPassword_md5')) $value =md5($value);
1338 } else $doit=0;
1339 }
1340
1341 $description = trim($commentArr[1][$k][$vk]);
1342 if (preg_match('/^string \(textarea\)/i', $description)) {
1343 $value = str_replace(chr(13),'',$value); // Force Unix linebreaks in textareas
1344 $value = str_replace(chr(10),"'.chr(10).'",$value); // Preserve linebreaks
1345 }
1346
1347 if ($doit && strcmp($GLOBALS['TYPO3_CONF_VARS'][$k][$vk],$value)) $this->setValueInLocalconfFile($lines, '$TYPO3_CONF_VARS[\''.$k.'\'][\''.$vk.'\']', $value);
1348 }
1349 }
1350 }
1351 }
1352 $this->writeToLocalconf_control($lines);
1353 }
1354 break;
1355 }
1356 }
1357
1358 /**
1359 * [Describe function...]
1360 *
1361 * @param [type] $string: ...
1362 * @param [type] $mainArray: ...
1363 * @param [type] $commentArray: ...
1364 * @return [type] ...
1365 */
1366 function getDefaultConfigArrayComments($string,$mainArray=array(),$commentArray=array()) {
1367 $lines = explode(chr(10),$string);
1368 $in=0;
1369 $mainKey='';
1370 while(list(,$lc)=each($lines)) {
1371 $lc = trim($lc);
1372 if ($in) {
1373 if (!strcmp($lc,');')) {
1374 $in=0;
1375 } else {
1376 if (preg_match('/["\']([[:alnum:]_-]*)["\'][[:space:]]*=>(.*)/i',$lc,$reg)) {
1377 preg_match('/,[\t\s]*\/\/(.*)/i',$reg[2],$creg);
1378 $theComment = trim($creg[1]);
1379 if (substr(strtolower(trim($reg[2])),0,5)=='array' && !strcmp($reg[1],strtoupper($reg[1]))) {
1380 $mainKey=trim($reg[1]);
1381 $mainArray[$mainKey]=$theComment;
1382 } elseif ($mainKey) {
1383 $commentArray[$mainKey][$reg[1]]=$theComment;
1384 }
1385 }
1386 }
1387 }
1388 if (!strcmp($lc,'$TYPO3_CONF_VARS = Array(')) {
1389 $in=1;
1390 }
1391 }
1392 return array($mainArray,$commentArray);
1393 }
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407 /*******************************
1408 *
1409 * CHECK CONFIGURATION FUNCTIONS
1410 *
1411 *******************************/
1412
1413 /**
1414 * Checking php.ini configuration and set appropriate messages and flags.
1415 *
1416 * @return [type] ...
1417 */
1418 function checkConfiguration() {
1419 $ext='php.ini configuration checked';
1420 $this->message($ext);
1421
1422 // *****************
1423 // Incoming values:
1424 // *****************
1425
1426 // Includepath
1427 $incPaths = t3lib_div::trimExplode(TYPO3_OS=='WIN'?';':':', ini_get('include_path'));
1428 if (!in_array('.',$incPaths)) {
1429 $this->message($ext, 'Current directory (./) is not in include path!',"
1430 <i>include_path=".ini_get('include_path')."</i>
1431 Normally the current path, '.', is included in the include_path of PHP. Although TYPO3 does not rely on this, it is an unusual setting that may introduce problems for some extensions.
1432 ",1);
1433 } else $this->message($ext, 'Current directory in include path',"",-1);
1434
1435 // *****************
1436 // File uploads
1437 // *****************
1438 if (!ini_get('file_uploads')) {
1439 $this->message($ext, 'File uploads not allowed',"
1440 <i>file_uploads=".ini_get('file_uploads')."</i>
1441 TYPO3 uses the ability to upload files from the browser in various cases.
1442 As long as this flag is disabled, you'll not be able to upload files.
1443 But it doesn't end here, because not only are files not accepted by the server - ALL content in the forms are discarded and therefore nothing at all will be editable if you don't set this flag!
1444 However if you cannot enable fileupload for some reason alternatively you change the default form encoding value with \$TYPO3_CONF_VARS[SYS][form_enctype].
1445 ",3);
1446 } else $this->message($ext, 'File uploads allowed',"",-1);
1447
1448 $upload_max_filesize = $this->convertByteSize(ini_get('upload_max_filesize'));
1449 $post_max_size = $this->convertByteSize(ini_get('post_max_size'));
1450 if ($upload_max_filesize<1024*1024*10) {
1451 $this->message($ext, 'Maximum upload filesize too small?',"
1452 <i>upload_max_filesize=".ini_get('upload_max_filesize')."</i>
1453 By default TYPO3 supports uploading, copying and moving files of sizes up to 10MB (You can alter the TYPO3 defaults by the config option TYPO3_CONF_VARS[BE][maxFileSize]).
1454 Your current value is below this, so at this point, PHP sets the limits for uploaded filesizes and not TYPO3.
1455 <strong>Notice:</strong> The limits for filesizes attached to database records are set in the tables.php configuration files (\$TCA) for each group/file field. You may override these values in localconf.php or by page TSconfig settings.
1456 ",1);
1457 }
1458 if ($upload_max_filesize > $post_max_size) {
1459 $this->message($ext, 'Maximum size for POST requests is smaller than max. upload filesize','
1460 <i>upload_max_filesize='.ini_get('upload_max_filesize').', post_max_size='.ini_get('post_max_size').'</i>
1461 You have defined a maximum size for file uploads which exceeds the allowed size for POST requests. Therefore the file uploads can not be larger than '.ini_get('post_max_size').'
1462 ',1);
1463 }
1464
1465 // *****************
1466 // Memory and functions
1467 // *****************
1468 $memory_limit_value = $this->convertByteSize(ini_get('memory_limit'));
1469 if ($memory_limit_value && $memory_limit_value < 16*1024*1024) {
1470 $this->message($ext, 'Memory limit below 16 MB',"
1471 <i>memory_limit=".ini_get('memory_limit')."</i>
1472 Your system is configured to enforce a memory limit of PHP scripts lower than 16 MB. The Extension Manager needs to include more PHP-classes than will fit into this memory space. There is nothing else to do than raise the limit. To be safe, ask the system administrator of the webserver to raise the limit to over 25 MB.
1473 ",3);
1474 } elseif(!$memory_limit_value) {
1475 $this->message($ext, 'Memory limit',"<i>No memory limit in effect.</i>",-1);
1476 } else $this->message($ext, 'Memory limit',"<i>memory_limit=".ini_get('memory_limit')."</i>",-1);
1477 if (ini_get('max_execution_time')<30) {
1478 $this->message($ext, 'Maximum execution time below 30 seconds',"
1479 <i>max_execution_time=".ini_get('max_execution_time')."</i>
1480 May impose problems if too low.
1481 ",1);
1482 } else {
1483 $this->message($ext, 'Maximum execution time',"<i>max_execution_time=".ini_get('max_execution_time')."</i>",-1);
1484 }
1485 if (ini_get('disable_functions')) {
1486 $this->message($ext, 'Functions disabled!',"
1487 <i>disable_functions=".ini_get('disable_functions')."</i>
1488 The above list of functions are disabled. If TYPO3 use any of these there might be trouble.
1489 TYPO3 is designed to use the default set of PHP4.3.0+ functions plus the functions of GDLib.
1490 Possibly these functions are disabled due to security risks and most likely the list would include a function like <i>exec()</i> which is use by TYPO3 to access ImageMagick.
1491 ",2);
1492 } else {
1493 $this->message($ext, 'Functions disabled: none',"",-1);
1494 }
1495 // Mail tests
1496 if (TYPO3_OS == 'WIN') {
1497 $smtp = ini_get('SMTP');
1498 $bad_smtp = false;
1499 if (!t3lib_div::validIP($smtp)) {
1500 $smtp_addr = @gethostbyname($smtp);
1501 $bad_smtp = ($smtp_addr == $smtp);
1502 }
1503 else {
1504 $smtp_addr = $smtp;
1505 }
1506 if (!$smtp || $bad_smtp || !t3lib_div::testInt(ini_get('smtp_port'))) {
1507 $this->message($ext, 'Mail configuration is not set correctly','
1508 Mail configuration is not set
1509 PHP mail() function requires SMTP and smtp_port to have correct values on Windows.',
1510 2);
1511 } else {
1512 if (($smtp_addr == '127.0.0.1' || $smtp_addr == '::1') && ($_SERVER['SERVER_ADDR'] == '127.0.0.1' || $_SERVER['SERVER_ADDR'] == '::1')) {
1513 $this->message($ext, 'Mail is configured (potential problem exists!)',
1514 '<i>SMTP=' . $smtp . '</i> - <b>Note:</b> this server! Are you sure it runs SMTP server?
1515 <i>smtp_port=' . ini_get('smtp_port') . '</i>
1516 '.$this->check_mail('get_form'), 1);
1517 } else {
1518 $this->message($ext, 'Mail is configured',
1519 '<i>SMTP=' . $smtp . '</i>
1520 <i>smtp_port=' . ini_get('smtp_port') . '</i>
1521 '.$this->check_mail('get_form'), -1);
1522 }
1523 }
1524 } elseif (!ini_get('sendmail_path')) {
1525 $this->message($ext, 'Sendmail path not defined!','
1526 This may be critical to TYPO3\'s use of the mail() function. Please be sure that the mail() function in your php-installation works!
1527 ' . $this->check_mail('get_form'),1);
1528 } else {
1529 list($prg) = explode(' ', ini_get('sendmail_path'));
1530 if (!@is_executable($prg)) {
1531 $this->message($ext, 'Sendmail program not found or not executable?','
1532 <i>sendmail_path=' . ini_get('sendmail_path') . '</i>
1533 This may be critical to TYPO3\'s use of the mail() function. Please be sure that the mail() function in your php-installation works!
1534 '.$this->check_mail('get_form'), 1);
1535 } else {
1536 $this->message($ext, 'Sendmail OK','
1537 <i>sendmail_path=' . ini_get('sendmail_path') . '</i>
1538 '.$this->check_mail('get_form'),-1);
1539 }
1540 }
1541
1542 // *****************
1543 // Safe mode related
1544 // *****************
1545 if (ini_get('safe_mode')) {
1546 $this->message($ext, 'Safe mode turned on',"
1547 <i>safe_mode=".ini_get('safe_mode')."</i>
1548 In safe_mode PHP is restricted in several ways. This is a good thing because it adds protection to your (and others) scripts. But it may also introduce problems. In TYPO3 this <em>may be</em> a problem in two areas: File administration and execution of external programs, in particular ImageMagick.
1549 If you just ignore this warning, you'll most likely find, that TYPO3 seems to work except from the image-generation. The problem in that case is that the external ImageMagick programs are not allowed to be executed from the regular paths like \"/usr/bin/\" or \"/usr/X11R6/bin/\".
1550 If you use safe_mode with TYPO3, you should disable use of external programs ([BE][disable_exec_function]=1).
1551 In safe mode you must ensure that all the php-scripts and upload folders are owned by the same user.
1552
1553 <i>safe_mode_exec_dir=".ini_get('safe_mode_exec_dir')."</i>
1554 If the ImageMagick utilities are located in this directory, everything is fine. Below on this page, you can see if ImageMagick is found here. If not, ask you ISP to put the three ImageMagick programs, 'convert', 'combine'/'composite' and 'identify' there (eg. with symlinks if Unix server)
1555
1556
1557 <strong>Example of safe_mode settings:</strong>
1558 Set this in the php.ini file:
1559
1560 ; Safe Mode
1561 safe_mode = On
1562 safe_mode_exec_dir = /usr/bin/
1563
1564 ...and the ImageMagick '/usr/bin/convert' will be executable.
1565 The last slash is important (..../) and you can only specify one directory.
1566
1567 <strong>Notice: </strong>
1568 ImageMagick 4.2.9 is recommended and the binaries are normally installed by RPM in /usr/X11R6/bin or by compiling in /usr/local/bin. Please look in the \"Inside TYPO3\" pdf-document for extensive information about ImageMagick issues.
1569 Paths to ImageMagick are defined in localconf.php and may be something else than /usr/bin/, but this is default for ImageMagick 5+
1570
1571
1572 ",2);
1573 if (ini_get('doc_root')) {
1574 $this->message($ext, 'doc_root set',"
1575 <i>doc_root=".ini_get('doc_root')."</i>
1576 PHP cannot execute scripts outside this directory. If that is a problem is please correct it.
1577 ",1);
1578 }
1579 $this->config_array['safemode']=1;
1580 } else $this->message($ext, 'safe_mode: off',"",-1);
1581 if (ini_get('sql.safe_mode')) {
1582 $this->message($ext, 'sql.safe_mode is enabled',"
1583 <i>sql.safe_mode=".ini_get('sql.safe_mode').'</i>
1584 This means that you can only connect to the database with a username corresponding to the user of the webserver process or fileowner. Consult your ISP for information about this. Also see '.$this->linkIt('http://www.wrox.com/Consumer/Store/Books/2963/29632002.htm').'
1585 The owner of the current file is: <strong>'.get_current_user ()."</strong>
1586 ",1);
1587 $this->config_array['sql.safe_mode_user'] = get_current_user();
1588 } else $this->message($ext, 'sql.safe_mode: off',"",-1);
1589 if (ini_get('open_basedir')) {
1590 $this->message($ext, 'open_basedir set',"
1591 <i>open_basedir=".ini_get('open_basedir')."</i>
1592 This restricts TYPO3 to open and include files only in this path. Please make sure that this does not prevent TYPO3 from running.
1593 <strong>Notice (UNIX):</strong> Before checking a path according to open_basedir, PHP resolves all symbolic links.
1594 ",1);
1595 // ???? If this option was set falsely you probably didn't see this page in the first place, but this option <strong>may spoil this configuration test</strong> when checking for such as ImageMagick executables.
1596 } else $this->message($ext, 'open_basedir: off',"",-1);
1597
1598 // Check availability of PHP session support
1599 if (extension_loaded('session')) {
1600 $this->message($ext, 'PHP sessions availiable','
1601 <i>PHP Sessions availiabe</i>
1602 PHP is compiled with session support and session support is available.
1603 ',-1);
1604 } else {
1605 $this->message($ext, 'PHP Sessions not availiabe','
1606 PHP is not compiled with session support, or session support is disabled in php.ini.
1607 TYPO3 needs session support
1608 ',3);
1609 }
1610 }
1611
1612 /**
1613 * Check if PHP function mail() works
1614 *
1615 * @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.
1616 * @return [type] ...
1617 */
1618 function check_mail($cmd='') {
1619 switch($cmd) {
1620 case 'get_form':
1621 $out='
1622 You can check the mail() function by entering your email address here and press the button. You should then receive a testmail from test@test.test.<br /> Since almost all mails in TYPO3 are sent using the t3lib_htmlmail class, sending with this class can be tested by checking the box <strong>Test t3lib_htmlmail</strong> below. The return-path of the mail is set to null@'.t3lib_div::getIndpEnv('HTTP_HOST').'. Some mail servers won\'t send the mail if the host of the return-path is not resolved correctly.
1623 <form action="'.$this->action.'" method="post"><input type="text" name="TYPO3_INSTALL[check_mail]"><br /><input type="checkbox" name="TYPO3_INSTALL[use_htmlmail]" id="use_htmlmail" ><label for="use_htmlmail">Test t3lib_htmlmail.</label>
1624 <input type="submit" value="Send test mail"></form>';
1625 break;
1626 default:
1627 if (trim($this->INSTALL['check_mail'])) {
1628 $subject = 'TEST SUBJECT';
1629 $email = trim($this->INSTALL['check_mail']);
1630
1631 if($this->INSTALL['use_htmlmail']) {
1632 $emailObj = t3lib_div::makeInstance('t3lib_htmlmail');
1633 /* @var $emailObj t3lib_htmlmail */
1634 $emailObj->start();
1635 $emailObj->subject = $subject;
1636 $emailObj->from_email = 'test@test.test';
1637 $emailObj->from_name = 'TYPO3 Install Tool';
1638 $emailObj->returnPath = 'null@'.t3lib_div::getIndpEnv('HTTP_HOST');
1639 $emailObj->addPlain('TEST CONTENT');
1640 $emailObj->setHTML($emailObj->encodeMsg('<html><body>HTML TEST CONTENT</body></html>'));
1641 $emailObj->send($email);
1642 } else {
1643 t3lib_div::plainMailEncoded($email,$subject,'TEST CONTENT','From: test@test.test');
1644 }
1645 $this->messages[]= 'MAIL WAS SENT TO: '.$email;
1646 }
1647 break;
1648 }
1649 return $out;
1650 }
1651
1652 /**
1653 * Checking php extensions, specifically GDLib and Freetype
1654 *
1655 * @return [type] ...
1656 */
1657 function checkExtensions() {
1658 $ext = 'GDLib';
1659 $this->message($ext);
1660
1661 $software_info=1;
1662 if (extension_loaded('gd') && $this->isGD()) {
1663 $this->config_array['gd']=1;
1664 $this->message($ext, 'GDLib found',"",-1);
1665 if ($this->isPNG()) {
1666 $this->config_array['gd_png']=1;
1667 $this->message($ext, 'PNG supported',"",-1);
1668 }
1669 if ($this->isGIF()) {
1670 $this->config_array['gd_gif']=1;
1671 $this->message($ext, 'GIF supported',"",-1);
1672 }
1673 if ($this->isJPG()) {
1674 $this->config_array['gd_jpg']=1;
1675 $this->message($ext, 'JPG supported (not used by TYPO3)','');
1676 }
1677 if (!$this->config_array['gd_gif'] && !$this->config_array['gd_png']) {
1678 $this->message($ext, 'PNG or GIF not supported', nl2br(trim('
1679 Your GDLib supports either GIF nor PNG. It must support either one of them.
1680 ')), 2);
1681 } else {
1682 $msg=array();
1683 if ($this->config_array['gd_gif'] && $this->config_array['gd_png']) {
1684 $msg[0]='You can choose between generating GIF or PNG files, as your GDLib supports both.';
1685 }
1686 if ($this->config_array['gd_gif']) {
1687 $msg[10]="You should watch out for the generated size of the GIF-files because some versions of the GD library do not compress them with LZW, but RLE and ImageMagick is subsequently used to compress with LZW. But in the case of ImageMagick failing this task (eg. not being compiled with LZW which is the case with some versions) you'll end up with GIF-filesizes all too big!
1688 This install tool tests what kinds of GIF compression are available in the ImageMagick installations by a physical test. You can also check it manually by opening a TYPO3 generated gif-file with Photoshop and save it in a new file. If the file sizes of the original and the new file are almost the same, you're having LZW compression and everything is fine.";
1689 }
1690 if ($this->config_array['gd_png']) {
1691 $msg[20]='TYPO3 prefers the use of GIF-files and most likely your visitors on your website does too as not all browsers support PNG yet.';
1692 }
1693 $this->message($ext, 'GIF / PNG issues', nl2br(trim(implode($msg,chr(10)))), 1);
1694 }
1695 if (!$this->isTTF()) {
1696 $this->message($ext, 'FreeType is apparently not installed', "
1697 It looks like the FreeType library is not compiled into GDLib. This is required when TYPO3 uses GDLib and you'll most likely get errors like 'ImageTTFBBox is not a function' or 'ImageTTFText is not a function'.
1698 ", 2);
1699 } else {
1700 $this->message($ext, 'FreeType quick-test ('.($this->isGIF()?'as GIF':'as PNG').')', '<img src="'.htmlspecialchars(t3lib_div::getIndpEnv('REQUEST_URI').'&testingTrueTypeSupport=1').'" alt=""><br />(If the text is exceeding the image borders you are using Freetype 2 and need to set TYPO3_CONF_VARS[GFX][TTFdpi]=96.<br />If there is no image at all Freetype is most likely NOT available and you can just as well disable GDlib for TYPO3...)', -1);
1701 $this->config_array['freetype']=1;
1702 }
1703 } else {
1704 $this->message($ext, 'GDLib not found', "
1705 GDLib is required if you want to use the GIFBUILDER object in TypoScript. GIFBUILDER is in charge of all advanced image generation in TypoScript, including graphical menuitems.
1706 GDLib is also used in the TYPO3 Backend (TBE) to generate record icons and new module tabs.
1707 It's highly recommended to install this library. Remember to compile GD with FreeType which is also required.
1708 If you choose not to install GDLib, you can disable it in the configuration with [GFX][gdlib]=0;.
1709 ", 2);
1710 }
1711 $this->message($ext, 'GDLib software information', nl2br(trim($this->getGDSoftwareInfo())));
1712 }
1713
1714 /**
1715 * Checking and testing that the required writable directories are writable.
1716 *
1717 * @return [type] ...
1718 */
1719 function checkDirs() {
1720 // Check typo3/temp/
1721 $ext='Directories';
1722 $this->message($ext);
1723
1724 $uniqueName = md5(uniqid(microtime()));
1725
1726 // The requirement level (the integer value, ie. the second value of the value array) has the following meanings:
1727 // -1 = not required, but if it exists may be writable or not
1728 // 0 = not required, if it exists the dir should be writable
1729 // 1 = required, don't has to be writable
1730 // 2 = required, has to be writable
1731
1732 $checkWrite=array(
1733 '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'),
1734 'typo3temp/pics/' => array('This folder is part of the typo3temp/ section. It needs to be writable, too.',2,'dir_typo3temp'),
1735 'typo3temp/temp/' => array('This folder is part of the typo3temp/ section. It needs to be writable, too.',2,'dir_typo3temp'),
1736 'typo3temp/llxml/' => array('This folder is part of the typo3temp/ section. It needs to be writable, too.',2,'dir_typo3temp'),
1737 'typo3temp/cs/' => array('This folder is part of the typo3temp/ section. It needs to be writable, too.',2,'dir_typo3temp'),
1738 'typo3temp/GB/' => array('This folder is part of the typo3temp/ section. It needs to be writable, too.',2,'dir_typo3temp'),
1739 'typo3temp/locks/' => array('This folder is part of the typo3temp/ section. It needs to be writable, too.',2,'dir_typo3temp'),
1740 '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),
1741 'typo3conf/ext/' => array('Location for local extensions. Must be writable if the Extension Manager is supposed to install extensions for this website.',0),
1742 'typo3conf/l10n/' => array('Location for translations. Must be writable if the Extension Manager is supposed to install translations for extensions.',0),
1743 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),
1744 'uploads/' => array('Location for uploaded files from RTE, in the subdirectories for uploaded files of content elements.',2),
1745 'uploads/pics/' => array('Typical location for uploaded files (images especially).',0),
1746 'uploads/media/' => array('Typical location for uploaded files (non-images especially).',0),
1747 'uploads/tf/' => array('Typical location for uploaded files (TS template resources).',0),
1748 'fileadmin/' => array('Location for local files such as templates, independent uploads etc.',-1),
1749 'fileadmin/_temp_/' => array('Typical temporary location for default upload of files by administrators.',0),
1750 );
1751
1752 foreach ($checkWrite as $relpath => $descr) {
1753
1754 // Check typo3temp/
1755 $general_message = $descr[0];
1756
1757 if (!@is_dir(PATH_site.$relpath)) { // If the directory is missing, try to create it
1758 t3lib_div::mkdir(PATH_site.$relpath);
1759 }
1760
1761 if (!@is_dir(PATH_site.$relpath)) {
1762 if ($descr[1]) { // required...
1763 $this->message($ext, $relpath.' directory does not exist and could not be created','
1764 <em>Full path: '.PATH_site.$relpath.'</em>
1765 '.$general_message.'
1766
1767 This error should not occur as '.$relpath.' must always be accessible in the root of a TYPO3 website.
1768 ',3);
1769 } else {
1770 if ($descr[1] == 0) {
1771 $msg = 'This directory does not necessarily have to exist but if it does it must be writable.';
1772 } else {
1773 $msg = 'This directory does not necessarily have to exist and if it does it can be writable or not.';
1774 }
1775 $this->message($ext, $relpath.' directory does not exist','
1776 <em>Full path: '.PATH_site.$relpath.'</em>
1777 '.$general_message.'
1778
1779 '.$msg.'
1780 ',2);
1781 }
1782 } else {
1783 $file = PATH_site.$relpath.$uniqueName;
1784 @touch($file);
1785 if (@is_file($file)) {
1786 unlink($file);
1787 if ($descr[2]) { $this->config_array[$descr[2]]=1; }
1788 $this->message($ext, $relpath.' writable','',-1);
1789 } else {
1790 $severity = ($descr[1]==2 || $descr[1]==0) ? 3 : 2;
1791 if ($descr[1] == 0 || $descr[1] == 2) {
1792 $msg = 'The directory '.$relpath.' must be writable!';
1793 } elseif ($descr[1] == -1 || $descr[1] == 1) {
1794 $msg = 'The directory '.$relpath.' does not neccesarily have to be writable.';
1795 }
1796 $this->message($ext, $relpath.' directory not writable','
1797 <em>Full path: '.$file.'</em>
1798 '.$general_message.'
1799
1800 Tried to write this file (with touch()) but didn\'t succeed.
1801 '.$msg.'
1802 ',$severity);
1803 }
1804 }
1805 }
1806 }
1807
1808 /**
1809 * Checking for existing ImageMagick installs.
1810 *
1811 * 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.
1812 *
1813 * @param [type] $paths: ...
1814 * @return [type] ...
1815 */
1816 function checkImageMagick($paths) {
1817 $ext='Check Image Magick';
1818 $this->message($ext);
1819
1820 $paths = array_unique($paths);
1821
1822 $programs = explode(',','gm,convert,combine,composite,identify');
1823 $isExt = TYPO3_OS=="WIN" ? ".exe" : "";
1824 $this->config_array['im_combine_filename']='combine';
1825 reset($paths);
1826 while(list($k,$v)=each($paths)) {
1827 reset($programs);
1828 if (!preg_match('/[\\/]$/',$v)) $v.='/';
1829 while(list(,$filename)=each($programs)) {
1830 if (ini_get('open_basedir') || (file_exists($v)&&@is_file($v.$filename.$isExt))) {
1831 $version = $this->_checkImageMagick_getVersion($filename,$v);
1832 if($version > 0) {
1833 if($filename=='gm') { // Assume GraphicsMagick
1834 $index[$v]['gm']=$version;
1835 continue; // No need to check for "identify" etc.
1836 } else { // Assume ImageMagick
1837 $index[$v][$filename]=$version;
1838 }
1839 }
1840 }
1841 }
1842 if (count($index[$v])>=3 || $index[$v]['gm']) { $this->config_array['im']=1; }
1843
1844 if ($index[$v]['gm'] || (!$index[$v]['composite'] && $index[$v]['combine'])) {
1845 $this->config_array['im_combine_filename']='combine';
1846 } elseif ($index[$v]['composite'] && !$index[$v]['combine']) {
1847 $this->config_array['im_combine_filename']='composite';
1848 }
1849
1850 if (isset($index[$v]['convert']) && $this->checkIMlzw) {
1851 $index[$v]['gif_capability'] = ''.$this->_checkImageMagickGifCapability($v);
1852 }
1853 }
1854 $this->config_array['im_versions']=$index;
1855 if (!$this->config_array['im']) {
1856 $this->message($ext, 'No ImageMagick installation available',"
1857 It seems that there is no adequate ImageMagick installation available at the checked locations (".implode($paths, ', ').")
1858 An 'adequate' installation for requires 'convert', 'combine'/'composite' and 'identify' to be available
1859 ",2);
1860 } else {
1861 $theCode='';
1862 reset($this->config_array['im_versions']);
1863 while(list($p,$v)=each($this->config_array['im_versions'])) {
1864 $ka=array();
1865 reset($v);
1866 while(list($ka[])=each($v)){}
1867 $theCode.='<tr><td>'.$this->fw($p).'</td><td>'.$this->fw(implode($ka,'<br />')).'</td><td>'.$this->fw(implode($v,'<br />')).'</td></tr>';
1868 }
1869 $this->message($ext, 'Available ImageMagick/GraphicsMagick installations:','<table border="1" cellpadding="2" cellspacing="2">'.$theCode.'</table>',-1);
1870 }
1871 $this->message($ext, 'Search for ImageMagick:','
1872 <form action="'.$this->action.'" method="post">
1873 <input type="checkbox" name="TYPO3_INSTALL[checkIM][lzw]" id="checkImLzw" value="1"'.($this->INSTALL['checkIM']['lzw']?' checked="checked"':'').'> <label for="checkImLzw">Check LZW capabilities.</label>
1874
1875 Check this path for ImageMagick installation:
1876 <input type="text" name="TYPO3_INSTALL[checkIM][path]" value="'.htmlspecialchars($this->INSTALL['checkIM']['path']).'">
1877 (Eg. "D:\wwwroot\im537\ImageMagick\" for Windows or "/usr/bin/" for Unix)<br />
1878
1879 <input type="submit" value="Send">
1880 </form>
1881 ',0);
1882
1883 }
1884
1885 /**
1886 * Checking GIF-compression capabilities of ImageMagick install
1887 *
1888 * @param [type] $file: ...
1889 * @return [type] ...
1890 */
1891 function _checkImageMagickGifCapability($path) {
1892 if ($this->config_array['dir_typo3temp']) { // && !$this->config_array['safemode']
1893 $tempPath = $this->typo3temp_path;
1894 $uniqueName = md5(uniqid(microtime()));
1895 $dest = $tempPath.$uniqueName.'.gif';
1896 $src = $this->backPath.'gfx/typo3logo.gif';
1897 if (@is_file($src) && !strstr($src,' ') && !strstr($dest,' ')) {
1898 $cmd = t3lib_div::imageMagickCommand('convert', $src.' '.$dest, $path);
1899 exec($cmd);
1900 } else die('No typo3/gfx/typo3logo.gif file!');
1901 $out='';
1902 if (@is_file($dest)) {
1903 $new_info = @getimagesize($dest);
1904 clearstatcache();
1905 $new_size = filesize($dest);
1906 $src_info = @getimagesize($src);
1907 clearstatcache();
1908 $src_size = @filesize($src);
1909
1910 if ($new_info[0]!=$src_info[0] || $new_info[1]!=$src_info[1] || !$new_size || !$src_size) {
1911 $out='error';
1912 } else {
1913 if ($new_size/$src_size > 4) { // NONE-LZW ratio was 5.5 in test
1914 $out='NONE';
1915 } elseif ($new_size/$src_size > 1.5) { // NONE-RLE ratio was not tested
1916 $out='RLE';
1917 } else {
1918 $out='LZW';
1919 }
1920 }
1921 unlink($dest);
1922 }
1923 return $out;
1924 }
1925 }
1926
1927 /**
1928 * Extracts the version number for ImageMagick
1929 *
1930 * @param string The program name to execute in order to find out the version number
1931 * @param string Path for the above program
1932 * @return string Version number of the found ImageMagick instance
1933 */
1934 function _checkImageMagick_getVersion($file, $path) {
1935 // Temporarily override some settings
1936 $im_version = $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_version_5'];
1937 $combine_filename = $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_combine_filename'];
1938
1939 if ($file=='gm') {
1940 $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_version_5'] = 'gm';
1941 $file = 'identify'; // Work-around, preventing execution of "gm gm"
1942 $parameters = '-version'; // Work-around - GM doesn't like to be executed without any arguments
1943 } else {
1944 $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_version_5'] = 'im5';
1945
1946 if($file=='combine' || $file=='composite') { // Override the combine_filename setting
1947 $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_combine_filename'] = $file;
1948 }
1949 }
1950
1951 $cmd = t3lib_div::imageMagickCommand($file, $parameters, $path);
1952 $retVal = false;
1953 exec($cmd, $retVal);
1954 $string = $retVal[0];
1955 list(,$ver) = explode('Magick', $string);
1956 list($ver) = explode(' ',trim($ver));
1957
1958 // Restore the values
1959 $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_version_5'] = $im_version;
1960 $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_combine_filename'] = $combine_filename;
1961 return trim($ver);
1962 }
1963
1964 /**
1965 * Checks database username/password/host/database
1966 *
1967 * @return [type] ...
1968 */
1969 function checkDatabase() {
1970 $ext='Check database';
1971 $this->message($ext);
1972
1973 if (!extension_loaded('mysql') && !t3lib_extMgm::isLoaded('dbal')) {
1974 $this->message($ext, 'MySQL not available',"
1975 PHP does not feature MySQL support (which is pretty unusual).
1976 ",2);
1977 } else {
1978 $cInfo='
1979 Username: <strong>'.TYPO3_db_username.'</strong>
1980 Host: <strong>'.TYPO3_db_host.'</strong>
1981 ';
1982 if (!TYPO3_db_host || !TYPO3_db_username) {
1983 $this->message($ext, 'Username, password or host not set',"
1984 You may need to enter data for these values:
1985 ".trim($cInfo)."
1986
1987 Use the form below.
1988 ",2);
1989 }
1990 if ($result = $GLOBALS['TYPO3_DB']->sql_pconnect(TYPO3_db_host, TYPO3_db_username, TYPO3_db_password)) {
1991 $this->message($ext, 'Connected to SQL database successfully',"
1992 ".trim($cInfo)."
1993 ",-1,1);
1994 $this->config_array['mysqlConnect']=1;
1995 if (!TYPO3_db) {
1996 $this->message($ext, 'No database selected',"
1997 Currently you have no database selected.
1998 Please select one or create a new database.
1999 ",3);
2000 $this->config_array['no_database']=1;
2001 } elseif (!$GLOBALS['TYPO3_DB']->sql_select_db(TYPO3_db)) {
2002 $this->message($ext, 'Database',"
2003 '".TYPO3_db."' could not be selected as database!
2004 Please select another one or create a new database.
2005 ",3,1);
2006 $this->config_array['no_database']=1;
2007 } else {
2008 $this->message($ext, 'Database',"
2009 <strong>".TYPO3_db."</strong> is selected as database.
2010 ",1,1);
2011 }
2012 } else {
2013 $this->message($ext, 'Could not connect to SQL database!',"
2014 Connecting to SQL database failed with these settings:
2015 ".trim($cInfo)."
2016
2017 Make sure you're using the correct set of data.".($this->config_array['sql.safe_mode_user']? "
2018 <strong>Notice:</strong> <em>sql.safe_mode</em> is turned on, so apparently your username to the database is the same as the scriptowner, which is '".$this->config_array['sql.safe_mode_user']."'":"")."
2019 ",3);
2020 }
2021 }
2022 }
2023
2024 /**
2025 * Prints form for updating localconf.php or updates localconf.php depending on $cmd
2026 *
2027 * @param string $cmd If "get_form" it outputs the form. Default is to write "localconf.php" based on input in ->INSTALL[localconf.php] array and flag ->setLocalconf
2028 * @return [type] ...
2029 */
2030 function setupGeneral($cmd='') {
2031 switch($cmd) {
2032 case 'get_form':
2033 // Database:
2034 $out='
2035 <form name="setupGeneral" action="'.$this->action.'" method="post">
2036 <table border="0" cellpadding="0" cellspacing="0">';
2037
2038 $out.=$this->wrapInCells('Username:', '<input type="text" name="TYPO3_INSTALL[localconf.php][typo_db_username]" value="'.htmlspecialchars(TYPO3_db_username?TYPO3_db_username:($this->config_array['sql.safe_mode_user']?$this->config_array['sql.safe_mode_user']:"")).'">'.($this->config_array['sql.safe_mode_user']?"<br />sql.safe_mode_user: <strong>".$this->config_array['sql.safe_mode_user']."</strong>":""));
2039 $out.=$this->wrapInCells('Password:', '<input type="password" name="TYPO3_INSTALL[localconf.php][typo_db_password]" value="'.htmlspecialchars(TYPO3_db_password).'">');
2040 $out.=$this->wrapInCells('Host:', '<input type="text" name="TYPO3_INSTALL[localconf.php][typo_db_host]" value="'.htmlspecialchars(TYPO3_db_host).'">');
2041 if ($this->config_array['mysqlConnect']) {
2042 $dbArr = $this->getDatabaseList();
2043 reset($dbArr);
2044 $options='';
2045 $dbIncluded=0;
2046 while(list(,$dbname)=each($dbArr)) {
2047 $options.='<option value="'.htmlspecialchars($dbname).'"'.($dbname==TYPO3_db?' selected="selected"':'').'>'.htmlspecialchars($dbname).'</option>';
2048 if ($dbname==TYPO3_db) $dbIncluded=1;
2049 }
2050 if (!$dbIncluded && TYPO3_db) {
2051 $options.='<option value="'.htmlspecialchars(TYPO3_db).'" selected="selected">'.htmlspecialchars(TYPO3_db).' (NO ACCESS!)</option>';
2052 }
2053 $theCode='<select name="TYPO3_INSTALL[localconf.php][typo_db]">'.$options.'</select><br />Create database? (Enter name):<br /><input type="text" name="TYPO3_INSTALL[localconf.php][NEW_DATABASE_NAME]" value="">';
2054 } else {
2055 $theCode='<strong>'.htmlspecialchars(TYPO3_db).'</strong><br />(Can only select database if username/password/host is correctly set first)<input type="hidden" name="TYPO3_INSTALL[localconf.php][typo_db]" value="'.htmlspecialchars(TYPO3_db).'">';
2056 }
2057 $out.=$this->wrapInCells('', '<br />');
2058 $out.=$this->wrapInCells('Database:', $theCode);
2059 $out.=$this->wrapInCells('', '<br />');
2060
2061 if ($this->mode!='123') {
2062 $this->headerStyle .= chr(10) .
2063 '<script type="text/javascript" src="' . t3lib_div::getIndpEnv('TYPO3_SITE_URL') . TYPO3_mainDir . 'contrib/prototype/prototype.js"></script>
2064 <script type="text/javascript" src="' . t3lib_div::getIndpEnv('TYPO3_SITE_URL') . TYPO3_mainDir . 'sysext/install/mod/install.js"></script>';
2065
2066
2067 $out.=$this->wrapInCells('Site name:', '<input type="text" name="TYPO3_INSTALL[localconf.php][sitename]" value="'.htmlspecialchars($GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename']).'">');
2068 $out.=$this->wrapInCells('', '<br />');
2069 $out.=$this->wrapInCells('Encryption key:', '<a name="set_encryptionKey"></a><input type="text" name="TYPO3_INSTALL[localconf.php][encryptionKey]" value="'.htmlspecialchars($GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey']).'"><br /><input type="button" onclick="EncryptionKey.load(this)" value="Generate random key">');
2070 $out.=$this->wrapInCells('', '<br />');
2071
2072 // Other
2073 $fA = $this->setupGeneralCalculate();
2074
2075 if (is_array($fA['disable_exec_function'])) {
2076 $out.=$this->wrapInCells('[BE][disable_exec_function]=', $this->getFormElement($fA['disable_exec_function'], $fA['disable_exec_function'], 'TYPO3_INSTALL[localconf.php][disable_exec_function]', $GLOBALS['TYPO3_CONF_VARS']['BE']['disable_exec_function']));
2077 }
2078 if (is_array($fA['gdlib'])) {
2079 $out.=$this->wrapInCells('[GFX][gdlib]=', $this->getFormElement($fA['gdlib'], $fA['gdlib'], 'TYPO3_INSTALL[localconf.php][gdlib]', $GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib']));
2080 if (is_array($fA['gdlib_png']) && $GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib']) {
2081 $out.=$this->wrapInCells('[GFX][gdlib_png]=', $this->getFormElement($this->setLabelValueArray($fA['gdlib_png'],2), $fA['gdlib_png'], 'TYPO3_INSTALL[localconf.php][gdlib_png]', $GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib_png']));
2082 }
2083 }
2084 if (is_array($fA['im'])) {
2085 $out.=$this->wrapInCells('[GFX][im]=', $this->getFormElement($fA['im'], $fA['im'], 'TYPO3_INSTALL[localconf.php][im]', $GLOBALS['TYPO3_CONF_VARS']['GFX']['im']));
2086 $out.=$this->wrapInCells('[GFX][im_combine_filename]=', $this->getFormElement($fA['im_combine_filename'], ($fA['im_combine_filename']?$fA['im_combine_filename']:"combine"), 'TYPO3_INSTALL[localconf.php][im_combine_filename]', $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_combine_filename']));
2087 $out.=$this->wrapInCells('[GFX][im_version_5]=', $this->getFormElement($fA['im_version_5'], ($fA['im_version_5']?$fA['im_version_5']:''), 'TYPO3_INSTALL[localconf.php][im_version_5]', $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_version_5']));
2088 if ($GLOBALS['TYPO3_CONF_VARS']['GFX']['im']) {
2089 if (is_array($fA['im_path'])) {
2090 $out.=$this->wrapInCells('[GFX][im_path]=', $this->getFormElement($this->setLabelValueArray($fA['im_path'],1), $this->setLabelValueArray($fA['im_path'],0), 'TYPO3_INSTALL[localconf.php][im_path]', $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_path']));
2091 }
2092 if (is_array($fA['im_path_lzw'])) {
2093 $out.=$this->wrapInCells('[GFX][im_path_lzw]=', $this->getFormElement($this->setLabelValueArray($fA['im_path_lzw'],1), $this->setLabelValueArray($fA['im_path_lzw'],0), 'TYPO3_INSTALL[localconf.php][im_path_lzw]', $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_path_lzw']));
2094 }
2095 }
2096 }
2097 $out.=$this->wrapInCells('[GFX][TTFdpi]=', '<input type="text" name="TYPO3_INSTALL[localconf.php][TTFdpi]" value="'.htmlspecialchars($GLOBALS['TYPO3_CONF_VARS']['GFX']['TTFdpi']).'">');
2098 }
2099
2100
2101 $out.=$this->wrapInCells('', '<br /><input type="submit" value="Update localconf.php"><br />
2102 <strong>NOTICE: </strong>By clicking this button, localconf.php is updated with new values for the parameters listed above!');
2103 $out.='
2104 </table>
2105 </form>';
2106 break;
2107 default:
2108 if (is_array($this->INSTALL['localconf.php'])) {
2109 $errorMessages=array();
2110 $lines = $this->writeToLocalconf_control();
2111
2112 // New database?
2113 #debug($this->INSTALL);
2114 if (trim($this->INSTALL['localconf.php']['NEW_DATABASE_NAME'])) {
2115 $newdbname=trim($this->INSTALL['localconf.php']['NEW_DATABASE_NAME']);
2116 if (!preg_match('/[^[:alnum:]_-]/',$newdbname)) {
2117 if ($result = $GLOBALS['TYPO3_DB']->sql_pconnect(TYPO3_db_host, TYPO3_db_username, TYPO3_db_password)) {
2118 if ($GLOBALS['TYPO3_DB']->admin_query('CREATE DATABASE '.$newdbname)) {
2119 $this->INSTALL['localconf.php']['typo_db'] = $newdbname;
2120 $this->messages[]= "Database '".$newdbname."' created";
2121 } else $this->messages[]= $errorMessages[] = "Could not create database '".$newdbname."' (...not created)";
2122 } else $this->messages[]= $errorMessages[] = "Could not connect to database when creating database '".$newdbname."' (...not created)";
2123 } else $this->messages[]= $errorMessages[] = "The NEW database name '".$newdbname."' was not alphanumeric, a-zA-Z0-9_- (...not created)";
2124 }
2125 #debug($this->messages) ;
2126 // Parsing values
2127 reset($this->INSTALL['localconf.php']);
2128 while(list($key,$value)=each($this->INSTALL['localconf.php'])) {
2129 switch((string)$key) {
2130 case 'typo_db_username':
2131 if (strlen($value)<50) {
2132 if (strcmp(TYPO3_db_username,$value)) $this->setValueInLocalconfFile($lines, '$typo_db_username', trim($value));
2133 } else $this->messages[]= $errorMessages[] = "Username '".$value."' was longer than 50 chars (...not saved)";
2134 break;
2135 case 'typo_db_password':
2136 if (strlen($value)<50) {
2137 if (strcmp(TYPO3_db_password,$value)) $this->setValueInLocalconfFile($lines, '$typo_db_password', trim($value));
2138 } else $this->messages[]= $errorMessages[] = "Password was longer than 50 chars (...not saved)";
2139 break;
2140 case 'typo_db_host':
2141 if (preg_match('/^[a-zA-Z0-9_\.-]+(:.+)?$/',$value) && strlen($value)<50) {
2142 if (strcmp(TYPO3_db_host,$value)) $this->setValueInLocalconfFile($lines, '$typo_db_host', $value);
2143 } else $this->messages[]= $errorMessages[] = "Host '".$value."' was not alphanumeric (a-z, A-Z, 0-9 or _-.), or longer than 50 chars (...not saved)";
2144 break;
2145 case 'typo_db':
2146 if (strlen($value)<50) {
2147 if (strcmp(TYPO3_db,$value)) $this->setValueInLocalconfFile($lines, '$typo_db', trim($value));
2148 } else $this->messages[]= $errorMessages[] = "Database name '".$value."' was longer than 50 chars (...not saved)";
2149 break;
2150 case 'disable_exec_function':
2151 if (strcmp($GLOBALS['TYPO3_CONF_VARS']['BE']['disable_exec_function'],$value)) $this->setValueInLocalconfFile($lines, '$TYPO3_CONF_VARS[\'BE\'][\'disable_exec_function\']', $value?1:0);
2152 break;
2153 case 'sitename':
2154 if (strcmp($GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'],$value)) $this->setValueInLocalconfFile($lines, '$TYPO3_CONF_VARS[\'SYS\'][\'sitename\']', $value);
2155 break;
2156 case 'encryptionKey':
2157 if (strcmp($GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'],$value)) $this->setValueInLocalconfFile($lines, '$TYPO3_CONF_VARS[\'SYS\'][\'encryptionKey\']', $value);
2158 break;
2159 case 'compat_version':
2160 if (strcmp($GLOBALS['TYPO3_CONF_VARS']['SYS']['compat_version'],$value)) $this->setValueInLocalconfFile($lines, '$TYPO3_CONF_VARS[\'SYS\'][\'compat_version\']', $value);
2161 break;
2162 case 'im_combine_filename':
2163 if (strcmp($GLOBALS['TYPO3_CONF_VARS']['GFX']['im_combine_filename'],$value)) $this->setValueInLocalconfFile($lines, '$TYPO3_CONF_VARS[\'GFX\'][\'im_combine_filename\']', $value);
2164 break;
2165 case 'gdlib':
2166 case 'gdlib_png':
2167 case 'im':
2168 if (strcmp($GLOBALS['TYPO3_CONF_VARS']['GFX'][$key], $value)) {
2169 $this->setValueInLocalconfFile($lines, '$TYPO3_CONF_VARS[\'GFX\'][\'' . $key . '\']', ($value ? 1 : 0));
2170 }
2171 break;
2172 case 'im_path':
2173 list($value,$version) = explode('|',$value);
2174 if (!preg_match('/[[:space:]]/',$value,$reg) && strlen($value)<100) {
2175 if (strcmp($GLOBALS['TYPO3_CONF_VARS']['GFX'][$key], $value)) {
2176 $this->setValueInLocalconfFile($lines, '$TYPO3_CONF_VARS[\'GFX\'][\'' . $key . '\']', $value);
2177 }
2178 if(doubleval($version)>0 && doubleval($version)<4) { // Assume GraphicsMagick
2179 $value_ext = 'gm';
2180 } elseif(doubleval($version)<5) { // Assume ImageMagick 4.x
2181 $value_ext = '';
2182 } elseif(doubleval($version) >= 6) { // Assume ImageMagick 6.x
2183 $value_ext = 'im6';
2184 } else { // Assume ImageMagick 5.x
2185 $value_ext = 'im5';
2186 }
2187 if (strcmp(strtolower($GLOBALS['TYPO3_CONF_VARS']['GFX']['im_version_5']),$value_ext)) {
2188 $this->setValueInLocalconfFile($lines, '$TYPO3_CONF_VARS[\'GFX\'][\'im_version_5\']', $value_ext);
2189 }
2190 // if (strcmp(strtolower($GLOBALS['TYPO3_CONF_VARS']['GFX']['im_version_5']),$value)) $this->setValueInLocalconfFile($lines, '$TYPO3_CONF_VARS['GFX']['im_version_5']', $value);
2191 } else $this->messages[]= $errorMessages[] = "Path '".$value."' contains spaces or is longer than 100 chars (...not saved)";
2192 break;
2193 case 'im_path_lzw':
2194 list($value) = explode('|',$value);
2195 if (!preg_match('/[[:space:]]/',$value) && strlen($value)<100) {
2196 if (strcmp($GLOBALS['TYPO3_CONF_VARS']['GFX'][$key], $value)) {
2197 $this->setValueInLocalconfFile($lines, '$TYPO3_CONF_VARS[\'GFX\'][\'' . $key . '\']', $value);
2198 }
2199 } else $this->messages[]= $errorMessages[] = "Path '".$value."' contains spaces or is longer than 100 chars (...not saved)";
2200 break;
2201 case 'TTFdpi':
2202 if (strcmp($GLOBALS['TYPO3_CONF_VARS']['GFX']['TTFdpi'],$value)) $this->setValueInLocalconfFile($lines, '$TYPO3_CONF_VARS[\'GFX\'][\'TTFdpi\']', $value);
2203 break;
2204 }
2205
2206
2207 }
2208
2209 if (count($errorMessages)) {
2210 echo '<h3>ERRORS</h3>';
2211 echo t3lib_div::view_array($errorMessages);
2212 echo 'Click the browsers "Back" button to reenter the values.';
2213 exit;
2214 }
2215 $this->writeToLocalconf_control($lines);
2216 }
2217 break;
2218 }
2219 return $out;
2220 }
2221
2222 /**
2223 * Writes or returns lines from localconf.php
2224 *
2225 * @param array Array of lines to write back to localconf.php. Possibly
2226 * @param boolean If TRUE then print what has been done.
2227 * @return mixed If $lines is not an array it will return an array with the lines from localconf.php. Otherwise it will return a status string, either "continue" (updated) or "nochange" (not updated)
2228 * @see parent::writeToLocalconf_control()
2229 */
2230 function writeToLocalconf_control($lines='', $showOutput=TRUE) {
2231 $returnVal = parent::writeToLocalconf_control($lines);
2232
2233 if ($showOutput) {
2234 switch($returnVal) {
2235 case 'continue':
2236 $content = '<br /><br />'.implode($this->messages,'<hr />').'<br /><br /><a href="'.$this->action.'">Click to continue...</a>';
2237 $this->outputExitBasedOnStep($content);
2238 break;
2239 case 'nochange':
2240 $content = '<strong>Writing to \'localconf.php\':</strong><br /><br />No values were changed, so nothing is updated!<br /><br /><a href="'.$this->action.'">Click to continue...</a>';
2241 $this->outputExitBasedOnStep('<br />'.$content);
2242 break;
2243 }
2244 }
2245 return $returnVal;
2246 }
2247
2248 /**
2249 * [Describe function...]
2250 *
2251 * @param [type] $content: ...
2252 * @return [type] ...
2253 */
2254 function outputExitBasedOnStep($content) {
2255 if ($this->step) {
2256 Header('Location: '.t3lib_div::locationHeaderUrl($this->action));
2257 } else {
2258 $this->output($this->outputWrapper($content));
2259 }
2260 exit;
2261 }
2262
2263 /**
2264 * This appends something to value in the input array based on $type. Private.
2265 *
2266 * @param [type] $arr: ...
2267 * @param [type] $type: ...
2268 * @return [type] ...
2269 */
2270 function setLabelValueArray($arr,$type) {
2271 reset($arr);
2272 while(list($k,$v)=each($arr)) {
2273 if($this->config_array['im_versions'][$v]['gm']) {
2274 $program = 'gm';
2275 } else {
2276 $program = 'convert';
2277 }
2278
2279 switch($type) {
2280 case 0: // value, im
2281 $arr[$k].='|'.$this->config_array['im_versions'][$v][$program];
2282 break;
2283 case 1: // labels, im
2284 if($this->config_array['im_versions'][$v][$program]) {
2285 $arr[$k].= ' ('.$this->config_array['im_versions'][$v][$program];
2286 $arr[$k].= ($this->config_array['im_versions'][$v]['gif_capability'] ? ', '.$this->config_array['im_versions'][$v]['gif_capability'] : '');
2287 $arr[$k].= ')';
2288 } else {
2289 $arr[$k].= '';
2290 }
2291 break;
2292 case 2: // labels, gd
2293 $arr[$k].=' ('.($v==1?'PNG':'GIF').')';
2294 break;
2295 }
2296 }
2297 return $arr;
2298 }
2299
2300 /**
2301 * Returns a form-element for the localconf.php update form
2302 *
2303 * @param [type] $labels: ...
2304 * @param [type] $values: ...
2305 * @param [type] $fieldName: ...
2306 * @param [type] $default: ...
2307 * @param [type] $msg: ...
2308 * @return [type] ...
2309 */
2310 function getFormElement($labels,$values,$fieldName,$default,$msg='') {
2311 $out.='<strong>'.htmlspecialchars(current($labels)).'</strong><br />current value is '.htmlspecialchars($default).($msg?'<br />'.$msg:'');
2312 if (count($labels)>1) {
2313 reset($labels);
2314 while(list($k,$v)=each($labels)) {
2315 list($cleanV) =explode('|',$values[$k]);
2316 $options.='<option value="'.htmlspecialchars($values[$k]).'"'.(!strcmp($default,$cleanV)?' selected="selected"':'').'>'.htmlspecialchars($v).'</option>';
2317 }
2318 $out.='<br /><select name="'.$fieldName.'">'.$options.'</select>';
2319 } else {
2320 $out.='<input type="hidden" name="'.$fieldName.'" value="'.htmlspecialchars(current($values)).'">';
2321 }
2322 return $out.'<br />';
2323 }
2324
2325 /**
2326 * Returns the list of available databases (with access-check based on username/password)
2327 *
2328 * @return [type] ...
2329 */
2330 function getDatabaseList() {
2331 $dbArr=array();
2332 if ($result = $GLOBALS['TYPO3_DB']->sql_pconnect(TYPO3_db_host, TYPO3_db_username, TYPO3_db_password)) {
2333 $dbArr = $GLOBALS['TYPO3_DB']->admin_get_dbs();
2334 }
2335 return $dbArr;
2336 }
2337
2338 /**
2339 * Calculates the suggested setup that should be written to localconf.php
2340 *
2341 * If safe_mode
2342 * - disable_exec_function = 1
2343 * - im = 0
2344 *
2345 * if PNG/GIF/GD
2346 * - disable gdlib if nothing
2347 * - select png/gif if only one of them is available, else PNG/GIF selector, defaulting to GIF
2348 * - (safe_mode is on)
2349 * - im_path (default to 4.2.9, preferable with LZW) im_ver5-flag is set based on im_path being 4.2.9 or 5+
2350 * - im_path_lzw (default to LZW version, pref. 4.2.9)
2351 *
2352 * @return [type] ...
2353 */
2354 function setupGeneralCalculate() {
2355 $formArray['disable_exec_function']=array(0);
2356 $formArray['im_path']=array('');
2357 $formArray['im_path_lzw']=array('');
2358 $formArray['im_combine_filename']=array('');
2359 $formArray['im_version_5']=array('');
2360 $formArray['im']=array(1);
2361 $formArray['gdlib']=array(1);
2362 if ($this->config_array['gd'] && ($this->config_array['gd_gif'] || $this->config_array['gd_png'])) {
2363 if ($this->config_array['gd_gif'] && !$this->config_array['gd_png']) {
2364 $formArray['gdlib_png']=array(0);
2365 } elseif (!$this->config_array['gd_gif'] && $this->config_array['gd_png']) {
2366 $formArray['gdlib_png']=array(1);
2367 } else {
2368 $formArray['gdlib_png']=array(0,1);
2369 }
2370 } else {
2371 $formArray['gdlib']=array(0);
2372 }
2373 if ($this->config_array['safemode']) {
2374 $formArray['disable_exec_function']=array(1);
2375 }
2376 if ($this->config_array['im']) {
2377 $formArray['im']=array(1);
2378 $LZW_found=0;
2379 $found=0;
2380 reset($this->config_array['im_versions']);
2381 $totalArr=array();
2382 while(list($path,$dat)=each($this->config_array['im_versions'])) {
2383 if (count($dat)>=3) {
2384 if (doubleval($dat['convert'])<5) {
2385 $formArray['im_version_5']=array(0);
2386 if ($dat['gif_capability']=='LZW') {
2387 $formArray['im_path']=array($path);
2388 $found=2;
2389 } elseif ($found<2) {
2390 $formArray['im_path']=array($path);
2391 $found=1;
2392 }
2393 } elseif (doubleval($dat['convert']) >= 6) {
2394 $formArray['im_version_5'] = array('im6');
2395 if ($dat['gif_capability'] == 'LZW') {
2396 $formArray['im_path'] = array($path);
2397 $found = 2;
2398 } elseif ($found < 2) {
2399 $formArray['im_path'] = array($path);
2400 $found = 1;
2401 }
2402 } elseif (!$found) {
2403 $formArray['im_version_5']=array('im5');
2404 $formArray['im_path']=array($path);
2405 $found=1;
2406 }
2407 } elseif ($dat['gm']) {
2408 $formArray['im_version_5']=array('gm');
2409 if ($dat['gif_capability']=='LZW') {
2410 $formArray['im_path']=array($path);
2411 $found=2;
2412 } elseif ($found<2) {
2413 $formArray['im_path']=array($path);
2414 $found=1;
2415 }
2416 }
2417 if ($dat['gif_capability']=='LZW') {
2418 if (doubleval($dat['convert'])<5 || !$LZW_found) {
2419 $formArray['im_path_lzw']=array($path);
2420 $LZW_found=1;
2421 }
2422 } elseif ($dat['gif_capability']=="RLE" && !$LZW_found) {
2423 $formArray['im_path_lzw']=array($path);
2424 }
2425 $totalArr[]=$path;
2426 }
2427 $formArray['im_path']=array_unique(array_merge($formArray['im_path'],$totalArr));
2428 $formArray['im_path_lzw']=array_unique(array_merge($formArray['im_path_lzw'],$totalArr));
2429 $formArray['im_combine_filename']=array($this->config_array['im_combine_filename']);
2430 } else {
2431 $formArray['im']=array(0);
2432 }
2433 return $formArray;
2434 }
2435
2436 /**
2437 * Returns the part of phpinfo() output that tells about GD library (HTML-code)
2438 *
2439 * @return [type] ...
2440 */
2441 function getGDPartOfPhpinfo() {
2442 ob_start();
2443 phpinfo();
2444 $contents = ob_get_contents();
2445 ob_end_clean();
2446 $start_string = $this->getGD_start_string;
2447 $end_string = $this->getGD_end_string;
2448 list(,$gdpart_tmp) = explode($start_string,$contents,2);
2449 list($gdpart) = explode($end_string,$start_string.$gdpart_tmp,2);
2450 $gdpart.=$end_string;
2451 return $gdpart;
2452 }
2453
2454 /**
2455 * Returns true if TTF lib is install according to phpinfo(). If $phpinfo supply as parameter that string is searched instead.
2456 *
2457 * @param [type] $phpinfo: ...
2458 * @return [type] ...
2459 */
2460 function isTTF($phpinfo='') {
2461 /* $phpinfo = $phpinfo?$phpinfo:$this->getGDPartOfPhpinfo();
2462 if (stristr($phpinfo, $this->getTTF_string)) return 1;
2463 if (stristr($phpinfo, $this->getTTF_string_alt)) return 1;
2464 */
2465
2466 if (!function_exists('imagettftext')) return 0; // Return right away if imageTTFtext does not exist.
2467
2468 // try, print truetype font:
2469 $im = @imagecreate (300, 50);
2470 $background_color = imagecolorallocate ($im, 255, 255, 55);
2471 $text_color = imagecolorallocate ($im, 233, 14, 91);
2472
2473 $test = @imagettftext($im, t3lib_div::freetypeDpiComp(20), 0, 10, 20, $text_color, PATH_t3lib."/fonts/vera.ttf", 'Testing Truetype support');
2474 if (t3lib_div::_GP('testingTrueTypeSupport')) {
2475 if ($this->isGIF()) {
2476 header ('Content-type: image/gif');
2477 imagegif ($im);
2478 } else {
2479 header ('Content-type: image/png');
2480 imagepng ($im);
2481 }
2482 exit;
2483 }
2484 return is_array($test)?1:0;
2485 }
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497 /*****************************************
2498 *
2499 * ABOUT the isXXX functions.
2500 *
2501 * I had a very real experience that these checks DID NOT fail eg PNG support if it didn't exist!
2502 * So first (1) we check if the functions are there. If they ARE we are going to make further investigations (2) by creating an actual image.
2503 * And if THAT succeeds also, then we can be certain of the support!
2504 */
2505
2506 /**
2507 * @return [type] ...
2508 */
2509 function isGD() {
2510 if (function_exists('imagecreate')) {
2511 if (@imagecreate (50, 100)) return 1;
2512 }
2513 }
2514
2515 /**
2516 * [Describe function...]
2517 *
2518 * @return [type] ...
2519 */
2520 function isGIF() {
2521 if (function_exists('imagecreatefromgif') && function_exists('imagegif') && ($this->ImageTypes() & IMG_GIF)) { // If GIF-functions exists, also do a real test of them:
2522 $im = @imagecreatefromgif(t3lib_extMgm::extPath('install').'imgs/jesus.gif');
2523 return $im?1:0;
2524 }
2525 }
2526
2527 /**
2528 * [Describe function...]
2529 *
2530 * @return [type] ...
2531 */
2532 function isJPG() {
2533 if (function_exists('imagecreatefromjpeg') && function_exists('imagejpeg') && ($this->ImageTypes() & IMG_JPG)) {
2534 return 1;
2535 }
2536 }
2537
2538 /**
2539 * [Describe function...]
2540 *
2541 * @return [type] ...
2542 */
2543 function isPNG() {
2544 if (function_exists('imagecreatefrompng') && function_exists('imagepng') && ($this->ImageTypes() & IMG_PNG)) {
2545 $im = imagecreatefrompng(t3lib_extMgm::extPath('install').'imgs/jesus.png');
2546 return $im?1:0;
2547 }
2548 }
2549
2550 /**
2551 * [Describe function...]
2552 *
2553 * @return [type] ...
2554 */
2555 function ImageTypes() {
2556 return imagetypes();
2557 }
2558
2559 /**
2560 * Returns general information about GDlib
2561 *
2562 * @return [type] ...
2563 */
2564 function getGDSoftwareInfo() {
2565 return trim('
2566 You can get GDLib in the PNG version from '.$this->linkIt('http://www.boutell.com/gd/').'.<br />FreeType is for download at '.$this->linkIt('http://www.freetype.org/').'.
2567 Generally, software for TYPO3 is found at '.$this->linkIt('http://typo3.sunsite.dk/software/').' and packages listed at '.$this->linkIt('http://typo3.org/1274.0.html').'.
2568 ');
2569 }
2570
2571 /**
2572 * Returns general information about configuration of TYPO3.
2573 *
2574 * @return [type] ...
2575 */
2576 function generallyAboutConfiguration() {
2577 $out='
2578 Local configuration is done by overriding default values in the included file, typo3conf/localconf.php. In this file you enter the database information along with values in the global array TYPO3_CONF_VARS.
2579 The options in the TYPO3_CONF_VARS array and how to use it for your own purposes is discussed in the base configuration file, t3lib/config_default.php. This file sets up the default values and subsequently includes the localconf.php file in which you can then override values.
2580 See this page for '.$this->linkIt('http://typo3.org/1275.0.html','more information about system requirements.').'
2581 ';
2582 return trim($out);
2583 }
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597 /**********************
2598 *
2599 * IMAGE processing
2600 *
2601 **********************/
2602
2603 /**
2604 * jesus.TIF: IBM/LZW
2605 * jesus.GIF: Save for web, 32 colors
2606 * jesus.JPG: Save for web, 30 quality
2607 * jesus.PNG: Save for web, PNG-24
2608 * jesus.tga 24 bit TGA file
2609 * jesus.pcx
2610 * jesus.bmp 24 bit BMP file
2611 * jesus_ps6.PDF: PDF w/layers and vector data
2612 * typo3logo.ai: Illustrator 8 file
2613 * pdf_from_imagemagick.PDF PDF-file made by Acrobat Distiller from InDesign PS-file
2614 *
2615 *
2616 * Imagemagick
2617 * - Read formats
2618 * - Write png, gif, jpg
2619 *
2620 * Problems may arise from the use of safe_mode (eg. png)
2621 * In safemode you will automatically execute the program convert in the safe_mode_exec_path no matter what other path you specify
2622 * check fileexist before anything...
2623 *
2624 * - compare gif size
2625 * - scaling (by stdgraphic)
2626 * - combining (by stdgraphic)
2627 *
2628 * GDlib:
2629 * - create from:....
2630 * - ttf text
2631 *
2632 * From TypoScript: (GD only, GD+IM, IM)
2633 *
2634 * @return [type] ...
2635 */
2636 function checkTheImageProcessing() {
2637 $this->message('Image Processing','What is it?',"
2638 TYPO3 is known for its ability to process images on the server.
2639 In the backend interface (TBE) thumbnails are automatically generated (by ImageMagick in thumbs.php) as well as icons, menu items and pane tabs (by GDLib).
2640 In the TypoScript enabled frontend all kinds of graphical elements are processed. Typically images are scaled down to fit the pages (by ImageMagick) and menu items, graphical headers and such are generated automatically (by GDLib + ImageMagick).
2641 In addition TYPO3 is able to handle many file formats (thanks to ImageMagick), for example TIF, BMP, PCX, TGA, AI and PDF in addition to the standard web formats; JPG, GIF, PNG.
2642
2643 In order to do this, TYPO3 uses two sets of tools:
2644
2645 <strong>ImageMagick:</strong>
2646 For conversion of non-web formats to webformats, combining images with alpha-masks, performing image-effects like blurring and sharpening.
2647 ImageMagick is a collection of external programs on the server called by the exec() function in PHP. TYPO3 uses three of these, namely 'convert' (converting fileformats, scaling, effects), 'combine'/'composite' (combining images with masks) and 'identify' (returns image information).
2648 Because ImageMagick are external programs, two requirements must be met: 1) The programs must be installed on the server and working and 2) if safe_mode is enabled, the programs must be located in the folder defined by the php.ini setting, <em>safe_mode_exec_dir</em> (else they are not executed).
2649 ImageMagick is available for both Windows and Unix. The current version is 5+, but TYPO3 enthusiasts prefer an old version 4.2.9 because that version has three main advantages: It's faster in some operations, the blur-function works, the sharpen-function works. Anyway you do it, you must tell TYPO3 by configuration whether you're using version 5+ or 4.2.9. (flag: [GFX][im_version_5])
2650 ImageMagick homepage is at ".$this->linkIt('http://www.imagemagick.org/')."
2651
2652 <strong>GDLib:</strong>
2653 For drawing boxes and rendering text on images with truetype fonts. Also used for icons, menuitems and generally the TypoScript GIFBUILDER object is based on GDlib, but extensively utilizing ImageMagick to process intermediate results.
2654 GDLib is accessed through internal functions in PHP, so in this case, you have no safe_mode problems, but you'll need a version of PHP with GDLib compiled in. Also in order to use TrueType fonts with GDLib you'll need FreeType compiled in as well.
2655 ".$this->getGDSoftwareInfo().'
2656
2657 You can disable all image processing options in TYPO3 ([GFX][image_processing]=0), but that would seriously disable TYPO3.
2658 ');
2659
2660 $this->message('Image Processing','Verifying the image processing capabilities of your server',"
2661 This page performs image processing and displays the result. It's a thorough check that everything you've configured is working correctly.
2662 It's quite simple to verify your installation; Just look down the page, the images in pairs should look like each other. If some images are not alike, something is wrong. You may also notice warnings and errors if this tool found signs of any problems.
2663
2664 The image to the right is the reference image (how it should be) and to the left the image made by your server.
2665 The reference images are made with the classic ImageMagick install based on the 4.2.9 RPM and 5.2.3 RPM. If the version 5 flag is set, the reference images are made by the 5.2.3 RPM.
2666
2667 This test will work only if your ImageMagick/GDLib configuration allows it to. The typo3temp/ folder must be writable for all the temporary image files. They are all prefixed 'install_' so they are easy to recognize and delete afterwards.
2668 ");
2669
2670 $im_path = $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_path'];
2671 if ($GLOBALS['TYPO3_CONF_VARS']['GFX']['im_version_5']=='gm') {
2672 $im_path_version = $this->config_array['im_versions'][$im_path]['gm'];
2673 } else {
2674 $im_path_version = $this->config_array['im_versions'][$im_path]['convert'];
2675 }
2676 $im_path_lzw = $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_path_lzw'];
2677 $im_path_lzw_version = $this->config_array['im_versions'][$im_path_lzw]['convert'];
2678 $msg = '
2679 ImageMagick enabled: <strong>'.$GLOBALS['TYPO3_CONF_VARS']['GFX']['im'].'</strong>
2680 ImageMagick path: <strong>'.$im_path.'</strong> ('.$im_path_version.')
2681 ImageMagick path/LZW: <strong>'.$im_path_lzw.'</strong> ('.$im_path_lzw_version.')
2682 Version 5/GraphicsMagick flag: <strong>'.$GLOBALS['TYPO3_CONF_VARS']['GFX']['im_version_5'].'</strong>
2683
2684 GDLib enabled: <strong>'.$GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib'].'</strong>
2685 GDLib using PNG: <strong>'.$GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib_png'].'</strong>
2686 GDLib 2 enabled: <strong>'.$GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib_2'].'</strong>
2687 IM5 effects enabled: <strong>'.$GLOBALS['TYPO3_CONF_VARS']['GFX']['im_v5effects'].'</strong> (Blurring/Sharpening with IM 5+)
2688 Freetype DPI: <strong>'.$GLOBALS['TYPO3_CONF_VARS']['GFX']['TTFdpi'].'</strong> (Should be 96 for Freetype 2)
2689 Mask invert: <strong>'.$GLOBALS['TYPO3_CONF_VARS']['GFX']['im_imvMaskState'].'</strong> (Should be set for some IM versions approx. 5.4+)
2690
2691 File Formats: <strong>'.$GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'].'</strong>
2692 ';
2693
2694 // Various checks to detect IM/GM version mismatches
2695 $mismatch=false;
2696 switch (strtolower($GLOBALS['TYPO3_CONF_VARS']['GFX']['im_version_5'])) {
2697 case 'gm':
2698 if (doubleval($im_path_version)>=2) $mismatch=true;
2699 break;
2700 case 'im4':
2701 if (doubleval($im_path_version)>=5) $mismatch=true;
2702 break;
2703 default:
2704 if (($GLOBALS['TYPO3_CONF_VARS']['GFX']['im_version_5']?true:false) != (doubleval($im_path_version)>=5)) $mismatch=true;
2705 break;
2706 }
2707
2708 if ($mismatch) {
2709 $msg.= 'Warning: Mismatch between the version of ImageMagick'.
2710 ' ('.$im_path_version.') and the configuration of '.