TYPO3 API  SVNRelease
class.tx_install.php
Go to the documentation of this file.
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 . '&amp;TYPO3_INSTALL[typo3conf_files]=' . rawurlencode($file) . ($this->allowFileEditOutsite_typo3conf_dir ? '&amp;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 . '&amp;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']) : '&nbsp;') . '
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']) : '&nbsp;') . '
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']) : '&nbsp;') . '
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">&nbsp;</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 . '&amp;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 &gt; 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 &copy; 1998-' . date('Y') . '
08089                 Kasper Sk&#229;rh&#248;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 : '&nbsp;'
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 ?>