|
TYPO3 API
SVNRelease
|
00001 <?php 00002 /*************************************************************** 00003 * Copyright notice 00004 * 00005 * (c) 1999-2011 Kasper Skårhøj (kasperYYYY@typo3.com) 00006 * All rights reserved 00007 * 00008 * This script is part of the TYPO3 project. The TYPO3 project is 00009 * free software; you can redistribute it and/or modify 00010 * it under the terms of the GNU General Public License as published by 00011 * the Free Software Foundation; either version 2 of the License, or 00012 * (at your option) any later version. 00013 * 00014 * The GNU General Public License can be found at 00015 * http://www.gnu.org/copyleft/gpl.html. 00016 * A copy is found in the textfile GPL.txt and important notices to the license 00017 * from the author is found in LICENSE.txt distributed with these scripts. 00018 * 00019 * 00020 * This script is distributed in the hope that it will be useful, 00021 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00022 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00023 * GNU General Public License for more details. 00024 * 00025 * This copyright notice MUST APPEAR in all copies of the script! 00026 ***************************************************************/ 00027 /** 00028 * Contains the class for the Install Tool 00029 * 00030 * $Id: class.tx_install.php 10389 2011-02-05 09:59:45Z stephenking $ 00031 * 00032 * @author Kasper Skårhøj <kasperYYYY@typo3.com> 00033 * @author Ingmar Schlecht <ingmar@typo3.org> 00034 */ 00035 /** 00036 * [CLASS/FUNCTION INDEX of SCRIPT] 00037 * 00038 * 00039 * 00040 * 162: class tx_install extends t3lib_install 00041 * 234: function tx_install() 00042 * 318: function checkPassword() 00043 * 362: function loginForm() 00044 * 396: function init() 00045 * 574: function stepOutput() 00046 * 836: function checkTheConfig() 00047 * 867: function typo3conf_edit() 00048 * 976: function phpinformation() 00049 * 00050 * SECTION: typo3temp/ manager 00051 * 1079: function typo3TempManager() 00052 * 1199: function getSelectorOptions($deleteType,$tt='') 00053 * 00054 * SECTION: cleanup manager 00055 * 1231: function cleanupManager() 00056 * 00057 * SECTION: CONFIGURATION FORM 00058 * 1299: function generateConfigForm($type='') 00059 * 1367: function getDefaultConfigArrayComments($string,$mainArray=array(),$commentArray=array()) 00060 * 00061 * SECTION: CHECK CONFIGURATION FUNCTIONS 00062 * 1419: function checkConfiguration() 00063 * 1572: function check_mail($cmd='') 00064 * 1611: function checkExtensions() 00065 * 1673: function checkDirs() 00066 * 1762: function checkImageMagick($paths) 00067 * 1837: function _checkImageMagickGifCapability($path) 00068 * 1880: function _checkImageMagick_getVersion($file, $path) 00069 * 1915: function checkDatabase() 00070 * 1977: function setupGeneral($cmd='') 00071 * 2166: function writeToLocalconf_control($lines="", $showOutput=1) 00072 * 2190: function outputExitBasedOnStep($content) 00073 * 2206: function setLabelValueArray($arr,$type) 00074 * 2246: function getFormElement($labels,$values,$fieldName,$default,$msg='') 00075 * 2266: function getDatabaseList() 00076 * 2290: function setupGeneralCalculate() 00077 * 2387: function isTTF() 00078 * 00079 * SECTION: ABOUT the isXXX functions. 00080 * 2436: function isGD() 00081 * 2447: function isGIF() 00082 * 2459: function isJPG() 00083 * 2470: function isPNG() 00084 * 2482: function ImageTypes() 00085 * 2493: function getGDSoftwareInfo() 00086 * 2505: function generallyAboutConfiguration() 00087 * 00088 * SECTION: IMAGE processing 00089 * 2565: function checkTheImageProcessing() 00090 * 3046: function isExtensionEnabled($ext, $headCode, $short) 00091 * 3062: function displayTwinImage ($imageFile, $IMcommands=array(), $note='') 00092 * 3130: function getTwinImageMessage($message, $label_1="", $label_2='') 00093 * 3146: function formatImCmds($arr) 00094 * 3167: function imagemenu() 00095 * 00096 * SECTION: DATABASE analysing 00097 * 3209: function checkTheDatabase() 00098 * 3849: function updateWizard() 00099 * 3873: function updateWizard_parts($action) 00100 * 3987: function getUpgradeObjInstance($className, $identifier) 00101 * 4000: function isBackendAdminUser() 00102 * 4023: function isBasicComplete($tLabel) 00103 * 4063: function generateUpdateDatabaseForm($type, $arr_update, $arr_remove, $action_type) 00104 * 4094: function getUpdateDbFormWrap($action_type, $content, $label='Write to database') 00105 * 4107: function displayFields($arr, $pre=0, $label='') 00106 * 4132: function displayFieldComp($arr, $arr_db) 00107 * 4174: function displaySuggestions($arr, $excludeList='') 00108 * 4204: function compareDatabaseAndTCA($FDsrc, $TCA, $onlyFields=0) 00109 * 4262: function compareTCAandDatabase($TCA, $FDcomp) 00110 * 4296: function suggestFieldDefinition($fieldInfo) 00111 * 4373: function getItemArrayType($arr) 00112 * 4401: function getItemBlobSize($len) 00113 * 4412: function suggestTCAFieldDefinition($fieldName,$fieldInfo) 00114 * 4555: function includeTCA() 00115 * 00116 * SECTION: GENERAL FUNCTIONS 00117 * 4597: function linkIt($url,$link='') 00118 * 4611: function message($head, $short_string='', $long_string='', $type=0, $force=0) 00119 * 4632: function printSection($head, $short_string, $long_string, $type) 00120 * 4673: function fw($str,$size=1) 00121 * 4696: function fwheader($str) 00122 * 4707: function wrapInCells($label,$content) 00123 * 4716: function printAll() 00124 * 4735: function outputWrapper($content) 00125 * 4801: function menu() 00126 * 4823: function stepHeader() 00127 * 4865: function note123() 00128 * 4879: function endNotes() 00129 * 4912: function securityRisk() 00130 * 4930: function alterPasswordForm() 00131 * 4946: function messageBasicFinished() 00132 * 4968: function setScriptName($type) 00133 * 4981: function formWidth($size=48,$textarea=0,$styleOverride='') 00134 * 5002: function formWidthText($size=48,$styleOverride='',$wrap='') 00135 * 5018: function getBackupFilename($filename) 00136 * 00137 * TOTAL FUNCTIONS: 82 00138 * (This index is automatically created/updated by the extension "extdeveval") 00139 * 00140 */ 00141 00142 // include requirements definition: 00143 require_once(t3lib_extMgm::extPath('install') . 'requirements.php'); 00144 00145 // include update classes 00146 require_once(t3lib_extMgm::extPath('install') . 'updates/class.tx_coreupdates_charsetdefaults.php'); 00147 require_once(t3lib_extMgm::extPath('install').'updates/class.tx_coreupdates_compatversion.php'); 00148 require_once(t3lib_extMgm::extPath('install').'updates/class.tx_coreupdates_cscsplit.php'); 00149 require_once(t3lib_extMgm::extPath('install').'updates/class.tx_coreupdates_notinmenu.php'); 00150 require_once(t3lib_extMgm::extPath('install').'updates/class.tx_coreupdates_mergeadvanced.php'); 00151 require_once(t3lib_extMgm::extPath('install').'updates/class.tx_coreupdates_installsysexts.php'); 00152 require_once(t3lib_extMgm::extPath('install').'updates/class.tx_coreupdates_imagescols.php'); 00153 require_once(t3lib_extMgm::extPath('install').'updates/class.tx_coreupdates_installnewsysexts.php'); 00154 require_once(t3lib_extMgm::extPath('install') . 'mod/class.tx_install_session.php'); 00155 require_once(t3lib_extMgm::extPath('install') . 'updates/class.tx_coreupdates_statictemplates.php'); 00156 require_once(t3lib_extMgm::extPath('install') . 'updates/class.tx_coreupdates_t3skin.php'); 00157 require_once(t3lib_extMgm::extPath('install') . 'updates/class.tx_coreupdates_compressionlevel.php'); 00158 require_once(t3lib_extMgm::extPath('install') . 'updates/class.tx_coreupdates_migrateworkspaces.php'); 00159 require_once(t3lib_extMgm::extPath('install') . 'updates/class.tx_coreupdates_flagsfromsprite.php'); 00160 require_once(t3lib_extMgm::extPath('install') . 'updates/class.tx_coreupdates_addflexformstoacl.php'); 00161 require_once(t3lib_extMgm::extPath('install') . 'updates/class.tx_coreupdates_imagelink.php'); 00162 00163 /** 00164 * Install Tool module 00165 * 00166 * $Id: class.tx_install.php 10389 2011-02-05 09:59:45Z stephenking $ 00167 * 00168 * @author Kasper Skårhøj <kasperYYYY@typo3.com> 00169 * @author Ingmar Schlecht <ingmar@typo3.org> 00170 * @package TYPO3 00171 * @subpackage tx_install 00172 */ 00173 class tx_install extends t3lib_install { 00174 var $templateFilePath = 'typo3/sysext/install/Resources/Private/Templates/'; 00175 var $template; 00176 var $javascript; 00177 var $stylesheets; 00178 var $markers = array(); 00179 var $messages = array(); 00180 var $errorMessages = array(); 00181 var $mailMessage = ''; 00182 var $action = ''; // The url that calls this script 00183 var $scriptSelf = 'index.php'; // The url that calls this script 00184 var $updateIdentity = 'TYPO3 Install Tool'; 00185 var $headerStyle =''; 00186 var $setAllCheckBoxesByDefault=0; 00187 00188 var $allowFileEditOutsite_typo3conf_dir=0; 00189 00190 var $INSTALL =array(); // In constructor: is set to global GET/POST var TYPO3_INSTALL 00191 var $checkIMlzw = 0; // If set, lzw capabilities of the available ImageMagick installs are check by actually writing a gif-file and comparing size 00192 var $checkIM = 0; // If set, ImageMagick is checked. 00193 var $dumpImCommands=1; // If set, the image Magick commands are always outputted in the image processing checker 00194 var $mode = ''; // If set to "123" then only most vital information is displayed. 00195 var $step = 0; // If set to 1,2,3 or GO it signifies various functions. 00196 var $totalSteps = 4; // Can be changed by hook to define the total steps in 123 mode 00197 00198 // internal 00199 var $passwordOK=0; // This is set, if the password check was ok. The function init() will exit if this is not set 00200 var $silent=1; // If set, the check routines don't add to the message-array 00201 var $sections=array(); // Used to gather the message information. 00202 var $fatalError=0; // This is set if some error occured that will definitely prevent TYpo3 from running. 00203 var $sendNoCacheHeaders=1; 00204 var $config_array = array( // Flags are set in this array if the options are available and checked ok. 00205 'gd'=>0, 00206 'gd_gif'=>0, 00207 'gd_png'=>0, 00208 'gd_jpg'=>0, 00209 'freetype' => 0, 00210 'safemode' => 0, 00211 'dir_typo3temp' => 0, 00212 'dir_temp' => 0, 00213 'im_versions' => array(), 00214 'im' => 0, 00215 'sql.safe_mode_user' => '', 00216 'mysqlConnect' => 0, 00217 'no_database' => 0 00218 ); 00219 var $typo3temp_path=''; 00220 /** 00221 * the session handling object 00222 * 00223 * @var tx_install_session 00224 */ 00225 protected $session = NULL; 00226 00227 /** 00228 * the form protection instance used for creating and verifying form tokens 00229 * 00230 * @var t3lib_formprotection_InstallToolFormProtection 00231 */ 00232 protected $formProtection = NULL; 00233 00234 var $menuitems = array( 00235 'config' => 'Basic Configuration', 00236 'database' => 'Database Analyser', 00237 'update' => 'Upgrade Wizard', 00238 'images' => 'Image Processing', 00239 'extConfig' => 'All Configuration', 00240 'cleanup' => 'Clean up', 00241 'phpinfo' => 'phpinfo()', 00242 'typo3conf_edit' => 'Edit files in typo3conf/', 00243 'about' => 'About', 00244 'logout' => 'Logout from Install Tool', 00245 ); 00246 00247 // PHP modules which are required. Can be changed by hook in getMissingPhpModules() 00248 protected $requiredPhpModules = array( 00249 'filter', 00250 'gd', 00251 'json', 00252 'mysql', 00253 'pcre', 00254 'session', 00255 'SPL', 00256 'standard', 00257 'xml', 00258 'zlib' 00259 ); 00260 00261 00262 00263 00264 00265 /** 00266 * Constructor 00267 * 00268 * @return void 00269 */ 00270 function tx_install() { 00271 parent::t3lib_install(); 00272 00273 if (!$GLOBALS['TYPO3_CONF_VARS']['BE']['installToolPassword']) { 00274 $this->outputErrorAndExit('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\';', 'Fatal error'); 00275 } 00276 00277 if ($this->sendNoCacheHeaders) { 00278 header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); 00279 header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); 00280 header('Expires: 0'); 00281 header('Cache-Control: no-cache, must-revalidate'); 00282 header('Pragma: no-cache'); 00283 } 00284 00285 // **************************** 00286 // Initializing incoming vars. 00287 // **************************** 00288 $this->INSTALL = t3lib_div::_GP('TYPO3_INSTALL'); 00289 $this->mode = t3lib_div::_GP('mode'); 00290 if ($this->mode !== '123') { 00291 $this->mode = ''; 00292 } 00293 if (t3lib_div::_GP('step') === 'go') { 00294 $this->step = 'go'; 00295 } else { 00296 $this->step = intval(t3lib_div::_GP('step')); 00297 } 00298 00299 // Let DBAL decide whether to load itself 00300 $dbalLoaderFile = $this->backPath . 'sysext/dbal/class.tx_dbal_autoloader.php'; 00301 if (@is_file($dbalLoaderFile)) { 00302 include($dbalLoaderFile); 00303 } 00304 00305 if ($this->mode === '123') { 00306 // Check for mandatory PHP modules 00307 $missingPhpModules = $this->getMissingPhpModules(); 00308 if (count($missingPhpModules) > 0) { 00309 throw new RuntimeException('TYPO3 Installation Error: The following PHP module(s) is/are missing: <em>' . 00310 implode(', ', $missingPhpModules) . 00311 '</em><br /><br />You need to install and enable these modules first to be able to install TYPO3.' 00312 ); 00313 } 00314 } 00315 $this->redirect_url = t3lib_div::sanitizeLocalUrl(t3lib_div::_GP('redirect_url')); 00316 00317 $this->INSTALL['type'] = ''; 00318 if ($_GET['TYPO3_INSTALL']['type']) { 00319 $allowedTypes = array( 00320 'config', 'database', 'update', 'images', 'extConfig', 00321 'cleanup', 'phpinfo', 'typo3conf_edit', 'about', 'logout' 00322 ); 00323 00324 if (in_array($_GET['TYPO3_INSTALL']['type'], $allowedTypes)) { 00325 $this->INSTALL['type'] = $_GET['TYPO3_INSTALL']['type']; 00326 } 00327 } 00328 00329 if ($this->step == 4) { 00330 $this->INSTALL['type'] = 'database'; 00331 } 00332 00333 // Hook to raise the counter for the total steps in the 1-2-3 installer 00334 if (is_array ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install/mod/class.tx_install.php']['additionalSteps'])) { 00335 foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install/mod/class.tx_install.php']['additionalSteps'] as $classData) { 00336 $hookObject = t3lib_div::getUserObj($classData); 00337 $this->totalSteps += (integer) $hookObject->executeAdditionalSteps($this); 00338 } 00339 } 00340 00341 if ($this->mode=='123') { 00342 $tempItems = $this->menuitems; 00343 $this->menuitems = array( 00344 'config' => $tempItems['config'], 00345 'database' => $tempItems['database'] 00346 ); 00347 if (!$this->INSTALL['type'] || !isset($this->menuitems[$this->INSTALL['type']])) { 00348 $this->INSTALL['type'] = 'config'; 00349 } 00350 } else { 00351 if (!$this->INSTALL['type'] || !isset($this->menuitems[$this->INSTALL['type']])) { 00352 $this->INSTALL['type'] = 'about'; 00353 } 00354 } 00355 00356 $this->action = $this->scriptSelf . 00357 '?TYPO3_INSTALL[type]=' . $this->INSTALL['type'] . 00358 ($this->mode? '&mode=' . $this->mode : '') . 00359 ($this->step? '&step=' . $this->step : ''); 00360 $this->typo3temp_path = PATH_site.'typo3temp/'; 00361 if (!is_dir($this->typo3temp_path) || !is_writeable($this->typo3temp_path)) { 00362 $this->outputErrorAndExit('Install Tool needs to write to typo3temp/. Make sure this directory is writeable by your webserver: ' . htmlspecialchars($this->typo3temp_path), 'Fatal error'); 00363 } 00364 00365 try { 00366 $this->session = t3lib_div::makeInstance('tx_install_session'); 00367 } catch (Exception $exception) { 00368 $this->outputErrorAndExit($exception->getMessage()); 00369 } 00370 00371 // ******************* 00372 // Check authorization 00373 // ******************* 00374 if (!$this->session->hasSession()) { 00375 $this->session->startSession(); 00376 } 00377 00378 if ($this->session->isAuthorized() || $this->checkPassword()) { 00379 $this->passwordOK=1; 00380 $this->session->refreshSession(); 00381 00382 $enableInstallToolFile = PATH_typo3conf . 'ENABLE_INSTALL_TOOL'; 00383 if (is_file ($enableInstallToolFile)) { 00384 // Extend the age of the ENABLE_INSTALL_TOOL file by one hour 00385 @touch($enableInstallToolFile); 00386 } 00387 00388 if($this->redirect_url) { 00389 t3lib_utility_Http::redirect($this->redirect_url); 00390 } 00391 00392 $this->formProtection = t3lib_formProtection_Factory::get( 00393 't3lib_formprotection_InstallToolFormProtection' 00394 ); 00395 $this->formProtection->injectInstallTool($this); 00396 } else { 00397 $this->loginForm(); 00398 } 00399 } 00400 00401 /** 00402 * Returns true if submitted password is ok. 00403 * 00404 * If password is ok, set session as "authorized". 00405 * 00406 * @return boolean true if the submitted password was ok and session was 00407 * authorized, false otherwise 00408 */ 00409 function checkPassword() { 00410 $p = t3lib_div::_GP('password'); 00411 00412 if ($p && md5($p)==$GLOBALS['TYPO3_CONF_VARS']['BE']['installToolPassword']) { 00413 $this->session->setAuthorized(); 00414 00415 // Sending warning email 00416 $wEmail = $GLOBALS['TYPO3_CONF_VARS']['BE']['warning_email_addr']; 00417 if ($wEmail) { 00418 $subject="Install Tool Login at '".$GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename']."'"; 00419 $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').')'; 00420 mail($wEmail, 00421 $subject, 00422 $email_body, 00423 'From: TYPO3 Install Tool WARNING <>' 00424 ); 00425 } 00426 return true; 00427 } else { 00428 // Bad password, send warning: 00429 if ($p) { 00430 $wEmail = $GLOBALS['TYPO3_CONF_VARS']['BE']['warning_email_addr']; 00431 if ($wEmail) { 00432 $subject="Install Tool Login ATTEMPT at '".$GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename']."'"; 00433 $email_body="There has been an Install Tool login attempt at TYPO3 site '".$GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename']."' (".t3lib_div::getIndpEnv('HTTP_HOST')."). 00434 The MD5 hash of the last 5 characters of the password tried was '".substr(md5($p), -5)."' 00435 REMOTE_ADDR was '".t3lib_div::getIndpEnv('REMOTE_ADDR')."' (".t3lib_div::getIndpEnv('REMOTE_HOST').')'; 00436 mail($wEmail, 00437 $subject, 00438 $email_body, 00439 'From: TYPO3 Install Tool WARNING <>' 00440 ); 00441 } 00442 } 00443 return false; 00444 } 00445 } 00446 00447 /** 00448 * Create the HTML for the login form 00449 * 00450 * Reads and fills the template. 00451 * Substitutes subparts when wrong password has been given 00452 * or the session has expired 00453 * 00454 * @return void 00455 */ 00456 function loginForm() { 00457 $password = t3lib_div::_GP('password'); 00458 $redirect_url = $this->redirect_url ? $this->redirect_url : $this->action; 00459 // Get the template file 00460 $templateFile = @file_get_contents( 00461 PATH_site . $this->templateFilePath . 'LoginForm.html' 00462 ); 00463 // Get the template part from the file 00464 $template = t3lib_parsehtml::getSubpart( 00465 $templateFile, '###TEMPLATE###' 00466 ); 00467 // Password has been given, but this form is rendered again. 00468 // This means the given password was wrong 00469 if (!empty($password)) { 00470 // Get the subpart for the wrong password 00471 $wrongPasswordSubPart = t3lib_parsehtml::getSubpart( 00472 $template, '###WRONGPASSWORD###' 00473 ); 00474 // Define the markers content 00475 $wrongPasswordMarkers = array( 00476 'passwordMessage' => 'The password you just tried has this md5-value:', 00477 'password' => md5($password) 00478 ); 00479 // Fill the markers in the subpart 00480 $wrongPasswordSubPart = t3lib_parsehtml::substituteMarkerArray( 00481 $wrongPasswordSubPart, 00482 $wrongPasswordMarkers, 00483 '###|###', 00484 TRUE, 00485 TRUE 00486 ); 00487 } 00488 // Session has expired 00489 if (!$this->session->isAuthorized() && $this->session->isExpired()) { 00490 // Get the subpart for the expired session message 00491 $sessionExpiredSubPart = t3lib_parsehtml::getSubpart( 00492 $template, '###SESSIONEXPIRED###' 00493 ); 00494 // Define the markers content 00495 $sessionExpiredMarkers = array( 00496 'message' => 'Your Install Tool session has expired' 00497 ); 00498 // Fill the markers in the subpart 00499 $sessionExpiredSubPart = t3lib_parsehtml::substituteMarkerArray( 00500 $sessionExpiredSubPart, 00501 $sessionExpiredMarkers, 00502 '###|###', 00503 TRUE, 00504 TRUE 00505 ); 00506 } 00507 // Substitute the subpart for the expired session in the template 00508 $template = t3lib_parsehtml::substituteSubpart( 00509 $template, 00510 '###SESSIONEXPIRED###', 00511 $sessionExpiredSubPart 00512 ); 00513 // Substitute the subpart for the wrong password in the template 00514 $template = t3lib_parsehtml::substituteSubpart( 00515 $template, 00516 '###WRONGPASSWORD###', 00517 $wrongPasswordSubPart 00518 ); 00519 // Define the markers content 00520 $markers = array( 00521 'siteName' => 'Site: ' . 00522 htmlspecialchars($GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename']), 00523 'headTitle' => 'Login to TYPO3 ' . TYPO3_version . ' Install Tool', 00524 'redirectUrl' => htmlspecialchars($redirect_url), 00525 'enterPassword' => 'Password', 00526 'login' => 'Login', 00527 'message' => ' 00528 <p class="typo3-message message-information"> 00529 The Install Tool Password is <em>not</em> the admin password 00530 of TYPO3. 00531 <br /> 00532 The default password is <em>joh316</em>. Be sure to change it! 00533 <br /><br /> 00534 If you don\'t know the current password, you can set a new 00535 one by setting the value of 00536 $TYPO3_CONF_VARS[\'BE\'][\'installToolPassword\'] in 00537 typo3conf/localconf.php to the md5() hash value of the 00538 password you desire. 00539 </p> 00540 ' 00541 ); 00542 // Fill the markers in the template 00543 $content = t3lib_parsehtml::substituteMarkerArray( 00544 $template, 00545 $markers, 00546 '###|###', 00547 TRUE, 00548 TRUE 00549 ); 00550 00551 // Send content to the page wrapper function 00552 $this->output($this->outputWrapper($content)); 00553 } 00554 00555 /** 00556 * Calling function that checks system, IM, GD, dirs, database 00557 * and lets you alter localconf.php 00558 * 00559 * This method is called from init.php to start the Install Tool. 00560 * 00561 * @return void 00562 */ 00563 function init() { 00564 // Must be called after inclusion of init.php (or from init.php) 00565 if (!defined('PATH_typo3')) exit; 00566 if (!$this->passwordOK) exit; 00567 00568 // Setting stuff... 00569 $this->check_mail(); 00570 $this->setupGeneral(); 00571 $this->generateConfigForm(); 00572 if (count($this->messages)) { 00573 t3lib_div::debug($this->messages); 00574 } 00575 00576 if ($this->step) { 00577 $this->output($this->outputWrapper($this->stepOutput())); 00578 } else { 00579 00580 // Menu... 00581 switch($this->INSTALL['type']) { 00582 case 'images': 00583 $this->checkIM=1; 00584 $this->checkTheConfig(); 00585 $this->silent=0; 00586 $this->checkTheImageProcessing(); 00587 break; 00588 case 'database': 00589 $this->checkTheConfig(); 00590 $this->silent=0; 00591 $this->checkTheDatabase(); 00592 break; 00593 case 'update': 00594 $this->checkDatabase(); 00595 $this->silent=0; 00596 $this->updateWizard(); 00597 break; 00598 case 'config': 00599 $this->silent=0; 00600 $this->checkIM=1; 00601 $this->message( 00602 'About configuration', 00603 'How to configure TYPO3', 00604 $this->generallyAboutConfiguration() 00605 ); 00606 $this->message( 00607 'System Information', 00608 'Your system has the following configuration', 00609 ' 00610 <dl id="systemInformation"> 00611 <dt>OS detected:</dt> 00612 <dd>' . (TYPO3_OS == 'WIN' ? 'WIN' : 'UNIX') .'</dd> 00613 <dt>UNIX/CGI detected:</dt> 00614 <dd>' . (PHP_SAPI == 'cgi' ? 'YES' : 'NO') . '</dd> 00615 <dt>PATH_thisScript:</dt> 00616 <dd>' . PATH_thisScript . '</dd> 00617 </dl> 00618 ' 00619 ); 00620 $this->checkTheConfig(); 00621 00622 $ext = 'Write config to localconf.php'; 00623 if ($this->fatalError) { 00624 if ( 00625 $this->config_array['no_database'] || 00626 !$this->config_array['mysqlConnect'] 00627 ) { 00628 $this->message($ext, 'Database not configured yet!', ' 00629 <p> 00630 You need to specify database username, 00631 password and host as one of the first things. 00632 <br /> 00633 Next you\'ll have to select a database to 00634 use with TYPO3. 00635 </p> 00636 <p> 00637 Use the form below. 00638 </p> 00639 ', 2); 00640 } else { 00641 $this->message($ext, 'Fatal error encountered!', ' 00642 <p> 00643 Somewhere above a fatal configuration 00644 problem is encountered. 00645 Please make sure that you\'ve fixed this 00646 error before you submit the configuration. 00647 TYPO3 will not run if this problem is not 00648 fixed! 00649 <br /> 00650 You should also check all warnings that may 00651 appear. 00652 </p> 00653 ', 2); 00654 } 00655 } elseif ($this->mode=='123') { 00656 if (!$this->fatalError) { 00657 $this->message($ext, 'Basic configuration completed', ' 00658 <p> 00659 You have no fatal errors in your basic 00660 configuration. 00661 You may have warnings though. Please pay 00662 attention to them! 00663 However you may continue and install the 00664 database. 00665 </p> 00666 <p> 00667 <strong> 00668 <span style="color:#f00;">Step 2: </span> 00669 </strong> 00670 <a href="' . $this->scriptSelf . 00671 '?TYPO3_INSTALL[type]=database' . 00672 ($this->mode ? '&mode=' . rawurlencode($this->mode) : '') . 00673 '">Click here to install the database.</a> 00674 </p> 00675 ', -1, 1); 00676 } 00677 } 00678 $this->message($ext, 'Very Important: Changing Image Processing settings', ' 00679 <p> 00680 When you change the settings for Image Processing 00681 you <em>must</em> take into account 00682 that <em>old images</em> may still be in typo3temp/ 00683 folder and prevent new files from being generated! 00684 <br /> 00685 This is especially important to know, if you\'re 00686 trying to set up image processing for the very first 00687 time. 00688 <br /> 00689 The problem is solved by <a href="' . 00690 htmlspecialchars($this->setScriptName('cleanup')) . 00691 '">clearing the typo3temp/ folder</a>. 00692 Also make sure to clear the cache_pages table. 00693 </p> 00694 ', 1, 1); 00695 $this->message($ext, 'Very Important: Changing Encryption Key setting', ' 00696 <p> 00697 When you change the setting for the Encryption Key 00698 you <em>must</em> take into account that a change to 00699 this value might invalidate temporary information, 00700 URLs etc. 00701 <br /> 00702 The problem is solved by <a href="' . 00703 htmlspecialchars($this->setScriptName('cleanup')) . 00704 '">clearing the typo3temp/ folder</a>. 00705 Also make sure to clear the cache_pages table. 00706 </p> 00707 ', 1, 1); 00708 $this->message($ext, 'Update localconf.php', ' 00709 <p> 00710 This form updates the localconf.php file with the 00711 suggested values you see below. The values are based 00712 on the analysis above. 00713 <br /> 00714 You can change the values in case you have 00715 alternatives to the suggested defaults. 00716 <br /> 00717 By this final step you will configure TYPO3 for 00718 immediate use provided that you have no fatal errors 00719 left above. 00720 </p>' . $this->setupGeneral('get_form') . ' 00721 ', 0, 1); 00722 00723 $this->output($this->outputWrapper($this->printAll())); 00724 00725 break; 00726 case 'extConfig': 00727 $this->silent=0; 00728 $this->generateConfigForm('get_form'); 00729 // Get the template file 00730 $templateFile = @file_get_contents( 00731 PATH_site . $this->templateFilePath . 'InitExtConfig.html' 00732 ); 00733 // Get the template part from the file 00734 $template = t3lib_parsehtml::getSubpart( 00735 $templateFile, '###TEMPLATE###' 00736 ); 00737 // Define the markers content 00738 $markers = array( 00739 'action' => $this->action, 00740 'content' => $this->printAll(), 00741 'write' => 'Write to localconf.php', 00742 'notice' => 'NOTICE:', 00743 'explanation' => ' 00744 By clicking this button, localconf.php is updated 00745 with new values for the parameters listed above! 00746 ' 00747 ); 00748 // Fill the markers in the template 00749 $content = t3lib_parsehtml::substituteMarkerArray( 00750 $template, 00751 $markers, 00752 '###|###', 00753 TRUE, 00754 FALSE 00755 ); 00756 // Send content to the page wrapper function 00757 $this->output($this->outputWrapper($content)); 00758 break; 00759 case 'cleanup': 00760 $this->checkTheConfig(); 00761 $this->silent=0; 00762 $this->cleanupManager(); 00763 break; 00764 case 'phpinfo': 00765 $this->silent=0; 00766 $this->phpinformation(); 00767 break; 00768 case 'typo3conf_edit': 00769 $this->silent=0; 00770 $this->typo3conf_edit(); 00771 break; 00772 case 'logout': 00773 $enableInstallToolFile = PATH_site . 'typo3conf/ENABLE_INSTALL_TOOL'; 00774 if (is_file($enableInstallToolFile) && trim(file_get_contents($enableInstallToolFile)) !== 'KEEP_FILE') { 00775 unlink(PATH_typo3conf . 'ENABLE_INSTALL_TOOL'); 00776 } 00777 $this->formProtection->clean(); 00778 $this->session->destroySession(); 00779 t3lib_utility_Http::redirect($this->scriptSelf); 00780 break; 00781 case 'about': 00782 default: 00783 $this->silent=0; 00784 $this->message('About', 'Warning - very important!', $this->securityRisk().$this->alterPasswordForm(),2); 00785 00786 $this->message('About', 'Using this script', ' 00787 <p> 00788 Installing TYPO3 has always been a hot topic on the 00789 mailing list and forums. Therefore we\'ve developed 00790 this tool which will help you through configuration 00791 and testing. 00792 <br /> 00793 There are three primary steps for you to take: 00794 </p> 00795 <p> 00796 <strong>1: Basic Configuration</strong> 00797 <br /> 00798 In this step your PHP-configuration is checked. If 00799 there are any settings that will prevent TYPO3 from 00800 running correctly you\'ll get warnings and errors 00801 with a description of the problem. 00802 <br /> 00803 You\'ll have to enter a database username, password 00804 and hostname. Then you can choose to create a new 00805 database or select an existing one. 00806 <br /> 00807 Finally the image processing settings are entered 00808 and verified and you can choose to let the script 00809 update the configuration file, 00810 typo3conf/localconf.php with the suggested settings. 00811 </p> 00812 <p> 00813 <strong>2: Database Analyser</strong> 00814 <br /> 00815 In this step you can either install a new database 00816 or update the database from any previous TYPO3 00817 version. 00818 <br /> 00819 You can also get an overview of extra/missing 00820 fields/tables in the database compared to a raw 00821 sql-file. 00822 <br /> 00823 The database is also verified against your 00824 \'tables.php\' configuration ($TCA) and you can 00825 even see suggestions to entries in $TCA or new 00826 fields in the database. 00827 </p> 00828 <p> 00829 <strong>3: Upgrade Wizard</strong> 00830 <br /> 00831 Here you will find update methods taking care of 00832 changes to the TYPO3 core which are not backwards 00833 compatible. 00834 <br /> 00835 It is recommended to run this wizard after every 00836 update to make sure everything will still work 00837 flawlessly. 00838 </p> 00839 <p> 00840 <strong>4: Image Processing</strong> 00841 <br /> 00842 This step is a visual guide to verify your 00843 configuration of the image processing software. 00844 <br /> 00845 You\'ll be presented to a list of images that should 00846 all match in pairs. If some irregularity appears, 00847 you\'ll get a warning. Thus you\'re able to track an 00848 error before you\'ll discover it on your website. 00849 </p> 00850 <p> 00851 <strong>5: All Configuration</strong> 00852 <br /> 00853 This gives you access to any of the configuration 00854 options in the TYPO3_CONF_VARS array. Every option 00855 is also presented with a comment explaining what it 00856 does. 00857 </p> 00858 <p> 00859 <strong>6: Cleanup</strong> 00860 <br /> 00861 Here you can clean up the temporary files in typo3temp/ 00862 folder and the tables used for caching of data in 00863 your database. 00864 </p> 00865 '); 00866 00867 $this->message('About', 'Why is this script stand-alone?', ' 00868 <p> 00869 You would think that this script should rather be a 00870 module in the backend and access-controlled to only 00871 admin-users from the database. But that\'s not how 00872 it works. 00873 <br /> 00874 The reason is, that this script must not be 00875 depending on the success of the configuration of 00876 TYPO3 and whether or not there is a working database 00877 behind. Therefore the script is invoked from the 00878 backend init.php file, which allows access if the 00879 constant \'TYPO3_enterInstallScript\' has been 00880 defined and is not false. That is and should be the 00881 case <em>only</em> when calling the script 00882 \'typo3/install/index.php\' - this script! 00883 </p> 00884 '); 00885 00886 00887 $headCode='Header legend'; 00888 $this->message($headCode, 'Notice!', ' 00889 <p> 00890 Indicates that something is important to be aware 00891 of. 00892 <br /> 00893 This does <em>not</em> indicate an error. 00894 </p> 00895 ', 1); 00896 $this->message($headCode, 'Just information', ' 00897 <p> 00898 This is a simple message with some information about 00899 something. 00900 </p> 00901 '); 00902 $this->message($headCode, 'Check was successful', ' 00903 <p> 00904 Indicates that something was checked and returned an 00905 expected result. 00906 </p> 00907 ', -1); 00908 $this->message($headCode, 'Warning!', ' 00909 <p> 00910 Indicates that something may very well cause trouble 00911 and you should definitely look into it before 00912 proceeding. 00913 <br /> 00914 This indicates a <em>potential</em> error. 00915 </p> 00916 ', 2); 00917 $this->message($headCode, 'Error!', ' 00918 <p> 00919 Indicates that something is definitely wrong and 00920 that TYPO3 will most likely not perform as expected 00921 if this problem is not solved. 00922 <br /> 00923 This indicates an actual error. 00924 </p> 00925 ', 3); 00926 00927 $this->output($this->outputWrapper($this->printAll())); 00928 break; 00929 } 00930 } 00931 00932 $this->formProtection->persistTokens(); 00933 } 00934 00935 /** 00936 * Controls the step 1-2-3-go process 00937 * 00938 * @return string The content to output to the screen 00939 */ 00940 function stepOutput() { 00941 // Get the template file 00942 $templateFile = @file_get_contents( 00943 PATH_site . $this->templateFilePath . 'StepOutput.html' 00944 ); 00945 // Get the template part from the file 00946 $template = t3lib_parsehtml::getSubpart( 00947 $templateFile, '###TEMPLATE###' 00948 ); 00949 // Define the markers content 00950 $markers = array( 00951 'stepHeader' => $this->stepHeader(), 00952 'notice' => 'Skip this wizard (for power users only)', 00953 'skip123' => $this->scriptSelf 00954 ); 00955 00956 $this->checkTheConfig(); 00957 $error_missingConnect = ' 00958 <p class="typo3-message message-error"> 00959 <strong> 00960 There is no connection to the database! 00961 </strong> 00962 <br /> 00963 (Username: <em>' . htmlspecialchars(TYPO3_db_username) . '</em>, 00964 Host: <em>' . htmlspecialchars(TYPO3_db_host) . '</em>, 00965 Using Password: YES) 00966 <br /> 00967 Go to Step 1 and enter a valid username and password! 00968 </p> 00969 '; 00970 $error_missingDB = ' 00971 <p class="typo3-message message-error"> 00972 <strong> 00973 There is no access to the database (<em>' . htmlspecialchars(TYPO3_db) . '</em>)! 00974 </strong> 00975 <br /> 00976 Go to Step 2 and select a valid database! 00977 </p> 00978 '; 00979 00980 // only get the number of tables if it is not the first two steps in the 123-installer 00981 // (= no DB connection yet) 00982 $whichTables = ($this->step != 1 && $this->step != 2 ? $this->getListOfTables() : array()); 00983 00984 $error_emptyDB = ' 00985 <p class="typo3-message message-error"> 00986 <strong> 00987 The database is still empty. There are no tables! 00988 </strong> 00989 <br /> 00990 Go to Step 3 and import a database! 00991 </p> 00992 '; 00993 00994 // Hook to override and add steps to the 1-2-3 installer 00995 if (is_array ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install/mod/class.tx_install.php']['stepOutput'])) { 00996 foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install/mod/class.tx_install.php']['stepOutput'] as $classData) { 00997 $hookObject = t3lib_div::getUserObj($classData); 00998 $hookObject->executeStepOutput($markers, $this->step, $this); 00999 } 01000 } 01001 // Use the default steps when there is no override 01002 if (!$markers['header'] && !$markers['step']) { 01003 switch(strtolower($this->step)) { 01004 case 1: 01005 // Get the subpart for the first step 01006 $step1SubPart = t3lib_parsehtml::getSubpart( 01007 $templateFile, '###STEP1###' 01008 ); 01009 // Add header marker for main template 01010 $markers['header'] = 'Welcome to the TYPO3 Install Tool'; 01011 // Define the markers content for the subpart 01012 $step1SubPartMarkers = array( 01013 'llIntroduction' => ' 01014 <p> 01015 TYPO3 is an enterprise content management system 01016 that is powerful, yet easy to install. 01017 </p> 01018 <p> 01019 In three simple steps you\'ll be ready to add content to your website. 01020 </p> 01021 ', 01022 'step' => $this->step + 1, 01023 'action' => htmlspecialchars($this->action), 01024 'continue' => 'Continue' 01025 ); 01026 // Add step marker for main template 01027 $markers['step'] = t3lib_parsehtml::substituteMarkerArray( 01028 $step1SubPart, 01029 $step1SubPartMarkers, 01030 '###|###', 01031 TRUE, 01032 FALSE 01033 ); 01034 break; 01035 case 2: 01036 // Get the subpart for the second step 01037 $step2SubPart = t3lib_parsehtml::getSubpart( 01038 $templateFile, '###STEP2###' 01039 ); 01040 // Add header marker for main template 01041 $markers['header'] = 'Connect to your database host'; 01042 // Define the markers content for the subpart 01043 $step2SubPartMarkers = array( 01044 'step' => $this->step + 1, 01045 'action' => htmlspecialchars($this->action), 01046 'encryptionKey' => $this->createEncryptionKey(), 01047 'branch' => TYPO3_branch, 01048 'labelUsername' => 'Username', 01049 'username' => htmlspecialchars(TYPO3_db_username), 01050 'labelPassword' => 'Password', 01051 'password' => htmlspecialchars(TYPO3_db_password), 01052 'labelHost' => 'Host', 01053 'host' => TYPO3_db_host ? htmlspecialchars(TYPO3_db_host) : 'localhost', 01054 'continue' => 'Continue', 01055 'llDescription' => 'If you have not already created a username and password to access the database, please do so now. This can be done using tools provided by your host.' 01056 ); 01057 // Add step marker for main template 01058 $markers['step'] = t3lib_parsehtml::substituteMarkerArray( 01059 $step2SubPart, 01060 $step2SubPartMarkers, 01061 '###|###', 01062 TRUE, 01063 FALSE 01064 ); 01065 break; 01066 case 3: 01067 // Add header marker for main template 01068 $markers['header'] = 'Select database'; 01069 // There should be a database host connection at this point 01070 if ($result = $GLOBALS['TYPO3_DB']->sql_pconnect( 01071 TYPO3_db_host, TYPO3_db_username, TYPO3_db_password 01072 )) { 01073 // Get the subpart for the third step 01074 $step3SubPart = t3lib_parsehtml::getSubpart( 01075 $templateFile, '###STEP3###' 01076 ); 01077 // Get the subpart for the database options 01078 $step3DatabaseOptionsSubPart = t3lib_parsehtml::getSubpart( 01079 $step3SubPart, '###DATABASEOPTIONS###' 01080 ); 01081 01082 $dbArr = $this->getDatabaseList(); 01083 $dbIncluded = 0; 01084 $step3DatabaseOptions = array(); 01085 foreach ($dbArr as $dbname) { 01086 // Define the markers content for database options 01087 $step3DatabaseOptionMarkers = array( 01088 'databaseValue' => htmlspecialchars($dbname), 01089 'databaseSelected' => $dbname == TYPO3_db ? 'selected="selected"' : '', 01090 'databaseName' => htmlspecialchars($dbname) 01091 ); 01092 // Add the option HTML to an array 01093 $step3DatabaseOptions[] = t3lib_parsehtml::substituteMarkerArray( 01094 $step3DatabaseOptionsSubPart, 01095 $step3DatabaseOptionMarkers, 01096 '###|###', 01097 TRUE, 01098 TRUE 01099 ); 01100 if ($dbname==TYPO3_db) $dbIncluded=1; 01101 } 01102 if (!$dbIncluded && TYPO3_db) { 01103 // // Define the markers content when no access 01104 $step3DatabaseOptionMarkers = array( 01105 'databaseValue' => htmlspecialchars(TYPO3_db), 01106 'databaseSelected' => 'selected="selected"', 01107 'databaseName' => htmlspecialchars(TYPO3_db) . ' (NO ACCESS!)' 01108 ); 01109 // Add the option HTML to an array 01110 $step3DatabaseOptions[] = t3lib_parsehtml::substituteMarkerArray( 01111 $step3DatabaseOptionsSubPart, 01112 $step3DatabaseOptionMarkers, 01113 '###|###', 01114 TRUE, 01115 TRUE 01116 ); 01117 } 01118 // Substitute the subpart for the database options 01119 $content = t3lib_parsehtml::substituteSubpart( 01120 $step3SubPart, 01121 '###DATABASEOPTIONS###', 01122 implode(LF, $step3DatabaseOptions) 01123 ); 01124 // Define the markers content 01125 $step3SubPartMarkers = array( 01126 'step' => $this->step + 1, 01127 'llOptions' => 'You have two options:', 01128 'action' => htmlspecialchars($this->action), 01129 'llOption1' => 'Create a new database (recommended):', 01130 'llRemark1' => 'Enter a name for your TYPO3 database.', 01131 'llOption2' => 'Select an EMPTY existing database:', 01132 'llRemark2' => 'Any tables used by TYPO3 will be overwritten.', 01133 'continue' => 'Continue' 01134 ); 01135 // Add step marker for main template 01136 $markers['step'] = t3lib_parsehtml::substituteMarkerArray( 01137 $content, 01138 $step3SubPartMarkers, 01139 '###|###', 01140 TRUE, 01141 TRUE 01142 ); 01143 } else { 01144 // Add step marker for main template when no connection 01145 $markers['step'] = $error_missingConnect; 01146 } 01147 break; 01148 case 4: 01149 // Add header marker for main template 01150 $markers['header'] = 'Import the Database Tables'; 01151 // There should be a database host connection at this point 01152 if ($result = $GLOBALS['TYPO3_DB']->sql_pconnect( 01153 TYPO3_db_host, TYPO3_db_username, TYPO3_db_password 01154 )) { 01155 // The selected database should be accessible 01156 if ($GLOBALS['TYPO3_DB']->sql_select_db(TYPO3_db)) { 01157 // Get the subpart for the fourth step 01158 $step4SubPart = t3lib_parsehtml::getSubpart( 01159 $templateFile, '###STEP4###' 01160 ); 01161 // Get the subpart for the database type options 01162 $step4DatabaseTypeOptionsSubPart = t3lib_parsehtml::getSubpart( 01163 $step4SubPart, '###DATABASETYPEOPTIONS###' 01164 ); 01165 01166 $sFiles = t3lib_div::getFilesInDir(PATH_typo3conf,'sql',1,1); 01167 01168 // Check if default database scheme "database.sql" already exists, otherwise create it 01169 if (!strstr(implode(',',$sFiles).',', '/database.sql,')) { 01170 array_unshift($sFiles,'Default TYPO3 Tables'); 01171 } 01172 01173 $step4DatabaseTypeOptions = array(); 01174 foreach ($sFiles as $f) { 01175 if ($f=='Default TYPO3 Tables') $key='CURRENT_TABLES+STATIC'; 01176 else $key=htmlspecialchars($f); 01177 // Define the markers content for database type subpart 01178 $step4DatabaseTypeOptionMarkers = array( 01179 'databaseTypeValue' => 'import|' . $key, 01180 'databaseName' => htmlspecialchars(basename($f)) 01181 ); 01182 // Add the option HTML to an array 01183 $step4DatabaseTypeOptions[] = t3lib_parsehtml::substituteMarkerArray( 01184 $step4DatabaseTypeOptionsSubPart, 01185 $step4DatabaseTypeOptionMarkers, 01186 '###|###', 01187 TRUE, 01188 FALSE 01189 ); 01190 } 01191 // Substitute the subpart for the database type options 01192 $content = t3lib_parsehtml::substituteSubpart( 01193 $step4SubPart, 01194 '###DATABASETYPEOPTIONS###', 01195 implode(LF, $step4DatabaseTypeOptions) 01196 ); 01197 // Define the markers content 01198 $step4SubPartMarkers = array( 01199 'llSummary' => 'Database summary:', 01200 'llUsername' => 'Username:', 01201 'username' => htmlspecialchars(TYPO3_db_username), 01202 'llHost' => 'Host:', 01203 'host' => htmlspecialchars(TYPO3_db_host), 01204 'llDatabase' => 'Database:', 01205 'database' => htmlspecialchars(TYPO3_db), 01206 'llNumberTables' => 'Number of tables:', 01207 'numberTables' => count($whichTables), 01208 'action' => htmlspecialchars($this->action), 01209 'llDatabaseType' => 'Select database contents:', 01210 'label' => 'Import database' 01211 ); 01212 // Add step marker for main template 01213 $markers['step'] = t3lib_parsehtml::substituteMarkerArray( 01214 $content, 01215 $step4SubPartMarkers, 01216 '###|###', 01217 TRUE, 01218 TRUE 01219 ); 01220 } else { 01221 // Add step marker for main template when no database 01222 $markers['step'] = $error_missingDB; 01223 } 01224 } else { 01225 // Add step marker for main template when no connection 01226 $markers['step'] = $error_missingConnect; 01227 } 01228 break; 01229 case 'go': 01230 // Add header marker for main template 01231 $markers['header'] = 'Congratulations!'; 01232 // There should be a database host connection at this point 01233 if ($result = $GLOBALS['TYPO3_DB']->sql_pconnect( 01234 TYPO3_db_host, TYPO3_db_username, TYPO3_db_password 01235 )) { 01236 // The selected database should be accessible 01237 if ($GLOBALS['TYPO3_DB']->sql_select_db(TYPO3_db)) { 01238 // The database should contain tables 01239 if (count($whichTables)) { 01240 // Get the subpart for the go step 01241 $stepGoSubPart = t3lib_parsehtml::getSubpart( 01242 $templateFile, '###STEPGO###' 01243 ); 01244 // Define the markers content 01245 $stepGoSubPartMarkers = array( 01246 'messageBasicFinished' => $this->messageBasicFinished(), 01247 'llImportant' => 'Important Security Warning', 01248 'securityRisk' => $this->securityRisk(), 01249 'llSwitchMode' => ' 01250 <a href="' . $this->scriptSelf . '"> 01251 Change the Install Tool password here 01252 </a> 01253 ' 01254 ); 01255 // Add step marker for main template 01256 $markers['step'] = t3lib_parsehtml::substituteMarkerArray( 01257 $stepGoSubPart, 01258 $stepGoSubPartMarkers, 01259 '###|###', 01260 TRUE, 01261 TRUE 01262 ); 01263 } else { 01264 // Add step marker for main template when empty database 01265 $markers['step'] = $error_emptyDB; 01266 } 01267 } else { 01268 // Add step marker for main template when no database 01269 $markers['step'] = $error_missingDB; 01270 } 01271 } else { 01272 // Add step marker for main template when no connection 01273 $markers['step'] = $error_missingConnect; 01274 } 01275 break; 01276 } 01277 } 01278 // Fill the markers in the template 01279 $content = t3lib_parsehtml::substituteMarkerArray( 01280 $template, 01281 $markers, 01282 '###|###', 01283 TRUE, 01284 FALSE 01285 ); 01286 01287 return $content; 01288 } 01289 01290 /** 01291 * Calling the functions that checks the system 01292 * 01293 * @return void 01294 */ 01295 function checkTheConfig() { 01296 // Order important: 01297 $this->checkDirs(); 01298 $this->checkConfiguration(); 01299 $this->checkExtensions(); 01300 01301 if (TYPO3_OS=='WIN') { 01302 $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\\'); 01303 if (!isset($_SERVER['PATH'])) { 01304 $serverPath = array_change_key_case($_SERVER, CASE_UPPER); 01305 $paths = array_merge($paths, explode(';', $serverPath['PATH'])); 01306 } else { 01307 $paths = array_merge($paths, explode(';', $_SERVER['PATH'])); 01308 } 01309 } else { 01310 $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/'); 01311 $paths = array_merge($paths, explode(':', $_SERVER['PATH'])); 01312 } 01313 $paths = array_unique($paths); 01314 01315 asort($paths); 01316 if (t3lib_utility_PhpOptions::isSafeModeEnabled()) { 01317 $paths=array(ini_get('safe_mode_exec_dir'),'/usr/local/php/bin/'); 01318 } 01319 if ($this->INSTALL['checkIM']['lzw']) { 01320 $this->checkIMlzw=1; 01321 } 01322 if ($this->INSTALL['checkIM']['path']) { 01323 $paths[]=trim($this->INSTALL['checkIM']['path']); 01324 } 01325 if ($this->checkIM) $this->checkImageMagick($paths); 01326 $this->checkDatabase(); 01327 } 01328 01329 /** 01330 * Editing files in typo3conf directory (or elsewhere if enabled) 01331 * 01332 * @return void 01333 */ 01334 function typo3conf_edit() { 01335 // default: 01336 $EDIT_path = PATH_typo3conf; 01337 if ($this->allowFileEditOutsite_typo3conf_dir && $this->INSTALL['FILE']['EDIT_path']) { 01338 if (t3lib_div::validPathStr($this->INSTALL['FILE']['EDIT_path']) && substr($this->INSTALL['FILE']['EDIT_path'],-1)=='/') { 01339 $tmp_path = PATH_site.$this->INSTALL['FILE']['EDIT_path']; 01340 if (is_dir($tmp_path)) { 01341 $EDIT_path=$tmp_path; 01342 } else { 01343 $this->errorMessages[] = ' 01344 \'' . $tmp_path . '\' was not directory 01345 '; 01346 } 01347 } else { 01348 $this->errorMessages[] = ' 01349 Bad directory name (must be like t3lib/ or media/script/) 01350 '; 01351 } 01352 } 01353 01354 $headCode = 'Edit files in '.basename($EDIT_path).'/'; 01355 $messages = ''; 01356 01357 if ($this->INSTALL['SAVE_FILE']) { 01358 $save_to_file = $this->INSTALL['FILE']['name']; 01359 if (@is_file($save_to_file)) { 01360 $save_to_file_md5 = md5($save_to_file); 01361 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')) { 01362 $this->INSTALL['typo3conf_files'] = $save_to_file; 01363 $save_fileContent = $this->INSTALL['FILE'][$save_to_file_md5]; 01364 01365 if ($this->INSTALL['FILE']['win_to_unix_br']) { 01366 $save_fileContent = str_replace(CRLF, LF, $save_fileContent); 01367 } 01368 01369 $backupFile = $this->getBackupFilename($save_to_file); 01370 if ($this->INSTALL['FILE']['backup']) { 01371 if (@is_file($backupFile)) { unlink($backupFile); } 01372 rename($save_to_file,$backupFile); 01373 $messages .= ' 01374 Backup written to <strong>' . $backupFile . '</strong> 01375 <br /> 01376 '; 01377 } 01378 01379 t3lib_div::writeFile($save_to_file,$save_fileContent); 01380 $messages .= ' 01381 File saved: <strong>' . $save_to_file . '</strong> 01382 <br /> 01383 MD5-sum: ' . $this->INSTALL['FILE']['prevMD5'] . ' (prev) 01384 <br /> 01385 MD5-sum: ' . md5($save_fileContent) . ' (new) 01386 <br /> 01387 '; 01388 } 01389 } 01390 } 01391 01392 // Filelist: 01393 // Get the template file 01394 $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'Typo3ConfEdit.html'); 01395 // Get the template part from the file 01396 $template = t3lib_parsehtml::getSubpart($templateFile, '###TEMPLATE###'); 01397 // Get the subpart for the files 01398 $filesSubpart = t3lib_parsehtml::getSubpart($template, '###FILES###'); 01399 $files = array(); 01400 01401 $typo3conf_files = t3lib_div::getFilesInDir($EDIT_path,'',1,1); 01402 $fileFound = 0; 01403 01404 01405 foreach ($typo3conf_files as $k => $file) { 01406 // Delete temp_CACHED files if option is set 01407 if ( $this->INSTALL['delTempCached'] && preg_match('|/temp_CACHED_[a-z0-9_]+\.php|', $file)) { 01408 unlink($file); 01409 continue; 01410 } 01411 if ($this->INSTALL['typo3conf_files'] && !strcmp($this->INSTALL['typo3conf_files'],$file)) { 01412 $fileFound = 1; 01413 } 01414 // Define the markers content for the files subpart 01415 $filesMarkers = array( 01416 'editUrl' => $this->action . '&TYPO3_INSTALL[typo3conf_files]=' . rawurlencode($file) . ($this->allowFileEditOutsite_typo3conf_dir ? '&TYPO3_INSTALL[FILE][EDIT_path]=' . rawurlencode($this->INSTALL['FILE']['EDIT_path']) : '') . '#confEditFileList', 01417 'fileName' => basename($file), 01418 'fileSize' => t3lib_div::formatSize(filesize($file)), 01419 'class' => $this->INSTALL['typo3conf_files'] && !strcmp($this->INSTALL['typo3conf_files'], $file) ? 'class="act"' : '' 01420 ); 01421 // Fill the markers in the subpart 01422 $files[] = t3lib_parsehtml::substituteMarkerArray( 01423 $filesSubpart, 01424 $filesMarkers, 01425 '###|###', 01426 TRUE, 01427 FALSE 01428 ); 01429 } 01430 01431 if ($fileFound && @is_file($this->INSTALL['typo3conf_files'])) { 01432 01433 $backupFile = $this->getBackupFilename($this->INSTALL['typo3conf_files']); 01434 $fileContent = t3lib_div::getUrl($this->INSTALL['typo3conf_files']); 01435 // Get the subpart to edit the files 01436 $fileEditTemplate = t3lib_parsehtml::getSubpart($template, '###FILEEDIT###'); 01437 $allowFileEditOutsideTypo3ConfDirSubPart = ''; 01438 01439 if (substr($this->INSTALL['typo3conf_files'], -1) != '~' && !strstr($this->INSTALL['typo3conf_files'], '_bak')) { 01440 // Get the subpart to show the save button 01441 $showSaveButtonSubPart = t3lib_parsehtml::getSubpart($fileEditTemplate, '###SHOWSAVEBUTTON###'); 01442 } 01443 01444 if ($this->allowFileEditOutsite_typo3conf_dir) { 01445 // Get the subpart to show if files are allowed outside the directory typo3conf 01446 $allowFileEditOutsideTypo3ConfDirSubPart = t3lib_parsehtml::getSubpart($fileEditTemplate, '###ALLOWFILEEDITOUTSIDETYPO3CONFDIR###'); 01447 } 01448 // Substitute the subpart for the save button 01449 $fileEditContent = t3lib_parsehtml::substituteSubpart( 01450 $fileEditTemplate, 01451 '###SHOWSAVEBUTTON###', 01452 $showSaveButtonSubPart 01453 ); 01454 // Substitute the subpart to show if files are allowed outside the directory typo3conf 01455 $fileEditContent = t3lib_parsehtml::substituteSubpart( 01456 $fileEditContent, 01457 '###ALLOWFILEEDITOUTSIDETYPO3CONFDIR###', 01458 $allowFileEditOutsideTypo3ConfDirSubPart 01459 ); 01460 // Define the markers content for subpart to edit the files 01461 $fileEditMarkers = array( 01462 'messages' => !empty($messages) ? '<p class="typo3-message message-warning">' . $messages . '</p>' : '', 01463 'action' => $this->action . '#fileEditHeader', 01464 'saveFile' => 'Save file', 01465 'close' => 'Close', 01466 'llEditing' => 'Editing file:', 01467 'file' => $this->INSTALL['typo3conf_files'], 01468 'md5Sum' => 'MD5-sum: ' . md5($fileContent), 01469 'fileName' => $this->INSTALL['typo3conf_files'], 01470 'fileEditPath' => $this->INSTALL['FILE']['EDIT_path'], 01471 'filePreviousMd5' => md5($fileContent), 01472 'fileMd5' => md5($this->INSTALL['typo3conf_files']), 01473 'fileContent' => t3lib_div::formatForTextarea($fileContent), 01474 'winToUnixBrChecked' => TYPO3_OS == 'WIN' ? '' : 'checked="checked"', 01475 'winToUnixBr' => 'Convert Windows linebreaks (13-10) to Unix (10)', 01476 'backupChecked' => @is_file($backupFile) ? 'checked="checked"' : '', 01477 'backup' => 'Make backup copy (rename to ' . basename($backupFile) . ')' 01478 ); 01479 // Fill the markers in the subpart to edit the files 01480 $fileEditContent = t3lib_parsehtml::substituteMarkerArray( 01481 $fileEditContent, 01482 $fileEditMarkers, 01483 '###|###', 01484 TRUE, 01485 FALSE 01486 ); 01487 } 01488 01489 if ($this->allowFileEditOutsite_typo3conf_dir) { 01490 // Get the subpart to show if files are allowed outside the directory typo3conf 01491 $allowFileEditOutsideTypo3ConfDirSubPart = t3lib_parsehtml::getSubpart($template, '###ALLOWFILEEDITOUTSIDETYPO3CONFDIR###'); 01492 // Define the markers content 01493 $allowFileEditOutsideTypo3ConfDirMarkers = array( 01494 'action' => $this->action, 01495 'pathSite' => PATH_site, 01496 'editPath' => $this->INSTALL['FILE']['EDIT_path'], 01497 'set' => 'Set' 01498 ); 01499 // Fill the markers in the subpart 01500 $allowFileEditOutsideTypo3ConfDirSubPart = t3lib_parsehtml::substituteMarkerArray( 01501 $allowFileEditOutsideTypo3ConfDirSubPart, 01502 $allowFileEditOutsideTypo3ConfDirMarkers, 01503 '###|###', 01504 TRUE, 01505 FALSE 01506 ); 01507 } 01508 // Substitute the subpart to edit the file 01509 $fileListContent = t3lib_parsehtml::substituteSubpart( 01510 $template, 01511 '###FILEEDIT###', 01512 $fileEditContent 01513 ); 01514 // Substitute the subpart when files can be edited outside typo3conf directory 01515 $fileListContent = t3lib_parsehtml::substituteSubpart( 01516 $fileListContent, 01517 '###ALLOWFILEEDITOUTSIDETYPO3CONFDIR###', 01518 $allowFileEditOutsideTypo3ConfDirSubPart 01519 ); 01520 // Substitute the subpart for the files 01521 $fileListContent = t3lib_parsehtml::substituteSubpart( 01522 $fileListContent, 01523 '###FILES###', 01524 implode(LF, $files) 01525 ); 01526 // Define the markers content 01527 $fileListMarkers = array( 01528 'editPath' => '(' . $EDIT_path . ')', 01529 'deleteTempCachedUrl' => $this->action . '&TYPO3_INSTALL[delTempCached]=1', 01530 'deleteTempCached' => 'Delete temp_CACHED* files' 01531 ); 01532 // Fill the markers 01533 $fileListContent = t3lib_parsehtml::substituteMarkerArray( 01534 $fileListContent, 01535 $fileListMarkers, 01536 '###|###', 01537 TRUE, 01538 FALSE 01539 ); 01540 // Add the content to the message array 01541 $this->message($headCode, 'Files in folder', $fileListContent); 01542 // Output the page 01543 $this->output($this->outputWrapper($this->printAll())); 01544 } 01545 01546 /** 01547 * Outputs system information 01548 * 01549 * @return void 01550 */ 01551 function phpinformation() { 01552 $headCode = 'PHP information'; 01553 01554 $sVar = t3lib_div::getIndpEnv('_ARRAY'); 01555 $sVar['CONST: PHP_OS']=PHP_OS; 01556 $sVar['CONST: TYPO3_OS']=TYPO3_OS; 01557 $sVar['CONST: PATH_thisScript']=PATH_thisScript; 01558 $sVar['CONST: php_sapi_name()']=PHP_SAPI; 01559 $sVar['OTHER: TYPO3_VERSION']=TYPO3_version; 01560 $sVar['OTHER: PHP_VERSION']=phpversion(); 01561 $sVar['imagecreatefromgif()']=function_exists('imagecreatefromgif'); 01562 $sVar['imagecreatefrompng()']=function_exists('imagecreatefrompng'); 01563 $sVar['imagecreatefromjpeg()']=function_exists('imagecreatefromjpeg'); 01564 $sVar['imagegif()']=function_exists('imagegif'); 01565 $sVar['imagepng()']=function_exists('imagepng'); 01566 $sVar['imagejpeg()']=function_exists('imagejpeg'); 01567 $sVar['imagettftext()']=function_exists('imagettftext'); 01568 $sVar['OTHER: IMAGE_TYPES']=function_exists('imagetypes') ? imagetypes() : 0; 01569 $sVar['OTHER: memory_limit']=ini_get('memory_limit'); 01570 01571 $gE_keys = explode(',','SERVER_PORT,SERVER_SOFTWARE,GATEWAY_INTERFACE,SCRIPT_NAME,PATH_TRANSLATED'); 01572 foreach ($gE_keys as $k) { 01573 $sVar['SERVER: '.$k]=$_SERVER[$k]; 01574 } 01575 01576 $gE_keys = explode(',','image_processing,gdlib,gdlib_png,im,im_path,im_path_lzw,im_version_5,im_negate_mask,im_imvMaskState,im_combine_filename'); 01577 01578 foreach ($gE_keys as $k) { 01579 $sVar['T3CV_GFX: '.$k]=$GLOBALS['TYPO3_CONF_VARS']['GFX'][$k]; 01580 } 01581 01582 $debugInfo = array( 01583 '### DEBUG SYSTEM INFORMATION - START ###' 01584 ); 01585 foreach ($sVar as $kkk => $vvv) { 01586 $debugInfo[]=str_pad(substr($kkk,0,20),20).': '.$vvv; 01587 } 01588 $debugInfo[]='### DEBUG SYSTEM INFORMATION - END ###'; 01589 // Get the template file 01590 $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'PhpInformation.html'); 01591 // Get the template part from the file 01592 $template = t3lib_parsehtml::getSubpart($templateFile, '###TEMPLATE###'); 01593 // Define the markers content 01594 $markers = array( 01595 'explanation' => 'Please copy/paste the information from this text field into an email or bug-report as "Debug System Information" whenever you wish to get support or report problems. This information helps others to check if your system has some obvious misconfiguration and you\'ll get your help faster!', 01596 'debugInfo' => t3lib_div::formatForTextarea(implode(LF, $debugInfo)) 01597 ); 01598 // Fill the markers 01599 $content = t3lib_parsehtml::substituteMarkerArray( 01600 $template, 01601 $markers, 01602 '###|###', 01603 TRUE, 01604 FALSE 01605 ); 01606 // Add the content to the message array 01607 $this->message($headCode, 'DEBUG information', $content); 01608 // Start with various server information 01609 $getEnvArray = array(); 01610 $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'); 01611 foreach ($gE_keys as $k) { 01612 $getEnvArray[$k] = getenv($k); 01613 } 01614 $this->message($headCode, 't3lib_div::getIndpEnv()', $this->viewArray(t3lib_div::getIndpEnv('_ARRAY'))); 01615 $this->message($headCode, 'getenv()', $this->viewArray($getEnvArray)); 01616 $this->message($headCode, '_ENV', $this->viewArray($_ENV)); 01617 $this->message($headCode, '_SERVER', $this->viewArray($_SERVER)); 01618 $this->message($headCode, '_COOKIE', $this->viewArray($_COOKIE)); 01619 $this->message($headCode, '_GET', $this->viewArray($_GET)); 01620 // Start with the phpinfo() part 01621 ob_start(); 01622 phpinfo(); 01623 $contents = explode('<body>',ob_get_contents()); 01624 ob_end_clean(); 01625 $contents = explode('</body>',$contents[1]); 01626 // Do code cleaning: phpinfo() is not XHTML1.1 compliant 01627 $phpinfo = str_replace('<font', '<span', $contents[0]); 01628 $phpinfo = str_replace('</font', '</span', $phpinfo); 01629 $phpinfo = str_replace('<img border="0"', '<img', $phpinfo); 01630 $phpinfo = str_replace('<a name=', '<a id=', $phpinfo); 01631 // Add phpinfo() to the message array 01632 $this->message($headCode, 'phpinfo()', ' 01633 <div class="phpinfo"> 01634 ' . $phpinfo . ' 01635 </div> 01636 '); 01637 // Output the page 01638 $this->output($this->outputWrapper($this->printAll())); 01639 } 01640 01641 01642 01643 01644 01645 01646 01647 01648 01649 01650 /******************************* 01651 * 01652 * cleanup manager 01653 * 01654 *******************************/ 01655 01656 /** 01657 * Provides a tool cleaning up various tables in the database 01658 * 01659 * @return void 01660 * @author Robert Lemke <rl@robertlemke.de> 01661 * @todo Add more functionality ... 01662 */ 01663 function cleanupManager() { 01664 $headCode = 'Clean up your TYPO3 installation'; 01665 $this->message($headCode, 'Database cache tables', ' 01666 <p> 01667 <strong>Clear cached image sizes</strong> 01668 <br /> 01669 Clears the cache used for memorizing sizes of all images used in 01670 your website. This information is cached in order to gain 01671 performance and will be stored each time a new image is being 01672 displayed in the frontend. 01673 </p> 01674 <p> 01675 You should <em>Clear All Cache</em> in the backend after 01676 clearing this cache. 01677 </p> 01678 '); 01679 01680 $tables = $this->getListOfTables(); 01681 $action = $this->INSTALL['cleanup_type']; 01682 01683 if (($action == 'cache_imagesizes' || $action == 'all') && isset ($tables['cache_imagesizes'])) { 01684 $GLOBALS['TYPO3_DB']->exec_TRUNCATEquery('cache_imagesizes'); 01685 } 01686 01687 $cleanupType = array ( 01688 'all' => 'Clean up everything', 01689 ); 01690 01691 // Get cache_imagesizes info 01692 if (isset ($tables['cache_imagesizes'])) { 01693 $cleanupType['cache_imagesizes'] = 'Clear cached image sizes only'; 01694 $cachedImageSizesCounter = intval($GLOBALS['TYPO3_DB']->exec_SELECTcountRows('*', 'cache_imagesizes')); 01695 } else { 01696 $this->message($headCode, 'Table cache_imagesizes does not exist!', ' 01697 <p> 01698 The table cache_imagesizes was not found. Please check your 01699 database settings in Basic Configuration and compare your 01700 table definition with the Database Analyzer. 01701 </p> 01702 ', 2); 01703 $cachedImageSizesCounter = 'unknown'; 01704 } 01705 // Get the template file 01706 $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'CleanUpManager.html'); 01707 // Get the template part from the file 01708 $template = t3lib_parsehtml::getSubpart($templateFile, '###TEMPLATE###'); 01709 // Get the subpart for the 'Clean up' dropdown 01710 $cleanUpOptionsSubpart = t3lib_parsehtml::getSubpart($template, '###CLEANUPOPTIONS###'); 01711 $cleanUpOptions = array(); 01712 01713 foreach ($cleanupType as $cleanUpKey => $cleanUpValue) { 01714 // Define the markers content 01715 $cleanUpMarkers = array( 01716 'value' => htmlspecialchars($cleanUpKey), 01717 'data' => htmlspecialchars($cleanUpValue) 01718 ); 01719 // Fill the markers in the subpart 01720 $cleanUpOptions[] = t3lib_parsehtml::substituteMarkerArray( 01721 $cleanUpOptionsSubpart, 01722 $cleanUpMarkers, 01723 '###|###', 01724 TRUE, 01725 FALSE 01726 ); 01727 } 01728 // Substitute the subpart for the 'Clean up' dropdown 01729 $content = t3lib_parsehtml::substituteSubpart( 01730 $template, 01731 '###CLEANUPOPTIONS###', 01732 implode(LF, $cleanUpOptions) 01733 ); 01734 // Define the markers content 01735 $markers = array( 01736 'numberCached' => 'Number cached image sizes:', 01737 'number' => $cachedImageSizesCounter, 01738 'action' => $this->action, 01739 'cleanUp' => 'Clean up', 01740 'execute' => 'Execute' 01741 ); 01742 // Fill the markers 01743 $content = t3lib_parsehtml::substituteMarkerArray( 01744 $content, 01745 $markers, 01746 '###|###', 01747 TRUE, 01748 FALSE 01749 ); 01750 // Add the content to the message array 01751 $this->message($headCode, 'Statistics', $content, 1); 01752 01753 01754 01755 01756 01757 01758 01759 $this->message($headCode, 'typo3temp/ folder', ' 01760 <p> 01761 TYPO3 uses this directory for temporary files, mainly processed 01762 and cached images. 01763 <br /> 01764 The filenames are very cryptic; They are unique representations 01765 of the file properties made by md5-hashing a serialized array 01766 with information. 01767 <br /> 01768 Anyway this directory may contain many thousand files and a lot 01769 of them may be of no use anymore. 01770 </p> 01771 <p> 01772 With this test you can delete the files in this folder. When you 01773 do that, you should also clear the cache database tables 01774 afterwards. 01775 </p> 01776 '); 01777 01778 if (!$this->config_array['dir_typo3temp']) { 01779 $this->message('typo3temp/ directory', 'typo3temp/ not writable!', ' 01780 <p> 01781 You must make typo3temp/ write enabled before you can 01782 proceed with this test. 01783 </p> 01784 ', 2); 01785 $this->output($this->outputWrapper($this->printAll())); 01786 return; 01787 } 01788 01789 // Run through files 01790 $fileCounter = 0; 01791 $deleteCounter = 0; 01792 $criteriaMatch = 0; 01793 $tmap=array('day'=>1, 'week'=>7, 'month'=>30); 01794 $tt = $this->INSTALL['typo3temp_delete']; 01795 $subdir = $this->INSTALL['typo3temp_subdir']; 01796 if (strlen($subdir) && !preg_match('/^[[:alnum:]_]+\/$/',$subdir)) die('subdir "'.$subdir.'" was not allowed!'); 01797 $action = $this->INSTALL['typo3temp_action']; 01798 $d = @dir($this->typo3temp_path.$subdir); 01799 if (is_object($d)) { 01800 while($entry=$d->read()) { 01801 $theFile = $this->typo3temp_path.$subdir.$entry; 01802 if (@is_file($theFile)) { 01803 $ok = 0; 01804 $fileCounter++; 01805 if ($tt) { 01806 if (t3lib_div::testInt($tt)) { 01807 if (filesize($theFile) > $tt*1024) $ok=1; 01808 } else { 01809 if (fileatime($theFile) < $GLOBALS['EXEC_TIME'] - (intval($tmap[$tt]) * 60 * 60 * 24)) { 01810 $ok = 1; 01811 } 01812 } 01813 } else { 01814 $ok = 1; 01815 } 01816 if ($ok) { 01817 $hashPart=substr(basename($theFile),-14,10); 01818 // This is a kind of check that the file being deleted has a 10 char hash in it 01819 if (!preg_match('/[^a-f0-9]/',$hashPart) || substr($theFile,-6)==='.cache' || substr($theFile,-4)==='.tbl' || substr(basename($theFile),0,8)==='install_') { 01820 if ($action && $deleteCounter<$action) { 01821 $deleteCounter++; 01822 unlink($theFile); 01823 } else { 01824 $criteriaMatch++; 01825 } 01826 } 01827 } 01828 } 01829 } 01830 $d->close(); 01831 } 01832 01833 // Find sub-dirs: 01834 $subdirRegistry = array(''=>''); 01835 $d = @dir($this->typo3temp_path); 01836 if (is_object($d)) { 01837 while($entry=$d->read()) { 01838 $theFile = $entry; 01839 if (@is_dir($this->typo3temp_path.$theFile) && $theFile!='..' && $theFile!='.') { 01840 $subdirRegistry[$theFile.'/'] = $theFile.'/ (Files: '.count(t3lib_div::getFilesInDir($this->typo3temp_path.$theFile)).')'; 01841 } 01842 } 01843 } 01844 01845 $deleteType=array( 01846 '0' => 'All', 01847 'day' => 'Last access more than a day ago', 01848 'week' => 'Last access more than a week ago', 01849 'month' => 'Last access more than a month ago', 01850 '10' => 'Filesize greater than 10KB', 01851 '50' => 'Filesize greater than 50KB', 01852 '100' => 'Filesize greater than 100KB' 01853 ); 01854 01855 $actionType=array( 01856 '0' => "Don't delete, just display statistics", 01857 '100' => 'Delete 100', 01858 '500' => 'Delete 500', 01859 '1000' => 'Delete 1000' 01860 ); 01861 // Get the template file 01862 $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'Typo3TempManager.html'); 01863 // Get the template part from the file 01864 $template = t3lib_parsehtml::getSubpart($templateFile, '###TEMPLATE###'); 01865 // Get the subpart for 'Delete files by condition' dropdown 01866 $deleteOptionsSubpart = t3lib_parsehtml::getSubpart($template, '###DELETEOPTIONS###'); 01867 $deleteOptions = array(); 01868 01869 foreach ($deleteType as $deleteKey => $deleteValue) { 01870 // Define the markers content 01871 $deleteMarkers = array( 01872 'value' => htmlspecialchars($deleteKey), 01873 'selected' => !strcmp($deleteKey, $tt) ? 'selected="selected"' : '', 01874 'data' => htmlspecialchars($deleteValue) 01875 ); 01876 // Fill the markers in the subpart 01877 $deleteOptions[] = t3lib_parsehtml::substituteMarkerArray( 01878 $deleteOptionsSubpart, 01879 $deleteMarkers, 01880 '###|###', 01881 TRUE, 01882 FALSE 01883 ); 01884 } 01885 // Substitute the subpart for 'Delete files by condition' dropdown 01886 $content = t3lib_parsehtml::substituteSubpart( 01887 $template, 01888 '###DELETEOPTIONS###', 01889 implode(LF, $deleteOptions) 01890 ); 01891 // Get the subpart for 'Number of files at a time' dropdown 01892 $actionOptionsSubpart = t3lib_parsehtml::getSubpart($template, '###ACTIONOPTIONS###'); 01893 $actionOptions = array(); 01894 01895 foreach ($actionType as $actionKey => $actionValue) { 01896 // Define the markers content 01897 $actionMarkers = array( 01898 'value' => htmlspecialchars($actionKey), 01899 'data' => htmlspecialchars($actionValue) 01900 ); 01901 // Fill the markers in the subpart 01902 $actionOptions[] = t3lib_parsehtml::substituteMarkerArray( 01903 $actionOptionsSubpart, 01904 $actionMarkers, 01905 '###|###', 01906 TRUE, 01907 FALSE 01908 ); 01909 } 01910 // Substitute the subpart for 'Number of files at a time' dropdown 01911 $content = t3lib_parsehtml::substituteSubpart( 01912 $content, 01913 '###ACTIONOPTIONS###', 01914 implode(LF, $actionOptions) 01915 ); 01916 // Get the subpart for 'From sub-directory' dropdown 01917 $subDirectoryOptionsSubpart = t3lib_parsehtml::getSubpart($template, '###SUBDIRECTORYOPTIONS###'); 01918 $subDirectoryOptions = array(); 01919 01920 foreach ($subdirRegistry as $subDirectoryKey => $subDirectoryValue) { 01921 // Define the markers content 01922 $subDirectoryMarkers = array( 01923 'value' => htmlspecialchars($subDirectoryKey), 01924 'selected' => !strcmp($subDirectoryKey, $this->INSTALL['typo3temp_subdir']) ? 'selected="selected"' : '', 01925 'data' => htmlspecialchars($subDirectoryValue) 01926 ); 01927 // Fill the markers in the subpart 01928 $subDirectoryOptions[] = t3lib_parsehtml::substituteMarkerArray( 01929 $subDirectoryOptionsSubpart, 01930 $subDirectoryMarkers, 01931 '###|###', 01932 TRUE, 01933 FALSE 01934 ); 01935 } 01936 // Substitute the subpart for 'From sub-directory' dropdown 01937 $content = t3lib_parsehtml::substituteSubpart( 01938 $content, 01939 '###SUBDIRECTORYOPTIONS###', 01940 implode(LF, $subDirectoryOptions) 01941 ); 01942 // Define the markers content 01943 $markers = array( 01944 'numberTemporary' => 'Number of temporary files:', 01945 'numberMatching' => 'Number matching:', 01946 'numberDeleted' => 'Number deleted:', 01947 'temporary' => ($fileCounter - $deleteCounter), 01948 'matching' => $criteriaMatch, 01949 'deleteType' => '<span>' . htmlspecialchars($deleteType[$tt]) . '</span>', 01950 'deleted' => $deleteCounter, 01951 'deleteCondition' => 'Delete files by condition', 01952 'numberFiles' => 'Number of files at a time:', 01953 'fromSubdirectory' => 'From sub-directory:', 01954 'execute' => 'Execute', 01955 'explanation' => ' 01956 <p> 01957 This tool will delete files only if the last 10 characters 01958 before the extension (3 chars+\'.\') are hexadecimal valid 01959 ciphers, which are lowercase a-f and 0-9. 01960 </p> 01961 ' 01962 ); 01963 // Fill the markers 01964 $content = t3lib_parsehtml::substituteMarkerArray( 01965 $content, 01966 $markers, 01967 '###|###', 01968 TRUE, 01969 FALSE 01970 ); 01971 // Add the content to the message array 01972 $this->message($headCode, 'Statistics', $content, 1); 01973 01974 01975 // Output the page 01976 $this->output($this->outputWrapper($this->printAll())); 01977 } 01978 01979 01980 01981 01982 01983 01984 01985 01986 01987 01988 01989 01990 01991 /******************************* 01992 * 01993 * CONFIGURATION FORM 01994 * 01995 ********************************/ 01996 01997 /** 01998 * Creating the form for editing the TYPO3_CONF_VARS options. 01999 * 02000 * @param string $type If get_form, display form, otherwise checks and store in localconf.php 02001 * @return void 02002 */ 02003 function generateConfigForm($type='') { 02004 $default_config_content = t3lib_div::getUrl(PATH_t3lib.'config_default.php'); 02005 $commentArr = $this->getDefaultConfigArrayComments($default_config_content); 02006 02007 switch($type) { 02008 case 'get_form': 02009 // Get the template file 02010 $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'GenerateConfigForm.html'); 02011 // Get the template part from the file 02012 $template = t3lib_parsehtml::getSubpart($templateFile, '###TEMPLATE###'); 02013 02014 foreach ($GLOBALS['TYPO3_CONF_VARS'] as $k => $va) { 02015 $ext='['.$k.']'; 02016 $this->message($ext, '$TYPO3_CONF_VARS[\''.$k.'\']',$commentArr[0][$k],1); 02017 02018 foreach ($va as $vk => $value) { 02019 $textAreaSubpart = ''; 02020 $booleanSubpart = ''; 02021 $textLineSubpart = ''; 02022 02023 $description = trim($commentArr[1][$k][$vk]); 02024 $isTextarea = preg_match('/^(<.*?>)?string \(textarea\)/i', $description) ? TRUE : FALSE; 02025 $doNotRender = preg_match('/^(<.*?>)?string \(exclude\)/i', $description) ? TRUE : FALSE; 02026 02027 if (!is_array($value) && !$doNotRender && ($this->checkForBadString($value) || $isTextarea)) { 02028 $k2 = '['.$vk.']'; 02029 02030 if ($isTextarea) { 02031 // Get the subpart for a textarea 02032 $textAreaSubpart = t3lib_parsehtml::getSubpart($template, '###TEXTAREA###'); 02033 // Define the markers content 02034 $textAreaMarkers = array( 02035 'id' => $k . '-' . $vk, 02036 'name' => 'TYPO3_INSTALL[extConfig]['.$k.']['.$vk.']', 02037 'value' => str_replace(array("'.chr(10).'", "' . LF . '"), array(LF, LF), $value) 02038 ); 02039 $value = str_replace(array("'.chr(10).'", "' . LF . '"), array(' | ', ' | '), $value); 02040 // Fill the markers in the subpart 02041 $textAreaSubpart = t3lib_parsehtml::substituteMarkerArray( 02042 $textAreaSubpart, 02043 $textAreaMarkers, 02044 '###|###', 02045 TRUE, 02046 FALSE 02047 ); 02048 } elseif (preg_match('/^(<.*?>)?boolean/i', $description)) { 02049 // Get the subpart for a checkbox 02050 $booleanSubpart = t3lib_parsehtml::getSubpart($template, '###BOOLEAN###'); 02051 // Define the markers content 02052 $booleanMarkers = array( 02053 'id' => $k . '-' . $vk, 02054 'name' => 'TYPO3_INSTALL[extConfig]['.$k.']['.$vk.']', 02055 'value' => $value && strcmp($value, '0') ? $value : 1, 02056 'checked' => $value ? 'checked="checked"' : '' 02057 ); 02058 // Fill the markers in the subpart 02059 $booleanSubpart = t3lib_parsehtml::substituteMarkerArray( 02060 $booleanSubpart, 02061 $booleanMarkers, 02062 '###|###', 02063 TRUE, 02064 FALSE 02065 ); 02066 } else { 02067 // Get the subpart for an input text field 02068 $textLineSubpart = t3lib_parsehtml::getSubpart($template, '###TEXTLINE###'); 02069 // Define the markers content 02070 $textLineMarkers = array( 02071 'id' => $k . '-' . $vk, 02072 'name' => 'TYPO3_INSTALL[extConfig]['.$k.']['.$vk.']', 02073 'value' => $value 02074 ); 02075 // Fill the markers in the subpart 02076 $textLineSubpart = t3lib_parsehtml::substituteMarkerArray( 02077 $textLineSubpart, 02078 $textLineMarkers, 02079 '###|###', 02080 TRUE, 02081 FALSE 02082 ); 02083 } 02084 // Substitute the subpart for a textarea 02085 $content = t3lib_parsehtml::substituteSubpart( 02086 $template, 02087 '###TEXTAREA###', 02088 $textAreaSubpart 02089 ); 02090 // Substitute the subpart for a checkbox 02091 $content = t3lib_parsehtml::substituteSubpart( 02092 $content, 02093 '###BOOLEAN###', 02094 $booleanSubpart 02095 ); 02096 // Substitute the subpart for an input text field 02097 $content = t3lib_parsehtml::substituteSubpart( 02098 $content, 02099 '###TEXTLINE###', 02100 $textLineSubpart 02101 ); 02102 // Define the markers content 02103 $markers = array( 02104 'description' => $description, 02105 'key' => '[' . $k . '][' . $vk . ']', 02106 'label' => htmlspecialchars(t3lib_div::fixed_lgd_cs($value, 40)) 02107 ); 02108 // Fill the markers 02109 $content = t3lib_parsehtml::substituteMarkerArray( 02110 $content, 02111 $markers, 02112 '###|###', 02113 TRUE, 02114 FALSE 02115 ); 02116 // Add the content to the message array 02117 $this->message($ext, $k2, $content); 02118 } 02119 } 02120 } 02121 break; 02122 default: 02123 if (is_array($this->INSTALL['extConfig'])) { 02124 $lines = $this->writeToLocalconf_control(); 02125 foreach ($this->INSTALL['extConfig'] as $k => $va) { 02126 if (is_array($GLOBALS['TYPO3_CONF_VARS'][$k])) { 02127 foreach ($va as $vk => $value) { 02128 if (isset($GLOBALS['TYPO3_CONF_VARS'][$k][$vk])) { 02129 $doit=1; 02130 if ($k=='BE' && $vk=='installToolPassword') { 02131 if ($value) { 02132 if (isset($_POST['installToolPassword_check'])) { 02133 if (!$this->formProtection->validateToken( 02134 (string) $_POST['formToken'], 02135 'installToolPassword', 02136 'change' 02137 )) { 02138 $doit = FALSE; 02139 break; 02140 } 02141 02142 if (!t3lib_div::_GP('installToolPassword_check') 02143 || strcmp(t3lib_div::_GP('installToolPassword_check'), $value) 02144 ) { 02145 $doit = FALSE; 02146 $this->errorMessages[] 02147 = 'The two passwords did not ' . 02148 'match! The password was not changed.'; 02149 } 02150 } 02151 if (t3lib_div::_GP('installToolPassword_md5')) $value =md5($value); 02152 } else $doit=0; 02153 } 02154 02155 $description = trim($commentArr[1][$k][$vk]); 02156 if (preg_match('/^string \(textarea\)/i', $description)) { 02157 // Force Unix linebreaks in textareas 02158 $value = str_replace(CR, '', $value); 02159 // Preserve linebreaks 02160 $value = str_replace(LF, "' . LF . '", $value); 02161 } 02162 if (preg_match('/^boolean/i', $description)) { 02163 // When submitting settings in the Install Tool, values that default to "false" or "true" 02164 // in config_default.php will be sent as "0" resp. "1". Therefore, reset the values 02165 // to their boolean equivalent. 02166 if ($GLOBALS['TYPO3_CONF_VARS'][$k][$vk] === false && $value === '0') { 02167 $value = false; 02168 } elseif ($GLOBALS['TYPO3_CONF_VARS'][$k][$vk] === true && $value === '1') { 02169 $value = true; 02170 } 02171 } 02172 02173 if ($doit && strcmp($GLOBALS['TYPO3_CONF_VARS'][$k][$vk],$value)) $this->setValueInLocalconfFile($lines, '$TYPO3_CONF_VARS[\''.$k.'\'][\''.$vk.'\']', $value); 02174 } 02175 } 02176 } 02177 } 02178 $this->writeToLocalconf_control($lines); 02179 } 02180 break; 02181 } 02182 } 02183 02184 /** 02185 * Make an array of the comments in the t3lib/config_default.php file 02186 * 02187 * @param string $string The contents of the config_default.php file 02188 * @param array $mainArray 02189 * @param array $commentArray 02190 * @return array 02191 */ 02192 function getDefaultConfigArrayComments($string,$mainArray=array(),$commentArray=array()) { 02193 $lines = explode(LF, $string); 02194 $in=0; 02195 $mainKey=''; 02196 foreach ($lines as $lc) { 02197 $lc = trim($lc); 02198 if ($in) { 02199 if (!strcmp($lc,');')) { 02200 $in=0; 02201 } else { 02202 if (preg_match('/["\']([[:alnum:]_-]*)["\'][[:space:]]*=>(.*)/i',$lc,$reg)) { 02203 preg_match('/,[\t\s]*\/\/(.*)/i',$reg[2],$creg); 02204 $theComment = trim($creg[1]); 02205 if (substr(strtolower(trim($reg[2])),0,5)=='array' && !strcmp($reg[1],strtoupper($reg[1]))) { 02206 $mainKey=trim($reg[1]); 02207 $mainArray[$mainKey]=$theComment; 02208 } elseif ($mainKey) { 02209 $commentArray[$mainKey][$reg[1]]=$theComment; 02210 } 02211 } 02212 } 02213 } 02214 if (!strcmp($lc, '$TYPO3_CONF_VARS = array(')) { 02215 $in=1; 02216 } 02217 } 02218 return array($mainArray,$commentArray); 02219 } 02220 02221 02222 02223 02224 02225 02226 02227 02228 02229 02230 02231 02232 02233 /******************************* 02234 * 02235 * CHECK CONFIGURATION FUNCTIONS 02236 * 02237 *******************************/ 02238 02239 /** 02240 * Checking php.ini configuration and set appropriate messages and flags. 02241 * 02242 * @return void 02243 */ 02244 function checkConfiguration() { 02245 $ext='php.ini configuration checked'; 02246 $this->message($ext); 02247 02248 // ***************** 02249 // Incoming values: 02250 // ***************** 02251 02252 // Includepath 02253 $incPaths = t3lib_div::trimExplode(TYPO3_OS=='WIN'?';':':', ini_get('include_path')); 02254 if (!in_array('.',$incPaths)) { 02255 $this->message($ext, 'Current directory (./) is not in include path!', ' 02256 <p> 02257 <em>include_path=' . ini_get('include_path') . '</em> 02258 <br /> 02259 Normally the current path, \'.\', is included in the 02260 include_path of PHP. Although TYPO3 does not rely on this, 02261 it is an unusual setting that may introduce problems for 02262 some extensions. 02263 </p> 02264 ', 1); 02265 } else $this->message($ext, 'Current directory in include path',"",-1); 02266 02267 // ***************** 02268 // File uploads 02269 // ***************** 02270 if (!ini_get('file_uploads')) { 02271 $this->message($ext, 'File uploads not allowed', ' 02272 <p> 02273 <em>file_uploads=' . ini_get('file_uploads') . '</em> 02274 <br /> 02275 TYPO3 uses the ability to upload files from the browser in 02276 various cases. 02277 <br /> 02278 As long as this flag is disabled, you\'ll not be able to 02279 upload files. 02280 <br /> 02281 But it doesn\'t end here, because not only are files not 02282 accepted by the server - ALL content in the forms are 02283 discarded and therefore nothing at all will be editable 02284 if you don\'t set this flag! 02285 <br /> 02286 However if you cannot enable fileupload for some reason 02287 alternatively you change the default form encoding value 02288 with \$TYPO3_CONF_VARS[SYS][form_enctype]. 02289 </p> 02290 ', 3); 02291 } else $this->message($ext, 'File uploads allowed',"",-1); 02292 02293 $upload_max_filesize = t3lib_div::getBytesFromSizeMeasurement(ini_get('upload_max_filesize')); 02294 $post_max_size = t3lib_div::getBytesFromSizeMeasurement(ini_get('post_max_size')); 02295 if ($upload_max_filesize<1024*1024*10) { 02296 $this->message($ext, 'Maximum upload filesize too small?', ' 02297 <p> 02298 <em>upload_max_filesize=' . ini_get('upload_max_filesize') . '</em> 02299 <br /> 02300 By default TYPO3 supports uploading, copying and moving 02301 files of sizes up to 10MB (You can alter the TYPO3 defaults 02302 by the config option TYPO3_CONF_VARS[BE][maxFileSize]). 02303 <br /> 02304 Your current value is below this, so at this point, PHP sets 02305 the limits for uploaded filesizes and not TYPO3. 02306 <br /> 02307 <strong>Notice:</strong> The limits for filesizes attached 02308 to database records are set in the tables.php configuration 02309 files (\$TCA) for each group/file field. You may override 02310 these values in localconf.php or by page TSconfig settings. 02311 </p> 02312 ', 1); 02313 } 02314 if ($upload_max_filesize > $post_max_size) { 02315 $this->message($ext, 'Maximum size for POST requests is smaller than max. upload filesize', ' 02316 <p> 02317 <em>upload_max_filesize=' . ini_get('upload_max_filesize') . ' 02318 , post_max_size=' . ini_get('post_max_size') . '</em> 02319 <br /> 02320 You have defined a maximum size for file uploads which 02321 exceeds the allowed size for POST requests. Therefore the 02322 file uploads can not be larger than ' . ini_get('post_max_size') . ' 02323 </p> 02324 ', 1); 02325 } 02326 02327 // ***************** 02328 // Memory and functions 02329 // ***************** 02330 $memory_limit_value = t3lib_div::getBytesFromSizeMeasurement(ini_get('memory_limit')); 02331 02332 if ($memory_limit_value && $memory_limit_value < t3lib_div::getBytesFromSizeMeasurement(TYPO3_REQUIREMENTS_MINIMUM_PHP_MEMORY_LIMIT)) { 02333 $this->message($ext, 'Memory limit below ' . TYPO3_REQUIREMENTS_MINIMUM_PHP_MEMORY_LIMIT, ' 02334 <p> 02335 <em>memory_limit=' . ini_get('memory_limit') . '</em> 02336 <br /> 02337 Your system is configured to enforce a memory limit of PHP 02338 scripts lower than ' . TYPO3_REQUIREMENTS_MINIMUM_PHP_MEMORY_LIMIT . '. 02339 The Extension Manager needs to include more PHP-classes than 02340 will fit into this memory space. There is nothing else to do 02341 than raise the limit. To be safe, ask the system 02342 administrator of the webserver to raise the limit to over 02343 ' . TYPO3_REQUIREMENTS_MINIMUM_PHP_MEMORY_LIMIT . '. 02344 </p> 02345 ', 3); 02346 } elseif(!$memory_limit_value) { 02347 $this->message($ext, 'Memory limit', ' 02348 <p> 02349 <em>No memory limit in effect.</em> 02350 </p> 02351 ', -1); 02352 } else { 02353 $this->message($ext, 'Memory limit: ' . ini_get('memory_limit'), '', -1); 02354 } 02355 if (ini_get('max_execution_time')<30) { 02356 $this->message($ext, 'Maximum execution time below 30 seconds', ' 02357 <p> 02358 <em>max_execution_time=' . ini_get('max_execution_time') . '</em> 02359 <br /> 02360 May impose problems if too low. 02361 </p> 02362 ', 1); 02363 } else { 02364 $this->message($ext, 'Maximum execution time: ' . ini_get('max_execution_time') . ' seconds', '', -1); 02365 } 02366 if (ini_get('disable_functions')) { 02367 $this->message($ext, 'Functions disabled!', ' 02368 <p> 02369 <em>disable_functions=' . ini_get('disable_functions') . '</em> 02370 <br /> 02371 The above list of functions are disabled. If TYPO3 use any 02372 of these there might be trouble. 02373 <br /> 02374 TYPO3 is designed to use the default set of PHP4.3.0+ 02375 functions plus the functions of GDLib. 02376 <br /> 02377 Possibly these functions are disabled due to security risks 02378 and most likely the list would include a function like 02379 <em>exec()</em> which is use by TYPO3 to access ImageMagick. 02380 </p> 02381 ', 2); 02382 } else { 02383 $this->message($ext, 'Functions disabled: none', '', -1); 02384 } 02385 // Mail tests 02386 if (TYPO3_OS == 'WIN') { 02387 $smtp = ini_get('SMTP'); 02388 $bad_smtp = false; 02389 if (!t3lib_div::validIP($smtp)) { 02390 $smtp_addr = @gethostbyname($smtp); 02391 $bad_smtp = ($smtp_addr == $smtp); 02392 } 02393 else { 02394 $smtp_addr = $smtp; 02395 } 02396 if (!$smtp || $bad_smtp || !t3lib_div::testInt(ini_get('smtp_port'))) { 02397 $this->message($ext, 'Mail configuration is not set correctly', ' 02398 <p> 02399 Mail configuration is not set 02400 <br /> 02401 PHP mail() function requires SMTP and smtp_port to have 02402 correct values on Windows. 02403 </p> 02404 ', 2); 02405 } else { 02406 if (($smtp_addr == '127.0.0.1' || $smtp_addr == '::1') && ($_SERVER['SERVER_ADDR'] == '127.0.0.1' || $_SERVER['SERVER_ADDR'] == '::1')) { 02407 $this->message($ext, 'Mail is configured (potential problem exists!)', ' 02408 <p> 02409 <em>SMTP=' . $smtp . '</em> - <strong>Note:</strong> 02410 this server! Are you sure it runs SMTP server? 02411 <br /> 02412 <em>smtp_port=' . ini_get('smtp_port') . '</em> 02413 </p>' . $this->check_mail('get_form') . ' 02414 ', 1); 02415 } else { 02416 $this->message($ext, 'Mail is configured', ' 02417 <p> 02418 <em>SMTP=' . $smtp . '</em> 02419 <br /> 02420 <em>smtp_port=' . ini_get('smtp_port') . '</em> 02421 </p>' . $this->check_mail('get_form') .' 02422 ', -1); 02423 } 02424 } 02425 } elseif (!ini_get('sendmail_path')) { 02426 $this->message($ext, 'Sendmail path not defined!', ' 02427 <p> 02428 This may be critical to TYPO3\'s use of the mail() function. 02429 Please be sure that the mail() function in your 02430 php-installation works! 02431 </p>' . $this->check_mail('get_form') . ' 02432 ', 1); 02433 } else { 02434 list($prg) = explode(' ', ini_get('sendmail_path')); 02435 if (!@is_executable($prg)) { 02436 $this->message($ext, 'Sendmail program not found or not executable?', ' 02437 <p> 02438 <em>sendmail_path=' . ini_get('sendmail_path') . '</em> 02439 <br /> 02440 This may be critical to TYPO3\'s use of the mail() 02441 function. Please be sure that the mail() function in 02442 your php-installation works! 02443 </p>' . $this->check_mail('get_form') .' 02444 ', 1); 02445 } else { 02446 $this->message($ext, 'Sendmail OK', ' 02447 <p> 02448 <em>sendmail_path=' . ini_get('sendmail_path') . '</em> 02449 </p>' . $this->check_mail('get_form') . ' 02450 ', -1); 02451 } 02452 } 02453 02454 // ***************** 02455 // Safe mode related 02456 // ***************** 02457 if (t3lib_utility_PhpOptions::isSafeModeEnabled()) { 02458 $this->message($ext, 'Safe mode turned on', ' 02459 <p> 02460 <em>safe_mode=' . ini_get('safe_mode') . '</em> 02461 <br /> 02462 In safe_mode PHP is restricted in several ways. This is a 02463 good thing because it adds protection to your (and others) 02464 scripts. But it may also introduce problems. In TYPO3 this 02465 <em>may be</em> a problem in two areas: File administration 02466 and execution of external programs, in particular 02467 ImageMagick. 02468 <br /> 02469 If you just ignore this warning, you\'ll most likely find, 02470 that TYPO3 seems to work except from the image-generation. 02471 The problem in that case is that the external ImageMagick 02472 programs are not allowed to be executed from the regular 02473 paths like "/usr/bin/" or "/usr/X11R6/bin/". 02474 <br /> 02475 If you use safe_mode with TYPO3, you should disable use of 02476 external programs ([BE][disable_exec_function]=1). 02477 <br /> 02478 In safe mode you must ensure that all the php-scripts and 02479 upload folders are owned by the same user. 02480 </p> 02481 <p> 02482 <em>safe_mode_exec_dir=' . ini_get('safe_mode_exec_dir') . '</em> 02483 <br /> 02484 If the ImageMagick utilities are located in this directory, 02485 everything is fine. Below on this page, you can see if 02486 ImageMagick is found here. If not, ask you ISP to put the 02487 three ImageMagick programs, \'convert\', 02488 \'combine\'/\'composite\' and \'identify\' there (eg. with 02489 symlinks if Unix server) 02490 </p> 02491 <p> 02492 <strong>Example of safe_mode settings:</strong> 02493 <br /> 02494 Set this in the php.ini file: 02495 </p> 02496 <p> 02497 ; Safe Mode 02498 <br /> 02499 safe_mode = On 02500 <br /> 02501 safe_mode_exec_dir = /usr/bin/ 02502 </p> 02503 <p> 02504 ...and the ImageMagick \'/usr/bin/convert\' will be 02505 executable. 02506 <br /> 02507 The last slash is important (..../) and you can only specify 02508 one directory. 02509 </p> 02510 <p> 02511 <strong>Notice: </strong> 02512 <br /> 02513 ImageMagick 6 or GraphicsMagick is recommended and the binaries are 02514 normally installed in /usr/bin. 02515 <br /> 02516 Paths to ImageMagick are defined in localconf.php and may be 02517 something else than /usr/bin/, but this is default for 02518 ImageMagick 6+ 02519 </p> 02520 ', 2); 02521 if (ini_get('doc_root')) { 02522 $this->message($ext, 'doc_root set', ' 02523 <p> 02524 <em>doc_root=' . ini_get('doc_root') . '</em> 02525 <br /> 02526 PHP cannot execute scripts outside this directory. If 02527 that is a problem is please correct it. 02528 </p> 02529 ', 1); 02530 } 02531 $this->config_array['safemode']=1; 02532 } else { 02533 $this->message($ext, 'safe_mode: off',"",-1); 02534 } 02535 if (t3lib_utility_PhpOptions::isSqlSafeModeEnabled()) { 02536 $this->message($ext, 'sql.safe_mode is enabled', ' 02537 <p> 02538 <em>sql.safe_mode=' . ini_get('sql.safe_mode') . '</em> 02539 <br /> 02540 This means that you can only connect to the database with a 02541 username corresponding to the user of the webserver process 02542 or fileowner. Consult your ISP for information about this. 02543 Also see <a href="http://www.wrox.com/Consumer/Store/Books/2963/29632002.htm"> 02544 http://www.wrox.com/Consumer/Store/Books/2963/29632002.htm</a> 02545 <br /> 02546 The owner of the current file is: 02547 <strong>' . get_current_user () . '</strong> 02548 </p> 02549 ', 1); 02550 $this->config_array['sql.safe_mode_user'] = get_current_user(); 02551 } else { 02552 $this->message($ext, 'sql.safe_mode: off',"",-1); 02553 } 02554 if (ini_get('open_basedir')) { 02555 $this->message($ext, 'open_basedir set', ' 02556 <p> 02557 <em>open_basedir=' . ini_get('open_basedir') . '</em> 02558 <br /> 02559 This restricts TYPO3 to open and include files only in this 02560 path. Please make sure that this does not prevent TYPO3 from 02561 running. 02562 <br /> 02563 <strong>Notice (UNIX):</strong> Before checking a path 02564 according to open_basedir, PHP resolves all symbolic links. 02565 </p> 02566 ', 1); 02567 // ???? If this option was set falsely you probably didn't see this page in the 02568 // first place, but this option <strong>may spoil this configuration test</strong> 02569 // when checking for such as ImageMagick executables. 02570 } else { 02571 $this->message($ext, 'open_basedir: off',"",-1); 02572 } 02573 02574 // Check availability of PHP session support 02575 if (extension_loaded('session')) { 02576 $this->message($ext, 'PHP sessions availiable', ' 02577 <p> 02578 <em>PHP Sessions availiabe</em> 02579 <br /> 02580 PHP is compiled with session support and session support is 02581 available. 02582 </p> 02583 ', -1); 02584 } else { 02585 $this->message($ext, 'PHP Sessions not availiabe', ' 02586 <p> 02587 PHP is not compiled with session support, or session support 02588 is disabled in php.ini. 02589 <br /> 02590 TYPO3 needs session support 02591 </p> 02592 ', 3); 02593 } 02594 02595 // Suhosin/Hardened PHP: 02596 $suhosinDescription = ' 02597 <p> 02598 Suhosin limits the number of elements that can be submitted in 02599 forms to the server. This will affect for example the 02600 "All configuration" section in the Install Tool or Inline 02601 Relational Record Editing (IRRE) with many child records. 02602 </p>'; 02603 if (extension_loaded('suhosin')) { 02604 $suhosinSuggestion = ' 02605 <p> 02606 At least a value of 400 is suggested. 02607 </p> 02608 '; 02609 02610 $suhosinRequestMaxVars = ini_get('suhosin.request.max_vars'); 02611 $suhosinPostMaxVars = ini_get('suhosin.post.max_vars'); 02612 $suhosinRequestMaxVarsType = ($suhosinRequestMaxVars < 400 ? 2 : -1); 02613 $suhosinPostMaxVarsType = ($suhosinPostMaxVars < 400 ? 2 : -1); 02614 $suhosinType = ($suhosinRequestMaxVars < 400 || $suhosinPostMaxVars < 400 ? 2 : -1); 02615 02616 $this->message($ext, 'Suhosin/Hardened PHP is loaded', $suhosinDescription, $suhosinType); 02617 $this->message($ext, 'suhosin.request.max_vars: ' . $suhosinRequestMaxVars, $suhosinSuggestion, $suhosinRequestMaxVarsType); 02618 $this->message($ext, 'suhosin.post.max_vars: ' . $suhosinPostMaxVars, $suhosinSuggestion, $suhosinPostMaxVarsType); 02619 } else { 02620 $this->message($ext, 'Suhosin/Hardened PHP is not loaded', $suhosinDescription, 0); 02621 } 02622 02623 // Check for stripped PHPdoc comments that are required to evaluate annotations: 02624 $method = new ReflectionMethod('tx_install', 'check_mail'); 02625 if (strlen($method->getDocComment()) === 0) { 02626 $description = ' 02627 <p> 02628 The system extension Extbase evaluates annotations in PHPdoc 02629 comments and thus requires eAccelerator not to strip away 02630 these parts. However, this is currently the only part in the 02631 TYPO3 Core (beside deprecation log and unit tests). If 02632 Extbase is not used, recompiling eAccelerator is not 02633 required at all. 02634 <br/> 02635 <br/> 02636 If you do not want comments to be stripped by eAccelerator, 02637 please recompile with the following configuration setting 02638 (<a href="http://eaccelerator.net/ticket/229" target="_blank"> 02639 more details</a>): 02640 <br /> 02641 <em>--with-eaccelerator-doc-comment-inclusion</em> 02642 </p> 02643 '; 02644 $this->message($ext, 'PHPdoc comments are stripped', $description, 2); 02645 } 02646 } 02647 02648 /** 02649 * Check if PHP function mail() works 02650 * 02651 * @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. 02652 * @return string The mail form if it is requested with get_form 02653 */ 02654 function check_mail($cmd='') { 02655 switch($cmd) { 02656 case 'get_form': 02657 $out = ' 02658 <p id="checkMailForm"> 02659 You can check the t3lib_mail functionality by entering your email 02660 address here and press the button. You should then 02661 receive a testmail from "typo3installtool@example.org". 02662 </p> 02663 '; 02664 // Get the template file 02665 $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'CheckMail.html'); 02666 // Get the template part from the file 02667 $template = t3lib_parsehtml::getSubpart($templateFile, '###TEMPLATE###'); 02668 02669 if (!empty($this->mailMessage)) { 02670 // Get the subpart for the mail is sent message 02671 $mailSentSubpart = t3lib_parsehtml::getSubpart($template, '###MAILSENT###'); 02672 } 02673 // Substitute the subpart for the mail is sent message 02674 $template = t3lib_parsehtml::substituteSubpart( 02675 $template, 02676 '###MAILSENT###', 02677 $mailSentSubpart 02678 ); 02679 // Define the markers content 02680 $markers = array( 02681 'message' => $this->mailMessage, 02682 'enterEmail' => 'Enter the email address', 02683 'actionUrl' => $this->action . '#checkMailForm', 02684 'submit' => 'Send test mail' 02685 ); 02686 // Fill the markers 02687 $out .= t3lib_parsehtml::substituteMarkerArray( 02688 $template, 02689 $markers, 02690 '###|###', 02691 TRUE, 02692 TRUE 02693 ); 02694 break; 02695 default: 02696 if (trim($this->INSTALL['check_mail'])) { 02697 $subject = 'TEST SUBJECT'; 02698 $email = trim($this->INSTALL['check_mail']); 02699 02700 /** @var $mailMessage t3lib_mail_Message */ 02701 $mailMessage = t3lib_div::makeInstance('t3lib_mail_Message'); 02702 $mailMessage->addTo($email) 02703 ->addFrom('typo3installtool@example.org', 'TYPO3 Install Tool') 02704 ->setSubject($subject) 02705 ->setBody('<html><body>HTML TEST CONTENT</body></html>'); 02706 $mailMessage->addPart('TEST CONTENT'); 02707 $mailMessage->send(); 02708 $this->mailMessage= 'Mail was sent to: ' . $email; 02709 } 02710 break; 02711 } 02712 return $out; 02713 } 02714 02715 /** 02716 * Checking php extensions, specifically GDLib and Freetype 02717 * 02718 * @return void 02719 */ 02720 function checkExtensions() { 02721 $ext = 'GDLib'; 02722 $this->message($ext); 02723 02724 $software_info=1; 02725 if (extension_loaded('gd') && $this->isGD()) { 02726 $this->config_array['gd']=1; 02727 $this->message($ext, 'GDLib found',"",-1); 02728 if ($this->isPNG()) { 02729 $this->config_array['gd_png']=1; 02730 $this->message($ext, 'PNG supported',"",-1); 02731 } 02732 if ($this->isGIF()) { 02733 $this->config_array['gd_gif']=1; 02734 $this->message($ext, 'GIF supported',"",-1); 02735 } 02736 if ($this->isJPG()) { 02737 $this->config_array['gd_jpg']=1; 02738 $this->message($ext, 'JPG supported (not used by TYPO3)',''); 02739 } 02740 if (!$this->config_array['gd_gif'] && !$this->config_array['gd_png']) { 02741 $this->message($ext, 'PNG or GIF not supported', ' 02742 <p> 02743 Your GDLib supports either GIF nor PNG. It must support 02744 either one of them. 02745 </p> 02746 ', 2); 02747 } else { 02748 $msg=array(); 02749 if ($this->config_array['gd_gif'] && $this->config_array['gd_png']) { 02750 $msg[] = ' 02751 <p> 02752 You can choose between generating GIF or PNG files, 02753 as your GDLib supports both. 02754 </p> 02755 '; 02756 } 02757 if ($this->config_array['gd_gif']) { 02758 $msg[] = ' 02759 <p> 02760 You should watch out for the generated size of the 02761 GIF-files because some versions of the GD library do 02762 not compress them with LZW, but RLE and ImageMagick 02763 is subsequently used to compress with LZW. But in 02764 the case of ImageMagick failing this task (eg. not 02765 being compiled with LZW which is the case with some 02766 versions) you\'ll end up with GIF-filesizes all too 02767 big! 02768 <br /> 02769 This Install Tool tests what kinds of GIF 02770 compression are available in the ImageMagick 02771 installations by a physical test. You can also check 02772 it manually by opening a TYPO3 generated gif-file 02773 with Photoshop and save it in a new file. If the 02774 file sizes of the original and the new file are 02775 almost the same, you\'re having LZW compression and 02776 everything is fine. 02777 </p> 02778 '; 02779 } 02780 if ($this->config_array['gd_png']) { 02781 $msg[] = ' 02782 <p> 02783 TYPO3 prefers the use of GIF-files and most likely 02784 your visitors on your website does too as not all 02785 browsers support PNG yet. 02786 </p> 02787 '; 02788 } 02789 $this->message($ext, 'GIF / PNG issues', implode(LF, $msg), 1); 02790 } 02791 if (!$this->isTTF()) { 02792 $this->message($ext, 'FreeType is apparently not installed', ' 02793 <p> 02794 It looks like the FreeType library is not compiled into 02795 GDLib. This is required when TYPO3 uses GDLib and 02796 you\'ll most likely get errors like \'ImageTTFBBox is 02797 not a function\' or \'ImageTTFText is not a function\'. 02798 </p> 02799 ', 2); 02800 } else { 02801 $this->message($ext, 'FreeType quick-test (' . ($this->isGIF() ? 'as GIF' : 'as PNG') . ')', ' 02802 <p> 02803 <img src="' . htmlspecialchars(t3lib_div::getIndpEnv('REQUEST_URI') . '&testingTrueTypeSupport=1') . '" alt="" /> 02804 <br /> 02805 (If the text is exceeding the image borders you are 02806 using Freetype 2 and need to set 02807 TYPO3_CONF_VARS[GFX][TTFdpi]=96. 02808 <br /> 02809 If there is no image at all Freetype is most likely NOT 02810 available and you can just as well disable GDlib for 02811 TYPO3...) 02812 </p> 02813 ', -1); 02814 $this->config_array['freetype']=1; 02815 } 02816 } else { 02817 $this->message($ext, 'GDLib2 not found', ' 02818 <p> 02819 GDLib2 is required if you want to use the GIFBUILDER object 02820 in TypoScript. GIFBUILDER is in charge of all advanced image 02821 generation in TypoScript, including graphical menuitems. 02822 <br /> 02823 GDLib2 is also used in the TYPO3 Backend (TBE) to generate 02824 record icons and new module tabs. 02825 <br /> 02826 It\'s highly recommended to install this library. Remember 02827 to compile GD with FreeType which is also required. 02828 <br /> 02829 If you choose not to install GDLib, you can disable it in 02830 the configuration with [GFX][gdlib]=0;. 02831 </p> 02832 ', 2); 02833 } 02834 $this->message($ext, 'GDLib software information', $this->getGDSoftwareInfo()); 02835 } 02836 02837 /** 02838 * Checking and testing that the required writable directories are writable. 02839 * 02840 * @return void 02841 */ 02842 function checkDirs() { 02843 // Check typo3/temp/ 02844 $ext='Directories'; 02845 $this->message($ext); 02846 02847 $uniqueName = md5(uniqid(microtime())); 02848 02849 // The requirement level (the integer value, ie. the second value of the value array) has the following meanings: 02850 // -1 = not required, but if it exists may be writable or not 02851 // 0 = not required, if it exists the dir should be writable 02852 // 1 = required, don't has to be writable 02853 // 2 = required, has to be writable 02854 02855 $checkWrite=array( 02856 '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'), 02857 'typo3temp/pics/' => array('This folder is part of the typo3temp/ section. It needs to be writable, too.',2,'dir_typo3temp'), 02858 'typo3temp/temp/' => array('This folder is part of the typo3temp/ section. It needs to be writable, too.',2,'dir_typo3temp'), 02859 'typo3temp/llxml/' => array('This folder is part of the typo3temp/ section. It needs to be writable, too.',2,'dir_typo3temp'), 02860 'typo3temp/cs/' => array('This folder is part of the typo3temp/ section. It needs to be writable, too.',2,'dir_typo3temp'), 02861 'typo3temp/GB/' => array('This folder is part of the typo3temp/ section. It needs to be writable, too.',2,'dir_typo3temp'), 02862 'typo3temp/locks/' => array('This folder is part of the typo3temp/ section. It needs to be writable, too.',2,'dir_typo3temp'), 02863 '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), 02864 'typo3conf/ext/' => array('Location for local extensions. Must be writable if the Extension Manager is supposed to install extensions for this website.',0), 02865 'typo3conf/l10n/' => array('Location for translations. Must be writable if the Extension Manager is supposed to install translations for extensions.',0), 02866 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), 02867 'uploads/' => array('Location for uploaded files from RTE, in the subdirectories for uploaded files of content elements.',2), 02868 'uploads/pics/' => array('Typical location for uploaded files (images especially).',0), 02869 'uploads/media/' => array('Typical location for uploaded files (non-images especially).',0), 02870 'uploads/tf/' => array('Typical location for uploaded files (TS template resources).',0), 02871 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileadminDir'] => array('Location for local files such as templates, independent uploads etc.',-1), 02872 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileadminDir'] . '_temp_/' => array('Typical temporary location for default upload of files by administrators.',0), 02873 ); 02874 02875 foreach ($checkWrite as $relpath => $descr) { 02876 02877 // Check typo3temp/ 02878 $general_message = $descr[0]; 02879 02880 // If the directory is missing, try to create it 02881 if (!@is_dir(PATH_site.$relpath)) { 02882 t3lib_div::mkdir(PATH_site.$relpath); 02883 } 02884 02885 if (!@is_dir(PATH_site.$relpath)) { 02886 if ($descr[1]) { // required... 02887 $this->message($ext, $relpath.' directory does not exist and could not be created', ' 02888 <p> 02889 <em>Full path: ' . PATH_site . $relpath . '</em> 02890 <br /> 02891 ' . $general_message . ' 02892 </p> 02893 <p> 02894 This error should not occur as ' . $relpath . ' must 02895 always be accessible in the root of a TYPO3 website. 02896 </p> 02897 ', 3); 02898 } else { 02899 if ($descr[1] == 0) { 02900 $msg = 'This directory does not necessarily have to exist but if it does it must be writable.'; 02901 } else { 02902 $msg = 'This directory does not necessarily have to exist and if it does it can be writable or not.'; 02903 } 02904 $this->message($ext, $relpath.' directory does not exist', ' 02905 <p> 02906 <em>Full path: ' . PATH_site . $relpath . '</em> 02907 <br /> 02908 ' . $general_message . ' 02909 </p> 02910 <p> 02911 ' . $msg . ' 02912 </p> 02913 ', 2); 02914 } 02915 } else { 02916 $file = PATH_site.$relpath.$uniqueName; 02917 @touch($file); 02918 if (@is_file($file)) { 02919 unlink($file); 02920 if ($descr[2]) { $this->config_array[$descr[2]]=1; } 02921 $this->message($ext, $relpath.' writable','',-1); 02922 } else { 02923 $severity = ($descr[1]==2 || $descr[1]==0) ? 3 : 2; 02924 if ($descr[1] == 0 || $descr[1] == 2) { 02925 $msg = 'The directory '.$relpath.' must be writable!'; 02926 } elseif ($descr[1] == -1 || $descr[1] == 1) { 02927 $msg = 'The directory '.$relpath.' does not neccesarily have to be writable.'; 02928 } 02929 $this->message($ext, $relpath .' directory not writable', ' 02930 <p> 02931 <em>Full path: ' . $file . '</em> 02932 <br /> 02933 ' . $general_message . ' 02934 </p> 02935 <p> 02936 Tried to write this file (with touch()) but didn\'t 02937 succeed. 02938 <br /> 02939 ' . $msg . ' 02940 </p> 02941 ', $severity); 02942 } 02943 } 02944 } 02945 } 02946 02947 /** 02948 * Checking for existing ImageMagick installs. 02949 * 02950 * 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. 02951 * 02952 * @param array $paths Possible ImageMagick paths 02953 * @return void 02954 */ 02955 function checkImageMagick($paths) { 02956 $ext='Check Image Magick'; 02957 $this->message($ext); 02958 // Get the template file 02959 $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'CheckImageMagick.html'); 02960 02961 $paths = array_unique($paths); 02962 02963 $programs = explode(',','gm,convert,combine,composite,identify'); 02964 $isExt = TYPO3_OS=="WIN" ? ".exe" : ""; 02965 $this->config_array['im_combine_filename']='combine'; 02966 foreach ($paths as $k => $v) { 02967 if (!preg_match('/[\\/]$/',$v)) $v.='/'; 02968 foreach ($programs as $filename) { 02969 if (ini_get('open_basedir') || (file_exists($v)&&@is_file($v.$filename.$isExt))) { 02970 $version = $this->_checkImageMagick_getVersion($filename,$v); 02971 if($version > 0) { 02972 // Assume GraphicsMagick 02973 if($filename=='gm') { 02974 $index[$v]['gm']=$version; 02975 // No need to check for "identify" etc. 02976 continue; 02977 } else { 02978 // Assume ImageMagick 02979 $index[$v][$filename]=$version; 02980 } 02981 } 02982 } 02983 } 02984 if (count($index[$v])>=3 || $index[$v]['gm']) { 02985 $this->config_array['im'] = 1; 02986 } 02987 02988 if ($index[$v]['gm'] || (!$index[$v]['composite'] && $index[$v]['combine'])) { 02989 $this->config_array['im_combine_filename']='combine'; 02990 } elseif ($index[$v]['composite'] && !$index[$v]['combine']) { 02991 $this->config_array['im_combine_filename']='composite'; 02992 } 02993 02994 if (isset($index[$v]['convert']) && $this->checkIMlzw) { 02995 $index[$v]['gif_capability'] = ''.$this->_checkImageMagickGifCapability($v); 02996 } 02997 } 02998 $this->config_array['im_versions']=$index; 02999 if (!$this->config_array['im']) { 03000 $this->message($ext, 'No ImageMagick installation available', ' 03001 <p> 03002 It seems that there is no adequate ImageMagick installation 03003 available at the checked locations (' . implode(', ', $paths) . ') 03004 <br /> 03005 An \'adequate\' installation for requires \'convert\', 03006 \'combine\'/\'composite\' and \'identify\' to be available 03007 </p> 03008 ', 2); 03009 } else { 03010 // Get the subpart for the ImageMagick versions 03011 $theCode = t3lib_parsehtml::getSubpart($templateFile, '###VERSIONS###'); 03012 // Get the subpart for each ImageMagick version 03013 $rowsSubPart = t3lib_parsehtml::getSubpart($theCode, '###ROWS###'); 03014 03015 $rows = array(); 03016 foreach ($this->config_array['im_versions'] as $p => $v) { 03017 $ka = array(); 03018 reset($v); 03019 while(list($ka[])=each($v)) {} 03020 // Define the markers content 03021 $rowsMarkers = array( 03022 'file' => $p, 03023 'type' => implode('<br />', $ka), 03024 'version' => implode('<br />', $v) 03025 ); 03026 // Fill the markers in the subpart 03027 $rows[] = t3lib_parsehtml::substituteMarkerArray( 03028 $rowsSubPart, 03029 $rowsMarkers, 03030 '###|###', 03031 TRUE, 03032 FALSE 03033 ); 03034 } 03035 // Substitute the subpart for the ImageMagick versions 03036 $theCode = t3lib_parsehtml::substituteSubpart( 03037 $theCode, 03038 '###ROWS###', 03039 implode(LF, $rows) 03040 ); 03041 // Add the content to the message array 03042 $this->message($ext, 'Available ImageMagick/GraphicsMagick installations:', $theCode, -1); 03043 } 03044 // Get the template file 03045 $formSubPart = t3lib_parsehtml::getSubpart($templateFile, '###FORM###'); 03046 // Define the markers content 03047 $formMarkers = array( 03048 'actionUrl' => $this->action, 03049 'lzwChecked' => ($this->INSTALL['checkIM']['lzw'] ? 'checked="checked"' : ''), 03050 'lzwLabel' => 'Check LZW capabilities.', 03051 'checkPath' => 'Check this path for ImageMagick installation:', 03052 'imageMagickPath' => htmlspecialchars($this->INSTALL['checkIM']['path']), 03053 'comment' => '(Eg. "D:\wwwroot\im537\ImageMagick\" for Windows or "/usr/bin/" for Unix)', 03054 'send' => 'Send' 03055 ); 03056 // Fill the markers 03057 $formSubPart = t3lib_parsehtml::substituteMarkerArray( 03058 $formSubPart, 03059 $formMarkers, 03060 '###|###', 03061 TRUE, 03062 FALSE 03063 ); 03064 // Add the content to the message array 03065 $this->message($ext, 'Search for ImageMagick:', $formSubPart, 0); 03066 } 03067 03068 /** 03069 * Checking GIF-compression capabilities of ImageMagick install 03070 * 03071 * @param string $path Path of ImageMagick installation 03072 * @return string Type of compression 03073 */ 03074 function _checkImageMagickGifCapability($path) { 03075 if ($this->config_array['dir_typo3temp']) { // && !$this->config_array['safemode'] 03076 $tempPath = $this->typo3temp_path; 03077 $uniqueName = md5(uniqid(microtime())); 03078 $dest = $tempPath.$uniqueName.'.gif'; 03079 $src = $this->backPath.'gfx/typo3logo.gif'; 03080 if (@is_file($src) && !strstr($src,' ') && !strstr($dest,' ')) { 03081 $cmd = t3lib_div::imageMagickCommand('convert', $src.' '.$dest, $path); 03082 t3lib_utility_Command::exec($cmd); 03083 } else die('No typo3/gfx/typo3logo.gif file!'); 03084 $out=''; 03085 if (@is_file($dest)) { 03086 $new_info = @getimagesize($dest); 03087 clearstatcache(); 03088 $new_size = filesize($dest); 03089 $src_info = @getimagesize($src); 03090 clearstatcache(); 03091 $src_size = @filesize($src); 03092 03093 if ($new_info[0]!=$src_info[0] || $new_info[1]!=$src_info[1] || !$new_size || !$src_size) { 03094 $out='error'; 03095 } else { 03096 // NONE-LZW ratio was 5.5 in test 03097 if ($new_size/$src_size > 4) { 03098 $out='NONE'; 03099 // NONE-RLE ratio was not tested 03100 } elseif ($new_size/$src_size > 1.5) { 03101 $out='RLE'; 03102 } else { 03103 $out='LZW'; 03104 } 03105 } 03106 unlink($dest); 03107 } 03108 return $out; 03109 } 03110 } 03111 03112 /** 03113 * Extracts the version number for ImageMagick 03114 * 03115 * @param string $file The program name to execute in order to find out the version number 03116 * @param string $path Path for the above program 03117 * @return string Version number of the found ImageMagick instance 03118 */ 03119 function _checkImageMagick_getVersion($file, $path) { 03120 // Temporarily override some settings 03121 $im_version = $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_version_5']; 03122 $combine_filename = $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_combine_filename']; 03123 03124 if ($file=='gm') { 03125 $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_version_5'] = 'gm'; 03126 // Work-around, preventing execution of "gm gm" 03127 $file = 'identify'; 03128 // Work-around - GM doesn't like to be executed without any arguments 03129 $parameters = '-version'; 03130 } else { 03131 $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_version_5'] = 'im5'; 03132 03133 // Override the combine_filename setting 03134 if ($file=='combine' || $file=='composite') { 03135 $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_combine_filename'] = $file; 03136 } 03137 } 03138 03139 $cmd = t3lib_div::imageMagickCommand($file, $parameters, $path); 03140 $retVal = false; 03141 t3lib_utility_Command::exec($cmd, $retVal); 03142 $string = $retVal[0]; 03143 list(,$ver) = explode('Magick', $string); 03144 list($ver) = explode(' ',trim($ver)); 03145 03146 // Restore the values 03147 $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_version_5'] = $im_version; 03148 $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_combine_filename'] = $combine_filename; 03149 return trim($ver); 03150 } 03151 03152 /** 03153 * Checks database username/password/host/database 03154 * 03155 * @return void 03156 */ 03157 function checkDatabase() { 03158 $ext='Check database'; 03159 $this->message($ext); 03160 03161 if (!extension_loaded('mysql') && !t3lib_extMgm::isLoaded('dbal')) { 03162 $this->message($ext, 'MySQL not available', ' 03163 <p> 03164 PHP does not feature MySQL support (which is pretty unusual). 03165 </p> 03166 ', 2); 03167 } else { 03168 if (!TYPO3_db_host || !TYPO3_db_username) { 03169 $this->message($ext, 'Username, password or host not set', ' 03170 <p> 03171 You may need to enter data for these values: 03172 <br /> 03173 Username: <strong>' . htmlspecialchars(TYPO3_db_username) . '</strong> 03174 <br /> 03175 Host: <strong>' . htmlspecialchars(TYPO3_db_host) . '</strong> 03176 <br /> 03177 <br /> 03178 Use the form below. 03179 </p> 03180 ', 2); 03181 } 03182 if ($result = $GLOBALS['TYPO3_DB']->sql_pconnect(TYPO3_db_host, TYPO3_db_username, TYPO3_db_password)) { 03183 $this->message($ext, 'Connected to SQL database successfully', ' 03184 <dl id="t3-install-databaseconnected"> 03185 <dt> 03186 Username: 03187 </dt> 03188 <dd> 03189 ' . htmlspecialchars(TYPO3_db_username) . ' 03190 </dd> 03191 <dt> 03192 Host: 03193 </dt> 03194 <dd> 03195 ' . htmlspecialchars(TYPO3_db_host) . ' 03196 </dd> 03197 </dl> 03198 ', -1, 1); 03199 $this->config_array['mysqlConnect']=1; 03200 if (!TYPO3_db) { 03201 $this->message($ext, 'No database selected', ' 03202 <p> 03203 Currently you have no database selected. 03204 <br /> 03205 Please select one or create a new database. 03206 </p> 03207 ', 3); 03208 $this->config_array['no_database']=1; 03209 } elseif (!$GLOBALS['TYPO3_DB']->sql_select_db(TYPO3_db)) { 03210 $this->message($ext, 'Database', ' 03211 <p> 03212 \'' . htmlspecialchars(TYPO3_db) . '\' could not be selected as database! 03213 <br /> 03214 Please select another one or create a new database. 03215 </p> 03216 ', 3, 1); 03217 $this->config_array['no_database']=1; 03218 } else { 03219 $this->message($ext, 'Database', ' 03220 <p> 03221 <strong>' . htmlspecialchars(TYPO3_db) . '</strong> is selected as 03222 database. 03223 </p> 03224 ', 1, 1); 03225 } 03226 } else { 03227 $sqlSafeModeUser = ''; 03228 03229 if ($this->config_array['sql.safe_mode_user']) { 03230 $sqlSafeModeUser = ' 03231 <strong>Notice:</strong> 03232 <em>sql.safe_mode</em> is turned on, so apparently your 03233 username to the database is the same as the scriptowner, 03234 which is ' . $this->config_array['sql.safe_mode_user']; 03235 } 03236 $this->message($ext, 'Could not connect to SQL database!', ' 03237 <p> 03238 Connecting to SQL database failed with these settings: 03239 <br /> 03240 Username: <strong>' . htmlspecialchars(TYPO3_db_username) . '</strong> 03241 <br /> 03242 Host: <strong>' . htmlspecialchars(TYPO3_db_host) . '</strong> 03243 </p> 03244 <p> 03245 Make sure you\'re using the correct set of data. 03246 <br /> 03247 ' . $sqlSafeModeUser . ' 03248 </p> 03249 ', 3); 03250 } 03251 } 03252 } 03253 03254 /** 03255 * Prints form for updating localconf.php or updates localconf.php depending on $cmd 03256 * 03257 * @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 03258 * @return string Form HTML 03259 */ 03260 function setupGeneral($cmd='') { 03261 switch($cmd) { 03262 case 'get_form': 03263 // Get the template file 03264 $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'SetupGeneral.html'); 03265 // Get the template part from the file 03266 $form = t3lib_parsehtml::getSubpart($templateFile, '###TEMPLATE###'); 03267 // Get the subpart for all modes 03268 $allModesSubpart = t3lib_parsehtml::getSubpart($form, '###ALLMODES###'); 03269 // Define the markers content 03270 $formMarkers['actionUrl'] = $this->action; 03271 03272 // Username 03273 if (TYPO3_db_username) { 03274 $username = TYPO3_db_username; 03275 } elseif ($this->config_array['sql.safe_mode_user']) { 03276 $username = $this->config_array['sql.safe_mode_user']; 03277 // Get the subpart for the sql safe mode user 03278 $sqlSafeModeUserSubpart = t3lib_parsehtml::getSubpart($allModesSubpart, '###SQLSAFEMODEUSERSUBPART###'); 03279 // Define the markers content 03280 $sqlSafeModeUserMarkers = array( 03281 'labelSqlSafeModeUser' => 'sql.safe_mode_user:', 03282 'sqlSafeModeUser' => $this->config_array['sql.safe_mode_user'] 03283 ); 03284 // Fill the markers in the subpart 03285 $sqlSafeModeUserSubpart = t3lib_parsehtml::substituteMarkerArray( 03286 $sqlSafeModeUserSubpart, 03287 $sqlSafeModeUserMarkers, 03288 '###|###', 03289 TRUE, 03290 FALSE 03291 ); 03292 } 03293 // Get the subpart for all modes 03294 $allModesSubpart = t3lib_parsehtml::substituteSubpart( 03295 $allModesSubpart, 03296 '###SQLSAFEMODEUSERSUBPART###', 03297 $sqlSafeModeUserSubpart 03298 ); 03299 // Define the markers content 03300 $allModesMarkers = array( 03301 'labelUsername' => 'Username:', 03302 'username' => htmlspecialchars($username), 03303 'labelPassword' => 'Password:', 03304 'password' => htmlspecialchars(TYPO3_db_password), 03305 'labelHost' => 'Host:', 03306 'host' => htmlspecialchars(TYPO3_db_host), 03307 'labelDatabase' => 'Database:', 03308 'labelCreateDatabase' => 'Create database?' 03309 ); 03310 // Get the subpart for the database list 03311 $databasesSubpart = t3lib_parsehtml::getSubpart($allModesSubpart, '###DATABASELIST###'); 03312 if ($this->config_array['mysqlConnect']) { 03313 // Get the subpart when database is available 03314 $databaseAvailableSubpart = t3lib_parsehtml::getSubpart($databasesSubpart, '###DATABASEAVAILABLE###'); 03315 // Get the subpart for each database table 03316 $databaseItemSubpart = t3lib_parsehtml::getSubpart($databaseAvailableSubpart, '###DATABASEITEM###'); 03317 $dbArr = $this->getDatabaseList(); 03318 $dbIncluded=0; 03319 $databaseItems = array(); 03320 foreach ($dbArr as $dbname) { 03321 // Define the markers content 03322 $databaseItemMarkers = array( 03323 'databaseSelected' => '', 03324 'databaseName' => htmlspecialchars($dbname), 03325 'databaseValue' => htmlspecialchars($dbname) 03326 ); 03327 if ($dbname == TYPO3_db) { 03328 $databaseItemMarkers['databaseSelected'] = 'selected="selected"'; 03329 } 03330 // Fill the markers in the subpart 03331 $databaseItems[] = t3lib_parsehtml::substituteMarkerArray( 03332 $databaseItemSubpart, 03333 $databaseItemMarkers, 03334 '###|###', 03335 TRUE, 03336 FALSE 03337 ); 03338 if ($dbname==TYPO3_db) $dbIncluded=1; 03339 } 03340 if (!$dbIncluded && TYPO3_db) { 03341 $databaseItemMarkers['databaseName'] = htmlspecialchars(TYPO3_db); 03342 $databaseItemMarkers['databaseSelected'] = 'selected="selected"'; 03343 $databaseItemMarkers['databaseValue'] = htmlspecialchars(TYPO3_db) . ' (NO ACCESS!)'; 03344 // Fill the markers in the subpart 03345 $databaseItems[] = t3lib_parsehtml::substituteMarkerArray( 03346 $databaseItemSubpart, 03347 $databaseItemMarkers, 03348 '###|###', 03349 TRUE, 03350 FALSE 03351 ); 03352 } 03353 // Substitute the subpart for the database tables 03354 $databaseAvailableSubpart = t3lib_parsehtml::substituteSubpart( 03355 $databaseAvailableSubpart, 03356 '###DATABASEITEM###', 03357 implode(LF, $databaseItems) 03358 ); 03359 } else { 03360 // Get the subpart when the database is not available 03361 $databaseNotAvailableSubpart = t3lib_parsehtml::getSubpart($databasesSubpart, '###DATABASENOTAVAILABLE###'); 03362 $databaseNotAvailableMarkers = array( 03363 'typo3Db' => htmlspecialchars(TYPO3_db), 03364 'labelNoDatabase' => ' 03365 (Can only select database if username/password/host 03366 is correctly set first) 03367 ' 03368 ); 03369 // Fill the markers in the subpart 03370 $databaseNotAvailableSubpart = t3lib_parsehtml::substituteMarkerArray( 03371 $databaseNotAvailableSubpart, 03372 $databaseNotAvailableMarkers, 03373 '###|###', 03374 TRUE, 03375 FALSE 03376 ); 03377 } 03378 // Substitute the subpart when database is available 03379 $databasesSubpart = t3lib_parsehtml::substituteSubpart( 03380 $databasesSubpart, 03381 '###DATABASEAVAILABLE###', 03382 $databaseAvailableSubpart 03383 ); 03384 // Substitute the subpart when database is not available 03385 $databasesSubpart = t3lib_parsehtml::substituteSubpart( 03386 $databasesSubpart, 03387 '###DATABASENOTAVAILABLE###', 03388 $databaseNotAvailableSubpart 03389 ); 03390 // Substitute the subpart for the databases 03391 $allModesSubpart = t3lib_parsehtml::substituteSubpart( 03392 $allModesSubpart, 03393 '###DATABASELIST###', 03394 $databasesSubpart 03395 ); 03396 // Fill the markers in the subpart for all modes 03397 $allModesSubpart = t3lib_parsehtml::substituteMarkerArray( 03398 $allModesSubpart, 03399 $allModesMarkers, 03400 '###|###', 03401 TRUE, 03402 FALSE 03403 ); 03404 // Substitute the subpart for all modes 03405 $form = t3lib_parsehtml::substituteSubpart( 03406 $form, 03407 '###ALLMODES###', 03408 $allModesSubpart 03409 ); 03410 03411 if ($this->mode!='123') { 03412 // Get the subpart for the regular mode 03413 $regularModeSubpart = t3lib_parsehtml::getSubpart($form, '###REGULARMODE###'); 03414 // Define the markers content 03415 $regularModeMarkers = array( 03416 'labelSiteName' => 'Site name:', 03417 'siteName' => htmlspecialchars($GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename']), 03418 'labelEncryptionKey' => 'Encryption key:', 03419 'encryptionKey' => htmlspecialchars($GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey']), 03420 'labelGenerateRandomKey' => 'Generate random key' 03421 ); 03422 03423 // Other 03424 $fA = $this->setupGeneralCalculate(); 03425 $regularModeMarkers['labelCurrentValueIs'] = 'current value is'; 03426 03427 // Disable exec function 03428 if (is_array($fA['disable_exec_function'])) { 03429 // Get the subpart for the disable exec function 03430 $disableExecFunctionSubpart = t3lib_parsehtml::getSubpart($regularModeSubpart, '###DISABLEEXECFUNCTIONSUBPART###'); 03431 $regularModeMarkers['labelDisableExecFunction'] = '[BE][disable_exec_function]='; 03432 $regularModeMarkers['strongDisableExecFunction'] = (integer) current($fA['disable_exec_function']); 03433 $regularModeMarkers['defaultDisableExecFunction'] = (integer) $GLOBALS['TYPO3_CONF_VARS']['BE']['disable_exec_function']; 03434 $regularModeMarkers['disableExecFunction'] = (integer) current($fA['disable_exec_function']); 03435 // Fill the markers in the subpart 03436 $disableExecFunctionSubpart = t3lib_parsehtml::substituteMarkerArray( 03437 $disableExecFunctionSubpart, 03438 $regularModeMarkers, 03439 '###|###', 03440 TRUE, 03441 FALSE 03442 ); 03443 } 03444 // Substitute the subpart for the disable exec function 03445 $regularModeSubpart = t3lib_parsehtml::substituteSubpart( 03446 $regularModeSubpart, 03447 '###DISABLEEXECFUNCTIONSUBPART###', 03448 $disableExecFunctionSubpart 03449 ); 03450 03451 // GDlib 03452 if (is_array($fA['gdlib'])) { 03453 // Get the subpart for the disable gd lib 03454 $gdLibSubpart = t3lib_parsehtml::getSubpart($regularModeSubpart, '###DISABLEGDLIB###'); 03455 $regularModeMarkers['labelGdLib'] = '[GFX][gdlib]='; 03456 $regularModeMarkers['strongGdLib'] = (integer) current($fA['gdlib']); 03457 $regularModeMarkers['defaultGdLib'] = (integer) $GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib']; 03458 $regularModeMarkers['gdLib'] = (integer) current($fA['gdlib']); 03459 // Fill the markers in the subpart 03460 $gdLibSubpart = t3lib_parsehtml::substituteMarkerArray( 03461 $gdLibSubpart, 03462 $regularModeMarkers, 03463 '###|###', 03464 TRUE, 03465 FALSE 03466 ); 03467 } 03468 // Substitute the subpart for the disable gdlib 03469 $regularModeSubpart = t3lib_parsehtml::substituteSubpart( 03470 $regularModeSubpart, 03471 '###DISABLEGDLIB###', 03472 $gdLibSubpart 03473 ); 03474 03475 // GDlib PNG 03476 if (is_array($fA['gdlib_png']) && $GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib']) { 03477 // Get the subpart for the gdlib png 03478 $gdLibPngSubpart = t3lib_parsehtml::getSubpart($regularModeSubpart, '###GDLIBPNGSUBPART###'); 03479 // Get the subpart for the dropdown options 03480 $gdLibPngOptionSubpart = t3lib_parsehtml::getSubpart($gdLibPngSubpart, '###GDLIBPNGOPTION###'); 03481 $gdLibPngLabels = $this->setLabelValueArray($fA['gdlib_png'], 2); 03482 reset($gdLibPngLabels); 03483 03484 $regularModeMarkers['labelGdLibPng'] = '[GFX][gdlib_png]='; 03485 $regularModeMarkers['strongGdLibPng'] = (string) current($gdLibPngLabels); 03486 $regularModeMarkers['defaultGdLibPng'] = (integer) $GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib_png']; 03487 03488 $gdLibPngOptions = array(); 03489 foreach ($gdLibPngLabels as $k => $v) { 03490 list($cleanV) = explode('|', $fA['gdlib_png'][$k]); 03491 $gdLibPngMarker['value'] = htmlspecialchars($fA['gdlib_png'][$k]); 03492 $gdLibPngMarker['data'] = htmlspecialchars($v); 03493 if (!strcmp($GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib_png'], $cleanV)) { 03494 $gdLibPngMarker['selected'] = 'selected="selected"'; 03495 } 03496 // Fill the markers in the subpart 03497 $gdLibPngOptions[] = t3lib_parsehtml::substituteMarkerArray( 03498 $gdLibPngOptionSubpart, 03499 $gdLibPngMarker, 03500 '###|###', 03501 TRUE, 03502 FALSE 03503 ); 03504 } 03505 // Substitute the subpart for the dropdown options 03506 $gdLibPngSubpart = t3lib_parsehtml::substituteSubpart( 03507 $gdLibPngSubpart, 03508 '###GDLIBPNGOPTION###', 03509 implode(LF, $gdLibPngOptions) 03510 ); 03511 // Fill the markers in the subpart 03512 $gdLibPngSubpart = t3lib_parsehtml::substituteMarkerArray( 03513 $gdLibPngSubpart, 03514 $regularModeMarkers, 03515 '###|###', 03516 TRUE, 03517 FALSE 03518 ); 03519 } 03520 // Substitute the subpart for the gdlib png 03521 $regularModeSubpart = t3lib_parsehtml::substituteSubpart( 03522 $regularModeSubpart, 03523 '###GDLIBPNGSUBPART###', 03524 $gdLibPngSubpart 03525 ); 03526 03527 // ImageMagick 03528 if (is_array($fA['im'])) { 03529 // Get the subpart for ImageMagick 03530 $imageMagickSubpart = t3lib_parsehtml::getSubpart($regularModeSubpart, '###IMAGEMAGICKSUBPART###'); 03531 // Define the markers content 03532 $regularModeMarkers['labelImageMagick'] = '[GFX][im]='; 03533 $regularModeMarkers['strongImageMagick'] = (string) current($fA['im']); 03534 $regularModeMarkers['defaultImageMagick'] = (integer) $GLOBALS['TYPO3_CONF_VARS']['GFX']['im']; 03535 $regularModeMarkers['imageMagick'] = (integer) current($fA['im']); 03536 // Fill the markers in the subpart 03537 $imageMagickSubpart = t3lib_parsehtml::substituteMarkerArray( 03538 $imageMagickSubpart, 03539 $regularModeMarkers, 03540 '###|###', 03541 TRUE, 03542 FALSE 03543 ); 03544 03545 // IM Combine Filename 03546 // Get the subpart for ImageMagick Combine filename 03547 $imCombineFileNameSubpart = t3lib_parsehtml::getSubpart($regularModeSubpart, '###IMCOMBINEFILENAMESUBPART###'); 03548 // Define the markers content 03549 $regularModeMarkers['labelImCombineFilename'] = '[GFX][im_combine_filename]'; 03550 $regularModeMarkers['strongImCombineFilename'] = (string) current($fA['im_combine_filename']); 03551 $regularModeMarkers['defaultImCombineFilename'] = (string) $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_combine_filename']; 03552 $regularModeMarkers['imCombineFilename'] = (string) ($fA['im_combine_filename'] ? current($fA['im_combine_filename']) : 'combine'); 03553 // Fill the markers in the subpart 03554 $imCombineFileNameSubpart = t3lib_parsehtml::substituteMarkerArray( 03555 $imCombineFileNameSubpart, 03556 $regularModeMarkers, 03557 '###|###', 03558 TRUE, 03559 FALSE 03560 ); 03561 03562 // IM Version 5 03563 // Get the subpart for ImageMagick Version 5 03564 $imVersion5Subpart = t3lib_parsehtml::getSubpart($regularModeSubpart, '###IMVERSION5SUBPART###'); 03565 // Define the markers content 03566 $regularModeMarkers['labelImVersion5'] = '[GFX][im_version_5]='; 03567 $regularModeMarkers['strongImVersion5'] = (string) current($fA['im_version_5']); 03568 $regularModeMarkers['defaultImVersion5'] = (string) $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_version_5']; 03569 $regularModeMarkers['imVersion5'] = (string) ($fA['im_version_5'] ? current($fA['im_version_5']) : ''); 03570 // Fill the markers in the subpart 03571 $imVersion5Subpart = t3lib_parsehtml::substituteMarkerArray( 03572 $imVersion5Subpart, 03573 $regularModeMarkers, 03574 '###|###', 03575 TRUE, 03576 FALSE 03577 ); 03578 03579 if ($GLOBALS['TYPO3_CONF_VARS']['GFX']['im']) { 03580 // IM Path 03581 if (is_array($fA['im_path'])) { 03582 // Get the subpart for ImageMagick path 03583 $imPathSubpart = t3lib_parsehtml::getSubpart($regularModeSubpart, '###IMPATHSUBPART###'); 03584 03585 $labelImPath = $this->setLabelValueArray($fA['im_path'], 1); 03586 reset($labelImPath); 03587 $imPath = $this->setLabelValueArray($fA['im_path'], 0); 03588 reset($imPath); 03589 // Define the markers content 03590 $regularModeMarkers['labelImPath'] = '[GFX][im_path]='; 03591 $regularModeMarkers['strongImPath'] = (string) current($labelImPath); 03592 $regularModeMarkers['defaultImPath'] = (string) $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_path']; 03593 $regularModeMarkers['ImPath'] = (string) current($imPath); 03594 // Fill the markers in the subpart 03595 $imPathSubpart = t3lib_parsehtml::substituteMarkerArray( 03596 $imPathSubpart, 03597 $regularModeMarkers, 03598 '###|###', 03599 TRUE, 03600 FALSE 03601 ); 03602 } 03603 // IM Path LZW 03604 if (is_array($fA['im_path_lzw'])) { 03605 // Get the subpart for ImageMagick lzw path 03606 $imPathLzwSubpart = t3lib_parsehtml::getSubpart($regularModeSubpart, '###IMPATHLZWSUBPART###'); 03607 // Get the subpart for ImageMagick lzw path dropdown options 03608 $imPathOptionSubpart = t3lib_parsehtml::getSubpart($regularModeSubpart, '###IMPATHLZWOPTION###'); 03609 03610 $labelImPathLzw = $this->setLabelValueArray($fA['im_path_lzw'], 1); 03611 reset($labelImPathLzw); 03612 $imPathLzw = $this->setLabelValueArray($fA['im_path_lzw'], 0); 03613 reset($imPathLzw); 03614 // Define the markers content 03615 $regularModeMarkers['labelImPathLzw'] = '[GFX][im_path_lzw]='; 03616 $regularModeMarkers['strongImPathLzw'] = (string) current($labelImPathLzw); 03617 $regularModeMarkers['defaultImPathLzw'] = (string) $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_path_lzw']; 03618 $regularModeMarkers['ImPathLzw'] = (string) current($imPathLzw); 03619 03620 $imPathLzwOptions = array(); 03621 foreach ($labelImPathLzw as $k => $v) { 03622 list($cleanV) = explode('|', $fA['im_path_lzw'][$k]); 03623 // Define the markers content 03624 $imPathLzwMarker = array( 03625 'value' => htmlspecialchars($fA['im_path_lzw'][$k]), 03626 'data' => htmlspecialchars($v) 03627 ); 03628 if (!strcmp($GLOBALS['TYPO3_CONF_VARS']['GFX']['im_path_lzw'], $cleanV)) { 03629 $imPathLzwMarker['selected'] = 'selected="selected"'; 03630 } 03631 // Fill the markers in the subpart 03632 $imPathLzwOptions[] = t3lib_parsehtml::substituteMarkerArray( 03633 $imPathOptionSubpart, 03634 $imPathLzwMarker, 03635 '###|###', 03636 TRUE, 03637 FALSE 03638 ); 03639 } 03640 // Substitute the subpart for ImageMagick lzw path dropdown options 03641 $imPathLzwSubpart = t3lib_parsehtml::substituteSubpart( 03642 $imPathLzwSubpart, 03643 '###IMPATHLZWOPTION###', 03644 implode(LF, $imPathLzwOptions) 03645 ); 03646 // Fill the markers in the subpart 03647 $imPathLzwSubpart = t3lib_parsehtml::substituteMarkerArray( 03648 $imPathLzwSubpart, 03649 $regularModeMarkers, 03650 '###|###', 03651 TRUE, 03652 FALSE 03653 ); 03654 } 03655 } 03656 } 03657 // Substitute the subpart for ImageMagick 03658 $regularModeSubpart = t3lib_parsehtml::substituteSubpart( 03659 $regularModeSubpart, 03660 '###IMAGEMAGICKSUBPART###', 03661 $imageMagickSubpart 03662 ); 03663 // Substitute the subpart for ImageMagick Combine filename 03664 $regularModeSubpart = t3lib_parsehtml::substituteSubpart( 03665 $regularModeSubpart, 03666 '###IMCOMBINEFILENAMESUBPART###', 03667 $imCombineFileNameSubpart 03668 ); 03669 // Substitute the subpart for ImageMagick Version 5 03670 $regularModeSubpart = t3lib_parsehtml::substituteSubpart( 03671 $regularModeSubpart, 03672 '###IMVERSION5SUBPART###', 03673 $imVersion5Subpart 03674 ); 03675 // Substitute the subpart for ImageMagick path 03676 $regularModeSubpart = t3lib_parsehtml::substituteSubpart( 03677 $regularModeSubpart, 03678 '###IMPATHSUBPART###', 03679 $imPathSubpart 03680 ); 03681 // Substitute the subpart for ImageMagick lzw path 03682 $regularModeSubpart = t3lib_parsehtml::substituteSubpart( 03683 $regularModeSubpart, 03684 '###IMPATHLZWSUBPART###', 03685 $imPathLzwSubpart 03686 ); 03687 03688 // TrueType Font dpi 03689 // Get the subpart for TrueType dpi 03690 $ttfDpiSubpart = t3lib_parsehtml::getSubpart($regularModeSubpart, '###TTFDPISUBPART###'); 03691 // Define the markers content 03692 $regularModeMarkers['labelTtfDpi'] = '[GFX][TTFdpi]='; 03693 $regularModeMarkers['ttfDpi'] = htmlspecialchars($GLOBALS['TYPO3_CONF_VARS']['GFX']['TTFdpi']); 03694 // Fill the markers in the subpart 03695 $ttfDpiSubpart = t3lib_parsehtml::substituteMarkerArray( 03696 $ttfDpiSubpart, 03697 $regularModeMarkers, 03698 '###|###', 03699 TRUE, 03700 FALSE 03701 ); 03702 // Substitute the subpart for TrueType dpi 03703 $regularModeSubpart = t3lib_parsehtml::substituteSubpart( 03704 $regularModeSubpart, 03705 '###TTFDPISUBPART###', 03706 $ttfDpiSubpart 03707 ); 03708 // Fill the markers in the regular mode subpart 03709 $regularModeSubpart = t3lib_parsehtml::substituteMarkerArray( 03710 $regularModeSubpart, 03711 $regularModeMarkers, 03712 '###|###', 03713 TRUE, 03714 FALSE 03715 ); 03716 } 03717 03718 $formMarkers['labelUpdateLocalConf'] = 'Update localconf.php'; 03719 $formMarkers['labelNotice'] = 'NOTICE:'; 03720 $formMarkers['labelCommentUpdateLocalConf'] = 'By clicking this button, localconf.php is updated with new values for the parameters listed above!'; 03721 // Substitute the subpart for regular mode 03722 $form = t3lib_parsehtml::substituteSubpart( 03723 $form, 03724 '###REGULARMODE###', 03725 $regularModeSubpart 03726 ); 03727 // Fill the markers 03728 $out = t3lib_parsehtml::substituteMarkerArray( 03729 $form, 03730 $formMarkers, 03731 '###|###', 03732 TRUE, 03733 FALSE 03734 ); 03735 break; 03736 default: 03737 if (is_array($this->INSTALL['localconf.php'])) { 03738 $lines = $this->writeToLocalconf_control(); 03739 03740 // New database? 03741 if (trim($this->INSTALL['localconf.php']['NEW_DATABASE_NAME'])) { 03742 $newdbname=trim($this->INSTALL['localconf.php']['NEW_DATABASE_NAME']); 03743 if (!preg_match('/[^[:alnum:]_-]/',$newdbname)) { 03744 if ($result = $GLOBALS['TYPO3_DB']->sql_pconnect(TYPO3_db_host, TYPO3_db_username, TYPO3_db_password)) { 03745 if ($GLOBALS['TYPO3_DB']->admin_query('CREATE DATABASE '.$newdbname)) { 03746 $this->INSTALL['localconf.php']['typo_db'] = $newdbname; 03747 $this->messages[]= "Database '".$newdbname."' created"; 03748 } else { 03749 $this->errorMessages[] = ' 03750 Could not create database \'' . 03751 $newdbname . '\' (...not created) 03752 '; 03753 } 03754 } else { 03755 $this->errorMessages[] = ' 03756 Could not connect to database when creating 03757 database \'' . $newdbname . '\' (...not 03758 created) 03759 '; 03760 } 03761 } else { 03762 $this->errorMessages[] = ' 03763 The NEW database name \'' . $newdbname . '\' was 03764 not alphanumeric, a-zA-Z0-9_- (...not created) 03765 '; 03766 } 03767 } 03768 // Parsing values 03769 foreach ($this->INSTALL['localconf.php'] as $key => $value) { 03770 switch((string)$key) { 03771 case 'typo_db_username': 03772 if (strlen($value)<50) { 03773 if (strcmp(TYPO3_db_username,$value)) $this->setValueInLocalconfFile($lines, '$typo_db_username', trim($value)); 03774 } else { 03775 $this->errorMessages[] = ' 03776 Username \'' . $value . '\' was longer 03777 than 50 chars (...not saved) 03778 '; 03779 } 03780 break; 03781 case 'typo_db_password': 03782 if (strlen($value)<50) { 03783 if (strcmp(TYPO3_db_password,$value)) $this->setValueInLocalconfFile($lines, '$typo_db_password', trim($value)); 03784 } else { 03785 $this->errorMessages[] = ' 03786 Password was longer than 50 chars (...not saved) 03787 '; 03788 } 03789 break; 03790 case 'typo_db_host': 03791 if (preg_match('/^[a-zA-Z0-9_\.-]+(:.+)?$/',$value) && strlen($value)<50) { 03792 if (strcmp(TYPO3_db_host,$value)) $this->setValueInLocalconfFile($lines, '$typo_db_host', $value); 03793 } else { 03794 $this->errorMessages[] = ' 03795 Host \'' . $value . '\' was not 03796 alphanumeric (a-z, A-Z, 0-9 or _-.), or 03797 longer than 50 chars (...not saved) 03798 '; 03799 } 03800 break; 03801 case 'typo_db': 03802 if (strlen($value)<50) { 03803 if (strcmp(TYPO3_db,$value)) $this->setValueInLocalconfFile($lines, '$typo_db', trim($value)); 03804 } else { 03805 $this->errorMessages[] = ' 03806 Database name \'' . $value . '\' was 03807 longer than 50 chars (...not saved) 03808 '; 03809 } 03810 break; 03811 case 'disable_exec_function': 03812 if (strcmp($GLOBALS['TYPO3_CONF_VARS']['BE']['disable_exec_function'],$value)) $this->setValueInLocalconfFile($lines, '$TYPO3_CONF_VARS[\'BE\'][\'disable_exec_function\']', $value?1:0); 03813 break; 03814 case 'sitename': 03815 if (strcmp($GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'],$value)) $this->setValueInLocalconfFile($lines, '$TYPO3_CONF_VARS[\'SYS\'][\'sitename\']', $value); 03816 break; 03817 case 'encryptionKey': 03818 if (strcmp($GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'],$value)) $this->setValueInLocalconfFile($lines, '$TYPO3_CONF_VARS[\'SYS\'][\'encryptionKey\']', $value); 03819 break; 03820 case 'compat_version': 03821 if (strcmp($GLOBALS['TYPO3_CONF_VARS']['SYS']['compat_version'],$value)) $this->setValueInLocalconfFile($lines, '$TYPO3_CONF_VARS[\'SYS\'][\'compat_version\']', $value); 03822 break; 03823 case 'im_combine_filename': 03824 if (strcmp($GLOBALS['TYPO3_CONF_VARS']['GFX']['im_combine_filename'],$value)) $this->setValueInLocalconfFile($lines, '$TYPO3_CONF_VARS[\'GFX\'][\'im_combine_filename\']', $value); 03825 break; 03826 case 'gdlib': 03827 case 'gdlib_png': 03828 case 'im': 03829 if (strcmp($GLOBALS['TYPO3_CONF_VARS']['GFX'][$key], $value)) { 03830 $this->setValueInLocalconfFile($lines, '$TYPO3_CONF_VARS[\'GFX\'][\'' . $key . '\']', ($value ? 1 : 0)); 03831 } 03832 break; 03833 case 'im_path': 03834 list($value,$version) = explode('|',$value); 03835 if (strcmp($GLOBALS['TYPO3_CONF_VARS']['GFX'][$key], $value)) { 03836 $this->setValueInLocalconfFile($lines, '$TYPO3_CONF_VARS[\'GFX\'][\'' . $key . '\']', $value); 03837 } 03838 if (doubleval($version) > 0 && doubleval($version) < 4) { 03839 // Assume GraphicsMagick 03840 $value_ext = 'gm'; 03841 } elseif (doubleval($version) < 5) { 03842 // Assume ImageMagick 4.x 03843 $value_ext = ''; 03844 } elseif (doubleval($version) >= 6) { 03845 // Assume ImageMagick 6.x 03846 $value_ext = 'im6'; 03847 } else { 03848 // Assume ImageMagick 5.x 03849 $value_ext = 'im5'; 03850 } 03851 if (strcmp(strtolower($GLOBALS['TYPO3_CONF_VARS']['GFX']['im_version_5']), $value_ext)) { 03852 $this->setValueInLocalconfFile($lines, '$TYPO3_CONF_VARS[\'GFX\'][\'im_version_5\']', $value_ext); 03853 } 03854 break; 03855 case 'im_path_lzw': 03856 list($value) = explode('|',$value); 03857 if (strcmp($GLOBALS['TYPO3_CONF_VARS']['GFX'][$key], $value)) { 03858 $this->setValueInLocalconfFile($lines, '$TYPO3_CONF_VARS[\'GFX\'][\'' . $key . '\']', $value); 03859 } 03860 break; 03861 case 'TTFdpi': 03862 if (strcmp($GLOBALS['TYPO3_CONF_VARS']['GFX']['TTFdpi'],$value)) $this->setValueInLocalconfFile($lines, '$TYPO3_CONF_VARS[\'GFX\'][\'TTFdpi\']', $value); 03863 break; 03864 } 03865 } 03866 03867 // Hook to modify localconf.php lines in the 1-2-3 installer 03868 if (is_array ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install/mod/class.tx_install.php']['writeLocalconf'])) { 03869 foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install/mod/class.tx_install.php']['writeLocalconf'] as $classData) { 03870 $hookObject = t3lib_div::getUserObj($classData); 03871 $hookObject->executeWriteLocalconf($lines, $this->step, $this); 03872 } 03873 } 03874 $this->writeToLocalconf_control($lines); 03875 } 03876 break; 03877 } 03878 return $out; 03879 } 03880 03881 /** 03882 * Writes or returns lines from localconf.php 03883 * 03884 * @param array $lines Array of lines to write back to localconf.php. Possibly 03885 * @param boolean $showOutput If TRUE then print what has been done. 03886 * @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) 03887 * @see parent::writeToLocalconf_control() 03888 */ 03889 function writeToLocalconf_control($lines='', $showOutput=TRUE) { 03890 // Get the template file 03891 $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'WriteToLocalConfControl.html'); 03892 03893 $returnVal = parent::writeToLocalconf_control($lines); 03894 03895 if ($showOutput) { 03896 switch($returnVal) { 03897 case 'continue': 03898 // Get the template part from the file 03899 $template = t3lib_parsehtml::getSubpart($templateFile, '###CONTINUE###'); 03900 // Get the subpart for messages 03901 $messagesSubPart = t3lib_parsehtml::getSubpart($template, '###MESSAGES###'); 03902 03903 $messages = array(); 03904 03905 foreach ($this->messages as $message) { 03906 // Define the markers content 03907 $messagesMarkers['message'] = $message; 03908 // Fill the markers in the subpart 03909 $messages[] = t3lib_parsehtml::substituteMarkerArray( 03910 $messagesSubPart, 03911 $messagesMarkers, 03912 '###|###', 03913 TRUE, 03914 FALSE 03915 ); 03916 } 03917 // Substitute the subpart for messages 03918 $content = t3lib_parsehtml::substituteSubpart( 03919 $template, 03920 '###MESSAGES###', 03921 implode(LF, $messages) 03922 ); 03923 // Define the markers content 03924 $markers = array( 03925 'header' => 'Writing to \'localconf.php\'', 03926 'action' => $this->action, 03927 'label' => 'Click to continue...' 03928 ); 03929 // Fill the markers 03930 $content = t3lib_parsehtml::substituteMarkerArray( 03931 $content, 03932 $markers, 03933 '###|###', 03934 TRUE, 03935 FALSE 03936 ); 03937 $this->outputExitBasedOnStep($content); 03938 break; 03939 case 'nochange': 03940 // Get the template part from the file 03941 $template = t3lib_parsehtml::getSubpart($templateFile, '###NOCHANGE###'); 03942 // Define the markers content 03943 $markers = array( 03944 'header' => 'Writing to \'localconf.php\'', 03945 'message' => 'No values were changed, so nothing is updated!', 03946 'action' => $this->action, 03947 'label' => 'Click to continue...' 03948 ); 03949 // Fill the markers 03950 $content = t3lib_parsehtml::substituteMarkerArray( 03951 $template, 03952 $markers, 03953 '###|###', 03954 TRUE, 03955 FALSE 03956 ); 03957 $this->outputExitBasedOnStep($content); 03958 break; 03959 } 03960 } 03961 return $returnVal; 03962 } 03963 03964 /** 03965 * If in 1-2-3 mode, send a redirect header response with the action and exit 03966 * otherwise send output to output() function 03967 * 03968 * @param string $content The HTML to output 03969 * @return void 03970 */ 03971 function outputExitBasedOnStep($content) { 03972 if ($this->step) { 03973 t3lib_utility_Http::redirect($this->action); 03974 } else { 03975 $this->output($this->outputWrapper($content)); 03976 } 03977 exit; 03978 } 03979 03980 /** 03981 * This appends something to value in the input array based on $type. Private. 03982 * 03983 * @param array $arr 03984 * @param integer $type 03985 * @return array 03986 */ 03987 function setLabelValueArray($arr,$type) { 03988 foreach ($arr as $k => $v) { 03989 if($this->config_array['im_versions'][$v]['gm']) { 03990 $program = 'gm'; 03991 } else { 03992 $program = 'convert'; 03993 } 03994 03995 switch($type) { 03996 // value, im 03997 case 0: 03998 $arr[$k].='|'.$this->config_array['im_versions'][$v][$program]; 03999 break; 04000 // labels, im 04001 case 1: 04002 if($this->config_array['im_versions'][$v][$program]) { 04003 $arr[$k].= ' ('.$this->config_array['im_versions'][$v][$program]; 04004 $arr[$k].= ($this->config_array['im_versions'][$v]['gif_capability'] ? ', '.$this->config_array['im_versions'][$v]['gif_capability'] : ''); 04005 $arr[$k].= ')'; 04006 } else { 04007 $arr[$k].= ''; 04008 } 04009 break; 04010 // labels, gd 04011 case 2: 04012 $arr[$k].=' ('.($v==1?'PNG':'GIF').')'; 04013 break; 04014 } 04015 } 04016 return $arr; 04017 } 04018 04019 /** 04020 * Returns the list of available databases (with access-check based on username/password) 04021 * 04022 * @return array List of available databases 04023 */ 04024 public function getDatabaseList() { 04025 $dbArr = array(); 04026 if ($result = $GLOBALS['TYPO3_DB']->sql_pconnect(TYPO3_db_host, TYPO3_db_username, TYPO3_db_password)) { 04027 $dbArr = $GLOBALS['TYPO3_DB']->admin_get_dbs(); 04028 } 04029 return $dbArr; 04030 } 04031 04032 /** 04033 * Calculates the suggested setup that should be written to localconf.php 04034 * 04035 * If safe_mode 04036 * - disable_exec_function = 1 04037 * - im = 0 04038 * 04039 * if PNG/GIF/GD 04040 * - disable gdlib if nothing 04041 * - select png/gif if only one of them is available, else PNG/GIF selector, defaulting to GIF 04042 * - (safe_mode is on) 04043 * - 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+ 04044 * - im_path_lzw (default to LZW version, pref. 4.2.9) 04045 * 04046 * @return array Suggested setup 04047 */ 04048 function setupGeneralCalculate() { 04049 $formArray['disable_exec_function']=array(0); 04050 $formArray['im_path']=array(''); 04051 $formArray['im_path_lzw']=array(''); 04052 $formArray['im_combine_filename']=array(''); 04053 $formArray['im_version_5']=array(''); 04054 $formArray['im']=array(1); 04055 $formArray['gdlib']=array(1); 04056 if ($this->config_array['gd'] && ($this->config_array['gd_gif'] || $this->config_array['gd_png'])) { 04057 if ($this->config_array['gd_gif'] && !$this->config_array['gd_png']) { 04058 $formArray['gdlib_png']=array(0); 04059 } elseif (!$this->config_array['gd_gif'] && $this->config_array['gd_png']) { 04060 $formArray['gdlib_png']=array(1); 04061 } else { 04062 $formArray['gdlib_png']=array(0,1); 04063 } 04064 } else { 04065 $formArray['gdlib']=array(0); 04066 } 04067 if ($this->config_array['safemode']) { 04068 $formArray['disable_exec_function']=array(1); 04069 } 04070 if ($this->config_array['im']) { 04071 $formArray['im'] = array(1); 04072 $found = $LZW_found = 0; 04073 $totalArr = array(); 04074 foreach ($this->config_array['im_versions'] as $path => $dat) { 04075 if (count($dat)>=3) { 04076 if (doubleval($dat['convert'])<5) { 04077 $formArray['im_version_5']=array(0); 04078 if ($dat['gif_capability']=='LZW') { 04079 $formArray['im_path']=array($path); 04080 $found=2; 04081 } elseif ($found<2) { 04082 $formArray['im_path']=array($path); 04083 $found=1; 04084 } 04085 } elseif (doubleval($dat['convert']) >= 6) { 04086 $formArray['im_version_5'] = array('im6'); 04087 if ($dat['gif_capability'] == 'LZW') { 04088 $formArray['im_path'] = array($path); 04089 $found = 2; 04090 } elseif ($found < 2) { 04091 $formArray['im_path'] = array($path); 04092 $found = 1; 04093 } 04094 } elseif (!$found) { 04095 $formArray['im_version_5']=array('im5'); 04096 $formArray['im_path']=array($path); 04097 $found=1; 04098 } 04099 } elseif ($dat['gm']) { 04100 $formArray['im_version_5']=array('gm'); 04101 if ($dat['gif_capability']=='LZW') { 04102 $formArray['im_path']=array($path); 04103 $found=2; 04104 } elseif ($found<2) { 04105 $formArray['im_path']=array($path); 04106 $found=1; 04107 } 04108 } 04109 if ($dat['gif_capability']=='LZW') { 04110 if (doubleval($dat['convert'])<5 || !$LZW_found) { 04111 $formArray['im_path_lzw']=array($path); 04112 $LZW_found=1; 04113 } 04114 } elseif ($dat['gif_capability']=="RLE" && !$LZW_found) { 04115 $formArray['im_path_lzw']=array($path); 04116 } 04117 $totalArr[]=$path; 04118 } 04119 $formArray['im_path']=array_unique(array_merge($formArray['im_path'],$totalArr)); 04120 $formArray['im_path_lzw']=array_unique(array_merge($formArray['im_path_lzw'],$totalArr)); 04121 $formArray['im_combine_filename']=array($this->config_array['im_combine_filename']); 04122 } else { 04123 $formArray['im']=array(0); 04124 } 04125 return $formArray; 04126 } 04127 04128 04129 /** 04130 * Returns true if TTF lib is installed. 04131 * 04132 * @return boolean TRUE if TrueType support 04133 */ 04134 function isTTF() { 04135 // Return right away if imageTTFtext does not exist. 04136 if (!function_exists('imagettftext')) { 04137 return 0; 04138 } 04139 04140 // try, print truetype font: 04141 $im = @imagecreate(300, 50); 04142 $background_color = imagecolorallocate($im, 255, 255, 55); 04143 $text_color = imagecolorallocate($im, 233, 14, 91); 04144 04145 $test = @imagettftext($im, t3lib_div::freetypeDpiComp(20), 0, 10, 20, $text_color, PATH_t3lib."/fonts/vera.ttf", 'Testing Truetype support'); 04146 if (t3lib_div::_GP('testingTrueTypeSupport')) { 04147 if ($this->isGIF()) { 04148 header('Content-type: image/gif'); 04149 imagegif($im); 04150 } else { 04151 header('Content-type: image/png'); 04152 imagepng($im); 04153 } 04154 exit; 04155 } 04156 return (is_array($test) ? 1 : 0); 04157 } 04158 04159 /** 04160 * Checks if the essential PHP modules are loaded 04161 * 04162 * @return array list of modules which are missing 04163 */ 04164 protected function getMissingPhpModules() { 04165 04166 // Hook to adjust the required PHP modules in the 1-2-3 installer 04167 $modules = $this->requiredPhpModules; 04168 if (is_array ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install/mod/class.tx_install.php']['requiredPhpModules'])) { 04169 foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install/mod/class.tx_install.php']['requiredPhpModules'] as $classData) { 04170 $hookObject = t3lib_div::getUserObj($classData); 04171 $modules = $hookObject->setRequiredPhpModules($modules, $this); 04172 } 04173 } 04174 $this->requiredPhpModules = $modules; 04175 04176 $result = array(); 04177 foreach ($this->requiredPhpModules as $module) { 04178 if (is_array($module)) { 04179 $detectedSubmodules = FALSE; 04180 foreach ($module as $submodule) { 04181 if (extension_loaded($submodule)) { 04182 $detectedSubmodules = TRUE; 04183 } 04184 } 04185 if ($detectedSubmodules === FALSE) { 04186 $result[] = 'one of: (' . implode(', ', $module) . ')'; 04187 } 04188 } else { 04189 if (!extension_loaded($module)) { 04190 $result[] = $module; 04191 } 04192 } 04193 } 04194 return $result; 04195 } 04196 04197 /***************************************** 04198 * 04199 * ABOUT the isXXX functions. 04200 * 04201 * I had a very real experience that these checks DID NOT fail eg PNG support if it didn't exist! 04202 * 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. 04203 * And if THAT succeeds also, then we can be certain of the support! 04204 */ 04205 04206 /** 04207 * Check if GD module is available by checking the function imagecreate 04208 * 04209 * @return boolean TRUE if GD is available 04210 */ 04211 function isGD() { 04212 if (function_exists('imagecreatetruecolor')) { 04213 if (@imagecreatetruecolor(50, 100)) { 04214 return 1; 04215 } 04216 } 04217 return 0; 04218 } 04219 04220 /** 04221 * Check if GIF functions are available 04222 * 04223 * @return boolean TRUE if GIF functions are available 04224 */ 04225 function isGIF() { 04226 // If GIF-functions exists, also do a real test of them: 04227 if (function_exists('imagecreatefromgif') && function_exists('imagegif') && ($this->ImageTypes() & IMG_GIF)) { 04228 $im = @imagecreatefromgif(t3lib_extMgm::extPath('install').'imgs/jesus.gif'); 04229 return ($im ? 1 : 0); 04230 } 04231 } 04232 04233 /** 04234 * Check if JPG functions are available 04235 * 04236 * @return boolean TRUE if JPEG functions are available 04237 */ 04238 function isJPG() { 04239 if (function_exists('imagecreatefromjpeg') && function_exists('imagejpeg') && ($this->ImageTypes() & IMG_JPG)) { 04240 return 1; 04241 } 04242 } 04243 04244 /** 04245 * Check if PNG functions are available 04246 * 04247 * @return boolean TRUE if PNG functions are available 04248 */ 04249 function isPNG() { 04250 if (function_exists('imagecreatefrompng') && function_exists('imagepng') && ($this->ImageTypes() & IMG_PNG)) { 04251 $im = imagecreatefrompng(t3lib_extMgm::extPath('install').'imgs/jesus.png'); 04252 return ($im ? 1 : 0); 04253 } 04254 } 04255 04256 /** 04257 * Return the image types supported by this PHP build 04258 * 04259 * @return integer A bit-field corresponding to the image formats supported by the version of GD linked into PHP. The following bits are returned, IMG_GIF | IMG_JPG | IMG_PNG | IMG_WBMP | IMG_XPM. 04260 */ 04261 function ImageTypes() { 04262 return imagetypes(); 04263 } 04264 04265 /** 04266 * Returns general information about GDlib 04267 * 04268 * @return string HTML with GD lib information 04269 */ 04270 function getGDSoftwareInfo() { 04271 return ' 04272 <p> 04273 You can get GDLib in the PNG version from 04274 <a href="http://www.libgd.org/">http://www.libgd.org/</a> 04275 <br /> 04276 FreeType is for download at 04277 <a href="http://www.freetype.org/">http://www.freetype.org/</a> 04278 <br /> 04279 Generally, TYPO3 packages are listed at 04280 <a href="' . TYPO3_URL_DOWNLOAD . '">' . TYPO3_URL_DOWNLOAD . '</a> 04281 </p> 04282 '; 04283 } 04284 04285 /** 04286 * Returns general information about configuration of TYPO3. 04287 * 04288 * @return string HTML with the general information 04289 */ 04290 function generallyAboutConfiguration() { 04291 return ' 04292 <p> 04293 Local configuration is done by overriding default values in the 04294 included file, typo3conf/localconf.php. In this file you enter the 04295 database information along with values in the global array 04296 TYPO3_CONF_VARS. 04297 <br /> 04298 The options in the TYPO3_CONF_VARS array and how to use it for your 04299 own purposes is discussed in the base configuration file, 04300 t3lib/config_default.php. This file sets up the default values and 04301 subsequently includes the localconf.php file in which you can then 04302 override values. 04303 <br /> 04304 See this page for <a href="' . TYPO3_URL_SYSTEMREQUIREMENTS . '">more 04305 information about system requirements.</a> 04306 </p>'; 04307 } 04308 04309 04310 04311 04312 04313 04314 04315 04316 04317 04318 04319 04320 04321 /********************** 04322 * 04323 * IMAGE processing 04324 * 04325 **********************/ 04326 04327 /** 04328 * jesus.TIF: IBM/LZW 04329 * jesus.GIF: Save for web, 32 colors 04330 * jesus.JPG: Save for web, 30 quality 04331 * jesus.PNG: Save for web, PNG-24 04332 * jesus.tga 24 bit TGA file 04333 * jesus.pcx 04334 * jesus.bmp 24 bit BMP file 04335 * jesus_ps6.PDF: PDF w/layers and vector data 04336 * typo3logo.ai: Illustrator 8 file 04337 * pdf_from_imagemagick.PDF PDF-file made by Acrobat Distiller from InDesign PS-file 04338 * 04339 * 04340 * Imagemagick 04341 * - Read formats 04342 * - Write png, gif, jpg 04343 * 04344 * Problems may arise from the use of safe_mode (eg. png) 04345 * In safemode you will automatically execute the program convert in the safe_mode_exec_path no matter what other path you specify 04346 * check fileexist before anything... 04347 * 04348 * - compare gif size 04349 * - scaling (by stdgraphic) 04350 * - combining (by stdgraphic) 04351 * 04352 * GDlib: 04353 * - create from:.... 04354 * - ttf text 04355 * 04356 * From TypoScript: (GD only, GD+IM, IM) 04357 * 04358 * @return void 04359 */ 04360 function checkTheImageProcessing() { 04361 $this->message('Image Processing', 'What is it?', ' 04362 <p> 04363 TYPO3 is known for its ability to process images on the server. 04364 <br /> 04365 In the backend interface (TBE) thumbnails are automatically 04366 generated (by ImageMagick in thumbs.php) as well as icons, menu 04367 items and pane tabs (by GDLib). 04368 <br /> 04369 In the TypoScript enabled frontend all kinds of graphical 04370 elements are processed. Typically images are scaled down to fit 04371 the pages (by ImageMagick) and menu items, graphical headers and 04372 such are generated automatically (by GDLib + ImageMagick). 04373 <br /> 04374 In addition TYPO3 is able to handle many file formats (thanks to 04375 ImageMagick), for example TIF, BMP, PCX, TGA, AI and PDF in 04376 addition to the standard web formats; JPG, GIF, PNG. 04377 </p> 04378 <p> 04379 In order to do this, TYPO3 uses two sets of tools: 04380 </p> 04381 <p> 04382 <strong>ImageMagick / GraphicsMagick:</strong> 04383 <br /> 04384 For conversion of non-web formats to webformats, combining 04385 images with alpha-masks, performing image-effects like blurring 04386 and sharpening. 04387 <br /> 04388 ImageMagick is a collection of external programs on the server 04389 called by the exec() function in PHP. TYPO3 uses three of these, 04390 namely \'convert\' (converting fileformats, scaling, effects), 04391 \'combine\'/\'composite\' (combining images with masks) and 04392 \'identify\' (returns image information). 04393 GraphicsMagick is an alternative to ImageMagick and can be enabled 04394 by setting [GFX][im_version_5] to \'gm\'. This is recommended and 04395 enabled by default. 04396 <br /> 04397 Because ImageMagick and Graphicsmagick are external programs, two 04398 requirements must be met: 1) The programs must be installed on the 04399 server and working and 2) if safe_mode is enabled, the programs must 04400 be located in the folder defined by the php.ini setting, 04401 <em>safe_mode_exec_dir</em> (else they are not executed). 04402 <br /> 04403 ImageMagick is available for both Windows and Unix. The current 04404 version is 6+. 04405 <br /> 04406 ImageMagick homepage is at <a href="http://www.imagemagick.org/">http://www.imagemagick.org/</a> 04407 </p> 04408 <p> 04409 <strong>GDLib:</strong> 04410 <br /> 04411 For drawing boxes and rendering text on images with truetype 04412 fonts. Also used for icons, menuitems and generally the 04413 TypoScript GIFBUILDER object is based on GDlib, but extensively 04414 utilizing ImageMagick to process intermediate results. 04415 <br /> 04416 GDLib is accessed through internal functions in PHP, so in this 04417 case, you have no safe_mode problems, but you\'ll need a version 04418 of PHP with GDLib compiled in. Also in order to use TrueType 04419 fonts with GDLib you\'ll need FreeType compiled in as well. 04420 <br /> 04421 </p> 04422 ' . $this->getGDSoftwareInfo() . ' 04423 <p> 04424 You can disable all image processing options in TYPO3 04425 ([GFX][image_processing]=0), but that would seriously disable 04426 TYPO3. 04427 </p> 04428 '); 04429 04430 $this->message('Image Processing', 'Verifying the image processing capabilities of your server', ' 04431 <p> 04432 This page performs image processing and displays the result. 04433 It\'s a thorough check that everything you\'ve configured is 04434 working correctly. 04435 <br /> 04436 It\'s quite simple to verify your installation; Just look down 04437 the page, the images in pairs should look like each other. If 04438 some images are not alike, something is wrong. You may also 04439 notice warnings and errors if this tool found signs of any 04440 problems. 04441 </p> 04442 <p> 04443 The image to the right is the reference image (how it should be) 04444 and to the left the image made by your server. 04445 <br /> 04446 The reference images are made with the classic ImageMagick 04447 install based on the 4.2.9 RPM and 5.2.3 RPM. If the version 5 04448 flag is set, the reference images are made by the 5.2.3 RPM. 04449 </p> 04450 <p> 04451 This test will work only if your ImageMagick/GDLib configuration 04452 allows it to. The typo3temp/ folder must be writable for all the 04453 temporary image files. They are all prefixed \'install_\' so 04454 they are easy to recognize and delete afterwards. 04455 </p> 04456 '); 04457 04458 $im_path = $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_path']; 04459 if ($GLOBALS['TYPO3_CONF_VARS']['GFX']['im_version_5']=='gm') { 04460 $im_path_version = $this->config_array['im_versions'][$im_path]['gm']; 04461 } else { 04462 $im_path_version = $this->config_array['im_versions'][$im_path]['convert']; 04463 } 04464 $im_path_lzw = $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_path_lzw']; 04465 $im_path_lzw_version = $this->config_array['im_versions'][$im_path_lzw]['convert']; 04466 $msg = ' 04467 <dl id="t3-install-imageprocessingim"> 04468 <dt> 04469 ImageMagick enabled: 04470 </dt> 04471 <dd> 04472 ' . htmlspecialchars($GLOBALS['TYPO3_CONF_VARS']['GFX']['im']) . ' 04473 </dd> 04474 <dt> 04475 ImageMagick path: 04476 </dt> 04477 <dd> 04478 ' . htmlspecialchars($im_path) . ' <span>(' . htmlspecialchars($im_path_version) . ')</span> 04479 </dd> 04480 <dt> 04481 ImageMagick path/LZW: 04482 </dt> 04483 <dd> 04484 ' . htmlspecialchars($im_path_lzw) . ' <span>(' . htmlspecialchars($im_path_lzw_version) . ')</span> 04485 </dd> 04486 <dt> 04487 Version 5/GraphicsMagick flag: 04488 </dt> 04489 <dd> 04490 ' . ($GLOBALS['TYPO3_CONF_VARS']['GFX']['im_version_5'] ? htmlspecialchars($GLOBALS['TYPO3_CONF_VARS']['GFX']['im_version_5']) : ' ') . ' 04491 </dd> 04492 </dl> 04493 <dl id="t3-install-imageprocessingother"> 04494 <dt> 04495 GDLib enabled: 04496 </dt> 04497 <dd> 04498 ' . ($GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib'] ? htmlspecialchars($GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib']) : ' ') . ' 04499 </dd> 04500 <dt> 04501 GDLib using PNG: 04502 </dt> 04503 <dd> 04504 ' . ($GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib_png'] ? htmlspecialchars($GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib_png']) : ' ') . ' 04505 </dd> 04506 <dt> 04507 IM5 effects enabled: 04508 </dt> 04509 <dd> 04510 ' . htmlspecialchars($GLOBALS['TYPO3_CONF_VARS']['GFX']['im_v5effects']) . ' 04511 <span>(Blurring/Sharpening with IM 5+)</span> 04512 </dd> 04513 <dt> 04514 Freetype DPI: 04515 </dt> 04516 <dd> 04517 ' . htmlspecialchars($GLOBALS['TYPO3_CONF_VARS']['GFX']['TTFdpi']) . ' 04518 <span>(Should be 96 for Freetype 2)</span> 04519 </dd> 04520 <dt> 04521 Mask invert: 04522 </dt> 04523 <dd> 04524 ' . htmlspecialchars($GLOBALS['TYPO3_CONF_VARS']['GFX']['im_imvMaskState']) . ' 04525 <span>(Should be set for some IM versions approx. 5.4+)</span> 04526 </dd> 04527 </dl> 04528 <dl id="t3-install-imageprocessingfileformats"> 04529 <dt> 04530 File Formats: 04531 </dt> 04532 <dd> 04533 ' . htmlspecialchars($GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext']) . ' 04534 </dd> 04535 </dl> 04536 '; 04537 04538 // Various checks to detect IM/GM version mismatches 04539 $mismatch=false; 04540 switch (strtolower($GLOBALS['TYPO3_CONF_VARS']['GFX']['im_version_5'])) { 04541 case 'gm': 04542 if (doubleval($im_path_version)>=2) $mismatch=true; 04543 break; 04544 case 'im4': 04545 if (doubleval($im_path_version)>=5) $mismatch=true; 04546 break; 04547 default: 04548 if (($GLOBALS['TYPO3_CONF_VARS']['GFX']['im_version_5']?true:false) != (doubleval($im_path_version)>=5)) $mismatch=true; 04549 break; 04550 } 04551 04552 if ($mismatch) { 04553 $msg .= ' 04554 <p> 04555 Warning: Mismatch between the version of ImageMagick' . 04556 ' (' . htmlspecialchars($im_path_version) . ') and the configuration of ' . 04557 '[GFX][im_version_5] (' . htmlspecialchars($GLOBALS['TYPO3_CONF_VARS']['GFX']['im_version_5']) . ') 04558 </p> 04559 '; 04560 $etype=2; 04561 } else $etype=1; 04562 04563 if ($GLOBALS['TYPO3_CONF_VARS']['GFX']['im_version_5']=='gm') { 04564 $msg = str_replace('ImageMagick','GraphicsMagick',$msg); 04565 } 04566 04567 $this->message('Image Processing', 'Current configuration',$msg,$etype); 04568 04569 04570 04571 04572 if (!$GLOBALS['TYPO3_CONF_VARS']['GFX']['image_processing']) { 04573 $this->message('Image Processing', 'Image Processing disabled!', ' 04574 <p> 04575 Image Processing is disabled by the config flag 04576 [GFX][image_processing] set to false (zero) 04577 </p> 04578 ', 2); 04579 $this->output($this->outputWrapper($this->printAll())); 04580 return; 04581 } 04582 if (!$this->config_array['dir_typo3temp']) { 04583 $this->message('Image Processing', 'typo3temp/ not writable!', ' 04584 <p> 04585 You must make typo3temp/ write enabled before you can 04586 proceed with this test. 04587 </p> 04588 ', 2); 04589 $this->output($this->outputWrapper($this->printAll())); 04590 return; 04591 } 04592 04593 04594 04595 $msg = ' 04596 <p> 04597 <a id="testmenu"></a> 04598 Click each of these links in turn to test a topic. 04599 <strong> 04600 Please be aware that each test may take several seconds! 04601 </strong>: 04602 </p> 04603 ' . $this->imagemenu(); 04604 $this->message('Image Processing','Testmenu',$msg,''); 04605 04606 04607 $parseStart = t3lib_div::milliseconds(); 04608 $imageProc = t3lib_div::makeInstance('t3lib_stdGraphic'); 04609 $imageProc->init(); 04610 $imageProc->tempPath = $this->typo3temp_path; 04611 $imageProc->dontCheckForExistingTempFile=1; 04612 // $imageProc->filenamePrefix='install_'.($GLOBALS['TYPO3_CONF_VARS']['GFX']['im_version_5']?"v5":""); 04613 $imageProc->filenamePrefix='install_'; 04614 $imageProc->dontCompress=1; 04615 $imageProc->alternativeOutputKey='TYPO3_INSTALL_SCRIPT'; 04616 $imageProc->noFramePrepended=$GLOBALS['TYPO3_CONF_VARS']['GFX']['im_noFramePrepended']; 04617 04618 // Very temporary!!! 04619 $imageProc->dontUnlinkTempFiles=0; 04620 04621 $imActive = ($this->config_array['im'] && $im_path); 04622 $gdActive = ($this->config_array['gd'] && $GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib']); 04623 04624 switch($this->INSTALL['images_type']) { 04625 case 'read': 04626 $refParseTime='5600'; // 4.2.9 04627 $refParseTime='3300'; // 5.2.3 04628 $headCode = 'Reading and converting images'; 04629 $this->message($headCode, 'Supported file formats', ' 04630 <p> 04631 This verifies that your ImageMagick installation is able 04632 to read the nine default file formats; JPG, GIF, PNG, 04633 TIF, BMP, PCX, TGA, PDF, AI. The tool \'identify\' will 04634 be used to read the pixeldimensions of non-web formats. 04635 The tool \'convert\' is used to read the image and write 04636 a temporary JPG-file 04637 </p> 04638 '); 04639 04640 if ($imActive) { 04641 // Reading formats - writing JPG 04642 04643 $extArr = explode(',','jpg,gif,png,tif,bmp,pcx,tga'); 04644 foreach ($extArr as $ext) { 04645 if ($this->isExtensionEnabled($ext, $headCode, "Read ".strtoupper($ext))) { 04646 $imageProc->IM_commands=array(); 04647 $theFile = t3lib_extMgm::extPath('install').'imgs/jesus.'.$ext; 04648 if (!@is_file($theFile)) die('Error: '.$theFile.' was not a file'); 04649 04650 $imageProc->imageMagickConvert_forceFileNameBody='read_'.$ext; 04651 $fileInfo = $imageProc->imageMagickConvert($theFile,'jpg',"",'',"",'',"",1); 04652 $result = $this->displayTwinImage($fileInfo[3],$imageProc->IM_commands); 04653 $this->message($headCode,"Read ".strtoupper($ext),$result[0],$result[1]); 04654 } 04655 } 04656 04657 if ($this->isExtensionEnabled('pdf', $headCode, 'Read PDF')) { 04658 $imageProc->IM_commands=array(); 04659 $theFile = t3lib_extMgm::extPath('install').'imgs/pdf_from_imagemagick.pdf'; 04660 if (!@is_file($theFile)) die('Error: '.$theFile.' was not a file'); 04661 04662 $imageProc->imageMagickConvert_forceFileNameBody='read_pdf'; 04663 $fileInfo = $imageProc->imageMagickConvert($theFile,'jpg',"170",'',"",'',"",1); 04664 $result = $this->displayTwinImage($fileInfo[3],$imageProc->IM_commands); 04665 $this->message($headCode,'Read PDF',$result[0],$result[1]); 04666 } 04667 if ($this->isExtensionEnabled('ai', $headCode, 'Read AI')) { 04668 $imageProc->IM_commands=array(); 04669 $theFile = t3lib_extMgm::extPath('install').'imgs/typo3logotype.ai'; 04670 if (!@is_file($theFile)) die('Error: '.$theFile.' was not a file'); 04671 04672 $imageProc->imageMagickConvert_forceFileNameBody='read_ai'; 04673 $fileInfo = $imageProc->imageMagickConvert($theFile,'jpg',"170",'',"",'',"",1); 04674 $result = $this->displayTwinImage($fileInfo[3],$imageProc->IM_commands); 04675 $this->message($headCode,'Read AI',$result[0],$result[1]); 04676 } 04677 } else { 04678 $this->message($headCode, 'Test skipped', ' 04679 <p> 04680 Use of ImageMagick has been disabled in the 04681 configuration. 04682 <br /> 04683 Refer to section \'Basic Configuration\' to change 04684 or review you configuration settings 04685 </p> 04686 ', 2); 04687 } 04688 break; 04689 case 'write': 04690 $refParseTime='300'; 04691 04692 // Writingformats - writing JPG 04693 $headCode = 'Writing images'; 04694 $this->message($headCode, 'Writing GIF and PNG', ' 04695 <p> 04696 This verifies that ImageMagick is able to write GIF and 04697 PNG files. 04698 <br /> 04699 The GIF-file is attempted compressed with LZW by the 04700 t3lib_div::gif_compress() function. 04701 </p> 04702 '); 04703 04704 if ($imActive) { 04705 // Writing GIF 04706 $imageProc->IM_commands=array(); 04707 $theFile = t3lib_extMgm::extPath('install').'imgs/jesus.gif'; 04708 if (!@is_file($theFile)) die('Error: '.$theFile.' was not a file'); 04709 04710 $imageProc->imageMagickConvert_forceFileNameBody='write_gif'; 04711 $fileInfo = $imageProc->imageMagickConvert($theFile,'gif',"",'',"",'',"",1); 04712 if ($GLOBALS['TYPO3_CONF_VARS']['GFX']['gif_compress']) { 04713 clearstatcache(); 04714 $prevSize=t3lib_div::formatSize(@filesize($fileInfo[3])); 04715 $returnCode = t3lib_div::gif_compress($fileInfo[3],''); 04716 clearstatcache(); 04717 $curSize=t3lib_div::formatSize(@filesize($fileInfo[3])); 04718 $note = array('Note on gif_compress() function:',"The 'gif_compress' method used was '".$returnCode."'.<br />Previous filesize: ".$prevSize.'. Current filesize:'.$curSize); 04719 } else $note=array('Note on gif_compress() function:','<em>Not used! Disabled by [GFX][gif_compress]</em>'); 04720 $result = $this->displayTwinImage($fileInfo[3],$imageProc->IM_commands, $note); 04721 $this->message($headCode,'Write GIF',$result[0],$result[1]); 04722 04723 04724 // Writing PNG 04725 $imageProc->IM_commands=array(); 04726 $theFile = t3lib_extMgm::extPath('install').'imgs/jesus.gif'; 04727 04728 $imageProc->imageMagickConvert_forceFileNameBody='write_png'; 04729 $fileInfo = $imageProc->imageMagickConvert($theFile,'png',"",'',"",'',"",1); 04730 $result = $this->displayTwinImage($fileInfo[3],$imageProc->IM_commands); 04731 $this->message($headCode,'Write PNG',$result[0],$result[1]); 04732 } else { 04733 $this->message($headCode, 'Test skipped', ' 04734 <p> 04735 Use of ImageMagick has been disabled in the 04736 configuration. 04737 <br /> 04738 Refer to section \'Basic Configuration\' to change 04739 or review you configuration settings 04740 </p> 04741 ', 2); 04742 } 04743 break; 04744 case 'scaling': 04745 $refParseTime='650'; 04746 04747 // Scaling 04748 $headCode = 'Scaling images'; 04749 $this->message($headCode, 'Scaling transparent images', ' 04750 <p> 04751 This shows how ImageMagick reacts when scaling 04752 transparent GIF and PNG files. 04753 </p> 04754 '); 04755 04756 if ($imActive) { 04757 // Scaling transparent image 04758 $imageProc->IM_commands=array(); 04759 $theFile = t3lib_extMgm::extPath('install').'imgs/jesus2_transp.gif'; 04760 if (!@is_file($theFile)) die('Error: '.$theFile.' was not a file'); 04761 04762 $imageProc->imageMagickConvert_forceFileNameBody='scale_gif'; 04763 $fileInfo = $imageProc->imageMagickConvert($theFile,'gif',"150",'',"",'',"",1); 04764 if ($GLOBALS['TYPO3_CONF_VARS']['GFX']['gif_compress']) { 04765 clearstatcache(); 04766 $prevSize=t3lib_div::formatSize(@filesize($fileInfo[3])); 04767 $returnCode = t3lib_div::gif_compress($fileInfo[3],''); 04768 clearstatcache(); 04769 $curSize=t3lib_div::formatSize(@filesize($fileInfo[3])); 04770 $note = array('Note on gif_compress() function:',"The 'gif_compress' method used was '".$returnCode."'.<br />Previous filesize: ".$prevSize.'. Current filesize:'.$curSize); 04771 } else $note=array('Note on gif_compress() function:','<em>Not used! Disabled by [GFX][gif_compress]</em>'); 04772 $result = $this->displayTwinImage($fileInfo[3],$imageProc->IM_commands,$note); 04773 $this->message($headCode,'GIF to GIF, 150 pixels wide',$result[0],$result[1]); 04774 04775 $imageProc->IM_commands=array(); 04776 $theFile = t3lib_extMgm::extPath('install').'imgs/jesus2_transp.png'; 04777 if (!@is_file($theFile)) die('Error: '.$theFile.' was not a file'); 04778 04779 $imageProc->imageMagickConvert_forceFileNameBody='scale_png'; 04780 $fileInfo = $imageProc->imageMagickConvert($theFile,'png',"150",'',"",'',"",1); 04781 $result = $this->displayTwinImage($fileInfo[3],$imageProc->IM_commands); 04782 $this->message($headCode,'PNG to PNG, 150 pixels wide',$result[0],$result[1]); 04783 04784 $imageProc->IM_commands=array(); 04785 $theFile = t3lib_extMgm::extPath('install').'imgs/jesus2_transp.gif'; 04786 if (!@is_file($theFile)) die('Error: '.$theFile.' was not a file'); 04787 $imageProc->imageMagickConvert_forceFileNameBody='scale_jpg'; 04788 $fileInfo = $imageProc->imageMagickConvert($theFile,'jpg',"150",'',"",'',"",1); 04789 $result = $this->displayTwinImage($fileInfo[3],$imageProc->IM_commands); 04790 $this->message($headCode,'GIF to JPG, 150 pixels wide',$result[0],$result[1]); 04791 } else { 04792 $this->message($headCode, 'Test skipped', ' 04793 <p> 04794 Use of ImageMagick has been disabled in the 04795 configuration. 04796 <br /> 04797 Refer to section \'Basic Configuration\' to change 04798 or review you configuration settings 04799 </p> 04800 ', 2); 04801 } 04802 break; 04803 case 'combining': 04804 $refParseTime='150'; // 4.2.9 04805 $refParseTime='250'; // 5.2.3 04806 // Combine 04807 $headCode = 'Combining images'; 04808 $this->message($headCode, 'Combining images', ' 04809 <p> 04810 This verifies that the ImageMagick tool, 04811 \'combine\'/\'composite\', is able to combine two images 04812 through a grayscale mask. 04813 <br /> 04814 If the masking seems to work but inverted, that just 04815 means you\'ll have to make sure the invert flag is set 04816 (some combination of im_negate_mask/im_imvMaskState) 04817 </p> 04818 '); 04819 04820 if ($imActive) { 04821 $imageProc->IM_commands=array(); 04822 $input = t3lib_extMgm::extPath('install').'imgs/greenback.gif'; 04823 $overlay = t3lib_extMgm::extPath('install').'imgs/jesus.jpg'; 04824 $mask = t3lib_extMgm::extPath('install').'imgs/blackwhite_mask.gif'; 04825 if (!@is_file($input)) die('Error: '.$input.' was not a file'); 04826 if (!@is_file($overlay)) die('Error: '.$overlay.' was not a file'); 04827 if (!@is_file($mask)) die('Error: '.$mask.' was not a file'); 04828 04829 $output = $imageProc->tempPath.$imageProc->filenamePrefix.t3lib_div::shortMD5($imageProc->alternativeOutputKey.'combine1').'.jpg'; 04830 $imageProc->combineExec($input,$overlay,$mask,$output, true); 04831 $fileInfo = $imageProc->getImageDimensions($output); 04832 $result = $this->displayTwinImage($fileInfo[3],$imageProc->IM_commands); 04833 $this->message($headCode,'Combine using a GIF mask with only black and white',$result[0],$result[1]); 04834 04835 // Combine 04836 $imageProc->IM_commands=array(); 04837 $input = t3lib_extMgm::extPath('install').'imgs/combine_back.jpg'; 04838 $overlay = t3lib_extMgm::extPath('install').'imgs/jesus.jpg'; 04839 $mask = t3lib_extMgm::extPath('install').'imgs/combine_mask.jpg'; 04840 if (!@is_file($input)) die('Error: '.$input.' was not a file'); 04841 if (!@is_file($overlay)) die('Error: '.$overlay.' was not a file'); 04842 if (!@is_file($mask)) die('Error: '.$mask.' was not a file'); 04843 04844 $output = $imageProc->tempPath.$imageProc->filenamePrefix.t3lib_div::shortMD5($imageProc->alternativeOutputKey.'combine2').'.jpg'; 04845 $imageProc->combineExec($input,$overlay,$mask,$output, true); 04846 $fileInfo = $imageProc->getImageDimensions($output); 04847 $result = $this->displayTwinImage($fileInfo[3],$imageProc->IM_commands); 04848 $this->message($headCode,'Combine using a JPG mask with graylevels',$result[0],$result[1]); 04849 } else { 04850 $this->message($headCode, 'Test skipped', ' 04851 <p> 04852 Use of ImageMagick has been disabled in the 04853 configuration. 04854 <br /> 04855 Refer to section \'Basic Configuration\' to change 04856 or review you configuration settings 04857 </p> 04858 ', 2); 04859 } 04860 break; 04861 case 'gdlib': 04862 // GIF / 4.2.9 / LZW (5.2.3) 04863 $refParseTime='1800'; 04864 // PNG / 4.2.9 / LZW (5.2.3) 04865 $refParseTime='2700'; 04866 // GIF / 5.2.3 / LZW (5.2.3) 04867 $refParseTime='1600'; 04868 // GDLibrary 04869 $headCode = 'GDLib'; 04870 $this->message($headCode, 'Testing GDLib', ' 04871 <p> 04872 This verifies that the GDLib installation works properly. 04873 </p> 04874 '); 04875 04876 04877 if ($gdActive) { 04878 // GD with box 04879 $imageProc->IM_commands=array(); 04880 $im = imagecreatetruecolor(170, 136); 04881 $Bcolor = ImageColorAllocate ($im, 0, 0, 0); 04882 ImageFilledRectangle($im, 0, 0, 170, 136, $Bcolor); 04883 $workArea=array(0,0,170,136); 04884 $conf=array( 04885 'dimensions' => '10,50,150,36', 04886 'color' => 'olive' 04887 ); 04888 $imageProc->makeBox($im,$conf,$workArea); 04889 $output = $imageProc->tempPath.$imageProc->filenamePrefix.t3lib_div::shortMD5('GDbox').'.'.$imageProc->gifExtension; 04890 $imageProc->ImageWrite($im,$output); 04891 $fileInfo = $imageProc->getImageDimensions($output); 04892 $result = $this->displayTwinImage($fileInfo[3],$imageProc->IM_commands); 04893 $this->message($headCode,'Create simple image',$result[0],$result[1]); 04894 04895 04896 // GD from image with box 04897 $imageProc->IM_commands=array(); 04898 $input = t3lib_extMgm::extPath('install').'imgs/jesus.'.$imageProc->gifExtension; 04899 if (!@is_file($input)) die('Error: '.$input.' was not a file'); 04900 $im = $imageProc->imageCreateFromFile($input); 04901 $workArea=array(0,0,170,136); 04902 $conf=array(); 04903 $conf['dimensions']='10,50,150,36'; 04904 $conf['color']='olive'; 04905 $imageProc->makeBox($im,$conf,$workArea); 04906 $output = $imageProc->tempPath.$imageProc->filenamePrefix.t3lib_div::shortMD5('GDfromImage+box').'.'.$imageProc->gifExtension; 04907 $imageProc->ImageWrite($im,$output); 04908 $fileInfo = $imageProc->getImageDimensions($output); 04909 $GDWithBox_filesize = @filesize($output); 04910 $result = $this->displayTwinImage($fileInfo[3],$imageProc->IM_commands); 04911 $this->message($headCode,'Create image from file',$result[0],$result[1]); 04912 04913 04914 // GD with text 04915 $imageProc->IM_commands=array(); 04916 $im = imagecreatetruecolor(170, 136); 04917 $Bcolor = ImageColorAllocate ($im, 128,128,150); 04918 ImageFilledRectangle($im, 0, 0, 170, 136, $Bcolor); 04919 $workArea=array(0,0,170,136); 04920 $conf=array( 04921 'iterations' => 1, 04922 'angle' => 0, 04923 'antiAlias' => 1, 04924 'text' => 'HELLO WORLD', 04925 'fontColor' => '#003366', 04926 'fontSize' => 18, 04927 'fontFile' => $this->backPath.'../t3lib/fonts/vera.ttf', 04928 'offset' => '17,40' 04929 ); 04930 $conf['BBOX'] = $imageProc->calcBBox($conf); 04931 $imageProc->makeText($im,$conf,$workArea); 04932 04933 $output = $imageProc->tempPath.$imageProc->filenamePrefix.t3lib_div::shortMD5('GDwithText').'.'.$imageProc->gifExtension; 04934 $imageProc->ImageWrite($im,$output); 04935 $fileInfo = $imageProc->getImageDimensions($output); 04936 $result = $this->displayTwinImage($fileInfo[3],$imageProc->IM_commands); 04937 $this->message($headCode,'Render text with TrueType font',$result[0],$result[1]); 04938 04939 if ($imActive) { 04940 // extension: GD with text, niceText 04941 $conf['offset'] = '17,65'; 04942 $conf['niceText'] = 1; 04943 $imageProc->makeText($im,$conf,$workArea); 04944 04945 $output = $imageProc->tempPath.$imageProc->filenamePrefix.t3lib_div::shortMD5('GDwithText-niceText').'.'.$imageProc->gifExtension; 04946 $imageProc->ImageWrite($im,$output); 04947 $fileInfo = $imageProc->getImageDimensions($output); 04948 $result = $this->displayTwinImage($fileInfo[3],$imageProc->IM_commands, array("Note on 'niceText':","'niceText' is a concept that tries to improve the antialiasing of the rendered type by actually rendering the textstring in double size on a black/white mask, downscaling the mask and masking the text onto the image through this mask. This involves ImageMagick 'combine'/'composite' and 'convert'.")); 04949 $this->message($headCode, 'Render text with TrueType font using \'niceText\' option', ' 04950 <p> 04951 (If the image has another background color than 04952 the image above (eg. dark background color with 04953 light text) then you will have to set 04954 TYPO3_CONF_VARS[GFX][im_imvMaskState]=1) 04955 </p> 04956 ' . $result[0], $result[1]); 04957 } else { 04958 $this->message($headCode, 'Render text with TrueType font using \'niceText\' option', ' 04959 <p> 04960 <strong>Test is skipped!</strong> 04961 </p> 04962 <p> 04963 Use of ImageMagick has been disabled in the 04964 configuration. ImageMagick is needed to generate 04965 text with the niceText option. 04966 <br /> 04967 Refer to section \'Basic Configuration\' to 04968 change or review you configuration settings 04969 </p> 04970 ', 2); 04971 } 04972 04973 if ($imActive) { 04974 // extension: GD with text, niceText AND shadow 04975 $conf['offset'] = '17,90'; 04976 $conf['niceText'] = 1; 04977 $conf['shadow.'] = array( 04978 'offset'=>'2,2', 04979 'blur' => $imageProc->V5_EFFECTS?"20":"90", 04980 'opacity' => '50', 04981 'color' => 'black' 04982 ); 04983 $imageProc->makeShadow($im,$conf['shadow.'],$workArea,$conf); 04984 $imageProc->makeText($im,$conf,$workArea); 04985 04986 $output = $imageProc->tempPath.$imageProc->filenamePrefix.t3lib_div::shortMD5('GDwithText-niceText-shadow').'.'.$imageProc->gifExtension; 04987 $imageProc->ImageWrite($im,$output); 04988 $fileInfo = $imageProc->getImageDimensions($output); 04989 $result = $this->displayTwinImage($fileInfo[3],$imageProc->IM_commands, array('Note on drop shadows:','Drop shadows are done by using ImageMagick to blur a mask through which the drop shadow is generated. The blurring of the mask only works in ImageMagick 4.2.9 and <em>not</em> ImageMagick 5 - which is why you may see a hard and not soft shadow.')); 04990 $this->message($headCode, 'Render \'niceText\' with a shadow under', ' 04991 <p> 04992 (This test makes sense only if the above test 04993 had a correct output. But if so, you may not see 04994 a soft dropshadow from the third text string as 04995 you should. In that case you are most likely 04996 using ImageMagick 5 and should set the flag 04997 TYPO3_CONF_VARS[GFX][im_v5effects]. However this 04998 may cost server performance! 04999 </p> 05000 ' . $result[0], $result[1]); 05001 } else { 05002 $this->message($headCode, 'Render \'niceText\' with a shadow under', ' 05003 <p> 05004 <strong>Test is skipped!</strong> 05005 </p> 05006 <p> 05007 Use of ImageMagick has been disabled in the 05008 configuration. ImageMagick is needed to generate 05009 shadows. 05010 <br /> 05011 Refer to section \'Basic Configuration\' to 05012 change or review you configuration settings 05013 </p> 05014 ', 2); 05015 } 05016 05017 if ($imageProc->gifExtension=='gif') { 05018 $buffer=20; 05019 $assess = "This assessment is based on the filesize from 'Create image from file' test, which were ".$GDWithBox_filesize.' bytes'; 05020 $goodNews = "If the image was LZW compressed you would expect to have a size of less than 9000 bytes. If you open the image with Photoshop and saves it from Photoshop, you'll a filesize like that.<br />The good news is (hopefully) that your [GFX][im_path_lzw] path is correctly set so the gif_compress() function will take care of the compression for you!"; 05021 if ($GDWithBox_filesize<8784+$buffer) { 05022 $msg = ' 05023 <p> 05024 <strong> 05025 Your GDLib appears to have LZW compression! 05026 </strong> 05027 <br /> 05028 This assessment is based on the filesize 05029 from \'Create image from file\' test, which 05030 were ' . $GDWithBox_filesize . ' bytes. 05031 <br /> 05032 This is a real advantage for you because you 05033 don\'t need to use ImageMagick for LZW 05034 compressing. In order to make sure that 05035 GDLib is used, 05036 <strong> 05037 please set the config option 05038 [GFX][im_path_lzw] to an empty string! 05039 </strong> 05040 <br /> 05041 When you disable the use of ImageMagick for 05042 LZW compressing, you\'ll see that the 05043 gif_compress() function has a return code of 05044 \'GD\' (for GDLib) instead of \'IM\' (for 05045 ImageMagick) 05046 </p> 05047 '; 05048 } elseif ($GDWithBox_filesize>19000) { 05049 $msg = ' 05050 <p> 05051 <strong> 05052 Your GDLib appears to have no 05053 compression at all! 05054 </strong> 05055 <br /> 05056 ' . $assess . ' 05057 <br /> 05058 ' . $goodNews . ' 05059 </p> 05060 '; 05061 } else { 05062 $msg = ' 05063 <p> 05064 Your GDLib appears to have RLE compression 05065 <br /> 05066 ' . $assess . ' 05067 <br /> 05068 ' . $goodNews . ' 05069 </p> 05070 '; 05071 } 05072 $this->message($headCode,'GIF compressing in GDLib'," 05073 ".$msg." 05074 ",1); 05075 } 05076 05077 } else { 05078 $this->message($headCode, 'Test skipped', ' 05079 <p> 05080 Use of GDLib has been disabled in the configuration. 05081 <br /> 05082 Refer to section \'Basic Configuration\' to change 05083 or review you configuration settings 05084 </p> 05085 ', 2); 05086 } 05087 break; 05088 } 05089 05090 if ($this->INSTALL['images_type']) { 05091 // End info 05092 if ($this->fatalError) { 05093 $this->message('Info', 'Errors', ' 05094 <p> 05095 It seems that you had some fatal errors in this test. 05096 Please make sure that your ImageMagick and GDLib 05097 settings are correct. Refer to the 05098 \'Basic Configuration\' section for more information and 05099 debugging of your settings. 05100 </p> 05101 '); 05102 } 05103 05104 $parseMS = t3lib_div::milliseconds() - $parseStart; 05105 $this->message('Info', 'Parsetime', ' 05106 <p> 05107 ' . $parseMS . ' ms 05108 </p> 05109 '); 05110 } 05111 $this->output($this->outputWrapper($this->printAll())); 05112 } 05113 05114 /** 05115 * Check if image file extension is enabled 05116 * Adds error message to the message array 05117 * 05118 * @param string $ext The image file extension 05119 * @param string $headCode The header for the message 05120 * @param string $short The short description for the message 05121 * @return boolean TRUE if extension is enabled 05122 */ 05123 function isExtensionEnabled($ext, $headCode, $short) { 05124 if (!t3lib_div::inList($GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'],$ext)) { 05125 $this->message($headCode, $short, ' 05126 <p> 05127 Skipped - extension not in the list of allowed extensions 05128 ([GFX][imagefile_ext]). 05129 </p> 05130 ',1); 05131 } else { 05132 return 1; 05133 } 05134 } 05135 05136 /** 05137 * Generate the HTML after reading and converting images 05138 * Displays the verification and the converted image if succeeded 05139 * Adds error messages if needed 05140 * 05141 * @param string $imageFile The file name of the converted image 05142 * @param array $IMcommands The ImageMagick commands used 05143 * @param string $note Additional note for image operation 05144 * @return array Contains content and highest error level 05145 */ 05146 function displayTwinImage ($imageFile, $IMcommands=array(), $note='') { 05147 // Get the template file 05148 $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'DisplayTwinImage.html'); 05149 // Get the template part from the file 05150 $template = t3lib_parsehtml::getSubpart($templateFile, '###TEMPLATE###'); 05151 05152 $content = ''; 05153 05154 $errorLevels=array(-1); 05155 if ($imageFile) { 05156 // Get the subpart for the images 05157 $imageSubpart = t3lib_parsehtml::getSubpart($template, '###IMAGE###'); 05158 $verifyFile = t3lib_extMgm::extPath('install').'verify_imgs/'.basename($imageFile); 05159 $destImg = @getImageSize($imageFile); 05160 $destImgCode ='<img src="'.$this->backPath.'../'.substr($imageFile,strlen(PATH_site)).'" '.$destImg[3].'>'; 05161 $verifyImg = @getImageSize($verifyFile); 05162 $verifyImgCode = '<img src="'.$this->backPath.t3lib_extMgm::extRelPath('install').'verify_imgs/'.basename($verifyFile).'" '.$verifyImg[3].'>'; 05163 05164 clearstatcache(); 05165 $destImg['filesize'] = @filesize($imageFile); 05166 clearstatcache(); 05167 $verifyImg['filesize'] = @filesize($verifyFile); 05168 // Define the markers content 05169 $imageMarkers = array( 05170 'destWidth' => $destImg[0], 05171 'destHeight' => $destImg[1], 05172 'destUrl' => $this->backPath . '../' . substr($imageFile, strlen(PATH_site)), 05173 'verifyWidth' => $verifyImg[0], 05174 'verifyHeight' => $verifyImg[1], 05175 'verifyUrl' => $this->backPath . t3lib_extMgm::extRelPath('install') . 'verify_imgs/' . basename($verifyFile), 05176 'yourServer' => 'Your server:', 05177 'yourServerInformation' => t3lib_div::formatSize($destImg['filesize']) . ', ' . $destImg[0] . 'x' . $destImg[1] . ' pixels', 05178 'reference' => 'Reference:', 05179 'referenceInformation' => t3lib_div::formatSize($verifyImg['filesize']) . ', ' . $verifyImg[0] . 'x' . $verifyImg[1] . ' pixels' 05180 ); 05181 05182 // Display a warning if the generated image is more than 2KB larger than its reference... 05183 if (($destImg['filesize']!=$verifyImg['filesize']) && (intval($destImg['filesize']) && ($destImg['filesize']-$verifyImg['filesize']) > 2048)) { 05184 // Get the subpart for the different filesize message 05185 $differentFileSizeSubpart = t3lib_parsehtml::getSubpart($imageSubpart, '###DIFFERENTFILESIZE###'); 05186 // Define the markers content 05187 $differentFileSizeMarkers = array( 05188 'message' => 'File size is very different from reference', 05189 'yourServerFileSize' => $destImg['filesize'], 05190 'referenceFileSize' => $verifyImg['filesize'] 05191 ); 05192 // Fill the markers in the subpart 05193 $differentFileSizeSubpart = t3lib_parsehtml::substituteMarkerArray( 05194 $differentFileSizeSubpart, 05195 $differentFileSizeMarkers, 05196 '###|###', 05197 TRUE, 05198 FALSE 05199 ); 05200 05201 $errorLevels[]=2; 05202 } 05203 // Substitute the subpart for different filesize message 05204 $imageSubpart = t3lib_parsehtml::substituteSubpart( 05205 $imageSubpart, 05206 '###DIFFERENTFILESIZE###', 05207 $differentFileSizeSubpart 05208 ); 05209 05210 if ($destImg[0]!=$verifyImg[0] || $destImg[1]!=$verifyImg[1]) { 05211 // Get the subpart for the different pixel dimensions message 05212 $differentPixelDimensionsSubpart = t3lib_parsehtml::getSubpart($imageSubpart, '###DIFFERENTPIXELDIMENSIONS###'); 05213 // Define the markers content 05214 $differentPixelDimensionsMarkers = array( 05215 'message' => 'Pixel dimension are not equal!' 05216 ); 05217 // Fill the markers in the subpart 05218 $differentPixelDimensionsSubpart = t3lib_parsehtml::substituteMarkerArray( 05219 $differentPixelDimensionsSubpart, 05220 $differentPixelDimensionsMarkers, 05221 '###|###', 05222 TRUE, 05223 FALSE 05224 ); 05225 05226 $errorLevels[]=2; 05227 } 05228 // Substitute the subpart for different pixel dimensions message 05229 $imageSubpart = t3lib_parsehtml::substituteSubpart( 05230 $imageSubpart, 05231 '###DIFFERENTPIXELDIMENSIONS###', 05232 $differentPixelDimensionsSubpart 05233 ); 05234 05235 if ($note) { 05236 // Get the subpart for the note 05237 $noteSubpart = t3lib_parsehtml::getSubpart($imageSubpart, '###NOTE###'); 05238 // Define the markers content 05239 $noteMarkers = array( 05240 'message' => $note[0], 05241 'label' => $note[1] 05242 ); 05243 // Fill the markers in the subpart 05244 $noteSubpart = t3lib_parsehtml::substituteMarkerArray( 05245 $noteSubpart, 05246 $noteMarkers, 05247 '###|###', 05248 TRUE, 05249 FALSE 05250 ); 05251 } 05252 // Substitute the subpart for the note 05253 $imageSubpart = t3lib_parsehtml::substituteSubpart( 05254 $imageSubpart, 05255 '###NOTE###', 05256 $noteSubpart 05257 ); 05258 05259 if ($this->dumpImCommands && count($IMcommands)) { 05260 $commands = $this->formatImCmds($IMcommands); 05261 // Get the subpart for the ImageMagick commands 05262 $imCommandsSubpart = t3lib_parsehtml::getSubpart($imageSubpart, '###IMCOMMANDS###'); 05263 // Define the markers content 05264 $imCommandsMarkers = array( 05265 'message' => 'ImageMagick commands executed:', 05266 'rows' => t3lib_div::intInRange(count($commands), 2, 10), 05267 'commands' => htmlspecialchars(implode(LF, $commands)) 05268 ); 05269 // Fill the markers in the subpart 05270 $imCommandsSubpart = t3lib_parsehtml::substituteMarkerArray( 05271 $imCommandsSubpart, 05272 $imCommandsMarkers, 05273 '###|###', 05274 TRUE, 05275 FALSE 05276 ); 05277 } 05278 // Substitute the subpart for the ImageMagick commands 05279 $imageSubpart = t3lib_parsehtml::substituteSubpart( 05280 $imageSubpart, 05281 '###IMCOMMANDS###', 05282 $imCommandsSubpart 05283 ); 05284 // Fill the markers 05285 $imageSubpart = t3lib_parsehtml::substituteMarkerArray( 05286 $imageSubpart, 05287 $imageMarkers, 05288 '###|###', 05289 TRUE, 05290 FALSE 05291 ); 05292 05293 } else { 05294 // Get the subpart when no image has been generated 05295 $noImageSubpart = t3lib_parsehtml::getSubpart($template, '###NOIMAGE###'); 05296 $commands = $this->formatImCmds($IMcommands); 05297 05298 if (count($commands)) { 05299 // Get the subpart for the ImageMagick commands 05300 $commandsSubpart = t3lib_parsehtml::getSubpart($noImageSubpart, '###COMMANDSAVAILABLE###'); 05301 // Define the markers content 05302 $commandsMarkers = array( 05303 'rows' => t3lib_div::intInRange(count($commands), 2, 10), 05304 'commands' => htmlspecialchars(implode(LF, $commands)) 05305 ); 05306 // Fill the markers in the subpart 05307 $commandsSubpart = t3lib_parsehtml::substituteMarkerArray( 05308 $commandsSubpart, 05309 $commandsMarkers, 05310 '###|###', 05311 TRUE, 05312 FALSE 05313 ); 05314 } 05315 // Substitute the subpart for the ImageMagick commands 05316 $noImageSubpart = t3lib_parsehtml::substituteSubpart( 05317 $noImageSubpart, 05318 '###COMMANDSAVAILABLE###', 05319 $commandsSubpart 05320 ); 05321 // Define the markers content 05322 $noImageMarkers = array( 05323 'message' => 'There was no result from the ImageMagick operation', 05324 'label' => 'Below there\'s a dump of the ImageMagick commands executed:' 05325 ); 05326 // Fill the markers 05327 $noImageSubpart = t3lib_parsehtml::substituteMarkerArray( 05328 $noImageSubpart, 05329 $noImageMarkers, 05330 '###|###', 05331 TRUE, 05332 FALSE 05333 ); 05334 05335 $errorLevels[]=3; 05336 } 05337 // Substitute the subpart when image has been generated 05338 $content = t3lib_parsehtml::substituteSubpart( 05339 $template, 05340 '###IMAGE###', 05341 $imageSubpart 05342 ); 05343 // Substitute the subpart when no image has been generated 05344 $content = t3lib_parsehtml::substituteSubpart( 05345 $content, 05346 '###NOIMAGE###', 05347 $noImageSubpart 05348 ); 05349 05350 return array($content, max($errorLevels)); 05351 } 05352 05353 /** 05354 * Format ImageMagick commands for use in HTML 05355 * 05356 * @param array $arr The ImageMagick commands 05357 * @return string The formatted commands 05358 */ 05359 function formatImCmds($arr) { 05360 $out = array(); 05361 if (is_array($arr)) { 05362 foreach ($arr as $k => $v) { 05363 $out[] = $v[1]; 05364 if ($v[2]) { 05365 $out[]=' RETURNED: ' . $v[2]; 05366 } 05367 } 05368 } 05369 05370 return $out; 05371 } 05372 05373 /** 05374 * Generate the menu for the test menu in 'image processing' 05375 * 05376 * @return string The HTML for the test menu 05377 */ 05378 function imagemenu() { 05379 // Get the template file 05380 $template = @file_get_contents(PATH_site . $this->templateFilePath . 'ImageMenu.html'); 05381 // Get the subpart for the menu 05382 $menuSubPart = t3lib_parsehtml::getSubpart($template, '###MENU###'); 05383 // Get the subpart for the single item in the menu 05384 $menuItemSubPart = t3lib_parsehtml::getSubpart($menuSubPart, '###MENUITEM###'); 05385 05386 $menuitems = array( 05387 'read' => 'Reading image formats', 05388 'write' => 'Writing GIF and PNG', 05389 'scaling' => 'Scaling images', 05390 'combining' => 'Combining images', 05391 'gdlib' => 'GD library functions' 05392 ); 05393 $c = 0; 05394 05395 $items = array(); 05396 foreach ($menuitems as $k => $v) { 05397 // Define the markers content 05398 $markers = array( 05399 'backgroundColor' => $this->INSTALL['images_type'] == $k ? 'activeMenu' : 'generalTableBackground', 05400 'url' => htmlspecialchars($this->action . '&TYPO3_INSTALL[images_type]=' . $k . '#imageMenu'), 05401 'item' => $v 05402 ); 05403 // Fill the markers in the subpart 05404 $items[] = t3lib_parsehtml::substituteMarkerArray( 05405 $menuItemSubPart, 05406 $markers, 05407 '###|###', 05408 TRUE, 05409 FALSE 05410 ); 05411 } 05412 // Substitute the subpart for the single item in the menu 05413 $menuSubPart = t3lib_parsehtml::substituteSubpart( 05414 $menuSubPart, 05415 '###MENUITEM###', 05416 implode(LF, $items) 05417 ); 05418 05419 return $menuSubPart; 05420 } 05421 05422 05423 05424 05425 05426 05427 05428 05429 05430 05431 05432 05433 /********************** 05434 * 05435 * DATABASE analysing 05436 * 05437 **********************/ 05438 05439 /** 05440 * The Database Analyzer 05441 * 05442 * @return void 05443 */ 05444 function checkTheDatabase() { 05445 if (!$this->config_array['mysqlConnect']) { 05446 $this->message('Database Analyser', 'Your database connection failed', ' 05447 <p> 05448 Please go to the \'Basic Configuration\' section and correct 05449 this problem first. 05450 </p> 05451 ', 2); 05452 $this->output($this->outputWrapper($this->printAll())); 05453 return; 05454 } 05455 if ($this->config_array['no_database']) { 05456 $this->message('Database Analyser', 'No database selected', ' 05457 <p> 05458 Please go to the \'Basic Configuration\' section and correct 05459 this problem first. 05460 </p> 05461 ', 2); 05462 $this->output($this->outputWrapper($this->printAll())); 05463 return; 05464 } 05465 05466 // Getting current tables 05467 $whichTables=$this->getListOfTables(); 05468 05469 05470 // Getting number of static_template records 05471 if ($whichTables['static_template']) { 05472 $static_template_count = $GLOBALS['TYPO3_DB']->exec_SELECTcountRows('uid', 'static_template'); 05473 } 05474 $static_template_count=intval($static_template_count); 05475 05476 $headCode ='Database Analyser'; 05477 $this->message($headCode, 'What is it?', ' 05478 <p> 05479 In this section you can get an overview of your currently 05480 selected database compared to sql-files. You can also import 05481 sql-data directly into the database or upgrade tables from 05482 earlier versions of TYPO3. 05483 </p> 05484 ', 0); 05485 05486 $this->message($headCode, 'Connected to SQL database successfully', ' 05487 <dl id="t3-install-databaseconnected"> 05488 <dt> 05489 Username: 05490 </dt> 05491 <dd> 05492 ' . htmlspecialchars(TYPO3_db_username) . ' 05493 </dd> 05494 <dt> 05495 Host: 05496 </dt> 05497 <dd> 05498 ' . htmlspecialchars(TYPO3_db_host) . ' 05499 </dd> 05500 </dl> 05501 ', -1, 1); 05502 05503 $this->message($headCode, 'Database', ' 05504 <p> 05505 <strong>' . htmlspecialchars(TYPO3_db) . '</strong> is selected as database. 05506 <br /> 05507 Has <strong>' . count($whichTables) . '</strong> tables. 05508 </p> 05509 ', -1, 1); 05510 05511 05512 // Menu 05513 $sql_files = array_merge( 05514 t3lib_div::getFilesInDir(PATH_typo3conf,'sql',1,1), 05515 array() 05516 ); 05517 05518 $action_type = $this->INSTALL['database_type']; 05519 $actionParts = explode('|',$action_type); 05520 if (count($actionParts)<2) { 05521 $action_type=''; 05522 } 05523 05524 // Get the template file 05525 $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'CheckTheDatabaseMenu.html'); 05526 // Get the template part from the file 05527 $menu = t3lib_parsehtml::getSubpart($templateFile, '###MENU###'); 05528 05529 $menuMarkers = array( 05530 'action' => $this->action, 05531 'updateRequiredTables' => 'Update required tables', 05532 'compare' => 'COMPARE', 05533 'noticeCmpFileCurrent' => ($action_type == 'cmpFile|CURRENT_TABLES' ? ' class="notice"' : ''), 05534 'dumpStaticData' => 'Dump static data', 05535 'import' => 'IMPORT', 05536 'noticeImportCurrent' => ($action_type == 'import|CURRENT_STATIC' ? ' class="notice"' : ''), 05537 'noticeCmpTca' => ($action_type == "cmpTCA|" ? ' class="notice"' : ''), 05538 'compareWithTca' => 'Compare with $TCA', 05539 'noticeAdminUser' => ($action_type == "adminUser|" ? ' class="notice"' : ''), 05540 'createAdminUser' => 'Create "admin" user', 05541 'noticeUc' => ($action_type == "UC|" ? ' class="notice"' : ''), 05542 'resetUserPreferences' => 'Reset user preferences', 05543 'noticeCache' => ($action_type == "cache|" ? ' class="notice"' : ''), 05544 'clearTables' => 'Clear tables' 05545 ); 05546 // Get the subpart for extra SQL 05547 $extraSql = t3lib_parsehtml::getSubpart($menu, '###EXTRASQL###'); 05548 05549 $directJump=''; 05550 $extraSqlFiles = array(); 05551 foreach ($sql_files as $k => $file) { 05552 if ($this->mode=="123" && !count($whichTables) && strstr($file,'_testsite')) { 05553 $directJump = $this->action.'&TYPO3_INSTALL[database_type]=import|'.rawurlencode($file); 05554 } 05555 $lf=t3lib_div::testInt($k); 05556 $fShortName = substr($file,strlen(PATH_site)); 05557 05558 $spec1 = $spec2 = ''; 05559 // Define the markers content 05560 $extraSqlMarkers = array( 05561 'fileShortName' => $fShortName, 05562 'fileSize' => t3lib_div::formatSize(filesize($file)), 05563 'noticeCmpFile' => ($action_type == 'cmpFile|' . $file ? ' class="notice"' : ''), 05564 'file' => rawurlencode($file), 05565 'noticeImport' => ($action_type == 'import|' . $file ? ' class="notice"' : ''), 05566 'specs' => $spec1 . $spec2, 05567 'noticeView' => ($action_type == 'view|' . $file ? ' class="notice"' : ''), 05568 'view' => 'VIEW' 05569 ); 05570 // Fill the markers in the subpart 05571 $extraSqlFiles[] = t3lib_parsehtml::substituteMarkerArray( 05572 $extraSql, 05573 $extraSqlMarkers, 05574 '###|###', 05575 TRUE, 05576 FALSE 05577 ); 05578 } 05579 // Substitute the subpart for extra SQL 05580 $menu = t3lib_parsehtml::substituteSubpart( 05581 $menu, 05582 '###EXTRASQL###', 05583 implode(LF, $extraSqlFiles) 05584 ); 05585 // Fill the markers 05586 $menu = t3lib_parsehtml::substituteMarkerArray( 05587 $menu, 05588 $menuMarkers, 05589 '###|###', 05590 TRUE, 05591 FALSE 05592 ); 05593 05594 if ($directJump) { 05595 if (!$action_type) { 05596 $this->message($headCode, 'Menu', ' 05597 <script language="javascript" type="text/javascript"> 05598 window.location.href = "' . $directJump . '"; 05599 </script>', 05600 0, 1); 05601 } 05602 } else { 05603 $this->message($headCode, 'Menu', ' 05604 <p> 05605 From this menu you can select which of the available SQL 05606 files you want to either compare or import/merge with the 05607 existing database. 05608 </p> 05609 <dl id="t3-install-checkthedatabaseexplanation"> 05610 <dt> 05611 COMPARE: 05612 </dt> 05613 <dd> 05614 Compares the tables and fields of the current database 05615 and the selected file. It also offers to \'update\' the 05616 difference found. 05617 </dd> 05618 <dt> 05619 IMPORT: 05620 </dt> 05621 <dd> 05622 Imports the SQL-dump file into the current database. You 05623 can either dump the raw file or choose which tables to 05624 import. In any case, you\'ll see a new screen where you 05625 must confirm the operation. 05626 </dd> 05627 <dt> 05628 VIEW: 05629 </dt> 05630 <dd> 05631 Shows the content of the SQL-file, limiting characters 05632 on a single line to a reader-friendly amount. 05633 </dd> 05634 </dl> 05635 <p> 05636 The SQL-files are selected from typo3conf/ (here you can put 05637 your own) and t3lib/stddb/ (TYPO3 distribution). The 05638 SQL-files should be made by the <em>mysqldump</em> tool or 05639 at least be formatted like that tool would do. 05640 </p> 05641 ' . $menu, 0, 1); 05642 } 05643 05644 if ($action_type) { 05645 switch($actionParts[0]) { 05646 case 'cmpFile': 05647 $tblFileContent=''; 05648 if (!strcmp($actionParts[1],'CURRENT_TABLES')) { 05649 $tblFileContent = t3lib_div::getUrl(PATH_t3lib.'stddb/tables.sql'); 05650 05651 foreach ($GLOBALS['TYPO3_LOADED_EXT'] as $loadedExtConf) { 05652 if (is_array($loadedExtConf) && $loadedExtConf['ext_tables.sql']) { 05653 $tblFileContent .= LF . LF . LF . LF . t3lib_div::getUrl($loadedExtConf['ext_tables.sql']); 05654 } 05655 } 05656 } elseif (@is_file($actionParts[1])) { 05657 $tblFileContent = t3lib_div::getUrl($actionParts[1]); 05658 } 05659 if ($tblFileContent) { 05660 $fileContent = implode( 05661 LF, 05662 $this->getStatementArray($tblFileContent,1,'^CREATE TABLE ') 05663 ); 05664 $FDfile = $this->getFieldDefinitions_fileContent($fileContent); 05665 if (!count($FDfile)) { 05666 die ("Error: There were no 'CREATE TABLE' definitions in the provided file"); 05667 } 05668 05669 // Updating database... 05670 if (is_array($this->INSTALL['database_update'])) { 05671 $FDdb = $this->getFieldDefinitions_database(); 05672 $diff = $this->getDatabaseExtra($FDfile, $FDdb); 05673 $update_statements = $this->getUpdateSuggestions($diff); 05674 $diff = $this->getDatabaseExtra($FDdb, $FDfile); 05675 $remove_statements = $this->getUpdateSuggestions($diff,'remove'); 05676 05677 $results = array(); 05678 $results[] = $this->performUpdateQueries($update_statements['clear_table'], $this->INSTALL['database_update']); 05679 05680 $results[] = $this->performUpdateQueries($update_statements['add'], $this->INSTALL['database_update']); 05681 $results[] = $this->performUpdateQueries($update_statements['change'], $this->INSTALL['database_update']); 05682 $results[] = $this->performUpdateQueries($remove_statements['change'], $this->INSTALL['database_update']); 05683 $results[] = $this->performUpdateQueries($remove_statements['drop'], $this->INSTALL['database_update']); 05684 05685 $results[] = $this->performUpdateQueries($update_statements['create_table'], $this->INSTALL['database_update']); 05686 $results[] = $this->performUpdateQueries($remove_statements['change_table'], $this->INSTALL['database_update']); 05687 $results[] = $this->performUpdateQueries($remove_statements['drop_table'], $this->INSTALL['database_update']); 05688 05689 $this->databaseUpdateErrorMessages = array(); 05690 foreach ($results as $resultSet) { 05691 if (is_array($resultSet)) { 05692 foreach ($resultSet as $key => $errorMessage) { 05693 $this->databaseUpdateErrorMessages[$key] = $errorMessage; 05694 } 05695 } 05696 } 05697 } 05698 05699 // Init again / first time depending... 05700 $FDdb = $this->getFieldDefinitions_database(); 05701 05702 $diff = $this->getDatabaseExtra($FDfile, $FDdb); 05703 $update_statements = $this->getUpdateSuggestions($diff); 05704 05705 $diff = $this->getDatabaseExtra($FDdb, $FDfile); 05706 $remove_statements = $this->getUpdateSuggestions($diff,'remove'); 05707 05708 $tLabel = 'Update database tables and fields'; 05709 05710 if ($remove_statements || $update_statements) { 05711 $formContent = $this->generateUpdateDatabaseForm('get_form',$update_statements,$remove_statements,$action_type); 05712 $this->message($tLabel, 'Table and field definitions should be updated', ' 05713 <p> 05714 There seems to be a number of differencies 05715 between the database and the selected 05716 SQL-file. 05717 <br /> 05718 Please select which statements you want to 05719 execute in order to update your database: 05720 </p> 05721 ' . $formContent, 2); 05722 } else { 05723 $formContent = $this->generateUpdateDatabaseForm('get_form',$update_statements,$remove_statements,$action_type); 05724 $this->message($tLabel, 'Table and field definitions are OK.', ' 05725 <p> 05726 The tables and fields in the current 05727 database corresponds perfectly to the 05728 database in the selected SQL-file. 05729 </p> 05730 ', -1); 05731 } 05732 } 05733 break; 05734 case 'cmpTCA': 05735 $this->includeTCA(); 05736 $FDdb = $this->getFieldDefinitions_database(); 05737 05738 // Displaying configured fields which are not in the database 05739 $tLabel='Tables and fields in $TCA, but not in database'; 05740 $cmpTCA_DB = $this->compareTCAandDatabase($GLOBALS['TCA'],$FDdb); 05741 if (!count($cmpTCA_DB['extra'])) { 05742 $this->message($tLabel, 'Table and field definitions OK', ' 05743 <p> 05744 All fields and tables configured in $TCA 05745 appeared to exist in the database as well 05746 </p> 05747 ', -1); 05748 } else { 05749 $this->message($tLabel, 'Invalid table and field definitions in $TCA!', ' 05750 <p> 05751 There are some tables and/or fields configured 05752 in the $TCA array which do not exist in the 05753 database! 05754 <br /> 05755 This will most likely cause you trouble with the 05756 TYPO3 backend interface! 05757 </p> 05758 ', 3); 05759 foreach ($cmpTCA_DB['extra'] as $tableName => $conf) { 05760 $this->message($tLabel, $tableName,$this->displayFields($conf['fields'],0,'Suggested database field:'),2); 05761 } 05762 } 05763 05764 // Displaying tables that are not setup in 05765 $cmpDB_TCA = $this->compareDatabaseAndTCA($FDdb,$GLOBALS['TCA']); 05766 $excludeTables='be_sessions,fe_session_data,fe_sessions'; 05767 if (TYPO3_OS=='WIN') {$excludeTables = strtolower($excludeTables);} 05768 $excludeFields = array( 05769 'be_users' => 'uc,lastlogin,usergroup_cached_list', 05770 'fe_users' => 'uc,lastlogin,fe_cruser_id', 05771 'pages' => 'SYS_LASTCHANGED', 05772 'sys_dmail' => 'mailContent', 05773 'tt_board' => 'doublePostCheck', 05774 'tt_guest' => 'doublePostCheck', 05775 'tt_products' => 'ordered' 05776 ); 05777 $tCount=0; 05778 $fCount=0; 05779 $tLabel="Tables from database, but not in \$TCA"; 05780 $fLabel="Fields from database, but not in \$TCA"; 05781 $this->message($tLabel); 05782 if (is_array($cmpDB_TCA['extra'])) { 05783 foreach ($cmpDB_TCA['extra'] as $tableName => $conf) { 05784 if (!t3lib_div::inList($excludeTables,$tableName) 05785 && substr($tableName,0,4)!="sys_" 05786 && substr($tableName,-3)!="_mm" 05787 && substr($tableName,0,6)!="index_" 05788 && substr($tableName,0,6)!='cache_') { 05789 if ($conf['whole_table']) { 05790 $this->message($tLabel, $tableName,$this->displayFields($conf['fields']),1); 05791 $tCount++; 05792 } else { 05793 list($theContent, $fC) = $this->displaySuggestions($conf['fields'],$excludeFields[$tableName]); 05794 $fCount+=$fC; 05795 if ($fC) { 05796 $this->message($fLabel, $tableName,$theContent,1); 05797 } 05798 } 05799 } 05800 } 05801 } 05802 if (!$tCount) { 05803 $this->message($tLabel, 'Correct number of tables in the database', ' 05804 <p> 05805 There are no extra tables in the database 05806 compared to the configured tables in the $TCA 05807 array. 05808 </p> 05809 ', -1); 05810 } else { 05811 $this->message($tLabel, 'Extra tables in the database', ' 05812 <p> 05813 There are some tables in the database which are 05814 not configured in the $TCA array. 05815 <br /> 05816 You should probably not worry about this, but 05817 please make sure that you know what these tables 05818 are about and why they are not configured in 05819 $TCA. 05820 </p> 05821 ', 2); 05822 } 05823 05824 if (!$fCount) { 05825 $this->message($fLabel, 'Correct number of fields in the database', ' 05826 <p> 05827 There are no additional fields in the database 05828 tables compared to the configured fields in the 05829 $TCA array. 05830 </p> 05831 ', -1); 05832 } else { 05833 $this->message($fLabel, 'Extra fields in the database', ' 05834 <p> 05835 There are some additional fields the database 05836 tables which are not configured in the $TCA 05837 array. 05838 <br /> 05839 You should probably not worry about this, but 05840 please make sure that you know what these fields 05841 are about and why they are not configured in 05842 $TCA. 05843 </p> 05844 ', 2); 05845 } 05846 05847 // Displaying actual and suggested field database defitions 05848 if (is_array($cmpTCA_DB['matching'])) { 05849 $tLabel="Comparison between database and \$TCA"; 05850 05851 $this->message($tLabel, 'Actual and suggested field definitions', ' 05852 <p> 05853 This table shows you the suggested field 05854 definitions which are calculated based on the 05855 configuration in $TCA. 05856 <br /> 05857 If the suggested value differs from the actual 05858 current database value, you should not panic, 05859 but simply check if the datatype of that field 05860 is sufficient compared to the data, you want 05861 TYPO3 to put there. 05862 </p> 05863 ', 0); 05864 foreach ($cmpTCA_DB['matching'] as $tableName => $conf) { 05865 $this->message($tLabel, $tableName,$this->displayFieldComp($conf['fields'], $FDdb[$tableName]['fields']),1); 05866 } 05867 } 05868 break; 05869 case 'import': 05870 $mode123Imported=0; 05871 $tblFileContent=''; 05872 if (preg_match('/^CURRENT_/', $actionParts[1])) { 05873 if (!strcmp($actionParts[1],'CURRENT_TABLES') || !strcmp($actionParts[1],'CURRENT_TABLES+STATIC')) { 05874 $tblFileContent = t3lib_div::getUrl(PATH_t3lib.'stddb/tables.sql'); 05875 05876 foreach ($GLOBALS['TYPO3_LOADED_EXT'] as $loadedExtConf) { 05877 if (is_array($loadedExtConf) && $loadedExtConf['ext_tables.sql']) { 05878 $tblFileContent.= LF . LF . LF . LF . t3lib_div::getUrl($loadedExtConf['ext_tables.sql']); 05879 } 05880 } 05881 } 05882 if (!strcmp($actionParts[1],'CURRENT_STATIC') || !strcmp($actionParts[1],'CURRENT_TABLES+STATIC')) { 05883 foreach ($GLOBALS['TYPO3_LOADED_EXT'] as $loadedExtConf) { 05884 if (is_array($loadedExtConf) && $loadedExtConf['ext_tables_static+adt.sql']) { 05885 $tblFileContent.= LF . LF . LF . LF . t3lib_div::getUrl($loadedExtConf['ext_tables_static+adt.sql']); 05886 } 05887 } 05888 } 05889 } elseif (@is_file($actionParts[1])) { 05890 $tblFileContent = t3lib_div::getUrl($actionParts[1]); 05891 } 05892 05893 if ($tblFileContent) { 05894 $tLabel='Import SQL dump'; 05895 // Getting statement array from 05896 $statements = $this->getStatementArray($tblFileContent,1); 05897 list($statements_table, $insertCount) = $this->getCreateTables($statements,1); 05898 05899 // Updating database... 05900 if ($this->INSTALL['database_import_all']) { 05901 $r=0; 05902 foreach ($statements as $k=>$v) { 05903 $res = $GLOBALS['TYPO3_DB']->admin_query($v); 05904 $r++; 05905 } 05906 05907 // Make a database comparison because some tables that are defined twice have 05908 // not been created at this point. This applies to the "pages.*" 05909 // fields defined in sysext/cms/ext_tables.sql for example. 05910 $fileContent = implode( 05911 LF, 05912 $this->getStatementArray($tblFileContent,1,'^CREATE TABLE ') 05913 ); 05914 $FDfile = $this->getFieldDefinitions_fileContent($fileContent); 05915 $FDdb = $this->getFieldDefinitions_database(); 05916 $diff = $this->getDatabaseExtra($FDfile, $FDdb); 05917 $update_statements = $this->getUpdateSuggestions($diff); 05918 if (is_array($update_statements['add'])) { 05919 foreach ($update_statements['add'] as $statement) { 05920 $res = $GLOBALS['TYPO3_DB']->admin_query($statement); 05921 } 05922 } 05923 05924 if ($this->mode=='123') { 05925 // Create default be_user admin/password 05926 $username = 'admin'; 05927 $pass = 'password'; 05928 05929 $count = $GLOBALS['TYPO3_DB']->exec_SELECTcountRows( 05930 'uid', 05931 'be_users', 05932 'username=' . $GLOBALS['TYPO3_DB']->fullQuoteStr($username, 'be_users') 05933 ); 05934 if (!$count) { 05935 $insertFields = array( 05936 'username' => $username, 05937 'password' => md5($pass), 05938 'admin' => 1, 05939 'uc' => '', 05940 'fileoper_perms' => 0, 05941 'tstamp' => $GLOBALS['EXEC_TIME'], 05942 'crdate' => $GLOBALS['EXEC_TIME'] 05943 ); 05944 05945 $GLOBALS['TYPO3_DB']->exec_INSERTquery('be_users', $insertFields); 05946 } 05947 } 05948 05949 $this->message($tLabel, 'Imported ALL', ' 05950 <p> 05951 Queries: ' . $r . ' 05952 </p> 05953 ', 1, 1); 05954 if (t3lib_div::_GP('goto_step')) { 05955 $this->action.='&step='.t3lib_div::_GP('goto_step'); 05956 t3lib_utility_Http::redirect($this->action); 05957 } 05958 } elseif (is_array($this->INSTALL['database_import'])) { 05959 // Traverse the tables 05960 foreach ($this->INSTALL['database_import'] as $table => $md5str) { 05961 if ($md5str==md5($statements_table[$table])) { 05962 $res = $GLOBALS['TYPO3_DB']->admin_query('DROP TABLE IF EXISTS '.$table); 05963 $res = $GLOBALS['TYPO3_DB']->admin_query($statements_table[$table]); 05964 05965 if ($insertCount[$table]) { 05966 $statements_insert = $this->getTableInsertStatements($statements, $table); 05967 foreach ($statements_insert as $k => $v) { 05968 $res = $GLOBALS['TYPO3_DB']->admin_query($v); 05969 } 05970 } 05971 05972 $this->message($tLabel, 'Imported \'' . $table . '\'', ' 05973 <p> 05974 Rows: ' . $insertCount[$table] . ' 05975 </p> 05976 ', 1, 1); 05977 } 05978 } 05979 } 05980 05981 $mode123Imported=$this->isBasicComplete($tLabel); 05982 05983 if (!$mode123Imported) { 05984 // Re-Getting current tables - may have been changed during import 05985 $whichTables=$this->getListOfTables(); 05986 05987 if (count($statements_table)) { 05988 reset($statements_table); 05989 $out=''; 05990 // Get the template file 05991 $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'CheckTheDatabaseImport.html'); 05992 // Get the template part from the file 05993 $content = t3lib_parsehtml::getSubpart($templateFile, '###IMPORT###'); 05994 05995 if ($this->mode!='123') { 05996 $tables = array(); 05997 // Get the subpart for regular mode 05998 $regularModeSubpart = t3lib_parsehtml::getSubpart($content, '###REGULARMODE###'); 05999 foreach ($statements_table as $table => $definition) { 06000 // Get the subpart for rows 06001 $tableSubpart = t3lib_parsehtml::getSubpart($content, '###ROWS###'); 06002 // Fill the 'table exists' part when it exists 06003 $exist=isset($whichTables[$table]); 06004 if ($exist) { 06005 // Get the subpart for table exists 06006 $existSubpart = t3lib_parsehtml::getSubpart($tableSubpart, '###EXIST###'); 06007 // Define the markers content 06008 $existMarkers = array ( 06009 'tableExists' => 'Table exists!', 06010 'backPath' => $this->backPath 06011 ); 06012 // Fill the markers in the subpart 06013 $existSubpart = t3lib_parsehtml::substituteMarkerArray( 06014 $existSubpart, 06015 $existMarkers, 06016 '###|###', 06017 TRUE, 06018 FALSE 06019 ); 06020 } 06021 // Substitute the subpart for table exists 06022 $tableHtml = t3lib_parsehtml::substituteSubpart( 06023 $tableSubpart, 06024 '###EXIST###', 06025 $existSubpart 06026 ); 06027 // Define the markers content 06028 $tableMarkers = array ( 06029 'table' => $table, 06030 'definition' => md5($definition), 06031 'count' => $insertCount[$table] ? $insertCount[$table] : '', 06032 'rowLabel' => $insertCount[$table] ? 'Rows: ' : '', 06033 'tableExists' => 'Table exists!', 06034 'backPath' => $this->backPath 06035 ); 06036 // Fill the markers 06037 $tables[] = t3lib_parsehtml::substituteMarkerArray( 06038 $tableHtml, 06039 $tableMarkers, 06040 '###|###', 06041 TRUE, 06042 FALSE 06043 ); 06044 } 06045 // Substitute the subpart for the rows 06046 $regularModeSubpart = t3lib_parsehtml::substituteSubpart( 06047 $regularModeSubpart, 06048 '###ROWS###', 06049 implode(LF, $tables) 06050 ); 06051 } 06052 // Substitute the subpart for the regular mode 06053 $content = t3lib_parsehtml::substituteSubpart( 06054 $content, 06055 '###REGULARMODE###', 06056 $regularModeSubpart 06057 ); 06058 // Define the markers content 06059 $contentMarkers = array( 06060 'checked' => ($this->mode == '123' || t3lib_div::_GP('presetWholeTable') ? 'checked="checked"' : ''), 06061 'label' => 'Import the whole file \'' . basename($actionParts[1]) . '\' directly (ignores selections above)' 06062 ); 06063 // Fill the markers 06064 $content = t3lib_parsehtml::substituteMarkerArray( 06065 $content, 06066 $contentMarkers, 06067 '###|###', 06068 TRUE, 06069 FALSE 06070 ); 06071 06072 $form = $this->getUpdateDbFormWrap($action_type, $content); 06073 $this->message($tLabel, 'Select tables to import', ' 06074 <p> 06075 This is an overview of the CREATE TABLE 06076 definitions in the SQL file. 06077 <br /> 06078 Select which tables you want to dump to 06079 the database. 06080 <br /> 06081 Any table you choose dump to the 06082 database is dropped from the database 06083 first, so you\'ll lose all data in 06084 existing tables. 06085 </p> 06086 ' . $form, 1, 1); 06087 } else { 06088 $this->message($tLabel, 'No tables', ' 06089 <p> 06090 There seems to be no CREATE TABLE 06091 definitions in the SQL file. 06092 <br /> 06093 This tool is intelligently creating one 06094 table at a time and not just dumping the 06095 whole content of the file uncritically. 06096 That\'s why there must be defined tables 06097 in the SQL file. 06098 </p> 06099 ', 3, 1); 06100 } 06101 } 06102 } 06103 break; 06104 case 'view': 06105 if (@is_file($actionParts[1])) { 06106 $tLabel = 'Import SQL dump'; 06107 // Getting statement array from 06108 $fileContent = t3lib_div::getUrl($actionParts[1]); 06109 $statements = $this->getStatementArray($fileContent, 1); 06110 $maxL = 1000; 06111 $strLen = strlen($fileContent); 06112 $maxlen = 200+($maxL-t3lib_div::intInRange(($strLen-20000)/100,0,$maxL)); 06113 if (count($statements)) { 06114 $out = ''; 06115 foreach ($statements as $statement) { 06116 $out.= '<p>' . nl2br(htmlspecialchars(t3lib_div::fixed_lgd_cs($statement,$maxlen))) . '</p>'; 06117 } 06118 } 06119 $this->message($tLabel,'Content of '.basename($actionParts[1]),$out,1); 06120 } 06121 break; 06122 // Create admin user 06123 case 'adminUser': 06124 if ($whichTables['be_users']) { 06125 if (is_array($this->INSTALL['database_adminUser'])) { 06126 $username = preg_replace('/[^\da-z._-]/i', '', trim($this->INSTALL['database_adminUser']['username'])); 06127 $pass = trim($this->INSTALL['database_adminUser']['password']); 06128 $pass2 = trim($this->INSTALL['database_adminUser']['password2']); 06129 if ($username && $pass && $pass2) { 06130 if ($pass != $pass2) { 06131 $this->message($headCode, 'Passwords are not equal!', ' 06132 <p> 06133 The passwords entered twice are not 06134 equal. 06135 </p> 06136 ', 2, 1); 06137 } else { 06138 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid', 'be_users', 'username='.$GLOBALS['TYPO3_DB']->fullQuoteStr($username, 'be_users')); 06139 if (!$GLOBALS['TYPO3_DB']->sql_num_rows($res)) { 06140 06141 $insertFields = array( 06142 'username' => $username, 06143 'password' => md5($pass), 06144 'admin' => 1, 06145 'uc' => '', 06146 'fileoper_perms' => 0, 06147 'tstamp' => $GLOBALS['EXEC_TIME'], 06148 'crdate' => $GLOBALS['EXEC_TIME'] 06149 ); 06150 06151 $result = $GLOBALS['TYPO3_DB']->exec_INSERTquery('be_users', $insertFields); 06152 06153 $this->isBasicComplete($headCode); 06154 06155 if ($result) { 06156 $this->message($headCode, 'User created', ' 06157 <p> 06158 Username: 06159 <strong>' . 06160 htmlspecialchars($username) . ' 06161 </strong> 06162 </p> 06163 ', 1, 1); 06164 } else { 06165 $this->message($headCode, 'User not created', ' 06166 <p> 06167 Error: 06168 <strong>' . 06169 htmlspecialchars($GLOBALS['TYPO3_DB']->sql_error()) . ' 06170 </strong> 06171 </p> 06172 ', 3, 1); 06173 } 06174 } else { 06175 $this->message($headCode, 'Username not unique!', ' 06176 <p> 06177 The username, 06178 <strong>' . 06179 htmlspecialchars($username) . ' 06180 </strong> 06181 , was not unique. 06182 </p> 06183 ', 2, 1); 06184 } 06185 } 06186 } else { 06187 $this->message($headCode, 'Missing data!', ' 06188 <p> 06189 Not all required form fields have been 06190 filled. 06191 </p> 06192 ', 2, 1); 06193 } 06194 } 06195 // Get the template file 06196 $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'CheckTheDatabaseAdminUser.html'); 06197 // Get the template part from the file 06198 $content = t3lib_parsehtml::getSubpart($templateFile, '###TEMPLATE###'); 06199 // Define the markers content 06200 $contentMarkers = array( 06201 'userName' => 'username - unique, no space, lowercase', 06202 'password' => 'password', 06203 'repeatPassword' => 'password (repeated)' 06204 ); 06205 // Fill the markers 06206 $content = t3lib_parsehtml::substituteMarkerArray( 06207 $content, 06208 $contentMarkers, 06209 '###|###', 06210 TRUE, 06211 FALSE 06212 ); 06213 $form = $this->getUpdateDbFormWrap($action_type, $content); 06214 $this->message($headCode, 'Create admin user', ' 06215 <p> 06216 Enter username and password for a new admin 06217 user. 06218 <br /> 06219 You should use this function only if there are 06220 no admin users in the database, for instance if 06221 this is a blank database. 06222 <br /> 06223 After you\'ve created the user, log in and add 06224 the rest of the user information, like email and 06225 real name. 06226 </p> 06227 ' . $form, 0, 1); 06228 } else { 06229 $this->message($headCode, 'Required table not in database', ' 06230 <p> 06231 \'be_users\' must be a table in the database! 06232 </p> 06233 ', 3, 1); 06234 } 06235 break; 06236 // clear uc 06237 case 'UC': 06238 if ($whichTables['be_users']) { 06239 if (!strcmp($this->INSTALL['database_UC'],1)) { 06240 $GLOBALS['TYPO3_DB']->exec_UPDATEquery('be_users', '', array('uc' => '')); 06241 $this->message($headCode, 'Clearing be_users.uc', ' 06242 <p> 06243 Done. 06244 </p> 06245 ', 1); 06246 } 06247 // Get the template file 06248 $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'CheckTheDatabaseUc.html'); 06249 // Get the template part from the file 06250 $content = t3lib_parsehtml::getSubpart($templateFile, '###TEMPLATE###'); 06251 // Define the markers content 06252 $contentMarkers = array( 06253 'clearBeUsers' => 'Clear be_users preferences ("uc" field)' 06254 ); 06255 // Fill the markers 06256 $content = t3lib_parsehtml::substituteMarkerArray( 06257 $content, 06258 $contentMarkers, 06259 '###|###', 06260 TRUE, 06261 FALSE 06262 ); 06263 06264 $form = $this->getUpdateDbFormWrap($action_type, $content); 06265 $this->message($headCode, 'Clear user preferences', ' 06266 <p> 06267 If you press this button all backend users from 06268 the tables be_users will have their user 06269 preferences cleared (field \'uc\' set to an 06270 empty string). 06271 <br /> 06272 This may come in handy in rare cases where that 06273 configuration may be corrupt. 06274 <br /> 06275 Clearing this will clear all user settings from 06276 the \'Setup\' module. 06277 </p> 06278 ' . $form); 06279 } else { 06280 $this->message($headCode, 'Required table not in database', ' 06281 <p> 06282 \'be_users\' must be a table in the database! 06283 </p> 06284 ', 3); 06285 } 06286 break; 06287 case 'cache': 06288 $tableListArr = explode(',','cache_pages,cache_pagesection,cache_hash,cache_imagesizes,--div--,sys_log,sys_history,--div--,be_sessions,fe_sessions,fe_session_data'. 06289 (t3lib_extMgm::isLoaded('indexed_search') ? ',--div--,index_words,index_rel,index_phash,index_grlist,index_section,index_fulltext' : ''). 06290 (t3lib_extMgm::isLoaded('tt_products') ? ',--div--,sys_products_orders,sys_products_orders_mm_tt_products' : ''). 06291 (t3lib_extMgm::isLoaded('direct_mail') ? ',--div--,sys_dmail_maillog' : ''). 06292 (t3lib_extMgm::isLoaded('sys_stat') ? ',--div--,sys_stat' : '') 06293 ); 06294 06295 if (is_array($this->INSTALL['database_clearcache'])) { 06296 $qList = array(); 06297 // Get the template file 06298 $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'CheckTheDatabaseCache.html'); 06299 // Get the subpart for emptied tables 06300 $emptiedTablesSubpart = t3lib_parsehtml::getSubpart($templateFile, '###EMPTIEDTABLES###'); 06301 // Get the subpart for table 06302 $tableSubpart = t3lib_parsehtml::getSubpart($emptiedTablesSubpart, '###TABLE###'); 06303 foreach ($tableListArr as $table) { 06304 if ($table!='--div--') { 06305 $table_c = TYPO3_OS=='WIN' ? strtolower($table) : $table; 06306 if ($this->INSTALL['database_clearcache'][$table] && $whichTables[$table_c]) { 06307 $GLOBALS['TYPO3_DB']->exec_TRUNCATEquery($table); 06308 // Define the markers content 06309 $emptiedTablesMarkers = array( 06310 'tableName' => $table 06311 ); 06312 // Fill the markers in the subpart 06313 $qList[] = t3lib_parsehtml::substituteMarkerArray( 06314 $tableSubpart, 06315 $emptiedTablesMarkers, 06316 '###|###', 06317 TRUE, 06318 FALSE 06319 ); 06320 } 06321 } 06322 } 06323 // Substitute the subpart for table 06324 $emptiedTablesSubpart = t3lib_parsehtml::substituteSubpart( 06325 $emptiedTablesSubpart, 06326 '###TABLE###', 06327 implode(LF, $qList) 06328 ); 06329 06330 if (count($qList)) { 06331 $this->message($headCode, 'Clearing cache', ' 06332 <p> 06333 The following tables were emptied: 06334 </p> 06335 ' . $emptiedTablesSubpart, 1); 06336 } 06337 } 06338 // Count entries and make checkboxes 06339 $labelArr = array( 06340 'cache_pages' => 'Pages', 06341 'cache_pagesection' => 'TS template related information', 06342 'cache_hash' => 'Multipurpose md5-hash cache', 06343 'cache_imagesizes' => 'Cached image sizes', 06344 'sys_log' => 'Backend action logging', 06345 'sys_stat' => 'Page hit statistics', 06346 'sys_history' => 'Addendum to the sys_log which tracks ALL changes to content through TCE. May become huge by time. Is used for rollback (undo) and the WorkFlow engine.', 06347 'be_sessions' => 'Backend User sessions', 06348 'fe_sessions' => 'Frontend User sessions', 06349 'fe_session_data' => 'Frontend User sessions data', 06350 'sys_dmail_maillog' => 'Direct Mail log', 06351 'sys_products_orders' => 'tt_product orders', 06352 'sys_products_orders_mm_tt_products' => 'relations between tt_products and sys_products_orders' 06353 ); 06354 06355 $countEntries=array(); 06356 reset($tableListArr); 06357 // Get the template file 06358 $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'CheckTheDatabaseCache.html'); 06359 // Get the subpart for table list 06360 $tableListSubpart = t3lib_parsehtml::getSubpart($templateFile, '###TABLELIST###'); 06361 // Get the subpart for the group separator 06362 $groupSubpart = t3lib_parsehtml::getSubpart($tableListSubpart, '###GROUP###'); 06363 // Get the subpart for a single table 06364 $singleTableSubpart = t3lib_parsehtml::getSubpart($tableListSubpart, '###SINGLETABLE###'); 06365 $checkBoxes = array(); 06366 foreach ($tableListArr as $table) { 06367 if ($table!='--div--') { 06368 $table_c = TYPO3_OS=='WIN' ? strtolower($table) : $table; 06369 if ($whichTables[$table_c]) { 06370 $countEntries[$table] = $GLOBALS['TYPO3_DB']->exec_SELECTcountRows('*', $table); 06371 // Checkboxes: 06372 if ( 06373 $this->INSTALL['database_clearcache'][$table] || 06374 $_GET['PRESET']['database_clearcache'][$table] 06375 ) { 06376 $checked = 'checked="checked"'; 06377 } else { 06378 $checked = ''; 06379 } 06380 // Define the markers content 06381 $singleTableMarkers = array( 06382 'table' => $table, 06383 'checked' => $checked, 06384 'count' => '(' . $countEntries[$table] . ' rows)', 06385 'label' => $labelArr[$table] 06386 06387 ); 06388 // Fill the markers in the subpart 06389 $checkBoxes[] = t3lib_parsehtml::substituteMarkerArray( 06390 $singleTableSubpart, 06391 $singleTableMarkers, 06392 '###|###', 06393 TRUE, 06394 FALSE 06395 ); 06396 } 06397 } else { 06398 $checkBoxes[] = $groupSubpart; 06399 } 06400 } 06401 // Substitute the subpart for the single tables 06402 $content = t3lib_parsehtml::substituteSubpart( 06403 $tableListSubpart, 06404 '###SINGLETABLE###', 06405 implode(LF, $checkBoxes) 06406 ); 06407 // Substitute the subpart for the group separator 06408 $content = t3lib_parsehtml::substituteSubpart( 06409 $content, 06410 '###GROUP###', 06411 '' 06412 ); 06413 06414 $form = $this->getUpdateDbFormWrap($action_type, $content); 06415 $this->message($headCode, 'Clear out selected tables', ' 06416 <p> 06417 Pressing this button will delete all records from 06418 the selected tables. 06419 </p> 06420 ' . $form); 06421 break; 06422 } 06423 } 06424 06425 $this->output($this->outputWrapper($this->printAll())); 06426 } 06427 06428 /** 06429 * Generates update wizard 06430 * 06431 * @return void 06432 */ 06433 function updateWizard() { 06434 // clear cache files 06435 t3lib_extMgm::removeCacheFiles(t3lib_extMgm::getCacheFilePrefix()); 06436 06437 // call wizard 06438 $action = ($this->INSTALL['database_type'] ? $this->INSTALL['database_type'] : 'checkForUpdate'); 06439 $this->updateWizard_parts($action); 06440 $this->output($this->outputWrapper($this->printAll())); 06441 } 06442 06443 /** 06444 * Implements the steps for the update wizard 06445 * 06446 * @param string $action Which should be done. 06447 * @return void 06448 */ 06449 function updateWizard_parts($action) { 06450 $content = ''; 06451 $updateItems = array(); 06452 06453 // Get the template file 06454 $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'UpdateWizardParts.html'); 06455 06456 switch ($action) { 06457 // first step - check for updates available 06458 case 'checkForUpdate': 06459 // Get the subpart for check for update 06460 $checkForUpdateSubpart = t3lib_parsehtml::getSubpart($templateFile, '###CHECKFORUPDATE###'); 06461 $title = 'Step 1 - Introduction'; 06462 $updateWizardBoxes = ''; 06463 if (!$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install']['update']) { 06464 $updatesAvailableSubpart = ' 06465 <p> 06466 <strong> 06467 No updates registered! 06468 </strong> 06469 </p> 06470 '; 06471 } else { 06472 06473 // step through list of updates, and check if update is needed and if yes, output an explanation 06474 $updatesAvailableSubpart = t3lib_parsehtml::getSubpart($checkForUpdateSubpart, '###UPDATESAVAILABLE###'); 06475 $updateWizardBoxesSubpart = t3lib_parsehtml::getSubpart($updatesAvailableSubpart, '###UPDATEWIZARDBOXES###'); 06476 $singleUpdateWizardBoxSubpart = t3lib_parsehtml::getSubpart($updateWizardBoxesSubpart, '###SINGLEUPDATEWIZARDBOX###'); 06477 $singleUpdate = array(); 06478 foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install']['update'] as $identifier => $className) { 06479 $tmpObj = $this->getUpgradeObjInstance($className, $identifier); 06480 if ($tmpObj->shouldRenderWizard()) { 06481 $explanation = ''; 06482 $tmpObj->checkForUpdate($explanation); 06483 06484 $updateMarkers = array( 06485 'next' => '<button type="submit" name="TYPO3_INSTALL[update][###IDENTIFIER###]"> 06486 Next 06487 <span class="t3-install-form-button-icon-positive"> </span> 06488 </button>', 06489 'identifier' => $identifier, 06490 'title' => $tmpObj->getTitle(), 06491 'explanation' => $explanation, 06492 ); 06493 06494 // only display the message, no button 06495 if (!$tmpObj->shouldRenderNextButton()) { 06496 $updateMarkers['next'] = ''; 06497 } 06498 06499 $singleUpdate[] = t3lib_parsehtml::substituteMarkerArray( 06500 $singleUpdateWizardBoxSubpart, 06501 $updateMarkers, 06502 '###|###', 06503 TRUE, 06504 FALSE 06505 ); 06506 } 06507 } 06508 06509 if (!empty($singleUpdate)) { 06510 $updateWizardBoxesSubpart = t3lib_parsehtml::substituteSubpart( 06511 $updateWizardBoxesSubpart, 06512 '###SINGLEUPDATEWIZARDBOX###', 06513 implode(LF, $singleUpdate) 06514 ); 06515 $updateWizardBoxesMarkers = array( 06516 'action' => $this->action 06517 ); 06518 $updateWizardBoxesSubpart = t3lib_parsehtml::substituteMarkerArray( 06519 $updateWizardBoxesSubpart, 06520 $updateWizardBoxesMarkers, 06521 '###|###', 06522 TRUE, 06523 FALSE 06524 ); 06525 } else { 06526 $updateWizardBoxesSubpart = ' 06527 <p> 06528 <strong> 06529 No updates to perform! 06530 </strong> 06531 </p> 06532 '; 06533 } 06534 $updatesAvailableSubpart = t3lib_parsehtml::substituteSubpart( 06535 $updatesAvailableSubpart, 06536 '###UPDATEWIZARDBOXES###', 06537 $updateWizardBoxesSubpart 06538 ); 06539 $updatesAvailableMarkers = array( 06540 'finalStep' => 'Final Step', 06541 'finalStepExplanation' => ' 06542 <p> 06543 When all updates are done you should check 06544 your database for required updates. 06545 <br /> 06546 Perform 06547 <strong> 06548 COMPARE DATABASE 06549 </strong> 06550 as often until no more changes are required. 06551 <br /> 06552 <br /> 06553 </p> 06554 ', 06555 'compareDatabase' => 'COMPARE DATABASE' 06556 ); 06557 $updatesAvailableSubpart = t3lib_parsehtml::substituteMarkerArray( 06558 $updatesAvailableSubpart, 06559 $updatesAvailableMarkers, 06560 '###|###', 06561 TRUE, 06562 FALSE 06563 ); 06564 } 06565 $content = t3lib_parsehtml::substituteSubpart( 06566 $checkForUpdateSubpart, 06567 '###UPDATESAVAILABLE###', 06568 $updatesAvailableSubpart 06569 ); 06570 break; 06571 // second step - get user input and ask for final confirmation 06572 case 'getUserInput': 06573 $title = 'Step 2 - Configuration of updates'; 06574 $getUserInputSubpart = t3lib_parsehtml::getSubpart($templateFile, '###GETUSERINPUT###'); 06575 06576 $markers = array( 06577 'introduction' => 'The following updates will be performed:', 06578 'showDatabaseQueries' => 'Show database queries performed', 06579 'performUpdates' => 'Perform updates!', 06580 'action' => $this->action 06581 ); 06582 06583 if (!$this->INSTALL['update']) { 06584 $noUpdatesAvailableSubpart = t3lib_parsehtml::getSubpart($getUserInputSubpart, '###NOUPDATESAVAILABLE###'); 06585 06586 $noUpdateMarkers['noUpdates'] = 'No updates selected!'; 06587 06588 $noUpdatesAvailableSubpart = t3lib_parsehtml::substituteMarkerArray( 06589 $noUpdatesAvailableSubpart, 06590 $noUpdateMarkers, 06591 '###|###', 06592 TRUE, 06593 FALSE 06594 ); 06595 break; 06596 } else { 06597 // update methods might need to get custom data 06598 $updatesAvailableSubpart = t3lib_parsehtml::getSubpart($getUserInputSubpart, '###UPDATESAVAILABLE###'); 06599 $updateItems = array(); 06600 foreach ($this->INSTALL['update'] as $identifier => $tmp) { 06601 $updateMarkers = array(); 06602 06603 $className = $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install']['update'][$identifier]; 06604 06605 $tmpObj = $this->getUpgradeObjInstance($className, $identifier); 06606 06607 $updateMarkers['identifier'] = $identifier; 06608 $updateMarkers['title'] = $tmpObj->getTitle(); 06609 06610 if (method_exists($tmpObj,'getUserInput')) { 06611 $updateMarkers['identifierMethod'] = $tmpObj->getUserInput('TYPO3_INSTALL[update][' . $identifier . ']'); 06612 } 06613 06614 $updateItems[] = t3lib_parsehtml::substituteMarkerArray( 06615 $updatesAvailableSubpart, 06616 $updateMarkers, 06617 '###|###', 06618 TRUE, 06619 TRUE 06620 ); 06621 } 06622 $updatesAvailableSubpart = implode(LF, $updateItems); 06623 } 06624 06625 $content = t3lib_parsehtml::substituteSubpart( 06626 $getUserInputSubpart, 06627 '###NOUPDATESAVAILABLE###', 06628 $noUpdatesAvailableSubpart 06629 ); 06630 $content = t3lib_parsehtml::substituteSubpart( 06631 $content, 06632 '###UPDATESAVAILABLE###', 06633 $updatesAvailableSubpart 06634 ); 06635 $content = t3lib_parsehtml::substituteMarkerArray( 06636 $content, 06637 $markers, 06638 '###|###', 06639 TRUE, 06640 FALSE 06641 ); 06642 break; 06643 case 'performUpdate': // third step - perform update 06644 $title = 'Step 3 - Perform updates'; 06645 $performUpdateSubpart = t3lib_parsehtml::getSubpart($templateFile, '###PERFORMUPDATE###'); 06646 $updateItemsSubpart = t3lib_parsehtml::getSubpart($performUpdateSubpart, '###UPDATEITEMS###'); 06647 $checkUserInputSubpart = t3lib_parsehtml::getSubpart($updateItemsSubpart, '###CHECKUSERINPUT###'); 06648 $updatePerformedSubpart = t3lib_parsehtml::getSubpart($updateItemsSubpart, '###UPDATEPERFORMED###'); 06649 $noPerformUpdateSubpart = t3lib_parsehtml::getSubpart($updateItemsSubpart, '###NOPERFORMUPDATE###'); 06650 $databaseQueriesSubpart = t3lib_parsehtml::getSubpart($updatePerformedSubpart, '###DATABASEQUERIES###'); 06651 $customOutputSubpart = t3lib_parsehtml::getSubpart($updatePerformedSubpart, '###CUSTOMOUTPUT###'); 06652 if (!$this->INSTALL['update']['extList']) { break; } 06653 06654 $GLOBALS['TYPO3_DB']->store_lastBuiltQuery = TRUE; 06655 foreach ($this->INSTALL['update']['extList'] as $identifier) { 06656 $className = $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install']['update'][$identifier]; 06657 06658 $tmpObj = $this->getUpgradeObjInstance($className, $identifier); 06659 $updateItemsMarkers['identifier'] = $identifier; 06660 $updateItemsMarkers['title'] = $tmpObj->getTitle(); 06661 // check user input if testing method is available 06662 if (method_exists($tmpObj,'checkUserInput') && !$tmpObj->checkUserInput($customOutput)) { 06663 $customOutput = ''; 06664 $userInputMarkers = array( 06665 'customOutput' => ($customOutput ? $customOutput : 'Something went wrong'), 06666 'goBack' => 'Go back to update configuration' 06667 ); 06668 $checkUserInput = t3lib_parsehtml::substituteMarkerArray( 06669 $checkUserInputSubpart, 06670 $userInputMarkers, 06671 '###|###', 06672 TRUE, 06673 FALSE 06674 ); 06675 } else { 06676 06677 if (method_exists($tmpObj,'performUpdate')) { 06678 $customOutput = ''; 06679 $dbQueries = array(); 06680 $databaseQueries = array(); 06681 if ($tmpObj->performUpdate($dbQueries, $customOutput)) { 06682 $performUpdateMarkers['updateStatus'] = 'Update successful!'; 06683 } else { 06684 $performUpdateMarkers['updateStatus'] = 'Update FAILED!'; 06685 } 06686 if ($this->INSTALL['update']['showDatabaseQueries']) { 06687 $content .= '<br />' . implode('<br />',$dbQueries); 06688 foreach($dbQueries as $query) { 06689 $databaseQueryMarkers['query'] = $query; 06690 $databaseQueries[] = t3lib_parsehtml::substituteMarkerArray( 06691 $databaseQueriesSubpart, 06692 $databaseQueryMarkers, 06693 '###|###', 06694 TRUE, 06695 FALSE 06696 ); 06697 } 06698 } 06699 06700 if (strlen($customOutput)) { 06701 $content.= '<br />' . $customOutput; 06702 $customOutputMarkers['custom'] = $customOutput; 06703 $customOutputItem = t3lib_parsehtml::substituteMarkerArray( 06704 $customOutputSubpart, 06705 $customOutputMarkers, 06706 '###|###', 06707 TRUE, 06708 FALSE 06709 ); 06710 } 06711 06712 $updatePerformed = t3lib_parsehtml::substituteSubpart( 06713 $updatePerformedSubpart, 06714 '###DATABASEQUERIES###', 06715 implode(LF, $databaseQueries) 06716 ); 06717 $updatePerformed = t3lib_parsehtml::substituteSubpart( 06718 $updatePerformed, 06719 '###CUSTOMOUTPUT###', 06720 $customOutputItem 06721 ); 06722 $updatePerformed = t3lib_parsehtml::substituteMarkerArray( 06723 $updatePerformed, 06724 $performUpdateMarkers, 06725 '###|###', 06726 TRUE, 06727 FALSE 06728 ); 06729 } else { 06730 $noPerformUpdateMarkers['noUpdateMethod'] = 'No update method available!'; 06731 $noPerformUpdate = t3lib_parsehtml::substituteMarkerArray( 06732 $noPerformUpdateSubpart, 06733 $noPerformUpdateMarkers, 06734 '###|###', 06735 TRUE, 06736 FALSE 06737 ); 06738 } 06739 } 06740 $updateItem = t3lib_parsehtml::substituteSubpart( 06741 $updateItemsSubpart, 06742 '###CHECKUSERINPUT###', 06743 $checkUserInput 06744 ); 06745 $updateItem = t3lib_parsehtml::substituteSubpart( 06746 $updateItem, 06747 '###UPDATEPERFORMED###', 06748 $updatePerformed 06749 ); 06750 $updateItem = t3lib_parsehtml::substituteSubpart( 06751 $updateItem, 06752 '###NOPERFORMUPDATE###', 06753 $noPerformUpdate 06754 ); 06755 $updateItem = t3lib_parsehtml::substituteSubpart( 06756 $updateItem, 06757 '###UPDATEITEMS###', 06758 implode(LF, $updateItems) 06759 ); 06760 $updateItems[] = t3lib_parsehtml::substituteMarkerArray( 06761 $updateItem, 06762 $updateItemsMarkers, 06763 '###|###', 06764 TRUE, 06765 FALSE 06766 ); 06767 } 06768 $content = t3lib_parsehtml::substituteSubpart( 06769 $performUpdateSubpart, 06770 '###UPDATEITEMS###', 06771 implode(LF, $updateItems) 06772 ); 06773 $GLOBALS['TYPO3_DB']->store_lastBuiltQuery = FALSE; 06774 06775 // also render the link to the next update wizard, if available 06776 $nextUpdateWizard = $this->getNextUpdadeWizardInstance($tmpObj); 06777 if ($nextUpdateWizard) { 06778 $content = t3lib_parsehtml::substituteMarkerArray( 06779 $content, 06780 array('NEXTIDENTIFIER' => $nextUpdateWizard->getIdentifier()), 06781 '###|###', 06782 TRUE, 06783 FALSE 06784 ); 06785 } else { 06786 // no next wizard, also hide the button to the next update wizard 06787 $content = t3lib_parsehtml::substituteSubpart( 06788 $content, 06789 '###NEXTUPDATEWIZARD###', 06790 '' 06791 ); 06792 } 06793 06794 break; 06795 } 06796 $this->message('Upgrade Wizard', $title, $content); 06797 } 06798 06799 /** 06800 * Creates instance of an upgrade object, setting the pObj, versionNumber and pObj 06801 * 06802 * @param string $className The class name 06803 * @param string $identifier The identifier of upgrade object - needed to fetch user input 06804 * @return object Newly instanciated upgrade object 06805 */ 06806 function getUpgradeObjInstance($className, $identifier) { 06807 $tmpObj = t3lib_div::getUserObj($className); 06808 $tmpObj->setIdentifier($identifier); 06809 $tmpObj->versionNumber = t3lib_div::int_from_ver(TYPO3_version); 06810 $tmpObj->pObj = $this; 06811 $tmpObj->userInput = $this->INSTALL['update'][$identifier]; 06812 return $tmpObj; 06813 } 06814 06815 /** 06816 * Returns the next upgrade wizard object. 06817 * 06818 * Used to show the link/button to the next upgrade wizard 06819 * @param object $currentObj current Upgrade Wizard Object 06820 * @return mixed Upgrade Wizard instance or FALSE 06821 */ 06822 protected function getNextUpdadeWizardInstance($currentObj) { 06823 $isPreviousRecord = TRUE; 06824 foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install']['update'] as $identifier => $className) { 06825 // first, find the current update wizard, and then start validating the next ones 06826 if ($currentObj->getIdentifier() == $identifier) { 06827 $isPreviousRecord = FALSE; 06828 continue; 06829 } 06830 06831 if (!$isPreviousRecord) { 06832 $nextUpdateWizard = $this->getUpgradeObjInstance($className, $identifier); 06833 if ($nextUpdateWizard->shouldRenderWizard()) { 06834 return $nextUpdateWizard; 06835 } 06836 } 06837 } 06838 return FALSE; 06839 } 06840 06841 /** 06842 * Check if at lease one backend admin user has been created 06843 * 06844 * @return integer Amount of backend users in the database 06845 */ 06846 function isBackendAdminUser() { 06847 return $GLOBALS['TYPO3_DB']->exec_SELECTcountRows('uid', 'be_users', 'admin=1'); 06848 } 06849 06850 /** 06851 * Check if the basic settings are complete 06852 * Only used by 1-2-3 mode 06853 * 06854 * @param string $tLabel The header for the message 06855 * @return boolean TRUE if complete 06856 */ 06857 function isBasicComplete($tLabel) { 06858 if ($this->mode=='123') { 06859 $tables = $this->getListOfTables(); 06860 06861 if (count($tables)) { 06862 $beuser = $this->isBackendAdminUser(); 06863 } 06864 if (count($tables) && $beuser) { 06865 $mode123Imported=1; 06866 $this->message($tLabel, 'Basic Installation Completed', $this->messageBasicFinished(), -1, 1); 06867 $this->message($tLabel,'Security Risk!',$this->securityRisk().$this->alterPasswordForm(),2,1); 06868 } else { 06869 $this->message($tLabel,'Still missing something?',nl2br(' 06870 You may be missing one of these points before your TYPO3 installation is complete: 06871 06872 '.(count($tables)?'':'- You haven\'t imported any tables yet. 06873 ') 06874 .($beuser?'':'- You haven\'t created an admin user yet. 06875 ') 06876 .' 06877 06878 You\'re about to import a database with a complete site in it, these three points should be met. 06879 '),-1,1); 06880 } 06881 } 06882 return $mode123Imported; 06883 } 06884 06885 /** 06886 * Generate the contents for the form for 'Database Analyzer' 06887 * when the 'COMPARE' still contains errors 06888 * 06889 * @param string $type get_form if the form needs to be generated 06890 * @param array $arr_update The tables/fields which needs an update 06891 * @param array $arr_remove The tables/fields which needs to be removed 06892 * @param string $action_type The action type 06893 * @return string HTML for the form 06894 */ 06895 function generateUpdateDatabaseForm($type, $arr_update, $arr_remove, $action_type) { 06896 $content = ''; 06897 switch($type) { 06898 case 'get_form': 06899 $content.= $this->generateUpdateDatabaseForm_checkboxes($arr_update['clear_table'],'Clear tables (use with care!)',false,true); 06900 06901 $content.= $this->generateUpdateDatabaseForm_checkboxes($arr_update['add'],'Add fields'); 06902 $content.= $this->generateUpdateDatabaseForm_checkboxes($arr_update['change'],'Changing fields',(t3lib_extMgm::isLoaded('dbal')?0:1),0,$arr_update['change_currentValue']); 06903 $content.= $this->generateUpdateDatabaseForm_checkboxes($arr_remove['change'],'Remove unused fields (rename with prefix)',$this->setAllCheckBoxesByDefault,1); 06904 $content.= $this->generateUpdateDatabaseForm_checkboxes($arr_remove['drop'],'Drop fields (really!)',$this->setAllCheckBoxesByDefault); 06905 06906 $content.= $this->generateUpdateDatabaseForm_checkboxes($arr_update['create_table'],'Add tables'); 06907 $content.= $this->generateUpdateDatabaseForm_checkboxes($arr_remove['change_table'],'Removing tables (rename with prefix)',$this->setAllCheckBoxesByDefault,1,$arr_remove['tables_count'],1); 06908 $content.= $this->generateUpdateDatabaseForm_checkboxes($arr_remove['drop_table'],'Drop tables (really!)',$this->setAllCheckBoxesByDefault,0,$arr_remove['tables_count'],1); 06909 06910 $content = $this->getUpdateDbFormWrap($action_type, $content); 06911 break; 06912 default: 06913 06914 break; 06915 } 06916 return $content; 06917 } 06918 06919 /** 06920 * Form wrap for 'Database Analyzer' 06921 * when the 'COMPARE' still contains errors 06922 * 06923 * @param string $action_type The action type 06924 * @param string $content The form content 06925 * @param string $label The submit button label 06926 * @return string HTML of the form 06927 */ 06928 function getUpdateDbFormWrap($action_type, $content, $label='Write to database') { 06929 // Get the template file 06930 $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'GetUpdateDbFormWrap.html'); 06931 // Get the template part from the file 06932 $form = t3lib_parsehtml::getSubpart($templateFile, '###TEMPLATE###'); 06933 // Define the markers content 06934 $formMarkers = array( 06935 'action' => $this->action, 06936 'actionType' => htmlspecialchars($action_type), 06937 'content' => $content, 06938 'label' => $label 06939 ); 06940 // Fill the markers 06941 $form = t3lib_parsehtml::substituteMarkerArray( 06942 $form, 06943 $formMarkers, 06944 '###|###', 06945 TRUE, 06946 FALSE 06947 ); 06948 06949 return $form; 06950 } 06951 06952 /** 06953 * Generates an HTML table for the setup of database tables 06954 * Used in 'Database analyzer > Compare with $TCA' 06955 * 06956 * @param array $arr Description of the table with fieldname and fieldcontent 06957 * @param boolean $pre TRUE if the field content needs to be wrapped with a <pre> tag 06958 * @param string $label The header label 06959 * @return string HTML of the table 06960 */ 06961 function displayFields($arr, $pre=0, $label='') { 06962 // Get the template file 06963 $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'DisplayFields.html'); 06964 // Get the template part from the file 06965 $template = t3lib_parsehtml::getSubpart($templateFile, '###TEMPLATE###'); 06966 // Define the markers content 06967 $templateMarkers = array( 06968 'headerFieldName' => 'Field name:', 06969 'headerLabel' => $label ? $label : 'Info:' 06970 ); 06971 if (is_array($arr)) { 06972 $rows = array(); 06973 // Get the subpart for rows 06974 $rowsSubpart = t3lib_parsehtml::getSubpart($template, '###ROWS###'); 06975 foreach ($arr as $fieldname => $fieldContent) { 06976 if ($pre) { 06977 $fieldContent = '<pre>'.trim($fieldContent).'</pre>'; 06978 } 06979 // Define the markers content 06980 $rowsMarkers = array( 06981 'fieldName' => $fieldname, 06982 'fieldContent' => $fieldContent 06983 ); 06984 // Fill the markers in the subpart 06985 $rows[] = t3lib_parsehtml::substituteMarkerArray( 06986 $rowsSubpart, 06987 $rowsMarkers, 06988 '###|###', 06989 TRUE, 06990 FALSE 06991 ); 06992 } 06993 } 06994 // Substitute the subpart for rows 06995 $template = t3lib_parsehtml::substituteSubpart( 06996 $template, 06997 '###ROWS###', 06998 implode(LF, $rows) 06999 ); 07000 // Fill the markers 07001 $template = t3lib_parsehtml::substituteMarkerArray( 07002 $template, 07003 $templateMarkers, 07004 '###|###', 07005 TRUE, 07006 FALSE 07007 ); 07008 return $template; 07009 } 07010 07011 /** 07012 * Generates an HTML table with comparison between database and $TCA 07013 * Used in 'Database analyzer > Compare with $TCA' 07014 * 07015 * @param array $arr Description of the table with fieldname and fieldcontent 07016 * @param array $arr_db The actual content of a field in the database 07017 * @return string HTML of the table 07018 */ 07019 function displayFieldComp($arr, $arr_db) { 07020 // Get the template file 07021 $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'DisplayFieldComp.html'); 07022 // Get the template part from the file 07023 $template = t3lib_parsehtml::getSubpart($templateFile, '###TEMPLATE###'); 07024 // Define the markers content 07025 $templateMarkers = array( 07026 'headerFieldName' => 'Field name:', 07027 'headerSuggested' => 'Suggested value from $TCA:', 07028 'headerActual' => 'Actual value from database:' 07029 ); 07030 $rows = array(); 07031 if (is_array($arr)) { 07032 // Get the subpart for rows 07033 $rowsSubpart = t3lib_parsehtml::getSubpart($template, '###ROWS###'); 07034 foreach ($arr as $fieldname => $fieldContent) { 07035 // This tries to equalize the types tinyint and int 07036 $str1 = $fieldContent; 07037 $str2 = trim($arr_db[$fieldname]); 07038 $str1 = str_replace('tinyint(3)','tinyint(4)',$str1); 07039 $str2 = str_replace('tinyint(3)','tinyint(4)',$str2); 07040 $str1 = str_replace('int(10)','int(11)',$str1); 07041 $str2 = str_replace('int(10)','int(11)',$str2); 07042 // Compare: 07043 if (strcmp($str1,$str2)) { 07044 $bgcolor=' class="warning"'; 07045 } else { 07046 $bgcolor=''; 07047 } 07048 // Define the markers content 07049 $rowsMarkers = array( 07050 'fieldName' => $fieldname, 07051 'fieldContent' => $fieldContent, 07052 'fieldContentDb' => $arr_db[$fieldname], 07053 'class' => $bgcolor 07054 ); 07055 // Fill the markers in the subpart 07056 $rows[] = t3lib_parsehtml::substituteMarkerArray( 07057 $rowsSubpart, 07058 $rowsMarkers, 07059 '###|###', 07060 TRUE, 07061 FALSE 07062 ); 07063 } 07064 } 07065 // Substitute the subpart for rows 07066 $template = t3lib_parsehtml::substituteSubpart( 07067 $template, 07068 '###ROWS###', 07069 implode(LF, $rows) 07070 ); 07071 // Fill the markers 07072 $out = t3lib_parsehtml::substituteMarkerArray( 07073 $template, 07074 $templateMarkers, 07075 '###|###', 07076 TRUE, 07077 FALSE 07078 ); 07079 return $out; 07080 } 07081 07082 /** 07083 * Generates an HTML table with $TCA suggestions looking at the type of field 07084 * Used in 'Database analyzer > Compare with $TCA' 07085 * 07086 * @param array $arr Description of the table with fieldname and fieldcontent 07087 * @param string $excludeList Comma separated list of fields which should be excluded from this table 07088 * @return string HTML of the table 07089 */ 07090 function displaySuggestions($arr, $excludeList='') { 07091 // Get the template file 07092 $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'DisplaySuggestions.html'); 07093 // Get the template part from the file 07094 $template = t3lib_parsehtml::getSubpart($templateFile, '###TEMPLATE###'); 07095 07096 $templateMarkers = array(); 07097 $fC=0; 07098 $rows = array(); 07099 if (is_array($arr)) { 07100 // Get the subpart for rows 07101 $rowsSubpart = t3lib_parsehtml::getSubpart($template, '###ROWS###'); 07102 foreach ($arr as $fieldname => $fieldContent) { 07103 if (!t3lib_div::inList($excludeList,$fieldname) && substr($fieldname,0,strlen($this->deletedPrefixKey))!=$this->deletedPrefixKey && substr($fieldname,-1)!='.') { 07104 if ($arr[$fieldname.'.']) { 07105 // Get the subpart for pre 07106 $preSubpart = t3lib_parsehtml::getSubpart($rowsSubpart, '###PRE###'); 07107 // Define the markers content 07108 $preMarkers = array( 07109 'code' => '<pre>' . trim($arr[$fieldname.'.']) . '</pre>' 07110 ); 07111 // Fill the markers in the subpart 07112 $preSubpart = t3lib_parsehtml::substituteMarkerArray( 07113 $preSubpart, 07114 $preMarkers, 07115 '###|###', 07116 TRUE, 07117 FALSE 07118 ); 07119 } 07120 // Substitute the subpart for pre 07121 $row = t3lib_parsehtml::substituteSubpart( 07122 $rowsSubpart, 07123 '###PRE###', 07124 $preSubpart 07125 ); 07126 // Define the markers content 07127 $rowsMarkers = array( 07128 'headerFieldName' => 'Field name:', 07129 'headerLabel' => 'Info:', 07130 'headerSuggestion' => 'Suggestion for the field:', 07131 'fieldName' => $fieldname, 07132 'fieldContent' => $fieldContent, 07133 ); 07134 // Fill the markers in the subpart 07135 $rows[] = t3lib_parsehtml::substituteMarkerArray( 07136 $row, 07137 $rowsMarkers, 07138 '###|###', 07139 TRUE, 07140 FALSE 07141 ); 07142 $fC++; 07143 } 07144 } 07145 } 07146 // Substitute the subpart for rows 07147 $template = t3lib_parsehtml::substituteSubpart( 07148 $template, 07149 '###ROWS###', 07150 implode(LF, $rows) 07151 ); 07152 // Fill the markers 07153 $out = t3lib_parsehtml::substituteMarkerArray( 07154 $template, 07155 $templateMarkers, 07156 '###|###', 07157 TRUE, 07158 FALSE 07159 ); 07160 return array($out,$fC); 07161 } 07162 07163 /** 07164 * Compares an array with field definitions with $TCA array 07165 * 07166 * @param array $FDsrc Field definition source 07167 * @param array $TCA The TCA array 07168 * @param boolean $onlyFields 07169 * @return array 07170 */ 07171 function compareDatabaseAndTCA($FDsrc, $TCA, $onlyFields=0) { 07172 $extraArr=array(); 07173 if (is_array($FDsrc)) { 07174 foreach ($FDsrc as $table => $info) { 07175 if (!isset($TCA[$table])) { 07176 if (!$onlyFields) { 07177 // If the table was not in the FDcomp-array, the result array is loaded with that table. 07178 $extraArr[$table]=$info; 07179 $extraArr[$table]['whole_table']=1; 07180 unset($extraArr[$table]['keys']); 07181 } 07182 } else { 07183 $theKey='fields'; 07184 $excludeListArr=array(); 07185 if (is_array($TCA[$table]['ctrl']['enablecolumns'])) { 07186 $excludeListArr[]=$TCA[$table]['ctrl']['enablecolumns']; 07187 } 07188 $excludeListArr[]=$TCA[$table]['ctrl']['tstamp']; 07189 $excludeListArr[]=$TCA[$table]['ctrl']['sortby']; 07190 $excludeListArr[]=$TCA[$table]['ctrl']['delete']; 07191 $excludeListArr[]=$TCA[$table]['ctrl']['cruser_id']; 07192 $excludeListArr[]=$TCA[$table]['ctrl']['crdate']; 07193 $excludeListArr[]='uid'; 07194 $excludeListArr[]='pid'; 07195 if ($table=='pages') { 07196 $excludeListArr[]='perms_userid'; 07197 $excludeListArr[]='perms_groupid'; 07198 $excludeListArr[]='perms_user'; 07199 $excludeListArr[]='perms_group'; 07200 $excludeListArr[]='perms_everybody'; 07201 } 07202 if ($table=='sys_dmail') { 07203 $excludeListArr[]='scheduled'; 07204 $excludeListArr[]='scheduled_begin'; 07205 $excludeListArr[]='scheduled_end'; 07206 $excludeListArr[]='query_info'; 07207 } 07208 07209 if (is_array($info[$theKey])) { 07210 foreach ($info[$theKey] as $fieldN => $fieldC) { 07211 if (!isset($TCA[$table]['columns'][$fieldN]) && !in_array($fieldN,$excludeListArr)) { 07212 $extraArr[$table][$theKey][$fieldN] = $info['fields'][$fieldN]; 07213 $extraArr[$table][$theKey][$fieldN.'.']=$this->suggestTCAFieldDefinition($fieldN,$fieldC); 07214 } 07215 } 07216 } 07217 } 07218 } 07219 } 07220 return array('extra'=>$extraArr); 07221 } 07222 07223 /** 07224 * Compares the $TCA array with a field definition array 07225 * 07226 * @param array $TCA The TCA 07227 * @param array $FDcomp Field definition comparison 07228 * @return array 07229 */ 07230 function compareTCAandDatabase($TCA, $FDcomp) { 07231 $matchingArr = $extraArr = array(); 07232 if (is_array($TCA)) { 07233 foreach ($TCA as $table => $info) { 07234 if (!isset($FDcomp[$table])) { 07235 // If the table was not in the FDcomp-array, the result array is loaded with that table. 07236 //$extraArr[$table]=$info; 07237 $extraArr[$table]['whole_table']=1; 07238 } else { 07239 foreach ($info['columns'] as $fieldN => $fieldC) { 07240 $fieldDef = $this->suggestFieldDefinition($fieldC); 07241 if (!is_array($fieldDef)) { 07242 if (!isset($FDcomp[$table]['fields'][$fieldN])) { 07243 $extraArr[$table]['fields'][$fieldN]=$fieldDef; 07244 } else { 07245 $matchingArr[$table]['fields'][$fieldN]=$fieldDef; 07246 } 07247 } 07248 } 07249 } 07250 } 07251 } 07252 return array('extra'=>$extraArr, 'matching'=>$matchingArr); 07253 } 07254 07255 /** 07256 * Suggests a field definition for a TCA config array. 07257 * 07258 * @param array $fieldInfo Info of a field 07259 * @return string The suggestion 07260 */ 07261 function suggestFieldDefinition($fieldInfo) { 07262 $out=''; 07263 switch($fieldInfo['config']['type']) { 07264 case 'input': 07265 if (preg_match('/date|time|int|year/',$fieldInfo['config']['eval'])) { 07266 $out = "int(11) NOT NULL default '0'"; 07267 } else { 07268 $max = intval($fieldInfo['config']['max']); 07269 if ($max>0 && $max<200) { 07270 $out = 'varchar('.$max.") NOT NULL default ''"; 07271 } else { 07272 $out = 'tinytext'; 07273 } 07274 } 07275 break; 07276 case 'text': 07277 $out = 'text'; 07278 break; 07279 case 'check': 07280 if (is_array($fieldInfo['config']['items']) && count($fieldInfo['config']['items'])>8) { 07281 $out = "int(11) NOT NULL default '0'"; 07282 } else { 07283 $out = "tinyint(3) NOT NULL default '0'"; 07284 } 07285 break; 07286 case 'radio': 07287 if (is_array($fieldInfo['config']['items'])) { 07288 $out = $this->getItemArrayType($fieldInfo['config']['items']); 07289 } else { 07290 $out = 'ERROR: Radiobox did not have items!'; 07291 } 07292 break; 07293 case 'group': 07294 if ($fieldInfo['config']['internal_type']=='db') { 07295 $max = t3lib_div::intInRange($fieldInfo['config']['maxitems'],1,10000); 07296 if (count(explode(',',$fieldInfo['config']['allowed']))>1) { 07297 // Tablenames are 10, "_" 1, uid's 5, comma 1 07298 $len = $max*(10+1+5+1); 07299 $out=$this->getItemBlobSize($len); 07300 } elseif ($max<=1) { 07301 $out = "int(11) NOT NULL default '0'"; 07302 } else { 07303 // uid's 5, comma 1 07304 $len = $max*(5+1); 07305 $out=$this->getItemBlobSize($len); 07306 } 07307 } 07308 if ($fieldInfo['config']['internal_type']=='file') { 07309 $max = t3lib_div::intInRange($fieldInfo['config']['maxitems'],1,10000); 07310 // Filenames is 30+ chars.... 07311 $len = $max*(30+1); 07312 $out=$this->getItemBlobSize($len); 07313 } 07314 break; 07315 case 'select': 07316 $max = t3lib_div::intInRange($fieldInfo['config']['maxitems'],1,10000); 07317 if ($max<=1) { 07318 if ($fieldInfo['config']['foreign_table']) { 07319 $out = "int(11) NOT NULL default '0'"; 07320 } else { 07321 $out = $this->getItemArrayType($fieldInfo['config']['items']); 07322 } 07323 } else { 07324 // five chars (special=10) + comma: 07325 $len = $max*(($fieldInfo['config']['special']?10:5)+1); 07326 $out=$this->getItemBlobSize($len); 07327 } 07328 break; 07329 default: 07330 break; 07331 } 07332 return $out?$out:$fieldInfo; 07333 } 07334 07335 /** 07336 * Check if field needs to be varchar or int 07337 * Private 07338 * 07339 * @param array $arr 07340 * @return string The definition 07341 */ 07342 function getItemArrayType($arr) { 07343 if (is_array($arr)) { 07344 $type[] = $intSize[] = 0; 07345 foreach ($arr as $item) { 07346 if (!t3lib_div::testInt($item[1]) && $item[1]!='--div--') { 07347 $type[]=strlen($item[1]); 07348 } else { 07349 $intSize[]=$item[1]; 07350 } 07351 } 07352 $us = min($intSize)>=0 ? ' unsigned' : ''; 07353 if (max($type)>0) { 07354 $out = 'varchar('.max($type).") NOT NULL default ''"; 07355 } else { 07356 $out = "int(11) NOT NULL default '0'"; 07357 } 07358 } 07359 return $out; 07360 } 07361 07362 /** 07363 * Defines the blob size of an item by a given length 07364 * Private 07365 * 07366 * @param integer $len The length 07367 * @return string The blob definition 07368 */ 07369 function getItemBlobSize($len) { 07370 return ($len>255 ? 'tiny' : '').'blob'; 07371 } 07372 07373 /** 07374 * Should suggest a TCA configuration for a specific field. 07375 * 07376 * @param string $fieldName The field name 07377 * @param string $fieldInfo The field information 07378 * @return string Suggested TCA configuration 07379 */ 07380 function suggestTCAFieldDefinition($fieldName,$fieldInfo) { 07381 list($type,$len) = preg_split('/ |\(|\)/', $fieldInfo, 3); 07382 switch($type) { 07383 case 'int': 07384 $out=" 07385 '".$fieldName."' => array ( 07386 'label' => '".strtoupper($fieldName).":', 07387 'exclude' => 0, 07388 'config' => array ( 07389 'type' => 'input', 07390 'size' => '8', 07391 'max' => '20', 07392 'eval' => 'date', 07393 'default' => '0', 07394 'checkbox' => '0' 07395 ) 07396 ), 07397 07398 ----- OR ----- 07399 07400 '".$fieldName."' => array ( 07401 'label' => '".strtoupper($fieldName).":', 07402 'exclude' => 0, 07403 'config' => array ( 07404 'type' => 'select', 07405 'items' => array ( 07406 array('[nothing]', 0), 07407 array('Extra choice! Only negative values here.', -1), 07408 array('__Divider:__', '--div--') 07409 ), 07410 'foreign_table' => '[some_table_name]' 07411 ) 07412 ),"; 07413 break; 07414 case 'varchar': 07415 if ($len>10) { 07416 $out=" 07417 '".$fieldName."' => array ( 07418 'label' => '".strtoupper($fieldName).":', 07419 'exclude' => 0, 07420 'config' => array ( 07421 'type' => 'input', 07422 'size' => '8', 07423 'max' => '".$len."', 07424 'eval' => 'trim', 07425 'default' => '' 07426 ) 07427 ),"; 07428 } else { 07429 $out=" 07430 '".$fieldName."' => array ( 07431 'label' => '".strtoupper($fieldName).":', 07432 'exclude' => 0, 07433 'config' => array ( 07434 'type' => 'select', 07435 'items' => array ( 07436 array('Item number 1', 'key1'), 07437 array('Item number 2', 'key2'), 07438 array('-----', '--div--'), 07439 array('Item number 3', 'key3') 07440 ), 07441 'default' => '1' 07442 ) 07443 ),"; 07444 } 07445 break; 07446 case 'tinyint': 07447 $out=" 07448 '".$fieldName."' => array ( 07449 'label' => '".strtoupper($fieldName).":', 07450 'exclude' => 0, 07451 'config' => array ( 07452 'type' => 'select', 07453 'items' => array ( 07454 array('Item number 1', '1'), 07455 array('Item number 2', '2'), 07456 array('-----', '--div--'), 07457 array('Item number 3', '3') 07458 ), 07459 'default' => '1' 07460 ) 07461 ), 07462 07463 ----- OR ----- 07464 07465 '".$fieldName."' => array ( 07466 'label' => '".strtoupper($fieldName).":', 07467 'exclude' => 0, 07468 'config' => array ( 07469 'type' => 'check', 07470 'default' => '1' 07471 ) 07472 ),"; 07473 break; 07474 case 'tinytext': 07475 $out=" 07476 '".$fieldName."' => array ( 07477 'label' => '".strtoupper($fieldName).":', 07478 'exclude' => 0, 07479 'config' => array ( 07480 'type' => 'input', 07481 'size' => '40', 07482 'max' => '255', 07483 'eval' => '', 07484 'default' => '' 07485 ) 07486 ),"; 07487 break; 07488 case 'text': 07489 case 'mediumtext': 07490 $out=" 07491 '".$fieldName."' => array ( 07492 'label' => '".strtoupper($fieldName).":', 07493 'config' => array ( 07494 'type' => 'text', 07495 'cols' => '48', 07496 'rows' => '5' 07497 ) 07498 ),"; 07499 break; 07500 default: 07501 $out=" 07502 '".$fieldName."' => array ( 07503 'label' => '".strtoupper($fieldName).":', 07504 'exclude' => 0, 07505 'config' => array ( 07506 'type' => 'input', 07507 'size' => '30', 07508 'max' => '', 07509 'eval' => '', 07510 'default' => '' 07511 ) 07512 ),"; 07513 break; 07514 } 07515 return $out?$out:$fieldInfo; 07516 } 07517 07518 /** 07519 * Includes TCA 07520 * 07521 * @return void 07522 */ 07523 function includeTCA() { 07524 global $TCA; 07525 07526 include (TYPO3_tables_script ? PATH_typo3conf.TYPO3_tables_script : PATH_t3lib.'stddb/tables.php'); 07527 07528 // Extension additions 07529 if ($GLOBALS['TYPO3_LOADED_EXT']['_CACHEFILE']) { 07530 include(PATH_typo3conf.$GLOBALS['TYPO3_LOADED_EXT']['_CACHEFILE'].'_ext_tables.php'); 07531 } else { 07532 include(PATH_t3lib.'stddb/load_ext_tables.php'); 07533 } 07534 07535 if (TYPO3_extTableDef_script) { 07536 include (PATH_typo3conf.TYPO3_extTableDef_script); 07537 } 07538 07539 foreach ($TCA as $table => $conf) { 07540 t3lib_div::loadTCA($table); 07541 } 07542 } 07543 07544 07545 07546 07547 07548 07549 07550 07551 /********************** 07552 * 07553 * GENERAL FUNCTIONS 07554 * 07555 **********************/ 07556 07557 /** 07558 * Setting a message in the message-log and sets the fatalError flag if error type is 3. 07559 * 07560 * @param string $head Section header 07561 * @param string $short_string A short description 07562 * @param string $long_string A long (more detailed) description 07563 * @param integer $type -1=OK sign, 0=message, 1=notification, 2=warning, 3=error 07564 * @param boolean $force Print message also in "Advanced" mode (not only in 1-2-3 mode) 07565 * @return void 07566 */ 07567 function message($head, $short_string='', $long_string='', $type=0, $force=0) { 07568 // Return directly if mode-123 is enabled. 07569 if (!$force && $this->mode=='123' && $type<2) { 07570 return; 07571 } 07572 07573 if ($type==3) { $this->fatalError=1; } 07574 07575 $long_string = trim($long_string); 07576 07577 if (!$this->silent) $this->printSection($head, $short_string, $long_string, $type); 07578 } 07579 07580 /** 07581 * This "prints" a section with a message to the ->sections array 07582 * 07583 * @param string $head Section header 07584 * @param string $short_string A short description 07585 * @param string $long_string A long (more detailed) description 07586 * @param integer $type -1=OK sign, 0=message, 1=notification, 2=warning , 3=error 07587 * @return void 07588 */ 07589 function printSection($head, $short_string, $long_string, $type) { 07590 // Get the template file 07591 $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'PrintSection.html'); 07592 // Get the template part from the file 07593 $template = t3lib_parsehtml::getSubpart($templateFile, '###TEMPLATE###'); 07594 07595 switch($type) { 07596 case 3: 07597 $messageType = 'message-error'; 07598 break; 07599 case 2: 07600 $messageType = 'message-warning'; 07601 break; 07602 case 1: 07603 $messageType = 'message-notice'; 07604 break; 07605 case 0: 07606 $messageType = 'message-information'; 07607 break; 07608 case -1: 07609 $messageType = 'message-ok'; 07610 break; 07611 } 07612 07613 if (!trim($short_string)) { 07614 $content = ''; 07615 } else { 07616 if (trim($long_string)) { 07617 // Get the subpart for the long string 07618 $longStringSubpart = t3lib_parsehtml::getSubpart($template, '###LONGSTRINGAVAILABLE###'); 07619 } 07620 // Substitute the subpart for the long string 07621 $content = t3lib_parsehtml::substituteSubpart( 07622 $template, 07623 '###LONGSTRINGAVAILABLE###', 07624 $longStringSubpart 07625 ); 07626 // Define the markers content 07627 $markers = array( 07628 'messageType' => $messageType, 07629 'shortString' => $short_string, 07630 'longString' => $long_string 07631 ); 07632 // Fill the markers 07633 $content = t3lib_parsehtml::substituteMarkerArray( 07634 $content, 07635 $markers, 07636 '###|###', 07637 TRUE, 07638 FALSE 07639 ); 07640 } 07641 $this->sections[$head][] = $content; 07642 } 07643 07644 /** 07645 * This prints all the messages in the ->section array 07646 * 07647 * @return string HTML of all the messages 07648 */ 07649 function printAll() { 07650 // Get the template file 07651 $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'PrintAll.html'); 07652 // Get the template part from the file 07653 $template = t3lib_parsehtml::getSubpart($templateFile, '###TEMPLATE###'); 07654 $sections = array(); 07655 07656 foreach ($this->sections as $header => $valArray) { 07657 // Get the subpart for sections 07658 $sectionSubpart = t3lib_parsehtml::getSubpart($template, '###SECTIONS###'); 07659 // Define the markers content 07660 $sectionMarkers = array( 07661 'header' => $header . ':', 07662 'sectionContent' => implode(LF, $valArray) 07663 ); 07664 // Fill the markers in the subpart 07665 $sections[] = t3lib_parsehtml::substituteMarkerArray( 07666 $sectionSubpart, 07667 $sectionMarkers, 07668 '###|###', 07669 TRUE, 07670 FALSE 07671 ); 07672 } 07673 // Substitute the subpart for the sections 07674 $content = t3lib_parsehtml::substituteSubpart( 07675 $template, 07676 '###SECTIONS###', 07677 implode(LF, $sections) 07678 ); 07679 07680 return $content; 07681 } 07682 07683 /** 07684 * This wraps and returns the main content of the page into proper html-code. 07685 * 07686 * @param string $content The page content 07687 * @return string The full HTML page 07688 */ 07689 function outputWrapper($content) { 07690 // Get the template file 07691 if (!$this->passwordOK) { 07692 $this->template = @file_get_contents(PATH_site . $this->templateFilePath . 'Install_login.html'); 07693 } elseif ($this->mode == '123') { 07694 $this->template = @file_get_contents(PATH_site . $this->templateFilePath . 'Install_123.html'); 07695 } else { 07696 $this->template = @file_get_contents(PATH_site . $this->templateFilePath . 'Install.html'); 07697 } 07698 07699 // Add prototype to javascript array for output 07700 $this->javascript[] = '<script type="text/javascript" src="' . 07701 t3lib_div::createVersionNumberedFilename( 07702 '../contrib/prototype/prototype.js' 07703 ) . '"></script>'; 07704 07705 // Add JS functions for output 07706 $this->javascript[] = '<script type="text/javascript" src="' . 07707 t3lib_div::createVersionNumberedFilename( 07708 '../sysext/install/Resources/Public/Javascript/install.js' 07709 ) . '"></script>'; 07710 07711 // Include the default stylesheets 07712 $this->stylesheets[] = '<link rel="stylesheet" type="text/css" href="' . 07713 t3lib_div::createVersionNumberedFilename($this->backPath . 07714 'sysext/install/Resources/Public/Stylesheets/reset.css' 07715 ) . '" />'; 07716 $this->stylesheets[] = '<link rel="stylesheet" type="text/css" href="' . 07717 t3lib_div::createVersionNumberedFilename($this->backPath . 07718 'sysext/install/Resources/Public/Stylesheets/general.css' 07719 ) . '" />'; 07720 07721 // Get the browser info 07722 $browserInfo = t3lib_utility_Client::getBrowserInfo(t3lib_div::getIndpEnv('HTTP_USER_AGENT')); 07723 07724 // Add the stylesheet for Internet Explorer 07725 if ($browserInfo['browser'] === 'msie') { 07726 // IE7 07727 if (intval($browserInfo['version']) === 7) { 07728 $this->stylesheets[] = '<link rel="stylesheet" type="text/css" href="' . 07729 t3lib_div::createVersionNumberedFilename($this->backPath . 07730 'sysext/install/Resources/Public/Stylesheets/ie7.css' 07731 ) . '" />'; 07732 // IE6 07733 } elseif (intval($browserInfo['version']) < 7) { 07734 $this->stylesheets[] = '<link rel="stylesheet" type="text/css" href="' . 07735 t3lib_div::createVersionNumberedFilename($this->backPath . 07736 'sysext/install/Resources/Public/Stylesheets/ie6.css' 07737 ) . '" />'; 07738 } 07739 } 07740 07741 // Include the stylesheets based on screen 07742 if ($this->mode == '123') { 07743 $this->stylesheets[] = '<link rel="stylesheet" type="text/css" href="' . 07744 t3lib_div::createVersionNumberedFilename($this->backPath . 07745 'sysext/install/Resources/Public/Stylesheets/install_123.css' 07746 ) . '" />'; 07747 } elseif ($this->passwordOK) { 07748 $this->stylesheets[] = '<link rel="stylesheet" type="text/css" href="' . 07749 t3lib_div::createVersionNumberedFilename($this->backPath . 07750 'sysext/install/Resources/Public/Stylesheets/install.css' 07751 ) . '" />'; 07752 } else { 07753 $this->stylesheets[] = '<link rel="stylesheet" type="text/css" href="' . 07754 t3lib_div::createVersionNumberedFilename($this->backPath . 07755 'sysext/install/Resources/Public/Stylesheets/install.css' 07756 ) . '" />'; 07757 $this->stylesheets[] = '<link rel="stylesheet" type="text/css" href="' . 07758 t3lib_div::createVersionNumberedFilename($this->backPath . 07759 'sysext/install/Resources/Public/Stylesheets/install_login.css' 07760 ) . '" />'; 07761 } 07762 07763 // Define the markers content 07764 if ($this->mode == '123') { 07765 $this->markers['headTitle'] = 'Installing TYPO3 ' . TYPO3_branch; 07766 } else { 07767 $this->markers['headTitle'] = ' 07768 TYPO3 ' . TYPO3_version . ' 07769 Install Tool on site: ' . htmlspecialchars($GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename']) . ' 07770 '; 07771 } 07772 $this->markers['title'] = 'TYPO3 ' . TYPO3_version; 07773 $this->markers['javascript'] = implode(LF, $this->javascript); 07774 $this->markers['stylesheets'] = implode(LF, $this->stylesheets); 07775 $this->markers['llErrors'] = 'The following errors occured'; 07776 $this->markers['copyright'] = $this->copyright(); 07777 $this->markers['charset'] = $GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset'] ? $GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset'] : 'iso-8859-1'; 07778 $this->markers['backendUrl'] = '../index.php'; 07779 $this->markers['backend'] = 'Backend admin'; 07780 $this->markers['frontendUrl'] = '../../index.php'; 07781 $this->markers['frontend'] = 'Frontend website'; 07782 07783 $this->markers['metaCharset'] = 'Content-Type" content="text/html; charset='; 07784 if (!empty($GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset'])) { 07785 $this->markers['metaCharset'] .= $GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset']; 07786 } else { 07787 $this->markers['metaCharset'] .= 'iso-8859-1'; 07788 } 07789 07790 // Add the error messages 07791 if (!empty($this->errorMessages)) { 07792 // Get the subpart for all error messages 07793 $errorMessagesSubPart = t3lib_parsehtml::getSubpart($this->template, '###ERRORMESSAGES###'); 07794 // Get the subpart for a single error message 07795 $errorMessageSubPart = t3lib_parsehtml::getSubpart($errorMessagesSubPart, '###MESSAGES###'); 07796 $errors = array(); 07797 07798 foreach ($this->errorMessages as $errorMessage) { 07799 // Define the markers content 07800 $errorMessageMarkers = array( 07801 'message' => $errorMessage 07802 ); 07803 // Fill the markers in the subpart 07804 $errors[] = t3lib_parsehtml::substituteMarkerArray( 07805 $errorMessageSubPart, 07806 $errorMessageMarkers, 07807 '###|###', 07808 TRUE, 07809 FALSE 07810 ); 07811 } 07812 // Substitute the subpart for a single message 07813 $errorMessagesSubPart = t3lib_parsehtml::substituteSubpart( 07814 $errorMessagesSubPart, 07815 '###MESSAGES###', 07816 implode(LF, $errors) 07817 ); 07818 } 07819 07820 // Version subpart is only allowed when password is ok 07821 if ($this->passwordOK) { 07822 // Get the subpart for the version 07823 $versionSubPart = t3lib_parsehtml::getSubpart($this->template, '###VERSIONSUBPART###'); 07824 // Define the markers content 07825 $versionSubPartMarkers['version'] = 'Version: ' . TYPO3_version; 07826 // Fill the markers in the subpart 07827 $versionSubPart = t3lib_parsehtml::substituteMarkerArray( 07828 $versionSubPart, 07829 $versionSubPartMarkers, 07830 '###|###', 07831 TRUE, 07832 FALSE 07833 ); 07834 } 07835 // Substitute the version subpart 07836 $this->template = t3lib_parsehtml::substituteSubpart( 07837 $this->template, 07838 '###VERSIONSUBPART###', 07839 $versionSubPart 07840 ); 07841 // Substitute the menu subpart 07842 $this->template = t3lib_parsehtml::substituteSubpart( 07843 $this->template, 07844 '###MENU###', 07845 $this->menu() 07846 ); 07847 // Substitute the error messages subpart 07848 $this->template = t3lib_parsehtml::substituteSubpart( 07849 $this->template, 07850 '###ERRORMESSAGES###', 07851 $errorMessagesSubPart 07852 ); 07853 // Substitute the content subpart 07854 $this->template = t3lib_parsehtml::substituteSubpart( 07855 $this->template, 07856 '###CONTENT###', 07857 $content 07858 ); 07859 // Fill the markers 07860 $this->template = t3lib_parsehtml::substituteMarkerArray( 07861 $this->template, 07862 $this->markers, 07863 '###|###', 07864 TRUE, 07865 FALSE 07866 ); 07867 07868 return $this->template; 07869 } 07870 07871 /** 07872 * Outputs an error and dies. 07873 * Should be used by all errors that occur before even starting the install tool process. 07874 * 07875 * @param string The content of the error 07876 * @return void 07877 */ 07878 protected function outputErrorAndExit($content, $title = 'Install Tool error') { 07879 // Define the stylesheet 07880 $stylesheet = '<link rel="stylesheet" type="text/css" href="' . 07881 '../stylesheets/install/install.css" />'; 07882 $javascript = '<script type="text/javascript" src="' . 07883 '../contrib/prototype/prototype.js"></script>' . LF; 07884 $javascript .= '<script type="text/javascript" src="' . 07885 '../sysext/install/Resources/Public/Javascript/install.js"></script>'; 07886 07887 // Get the template file 07888 $template = @file_get_contents(PATH_site . '/typo3/templates/install.html'); 07889 // Define the markers content 07890 $markers = array( 07891 'styleSheet' => $stylesheet, 07892 'javascript' => $javascript, 07893 'title' => $title, 07894 'content' => $content, 07895 ); 07896 // Fill the markers 07897 $content = t3lib_parsehtml::substituteMarkerArray( 07898 $template, 07899 $markers, 07900 '###|###', 07901 1, 07902 1 07903 ); 07904 // Output the warning message and exit 07905 header('Content-Type: text/html; charset=utf-8'); 07906 header('Cache-Control: no-cache, must-revalidate'); 07907 header('Pragma: no-cache'); 07908 echo $content; 07909 exit(); 07910 } 07911 07912 /** 07913 * Sends the page to the client. 07914 * 07915 * @param string $content The HTML page 07916 * @return void 07917 */ 07918 function output($content) { 07919 header ('Content-Type: text/html; charset=' . 07920 ($GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset']?$GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset']:'iso-8859-1')); 07921 echo $content; 07922 } 07923 07924 /** 07925 * Generates the main menu 07926 * 07927 * @return string HTML of the main menu 07928 */ 07929 function menu() { 07930 if ($this->mode !='123') { 07931 if (!$this->passwordOK) return; 07932 07933 $c = 0; 07934 $items = array(); 07935 // Get the subpart for the main menu 07936 $menuSubPart = t3lib_parsehtml::getSubpart($this->template, '###MENU###'); 07937 // Get the subpart for each single menu item 07938 $menuItemSubPart = t3lib_parsehtml::getSubpart($this->template, '###MENUITEM###'); 07939 07940 foreach ($this->menuitems as $k => $v) { 07941 // Define the markers content 07942 $markers = array( 07943 'class' => ($this->INSTALL['type']==$k ? 'class="act"' : ''), 07944 'id' => 't3-install-menu-' . $k, 07945 'url' => htmlspecialchars( 07946 $this->scriptSelf . 07947 '?TYPO3_INSTALL[type]=' . 07948 $k . 07949 ($this->mode ? '&mode=' . rawurlencode($this->mode) : '') 07950 ), 07951 'item' => $v 07952 ); 07953 // Fill the markers in the subpart 07954 $items[] = t3lib_parsehtml::substituteMarkerArray( 07955 $menuItemSubPart, 07956 $markers, 07957 '###|###', 07958 TRUE, 07959 FALSE 07960 ); 07961 } 07962 // Substitute the subpart for the single menu items 07963 $menuSubPart = t3lib_parsehtml::substituteSubpart( 07964 $menuSubPart, 07965 '###MENUITEM###', 07966 implode(LF, $items) 07967 ); 07968 07969 return $menuSubPart; 07970 } 07971 } 07972 07973 /** 07974 * Generates the step header for 1-2-3 mode, the numbers at the top 07975 * 07976 * @return string HTML for the step header 07977 */ 07978 function stepHeader() { 07979 // Get the template file 07980 $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'StepHeader.html'); 07981 // Get the template part from the file 07982 $template = t3lib_parsehtml::getSubpart($templateFile, '###TEMPLATE###'); 07983 // Get the subpart for each item 07984 $stepItemSubPart = t3lib_parsehtml::getSubpart($template, '###STEPITEM###'); 07985 07986 $steps = array(); 07987 07988 for ($counter = 2; $counter <= $this->totalSteps; $counter++) { 07989 $state = ''; 07990 07991 if ($this->step === $counter) { 07992 $state = 'act'; 07993 } elseif ($this->step === 'go' || $counter < $this->step) { 07994 $state = 'done'; 07995 } 07996 // Define the markers content 07997 $stepItemMarkers = array( 07998 'class' => 'class="step' . ($counter - 1) . ($state ? ' ' . $state : '') . '"', 07999 'url' => $this->scriptSelf . '?mode=' . $this->mode . '&step=' . $counter, 08000 'step' => $counter 08001 ); 08002 // Fill the markers in the subpart 08003 $steps[] = t3lib_parsehtml::substituteMarkerArray( 08004 $stepItemSubPart, 08005 $stepItemMarkers, 08006 '###|###', 08007 TRUE, 08008 FALSE 08009 ); 08010 } 08011 // Substitute the subpart for the items 08012 $content = t3lib_parsehtml::substituteSubpart( 08013 $template, 08014 '###STEPITEM###', 08015 implode(LF, $steps) 08016 ); 08017 08018 return $content; 08019 } 08020 08021 /** 08022 * Generate HTML for the security risk message 08023 * 08024 * @return string HTML for the security risk message 08025 */ 08026 function securityRisk() { 08027 return ' 08028 <p> 08029 <strong>An unsecured Install Tool presents a security risk.</strong> 08030 Minimize the risk with the following actions: 08031 </p> 08032 <ul> 08033 <li> 08034 Change the Install Tool password. 08035 </li> 08036 <li> 08037 Delete the ENABLE_INSTALL_TOOL file in the /typo3conf folder. This can be done 08038 manually or through User tools > User settings in the backend. 08039 </li> 08040 <li> 08041 For additional security, the /typo3/install/ folder can be 08042 renamed, deleted, or password protected with a .htaccess file. 08043 </li> 08044 </ul> 08045 '; 08046 } 08047 08048 /** 08049 * Generates the form to alter the password of the Install Tool 08050 * 08051 * @return string HTML of the form 08052 */ 08053 function alterPasswordForm() { 08054 // Get the template file 08055 $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'AlterPasswordForm.html'); 08056 // Get the template part from the file 08057 $template = t3lib_parsehtml::getSubpart($templateFile, '###TEMPLATE###'); 08058 // Define the markers content 08059 $markers = array( 08060 'action' => $this->scriptSelf.'?TYPO3_INSTALL[type]=extConfig', 08061 'enterPassword' => 'Enter new password:', 08062 'enterAgain' => 'Enter again:', 08063 'submit' => 'Set new password', 08064 'formToken' => $this->formProtection->generateToken( 08065 'installToolPassword', 'change' 08066 ), 08067 ); 08068 // Fill the markers 08069 $content = t3lib_parsehtml::substituteMarkerArray( 08070 $template, 08071 $markers, 08072 '###|###', 08073 TRUE, 08074 FALSE 08075 ); 08076 08077 return $content; 08078 } 08079 08080 /** 08081 * Generate HTML for the copyright 08082 * 08083 * @return string HTML of the copyright 08084 */ 08085 function copyright() { 08086 $content = ' 08087 <p> 08088 <strong>TYPO3 CMS.</strong> Copyright © 1998-' . date('Y') . ' 08089 Kasper Skårhøj. Extensions are copyright of their respective 08090 owners. Go to <a href="' . TYPO3_URL_GENERAL . '">' . TYPO3_URL_GENERAL . '</a> 08091 for details. TYPO3 comes with ABSOLUTELY NO WARRANTY; 08092 <a href="' . TYPO3_URL_LICENSE . '">click</a> for details. 08093 This is free software, and you are welcome to redistribute it 08094 under certain conditions; <a href="' . TYPO3_URL_LICENSE . '">click</a> 08095 for details. Obstructing the appearance of this notice is prohibited by law. 08096 </p> 08097 <p> 08098 <a href="' . TYPO3_URL_DONATE . '"><strong>Donate</strong></a> | 08099 <a href="' . TYPO3_URL_ORG . '">TYPO3.org</a> 08100 </p> 08101 '; 08102 08103 return $content; 08104 } 08105 08106 /** 08107 * Generate HTML for the message that the basic setup has been finished 08108 * 08109 * @return string HTML of the message 08110 */ 08111 function messageBasicFinished() { 08112 return ' 08113 <p> 08114 You have completed the basic setup of the TYPO3 Content Management System. 08115 Choose between these options to continue: 08116 </p> 08117 <ul> 08118 <li> 08119 <a href="' . $this->scriptSelf . '">Configure TYPO3</a> (Recommended) 08120 <br /> 08121 This will let you analyze and verify that everything in your 08122 installation is in order. In addition, you can configure advanced 08123 TYPO3 options in this step. 08124 </li> 08125 <li> 08126 <a href="../../index.php"> 08127 Visit the frontend 08128 </a> 08129 </li> 08130 <li> 08131 <a href="../index.php"> 08132 Login to the backend 08133 </a> 08134 <br /> 08135 (Default username: <em>admin</em>, default password: <em>password</em>.) 08136 </li> 08137 </ul> 08138 '; 08139 } 08140 08141 /** 08142 * Make the url of the script according to type, mode and step 08143 * 08144 * @param string $type The type 08145 * @return string The url 08146 */ 08147 function setScriptName($type) { 08148 $value = $this->scriptSelf.'?TYPO3_INSTALL[type]='.$type.($this->mode?'&mode='.rawurlencode($this->mode):'').($this->step?'&step='.rawurlencode($this->step):''); 08149 return $value; 08150 } 08151 08152 /** 08153 * Return the filename that will be used for the backup. 08154 * It is important that backups of PHP files still stay as a PHP file, otherwise they could be viewed un-parsed in clear-text. 08155 * 08156 * @param string $filename Full path to a file 08157 * @return string The name of the backup file (again, including the full path) 08158 */ 08159 function getBackupFilename($filename) { 08160 if (preg_match('/\.php$/', $filename)) { 08161 $backupFile = str_replace('.php', '_bak.php', $filename); 08162 } else { 08163 $backupFile = $filename.'~'; 08164 } 08165 08166 return $backupFile; 08167 } 08168 08169 /** 08170 * Creates a table which checkboxes for updating database. 08171 * 08172 * @param array $arr Array of statements (key / value pairs where key is used for the checkboxes) 08173 * @param string $label Label for the table. 08174 * @param boolean $checked If set, then checkboxes are set by default. 08175 * @param boolean $iconDis If set, then icons are shown. 08176 * @param array $currentValue Array of "current values" for each key/value pair in $arr. Shown if given. 08177 * @param boolean $cVfullMsg If set, will show the prefix "Current value" if $currentValue is given. 08178 * @return string HTML table with checkboxes for update. Must be wrapped in a form. 08179 */ 08180 function generateUpdateDatabaseForm_checkboxes($arr,$label,$checked=1,$iconDis=0,$currentValue=array(),$cVfullMsg=0) { 08181 $out = array(); 08182 $tableId = uniqid('table'); 08183 $templateMarkers = array(); 08184 if (is_array($arr)) { 08185 // Get the template file 08186 $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'GenerateUpdateDatabaseFormCheckboxes.html'); 08187 // Get the template part from the file 08188 $content = t3lib_parsehtml::getSubpart($templateFile, '###TEMPLATE###'); 08189 // Define the markers content 08190 $templateMarkers = array( 08191 'label' => $label, 08192 'tableId' => $tableId 08193 ); 08194 // Select/Deselect All 08195 if (count($arr) > 1) { 08196 // Get the subpart for multiple tables 08197 $multipleTablesSubpart = t3lib_parsehtml::getSubpart($content, '###MULTIPLETABLES###'); 08198 // Define the markers content 08199 $multipleTablesMarkers = array( 08200 'label' => $label, 08201 'tableId' => $tableId, 08202 'checked' => ($checked ? ' checked="checked"' : ''), 08203 'selectAllId' => 't3-install-' . $tableId . '-checkbox', 08204 'selectDeselectAll' => 'select/deselect all' 08205 ); 08206 // Fill the markers in the subpart 08207 $multipleTablesSubpart = t3lib_parsehtml::substituteMarkerArray( 08208 $multipleTablesSubpart, 08209 $multipleTablesMarkers, 08210 '###|###', 08211 TRUE, 08212 FALSE 08213 ); 08214 } 08215 // Substitute the subpart for multiple tables 08216 $content = t3lib_parsehtml::substituteSubpart( 08217 $content, 08218 '###MULTIPLETABLES###', 08219 $multipleTablesSubpart 08220 ); 08221 // Rows 08222 foreach ($arr as $key => $string) { 08223 // Get the subpart for rows 08224 $rowsSubpart = t3lib_parsehtml::getSubpart($content, '###ROWS###'); 08225 $currentSubpart = ''; 08226 $ico = ''; 08227 $warnings = array(); 08228 // Define the markers content 08229 $rowsMarkers = array( 08230 'checkboxId' => 't3-install-db-' . $key, 08231 'name' => $this->dbUpdateCheckboxPrefix . '[' . $key . ']', 08232 'checked' => ($checked ? 'checked="checked"' : ''), 08233 'string' => htmlspecialchars($string) 08234 ); 08235 08236 if ($iconDis) { 08237 $iconMarkers['backPath'] = $this->backPath; 08238 if (preg_match('/^TRUNCATE/i', $string)) { 08239 $iconMarkers['iconText'] = ''; 08240 $warnings['clear_table_info'] = 'Clearing the table is sometimes neccessary when adding new keys. In case of cache_* tables this should not hurt at all. However, use it with care.'; 08241 } elseif (stristr($string,' user_')) { 08242 $iconMarkers['iconText'] = '(USER)'; 08243 } elseif (stristr($string,' app_')) { 08244 $iconMarkers['iconText'] = '(APP)'; 08245 } elseif (stristr($string,' ttx_') || stristr($string,' tx_')) { 08246 $iconMarkers['iconText'] = '(EXT)'; 08247 } 08248 08249 if (!empty($iconMarkers)) { 08250 // Get the subpart for icons 08251 $iconSubpart = t3lib_parsehtml::getSubpart($content, '###ICONAVAILABLE###'); 08252 // Fill the markers in the subpart 08253 $iconSubpart = t3lib_parsehtml::substituteMarkerArray( 08254 $iconSubpart, 08255 $iconMarkers, 08256 '###|###', 08257 TRUE, 08258 TRUE 08259 ); 08260 } 08261 } 08262 // Substitute the subpart for icons 08263 $rowsSubpart = t3lib_parsehtml::substituteSubpart( 08264 $rowsSubpart, 08265 '###ICONAVAILABLE###', 08266 $iconSubpart 08267 ); 08268 08269 if (isset($currentValue[$key])) { 08270 // Get the subpart for current 08271 $currentSubpart = t3lib_parsehtml::getSubpart($rowsSubpart, '###CURRENT###'); 08272 // Define the markers content 08273 $currentMarkers = array ( 08274 'message' => (!$cVfullMsg ? 'Current value:': ''), 08275 'value' => $currentValue[$key] 08276 ); 08277 // Fill the markers in the subpart 08278 $currentSubpart = t3lib_parsehtml::substituteMarkerArray( 08279 $currentSubpart, 08280 $currentMarkers, 08281 '###|###', 08282 TRUE, 08283 FALSE 08284 ); 08285 } 08286 // Substitute the subpart for current 08287 $rowsSubpart = t3lib_parsehtml::substituteSubpart( 08288 $rowsSubpart, 08289 '###CURRENT###', 08290 $currentSubpart 08291 ); 08292 08293 $errorSubpart = ''; 08294 if (isset($this->databaseUpdateErrorMessages[$key])) { 08295 // Get the subpart for current 08296 $errorSubpart = t3lib_parsehtml::getSubpart($rowsSubpart, '###ERROR###'); 08297 // Define the markers content 08298 $currentMarkers = array ( 08299 'errorMessage' => $this->databaseUpdateErrorMessages[$key], 08300 ); 08301 // Fill the markers in the subpart 08302 $errorSubpart = t3lib_parsehtml::substituteMarkerArray( 08303 $errorSubpart, 08304 $currentMarkers, 08305 '###|###', 08306 TRUE, 08307 FALSE 08308 ); 08309 } 08310 // Substitute the subpart for error messages 08311 $rowsSubpart = t3lib_parsehtml::substituteSubpart( 08312 $rowsSubpart, 08313 '###ERROR###', 08314 $errorSubpart 08315 ); 08316 08317 // Fill the markers in the subpart 08318 $rowsSubpart = t3lib_parsehtml::substituteMarkerArray( 08319 $rowsSubpart, 08320 $rowsMarkers, 08321 '###|###', 08322 TRUE, 08323 FALSE 08324 ); 08325 08326 $rows[] = $rowsSubpart; 08327 } 08328 // Substitute the subpart for rows 08329 $content = t3lib_parsehtml::substituteSubpart( 08330 $content, 08331 '###ROWS###', 08332 implode(LF, $rows) 08333 ); 08334 08335 if (count($warnings)) { 08336 // Get the subpart for warnings 08337 $warningsSubpart = t3lib_parsehtml::getSubpart($content, '###WARNINGS###'); 08338 $warningItems = array(); 08339 08340 foreach ($warnings as $warning) { 08341 // Get the subpart for single warning items 08342 $warningItemSubpart = t3lib_parsehtml::getSubpart($warningsSubpart, '###WARNINGITEM###'); 08343 // Define the markers content 08344 $warningItemMarker['warning'] = $warning; 08345 // Fill the markers in the subpart 08346 $warningItems[] = t3lib_parsehtml::substituteMarkerArray( 08347 $warningItemSubpart, 08348 $warningItemMarker, 08349 '###|###', 08350 TRUE, 08351 FALSE 08352 ); 08353 } 08354 // Substitute the subpart for single warning items 08355 $warningsSubpart = t3lib_parsehtml::substituteSubpart( 08356 $warningsSubpart, 08357 '###WARNINGITEM###', 08358 implode(LF, $warningItems) 08359 ); 08360 } 08361 // Substitute the subpart for warnings 08362 $content = t3lib_parsehtml::substituteSubpart( 08363 $content, 08364 '###WARNINGS###', 08365 $warningsSubpart 08366 ); 08367 } 08368 // Fill the markers 08369 $content = t3lib_parsehtml::substituteMarkerArray( 08370 $content, 08371 $templateMarkers, 08372 '###|###', 08373 TRUE, 08374 FALSE 08375 ); 08376 08377 return $content; 08378 } 08379 08380 /** 08381 * Returns HTML-code, which is a visual representation of a multidimensional array 08382 * Returns false if $array_in is not an array 08383 * 08384 * @param mixed $incomingValue Array to view 08385 * @return string HTML output 08386 */ 08387 function viewArray($incomingValue) { 08388 // Get the template file 08389 $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'ViewArray.html'); 08390 08391 if (is_array($incomingValue) && !empty($incomingValue)) { 08392 // Get the template part from the file 08393 $content = t3lib_parsehtml::getSubpart($templateFile, '###TEMPLATE###'); 08394 // Get the subpart for a single item 08395 $itemSubpart = t3lib_parsehtml::getSubpart($content, '###ITEM###'); 08396 08397 foreach ($incomingValue as $key => $value) { 08398 if (is_array($value)) { 08399 $description = $this->viewArray($value); 08400 } elseif (is_object($value)) { 08401 $description = get_class($value); 08402 if (method_exists($value, '__toString')) { 08403 $description .= ': ' . (string)$value; 08404 } 08405 } else { 08406 if (gettype($value) == 'object') { 08407 $description = 'Unknown object'; 08408 } else { 08409 $description = htmlspecialchars((string) $value); 08410 } 08411 } 08412 // Define the markers content 08413 $itemMarkers = array( 08414 'key' => htmlspecialchars((string) $key), 08415 'description' => !empty($description) ? $description : ' ' 08416 ); 08417 // Fill the markers in the subpart 08418 $items[] = t3lib_parsehtml::substituteMarkerArray( 08419 $itemSubpart, 08420 $itemMarkers, 08421 '###|###', 08422 TRUE, 08423 FALSE 08424 ); 08425 } 08426 // Substitute the subpart for single item 08427 $content = t3lib_parsehtml::substituteSubpart( 08428 $content, 08429 '###ITEM###', 08430 implode(LF, $items) 08431 ); 08432 } 08433 return $content; 08434 } 08435 08436 /** 08437 * Returns a newly created TYPO3 encryption key with a given length. 08438 * 08439 * @param integer $keyLength Desired key length 08440 * @return string The encryption key 08441 */ 08442 public function createEncryptionKey($keyLength = 96) { 08443 $bytes = t3lib_div::generateRandomBytes($keyLength); 08444 return substr(bin2hex($bytes), -96); 08445 } 08446 08447 /** 08448 * Adds an error message that should be displayed. 08449 * 08450 * @param string $messageText 08451 * the text of the message to display, must not be empty 08452 */ 08453 public function addErrorMessage($messageText) { 08454 if ($messageText == '') { 08455 throw new InvalidArgumentException('$messageText must not be empty.'); 08456 } 08457 08458 $this->errorMessages[] = $messageText; 08459 } 08460 } 08461 08462 if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['ext/install/mod/class.tx_install.php'])) { 08463 include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['ext/install/mod/class.tx_install.php']); 08464 } 08465 ?>
1.8.0