PageRenderTime 96ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 1ms

/typo3/sysext/install/mod/class.tx_install.php

https://github.com/andreaswolf/typo3-tceforms
PHP | 8438 lines | 6612 code | 522 blank | 1304 comment | 700 complexity | 112a7ab7236cdc0a175ba1a4581558aa MD5 | raw file
Possible License(s): Apache-2.0, BSD-2-Clause, LGPL-3.0
  1. <?php
  2. /***************************************************************
  3. * Copyright notice
  4. *
  5. * (c) 1999-2011 Kasper Skårhøj (kasperYYYY@typo3.com)
  6. * All rights reserved
  7. *
  8. * This script is part of the TYPO3 project. The TYPO3 project is
  9. * free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License as published by
  11. * the Free Software Foundation; either version 2 of the License, or
  12. * (at your option) any later version.
  13. *
  14. * The GNU General Public License can be found at
  15. * http://www.gnu.org/copyleft/gpl.html.
  16. * A copy is found in the textfile GPL.txt and important notices to the license
  17. * from the author is found in LICENSE.txt distributed with these scripts.
  18. *
  19. *
  20. * This script is distributed in the hope that it will be useful,
  21. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  22. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  23. * GNU General Public License for more details.
  24. *
  25. * This copyright notice MUST APPEAR in all copies of the script!
  26. ***************************************************************/
  27. /**
  28. * Contains the class for the Install Tool
  29. *
  30. * $Id$
  31. *
  32. * @author Kasper Skårhøj <kasperYYYY@typo3.com>
  33. * @author Ingmar Schlecht <ingmar@typo3.org>
  34. */
  35. /**
  36. * [CLASS/FUNCTION INDEX of SCRIPT]
  37. *
  38. *
  39. *
  40. * 162: class tx_install extends t3lib_install
  41. * 234: function tx_install()
  42. * 318: function checkPassword()
  43. * 362: function loginForm()
  44. * 396: function init()
  45. * 574: function stepOutput()
  46. * 836: function checkTheConfig()
  47. * 867: function typo3conf_edit()
  48. * 976: function phpinformation()
  49. *
  50. * SECTION: typo3temp/ manager
  51. * 1079: function typo3TempManager()
  52. * 1199: function getSelectorOptions($deleteType,$tt='')
  53. *
  54. * SECTION: cleanup manager
  55. * 1231: function cleanupManager()
  56. *
  57. * SECTION: CONFIGURATION FORM
  58. * 1299: function generateConfigForm($type='')
  59. * 1367: function getDefaultConfigArrayComments($string,$mainArray=array(),$commentArray=array())
  60. *
  61. * SECTION: CHECK CONFIGURATION FUNCTIONS
  62. * 1419: function checkConfiguration()
  63. * 1572: function check_mail($cmd='')
  64. * 1611: function checkExtensions()
  65. * 1673: function checkDirs()
  66. * 1762: function checkImageMagick($paths)
  67. * 1837: function _checkImageMagickGifCapability($path)
  68. * 1880: function _checkImageMagick_getVersion($file, $path)
  69. * 1915: function checkDatabase()
  70. * 1977: function setupGeneral($cmd='')
  71. * 2166: function writeToLocalconf_control($lines="", $showOutput=1)
  72. * 2190: function outputExitBasedOnStep($content)
  73. * 2206: function setLabelValueArray($arr,$type)
  74. * 2246: function getFormElement($labels,$values,$fieldName,$default,$msg='')
  75. * 2266: function getDatabaseList()
  76. * 2290: function setupGeneralCalculate()
  77. * 2387: function isTTF()
  78. *
  79. * SECTION: ABOUT the isXXX functions.
  80. * 2436: function isGD()
  81. * 2447: function isGIF()
  82. * 2459: function isJPG()
  83. * 2470: function isPNG()
  84. * 2482: function ImageTypes()
  85. * 2493: function getGDSoftwareInfo()
  86. * 2505: function generallyAboutConfiguration()
  87. *
  88. * SECTION: IMAGE processing
  89. * 2565: function checkTheImageProcessing()
  90. * 3046: function isExtensionEnabled($ext, $headCode, $short)
  91. * 3062: function displayTwinImage ($imageFile, $IMcommands=array(), $note='')
  92. * 3130: function getTwinImageMessage($message, $label_1="", $label_2='')
  93. * 3146: function formatImCmds($arr)
  94. * 3167: function imagemenu()
  95. *
  96. * SECTION: DATABASE analysing
  97. * 3209: function checkTheDatabase()
  98. * 3849: function updateWizard()
  99. * 3873: function updateWizard_parts($action)
  100. * 3987: function getUpgradeObjInstance($className, $identifier)
  101. * 4000: function isBackendAdminUser()
  102. * 4023: function isBasicComplete($tLabel)
  103. * 4063: function generateUpdateDatabaseForm($type, $arr_update, $arr_remove, $action_type)
  104. * 4094: function getUpdateDbFormWrap($action_type, $content, $label='Write to database')
  105. * 4107: function displayFields($arr, $pre=0, $label='')
  106. * 4132: function displayFieldComp($arr, $arr_db)
  107. * 4174: function displaySuggestions($arr, $excludeList='')
  108. * 4204: function compareDatabaseAndTCA($FDsrc, $TCA, $onlyFields=0)
  109. * 4262: function compareTCAandDatabase($TCA, $FDcomp)
  110. * 4296: function suggestFieldDefinition($fieldInfo)
  111. * 4373: function getItemArrayType($arr)
  112. * 4401: function getItemBlobSize($len)
  113. * 4412: function suggestTCAFieldDefinition($fieldName,$fieldInfo)
  114. * 4555: function includeTCA()
  115. *
  116. * SECTION: GENERAL FUNCTIONS
  117. * 4597: function linkIt($url,$link='')
  118. * 4611: function message($head, $short_string='', $long_string='', $type=0, $force=0)
  119. * 4632: function printSection($head, $short_string, $long_string, $type)
  120. * 4673: function fw($str,$size=1)
  121. * 4696: function fwheader($str)
  122. * 4707: function wrapInCells($label,$content)
  123. * 4716: function printAll()
  124. * 4735: function outputWrapper($content)
  125. * 4801: function menu()
  126. * 4823: function stepHeader()
  127. * 4865: function note123()
  128. * 4879: function endNotes()
  129. * 4912: function securityRisk()
  130. * 4930: function alterPasswordForm()
  131. * 4946: function messageBasicFinished()
  132. * 4968: function setScriptName($type)
  133. * 4981: function formWidth($size=48,$textarea=0,$styleOverride='')
  134. * 5002: function formWidthText($size=48,$styleOverride='',$wrap='')
  135. * 5018: function getBackupFilename($filename)
  136. *
  137. * TOTAL FUNCTIONS: 82
  138. * (This index is automatically created/updated by the extension "extdeveval")
  139. *
  140. */
  141. // include requirements definition:
  142. require_once(t3lib_extMgm::extPath('install') . 'requirements.php');
  143. // include update classes
  144. require_once(t3lib_extMgm::extPath('install') . 'updates/class.tx_coreupdates_charsetdefaults.php');
  145. require_once(t3lib_extMgm::extPath('install').'updates/class.tx_coreupdates_compatversion.php');
  146. require_once(t3lib_extMgm::extPath('install').'updates/class.tx_coreupdates_cscsplit.php');
  147. require_once(t3lib_extMgm::extPath('install').'updates/class.tx_coreupdates_notinmenu.php');
  148. require_once(t3lib_extMgm::extPath('install').'updates/class.tx_coreupdates_mergeadvanced.php');
  149. require_once(t3lib_extMgm::extPath('install').'updates/class.tx_coreupdates_installsysexts.php');
  150. require_once(t3lib_extMgm::extPath('install').'updates/class.tx_coreupdates_imagescols.php');
  151. require_once(t3lib_extMgm::extPath('install').'updates/class.tx_coreupdates_installnewsysexts.php');
  152. require_once(t3lib_extMgm::extPath('install') . 'mod/class.tx_install_session.php');
  153. require_once(t3lib_extMgm::extPath('install') . 'updates/class.tx_coreupdates_statictemplates.php');
  154. require_once(t3lib_extMgm::extPath('install') . 'updates/class.tx_coreupdates_t3skin.php');
  155. require_once(t3lib_extMgm::extPath('install') . 'updates/class.tx_coreupdates_compressionlevel.php');
  156. require_once(t3lib_extMgm::extPath('install') . 'updates/class.tx_coreupdates_migrateworkspaces.php');
  157. require_once(t3lib_extMgm::extPath('install') . 'updates/class.tx_coreupdates_flagsfromsprite.php');
  158. require_once(t3lib_extMgm::extPath('install') . 'updates/class.tx_coreupdates_addflexformstoacl.php');
  159. require_once(t3lib_extMgm::extPath('install') . 'updates/class.tx_coreupdates_imagelink.php');
  160. /**
  161. * Install Tool module
  162. *
  163. * $Id$
  164. *
  165. * @author Kasper Skårhøj <kasperYYYY@typo3.com>
  166. * @author Ingmar Schlecht <ingmar@typo3.org>
  167. * @package TYPO3
  168. * @subpackage tx_install
  169. */
  170. class tx_install extends t3lib_install {
  171. var $templateFilePath = 'typo3/sysext/install/Resources/Private/Templates/';
  172. var $template;
  173. var $javascript;
  174. var $stylesheets;
  175. var $markers = array();
  176. var $messages = array();
  177. var $errorMessages = array();
  178. var $mailMessage = '';
  179. var $action = ''; // The url that calls this script
  180. var $scriptSelf = 'index.php'; // The url that calls this script
  181. var $updateIdentity = 'TYPO3 Install Tool';
  182. var $headerStyle ='';
  183. var $setAllCheckBoxesByDefault=0;
  184. var $allowFileEditOutsite_typo3conf_dir=0;
  185. var $INSTALL =array(); // In constructor: is set to global GET/POST var TYPO3_INSTALL
  186. var $checkIMlzw = 0; // If set, lzw capabilities of the available ImageMagick installs are check by actually writing a gif-file and comparing size
  187. var $checkIM = 0; // If set, ImageMagick is checked.
  188. var $dumpImCommands=1; // If set, the image Magick commands are always outputted in the image processing checker
  189. var $mode = ''; // If set to "123" then only most vital information is displayed.
  190. var $step = 0; // If set to 1,2,3 or GO it signifies various functions.
  191. var $totalSteps = 4; // Can be changed by hook to define the total steps in 123 mode
  192. // internal
  193. var $passwordOK=0; // This is set, if the password check was ok. The function init() will exit if this is not set
  194. var $silent=1; // If set, the check routines don't add to the message-array
  195. var $sections=array(); // Used to gather the message information.
  196. var $fatalError=0; // This is set if some error occured that will definitely prevent TYpo3 from running.
  197. var $sendNoCacheHeaders=1;
  198. var $config_array = array( // Flags are set in this array if the options are available and checked ok.
  199. 'gd'=>0,
  200. 'gd_gif'=>0,
  201. 'gd_png'=>0,
  202. 'gd_jpg'=>0,
  203. 'freetype' => 0,
  204. 'safemode' => 0,
  205. 'dir_typo3temp' => 0,
  206. 'dir_temp' => 0,
  207. 'im_versions' => array(),
  208. 'im' => 0,
  209. 'sql.safe_mode_user' => '',
  210. 'mysqlConnect' => 0,
  211. 'no_database' => 0
  212. );
  213. var $typo3temp_path='';
  214. /**
  215. * the session handling object
  216. *
  217. * @var tx_install_session
  218. */
  219. protected $session = NULL;
  220. /**
  221. * the form protection instance used for creating and verifying form tokens
  222. *
  223. * @var t3lib_formprotection_InstallToolFormProtection
  224. */
  225. protected $formProtection = NULL;
  226. var $menuitems = array(
  227. 'config' => 'Basic Configuration',
  228. 'database' => 'Database Analyser',
  229. 'update' => 'Upgrade Wizard',
  230. 'images' => 'Image Processing',
  231. 'extConfig' => 'All Configuration',
  232. 'cleanup' => 'Clean up',
  233. 'phpinfo' => 'phpinfo()',
  234. 'typo3conf_edit' => 'Edit files in typo3conf/',
  235. 'about' => 'About',
  236. 'logout' => 'Logout from Install Tool',
  237. );
  238. // PHP modules which are required. Can be changed by hook in getMissingPhpModules()
  239. protected $requiredPhpModules = array(
  240. 'filter',
  241. 'gd',
  242. 'json',
  243. 'mysql',
  244. 'pcre',
  245. 'session',
  246. 'SPL',
  247. 'standard',
  248. 'xml',
  249. 'zlib'
  250. );
  251. /**
  252. * Constructor
  253. *
  254. * @return void
  255. */
  256. function tx_install() {
  257. parent::t3lib_install();
  258. if (!$GLOBALS['TYPO3_CONF_VARS']['BE']['installToolPassword']) {
  259. $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');
  260. }
  261. if ($this->sendNoCacheHeaders) {
  262. header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
  263. header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
  264. header('Expires: 0');
  265. header('Cache-Control: no-cache, must-revalidate');
  266. header('Pragma: no-cache');
  267. }
  268. // ****************************
  269. // Initializing incoming vars.
  270. // ****************************
  271. $this->INSTALL = t3lib_div::_GP('TYPO3_INSTALL');
  272. $this->mode = t3lib_div::_GP('mode');
  273. if ($this->mode !== '123') {
  274. $this->mode = '';
  275. }
  276. if (t3lib_div::_GP('step') === 'go') {
  277. $this->step = 'go';
  278. } else {
  279. $this->step = intval(t3lib_div::_GP('step'));
  280. }
  281. // Let DBAL decide whether to load itself
  282. $dbalLoaderFile = $this->backPath . 'sysext/dbal/class.tx_dbal_autoloader.php';
  283. if (@is_file($dbalLoaderFile)) {
  284. include($dbalLoaderFile);
  285. }
  286. if ($this->mode === '123') {
  287. // Check for mandatory PHP modules
  288. $missingPhpModules = $this->getMissingPhpModules();
  289. if (count($missingPhpModules) > 0) {
  290. throw new RuntimeException('TYPO3 Installation Error: The following PHP module(s) is/are missing: <em>' .
  291. implode(', ', $missingPhpModules) .
  292. '</em><br /><br />You need to install and enable these modules first to be able to install TYPO3.',
  293. 1294587482
  294. );
  295. }
  296. }
  297. $this->redirect_url = t3lib_div::sanitizeLocalUrl(t3lib_div::_GP('redirect_url'));
  298. $this->INSTALL['type'] = '';
  299. if ($_GET['TYPO3_INSTALL']['type']) {
  300. $allowedTypes = array(
  301. 'config', 'database', 'update', 'images', 'extConfig',
  302. 'cleanup', 'phpinfo', 'typo3conf_edit', 'about', 'logout'
  303. );
  304. if (in_array($_GET['TYPO3_INSTALL']['type'], $allowedTypes)) {
  305. $this->INSTALL['type'] = $_GET['TYPO3_INSTALL']['type'];
  306. }
  307. }
  308. if ($this->step == 4) {
  309. $this->INSTALL['type'] = 'database';
  310. }
  311. // Hook to raise the counter for the total steps in the 1-2-3 installer
  312. if (is_array ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install/mod/class.tx_install.php']['additionalSteps'])) {
  313. foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install/mod/class.tx_install.php']['additionalSteps'] as $classData) {
  314. $hookObject = t3lib_div::getUserObj($classData);
  315. $this->totalSteps += (integer) $hookObject->executeAdditionalSteps($this);
  316. }
  317. }
  318. if ($this->mode=='123') {
  319. $tempItems = $this->menuitems;
  320. $this->menuitems = array(
  321. 'config' => $tempItems['config'],
  322. 'database' => $tempItems['database']
  323. );
  324. if (!$this->INSTALL['type'] || !isset($this->menuitems[$this->INSTALL['type']])) {
  325. $this->INSTALL['type'] = 'config';
  326. }
  327. } else {
  328. if (!$this->INSTALL['type'] || !isset($this->menuitems[$this->INSTALL['type']])) {
  329. $this->INSTALL['type'] = 'about';
  330. }
  331. }
  332. $this->action = $this->scriptSelf .
  333. '?TYPO3_INSTALL[type]=' . $this->INSTALL['type'] .
  334. ($this->mode? '&mode=' . $this->mode : '') .
  335. ($this->step? '&step=' . $this->step : '');
  336. $this->typo3temp_path = PATH_site.'typo3temp/';
  337. if (!is_dir($this->typo3temp_path) || !is_writeable($this->typo3temp_path)) {
  338. $this->outputErrorAndExit('Install Tool needs to write to typo3temp/. Make sure this directory is writeable by your webserver: ' . htmlspecialchars($this->typo3temp_path), 'Fatal error');
  339. }
  340. try {
  341. $this->session = t3lib_div::makeInstance('tx_install_session');
  342. } catch (Exception $exception) {
  343. $this->outputErrorAndExit($exception->getMessage());
  344. }
  345. // *******************
  346. // Check authorization
  347. // *******************
  348. if (!$this->session->hasSession()) {
  349. $this->session->startSession();
  350. }
  351. if ($this->session->isAuthorized() || $this->checkPassword()) {
  352. $this->passwordOK=1;
  353. $this->session->refreshSession();
  354. $enableInstallToolFile = PATH_typo3conf . 'ENABLE_INSTALL_TOOL';
  355. if (is_file ($enableInstallToolFile)) {
  356. // Extend the age of the ENABLE_INSTALL_TOOL file by one hour
  357. @touch($enableInstallToolFile);
  358. }
  359. if($this->redirect_url) {
  360. t3lib_utility_Http::redirect($this->redirect_url);
  361. }
  362. $this->formProtection = t3lib_formProtection_Factory::get(
  363. 't3lib_formprotection_InstallToolFormProtection'
  364. );
  365. $this->formProtection->injectInstallTool($this);
  366. } else {
  367. $this->loginForm();
  368. }
  369. }
  370. /**
  371. * Returns true if submitted password is ok.
  372. *
  373. * If password is ok, set session as "authorized".
  374. *
  375. * @return boolean true if the submitted password was ok and session was
  376. * authorized, false otherwise
  377. */
  378. function checkPassword() {
  379. $p = t3lib_div::_GP('password');
  380. if ($p && md5($p)==$GLOBALS['TYPO3_CONF_VARS']['BE']['installToolPassword']) {
  381. $this->session->setAuthorized();
  382. // Sending warning email
  383. $wEmail = $GLOBALS['TYPO3_CONF_VARS']['BE']['warning_email_addr'];
  384. if ($wEmail) {
  385. $subject="Install Tool Login at '".$GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename']."'";
  386. $email_body="There has been a Install Tool login at TYPO3 site '".$GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename']."' (".t3lib_div::getIndpEnv('HTTP_HOST').") from remote address '".t3lib_div::getIndpEnv('REMOTE_ADDR')."' (".t3lib_div::getIndpEnv('REMOTE_HOST').')';
  387. mail($wEmail,
  388. $subject,
  389. $email_body,
  390. 'From: TYPO3 Install Tool WARNING <>'
  391. );
  392. }
  393. return true;
  394. } else {
  395. // Bad password, send warning:
  396. if ($p) {
  397. $wEmail = $GLOBALS['TYPO3_CONF_VARS']['BE']['warning_email_addr'];
  398. if ($wEmail) {
  399. $subject="Install Tool Login ATTEMPT at '".$GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename']."'";
  400. $email_body="There has been an Install Tool login attempt at TYPO3 site '".$GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename']."' (".t3lib_div::getIndpEnv('HTTP_HOST').").
  401. The MD5 hash of the last 5 characters of the password tried was '".substr(md5($p), -5)."'
  402. REMOTE_ADDR was '".t3lib_div::getIndpEnv('REMOTE_ADDR')."' (".t3lib_div::getIndpEnv('REMOTE_HOST').')';
  403. mail($wEmail,
  404. $subject,
  405. $email_body,
  406. 'From: TYPO3 Install Tool WARNING <>'
  407. );
  408. }
  409. }
  410. return false;
  411. }
  412. }
  413. /**
  414. * Create the HTML for the login form
  415. *
  416. * Reads and fills the template.
  417. * Substitutes subparts when wrong password has been given
  418. * or the session has expired
  419. *
  420. * @return void
  421. */
  422. function loginForm() {
  423. $password = t3lib_div::_GP('password');
  424. $redirect_url = $this->redirect_url ? $this->redirect_url : $this->action;
  425. // Get the template file
  426. $templateFile = @file_get_contents(
  427. PATH_site . $this->templateFilePath . 'LoginForm.html'
  428. );
  429. // Get the template part from the file
  430. $template = t3lib_parsehtml::getSubpart(
  431. $templateFile, '###TEMPLATE###'
  432. );
  433. // Password has been given, but this form is rendered again.
  434. // This means the given password was wrong
  435. if (!empty($password)) {
  436. // Get the subpart for the wrong password
  437. $wrongPasswordSubPart = t3lib_parsehtml::getSubpart(
  438. $template, '###WRONGPASSWORD###'
  439. );
  440. // Define the markers content
  441. $wrongPasswordMarkers = array(
  442. 'passwordMessage' => 'The password you just tried has this md5-value:',
  443. 'password' => md5($password)
  444. );
  445. // Fill the markers in the subpart
  446. $wrongPasswordSubPart = t3lib_parsehtml::substituteMarkerArray(
  447. $wrongPasswordSubPart,
  448. $wrongPasswordMarkers,
  449. '###|###',
  450. TRUE,
  451. TRUE
  452. );
  453. }
  454. // Session has expired
  455. if (!$this->session->isAuthorized() && $this->session->isExpired()) {
  456. // Get the subpart for the expired session message
  457. $sessionExpiredSubPart = t3lib_parsehtml::getSubpart(
  458. $template, '###SESSIONEXPIRED###'
  459. );
  460. // Define the markers content
  461. $sessionExpiredMarkers = array(
  462. 'message' => 'Your Install Tool session has expired'
  463. );
  464. // Fill the markers in the subpart
  465. $sessionExpiredSubPart = t3lib_parsehtml::substituteMarkerArray(
  466. $sessionExpiredSubPart,
  467. $sessionExpiredMarkers,
  468. '###|###',
  469. TRUE,
  470. TRUE
  471. );
  472. }
  473. // Substitute the subpart for the expired session in the template
  474. $template = t3lib_parsehtml::substituteSubpart(
  475. $template,
  476. '###SESSIONEXPIRED###',
  477. $sessionExpiredSubPart
  478. );
  479. // Substitute the subpart for the wrong password in the template
  480. $template = t3lib_parsehtml::substituteSubpart(
  481. $template,
  482. '###WRONGPASSWORD###',
  483. $wrongPasswordSubPart
  484. );
  485. // Define the markers content
  486. $markers = array(
  487. 'siteName' => 'Site: ' .
  488. htmlspecialchars($GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename']),
  489. 'headTitle' => 'Login to TYPO3 ' . TYPO3_version . ' Install Tool',
  490. 'redirectUrl' => htmlspecialchars($redirect_url),
  491. 'enterPassword' => 'Password',
  492. 'login' => 'Login',
  493. 'message' => '
  494. <p class="typo3-message message-information">
  495. The Install Tool Password is <em>not</em> the admin password
  496. of TYPO3.
  497. <br />
  498. The default password is <em>joh316</em>. Be sure to change it!
  499. <br /><br />
  500. If you don\'t know the current password, you can set a new
  501. one by setting the value of
  502. $TYPO3_CONF_VARS[\'BE\'][\'installToolPassword\'] in
  503. typo3conf/localconf.php to the md5() hash value of the
  504. password you desire.
  505. </p>
  506. '
  507. );
  508. // Fill the markers in the template
  509. $content = t3lib_parsehtml::substituteMarkerArray(
  510. $template,
  511. $markers,
  512. '###|###',
  513. TRUE,
  514. TRUE
  515. );
  516. // Send content to the page wrapper function
  517. $this->output($this->outputWrapper($content));
  518. }
  519. /**
  520. * Calling function that checks system, IM, GD, dirs, database
  521. * and lets you alter localconf.php
  522. *
  523. * This method is called from init.php to start the Install Tool.
  524. *
  525. * @return void
  526. */
  527. function init() {
  528. // Must be called after inclusion of init.php (or from init.php)
  529. if (!defined('PATH_typo3')) exit;
  530. if (!$this->passwordOK) exit;
  531. // Setting stuff...
  532. $this->check_mail();
  533. $this->setupGeneral();
  534. $this->generateConfigForm();
  535. if (count($this->messages)) {
  536. t3lib_div::debug($this->messages);
  537. }
  538. if ($this->step) {
  539. $this->output($this->outputWrapper($this->stepOutput()));
  540. } else {
  541. // Menu...
  542. switch($this->INSTALL['type']) {
  543. case 'images':
  544. $this->checkIM=1;
  545. $this->checkTheConfig();
  546. $this->silent=0;
  547. $this->checkTheImageProcessing();
  548. break;
  549. case 'database':
  550. $this->checkTheConfig();
  551. $this->silent=0;
  552. $this->checkTheDatabase();
  553. break;
  554. case 'update':
  555. $this->checkDatabase();
  556. $this->silent=0;
  557. $this->updateWizard();
  558. break;
  559. case 'config':
  560. $this->silent=0;
  561. $this->checkIM=1;
  562. $this->message(
  563. 'About configuration',
  564. 'How to configure TYPO3',
  565. $this->generallyAboutConfiguration()
  566. );
  567. $this->message(
  568. 'System Information',
  569. 'Your system has the following configuration',
  570. '
  571. <dl id="systemInformation">
  572. <dt>OS detected:</dt>
  573. <dd>' . (TYPO3_OS == 'WIN' ? 'WIN' : 'UNIX') .'</dd>
  574. <dt>UNIX/CGI detected:</dt>
  575. <dd>' . (PHP_SAPI == 'cgi' ? 'YES' : 'NO') . '</dd>
  576. <dt>PATH_thisScript:</dt>
  577. <dd>' . PATH_thisScript . '</dd>
  578. </dl>
  579. '
  580. );
  581. $this->checkTheConfig();
  582. $ext = 'Write config to localconf.php';
  583. if ($this->fatalError) {
  584. if (
  585. $this->config_array['no_database'] ||
  586. !$this->config_array['mysqlConnect']
  587. ) {
  588. $this->message($ext, 'Database not configured yet!', '
  589. <p>
  590. You need to specify database username,
  591. password and host as one of the first things.
  592. <br />
  593. Next you\'ll have to select a database to
  594. use with TYPO3.
  595. </p>
  596. <p>
  597. Use the form below.
  598. </p>
  599. ', 2);
  600. } else {
  601. $this->message($ext, 'Fatal error encountered!', '
  602. <p>
  603. Somewhere above a fatal configuration
  604. problem is encountered.
  605. Please make sure that you\'ve fixed this
  606. error before you submit the configuration.
  607. TYPO3 will not run if this problem is not
  608. fixed!
  609. <br />
  610. You should also check all warnings that may
  611. appear.
  612. </p>
  613. ', 2);
  614. }
  615. } elseif ($this->mode=='123') {
  616. if (!$this->fatalError) {
  617. $this->message($ext, 'Basic configuration completed', '
  618. <p>
  619. You have no fatal errors in your basic
  620. configuration.
  621. You may have warnings though. Please pay
  622. attention to them!
  623. However you may continue and install the
  624. database.
  625. </p>
  626. <p>
  627. <strong>
  628. <span style="color:#f00;">Step 2: </span>
  629. </strong>
  630. <a href="' . $this->scriptSelf .
  631. '?TYPO3_INSTALL[type]=database' .
  632. ($this->mode ? '&mode=' . rawurlencode($this->mode) : '') .
  633. '">Click here to install the database.</a>
  634. </p>
  635. ', -1, 1);
  636. }
  637. }
  638. $this->message($ext, 'Very Important: Changing Image Processing settings', '
  639. <p>
  640. When you change the settings for Image Processing
  641. you <em>must</em> take into account
  642. that <em>old images</em> may still be in typo3temp/
  643. folder and prevent new files from being generated!
  644. <br />
  645. This is especially important to know, if you\'re
  646. trying to set up image processing for the very first
  647. time.
  648. <br />
  649. The problem is solved by <a href="' .
  650. htmlspecialchars($this->setScriptName('cleanup')) .
  651. '">clearing the typo3temp/ folder</a>.
  652. Also make sure to clear the cache_pages table.
  653. </p>
  654. ', 1, 1);
  655. $this->message($ext, 'Very Important: Changing Encryption Key setting', '
  656. <p>
  657. When you change the setting for the Encryption Key
  658. you <em>must</em> take into account that a change to
  659. this value might invalidate temporary information,
  660. URLs etc.
  661. <br />
  662. The problem is solved by <a href="' .
  663. htmlspecialchars($this->setScriptName('cleanup')) .
  664. '">clearing the typo3temp/ folder</a>.
  665. Also make sure to clear the cache_pages table.
  666. </p>
  667. ', 1, 1);
  668. $this->message($ext, 'Update localconf.php', '
  669. <p>
  670. This form updates the localconf.php file with the
  671. suggested values you see below. The values are based
  672. on the analysis above.
  673. <br />
  674. You can change the values in case you have
  675. alternatives to the suggested defaults.
  676. <br />
  677. By this final step you will configure TYPO3 for
  678. immediate use provided that you have no fatal errors
  679. left above.
  680. </p>' . $this->setupGeneral('get_form') . '
  681. ', 0, 1);
  682. $this->output($this->outputWrapper($this->printAll()));
  683. break;
  684. case 'extConfig':
  685. $this->silent=0;
  686. $this->generateConfigForm('get_form');
  687. // Get the template file
  688. $templateFile = @file_get_contents(
  689. PATH_site . $this->templateFilePath . 'InitExtConfig.html'
  690. );
  691. // Get the template part from the file
  692. $template = t3lib_parsehtml::getSubpart(
  693. $templateFile, '###TEMPLATE###'
  694. );
  695. // Define the markers content
  696. $markers = array(
  697. 'action' => $this->action,
  698. 'content' => $this->printAll(),
  699. 'write' => 'Write to localconf.php',
  700. 'notice' => 'NOTICE:',
  701. 'explanation' => '
  702. By clicking this button, localconf.php is updated
  703. with new values for the parameters listed above!
  704. '
  705. );
  706. // Fill the markers in the template
  707. $content = t3lib_parsehtml::substituteMarkerArray(
  708. $template,
  709. $markers,
  710. '###|###',
  711. TRUE,
  712. FALSE
  713. );
  714. // Send content to the page wrapper function
  715. $this->output($this->outputWrapper($content));
  716. break;
  717. case 'cleanup':
  718. $this->checkTheConfig();
  719. $this->silent=0;
  720. $this->cleanupManager();
  721. break;
  722. case 'phpinfo':
  723. $this->silent=0;
  724. $this->phpinformation();
  725. break;
  726. case 'typo3conf_edit':
  727. $this->silent=0;
  728. $this->typo3conf_edit();
  729. break;
  730. case 'logout':
  731. $enableInstallToolFile = PATH_site . 'typo3conf/ENABLE_INSTALL_TOOL';
  732. if (is_file($enableInstallToolFile) && trim(file_get_contents($enableInstallToolFile)) !== 'KEEP_FILE') {
  733. unlink(PATH_typo3conf . 'ENABLE_INSTALL_TOOL');
  734. }
  735. $this->formProtection->clean();
  736. $this->session->destroySession();
  737. t3lib_utility_Http::redirect($this->scriptSelf);
  738. break;
  739. case 'about':
  740. default:
  741. $this->silent=0;
  742. $this->message('About', 'Warning - very important!', $this->securityRisk().$this->alterPasswordForm(),2);
  743. $this->message('About', 'Using this script', '
  744. <p>
  745. Installing TYPO3 has always been a hot topic on the
  746. mailing list and forums. Therefore we\'ve developed
  747. this tool which will help you through configuration
  748. and testing.
  749. <br />
  750. There are three primary steps for you to take:
  751. </p>
  752. <p>
  753. <strong>1: Basic Configuration</strong>
  754. <br />
  755. In this step your PHP-configuration is checked. If
  756. there are any settings that will prevent TYPO3 from
  757. running correctly you\'ll get warnings and errors
  758. with a description of the problem.
  759. <br />
  760. You\'ll have to enter a database username, password
  761. and hostname. Then you can choose to create a new
  762. database or select an existing one.
  763. <br />
  764. Finally the image processing settings are entered
  765. and verified and you can choose to let the script
  766. update the configuration file,
  767. typo3conf/localconf.php with the suggested settings.
  768. </p>
  769. <p>
  770. <strong>2: Database Analyser</strong>
  771. <br />
  772. In this step you can either install a new database
  773. or update the database from any previous TYPO3
  774. version.
  775. <br />
  776. You can also get an overview of extra/missing
  777. fields/tables in the database compared to a raw
  778. sql-file.
  779. <br />
  780. The database is also verified against your
  781. \'tables.php\' configuration ($TCA) and you can
  782. even see suggestions to entries in $TCA or new
  783. fields in the database.
  784. </p>
  785. <p>
  786. <strong>3: Upgrade Wizard</strong>
  787. <br />
  788. Here you will find update methods taking care of
  789. changes to the TYPO3 core which are not backwards
  790. compatible.
  791. <br />
  792. It is recommended to run this wizard after every
  793. update to make sure everything will still work
  794. flawlessly.
  795. </p>
  796. <p>
  797. <strong>4: Image Processing</strong>
  798. <br />
  799. This step is a visual guide to verify your
  800. configuration of the image processing software.
  801. <br />
  802. You\'ll be presented to a list of images that should
  803. all match in pairs. If some irregularity appears,
  804. you\'ll get a warning. Thus you\'re able to track an
  805. error before you\'ll discover it on your website.
  806. </p>
  807. <p>
  808. <strong>5: All Configuration</strong>
  809. <br />
  810. This gives you access to any of the configuration
  811. options in the TYPO3_CONF_VARS array. Every option
  812. is also presented with a comment explaining what it
  813. does.
  814. </p>
  815. <p>
  816. <strong>6: Cleanup</strong>
  817. <br />
  818. Here you can clean up the temporary files in typo3temp/
  819. folder and the tables used for caching of data in
  820. your database.
  821. </p>
  822. ');
  823. $this->message('About', 'Why is this script stand-alone?', '
  824. <p>
  825. You would think that this script should rather be a
  826. module in the backend and access-controlled to only
  827. admin-users from the database. But that\'s not how
  828. it works.
  829. <br />
  830. The reason is, that this script must not be
  831. depending on the success of the configuration of
  832. TYPO3 and whether or not there is a working database
  833. behind. Therefore the script is invoked from the
  834. backend init.php file, which allows access if the
  835. constant \'TYPO3_enterInstallScript\' has been
  836. defined and is not false. That is and should be the
  837. case <em>only</em> when calling the script
  838. \'typo3/install/index.php\' - this script!
  839. </p>
  840. ');
  841. $headCode='Header legend';
  842. $this->message($headCode, 'Notice!', '
  843. <p>
  844. Indicates that something is important to be aware
  845. of.
  846. <br />
  847. This does <em>not</em> indicate an error.
  848. </p>
  849. ', 1);
  850. $this->message($headCode, 'Just information', '
  851. <p>
  852. This is a simple message with some information about
  853. something.
  854. </p>
  855. ');
  856. $this->message($headCode, 'Check was successful', '
  857. <p>
  858. Indicates that something was checked and returned an
  859. expected result.
  860. </p>
  861. ', -1);
  862. $this->message($headCode, 'Warning!', '
  863. <p>
  864. Indicates that something may very well cause trouble
  865. and you should definitely look into it before
  866. proceeding.
  867. <br />
  868. This indicates a <em>potential</em> error.
  869. </p>
  870. ', 2);
  871. $this->message($headCode, 'Error!', '
  872. <p>
  873. Indicates that something is definitely wrong and
  874. that TYPO3 will most likely not perform as expected
  875. if this problem is not solved.
  876. <br />
  877. This indicates an actual error.
  878. </p>
  879. ', 3);
  880. $this->output($this->outputWrapper($this->printAll()));
  881. break;
  882. }
  883. }
  884. $this->formProtection->persistTokens();
  885. }
  886. /**
  887. * Controls the step 1-2-3-go process
  888. *
  889. * @return string The content to output to the screen
  890. */
  891. function stepOutput() {
  892. // Get the template file
  893. $templateFile = @file_get_contents(
  894. PATH_site . $this->templateFilePath . 'StepOutput.html'
  895. );
  896. // Get the template part from the file
  897. $template = t3lib_parsehtml::getSubpart(
  898. $templateFile, '###TEMPLATE###'
  899. );
  900. // Define the markers content
  901. $markers = array(
  902. 'stepHeader' => $this->stepHeader(),
  903. 'notice' => 'Skip this wizard (for power users only)',
  904. 'skip123' => $this->scriptSelf
  905. );
  906. $this->checkTheConfig();
  907. $error_missingConnect = '
  908. <p class="typo3-message message-error">
  909. <strong>
  910. There is no connection to the database!
  911. </strong>
  912. <br />
  913. (Username: <em>' . htmlspecialchars(TYPO3_db_username) . '</em>,
  914. Host: <em>' . htmlspecialchars(TYPO3_db_host) . '</em>,
  915. Using Password: YES)
  916. <br />
  917. Go to Step 1 and enter a valid username and password!
  918. </p>
  919. ';
  920. $error_missingDB = '
  921. <p class="typo3-message message-error">
  922. <strong>
  923. There is no access to the database (<em>' . htmlspecialchars(TYPO3_db) . '</em>)!
  924. </strong>
  925. <br />
  926. Go to Step 2 and select a valid database!
  927. </p>
  928. ';
  929. // only get the number of tables if it is not the first two steps in the 123-installer
  930. // (= no DB connection yet)
  931. $whichTables = ($this->step != 1 && $this->step != 2 ? $this->getListOfTables() : array());
  932. $error_emptyDB = '
  933. <p class="typo3-message message-error">
  934. <strong>
  935. The database is still empty. There are no tables!
  936. </strong>
  937. <br />
  938. Go to Step 3 and import a database!
  939. </p>
  940. ';
  941. // Hook to override and add steps to the 1-2-3 installer
  942. if (is_array ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install/mod/class.tx_install.php']['stepOutput'])) {
  943. foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install/mod/class.tx_install.php']['stepOutput'] as $classData) {
  944. $hookObject = t3lib_div::getUserObj($classData);
  945. $hookObject->executeStepOutput($markers, $this->step, $this);
  946. }
  947. }
  948. // Use the default steps when there is no override
  949. if (!$markers['header'] && !$markers['step']) {
  950. switch(strtolower($this->step)) {
  951. case 1:
  952. // Get the subpart for the first step
  953. $step1SubPart = t3lib_parsehtml::getSubpart(
  954. $templateFile, '###STEP1###'
  955. );
  956. // Add header marker for main template
  957. $markers['header'] = 'Welcome to the TYPO3 Install Tool';
  958. // Define the markers content for the subpart
  959. $step1SubPartMarkers = array(
  960. 'llIntroduction' => '
  961. <p>
  962. TYPO3 is an enterprise content management system
  963. that is powerful, yet easy to install.
  964. </p>
  965. <p>
  966. In three simple steps you\'ll be ready to add content to your website.
  967. </p>
  968. ',
  969. 'step' => $this->step + 1,
  970. 'action' => htmlspecialchars($this->action),
  971. 'continue' => 'Continue'
  972. );
  973. // Add step marker for main template
  974. $markers['step'] = t3lib_parsehtml::substituteMarkerArray(
  975. $step1SubPart,
  976. $step1SubPartMarkers,
  977. '###|###',
  978. TRUE,
  979. FALSE
  980. );
  981. break;
  982. case 2:
  983. // Get the subpart for the second step
  984. $step2SubPart = t3lib_parsehtml::getSubpart(
  985. $templateFile, '###STEP2###'
  986. );
  987. // Add header marker for main template
  988. $markers['header'] = 'Connect to your database host';
  989. // Define the markers content for the subpart
  990. $step2SubPartMarkers = array(
  991. 'step' => $this->step + 1,
  992. 'action' => htmlspecialchars($this->action),
  993. 'encryptionKey' => $this->createEncryptionKey(),
  994. 'branch' => TYPO3_branch,
  995. 'labelUsername' => 'Username',
  996. 'username' => htmlspecialchars(TYPO3_db_username),
  997. 'labelPassword' => 'Password',
  998. 'password' => htmlspecialchars(TYPO3_db_password),
  999. 'labelHost' => 'Host',
  1000. 'host' => TYPO3_db_host ? htmlspecialchars(TYPO3_db_host) : 'localhost',
  1001. 'continue' => 'Continue',
  1002. '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.'
  1003. );
  1004. // Add step marker for main template
  1005. $markers['step'] = t3lib_parsehtml::substituteMarkerArray(
  1006. $step2SubPart,
  1007. $step2SubPartMarkers,
  1008. '###|###',
  1009. TRUE,
  1010. FALSE
  1011. );
  1012. break;
  1013. case 3:
  1014. // Add header marker for main template
  1015. $markers['header'] = 'Select database';
  1016. // There should be a database host connection at this point
  1017. if ($result = $GLOBALS['TYPO3_DB']->sql_pconnect(
  1018. TYPO3_db_host, TYPO3_db_username, TYPO3_db_password
  1019. )) {
  1020. // Get the subpart for the third step
  1021. $step3SubPart = t3lib_parsehtml::getSubpart(
  1022. $templateFile, '###STEP3###'
  1023. );
  1024. // Get the subpart for the database options
  1025. $step3DatabaseOptionsSubPart = t3lib_parsehtml::getSubpart(
  1026. $step3SubPart, '###DATABASEOPTIONS###'
  1027. );
  1028. $dbArr = $this->getDatabaseList();
  1029. $dbIncluded = 0;
  1030. $step3DatabaseOptions = array();
  1031. foreach ($dbArr as $dbname) {
  1032. // Define the markers content for database options
  1033. $step3DatabaseOptionMarkers = array(
  1034. 'databaseValue' => htmlspecialchars($dbname),
  1035. 'databaseSelected' => $dbname == TYPO3_db ? 'selected="selected"' : '',
  1036. 'databaseName' => htmlspecialchars($dbname)
  1037. );
  1038. // Add the option HTML to an array
  1039. $step3DatabaseOptions[] = t3lib_parsehtml::substituteMarkerArray(
  1040. $step3DatabaseOptionsSubPart,
  1041. $step3DatabaseOptionMarkers,
  1042. '###|###',
  1043. TRUE,
  1044. TRUE
  1045. );
  1046. if ($dbname==TYPO3_db) $dbIncluded=1;
  1047. }
  1048. if (!$dbIncluded && TYPO3_db) {
  1049. // // Define the markers content when no access
  1050. $step3DatabaseOptionMarkers = array(
  1051. 'databaseValue' => htmlspecialchars(TYPO3_db),
  1052. 'databaseSelected' => 'selected="selected"',
  1053. 'databaseName' => htmlspecialchars(TYPO3_db) . ' (NO ACCESS!)'
  1054. );
  1055. // Add the option HTML to an array
  1056. $step3DatabaseOptions[] = t3lib_parsehtml::substituteMarkerArray(
  1057. $step3DatabaseOptionsSubPart,
  1058. $step3DatabaseOptionMarkers,
  1059. '###|###',
  1060. TRUE,
  1061. TRUE
  1062. );
  1063. }
  1064. // Substitute the subpart for the database options
  1065. $content = t3lib_parsehtml::substituteSubpart(
  1066. $step3SubPart,
  1067. '###DATABASEOPTIONS###',
  1068. implode(LF, $step3DatabaseOptions)
  1069. );
  1070. // Define the markers content
  1071. $step3SubPartMarkers = array(
  1072. 'step' => $this->step + 1,
  1073. 'llOptions' => 'You have two options:',
  1074. 'action' => htmlspecialchars($this->action),
  1075. 'llOption1' => 'Create a new database (recommended):',
  1076. 'llRemark1' => 'Enter a name for your TYPO3 database.',
  1077. 'llOption2' => 'Select an EMPTY existing database:',
  1078. 'llRemark2' => 'Any tables used by TYPO3 will be overwritten.',
  1079. 'continue' => 'Continue'
  1080. );
  1081. // Add step marker for main template
  1082. $markers['step'] = t3lib_parsehtml::substituteMarkerArray(
  1083. $content,
  1084. $step3SubPartMarkers,
  1085. '###|###',
  1086. TRUE,
  1087. TRUE
  1088. );
  1089. } else {
  1090. // Add step marker for main template when no connection
  1091. $markers['step'] = $error_missingConnect;
  1092. }
  1093. break;
  1094. case 4:
  1095. // Add header marker for main template
  1096. $markers['header'] = 'Import the Database Tables';
  1097. // There should be a database host connection at this point
  1098. if ($result = $GLOBALS['TYPO3_DB']->sql_pconnect(
  1099. TYPO3_db_host, TYPO3_db_username, TYPO3_db_password
  1100. )) {
  1101. // The selected database should be accessible
  1102. if ($GLOBALS['TYPO3_DB']->sql_select_db(TYPO3_db)) {
  1103. // Get the subpart for the fourth step
  1104. $step4SubPart = t3lib_parsehtml::getSubpart(
  1105. $templateFile, '###STEP4###'
  1106. );
  1107. // Get the subpart for the database type options
  1108. $step4DatabaseTypeOptionsSubPart = t3lib_parsehtml::getSubpart(
  1109. $step4SubPart, '###DATABASETYPEOPTIONS###'
  1110. );
  1111. $sFiles = t3lib_div::getFilesInDir(PATH_typo3conf,'sql',1,1);
  1112. // Check if default database scheme "database.sql" already exists, otherwise create it
  1113. if (!strstr(implode(',',$sFiles).',', '/database.sql,')) {
  1114. array_unshift($sFiles,'Default TYPO3 Tables');
  1115. }
  1116. $step4DatabaseTypeOptions = array();
  1117. foreach ($sFiles as $f) {
  1118. if ($f=='Default TYPO3 Tables') $key='CURRENT_TABLES+STATIC';
  1119. else $key=htmlspecialchars($f);
  1120. // Define the markers content for database type subpart
  1121. $step4DatabaseTypeOptionMarkers = array(
  1122. 'databaseTypeValue' => 'import|' . $key,
  1123. 'databaseName' => htmlspecialchars(basename($f))
  1124. );
  1125. // Add the option HTML to an array
  1126. $step4DatabaseTypeOptions[] = t3lib_parsehtml::substituteMarkerArray(
  1127. $step4DatabaseTypeOptionsSubPart,
  1128. $step4DatabaseTypeOptionMarkers,
  1129. '###|###',
  1130. TRUE,
  1131. FALSE
  1132. );
  1133. }
  1134. // Substitute the subpart for the database type options
  1135. $content = t3lib_parsehtml::substituteSubpart(
  1136. $step4SubPart,
  1137. '###DATABASETYPEOPTIONS###',
  1138. implode(LF, $step4DatabaseTypeOptions)
  1139. );
  1140. // Define the markers content
  1141. $step4SubPartMarkers = array(
  1142. 'llSummary' => 'Database summary:',
  1143. 'llUsername' => 'Username:',
  1144. 'username' => htmlspecialchars(TYPO3_db_username),
  1145. 'llHost' => 'Host:',
  1146. 'host' => htmlspecialchars(TYPO3_db_host),
  1147. 'llDatabase' => 'Database:',
  1148. 'database' => htmlspecialchars(TYPO3_db),
  1149. 'llNumberTables' => 'Number of tables:',
  1150. 'numberTables' => count($whichTables),
  1151. 'action' => htmlspecialchars($this->action),
  1152. 'llDatabaseType' => 'Select database contents:',
  1153. 'label' => 'Import database'
  1154. );
  1155. // Add step marker for main template
  1156. $markers['step'] = t3lib_parsehtml::substituteMarkerArray(
  1157. $content,
  1158. $step4SubPartMarkers,
  1159. '###|###',
  1160. TRUE,
  1161. TRUE
  1162. );
  1163. } else {
  1164. // Add step marker for main template when no database
  1165. $markers['step'] = $error_missingDB;
  1166. }
  1167. } else {
  1168. // Add step marker for main template when no connection
  1169. $markers['step'] = $error_missingConnect;
  1170. }
  1171. break;
  1172. case 'go':
  1173. // Add header marker for main template
  1174. $markers['header'] = 'Congratulations!';
  1175. // There should be a database host connection at this point
  1176. if ($result = $GLOBALS['TYPO3_DB']->sql_pconnect(
  1177. TYPO3_db_host, TYPO3_db_username, TYPO3_db_password
  1178. )) {
  1179. // The selected database should be accessible
  1180. if ($GLOBALS['TYPO3_DB']->sql_select_db(TYPO3_db)) {
  1181. // The database should contain tables
  1182. if (count($whichTables)) {
  1183. // Get the subpart for the go step
  1184. $stepGoSubPart = t3lib_parsehtml::getSubpart(
  1185. $templateFile, '###STEPGO###'
  1186. );
  1187. // Define the markers content
  1188. $stepGoSubPartMarkers = array(
  1189. 'messageBasicFinished' => $this->messageBasicFinished(),
  1190. 'llImportant' => 'Important Security Warning',
  1191. 'securityRisk' => $this->securityRisk(),
  1192. 'llSwitchMode' => '
  1193. <a href="' . $this->scriptSelf . '">
  1194. Change the Install Tool password here
  1195. </a>
  1196. '
  1197. );
  1198. // Add step marker for main template
  1199. $markers['step'] = t3lib_parsehtml::substituteMarkerArray(
  1200. $stepGoSubPart,
  1201. $stepGoSubPartMarkers,
  1202. '###|###',
  1203. TRUE,
  1204. TRUE
  1205. );
  1206. } else {
  1207. // Add step marker for main template when empty database
  1208. $markers['step'] = $error_emptyDB;
  1209. }
  1210. } else {
  1211. // Add step marker for main template when no database
  1212. $markers['step'] = $error_missingDB;
  1213. }
  1214. } else {
  1215. // Add step marker for main template when no connection
  1216. $markers['step'] = $error_missingConnect;
  1217. }
  1218. break;
  1219. }
  1220. }
  1221. // Fill the markers in the template
  1222. $content = t3lib_parsehtml::substituteMarkerArray(
  1223. $template,
  1224. $markers,
  1225. '###|###',
  1226. TRUE,
  1227. FALSE
  1228. );
  1229. return $content;
  1230. }
  1231. /**
  1232. * Calling the functions that checks the system
  1233. *
  1234. * @return void
  1235. */
  1236. function checkTheConfig() {
  1237. // Order important:
  1238. $this->checkDirs();
  1239. $this->checkConfiguration();
  1240. $this->checkExtensions();
  1241. if (TYPO3_OS=='WIN') {
  1242. $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\\');
  1243. if (!isset($_SERVER['PATH'])) {
  1244. $serverPath = array_change_key_case($_SERVER, CASE_UPPER);
  1245. $paths = array_merge($paths, explode(';', $serverPath['PATH']));
  1246. } else {
  1247. $paths = array_merge($paths, explode(';', $_SERVER['PATH']));
  1248. }
  1249. } else {
  1250. $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/');
  1251. $paths = array_merge($paths, explode(':', $_SERVER['PATH']));
  1252. }
  1253. $paths = array_unique($paths);
  1254. asort($paths);
  1255. if (t3lib_utility_PhpOptions::isSafeModeEnabled()) {
  1256. $paths=array(ini_get('safe_mode_exec_dir'),'/usr/local/php/bin/');
  1257. }
  1258. if ($this->INSTALL['checkIM']['lzw']) {
  1259. $this->checkIMlzw=1;
  1260. }
  1261. if ($this->INSTALL['checkIM']['path']) {
  1262. $paths[]=trim($this->INSTALL['checkIM']['path']);
  1263. }
  1264. if ($this->checkIM) $this->checkImageMagick($paths);
  1265. $this->checkDatabase();
  1266. }
  1267. /**
  1268. * Editing files in typo3conf directory (or elsewhere if enabled)
  1269. *
  1270. * @return void
  1271. */
  1272. function typo3conf_edit() {
  1273. // default:
  1274. $EDIT_path = PATH_typo3conf;
  1275. if ($this->allowFileEditOutsite_typo3conf_dir && $this->INSTALL['FILE']['EDIT_path']) {
  1276. if (t3lib_div::validPathStr($this->INSTALL['FILE']['EDIT_path']) && substr($this->INSTALL['FILE']['EDIT_path'],-1)=='/') {
  1277. $tmp_path = PATH_site.$this->INSTALL['FILE']['EDIT_path'];
  1278. if (is_dir($tmp_path)) {
  1279. $EDIT_path=$tmp_path;
  1280. } else {
  1281. $this->errorMessages[] = '
  1282. \'' . $tmp_path . '\' was not directory
  1283. ';
  1284. }
  1285. } else {
  1286. $this->errorMessages[] = '
  1287. Bad directory name (must be like t3lib/ or media/script/)
  1288. ';
  1289. }
  1290. }
  1291. $headCode = 'Edit files in '.basename($EDIT_path).'/';
  1292. $messages = '';
  1293. if ($this->INSTALL['SAVE_FILE']) {
  1294. $save_to_file = $this->INSTALL['FILE']['name'];
  1295. if (@is_file($save_to_file)) {
  1296. $save_to_file_md5 = md5($save_to_file);
  1297. 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')) {
  1298. $this->INSTALL['typo3conf_files'] = $save_to_file;
  1299. $save_fileContent = $this->INSTALL['FILE'][$save_to_file_md5];
  1300. if ($this->INSTALL['FILE']['win_to_unix_br']) {
  1301. $save_fileContent = str_replace(CRLF, LF, $save_fileContent);
  1302. }
  1303. $backupFile = $this->getBackupFilename($save_to_file);
  1304. if ($this->INSTALL['FILE']['backup']) {
  1305. if (@is_file($backupFile)) { unlink($backupFile); }
  1306. rename($save_to_file,$backupFile);
  1307. $messages .= '
  1308. Backup written to <strong>' . $backupFile . '</strong>
  1309. <br />
  1310. ';
  1311. }
  1312. t3lib_div::writeFile($save_to_file,$save_fileContent);
  1313. $messages .= '
  1314. File saved: <strong>' . $save_to_file . '</strong>
  1315. <br />
  1316. MD5-sum: ' . $this->INSTALL['FILE']['prevMD5'] . ' (prev)
  1317. <br />
  1318. MD5-sum: ' . md5($save_fileContent) . ' (new)
  1319. <br />
  1320. ';
  1321. }
  1322. }
  1323. }
  1324. // Filelist:
  1325. // Get the template file
  1326. $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'Typo3ConfEdit.html');
  1327. // Get the template part from the file
  1328. $template = t3lib_parsehtml::getSubpart($templateFile, '###TEMPLATE###');
  1329. // Get the subpart for the files
  1330. $filesSubpart = t3lib_parsehtml::getSubpart($template, '###FILES###');
  1331. $files = array();
  1332. $typo3conf_files = t3lib_div::getFilesInDir($EDIT_path,'',1,1);
  1333. $fileFound = 0;
  1334. foreach ($typo3conf_files as $k => $file) {
  1335. // Delete temp_CACHED files if option is set
  1336. if ( $this->INSTALL['delTempCached'] && preg_match('|/temp_CACHED_[a-z0-9_]+\.php|', $file)) {
  1337. unlink($file);
  1338. continue;
  1339. }
  1340. if ($this->INSTALL['typo3conf_files'] && !strcmp($this->INSTALL['typo3conf_files'],$file)) {
  1341. $fileFound = 1;
  1342. }
  1343. // Define the markers content for the files subpart
  1344. $filesMarkers = array(
  1345. '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',
  1346. 'fileName' => basename($file),
  1347. 'fileSize' => t3lib_div::formatSize(filesize($file)),
  1348. 'class' => $this->INSTALL['typo3conf_files'] && !strcmp($this->INSTALL['typo3conf_files'], $file) ? 'class="act"' : ''
  1349. );
  1350. // Fill the markers in the subpart
  1351. $files[] = t3lib_parsehtml::substituteMarkerArray(
  1352. $filesSubpart,
  1353. $filesMarkers,
  1354. '###|###',
  1355. TRUE,
  1356. FALSE
  1357. );
  1358. }
  1359. if ($fileFound && @is_file($this->INSTALL['typo3conf_files'])) {
  1360. $backupFile = $this->getBackupFilename($this->INSTALL['typo3conf_files']);
  1361. $fileContent = t3lib_div::getUrl($this->INSTALL['typo3conf_files']);
  1362. // Get the subpart to edit the files
  1363. $fileEditTemplate = t3lib_parsehtml::getSubpart($template, '###FILEEDIT###');
  1364. $allowFileEditOutsideTypo3ConfDirSubPart = '';
  1365. if (substr($this->INSTALL['typo3conf_files'], -1) != '~' && !strstr($this->INSTALL['typo3conf_files'], '_bak')) {
  1366. // Get the subpart to show the save button
  1367. $showSaveButtonSubPart = t3lib_parsehtml::getSubpart($fileEditTemplate, '###SHOWSAVEBUTTON###');
  1368. }
  1369. if ($this->allowFileEditOutsite_typo3conf_dir) {
  1370. // Get the subpart to show if files are allowed outside the directory typo3conf
  1371. $allowFileEditOutsideTypo3ConfDirSubPart = t3lib_parsehtml::getSubpart($fileEditTemplate, '###ALLOWFILEEDITOUTSIDETYPO3CONFDIR###');
  1372. }
  1373. // Substitute the subpart for the save button
  1374. $fileEditContent = t3lib_parsehtml::substituteSubpart(
  1375. $fileEditTemplate,
  1376. '###SHOWSAVEBUTTON###',
  1377. $showSaveButtonSubPart
  1378. );
  1379. // Substitute the subpart to show if files are allowed outside the directory typo3conf
  1380. $fileEditContent = t3lib_parsehtml::substituteSubpart(
  1381. $fileEditContent,
  1382. '###ALLOWFILEEDITOUTSIDETYPO3CONFDIR###',
  1383. $allowFileEditOutsideTypo3ConfDirSubPart
  1384. );
  1385. // Define the markers content for subpart to edit the files
  1386. $fileEditMarkers = array(
  1387. 'messages' => !empty($messages) ? '<p class="typo3-message message-warning">' . $messages . '</p>' : '',
  1388. 'action' => $this->action . '#fileEditHeader',
  1389. 'saveFile' => 'Save file',
  1390. 'close' => 'Close',
  1391. 'llEditing' => 'Editing file:',
  1392. 'file' => $this->INSTALL['typo3conf_files'],
  1393. 'md5Sum' => 'MD5-sum: ' . md5($fileContent),
  1394. 'fileName' => $this->INSTALL['typo3conf_files'],
  1395. 'fileEditPath' => $this->INSTALL['FILE']['EDIT_path'],
  1396. 'filePreviousMd5' => md5($fileContent),
  1397. 'fileMd5' => md5($this->INSTALL['typo3conf_files']),
  1398. 'fileContent' => t3lib_div::formatForTextarea($fileContent),
  1399. 'winToUnixBrChecked' => TYPO3_OS == 'WIN' ? '' : 'checked="checked"',
  1400. 'winToUnixBr' => 'Convert Windows linebreaks (13-10) to Unix (10)',
  1401. 'backupChecked' => @is_file($backupFile) ? 'checked="checked"' : '',
  1402. 'backup' => 'Make backup copy (rename to ' . basename($backupFile) . ')'
  1403. );
  1404. // Fill the markers in the subpart to edit the files
  1405. $fileEditContent = t3lib_parsehtml::substituteMarkerArray(
  1406. $fileEditContent,
  1407. $fileEditMarkers,
  1408. '###|###',
  1409. TRUE,
  1410. FALSE
  1411. );
  1412. }
  1413. if ($this->allowFileEditOutsite_typo3conf_dir) {
  1414. // Get the subpart to show if files are allowed outside the directory typo3conf
  1415. $allowFileEditOutsideTypo3ConfDirSubPart = t3lib_parsehtml::getSubpart($template, '###ALLOWFILEEDITOUTSIDETYPO3CONFDIR###');
  1416. // Define the markers content
  1417. $allowFileEditOutsideTypo3ConfDirMarkers = array(
  1418. 'action' => $this->action,
  1419. 'pathSite' => PATH_site,
  1420. 'editPath' => $this->INSTALL['FILE']['EDIT_path'],
  1421. 'set' => 'Set'
  1422. );
  1423. // Fill the markers in the subpart
  1424. $allowFileEditOutsideTypo3ConfDirSubPart = t3lib_parsehtml::substituteMarkerArray(
  1425. $allowFileEditOutsideTypo3ConfDirSubPart,
  1426. $allowFileEditOutsideTypo3ConfDirMarkers,
  1427. '###|###',
  1428. TRUE,
  1429. FALSE
  1430. );
  1431. }
  1432. // Substitute the subpart to edit the file
  1433. $fileListContent = t3lib_parsehtml::substituteSubpart(
  1434. $template,
  1435. '###FILEEDIT###',
  1436. $fileEditContent
  1437. );
  1438. // Substitute the subpart when files can be edited outside typo3conf directory
  1439. $fileListContent = t3lib_parsehtml::substituteSubpart(
  1440. $fileListContent,
  1441. '###ALLOWFILEEDITOUTSIDETYPO3CONFDIR###',
  1442. $allowFileEditOutsideTypo3ConfDirSubPart
  1443. );
  1444. // Substitute the subpart for the files
  1445. $fileListContent = t3lib_parsehtml::substituteSubpart(
  1446. $fileListContent,
  1447. '###FILES###',
  1448. implode(LF, $files)
  1449. );
  1450. // Define the markers content
  1451. $fileListMarkers = array(
  1452. 'editPath' => '(' . $EDIT_path . ')',
  1453. 'deleteTempCachedUrl' => $this->action . '&amp;TYPO3_INSTALL[delTempCached]=1',
  1454. 'deleteTempCached' => 'Delete temp_CACHED* files'
  1455. );
  1456. // Fill the markers
  1457. $fileListContent = t3lib_parsehtml::substituteMarkerArray(
  1458. $fileListContent,
  1459. $fileListMarkers,
  1460. '###|###',
  1461. TRUE,
  1462. FALSE
  1463. );
  1464. // Add the content to the message array
  1465. $this->message($headCode, 'Files in folder', $fileListContent);
  1466. // Output the page
  1467. $this->output($this->outputWrapper($this->printAll()));
  1468. }
  1469. /**
  1470. * Outputs system information
  1471. *
  1472. * @return void
  1473. */
  1474. function phpinformation() {
  1475. $headCode = 'PHP information';
  1476. $sVar = t3lib_div::getIndpEnv('_ARRAY');
  1477. $sVar['CONST: PHP_OS']=PHP_OS;
  1478. $sVar['CONST: TYPO3_OS']=TYPO3_OS;
  1479. $sVar['CONST: PATH_thisScript']=PATH_thisScript;
  1480. $sVar['CONST: php_sapi_name()']=PHP_SAPI;
  1481. $sVar['OTHER: TYPO3_VERSION']=TYPO3_version;
  1482. $sVar['OTHER: PHP_VERSION']=phpversion();
  1483. $sVar['imagecreatefromgif()']=function_exists('imagecreatefromgif');
  1484. $sVar['imagecreatefrompng()']=function_exists('imagecreatefrompng');
  1485. $sVar['imagecreatefromjpeg()']=function_exists('imagecreatefromjpeg');
  1486. $sVar['imagegif()']=function_exists('imagegif');
  1487. $sVar['imagepng()']=function_exists('imagepng');
  1488. $sVar['imagejpeg()']=function_exists('imagejpeg');
  1489. $sVar['imagettftext()']=function_exists('imagettftext');
  1490. $sVar['OTHER: IMAGE_TYPES']=function_exists('imagetypes') ? imagetypes() : 0;
  1491. $sVar['OTHER: memory_limit']=ini_get('memory_limit');
  1492. $gE_keys = explode(',','SERVER_PORT,SERVER_SOFTWARE,GATEWAY_INTERFACE,SCRIPT_NAME,PATH_TRANSLATED');
  1493. foreach ($gE_keys as $k) {
  1494. $sVar['SERVER: '.$k]=$_SERVER[$k];
  1495. }
  1496. $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');
  1497. foreach ($gE_keys as $k) {
  1498. $sVar['T3CV_GFX: '.$k]=$GLOBALS['TYPO3_CONF_VARS']['GFX'][$k];
  1499. }
  1500. $debugInfo = array(
  1501. '### DEBUG SYSTEM INFORMATION - START ###'
  1502. );
  1503. foreach ($sVar as $kkk => $vvv) {
  1504. $debugInfo[]=str_pad(substr($kkk,0,20),20).': '.$vvv;
  1505. }
  1506. $debugInfo[]='### DEBUG SYSTEM INFORMATION - END ###';
  1507. // Get the template file
  1508. $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'PhpInformation.html');
  1509. // Get the template part from the file
  1510. $template = t3lib_parsehtml::getSubpart($templateFile, '###TEMPLATE###');
  1511. // Define the markers content
  1512. $markers = array(
  1513. '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!',
  1514. 'debugInfo' => t3lib_div::formatForTextarea(implode(LF, $debugInfo))
  1515. );
  1516. // Fill the markers
  1517. $content = t3lib_parsehtml::substituteMarkerArray(
  1518. $template,
  1519. $markers,
  1520. '###|###',
  1521. TRUE,
  1522. FALSE
  1523. );
  1524. // Add the content to the message array
  1525. $this->message($headCode, 'DEBUG information', $content);
  1526. // Start with various server information
  1527. $getEnvArray = array();
  1528. $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');
  1529. foreach ($gE_keys as $k) {
  1530. $getEnvArray[$k] = getenv($k);
  1531. }
  1532. $this->message($headCode, 't3lib_div::getIndpEnv()', $this->viewArray(t3lib_div::getIndpEnv('_ARRAY')));
  1533. $this->message($headCode, 'getenv()', $this->viewArray($getEnvArray));
  1534. $this->message($headCode, '_ENV', $this->viewArray($_ENV));
  1535. $this->message($headCode, '_SERVER', $this->viewArray($_SERVER));
  1536. $this->message($headCode, '_COOKIE', $this->viewArray($_COOKIE));
  1537. $this->message($headCode, '_GET', $this->viewArray($_GET));
  1538. // Start with the phpinfo() part
  1539. ob_start();
  1540. phpinfo();
  1541. $contents = explode('<body>',ob_get_contents());
  1542. ob_end_clean();
  1543. $contents = explode('</body>',$contents[1]);
  1544. // Do code cleaning: phpinfo() is not XHTML1.1 compliant
  1545. $phpinfo = str_replace('<font', '<span', $contents[0]);
  1546. $phpinfo = str_replace('</font', '</span', $phpinfo);
  1547. $phpinfo = str_replace('<img border="0"', '<img', $phpinfo);
  1548. $phpinfo = str_replace('<a name=', '<a id=', $phpinfo);
  1549. // Add phpinfo() to the message array
  1550. $this->message($headCode, 'phpinfo()', '
  1551. <div class="phpinfo">
  1552. ' . $phpinfo . '
  1553. </div>
  1554. ');
  1555. // Output the page
  1556. $this->output($this->outputWrapper($this->printAll()));
  1557. }
  1558. /*******************************
  1559. *
  1560. * cleanup manager
  1561. *
  1562. *******************************/
  1563. /**
  1564. * Provides a tool cleaning up various tables in the database
  1565. *
  1566. * @return void
  1567. * @author Robert Lemke <rl@robertlemke.de>
  1568. * @todo Add more functionality ...
  1569. */
  1570. function cleanupManager() {
  1571. $headCode = 'Clean up your TYPO3 installation';
  1572. $this->message($headCode, 'Database cache tables', '
  1573. <p>
  1574. <strong>Clear cached image sizes</strong>
  1575. <br />
  1576. Clears the cache used for memorizing sizes of all images used in
  1577. your website. This information is cached in order to gain
  1578. performance and will be stored each time a new image is being
  1579. displayed in the frontend.
  1580. </p>
  1581. <p>
  1582. You should <em>Clear All Cache</em> in the backend after
  1583. clearing this cache.
  1584. </p>
  1585. ');
  1586. $tables = $this->getListOfTables();
  1587. $action = $this->INSTALL['cleanup_type'];
  1588. if (($action == 'cache_imagesizes' || $action == 'all') && isset ($tables['cache_imagesizes'])) {
  1589. $GLOBALS['TYPO3_DB']->exec_TRUNCATEquery('cache_imagesizes');
  1590. }
  1591. $cleanupType = array (
  1592. 'all' => 'Clean up everything',
  1593. );
  1594. // Get cache_imagesizes info
  1595. if (isset ($tables['cache_imagesizes'])) {
  1596. $cleanupType['cache_imagesizes'] = 'Clear cached image sizes only';
  1597. $cachedImageSizesCounter = intval($GLOBALS['TYPO3_DB']->exec_SELECTcountRows('*', 'cache_imagesizes'));
  1598. } else {
  1599. $this->message($headCode, 'Table cache_imagesizes does not exist!', '
  1600. <p>
  1601. The table cache_imagesizes was not found. Please check your
  1602. database settings in Basic Configuration and compare your
  1603. table definition with the Database Analyzer.
  1604. </p>
  1605. ', 2);
  1606. $cachedImageSizesCounter = 'unknown';
  1607. }
  1608. // Get the template file
  1609. $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'CleanUpManager.html');
  1610. // Get the template part from the file
  1611. $template = t3lib_parsehtml::getSubpart($templateFile, '###TEMPLATE###');
  1612. // Get the subpart for the 'Clean up' dropdown
  1613. $cleanUpOptionsSubpart = t3lib_parsehtml::getSubpart($template, '###CLEANUPOPTIONS###');
  1614. $cleanUpOptions = array();
  1615. foreach ($cleanupType as $cleanUpKey => $cleanUpValue) {
  1616. // Define the markers content
  1617. $cleanUpMarkers = array(
  1618. 'value' => htmlspecialchars($cleanUpKey),
  1619. 'data' => htmlspecialchars($cleanUpValue)
  1620. );
  1621. // Fill the markers in the subpart
  1622. $cleanUpOptions[] = t3lib_parsehtml::substituteMarkerArray(
  1623. $cleanUpOptionsSubpart,
  1624. $cleanUpMarkers,
  1625. '###|###',
  1626. TRUE,
  1627. FALSE
  1628. );
  1629. }
  1630. // Substitute the subpart for the 'Clean up' dropdown
  1631. $content = t3lib_parsehtml::substituteSubpart(
  1632. $template,
  1633. '###CLEANUPOPTIONS###',
  1634. implode(LF, $cleanUpOptions)
  1635. );
  1636. // Define the markers content
  1637. $markers = array(
  1638. 'numberCached' => 'Number cached image sizes:',
  1639. 'number' => $cachedImageSizesCounter,
  1640. 'action' => $this->action,
  1641. 'cleanUp' => 'Clean up',
  1642. 'execute' => 'Execute'
  1643. );
  1644. // Fill the markers
  1645. $content = t3lib_parsehtml::substituteMarkerArray(
  1646. $content,
  1647. $markers,
  1648. '###|###',
  1649. TRUE,
  1650. FALSE
  1651. );
  1652. // Add the content to the message array
  1653. $this->message($headCode, 'Statistics', $content, 1);
  1654. $this->message($headCode, 'typo3temp/ folder', '
  1655. <p>
  1656. TYPO3 uses this directory for temporary files, mainly processed
  1657. and cached images.
  1658. <br />
  1659. The filenames are very cryptic; They are unique representations
  1660. of the file properties made by md5-hashing a serialized array
  1661. with information.
  1662. <br />
  1663. Anyway this directory may contain many thousand files and a lot
  1664. of them may be of no use anymore.
  1665. </p>
  1666. <p>
  1667. With this test you can delete the files in this folder. When you
  1668. do that, you should also clear the cache database tables
  1669. afterwards.
  1670. </p>
  1671. ');
  1672. if (!$this->config_array['dir_typo3temp']) {
  1673. $this->message('typo3temp/ directory', 'typo3temp/ not writable!', '
  1674. <p>
  1675. You must make typo3temp/ write enabled before you can
  1676. proceed with this test.
  1677. </p>
  1678. ', 2);
  1679. $this->output($this->outputWrapper($this->printAll()));
  1680. return;
  1681. }
  1682. // Run through files
  1683. $fileCounter = 0;
  1684. $deleteCounter = 0;
  1685. $criteriaMatch = 0;
  1686. $tmap=array('day'=>1, 'week'=>7, 'month'=>30);
  1687. $tt = $this->INSTALL['typo3temp_delete'];
  1688. $subdir = $this->INSTALL['typo3temp_subdir'];
  1689. if (strlen($subdir) && !preg_match('/^[[:alnum:]_]+\/$/',$subdir)) die('subdir "'.$subdir.'" was not allowed!');
  1690. $action = $this->INSTALL['typo3temp_action'];
  1691. $d = @dir($this->typo3temp_path.$subdir);
  1692. if (is_object($d)) {
  1693. while($entry=$d->read()) {
  1694. $theFile = $this->typo3temp_path.$subdir.$entry;
  1695. if (@is_file($theFile)) {
  1696. $ok = 0;
  1697. $fileCounter++;
  1698. if ($tt) {
  1699. if (t3lib_div::testInt($tt)) {
  1700. if (filesize($theFile) > $tt*1024) $ok=1;
  1701. } else {
  1702. if (fileatime($theFile) < $GLOBALS['EXEC_TIME'] - (intval($tmap[$tt]) * 60 * 60 * 24)) {
  1703. $ok = 1;
  1704. }
  1705. }
  1706. } else {
  1707. $ok = 1;
  1708. }
  1709. if ($ok) {
  1710. $hashPart=substr(basename($theFile),-14,10);
  1711. // This is a kind of check that the file being deleted has a 10 char hash in it
  1712. if (!preg_match('/[^a-f0-9]/',$hashPart) || substr($theFile,-6)==='.cache' || substr($theFile,-4)==='.tbl' || substr(basename($theFile),0,8)==='install_') {
  1713. if ($action && $deleteCounter<$action) {
  1714. $deleteCounter++;
  1715. unlink($theFile);
  1716. } else {
  1717. $criteriaMatch++;
  1718. }
  1719. }
  1720. }
  1721. }
  1722. }
  1723. $d->close();
  1724. }
  1725. // Find sub-dirs:
  1726. $subdirRegistry = array(''=>'');
  1727. $d = @dir($this->typo3temp_path);
  1728. if (is_object($d)) {
  1729. while($entry=$d->read()) {
  1730. $theFile = $entry;
  1731. if (@is_dir($this->typo3temp_path.$theFile) && $theFile!='..' && $theFile!='.') {
  1732. $subdirRegistry[$theFile.'/'] = $theFile.'/ (Files: '.count(t3lib_div::getFilesInDir($this->typo3temp_path.$theFile)).')';
  1733. }
  1734. }
  1735. }
  1736. $deleteType=array(
  1737. '0' => 'All',
  1738. 'day' => 'Last access more than a day ago',
  1739. 'week' => 'Last access more than a week ago',
  1740. 'month' => 'Last access more than a month ago',
  1741. '10' => 'Filesize greater than 10KB',
  1742. '50' => 'Filesize greater than 50KB',
  1743. '100' => 'Filesize greater than 100KB'
  1744. );
  1745. $actionType=array(
  1746. '0' => "Don't delete, just display statistics",
  1747. '100' => 'Delete 100',
  1748. '500' => 'Delete 500',
  1749. '1000' => 'Delete 1000'
  1750. );
  1751. // Get the template file
  1752. $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'Typo3TempManager.html');
  1753. // Get the template part from the file
  1754. $template = t3lib_parsehtml::getSubpart($templateFile, '###TEMPLATE###');
  1755. // Get the subpart for 'Delete files by condition' dropdown
  1756. $deleteOptionsSubpart = t3lib_parsehtml::getSubpart($template, '###DELETEOPTIONS###');
  1757. $deleteOptions = array();
  1758. foreach ($deleteType as $deleteKey => $deleteValue) {
  1759. // Define the markers content
  1760. $deleteMarkers = array(
  1761. 'value' => htmlspecialchars($deleteKey),
  1762. 'selected' => !strcmp($deleteKey, $tt) ? 'selected="selected"' : '',
  1763. 'data' => htmlspecialchars($deleteValue)
  1764. );
  1765. // Fill the markers in the subpart
  1766. $deleteOptions[] = t3lib_parsehtml::substituteMarkerArray(
  1767. $deleteOptionsSubpart,
  1768. $deleteMarkers,
  1769. '###|###',
  1770. TRUE,
  1771. FALSE
  1772. );
  1773. }
  1774. // Substitute the subpart for 'Delete files by condition' dropdown
  1775. $content = t3lib_parsehtml::substituteSubpart(
  1776. $template,
  1777. '###DELETEOPTIONS###',
  1778. implode(LF, $deleteOptions)
  1779. );
  1780. // Get the subpart for 'Number of files at a time' dropdown
  1781. $actionOptionsSubpart = t3lib_parsehtml::getSubpart($template, '###ACTIONOPTIONS###');
  1782. $actionOptions = array();
  1783. foreach ($actionType as $actionKey => $actionValue) {
  1784. // Define the markers content
  1785. $actionMarkers = array(
  1786. 'value' => htmlspecialchars($actionKey),
  1787. 'data' => htmlspecialchars($actionValue)
  1788. );
  1789. // Fill the markers in the subpart
  1790. $actionOptions[] = t3lib_parsehtml::substituteMarkerArray(
  1791. $actionOptionsSubpart,
  1792. $actionMarkers,
  1793. '###|###',
  1794. TRUE,
  1795. FALSE
  1796. );
  1797. }
  1798. // Substitute the subpart for 'Number of files at a time' dropdown
  1799. $content = t3lib_parsehtml::substituteSubpart(
  1800. $content,
  1801. '###ACTIONOPTIONS###',
  1802. implode(LF, $actionOptions)
  1803. );
  1804. // Get the subpart for 'From sub-directory' dropdown
  1805. $subDirectoryOptionsSubpart = t3lib_parsehtml::getSubpart($template, '###SUBDIRECTORYOPTIONS###');
  1806. $subDirectoryOptions = array();
  1807. foreach ($subdirRegistry as $subDirectoryKey => $subDirectoryValue) {
  1808. // Define the markers content
  1809. $subDirectoryMarkers = array(
  1810. 'value' => htmlspecialchars($subDirectoryKey),
  1811. 'selected' => !strcmp($subDirectoryKey, $this->INSTALL['typo3temp_subdir']) ? 'selected="selected"' : '',
  1812. 'data' => htmlspecialchars($subDirectoryValue)
  1813. );
  1814. // Fill the markers in the subpart
  1815. $subDirectoryOptions[] = t3lib_parsehtml::substituteMarkerArray(
  1816. $subDirectoryOptionsSubpart,
  1817. $subDirectoryMarkers,
  1818. '###|###',
  1819. TRUE,
  1820. FALSE
  1821. );
  1822. }
  1823. // Substitute the subpart for 'From sub-directory' dropdown
  1824. $content = t3lib_parsehtml::substituteSubpart(
  1825. $content,
  1826. '###SUBDIRECTORYOPTIONS###',
  1827. implode(LF, $subDirectoryOptions)
  1828. );
  1829. // Define the markers content
  1830. $markers = array(
  1831. 'numberTemporary' => 'Number of temporary files:',
  1832. 'numberMatching' => 'Number matching:',
  1833. 'numberDeleted' => 'Number deleted:',
  1834. 'temporary' => ($fileCounter - $deleteCounter),
  1835. 'matching' => $criteriaMatch,
  1836. 'deleteType' => '<span>' . htmlspecialchars($deleteType[$tt]) . '</span>',
  1837. 'deleted' => $deleteCounter,
  1838. 'deleteCondition' => 'Delete files by condition',
  1839. 'numberFiles' => 'Number of files at a time:',
  1840. 'fromSubdirectory' => 'From sub-directory:',
  1841. 'execute' => 'Execute',
  1842. 'explanation' => '
  1843. <p>
  1844. This tool will delete files only if the last 10 characters
  1845. before the extension (3 chars+\'.\') are hexadecimal valid
  1846. ciphers, which are lowercase a-f and 0-9.
  1847. </p>
  1848. '
  1849. );
  1850. // Fill the markers
  1851. $content = t3lib_parsehtml::substituteMarkerArray(
  1852. $content,
  1853. $markers,
  1854. '###|###',
  1855. TRUE,
  1856. FALSE
  1857. );
  1858. // Add the content to the message array
  1859. $this->message($headCode, 'Statistics', $content, 1);
  1860. // Output the page
  1861. $this->output($this->outputWrapper($this->printAll()));
  1862. }
  1863. /*******************************
  1864. *
  1865. * CONFIGURATION FORM
  1866. *
  1867. ********************************/
  1868. /**
  1869. * Creating the form for editing the TYPO3_CONF_VARS options.
  1870. *
  1871. * @param string $type If get_form, display form, otherwise checks and store in localconf.php
  1872. * @return void
  1873. */
  1874. function generateConfigForm($type='') {
  1875. $default_config_content = t3lib_div::getUrl(PATH_t3lib.'config_default.php');
  1876. $commentArr = $this->getDefaultConfigArrayComments($default_config_content);
  1877. switch($type) {
  1878. case 'get_form':
  1879. // Get the template file
  1880. $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'GenerateConfigForm.html');
  1881. // Get the template part from the file
  1882. $template = t3lib_parsehtml::getSubpart($templateFile, '###TEMPLATE###');
  1883. foreach ($GLOBALS['TYPO3_CONF_VARS'] as $k => $va) {
  1884. $ext='['.$k.']';
  1885. $this->message($ext, '$TYPO3_CONF_VARS[\''.$k.'\']',$commentArr[0][$k],1);
  1886. foreach ($va as $vk => $value) {
  1887. $textAreaSubpart = '';
  1888. $booleanSubpart = '';
  1889. $textLineSubpart = '';
  1890. $description = trim($commentArr[1][$k][$vk]);
  1891. $isTextarea = preg_match('/^(<.*?>)?string \(textarea\)/i', $description) ? TRUE : FALSE;
  1892. $doNotRender = preg_match('/^(<.*?>)?string \(exclude\)/i', $description) ? TRUE : FALSE;
  1893. if (!is_array($value) && !$doNotRender && ($this->checkForBadString($value) || $isTextarea)) {
  1894. $k2 = '['.$vk.']';
  1895. if ($isTextarea) {
  1896. // Get the subpart for a textarea
  1897. $textAreaSubpart = t3lib_parsehtml::getSubpart($template, '###TEXTAREA###');
  1898. // Define the markers content
  1899. $textAreaMarkers = array(
  1900. 'id' => $k . '-' . $vk,
  1901. 'name' => 'TYPO3_INSTALL[extConfig]['.$k.']['.$vk.']',
  1902. 'value' => str_replace(array("'.chr(10).'", "' . LF . '"), array(LF, LF), $value)
  1903. );
  1904. $value = str_replace(array("'.chr(10).'", "' . LF . '"), array(' | ', ' | '), $value);
  1905. // Fill the markers in the subpart
  1906. $textAreaSubpart = t3lib_parsehtml::substituteMarkerArray(
  1907. $textAreaSubpart,
  1908. $textAreaMarkers,
  1909. '###|###',
  1910. TRUE,
  1911. FALSE
  1912. );
  1913. } elseif (preg_match('/^(<.*?>)?boolean/i', $description)) {
  1914. // Get the subpart for a checkbox
  1915. $booleanSubpart = t3lib_parsehtml::getSubpart($template, '###BOOLEAN###');
  1916. // Define the markers content
  1917. $booleanMarkers = array(
  1918. 'id' => $k . '-' . $vk,
  1919. 'name' => 'TYPO3_INSTALL[extConfig]['.$k.']['.$vk.']',
  1920. 'value' => $value && strcmp($value, '0') ? $value : 1,
  1921. 'checked' => $value ? 'checked="checked"' : ''
  1922. );
  1923. // Fill the markers in the subpart
  1924. $booleanSubpart = t3lib_parsehtml::substituteMarkerArray(
  1925. $booleanSubpart,
  1926. $booleanMarkers,
  1927. '###|###',
  1928. TRUE,
  1929. FALSE
  1930. );
  1931. } else {
  1932. // Get the subpart for an input text field
  1933. $textLineSubpart = t3lib_parsehtml::getSubpart($template, '###TEXTLINE###');
  1934. // Define the markers content
  1935. $textLineMarkers = array(
  1936. 'id' => $k . '-' . $vk,
  1937. 'name' => 'TYPO3_INSTALL[extConfig]['.$k.']['.$vk.']',
  1938. 'value' => $value
  1939. );
  1940. // Fill the markers in the subpart
  1941. $textLineSubpart = t3lib_parsehtml::substituteMarkerArray(
  1942. $textLineSubpart,
  1943. $textLineMarkers,
  1944. '###|###',
  1945. TRUE,
  1946. FALSE
  1947. );
  1948. }
  1949. // Substitute the subpart for a textarea
  1950. $content = t3lib_parsehtml::substituteSubpart(
  1951. $template,
  1952. '###TEXTAREA###',
  1953. $textAreaSubpart
  1954. );
  1955. // Substitute the subpart for a checkbox
  1956. $content = t3lib_parsehtml::substituteSubpart(
  1957. $content,
  1958. '###BOOLEAN###',
  1959. $booleanSubpart
  1960. );
  1961. // Substitute the subpart for an input text field
  1962. $content = t3lib_parsehtml::substituteSubpart(
  1963. $content,
  1964. '###TEXTLINE###',
  1965. $textLineSubpart
  1966. );
  1967. // Define the markers content
  1968. $markers = array(
  1969. 'description' => $description,
  1970. 'key' => '[' . $k . '][' . $vk . ']',
  1971. 'label' => htmlspecialchars(t3lib_div::fixed_lgd_cs($value, 40))
  1972. );
  1973. // Fill the markers
  1974. $content = t3lib_parsehtml::substituteMarkerArray(
  1975. $content,
  1976. $markers,
  1977. '###|###',
  1978. TRUE,
  1979. FALSE
  1980. );
  1981. // Add the content to the message array
  1982. $this->message($ext, $k2, $content);
  1983. }
  1984. }
  1985. }
  1986. break;
  1987. default:
  1988. if (is_array($this->INSTALL['extConfig'])) {
  1989. $lines = $this->writeToLocalconf_control();
  1990. foreach ($this->INSTALL['extConfig'] as $k => $va) {
  1991. if (is_array($GLOBALS['TYPO3_CONF_VARS'][$k])) {
  1992. foreach ($va as $vk => $value) {
  1993. if (isset($GLOBALS['TYPO3_CONF_VARS'][$k][$vk])) {
  1994. $doit=1;
  1995. if ($k=='BE' && $vk=='installToolPassword') {
  1996. if ($value) {
  1997. if (isset($_POST['installToolPassword_check'])) {
  1998. if (!$this->formProtection->validateToken(
  1999. (string) $_POST['formToken'],
  2000. 'installToolPassword',
  2001. 'change'
  2002. )) {
  2003. $doit = FALSE;
  2004. break;
  2005. }
  2006. if (!t3lib_div::_GP('installToolPassword_check')
  2007. || strcmp(t3lib_div::_GP('installToolPassword_check'), $value)
  2008. ) {
  2009. $doit = FALSE;
  2010. $this->errorMessages[]
  2011. = 'The two passwords did not ' .
  2012. 'match! The password was not changed.';
  2013. }
  2014. }
  2015. if (t3lib_div::_GP('installToolPassword_md5')) $value =md5($value);
  2016. } else $doit=0;
  2017. }
  2018. $description = trim($commentArr[1][$k][$vk]);
  2019. if (preg_match('/^string \(textarea\)/i', $description)) {
  2020. // Force Unix linebreaks in textareas
  2021. $value = str_replace(CR, '', $value);
  2022. // Preserve linebreaks
  2023. $value = str_replace(LF, "' . LF . '", $value);
  2024. }
  2025. if (preg_match('/^boolean/i', $description)) {
  2026. // When submitting settings in the Install Tool, values that default to "false" or "true"
  2027. // in config_default.php will be sent as "0" resp. "1". Therefore, reset the values
  2028. // to their boolean equivalent.
  2029. if ($GLOBALS['TYPO3_CONF_VARS'][$k][$vk] === false && $value === '0') {
  2030. $value = false;
  2031. } elseif ($GLOBALS['TYPO3_CONF_VARS'][$k][$vk] === true && $value === '1') {
  2032. $value = true;
  2033. }
  2034. }
  2035. if ($doit && strcmp($GLOBALS['TYPO3_CONF_VARS'][$k][$vk],$value)) $this->setValueInLocalconfFile($lines, '$TYPO3_CONF_VARS[\''.$k.'\'][\''.$vk.'\']', $value);
  2036. }
  2037. }
  2038. }
  2039. }
  2040. $this->writeToLocalconf_control($lines);
  2041. }
  2042. break;
  2043. }
  2044. }
  2045. /**
  2046. * Make an array of the comments in the t3lib/config_default.php file
  2047. *
  2048. * @param string $string The contents of the config_default.php file
  2049. * @param array $mainArray
  2050. * @param array $commentArray
  2051. * @return array
  2052. */
  2053. function getDefaultConfigArrayComments($string,$mainArray=array(),$commentArray=array()) {
  2054. $lines = explode(LF, $string);
  2055. $in=0;
  2056. $mainKey='';
  2057. foreach ($lines as $lc) {
  2058. $lc = trim($lc);
  2059. if ($in) {
  2060. if (!strcmp($lc,');')) {
  2061. $in=0;
  2062. } else {
  2063. if (preg_match('/["\']([[:alnum:]_-]*)["\'][[:space:]]*=>(.*)/i',$lc,$reg)) {
  2064. preg_match('/,[\t\s]*\/\/(.*)/i',$reg[2],$creg);
  2065. $theComment = trim($creg[1]);
  2066. if (substr(strtolower(trim($reg[2])),0,5)=='array' && !strcmp($reg[1],strtoupper($reg[1]))) {
  2067. $mainKey=trim($reg[1]);
  2068. $mainArray[$mainKey]=$theComment;
  2069. } elseif ($mainKey) {
  2070. $commentArray[$mainKey][$reg[1]]=$theComment;
  2071. }
  2072. }
  2073. }
  2074. }
  2075. if (!strcmp($lc, '$TYPO3_CONF_VARS = array(')) {
  2076. $in=1;
  2077. }
  2078. }
  2079. return array($mainArray,$commentArray);
  2080. }
  2081. /*******************************
  2082. *
  2083. * CHECK CONFIGURATION FUNCTIONS
  2084. *
  2085. *******************************/
  2086. /**
  2087. * Checking php.ini configuration and set appropriate messages and flags.
  2088. *
  2089. * @return void
  2090. */
  2091. function checkConfiguration() {
  2092. $ext='php.ini configuration checked';
  2093. $this->message($ext);
  2094. // *****************
  2095. // Incoming values:
  2096. // *****************
  2097. // Includepath
  2098. $incPaths = t3lib_div::trimExplode(TYPO3_OS=='WIN'?';':':', ini_get('include_path'));
  2099. if (!in_array('.',$incPaths)) {
  2100. $this->message($ext, 'Current directory (./) is not in include path!', '
  2101. <p>
  2102. <em>include_path=' . ini_get('include_path') . '</em>
  2103. <br />
  2104. Normally the current path, \'.\', is included in the
  2105. include_path of PHP. Although TYPO3 does not rely on this,
  2106. it is an unusual setting that may introduce problems for
  2107. some extensions.
  2108. </p>
  2109. ', 1);
  2110. } else $this->message($ext, 'Current directory in include path',"",-1);
  2111. // *****************
  2112. // File uploads
  2113. // *****************
  2114. if (!ini_get('file_uploads')) {
  2115. $this->message($ext, 'File uploads not allowed', '
  2116. <p>
  2117. <em>file_uploads=' . ini_get('file_uploads') . '</em>
  2118. <br />
  2119. TYPO3 uses the ability to upload files from the browser in
  2120. various cases.
  2121. <br />
  2122. As long as this flag is disabled, you\'ll not be able to
  2123. upload files.
  2124. <br />
  2125. But it doesn\'t end here, because not only are files not
  2126. accepted by the server - ALL content in the forms are
  2127. discarded and therefore nothing at all will be editable
  2128. if you don\'t set this flag!
  2129. <br />
  2130. However if you cannot enable fileupload for some reason
  2131. alternatively you change the default form encoding value
  2132. with \$TYPO3_CONF_VARS[SYS][form_enctype].
  2133. </p>
  2134. ', 3);
  2135. } else $this->message($ext, 'File uploads allowed',"",-1);
  2136. $upload_max_filesize = t3lib_div::getBytesFromSizeMeasurement(ini_get('upload_max_filesize'));
  2137. $post_max_size = t3lib_div::getBytesFromSizeMeasurement(ini_get('post_max_size'));
  2138. if ($upload_max_filesize<1024*1024*10) {
  2139. $this->message($ext, 'Maximum upload filesize too small?', '
  2140. <p>
  2141. <em>upload_max_filesize=' . ini_get('upload_max_filesize') . '</em>
  2142. <br />
  2143. By default TYPO3 supports uploading, copying and moving
  2144. files of sizes up to 10MB (You can alter the TYPO3 defaults
  2145. by the config option TYPO3_CONF_VARS[BE][maxFileSize]).
  2146. <br />
  2147. Your current value is below this, so at this point, PHP sets
  2148. the limits for uploaded filesizes and not TYPO3.
  2149. <br />
  2150. <strong>Notice:</strong> The limits for filesizes attached
  2151. to database records are set in the tables.php configuration
  2152. files (\$TCA) for each group/file field. You may override
  2153. these values in localconf.php or by page TSconfig settings.
  2154. </p>
  2155. ', 1);
  2156. }
  2157. if ($upload_max_filesize > $post_max_size) {
  2158. $this->message($ext, 'Maximum size for POST requests is smaller than max. upload filesize', '
  2159. <p>
  2160. <em>upload_max_filesize=' . ini_get('upload_max_filesize') . '
  2161. , post_max_size=' . ini_get('post_max_size') . '</em>
  2162. <br />
  2163. You have defined a maximum size for file uploads which
  2164. exceeds the allowed size for POST requests. Therefore the
  2165. file uploads can not be larger than ' . ini_get('post_max_size') . '
  2166. </p>
  2167. ', 1);
  2168. }
  2169. // *****************
  2170. // Memory and functions
  2171. // *****************
  2172. $memory_limit_value = t3lib_div::getBytesFromSizeMeasurement(ini_get('memory_limit'));
  2173. if ($memory_limit_value && $memory_limit_value < t3lib_div::getBytesFromSizeMeasurement(TYPO3_REQUIREMENTS_MINIMUM_PHP_MEMORY_LIMIT)) {
  2174. $this->message($ext, 'Memory limit below ' . TYPO3_REQUIREMENTS_MINIMUM_PHP_MEMORY_LIMIT, '
  2175. <p>
  2176. <em>memory_limit=' . ini_get('memory_limit') . '</em>
  2177. <br />
  2178. Your system is configured to enforce a memory limit of PHP
  2179. scripts lower than ' . TYPO3_REQUIREMENTS_MINIMUM_PHP_MEMORY_LIMIT . '.
  2180. The Extension Manager needs to include more PHP-classes than
  2181. will fit into this memory space. There is nothing else to do
  2182. than raise the limit. To be safe, ask the system
  2183. administrator of the webserver to raise the limit to over
  2184. ' . TYPO3_REQUIREMENTS_MINIMUM_PHP_MEMORY_LIMIT . '.
  2185. </p>
  2186. ', 3);
  2187. } elseif(!$memory_limit_value) {
  2188. $this->message($ext, 'Memory limit', '
  2189. <p>
  2190. <em>No memory limit in effect.</em>
  2191. </p>
  2192. ', -1);
  2193. } else {
  2194. $this->message($ext, 'Memory limit: ' . ini_get('memory_limit'), '', -1);
  2195. }
  2196. if (ini_get('max_execution_time')<30) {
  2197. $this->message($ext, 'Maximum execution time below 30 seconds', '
  2198. <p>
  2199. <em>max_execution_time=' . ini_get('max_execution_time') . '</em>
  2200. <br />
  2201. May impose problems if too low.
  2202. </p>
  2203. ', 1);
  2204. } else {
  2205. $this->message($ext, 'Maximum execution time: ' . ini_get('max_execution_time') . ' seconds', '', -1);
  2206. }
  2207. if (ini_get('disable_functions')) {
  2208. $this->message($ext, 'Functions disabled!', '
  2209. <p>
  2210. <em>disable_functions=' . ini_get('disable_functions') . '</em>
  2211. <br />
  2212. The above list of functions are disabled. If TYPO3 use any
  2213. of these there might be trouble.
  2214. <br />
  2215. TYPO3 is designed to use the default set of PHP4.3.0+
  2216. functions plus the functions of GDLib.
  2217. <br />
  2218. Possibly these functions are disabled due to security risks
  2219. and most likely the list would include a function like
  2220. <em>exec()</em> which is use by TYPO3 to access ImageMagick.
  2221. </p>
  2222. ', 2);
  2223. } else {
  2224. $this->message($ext, 'Functions disabled: none', '', -1);
  2225. }
  2226. // Mail tests
  2227. if (TYPO3_OS == 'WIN') {
  2228. $smtp = ini_get('SMTP');
  2229. $bad_smtp = false;
  2230. if (!t3lib_div::validIP($smtp)) {
  2231. $smtp_addr = @gethostbyname($smtp);
  2232. $bad_smtp = ($smtp_addr == $smtp);
  2233. }
  2234. else {
  2235. $smtp_addr = $smtp;
  2236. }
  2237. if (!$smtp || $bad_smtp || !t3lib_div::testInt(ini_get('smtp_port'))) {
  2238. $this->message($ext, 'Mail configuration is not set correctly', '
  2239. <p>
  2240. Mail configuration is not set
  2241. <br />
  2242. PHP mail() function requires SMTP and smtp_port to have
  2243. correct values on Windows.
  2244. </p>
  2245. ', 2);
  2246. } else {
  2247. if (($smtp_addr == '127.0.0.1' || $smtp_addr == '::1') && ($_SERVER['SERVER_ADDR'] == '127.0.0.1' || $_SERVER['SERVER_ADDR'] == '::1')) {
  2248. $this->message($ext, 'Mail is configured (potential problem exists!)', '
  2249. <p>
  2250. <em>SMTP=' . $smtp . '</em> - <strong>Note:</strong>
  2251. this server! Are you sure it runs SMTP server?
  2252. <br />
  2253. <em>smtp_port=' . ini_get('smtp_port') . '</em>
  2254. </p>' . $this->check_mail('get_form') . '
  2255. ', 1);
  2256. } else {
  2257. $this->message($ext, 'Mail is configured', '
  2258. <p>
  2259. <em>SMTP=' . $smtp . '</em>
  2260. <br />
  2261. <em>smtp_port=' . ini_get('smtp_port') . '</em>
  2262. </p>' . $this->check_mail('get_form') .'
  2263. ', -1);
  2264. }
  2265. }
  2266. } elseif (!ini_get('sendmail_path')) {
  2267. $this->message($ext, 'Sendmail path not defined!', '
  2268. <p>
  2269. This may be critical to TYPO3\'s use of the mail() function.
  2270. Please be sure that the mail() function in your
  2271. php-installation works!
  2272. </p>' . $this->check_mail('get_form') . '
  2273. ', 1);
  2274. } else {
  2275. list($prg) = explode(' ', ini_get('sendmail_path'));
  2276. if (!@is_executable($prg)) {
  2277. $this->message($ext, 'Sendmail program not found or not executable?', '
  2278. <p>
  2279. <em>sendmail_path=' . ini_get('sendmail_path') . '</em>
  2280. <br />
  2281. This may be critical to TYPO3\'s use of the mail()
  2282. function. Please be sure that the mail() function in
  2283. your php-installation works!
  2284. </p>' . $this->check_mail('get_form') .'
  2285. ', 1);
  2286. } else {
  2287. $this->message($ext, 'Sendmail OK', '
  2288. <p>
  2289. <em>sendmail_path=' . ini_get('sendmail_path') . '</em>
  2290. </p>' . $this->check_mail('get_form') . '
  2291. ', -1);
  2292. }
  2293. }
  2294. // *****************
  2295. // Safe mode related
  2296. // *****************
  2297. if (t3lib_utility_PhpOptions::isSafeModeEnabled()) {
  2298. $this->message($ext, 'Safe mode turned on', '
  2299. <p>
  2300. <em>safe_mode=' . ini_get('safe_mode') . '</em>
  2301. <br />
  2302. In safe_mode PHP is restricted in several ways. This is a
  2303. good thing because it adds protection to your (and others)
  2304. scripts. But it may also introduce problems. In TYPO3 this
  2305. <em>may be</em> a problem in two areas: File administration
  2306. and execution of external programs, in particular
  2307. ImageMagick.
  2308. <br />
  2309. If you just ignore this warning, you\'ll most likely find,
  2310. that TYPO3 seems to work except from the image-generation.
  2311. The problem in that case is that the external ImageMagick
  2312. programs are not allowed to be executed from the regular
  2313. paths like "/usr/bin/" or "/usr/X11R6/bin/".
  2314. <br />
  2315. If you use safe_mode with TYPO3, you should disable use of
  2316. external programs ([BE][disable_exec_function]=1).
  2317. <br />
  2318. In safe mode you must ensure that all the php-scripts and
  2319. upload folders are owned by the same user.
  2320. </p>
  2321. <p>
  2322. <em>safe_mode_exec_dir=' . ini_get('safe_mode_exec_dir') . '</em>
  2323. <br />
  2324. If the ImageMagick utilities are located in this directory,
  2325. everything is fine. Below on this page, you can see if
  2326. ImageMagick is found here. If not, ask you ISP to put the
  2327. three ImageMagick programs, \'convert\',
  2328. \'combine\'/\'composite\' and \'identify\' there (eg. with
  2329. symlinks if Unix server)
  2330. </p>
  2331. <p>
  2332. <strong>Example of safe_mode settings:</strong>
  2333. <br />
  2334. Set this in the php.ini file:
  2335. </p>
  2336. <p>
  2337. ; Safe Mode
  2338. <br />
  2339. safe_mode = On
  2340. <br />
  2341. safe_mode_exec_dir = /usr/bin/
  2342. </p>
  2343. <p>
  2344. ...and the ImageMagick \'/usr/bin/convert\' will be
  2345. executable.
  2346. <br />
  2347. The last slash is important (..../) and you can only specify
  2348. one directory.
  2349. </p>
  2350. <p>
  2351. <strong>Notice: </strong>
  2352. <br />
  2353. ImageMagick 6 or GraphicsMagick is recommended and the binaries are
  2354. normally installed in /usr/bin.
  2355. <br />
  2356. Paths to ImageMagick are defined in localconf.php and may be
  2357. something else than /usr/bin/, but this is default for
  2358. ImageMagick 6+
  2359. </p>
  2360. ', 2);
  2361. if (ini_get('doc_root')) {
  2362. $this->message($ext, 'doc_root set', '
  2363. <p>
  2364. <em>doc_root=' . ini_get('doc_root') . '</em>
  2365. <br />
  2366. PHP cannot execute scripts outside this directory. If
  2367. that is a problem is please correct it.
  2368. </p>
  2369. ', 1);
  2370. }
  2371. $this->config_array['safemode']=1;
  2372. } else {
  2373. $this->message($ext, 'safe_mode: off',"",-1);
  2374. }
  2375. if (t3lib_utility_PhpOptions::isSqlSafeModeEnabled()) {
  2376. $this->message($ext, 'sql.safe_mode is enabled', '
  2377. <p>
  2378. <em>sql.safe_mode=' . ini_get('sql.safe_mode') . '</em>
  2379. <br />
  2380. This means that you can only connect to the database with a
  2381. username corresponding to the user of the webserver process
  2382. or fileowner. Consult your ISP for information about this.
  2383. Also see <a href="http://www.wrox.com/Consumer/Store/Books/2963/29632002.htm">
  2384. http://www.wrox.com/Consumer/Store/Books/2963/29632002.htm</a>
  2385. <br />
  2386. The owner of the current file is:
  2387. <strong>' . get_current_user () . '</strong>
  2388. </p>
  2389. ', 1);
  2390. $this->config_array['sql.safe_mode_user'] = get_current_user();
  2391. } else {
  2392. $this->message($ext, 'sql.safe_mode: off',"",-1);
  2393. }
  2394. if (ini_get('open_basedir')) {
  2395. $this->message($ext, 'open_basedir set', '
  2396. <p>
  2397. <em>open_basedir=' . ini_get('open_basedir') . '</em>
  2398. <br />
  2399. This restricts TYPO3 to open and include files only in this
  2400. path. Please make sure that this does not prevent TYPO3 from
  2401. running.
  2402. <br />
  2403. <strong>Notice (UNIX):</strong> Before checking a path
  2404. according to open_basedir, PHP resolves all symbolic links.
  2405. </p>
  2406. ', 1);
  2407. // ???? If this option was set falsely you probably didn't see this page in the
  2408. // first place, but this option <strong>may spoil this configuration test</strong>
  2409. // when checking for such as ImageMagick executables.
  2410. } else {
  2411. $this->message($ext, 'open_basedir: off',"",-1);
  2412. }
  2413. // Check availability of PHP session support
  2414. if (extension_loaded('session')) {
  2415. $this->message($ext, 'PHP sessions availiable', '
  2416. <p>
  2417. <em>PHP Sessions availiabe</em>
  2418. <br />
  2419. PHP is compiled with session support and session support is
  2420. available.
  2421. </p>
  2422. ', -1);
  2423. } else {
  2424. $this->message($ext, 'PHP Sessions not availiabe', '
  2425. <p>
  2426. PHP is not compiled with session support, or session support
  2427. is disabled in php.ini.
  2428. <br />
  2429. TYPO3 needs session support
  2430. </p>
  2431. ', 3);
  2432. }
  2433. // Suhosin/Hardened PHP:
  2434. $suhosinDescription = '
  2435. <p>
  2436. Suhosin limits the number of elements that can be submitted in
  2437. forms to the server. This will affect for example the
  2438. "All configuration" section in the Install Tool or Inline
  2439. Relational Record Editing (IRRE) with many child records.
  2440. </p>';
  2441. if (extension_loaded('suhosin')) {
  2442. $suhosinSuggestion = '
  2443. <p>
  2444. At least a value of 400 is suggested.
  2445. </p>
  2446. ';
  2447. $suhosinRequestMaxVars = ini_get('suhosin.request.max_vars');
  2448. $suhosinPostMaxVars = ini_get('suhosin.post.max_vars');
  2449. $suhosinRequestMaxVarsType = ($suhosinRequestMaxVars < 400 ? 2 : -1);
  2450. $suhosinPostMaxVarsType = ($suhosinPostMaxVars < 400 ? 2 : -1);
  2451. $suhosinType = ($suhosinRequestMaxVars < 400 || $suhosinPostMaxVars < 400 ? 2 : -1);
  2452. $this->message($ext, 'Suhosin/Hardened PHP is loaded', $suhosinDescription, $suhosinType);
  2453. $this->message($ext, 'suhosin.request.max_vars: ' . $suhosinRequestMaxVars, $suhosinSuggestion, $suhosinRequestMaxVarsType);
  2454. $this->message($ext, 'suhosin.post.max_vars: ' . $suhosinPostMaxVars, $suhosinSuggestion, $suhosinPostMaxVarsType);
  2455. } else {
  2456. $this->message($ext, 'Suhosin/Hardened PHP is not loaded', $suhosinDescription, 0);
  2457. }
  2458. // Check for stripped PHPdoc comments that are required to evaluate annotations:
  2459. $method = new ReflectionMethod('tx_install', 'check_mail');
  2460. if (strlen($method->getDocComment()) === 0) {
  2461. $description = '
  2462. <p>
  2463. The system extension Extbase evaluates annotations in PHPdoc
  2464. comments and thus requires eAccelerator not to strip away
  2465. these parts. However, this is currently the only part in the
  2466. TYPO3 Core (beside deprecation log and unit tests). If
  2467. Extbase is not used, recompiling eAccelerator is not
  2468. required at all.
  2469. <br/>
  2470. <br/>
  2471. If you do not want comments to be stripped by eAccelerator,
  2472. please recompile with the following configuration setting
  2473. (<a href="http://eaccelerator.net/ticket/229" target="_blank">
  2474. more details</a>):
  2475. <br />
  2476. <em>--with-eaccelerator-doc-comment-inclusion</em>
  2477. </p>
  2478. ';
  2479. $this->message($ext, 'PHPdoc comments are stripped', $description, 2);
  2480. }
  2481. }
  2482. /**
  2483. * Check if PHP function mail() works
  2484. *
  2485. * @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.
  2486. * @return string The mail form if it is requested with get_form
  2487. */
  2488. function check_mail($cmd='') {
  2489. switch($cmd) {
  2490. case 'get_form':
  2491. $out = '
  2492. <p id="checkMailForm">
  2493. You can check the t3lib_mail functionality by entering your email
  2494. address here and press the button. You should then
  2495. receive a testmail from "typo3installtool@example.org".
  2496. </p>
  2497. ';
  2498. // Get the template file
  2499. $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'CheckMail.html');
  2500. // Get the template part from the file
  2501. $template = t3lib_parsehtml::getSubpart($templateFile, '###TEMPLATE###');
  2502. if (!empty($this->mailMessage)) {
  2503. // Get the subpart for the mail is sent message
  2504. $mailSentSubpart = t3lib_parsehtml::getSubpart($template, '###MAILSENT###');
  2505. }
  2506. // Substitute the subpart for the mail is sent message
  2507. $template = t3lib_parsehtml::substituteSubpart(
  2508. $template,
  2509. '###MAILSENT###',
  2510. $mailSentSubpart
  2511. );
  2512. // Define the markers content
  2513. $markers = array(
  2514. 'message' => $this->mailMessage,
  2515. 'enterEmail' => 'Enter the email address',
  2516. 'actionUrl' => $this->action . '#checkMailForm',
  2517. 'submit' => 'Send test mail'
  2518. );
  2519. // Fill the markers
  2520. $out .= t3lib_parsehtml::substituteMarkerArray(
  2521. $template,
  2522. $markers,
  2523. '###|###',
  2524. TRUE,
  2525. TRUE
  2526. );
  2527. break;
  2528. default:
  2529. if (trim($this->INSTALL['check_mail'])) {
  2530. $subject = 'TEST SUBJECT';
  2531. $email = trim($this->INSTALL['check_mail']);
  2532. /** @var $mailMessage t3lib_mail_Message */
  2533. $mailMessage = t3lib_div::makeInstance('t3lib_mail_Message');
  2534. $mailMessage->addTo($email)
  2535. ->addFrom('typo3installtool@example.org', 'TYPO3 Install Tool')
  2536. ->setSubject($subject)
  2537. ->setBody('<html><body>HTML TEST CONTENT</body></html>');
  2538. $mailMessage->addPart('TEST CONTENT');
  2539. $mailMessage->send();
  2540. $this->mailMessage= 'Mail was sent to: ' . $email;
  2541. }
  2542. break;
  2543. }
  2544. return $out;
  2545. }
  2546. /**
  2547. * Checking php extensions, specifically GDLib and Freetype
  2548. *
  2549. * @return void
  2550. */
  2551. function checkExtensions() {
  2552. $ext = 'GDLib';
  2553. $this->message($ext);
  2554. $software_info=1;
  2555. if (extension_loaded('gd') && $this->isGD()) {
  2556. $this->config_array['gd']=1;
  2557. $this->message($ext, 'GDLib found',"",-1);
  2558. if ($this->isPNG()) {
  2559. $this->config_array['gd_png']=1;
  2560. $this->message($ext, 'PNG supported',"",-1);
  2561. }
  2562. if ($this->isGIF()) {
  2563. $this->config_array['gd_gif']=1;
  2564. $this->message($ext, 'GIF supported',"",-1);
  2565. }
  2566. if ($this->isJPG()) {
  2567. $this->config_array['gd_jpg']=1;
  2568. $this->message($ext, 'JPG supported (not used by TYPO3)','');
  2569. }
  2570. if (!$this->config_array['gd_gif'] && !$this->config_array['gd_png']) {
  2571. $this->message($ext, 'PNG or GIF not supported', '
  2572. <p>
  2573. Your GDLib supports either GIF nor PNG. It must support
  2574. either one of them.
  2575. </p>
  2576. ', 2);
  2577. } else {
  2578. $msg=array();
  2579. if ($this->config_array['gd_gif'] && $this->config_array['gd_png']) {
  2580. $msg[] = '
  2581. <p>
  2582. You can choose between generating GIF or PNG files,
  2583. as your GDLib supports both.
  2584. </p>
  2585. ';
  2586. }
  2587. if ($this->config_array['gd_gif']) {
  2588. $msg[] = '
  2589. <p>
  2590. You should watch out for the generated size of the
  2591. GIF-files because some versions of the GD library do
  2592. not compress them with LZW, but RLE and ImageMagick
  2593. is subsequently used to compress with LZW. But in
  2594. the case of ImageMagick failing this task (eg. not
  2595. being compiled with LZW which is the case with some
  2596. versions) you\'ll end up with GIF-filesizes all too
  2597. big!
  2598. <br />
  2599. This Install Tool tests what kinds of GIF
  2600. compression are available in the ImageMagick
  2601. installations by a physical test. You can also check
  2602. it manually by opening a TYPO3 generated gif-file
  2603. with Photoshop and save it in a new file. If the
  2604. file sizes of the original and the new file are
  2605. almost the same, you\'re having LZW compression and
  2606. everything is fine.
  2607. </p>
  2608. ';
  2609. }
  2610. if ($this->config_array['gd_png']) {
  2611. $msg[] = '
  2612. <p>
  2613. TYPO3 prefers the use of GIF-files and most likely
  2614. your visitors on your website does too as not all
  2615. browsers support PNG yet.
  2616. </p>
  2617. ';
  2618. }
  2619. $this->message($ext, 'GIF / PNG issues', implode(LF, $msg), 1);
  2620. }
  2621. if (!$this->isTTF()) {
  2622. $this->message($ext, 'FreeType is apparently not installed', '
  2623. <p>
  2624. It looks like the FreeType library is not compiled into
  2625. GDLib. This is required when TYPO3 uses GDLib and
  2626. you\'ll most likely get errors like \'ImageTTFBBox is
  2627. not a function\' or \'ImageTTFText is not a function\'.
  2628. </p>
  2629. ', 2);
  2630. } else {
  2631. $this->message($ext, 'FreeType quick-test (' . ($this->isGIF() ? 'as GIF' : 'as PNG') . ')', '
  2632. <p>
  2633. <img src="' . htmlspecialchars(t3lib_div::getIndpEnv('REQUEST_URI') . '&testingTrueTypeSupport=1') . '" alt="" />
  2634. <br />
  2635. (If the text is exceeding the image borders you are
  2636. using Freetype 2 and need to set
  2637. TYPO3_CONF_VARS[GFX][TTFdpi]=96.
  2638. <br />
  2639. If there is no image at all Freetype is most likely NOT
  2640. available and you can just as well disable GDlib for
  2641. TYPO3...)
  2642. </p>
  2643. ', -1);
  2644. $this->config_array['freetype']=1;
  2645. }
  2646. } else {
  2647. $this->message($ext, 'GDLib2 not found', '
  2648. <p>
  2649. GDLib2 is required if you want to use the GIFBUILDER object
  2650. in TypoScript. GIFBUILDER is in charge of all advanced image
  2651. generation in TypoScript, including graphical menuitems.
  2652. <br />
  2653. GDLib2 is also used in the TYPO3 Backend (TBE) to generate
  2654. record icons and new module tabs.
  2655. <br />
  2656. It\'s highly recommended to install this library. Remember
  2657. to compile GD with FreeType which is also required.
  2658. <br />
  2659. If you choose not to install GDLib, you can disable it in
  2660. the configuration with [GFX][gdlib]=0;.
  2661. </p>
  2662. ', 2);
  2663. }
  2664. $this->message($ext, 'GDLib software information', $this->getGDSoftwareInfo());
  2665. }
  2666. /**
  2667. * Checking and testing that the required writable directories are writable.
  2668. *
  2669. * @return void
  2670. */
  2671. function checkDirs() {
  2672. // Check typo3/temp/
  2673. $ext='Directories';
  2674. $this->message($ext);
  2675. $uniqueName = md5(uniqid(microtime()));
  2676. // The requirement level (the integer value, ie. the second value of the value array) has the following meanings:
  2677. // -1 = not required, but if it exists may be writable or not
  2678. // 0 = not required, if it exists the dir should be writable
  2679. // 1 = required, don't has to be writable
  2680. // 2 = required, has to be writable
  2681. $checkWrite=array(
  2682. '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'),
  2683. 'typo3temp/pics/' => array('This folder is part of the typo3temp/ section. It needs to be writable, too.',2,'dir_typo3temp'),
  2684. 'typo3temp/temp/' => array('This folder is part of the typo3temp/ section. It needs to be writable, too.',2,'dir_typo3temp'),
  2685. 'typo3temp/llxml/' => array('This folder is part of the typo3temp/ section. It needs to be writable, too.',2,'dir_typo3temp'),
  2686. 'typo3temp/cs/' => array('This folder is part of the typo3temp/ section. It needs to be writable, too.',2,'dir_typo3temp'),
  2687. 'typo3temp/GB/' => array('This folder is part of the typo3temp/ section. It needs to be writable, too.',2,'dir_typo3temp'),
  2688. 'typo3temp/locks/' => array('This folder is part of the typo3temp/ section. It needs to be writable, too.',2,'dir_typo3temp'),
  2689. '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),
  2690. 'typo3conf/ext/' => array('Location for local extensions. Must be writable if the Extension Manager is supposed to install extensions for this website.',0),
  2691. 'typo3conf/l10n/' => array('Location for translations. Must be writable if the Extension Manager is supposed to install translations for extensions.',0),
  2692. 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),
  2693. 'uploads/' => array('Location for uploaded files from RTE, in the subdirectories for uploaded files of content elements.',2),
  2694. 'uploads/pics/' => array('Typical location for uploaded files (images especially).',0),
  2695. 'uploads/media/' => array('Typical location for uploaded files (non-images especially).',0),
  2696. 'uploads/tf/' => array('Typical location for uploaded files (TS template resources).',0),
  2697. $GLOBALS['TYPO3_CONF_VARS']['BE']['fileadminDir'] => array('Location for local files such as templates, independent uploads etc.',-1),
  2698. $GLOBALS['TYPO3_CONF_VARS']['BE']['fileadminDir'] . '_temp_/' => array('Typical temporary location for default upload of files by administrators.',0),
  2699. );
  2700. foreach ($checkWrite as $relpath => $descr) {
  2701. // Check typo3temp/
  2702. $general_message = $descr[0];
  2703. // If the directory is missing, try to create it
  2704. if (!@is_dir(PATH_site.$relpath)) {
  2705. t3lib_div::mkdir(PATH_site.$relpath);
  2706. }
  2707. if (!@is_dir(PATH_site.$relpath)) {
  2708. if ($descr[1]) { // required...
  2709. $this->message($ext, $relpath.' directory does not exist and could not be created', '
  2710. <p>
  2711. <em>Full path: ' . PATH_site . $relpath . '</em>
  2712. <br />
  2713. ' . $general_message . '
  2714. </p>
  2715. <p>
  2716. This error should not occur as ' . $relpath . ' must
  2717. always be accessible in the root of a TYPO3 website.
  2718. </p>
  2719. ', 3);
  2720. } else {
  2721. if ($descr[1] == 0) {
  2722. $msg = 'This directory does not necessarily have to exist but if it does it must be writable.';
  2723. } else {
  2724. $msg = 'This directory does not necessarily have to exist and if it does it can be writable or not.';
  2725. }
  2726. $this->message($ext, $relpath.' directory does not exist', '
  2727. <p>
  2728. <em>Full path: ' . PATH_site . $relpath . '</em>
  2729. <br />
  2730. ' . $general_message . '
  2731. </p>
  2732. <p>
  2733. ' . $msg . '
  2734. </p>
  2735. ', 2);
  2736. }
  2737. } else {
  2738. $file = PATH_site.$relpath.$uniqueName;
  2739. @touch($file);
  2740. if (@is_file($file)) {
  2741. unlink($file);
  2742. if ($descr[2]) { $this->config_array[$descr[2]]=1; }
  2743. $this->message($ext, $relpath.' writable','',-1);
  2744. } else {
  2745. $severity = ($descr[1]==2 || $descr[1]==0) ? 3 : 2;
  2746. if ($descr[1] == 0 || $descr[1] == 2) {
  2747. $msg = 'The directory '.$relpath.' must be writable!';
  2748. } elseif ($descr[1] == -1 || $descr[1] == 1) {
  2749. $msg = 'The directory '.$relpath.' does not neccesarily have to be writable.';
  2750. }
  2751. $this->message($ext, $relpath .' directory not writable', '
  2752. <p>
  2753. <em>Full path: ' . $file . '</em>
  2754. <br />
  2755. ' . $general_message . '
  2756. </p>
  2757. <p>
  2758. Tried to write this file (with touch()) but didn\'t
  2759. succeed.
  2760. <br />
  2761. ' . $msg . '
  2762. </p>
  2763. ', $severity);
  2764. }
  2765. }
  2766. }
  2767. }
  2768. /**
  2769. * Checking for existing ImageMagick installs.
  2770. *
  2771. * 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.
  2772. *
  2773. * @param array $paths Possible ImageMagick paths
  2774. * @return void
  2775. */
  2776. function checkImageMagick($paths) {
  2777. $ext='Check Image Magick';
  2778. $this->message($ext);
  2779. // Get the template file
  2780. $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'CheckImageMagick.html');
  2781. $paths = array_unique($paths);
  2782. $programs = explode(',','gm,convert,combine,composite,identify');
  2783. $isExt = TYPO3_OS=="WIN" ? ".exe" : "";
  2784. $this->config_array['im_combine_filename']='combine';
  2785. foreach ($paths as $k => $v) {
  2786. if (!preg_match('/[\\/]$/',$v)) $v.='/';
  2787. foreach ($programs as $filename) {
  2788. if (ini_get('open_basedir') || (file_exists($v)&&@is_file($v.$filename.$isExt))) {
  2789. $version = $this->_checkImageMagick_getVersion($filename,$v);
  2790. if($version > 0) {
  2791. // Assume GraphicsMagick
  2792. if($filename=='gm') {
  2793. $index[$v]['gm']=$version;
  2794. // No need to check for "identify" etc.
  2795. continue;
  2796. } else {
  2797. // Assume ImageMagick
  2798. $index[$v][$filename]=$version;
  2799. }
  2800. }
  2801. }
  2802. }
  2803. if (count($index[$v])>=3 || $index[$v]['gm']) {
  2804. $this->config_array['im'] = 1;
  2805. }
  2806. if ($index[$v]['gm'] || (!$index[$v]['composite'] && $index[$v]['combine'])) {
  2807. $this->config_array['im_combine_filename']='combine';
  2808. } elseif ($index[$v]['composite'] && !$index[$v]['combine']) {
  2809. $this->config_array['im_combine_filename']='composite';
  2810. }
  2811. if (isset($index[$v]['convert']) && $this->checkIMlzw) {
  2812. $index[$v]['gif_capability'] = ''.$this->_checkImageMagickGifCapability($v);
  2813. }
  2814. }
  2815. $this->config_array['im_versions']=$index;
  2816. if (!$this->config_array['im']) {
  2817. $this->message($ext, 'No ImageMagick installation available', '
  2818. <p>
  2819. It seems that there is no adequate ImageMagick installation
  2820. available at the checked locations (' . implode(', ', $paths) . ')
  2821. <br />
  2822. An \'adequate\' installation for requires \'convert\',
  2823. \'combine\'/\'composite\' and \'identify\' to be available
  2824. </p>
  2825. ', 2);
  2826. } else {
  2827. // Get the subpart for the ImageMagick versions
  2828. $theCode = t3lib_parsehtml::getSubpart($templateFile, '###VERSIONS###');
  2829. // Get the subpart for each ImageMagick version
  2830. $rowsSubPart = t3lib_parsehtml::getSubpart($theCode, '###ROWS###');
  2831. $rows = array();
  2832. foreach ($this->config_array['im_versions'] as $p => $v) {
  2833. $ka = array();
  2834. reset($v);
  2835. while(list($ka[])=each($v)) {}
  2836. // Define the markers content
  2837. $rowsMarkers = array(
  2838. 'file' => $p,
  2839. 'type' => implode('<br />', $ka),
  2840. 'version' => implode('<br />', $v)
  2841. );
  2842. // Fill the markers in the subpart
  2843. $rows[] = t3lib_parsehtml::substituteMarkerArray(
  2844. $rowsSubPart,
  2845. $rowsMarkers,
  2846. '###|###',
  2847. TRUE,
  2848. FALSE
  2849. );
  2850. }
  2851. // Substitute the subpart for the ImageMagick versions
  2852. $theCode = t3lib_parsehtml::substituteSubpart(
  2853. $theCode,
  2854. '###ROWS###',
  2855. implode(LF, $rows)
  2856. );
  2857. // Add the content to the message array
  2858. $this->message($ext, 'Available ImageMagick/GraphicsMagick installations:', $theCode, -1);
  2859. }
  2860. // Get the template file
  2861. $formSubPart = t3lib_parsehtml::getSubpart($templateFile, '###FORM###');
  2862. // Define the markers content
  2863. $formMarkers = array(
  2864. 'actionUrl' => $this->action,
  2865. 'lzwChecked' => ($this->INSTALL['checkIM']['lzw'] ? 'checked="checked"' : ''),
  2866. 'lzwLabel' => 'Check LZW capabilities.',
  2867. 'checkPath' => 'Check this path for ImageMagick installation:',
  2868. 'imageMagickPath' => htmlspecialchars($this->INSTALL['checkIM']['path']),
  2869. 'comment' => '(Eg. "D:\wwwroot\im537\ImageMagick\" for Windows or "/usr/bin/" for Unix)',
  2870. 'send' => 'Send'
  2871. );
  2872. // Fill the markers
  2873. $formSubPart = t3lib_parsehtml::substituteMarkerArray(
  2874. $formSubPart,
  2875. $formMarkers,
  2876. '###|###',
  2877. TRUE,
  2878. FALSE
  2879. );
  2880. // Add the content to the message array
  2881. $this->message($ext, 'Search for ImageMagick:', $formSubPart, 0);
  2882. }
  2883. /**
  2884. * Checking GIF-compression capabilities of ImageMagick install
  2885. *
  2886. * @param string $path Path of ImageMagick installation
  2887. * @return string Type of compression
  2888. */
  2889. function _checkImageMagickGifCapability($path) {
  2890. if ($this->config_array['dir_typo3temp']) { // && !$this->config_array['safemode']
  2891. $tempPath = $this->typo3temp_path;
  2892. $uniqueName = md5(uniqid(microtime()));
  2893. $dest = $tempPath.$uniqueName.'.gif';
  2894. $src = $this->backPath.'gfx/typo3logo.gif';
  2895. if (@is_file($src) && !strstr($src,' ') && !strstr($dest,' ')) {
  2896. $cmd = t3lib_div::imageMagickCommand('convert', $src.' '.$dest, $path);
  2897. t3lib_utility_Command::exec($cmd);
  2898. } else die('No typo3/gfx/typo3logo.gif file!');
  2899. $out='';
  2900. if (@is_file($dest)) {
  2901. $new_info = @getimagesize($dest);
  2902. clearstatcache();
  2903. $new_size = filesize($dest);
  2904. $src_info = @getimagesize($src);
  2905. clearstatcache();
  2906. $src_size = @filesize($src);
  2907. if ($new_info[0]!=$src_info[0] || $new_info[1]!=$src_info[1] || !$new_size || !$src_size) {
  2908. $out='error';
  2909. } else {
  2910. // NONE-LZW ratio was 5.5 in test
  2911. if ($new_size/$src_size > 4) {
  2912. $out='NONE';
  2913. // NONE-RLE ratio was not tested
  2914. } elseif ($new_size/$src_size > 1.5) {
  2915. $out='RLE';
  2916. } else {
  2917. $out='LZW';
  2918. }
  2919. }
  2920. unlink($dest);
  2921. }
  2922. return $out;
  2923. }
  2924. }
  2925. /**
  2926. * Extracts the version number for ImageMagick
  2927. *
  2928. * @param string $file The program name to execute in order to find out the version number
  2929. * @param string $path Path for the above program
  2930. * @return string Version number of the found ImageMagick instance
  2931. */
  2932. function _checkImageMagick_getVersion($file, $path) {
  2933. // Temporarily override some settings
  2934. $im_version = $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_version_5'];
  2935. $combine_filename = $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_combine_filename'];
  2936. if ($file=='gm') {
  2937. $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_version_5'] = 'gm';
  2938. // Work-around, preventing execution of "gm gm"
  2939. $file = 'identify';
  2940. // Work-around - GM doesn't like to be executed without any arguments
  2941. $parameters = '-version';
  2942. } else {
  2943. $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_version_5'] = 'im5';
  2944. // Override the combine_filename setting
  2945. if ($file=='combine' || $file=='composite') {
  2946. $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_combine_filename'] = $file;
  2947. }
  2948. }
  2949. $cmd = t3lib_div::imageMagickCommand($file, $parameters, $path);
  2950. $retVal = false;
  2951. t3lib_utility_Command::exec($cmd, $retVal);
  2952. $string = $retVal[0];
  2953. list(,$ver) = explode('Magick', $string);
  2954. list($ver) = explode(' ',trim($ver));
  2955. // Restore the values
  2956. $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_version_5'] = $im_version;
  2957. $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_combine_filename'] = $combine_filename;
  2958. return trim($ver);
  2959. }
  2960. /**
  2961. * Checks database username/password/host/database
  2962. *
  2963. * @return void
  2964. */
  2965. function checkDatabase() {
  2966. $ext='Check database';
  2967. $this->message($ext);
  2968. if (!extension_loaded('mysql') && !t3lib_extMgm::isLoaded('dbal')) {
  2969. $this->message($ext, 'MySQL not available', '
  2970. <p>
  2971. PHP does not feature MySQL support (which is pretty unusual).
  2972. </p>
  2973. ', 2);
  2974. } else {
  2975. if (!TYPO3_db_host || !TYPO3_db_username) {
  2976. $this->message($ext, 'Username, password or host not set', '
  2977. <p>
  2978. You may need to enter data for these values:
  2979. <br />
  2980. Username: <strong>' . htmlspecialchars(TYPO3_db_username) . '</strong>
  2981. <br />
  2982. Host: <strong>' . htmlspecialchars(TYPO3_db_host) . '</strong>
  2983. <br />
  2984. <br />
  2985. Use the form below.
  2986. </p>
  2987. ', 2);
  2988. }
  2989. if ($result = $GLOBALS['TYPO3_DB']->sql_pconnect(TYPO3_db_host, TYPO3_db_username, TYPO3_db_password)) {
  2990. $this->message($ext, 'Connected to SQL database successfully', '
  2991. <dl id="t3-install-databaseconnected">
  2992. <dt>
  2993. Username:
  2994. </dt>
  2995. <dd>
  2996. ' . htmlspecialchars(TYPO3_db_username) . '
  2997. </dd>
  2998. <dt>
  2999. Host:
  3000. </dt>
  3001. <dd>
  3002. ' . htmlspecialchars(TYPO3_db_host) . '
  3003. </dd>
  3004. </dl>
  3005. ', -1, 1);
  3006. $this->config_array['mysqlConnect']=1;
  3007. if (!TYPO3_db) {
  3008. $this->message($ext, 'No database selected', '
  3009. <p>
  3010. Currently you have no database selected.
  3011. <br />
  3012. Please select one or create a new database.
  3013. </p>
  3014. ', 3);
  3015. $this->config_array['no_database']=1;
  3016. } elseif (!$GLOBALS['TYPO3_DB']->sql_select_db(TYPO3_db)) {
  3017. $this->message($ext, 'Database', '
  3018. <p>
  3019. \'' . htmlspecialchars(TYPO3_db) . '\' could not be selected as database!
  3020. <br />
  3021. Please select another one or create a new database.
  3022. </p>
  3023. ', 3, 1);
  3024. $this->config_array['no_database']=1;
  3025. } else {
  3026. $this->message($ext, 'Database', '
  3027. <p>
  3028. <strong>' . htmlspecialchars(TYPO3_db) . '</strong> is selected as
  3029. database.
  3030. </p>
  3031. ', 1, 1);
  3032. }
  3033. } else {
  3034. $sqlSafeModeUser = '';
  3035. if ($this->config_array['sql.safe_mode_user']) {
  3036. $sqlSafeModeUser = '
  3037. <strong>Notice:</strong>
  3038. <em>sql.safe_mode</em> is turned on, so apparently your
  3039. username to the database is the same as the scriptowner,
  3040. which is ' . $this->config_array['sql.safe_mode_user'];
  3041. }
  3042. $this->message($ext, 'Could not connect to SQL database!', '
  3043. <p>
  3044. Connecting to SQL database failed with these settings:
  3045. <br />
  3046. Username: <strong>' . htmlspecialchars(TYPO3_db_username) . '</strong>
  3047. <br />
  3048. Host: <strong>' . htmlspecialchars(TYPO3_db_host) . '</strong>
  3049. </p>
  3050. <p>
  3051. Make sure you\'re using the correct set of data.
  3052. <br />
  3053. ' . $sqlSafeModeUser . '
  3054. </p>
  3055. ', 3);
  3056. }
  3057. }
  3058. }
  3059. /**
  3060. * Prints form for updating localconf.php or updates localconf.php depending on $cmd
  3061. *
  3062. * @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
  3063. * @return string Form HTML
  3064. */
  3065. function setupGeneral($cmd='') {
  3066. switch($cmd) {
  3067. case 'get_form':
  3068. // Get the template file
  3069. $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'SetupGeneral.html');
  3070. // Get the template part from the file
  3071. $form = t3lib_parsehtml::getSubpart($templateFile, '###TEMPLATE###');
  3072. // Get the subpart for all modes
  3073. $allModesSubpart = t3lib_parsehtml::getSubpart($form, '###ALLMODES###');
  3074. // Define the markers content
  3075. $formMarkers['actionUrl'] = $this->action;
  3076. // Username
  3077. if (TYPO3_db_username) {
  3078. $username = TYPO3_db_username;
  3079. } elseif ($this->config_array['sql.safe_mode_user']) {
  3080. $username = $this->config_array['sql.safe_mode_user'];
  3081. // Get the subpart for the sql safe mode user
  3082. $sqlSafeModeUserSubpart = t3lib_parsehtml::getSubpart($allModesSubpart, '###SQLSAFEMODEUSERSUBPART###');
  3083. // Define the markers content
  3084. $sqlSafeModeUserMarkers = array(
  3085. 'labelSqlSafeModeUser' => 'sql.safe_mode_user:',
  3086. 'sqlSafeModeUser' => $this->config_array['sql.safe_mode_user']
  3087. );
  3088. // Fill the markers in the subpart
  3089. $sqlSafeModeUserSubpart = t3lib_parsehtml::substituteMarkerArray(
  3090. $sqlSafeModeUserSubpart,
  3091. $sqlSafeModeUserMarkers,
  3092. '###|###',
  3093. TRUE,
  3094. FALSE
  3095. );
  3096. }
  3097. // Get the subpart for all modes
  3098. $allModesSubpart = t3lib_parsehtml::substituteSubpart(
  3099. $allModesSubpart,
  3100. '###SQLSAFEMODEUSERSUBPART###',
  3101. $sqlSafeModeUserSubpart
  3102. );
  3103. // Define the markers content
  3104. $allModesMarkers = array(
  3105. 'labelUsername' => 'Username:',
  3106. 'username' => htmlspecialchars($username),
  3107. 'labelPassword' => 'Password:',
  3108. 'password' => htmlspecialchars(TYPO3_db_password),
  3109. 'labelHost' => 'Host:',
  3110. 'host' => htmlspecialchars(TYPO3_db_host),
  3111. 'labelDatabase' => 'Database:',
  3112. 'labelCreateDatabase' => 'Create database?'
  3113. );
  3114. // Get the subpart for the database list
  3115. $databasesSubpart = t3lib_parsehtml::getSubpart($allModesSubpart, '###DATABASELIST###');
  3116. if ($this->config_array['mysqlConnect']) {
  3117. // Get the subpart when database is available
  3118. $databaseAvailableSubpart = t3lib_parsehtml::getSubpart($databasesSubpart, '###DATABASEAVAILABLE###');
  3119. // Get the subpart for each database table
  3120. $databaseItemSubpart = t3lib_parsehtml::getSubpart($databaseAvailableSubpart, '###DATABASEITEM###');
  3121. $dbArr = $this->getDatabaseList();
  3122. $dbIncluded=0;
  3123. $databaseItems = array();
  3124. foreach ($dbArr as $dbname) {
  3125. // Define the markers content
  3126. $databaseItemMarkers = array(
  3127. 'databaseSelected' => '',
  3128. 'databaseName' => htmlspecialchars($dbname),
  3129. 'databaseValue' => htmlspecialchars($dbname)
  3130. );
  3131. if ($dbname == TYPO3_db) {
  3132. $databaseItemMarkers['databaseSelected'] = 'selected="selected"';
  3133. }
  3134. // Fill the markers in the subpart
  3135. $databaseItems[] = t3lib_parsehtml::substituteMarkerArray(
  3136. $databaseItemSubpart,
  3137. $databaseItemMarkers,
  3138. '###|###',
  3139. TRUE,
  3140. FALSE
  3141. );
  3142. if ($dbname==TYPO3_db) $dbIncluded=1;
  3143. }
  3144. if (!$dbIncluded && TYPO3_db) {
  3145. $databaseItemMarkers['databaseName'] = htmlspecialchars(TYPO3_db);
  3146. $databaseItemMarkers['databaseSelected'] = 'selected="selected"';
  3147. $databaseItemMarkers['databaseValue'] = htmlspecialchars(TYPO3_db) . ' (NO ACCESS!)';
  3148. // Fill the markers in the subpart
  3149. $databaseItems[] = t3lib_parsehtml::substituteMarkerArray(
  3150. $databaseItemSubpart,
  3151. $databaseItemMarkers,
  3152. '###|###',
  3153. TRUE,
  3154. FALSE
  3155. );
  3156. }
  3157. // Substitute the subpart for the database tables
  3158. $databaseAvailableSubpart = t3lib_parsehtml::substituteSubpart(
  3159. $databaseAvailableSubpart,
  3160. '###DATABASEITEM###',
  3161. implode(LF, $databaseItems)
  3162. );
  3163. } else {
  3164. // Get the subpart when the database is not available
  3165. $databaseNotAvailableSubpart = t3lib_parsehtml::getSubpart($databasesSubpart, '###DATABASENOTAVAILABLE###');
  3166. $databaseNotAvailableMarkers = array(
  3167. 'typo3Db' => htmlspecialchars(TYPO3_db),
  3168. 'labelNoDatabase' => '
  3169. (Can only select database if username/password/host
  3170. is correctly set first)
  3171. '
  3172. );
  3173. // Fill the markers in the subpart
  3174. $databaseNotAvailableSubpart = t3lib_parsehtml::substituteMarkerArray(
  3175. $databaseNotAvailableSubpart,
  3176. $databaseNotAvailableMarkers,
  3177. '###|###',
  3178. TRUE,
  3179. FALSE
  3180. );
  3181. }
  3182. // Substitute the subpart when database is available
  3183. $databasesSubpart = t3lib_parsehtml::substituteSubpart(
  3184. $databasesSubpart,
  3185. '###DATABASEAVAILABLE###',
  3186. $databaseAvailableSubpart
  3187. );
  3188. // Substitute the subpart when database is not available
  3189. $databasesSubpart = t3lib_parsehtml::substituteSubpart(
  3190. $databasesSubpart,
  3191. '###DATABASENOTAVAILABLE###',
  3192. $databaseNotAvailableSubpart
  3193. );
  3194. // Substitute the subpart for the databases
  3195. $allModesSubpart = t3lib_parsehtml::substituteSubpart(
  3196. $allModesSubpart,
  3197. '###DATABASELIST###',
  3198. $databasesSubpart
  3199. );
  3200. // Fill the markers in the subpart for all modes
  3201. $allModesSubpart = t3lib_parsehtml::substituteMarkerArray(
  3202. $allModesSubpart,
  3203. $allModesMarkers,
  3204. '###|###',
  3205. TRUE,
  3206. FALSE
  3207. );
  3208. // Substitute the subpart for all modes
  3209. $form = t3lib_parsehtml::substituteSubpart(
  3210. $form,
  3211. '###ALLMODES###',
  3212. $allModesSubpart
  3213. );
  3214. if ($this->mode!='123') {
  3215. // Get the subpart for the regular mode
  3216. $regularModeSubpart = t3lib_parsehtml::getSubpart($form, '###REGULARMODE###');
  3217. // Define the markers content
  3218. $regularModeMarkers = array(
  3219. 'labelSiteName' => 'Site name:',
  3220. 'siteName' => htmlspecialchars($GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename']),
  3221. 'labelEncryptionKey' => 'Encryption key:',
  3222. 'encryptionKey' => htmlspecialchars($GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey']),
  3223. 'labelGenerateRandomKey' => 'Generate random key'
  3224. );
  3225. // Other
  3226. $fA = $this->setupGeneralCalculate();
  3227. $regularModeMarkers['labelCurrentValueIs'] = 'current value is';
  3228. // Disable exec function
  3229. if (is_array($fA['disable_exec_function'])) {
  3230. // Get the subpart for the disable exec function
  3231. $disableExecFunctionSubpart = t3lib_parsehtml::getSubpart($regularModeSubpart, '###DISABLEEXECFUNCTIONSUBPART###');
  3232. $regularModeMarkers['labelDisableExecFunction'] = '[BE][disable_exec_function]=';
  3233. $regularModeMarkers['strongDisableExecFunction'] = (integer) current($fA['disable_exec_function']);
  3234. $regularModeMarkers['defaultDisableExecFunction'] = (integer) $GLOBALS['TYPO3_CONF_VARS']['BE']['disable_exec_function'];
  3235. $regularModeMarkers['disableExecFunction'] = (integer) current($fA['disable_exec_function']);
  3236. // Fill the markers in the subpart
  3237. $disableExecFunctionSubpart = t3lib_parsehtml::substituteMarkerArray(
  3238. $disableExecFunctionSubpart,
  3239. $regularModeMarkers,
  3240. '###|###',
  3241. TRUE,
  3242. FALSE
  3243. );
  3244. }
  3245. // Substitute the subpart for the disable exec function
  3246. $regularModeSubpart = t3lib_parsehtml::substituteSubpart(
  3247. $regularModeSubpart,
  3248. '###DISABLEEXECFUNCTIONSUBPART###',
  3249. $disableExecFunctionSubpart
  3250. );
  3251. // GDlib
  3252. if (is_array($fA['gdlib'])) {
  3253. // Get the subpart for the disable gd lib
  3254. $gdLibSubpart = t3lib_parsehtml::getSubpart($regularModeSubpart, '###DISABLEGDLIB###');
  3255. $regularModeMarkers['labelGdLib'] = '[GFX][gdlib]=';
  3256. $regularModeMarkers['strongGdLib'] = (integer) current($fA['gdlib']);
  3257. $regularModeMarkers['defaultGdLib'] = (integer) $GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib'];
  3258. $regularModeMarkers['gdLib'] = (integer) current($fA['gdlib']);
  3259. // Fill the markers in the subpart
  3260. $gdLibSubpart = t3lib_parsehtml::substituteMarkerArray(
  3261. $gdLibSubpart,
  3262. $regularModeMarkers,
  3263. '###|###',
  3264. TRUE,
  3265. FALSE
  3266. );
  3267. }
  3268. // Substitute the subpart for the disable gdlib
  3269. $regularModeSubpart = t3lib_parsehtml::substituteSubpart(
  3270. $regularModeSubpart,
  3271. '###DISABLEGDLIB###',
  3272. $gdLibSubpart
  3273. );
  3274. // GDlib PNG
  3275. if (is_array($fA['gdlib_png']) && $GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib']) {
  3276. // Get the subpart for the gdlib png
  3277. $gdLibPngSubpart = t3lib_parsehtml::getSubpart($regularModeSubpart, '###GDLIBPNGSUBPART###');
  3278. // Get the subpart for the dropdown options
  3279. $gdLibPngOptionSubpart = t3lib_parsehtml::getSubpart($gdLibPngSubpart, '###GDLIBPNGOPTION###');
  3280. $gdLibPngLabels = $this->setLabelValueArray($fA['gdlib_png'], 2);
  3281. reset($gdLibPngLabels);
  3282. $regularModeMarkers['labelGdLibPng'] = '[GFX][gdlib_png]=';
  3283. $regularModeMarkers['strongGdLibPng'] = (string) current($gdLibPngLabels);
  3284. $regularModeMarkers['defaultGdLibPng'] = (integer) $GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib_png'];
  3285. $gdLibPngOptions = array();
  3286. foreach ($gdLibPngLabels as $k => $v) {
  3287. list($cleanV) = explode('|', $fA['gdlib_png'][$k]);
  3288. $gdLibPngMarker['value'] = htmlspecialchars($fA['gdlib_png'][$k]);
  3289. $gdLibPngMarker['data'] = htmlspecialchars($v);
  3290. if (!strcmp($GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib_png'], $cleanV)) {
  3291. $gdLibPngMarker['selected'] = 'selected="selected"';
  3292. }
  3293. // Fill the markers in the subpart
  3294. $gdLibPngOptions[] = t3lib_parsehtml::substituteMarkerArray(
  3295. $gdLibPngOptionSubpart,
  3296. $gdLibPngMarker,
  3297. '###|###',
  3298. TRUE,
  3299. FALSE
  3300. );
  3301. }
  3302. // Substitute the subpart for the dropdown options
  3303. $gdLibPngSubpart = t3lib_parsehtml::substituteSubpart(
  3304. $gdLibPngSubpart,
  3305. '###GDLIBPNGOPTION###',
  3306. implode(LF, $gdLibPngOptions)
  3307. );
  3308. // Fill the markers in the subpart
  3309. $gdLibPngSubpart = t3lib_parsehtml::substituteMarkerArray(
  3310. $gdLibPngSubpart,
  3311. $regularModeMarkers,
  3312. '###|###',
  3313. TRUE,
  3314. FALSE
  3315. );
  3316. }
  3317. // Substitute the subpart for the gdlib png
  3318. $regularModeSubpart = t3lib_parsehtml::substituteSubpart(
  3319. $regularModeSubpart,
  3320. '###GDLIBPNGSUBPART###',
  3321. $gdLibPngSubpart
  3322. );
  3323. // ImageMagick
  3324. if (is_array($fA['im'])) {
  3325. // Get the subpart for ImageMagick
  3326. $imageMagickSubpart = t3lib_parsehtml::getSubpart($regularModeSubpart, '###IMAGEMAGICKSUBPART###');
  3327. // Define the markers content
  3328. $regularModeMarkers['labelImageMagick'] = '[GFX][im]=';
  3329. $regularModeMarkers['strongImageMagick'] = (string) current($fA['im']);
  3330. $regularModeMarkers['defaultImageMagick'] = (integer) $GLOBALS['TYPO3_CONF_VARS']['GFX']['im'];
  3331. $regularModeMarkers['imageMagick'] = (integer) current($fA['im']);
  3332. // Fill the markers in the subpart
  3333. $imageMagickSubpart = t3lib_parsehtml::substituteMarkerArray(
  3334. $imageMagickSubpart,
  3335. $regularModeMarkers,
  3336. '###|###',
  3337. TRUE,
  3338. FALSE
  3339. );
  3340. // IM Combine Filename
  3341. // Get the subpart for ImageMagick Combine filename
  3342. $imCombineFileNameSubpart = t3lib_parsehtml::getSubpart($regularModeSubpart, '###IMCOMBINEFILENAMESUBPART###');
  3343. // Define the markers content
  3344. $regularModeMarkers['labelImCombineFilename'] = '[GFX][im_combine_filename]';
  3345. $regularModeMarkers['strongImCombineFilename'] = (string) current($fA['im_combine_filename']);
  3346. $regularModeMarkers['defaultImCombineFilename'] = (string) $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_combine_filename'];
  3347. $regularModeMarkers['imCombineFilename'] = (string) ($fA['im_combine_filename'] ? current($fA['im_combine_filename']) : 'combine');
  3348. // Fill the markers in the subpart
  3349. $imCombineFileNameSubpart = t3lib_parsehtml::substituteMarkerArray(
  3350. $imCombineFileNameSubpart,
  3351. $regularModeMarkers,
  3352. '###|###',
  3353. TRUE,
  3354. FALSE
  3355. );
  3356. // IM Version 5
  3357. // Get the subpart for ImageMagick Version 5
  3358. $imVersion5Subpart = t3lib_parsehtml::getSubpart($regularModeSubpart, '###IMVERSION5SUBPART###');
  3359. // Define the markers content
  3360. $regularModeMarkers['labelImVersion5'] = '[GFX][im_version_5]=';
  3361. $regularModeMarkers['strongImVersion5'] = (string) current($fA['im_version_5']);
  3362. $regularModeMarkers['defaultImVersion5'] = (string) $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_version_5'];
  3363. $regularModeMarkers['imVersion5'] = (string) ($fA['im_version_5'] ? current($fA['im_version_5']) : '');
  3364. // Fill the markers in the subpart
  3365. $imVersion5Subpart = t3lib_parsehtml::substituteMarkerArray(
  3366. $imVersion5Subpart,
  3367. $regularModeMarkers,
  3368. '###|###',
  3369. TRUE,
  3370. FALSE
  3371. );
  3372. if ($GLOBALS['TYPO3_CONF_VARS']['GFX']['im']) {
  3373. // IM Path
  3374. if (is_array($fA['im_path'])) {
  3375. // Get the subpart for ImageMagick path
  3376. $imPathSubpart = t3lib_parsehtml::getSubpart($regularModeSubpart, '###IMPATHSUBPART###');
  3377. $labelImPath = $this->setLabelValueArray($fA['im_path'], 1);
  3378. reset($labelImPath);
  3379. $imPath = $this->setLabelValueArray($fA['im_path'], 0);
  3380. reset($imPath);
  3381. // Define the markers content
  3382. $regularModeMarkers['labelImPath'] = '[GFX][im_path]=';
  3383. $regularModeMarkers['strongImPath'] = (string) current($labelImPath);
  3384. $regularModeMarkers['defaultImPath'] = (string) $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_path'];
  3385. $regularModeMarkers['ImPath'] = (string) current($imPath);
  3386. // Fill the markers in the subpart
  3387. $imPathSubpart = t3lib_parsehtml::substituteMarkerArray(
  3388. $imPathSubpart,
  3389. $regularModeMarkers,
  3390. '###|###',
  3391. TRUE,
  3392. FALSE
  3393. );
  3394. }
  3395. // IM Path LZW
  3396. if (is_array($fA['im_path_lzw'])) {
  3397. // Get the subpart for ImageMagick lzw path
  3398. $imPathLzwSubpart = t3lib_parsehtml::getSubpart($regularModeSubpart, '###IMPATHLZWSUBPART###');
  3399. // Get the subpart for ImageMagick lzw path dropdown options
  3400. $imPathOptionSubpart = t3lib_parsehtml::getSubpart($regularModeSubpart, '###IMPATHLZWOPTION###');
  3401. $labelImPathLzw = $this->setLabelValueArray($fA['im_path_lzw'], 1);
  3402. reset($labelImPathLzw);
  3403. $imPathLzw = $this->setLabelValueArray($fA['im_path_lzw'], 0);
  3404. reset($imPathLzw);
  3405. // Define the markers content
  3406. $regularModeMarkers['labelImPathLzw'] = '[GFX][im_path_lzw]=';
  3407. $regularModeMarkers['strongImPathLzw'] = (string) current($labelImPathLzw);
  3408. $regularModeMarkers['defaultImPathLzw'] = (string) $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_path_lzw'];
  3409. $regularModeMarkers['ImPathLzw'] = (string) current($imPathLzw);
  3410. $imPathLzwOptions = array();
  3411. foreach ($labelImPathLzw as $k => $v) {
  3412. list($cleanV) = explode('|', $fA['im_path_lzw'][$k]);
  3413. // Define the markers content
  3414. $imPathLzwMarker = array(
  3415. 'value' => htmlspecialchars($fA['im_path_lzw'][$k]),
  3416. 'data' => htmlspecialchars($v)
  3417. );
  3418. if (!strcmp($GLOBALS['TYPO3_CONF_VARS']['GFX']['im_path_lzw'], $cleanV)) {
  3419. $imPathLzwMarker['selected'] = 'selected="selected"';
  3420. }
  3421. // Fill the markers in the subpart
  3422. $imPathLzwOptions[] = t3lib_parsehtml::substituteMarkerArray(
  3423. $imPathOptionSubpart,
  3424. $imPathLzwMarker,
  3425. '###|###',
  3426. TRUE,
  3427. FALSE
  3428. );
  3429. }
  3430. // Substitute the subpart for ImageMagick lzw path dropdown options
  3431. $imPathLzwSubpart = t3lib_parsehtml::substituteSubpart(
  3432. $imPathLzwSubpart,
  3433. '###IMPATHLZWOPTION###',
  3434. implode(LF, $imPathLzwOptions)
  3435. );
  3436. // Fill the markers in the subpart
  3437. $imPathLzwSubpart = t3lib_parsehtml::substituteMarkerArray(
  3438. $imPathLzwSubpart,
  3439. $regularModeMarkers,
  3440. '###|###',
  3441. TRUE,
  3442. FALSE
  3443. );
  3444. }
  3445. }
  3446. }
  3447. // Substitute the subpart for ImageMagick
  3448. $regularModeSubpart = t3lib_parsehtml::substituteSubpart(
  3449. $regularModeSubpart,
  3450. '###IMAGEMAGICKSUBPART###',
  3451. $imageMagickSubpart
  3452. );
  3453. // Substitute the subpart for ImageMagick Combine filename
  3454. $regularModeSubpart = t3lib_parsehtml::substituteSubpart(
  3455. $regularModeSubpart,
  3456. '###IMCOMBINEFILENAMESUBPART###',
  3457. $imCombineFileNameSubpart
  3458. );
  3459. // Substitute the subpart for ImageMagick Version 5
  3460. $regularModeSubpart = t3lib_parsehtml::substituteSubpart(
  3461. $regularModeSubpart,
  3462. '###IMVERSION5SUBPART###',
  3463. $imVersion5Subpart
  3464. );
  3465. // Substitute the subpart for ImageMagick path
  3466. $regularModeSubpart = t3lib_parsehtml::substituteSubpart(
  3467. $regularModeSubpart,
  3468. '###IMPATHSUBPART###',
  3469. $imPathSubpart
  3470. );
  3471. // Substitute the subpart for ImageMagick lzw path
  3472. $regularModeSubpart = t3lib_parsehtml::substituteSubpart(
  3473. $regularModeSubpart,
  3474. '###IMPATHLZWSUBPART###',
  3475. $imPathLzwSubpart
  3476. );
  3477. // TrueType Font dpi
  3478. // Get the subpart for TrueType dpi
  3479. $ttfDpiSubpart = t3lib_parsehtml::getSubpart($regularModeSubpart, '###TTFDPISUBPART###');
  3480. // Define the markers content
  3481. $regularModeMarkers['labelTtfDpi'] = '[GFX][TTFdpi]=';
  3482. $regularModeMarkers['ttfDpi'] = htmlspecialchars($GLOBALS['TYPO3_CONF_VARS']['GFX']['TTFdpi']);
  3483. // Fill the markers in the subpart
  3484. $ttfDpiSubpart = t3lib_parsehtml::substituteMarkerArray(
  3485. $ttfDpiSubpart,
  3486. $regularModeMarkers,
  3487. '###|###',
  3488. TRUE,
  3489. FALSE
  3490. );
  3491. // Substitute the subpart for TrueType dpi
  3492. $regularModeSubpart = t3lib_parsehtml::substituteSubpart(
  3493. $regularModeSubpart,
  3494. '###TTFDPISUBPART###',
  3495. $ttfDpiSubpart
  3496. );
  3497. // Fill the markers in the regular mode subpart
  3498. $regularModeSubpart = t3lib_parsehtml::substituteMarkerArray(
  3499. $regularModeSubpart,
  3500. $regularModeMarkers,
  3501. '###|###',
  3502. TRUE,
  3503. FALSE
  3504. );
  3505. }
  3506. $formMarkers['labelUpdateLocalConf'] = 'Update localconf.php';
  3507. $formMarkers['labelNotice'] = 'NOTICE:';
  3508. $formMarkers['labelCommentUpdateLocalConf'] = 'By clicking this button, localconf.php is updated with new values for the parameters listed above!';
  3509. // Substitute the subpart for regular mode
  3510. $form = t3lib_parsehtml::substituteSubpart(
  3511. $form,
  3512. '###REGULARMODE###',
  3513. $regularModeSubpart
  3514. );
  3515. // Fill the markers
  3516. $out = t3lib_parsehtml::substituteMarkerArray(
  3517. $form,
  3518. $formMarkers,
  3519. '###|###',
  3520. TRUE,
  3521. FALSE
  3522. );
  3523. break;
  3524. default:
  3525. if (is_array($this->INSTALL['localconf.php'])) {
  3526. $lines = $this->writeToLocalconf_control();
  3527. // New database?
  3528. if (trim($this->INSTALL['localconf.php']['NEW_DATABASE_NAME'])) {
  3529. $newdbname=trim($this->INSTALL['localconf.php']['NEW_DATABASE_NAME']);
  3530. if (!preg_match('/[^[:alnum:]_-]/',$newdbname)) {
  3531. if ($result = $GLOBALS['TYPO3_DB']->sql_pconnect(TYPO3_db_host, TYPO3_db_username, TYPO3_db_password)) {
  3532. if ($GLOBALS['TYPO3_DB']->admin_query('CREATE DATABASE '.$newdbname)) {
  3533. $this->INSTALL['localconf.php']['typo_db'] = $newdbname;
  3534. $this->messages[]= "Database '".$newdbname."' created";
  3535. } else {
  3536. $this->errorMessages[] = '
  3537. Could not create database \'' .
  3538. $newdbname . '\' (...not created)
  3539. ';
  3540. }
  3541. } else {
  3542. $this->errorMessages[] = '
  3543. Could not connect to database when creating
  3544. database \'' . $newdbname . '\' (...not
  3545. created)
  3546. ';
  3547. }
  3548. } else {
  3549. $this->errorMessages[] = '
  3550. The NEW database name \'' . $newdbname . '\' was
  3551. not alphanumeric, a-zA-Z0-9_- (...not created)
  3552. ';
  3553. }
  3554. }
  3555. // Parsing values
  3556. foreach ($this->INSTALL['localconf.php'] as $key => $value) {
  3557. switch((string)$key) {
  3558. case 'typo_db_username':
  3559. if (strlen($value)<50) {
  3560. if (strcmp(TYPO3_db_username,$value)) $this->setValueInLocalconfFile($lines, '$typo_db_username', trim($value));
  3561. } else {
  3562. $this->errorMessages[] = '
  3563. Username \'' . $value . '\' was longer
  3564. than 50 chars (...not saved)
  3565. ';
  3566. }
  3567. break;
  3568. case 'typo_db_password':
  3569. if (strlen($value)<50) {
  3570. if (strcmp(TYPO3_db_password,$value)) $this->setValueInLocalconfFile($lines, '$typo_db_password', trim($value));
  3571. } else {
  3572. $this->errorMessages[] = '
  3573. Password was longer than 50 chars (...not saved)
  3574. ';
  3575. }
  3576. break;
  3577. case 'typo_db_host':
  3578. if (preg_match('/^[a-zA-Z0-9_\.-]+(:.+)?$/',$value) && strlen($value)<50) {
  3579. if (strcmp(TYPO3_db_host,$value)) $this->setValueInLocalconfFile($lines, '$typo_db_host', $value);
  3580. } else {
  3581. $this->errorMessages[] = '
  3582. Host \'' . $value . '\' was not
  3583. alphanumeric (a-z, A-Z, 0-9 or _-.), or
  3584. longer than 50 chars (...not saved)
  3585. ';
  3586. }
  3587. break;
  3588. case 'typo_db':
  3589. if (strlen($value)<50) {
  3590. if (strcmp(TYPO3_db,$value)) $this->setValueInLocalconfFile($lines, '$typo_db', trim($value));
  3591. } else {
  3592. $this->errorMessages[] = '
  3593. Database name \'' . $value . '\' was
  3594. longer than 50 chars (...not saved)
  3595. ';
  3596. }
  3597. break;
  3598. case 'disable_exec_function':
  3599. if (strcmp($GLOBALS['TYPO3_CONF_VARS']['BE']['disable_exec_function'],$value)) $this->setValueInLocalconfFile($lines, '$TYPO3_CONF_VARS[\'BE\'][\'disable_exec_function\']', $value?1:0);
  3600. break;
  3601. case 'sitename':
  3602. if (strcmp($GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'],$value)) $this->setValueInLocalconfFile($lines, '$TYPO3_CONF_VARS[\'SYS\'][\'sitename\']', $value);
  3603. break;
  3604. case 'encryptionKey':
  3605. if (strcmp($GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'],$value)) $this->setValueInLocalconfFile($lines, '$TYPO3_CONF_VARS[\'SYS\'][\'encryptionKey\']', $value);
  3606. break;
  3607. case 'compat_version':
  3608. if (strcmp($GLOBALS['TYPO3_CONF_VARS']['SYS']['compat_version'],$value)) $this->setValueInLocalconfFile($lines, '$TYPO3_CONF_VARS[\'SYS\'][\'compat_version\']', $value);
  3609. break;
  3610. case 'im_combine_filename':
  3611. if (strcmp($GLOBALS['TYPO3_CONF_VARS']['GFX']['im_combine_filename'],$value)) $this->setValueInLocalconfFile($lines, '$TYPO3_CONF_VARS[\'GFX\'][\'im_combine_filename\']', $value);
  3612. break;
  3613. case 'gdlib':
  3614. case 'gdlib_png':
  3615. case 'im':
  3616. if (strcmp($GLOBALS['TYPO3_CONF_VARS']['GFX'][$key], $value)) {
  3617. $this->setValueInLocalconfFile($lines, '$TYPO3_CONF_VARS[\'GFX\'][\'' . $key . '\']', ($value ? 1 : 0));
  3618. }
  3619. break;
  3620. case 'im_path':
  3621. list($value,$version) = explode('|',$value);
  3622. if (strcmp($GLOBALS['TYPO3_CONF_VARS']['GFX'][$key], $value)) {
  3623. $this->setValueInLocalconfFile($lines, '$TYPO3_CONF_VARS[\'GFX\'][\'' . $key . '\']', $value);
  3624. }
  3625. if (doubleval($version) > 0 && doubleval($version) < 4) {
  3626. // Assume GraphicsMagick
  3627. $value_ext = 'gm';
  3628. } elseif (doubleval($version) < 5) {
  3629. // Assume ImageMagick 4.x
  3630. $value_ext = '';
  3631. } elseif (doubleval($version) >= 6) {
  3632. // Assume ImageMagick 6.x
  3633. $value_ext = 'im6';
  3634. } else {
  3635. // Assume ImageMagick 5.x
  3636. $value_ext = 'im5';
  3637. }
  3638. if (strcmp(strtolower($GLOBALS['TYPO3_CONF_VARS']['GFX']['im_version_5']), $value_ext)) {
  3639. $this->setValueInLocalconfFile($lines, '$TYPO3_CONF_VARS[\'GFX\'][\'im_version_5\']', $value_ext);
  3640. }
  3641. break;
  3642. case 'im_path_lzw':
  3643. list($value) = explode('|',$value);
  3644. if (strcmp($GLOBALS['TYPO3_CONF_VARS']['GFX'][$key], $value)) {
  3645. $this->setValueInLocalconfFile($lines, '$TYPO3_CONF_VARS[\'GFX\'][\'' . $key . '\']', $value);
  3646. }
  3647. break;
  3648. case 'TTFdpi':
  3649. if (strcmp($GLOBALS['TYPO3_CONF_VARS']['GFX']['TTFdpi'],$value)) $this->setValueInLocalconfFile($lines, '$TYPO3_CONF_VARS[\'GFX\'][\'TTFdpi\']', $value);
  3650. break;
  3651. }
  3652. }
  3653. // Hook to modify localconf.php lines in the 1-2-3 installer
  3654. if (is_array ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install/mod/class.tx_install.php']['writeLocalconf'])) {
  3655. foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install/mod/class.tx_install.php']['writeLocalconf'] as $classData) {
  3656. $hookObject = t3lib_div::getUserObj($classData);
  3657. $hookObject->executeWriteLocalconf($lines, $this->step, $this);
  3658. }
  3659. }
  3660. $this->writeToLocalconf_control($lines);
  3661. }
  3662. break;
  3663. }
  3664. return $out;
  3665. }
  3666. /**
  3667. * Writes or returns lines from localconf.php
  3668. *
  3669. * @param array $lines Array of lines to write back to localconf.php. Possibly
  3670. * @param boolean $showOutput If TRUE then print what has been done.
  3671. * @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)
  3672. * @see parent::writeToLocalconf_control()
  3673. */
  3674. function writeToLocalconf_control($lines='', $showOutput=TRUE) {
  3675. // Get the template file
  3676. $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'WriteToLocalConfControl.html');
  3677. $returnVal = parent::writeToLocalconf_control($lines);
  3678. if ($showOutput) {
  3679. switch($returnVal) {
  3680. case 'continue':
  3681. // Get the template part from the file
  3682. $template = t3lib_parsehtml::getSubpart($templateFile, '###CONTINUE###');
  3683. // Get the subpart for messages
  3684. $messagesSubPart = t3lib_parsehtml::getSubpart($template, '###MESSAGES###');
  3685. $messages = array();
  3686. foreach ($this->messages as $message) {
  3687. // Define the markers content
  3688. $messagesMarkers['message'] = $message;
  3689. // Fill the markers in the subpart
  3690. $messages[] = t3lib_parsehtml::substituteMarkerArray(
  3691. $messagesSubPart,
  3692. $messagesMarkers,
  3693. '###|###',
  3694. TRUE,
  3695. FALSE
  3696. );
  3697. }
  3698. // Substitute the subpart for messages
  3699. $content = t3lib_parsehtml::substituteSubpart(
  3700. $template,
  3701. '###MESSAGES###',
  3702. implode(LF, $messages)
  3703. );
  3704. // Define the markers content
  3705. $markers = array(
  3706. 'header' => 'Writing to \'localconf.php\'',
  3707. 'action' => $this->action,
  3708. 'label' => 'Click to continue...'
  3709. );
  3710. // Fill the markers
  3711. $content = t3lib_parsehtml::substituteMarkerArray(
  3712. $content,
  3713. $markers,
  3714. '###|###',
  3715. TRUE,
  3716. FALSE
  3717. );
  3718. $this->outputExitBasedOnStep($content);
  3719. break;
  3720. case 'nochange':
  3721. // Get the template part from the file
  3722. $template = t3lib_parsehtml::getSubpart($templateFile, '###NOCHANGE###');
  3723. // Define the markers content
  3724. $markers = array(
  3725. 'header' => 'Writing to \'localconf.php\'',
  3726. 'message' => 'No values were changed, so nothing is updated!',
  3727. 'action' => $this->action,
  3728. 'label' => 'Click to continue...'
  3729. );
  3730. // Fill the markers
  3731. $content = t3lib_parsehtml::substituteMarkerArray(
  3732. $template,
  3733. $markers,
  3734. '###|###',
  3735. TRUE,
  3736. FALSE
  3737. );
  3738. $this->outputExitBasedOnStep($content);
  3739. break;
  3740. }
  3741. }
  3742. return $returnVal;
  3743. }
  3744. /**
  3745. * If in 1-2-3 mode, send a redirect header response with the action and exit
  3746. * otherwise send output to output() function
  3747. *
  3748. * @param string $content The HTML to output
  3749. * @return void
  3750. */
  3751. function outputExitBasedOnStep($content) {
  3752. if ($this->step) {
  3753. t3lib_utility_Http::redirect($this->action);
  3754. } else {
  3755. $this->output($this->outputWrapper($content));
  3756. }
  3757. exit;
  3758. }
  3759. /**
  3760. * This appends something to value in the input array based on $type. Private.
  3761. *
  3762. * @param array $arr
  3763. * @param integer $type
  3764. * @return array
  3765. */
  3766. function setLabelValueArray($arr,$type) {
  3767. foreach ($arr as $k => $v) {
  3768. if($this->config_array['im_versions'][$v]['gm']) {
  3769. $program = 'gm';
  3770. } else {
  3771. $program = 'convert';
  3772. }
  3773. switch($type) {
  3774. // value, im
  3775. case 0:
  3776. $arr[$k].='|'.$this->config_array['im_versions'][$v][$program];
  3777. break;
  3778. // labels, im
  3779. case 1:
  3780. if($this->config_array['im_versions'][$v][$program]) {
  3781. $arr[$k].= ' ('.$this->config_array['im_versions'][$v][$program];
  3782. $arr[$k].= ($this->config_array['im_versions'][$v]['gif_capability'] ? ', '.$this->config_array['im_versions'][$v]['gif_capability'] : '');
  3783. $arr[$k].= ')';
  3784. } else {
  3785. $arr[$k].= '';
  3786. }
  3787. break;
  3788. // labels, gd
  3789. case 2:
  3790. $arr[$k].=' ('.($v==1?'PNG':'GIF').')';
  3791. break;
  3792. }
  3793. }
  3794. return $arr;
  3795. }
  3796. /**
  3797. * Returns the list of available databases (with access-check based on username/password)
  3798. *
  3799. * @return array List of available databases
  3800. */
  3801. public function getDatabaseList() {
  3802. $dbArr = array();
  3803. if ($result = $GLOBALS['TYPO3_DB']->sql_pconnect(TYPO3_db_host, TYPO3_db_username, TYPO3_db_password)) {
  3804. $dbArr = $GLOBALS['TYPO3_DB']->admin_get_dbs();
  3805. }
  3806. return $dbArr;
  3807. }
  3808. /**
  3809. * Calculates the suggested setup that should be written to localconf.php
  3810. *
  3811. * If safe_mode
  3812. * - disable_exec_function = 1
  3813. * - im = 0
  3814. *
  3815. * if PNG/GIF/GD
  3816. * - disable gdlib if nothing
  3817. * - select png/gif if only one of them is available, else PNG/GIF selector, defaulting to GIF
  3818. * - (safe_mode is on)
  3819. * - 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+
  3820. * - im_path_lzw (default to LZW version, pref. 4.2.9)
  3821. *
  3822. * @return array Suggested setup
  3823. */
  3824. function setupGeneralCalculate() {
  3825. $formArray['disable_exec_function']=array(0);
  3826. $formArray['im_path']=array('');
  3827. $formArray['im_path_lzw']=array('');
  3828. $formArray['im_combine_filename']=array('');
  3829. $formArray['im_version_5']=array('');
  3830. $formArray['im']=array(1);
  3831. $formArray['gdlib']=array(1);
  3832. if ($this->config_array['gd'] && ($this->config_array['gd_gif'] || $this->config_array['gd_png'])) {
  3833. if ($this->config_array['gd_gif'] && !$this->config_array['gd_png']) {
  3834. $formArray['gdlib_png']=array(0);
  3835. } elseif (!$this->config_array['gd_gif'] && $this->config_array['gd_png']) {
  3836. $formArray['gdlib_png']=array(1);
  3837. } else {
  3838. $formArray['gdlib_png']=array(0,1);
  3839. }
  3840. } else {
  3841. $formArray['gdlib']=array(0);
  3842. }
  3843. if ($this->config_array['safemode']) {
  3844. $formArray['disable_exec_function']=array(1);
  3845. }
  3846. if ($this->config_array['im']) {
  3847. $formArray['im'] = array(1);
  3848. $found = $LZW_found = 0;
  3849. $totalArr = array();
  3850. foreach ($this->config_array['im_versions'] as $path => $dat) {
  3851. if (count($dat)>=3) {
  3852. if (doubleval($dat['convert'])<5) {
  3853. $formArray['im_version_5']=array(0);
  3854. if ($dat['gif_capability']=='LZW') {
  3855. $formArray['im_path']=array($path);
  3856. $found=2;
  3857. } elseif ($found<2) {
  3858. $formArray['im_path']=array($path);
  3859. $found=1;
  3860. }
  3861. } elseif (doubleval($dat['convert']) >= 6) {
  3862. $formArray['im_version_5'] = array('im6');
  3863. if ($dat['gif_capability'] == 'LZW') {
  3864. $formArray['im_path'] = array($path);
  3865. $found = 2;
  3866. } elseif ($found < 2) {
  3867. $formArray['im_path'] = array($path);
  3868. $found = 1;
  3869. }
  3870. } elseif (!$found) {
  3871. $formArray['im_version_5']=array('im5');
  3872. $formArray['im_path']=array($path);
  3873. $found=1;
  3874. }
  3875. } elseif ($dat['gm']) {
  3876. $formArray['im_version_5']=array('gm');
  3877. if ($dat['gif_capability']=='LZW') {
  3878. $formArray['im_path']=array($path);
  3879. $found=2;
  3880. } elseif ($found<2) {
  3881. $formArray['im_path']=array($path);
  3882. $found=1;
  3883. }
  3884. }
  3885. if ($dat['gif_capability']=='LZW') {
  3886. if (doubleval($dat['convert'])<5 || !$LZW_found) {
  3887. $formArray['im_path_lzw']=array($path);
  3888. $LZW_found=1;
  3889. }
  3890. } elseif ($dat['gif_capability']=="RLE" && !$LZW_found) {
  3891. $formArray['im_path_lzw']=array($path);
  3892. }
  3893. $totalArr[]=$path;
  3894. }
  3895. $formArray['im_path']=array_unique(array_merge($formArray['im_path'],$totalArr));
  3896. $formArray['im_path_lzw']=array_unique(array_merge($formArray['im_path_lzw'],$totalArr));
  3897. $formArray['im_combine_filename']=array($this->config_array['im_combine_filename']);
  3898. } else {
  3899. $formArray['im']=array(0);
  3900. }
  3901. return $formArray;
  3902. }
  3903. /**
  3904. * Returns true if TTF lib is installed.
  3905. *
  3906. * @return boolean TRUE if TrueType support
  3907. */
  3908. function isTTF() {
  3909. // Return right away if imageTTFtext does not exist.
  3910. if (!function_exists('imagettftext')) {
  3911. return 0;
  3912. }
  3913. // try, print truetype font:
  3914. $im = @imagecreate(300, 50);
  3915. $background_color = imagecolorallocate($im, 255, 255, 55);
  3916. $text_color = imagecolorallocate($im, 233, 14, 91);
  3917. $test = @imagettftext($im, t3lib_div::freetypeDpiComp(20), 0, 10, 20, $text_color, PATH_t3lib."/fonts/vera.ttf", 'Testing Truetype support');
  3918. if (t3lib_div::_GP('testingTrueTypeSupport')) {
  3919. if ($this->isGIF()) {
  3920. header('Content-type: image/gif');
  3921. imagegif($im);
  3922. } else {
  3923. header('Content-type: image/png');
  3924. imagepng($im);
  3925. }
  3926. exit;
  3927. }
  3928. return (is_array($test) ? 1 : 0);
  3929. }
  3930. /**
  3931. * Checks if the essential PHP modules are loaded
  3932. *
  3933. * @return array list of modules which are missing
  3934. */
  3935. protected function getMissingPhpModules() {
  3936. // Hook to adjust the required PHP modules in the 1-2-3 installer
  3937. $modules = $this->requiredPhpModules;
  3938. if (is_array ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install/mod/class.tx_install.php']['requiredPhpModules'])) {
  3939. foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install/mod/class.tx_install.php']['requiredPhpModules'] as $classData) {
  3940. $hookObject = t3lib_div::getUserObj($classData);
  3941. $modules = $hookObject->setRequiredPhpModules($modules, $this);
  3942. }
  3943. }
  3944. $this->requiredPhpModules = $modules;
  3945. $result = array();
  3946. foreach ($this->requiredPhpModules as $module) {
  3947. if (is_array($module)) {
  3948. $detectedSubmodules = FALSE;
  3949. foreach ($module as $submodule) {
  3950. if (extension_loaded($submodule)) {
  3951. $detectedSubmodules = TRUE;
  3952. }
  3953. }
  3954. if ($detectedSubmodules === FALSE) {
  3955. $result[] = 'one of: (' . implode(', ', $module) . ')';
  3956. }
  3957. } else {
  3958. if (!extension_loaded($module)) {
  3959. $result[] = $module;
  3960. }
  3961. }
  3962. }
  3963. return $result;
  3964. }
  3965. /*****************************************
  3966. *
  3967. * ABOUT the isXXX functions.
  3968. *
  3969. * I had a very real experience that these checks DID NOT fail eg PNG support if it didn't exist!
  3970. * 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.
  3971. * And if THAT succeeds also, then we can be certain of the support!
  3972. */
  3973. /**
  3974. * Check if GD module is available by checking the function imagecreate
  3975. *
  3976. * @return boolean TRUE if GD is available
  3977. */
  3978. function isGD() {
  3979. if (function_exists('imagecreatetruecolor')) {
  3980. if (@imagecreatetruecolor(50, 100)) {
  3981. return 1;
  3982. }
  3983. }
  3984. return 0;
  3985. }
  3986. /**
  3987. * Check if GIF functions are available
  3988. *
  3989. * @return boolean TRUE if GIF functions are available
  3990. */
  3991. function isGIF() {
  3992. // If GIF-functions exists, also do a real test of them:
  3993. if (function_exists('imagecreatefromgif') && function_exists('imagegif') && ($this->ImageTypes() & IMG_GIF)) {
  3994. $im = @imagecreatefromgif(t3lib_extMgm::extPath('install').'imgs/jesus.gif');
  3995. return ($im ? 1 : 0);
  3996. }
  3997. }
  3998. /**
  3999. * Check if JPG functions are available
  4000. *
  4001. * @return boolean TRUE if JPEG functions are available
  4002. */
  4003. function isJPG() {
  4004. if (function_exists('imagecreatefromjpeg') && function_exists('imagejpeg') && ($this->ImageTypes() & IMG_JPG)) {
  4005. return 1;
  4006. }
  4007. }
  4008. /**
  4009. * Check if PNG functions are available
  4010. *
  4011. * @return boolean TRUE if PNG functions are available
  4012. */
  4013. function isPNG() {
  4014. if (function_exists('imagecreatefrompng') && function_exists('imagepng') && ($this->ImageTypes() & IMG_PNG)) {
  4015. $im = imagecreatefrompng(t3lib_extMgm::extPath('install').'imgs/jesus.png');
  4016. return ($im ? 1 : 0);
  4017. }
  4018. }
  4019. /**
  4020. * Return the image types supported by this PHP build
  4021. *
  4022. * @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.
  4023. */
  4024. function ImageTypes() {
  4025. return imagetypes();
  4026. }
  4027. /**
  4028. * Returns general information about GDlib
  4029. *
  4030. * @return string HTML with GD lib information
  4031. */
  4032. function getGDSoftwareInfo() {
  4033. return '
  4034. <p>
  4035. You can get GDLib in the PNG version from
  4036. <a href="http://www.libgd.org/">http://www.libgd.org/</a>
  4037. <br />
  4038. FreeType is for download at
  4039. <a href="http://www.freetype.org/">http://www.freetype.org/</a>
  4040. <br />
  4041. Generally, TYPO3 packages are listed at
  4042. <a href="' . TYPO3_URL_DOWNLOAD . '">' . TYPO3_URL_DOWNLOAD . '</a>
  4043. </p>
  4044. ';
  4045. }
  4046. /**
  4047. * Returns general information about configuration of TYPO3.
  4048. *
  4049. * @return string HTML with the general information
  4050. */
  4051. function generallyAboutConfiguration() {
  4052. return '
  4053. <p>
  4054. Local configuration is done by overriding default values in the
  4055. included file, typo3conf/localconf.php. In this file you enter the
  4056. database information along with values in the global array
  4057. TYPO3_CONF_VARS.
  4058. <br />
  4059. The options in the TYPO3_CONF_VARS array and how to use it for your
  4060. own purposes is discussed in the base configuration file,
  4061. t3lib/config_default.php. This file sets up the default values and
  4062. subsequently includes the localconf.php file in which you can then
  4063. override values.
  4064. <br />
  4065. See this page for <a href="' . TYPO3_URL_SYSTEMREQUIREMENTS . '">more
  4066. information about system requirements.</a>
  4067. </p>';
  4068. }
  4069. /**********************
  4070. *
  4071. * IMAGE processing
  4072. *
  4073. **********************/
  4074. /**
  4075. * jesus.TIF: IBM/LZW
  4076. * jesus.GIF: Save for web, 32 colors
  4077. * jesus.JPG: Save for web, 30 quality
  4078. * jesus.PNG: Save for web, PNG-24
  4079. * jesus.tga 24 bit TGA file
  4080. * jesus.pcx
  4081. * jesus.bmp 24 bit BMP file
  4082. * jesus_ps6.PDF: PDF w/layers and vector data
  4083. * typo3logo.ai: Illustrator 8 file
  4084. * pdf_from_imagemagick.PDF PDF-file made by Acrobat Distiller from InDesign PS-file
  4085. *
  4086. *
  4087. * Imagemagick
  4088. * - Read formats
  4089. * - Write png, gif, jpg
  4090. *
  4091. * Problems may arise from the use of safe_mode (eg. png)
  4092. * In safemode you will automatically execute the program convert in the safe_mode_exec_path no matter what other path you specify
  4093. * check fileexist before anything...
  4094. *
  4095. * - compare gif size
  4096. * - scaling (by stdgraphic)
  4097. * - combining (by stdgraphic)
  4098. *
  4099. * GDlib:
  4100. * - create from:....
  4101. * - ttf text
  4102. *
  4103. * From TypoScript: (GD only, GD+IM, IM)
  4104. *
  4105. * @return void
  4106. */
  4107. function checkTheImageProcessing() {
  4108. $this->message('Image Processing', 'What is it?', '
  4109. <p>
  4110. TYPO3 is known for its ability to process images on the server.
  4111. <br />
  4112. In the backend interface (TBE) thumbnails are automatically
  4113. generated (by ImageMagick in thumbs.php) as well as icons, menu
  4114. items and pane tabs (by GDLib).
  4115. <br />
  4116. In the TypoScript enabled frontend all kinds of graphical
  4117. elements are processed. Typically images are scaled down to fit
  4118. the pages (by ImageMagick) and menu items, graphical headers and
  4119. such are generated automatically (by GDLib + ImageMagick).
  4120. <br />
  4121. In addition TYPO3 is able to handle many file formats (thanks to
  4122. ImageMagick), for example TIF, BMP, PCX, TGA, AI and PDF in
  4123. addition to the standard web formats; JPG, GIF, PNG.
  4124. </p>
  4125. <p>
  4126. In order to do this, TYPO3 uses two sets of tools:
  4127. </p>
  4128. <p>
  4129. <strong>ImageMagick / GraphicsMagick:</strong>
  4130. <br />
  4131. For conversion of non-web formats to webformats, combining
  4132. images with alpha-masks, performing image-effects like blurring
  4133. and sharpening.
  4134. <br />
  4135. ImageMagick is a collection of external programs on the server
  4136. called by the exec() function in PHP. TYPO3 uses three of these,
  4137. namely \'convert\' (converting fileformats, scaling, effects),
  4138. \'combine\'/\'composite\' (combining images with masks) and
  4139. \'identify\' (returns image information).
  4140. GraphicsMagick is an alternative to ImageMagick and can be enabled
  4141. by setting [GFX][im_version_5] to \'gm\'. This is recommended and
  4142. enabled by default.
  4143. <br />
  4144. Because ImageMagick and Graphicsmagick are external programs, two
  4145. requirements must be met: 1) The programs must be installed on the
  4146. server and working and 2) if safe_mode is enabled, the programs must
  4147. be located in the folder defined by the php.ini setting,
  4148. <em>safe_mode_exec_dir</em> (else they are not executed).
  4149. <br />
  4150. ImageMagick is available for both Windows and Unix. The current
  4151. version is 6+.
  4152. <br />
  4153. ImageMagick homepage is at <a href="http://www.imagemagick.org/">http://www.imagemagick.org/</a>
  4154. </p>
  4155. <p>
  4156. <strong>GDLib:</strong>
  4157. <br />
  4158. For drawing boxes and rendering text on images with truetype
  4159. fonts. Also used for icons, menuitems and generally the
  4160. TypoScript GIFBUILDER object is based on GDlib, but extensively
  4161. utilizing ImageMagick to process intermediate results.
  4162. <br />
  4163. GDLib is accessed through internal functions in PHP, so in this
  4164. case, you have no safe_mode problems, but you\'ll need a version
  4165. of PHP with GDLib compiled in. Also in order to use TrueType
  4166. fonts with GDLib you\'ll need FreeType compiled in as well.
  4167. <br />
  4168. </p>
  4169. ' . $this->getGDSoftwareInfo() . '
  4170. <p>
  4171. You can disable all image processing options in TYPO3
  4172. ([GFX][image_processing]=0), but that would seriously disable
  4173. TYPO3.
  4174. </p>
  4175. ');
  4176. $this->message('Image Processing', 'Verifying the image processing capabilities of your server', '
  4177. <p>
  4178. This page performs image processing and displays the result.
  4179. It\'s a thorough check that everything you\'ve configured is
  4180. working correctly.
  4181. <br />
  4182. It\'s quite simple to verify your installation; Just look down
  4183. the page, the images in pairs should look like each other. If
  4184. some images are not alike, something is wrong. You may also
  4185. notice warnings and errors if this tool found signs of any
  4186. problems.
  4187. </p>
  4188. <p>
  4189. The image to the right is the reference image (how it should be)
  4190. and to the left the image made by your server.
  4191. <br />
  4192. The reference images are made with the classic ImageMagick
  4193. install based on the 4.2.9 RPM and 5.2.3 RPM. If the version 5
  4194. flag is set, the reference images are made by the 5.2.3 RPM.
  4195. </p>
  4196. <p>
  4197. This test will work only if your ImageMagick/GDLib configuration
  4198. allows it to. The typo3temp/ folder must be writable for all the
  4199. temporary image files. They are all prefixed \'install_\' so
  4200. they are easy to recognize and delete afterwards.
  4201. </p>
  4202. ');
  4203. $im_path = $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_path'];
  4204. if ($GLOBALS['TYPO3_CONF_VARS']['GFX']['im_version_5']=='gm') {
  4205. $im_path_version = $this->config_array['im_versions'][$im_path]['gm'];
  4206. } else {
  4207. $im_path_version = $this->config_array['im_versions'][$im_path]['convert'];
  4208. }
  4209. $im_path_lzw = $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_path_lzw'];
  4210. $im_path_lzw_version = $this->config_array['im_versions'][$im_path_lzw]['convert'];
  4211. $msg = '
  4212. <dl id="t3-install-imageprocessingim">
  4213. <dt>
  4214. ImageMagick enabled:
  4215. </dt>
  4216. <dd>
  4217. ' . htmlspecialchars($GLOBALS['TYPO3_CONF_VARS']['GFX']['im']) . '
  4218. </dd>
  4219. <dt>
  4220. ImageMagick path:
  4221. </dt>
  4222. <dd>
  4223. ' . htmlspecialchars($im_path) . ' <span>(' . htmlspecialchars($im_path_version) . ')</span>
  4224. </dd>
  4225. <dt>
  4226. ImageMagick path/LZW:
  4227. </dt>
  4228. <dd>
  4229. ' . htmlspecialchars($im_path_lzw) . ' <span>(' . htmlspecialchars($im_path_lzw_version) . ')</span>
  4230. </dd>
  4231. <dt>
  4232. Version 5/GraphicsMagick flag:
  4233. </dt>
  4234. <dd>
  4235. ' . ($GLOBALS['TYPO3_CONF_VARS']['GFX']['im_version_5'] ? htmlspecialchars($GLOBALS['TYPO3_CONF_VARS']['GFX']['im_version_5']) : '&nbsp;') . '
  4236. </dd>
  4237. </dl>
  4238. <dl id="t3-install-imageprocessingother">
  4239. <dt>
  4240. GDLib enabled:
  4241. </dt>
  4242. <dd>
  4243. ' . ($GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib'] ? htmlspecialchars($GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib']) : '&nbsp;') . '
  4244. </dd>
  4245. <dt>
  4246. GDLib using PNG:
  4247. </dt>
  4248. <dd>
  4249. ' . ($GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib_png'] ? htmlspecialchars($GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib_png']) : '&nbsp;') . '
  4250. </dd>
  4251. <dt>
  4252. IM5 effects enabled:
  4253. </dt>
  4254. <dd>
  4255. ' . htmlspecialchars($GLOBALS['TYPO3_CONF_VARS']['GFX']['im_v5effects']) . '
  4256. <span>(Blurring/Sharpening with IM 5+)</span>
  4257. </dd>
  4258. <dt>
  4259. Freetype DPI:
  4260. </dt>
  4261. <dd>
  4262. ' . htmlspecialchars($GLOBALS['TYPO3_CONF_VARS']['GFX']['TTFdpi']) . '
  4263. <span>(Should be 96 for Freetype 2)</span>
  4264. </dd>
  4265. <dt>
  4266. Mask invert:
  4267. </dt>
  4268. <dd>
  4269. ' . htmlspecialchars($GLOBALS['TYPO3_CONF_VARS']['GFX']['im_imvMaskState']) . '
  4270. <span>(Should be set for some IM versions approx. 5.4+)</span>
  4271. </dd>
  4272. </dl>
  4273. <dl id="t3-install-imageprocessingfileformats">
  4274. <dt>
  4275. File Formats:
  4276. </dt>
  4277. <dd>
  4278. ' . htmlspecialchars($GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext']) . '
  4279. </dd>
  4280. </dl>
  4281. ';
  4282. // Various checks to detect IM/GM version mismatches
  4283. $mismatch=false;
  4284. switch (strtolower($GLOBALS['TYPO3_CONF_VARS']['GFX']['im_version_5'])) {
  4285. case 'gm':
  4286. if (doubleval($im_path_version)>=2) $mismatch=true;
  4287. break;
  4288. case 'im4':
  4289. if (doubleval($im_path_version)>=5) $mismatch=true;
  4290. break;
  4291. default:
  4292. if (($GLOBALS['TYPO3_CONF_VARS']['GFX']['im_version_5']?true:false) != (doubleval($im_path_version)>=5)) $mismatch=true;
  4293. break;
  4294. }
  4295. if ($mismatch) {
  4296. $msg .= '
  4297. <p>
  4298. Warning: Mismatch between the version of ImageMagick' .
  4299. ' (' . htmlspecialchars($im_path_version) . ') and the configuration of ' .
  4300. '[GFX][im_version_5] (' . htmlspecialchars($GLOBALS['TYPO3_CONF_VARS']['GFX']['im_version_5']) . ')
  4301. </p>
  4302. ';
  4303. $etype=2;
  4304. } else $etype=1;
  4305. if ($GLOBALS['TYPO3_CONF_VARS']['GFX']['im_version_5']=='gm') {
  4306. $msg = str_replace('ImageMagick','GraphicsMagick',$msg);
  4307. }
  4308. $this->message('Image Processing', 'Current configuration',$msg,$etype);
  4309. if (!$GLOBALS['TYPO3_CONF_VARS']['GFX']['image_processing']) {
  4310. $this->message('Image Processing', 'Image Processing disabled!', '
  4311. <p>
  4312. Image Processing is disabled by the config flag
  4313. [GFX][image_processing] set to false (zero)
  4314. </p>
  4315. ', 2);
  4316. $this->output($this->outputWrapper($this->printAll()));
  4317. return;
  4318. }
  4319. if (!$this->config_array['dir_typo3temp']) {
  4320. $this->message('Image Processing', 'typo3temp/ not writable!', '
  4321. <p>
  4322. You must make typo3temp/ write enabled before you can
  4323. proceed with this test.
  4324. </p>
  4325. ', 2);
  4326. $this->output($this->outputWrapper($this->printAll()));
  4327. return;
  4328. }
  4329. $msg = '
  4330. <p>
  4331. <a id="testmenu"></a>
  4332. Click each of these links in turn to test a topic.
  4333. <strong>
  4334. Please be aware that each test may take several seconds!
  4335. </strong>:
  4336. </p>
  4337. ' . $this->imagemenu();
  4338. $this->message('Image Processing','Testmenu',$msg,'');
  4339. $parseStart = t3lib_div::milliseconds();
  4340. $imageProc = t3lib_div::makeInstance('t3lib_stdGraphic');
  4341. $imageProc->init();
  4342. $imageProc->tempPath = $this->typo3temp_path;
  4343. $imageProc->dontCheckForExistingTempFile=1;
  4344. // $imageProc->filenamePrefix='install_'.($GLOBALS['TYPO3_CONF_VARS']['GFX']['im_version_5']?"v5":"");
  4345. $imageProc->filenamePrefix='install_';
  4346. $imageProc->dontCompress=1;
  4347. $imageProc->alternativeOutputKey='TYPO3_INSTALL_SCRIPT';
  4348. $imageProc->noFramePrepended=$GLOBALS['TYPO3_CONF_VARS']['GFX']['im_noFramePrepended'];
  4349. // Very temporary!!!
  4350. $imageProc->dontUnlinkTempFiles=0;
  4351. $imActive = ($this->config_array['im'] && $im_path);
  4352. $gdActive = ($this->config_array['gd'] && $GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib']);
  4353. switch($this->INSTALL['images_type']) {
  4354. case 'read':
  4355. $refParseTime='5600'; // 4.2.9
  4356. $refParseTime='3300'; // 5.2.3
  4357. $headCode = 'Reading and converting images';
  4358. $this->message($headCode, 'Supported file formats', '
  4359. <p>
  4360. This verifies that your ImageMagick installation is able
  4361. to read the nine default file formats; JPG, GIF, PNG,
  4362. TIF, BMP, PCX, TGA, PDF, AI. The tool \'identify\' will
  4363. be used to read the pixeldimensions of non-web formats.
  4364. The tool \'convert\' is used to read the image and write
  4365. a temporary JPG-file
  4366. </p>
  4367. ');
  4368. if ($imActive) {
  4369. // Reading formats - writing JPG
  4370. $extArr = explode(',','jpg,gif,png,tif,bmp,pcx,tga');
  4371. foreach ($extArr as $ext) {
  4372. if ($this->isExtensionEnabled($ext, $headCode, "Read ".strtoupper($ext))) {
  4373. $imageProc->IM_commands=array();
  4374. $theFile = t3lib_extMgm::extPath('install').'imgs/jesus.'.$ext;
  4375. if (!@is_file($theFile)) die('Error: '.$theFile.' was not a file');
  4376. $imageProc->imageMagickConvert_forceFileNameBody='read_'.$ext;
  4377. $fileInfo = $imageProc->imageMagickConvert($theFile,'jpg',"",'',"",'',"",1);
  4378. $result = $this->displayTwinImage($fileInfo[3],$imageProc->IM_commands);
  4379. $this->message($headCode,"Read ".strtoupper($ext),$result[0],$result[1]);
  4380. }
  4381. }
  4382. if ($this->isExtensionEnabled('pdf', $headCode, 'Read PDF')) {
  4383. $imageProc->IM_commands=array();
  4384. $theFile = t3lib_extMgm::extPath('install').'imgs/pdf_from_imagemagick.pdf';
  4385. if (!@is_file($theFile)) die('Error: '.$theFile.' was not a file');
  4386. $imageProc->imageMagickConvert_forceFileNameBody='read_pdf';
  4387. $fileInfo = $imageProc->imageMagickConvert($theFile,'jpg',"170",'',"",'',"",1);
  4388. $result = $this->displayTwinImage($fileInfo[3],$imageProc->IM_commands);
  4389. $this->message($headCode,'Read PDF',$result[0],$result[1]);
  4390. }
  4391. if ($this->isExtensionEnabled('ai', $headCode, 'Read AI')) {
  4392. $imageProc->IM_commands=array();
  4393. $theFile = t3lib_extMgm::extPath('install').'imgs/typo3logotype.ai';
  4394. if (!@is_file($theFile)) die('Error: '.$theFile.' was not a file');
  4395. $imageProc->imageMagickConvert_forceFileNameBody='read_ai';
  4396. $fileInfo = $imageProc->imageMagickConvert($theFile,'jpg',"170",'',"",'',"",1);
  4397. $result = $this->displayTwinImage($fileInfo[3],$imageProc->IM_commands);
  4398. $this->message($headCode,'Read AI',$result[0],$result[1]);
  4399. }
  4400. } else {
  4401. $this->message($headCode, 'Test skipped', '
  4402. <p>
  4403. Use of ImageMagick has been disabled in the
  4404. configuration.
  4405. <br />
  4406. Refer to section \'Basic Configuration\' to change
  4407. or review you configuration settings
  4408. </p>
  4409. ', 2);
  4410. }
  4411. break;
  4412. case 'write':
  4413. $refParseTime='300';
  4414. // Writingformats - writing JPG
  4415. $headCode = 'Writing images';
  4416. $this->message($headCode, 'Writing GIF and PNG', '
  4417. <p>
  4418. This verifies that ImageMagick is able to write GIF and
  4419. PNG files.
  4420. <br />
  4421. The GIF-file is attempted compressed with LZW by the
  4422. t3lib_div::gif_compress() function.
  4423. </p>
  4424. ');
  4425. if ($imActive) {
  4426. // Writing GIF
  4427. $imageProc->IM_commands=array();
  4428. $theFile = t3lib_extMgm::extPath('install').'imgs/jesus.gif';
  4429. if (!@is_file($theFile)) die('Error: '.$theFile.' was not a file');
  4430. $imageProc->imageMagickConvert_forceFileNameBody='write_gif';
  4431. $fileInfo = $imageProc->imageMagickConvert($theFile,'gif',"",'',"",'',"",1);
  4432. if ($GLOBALS['TYPO3_CONF_VARS']['GFX']['gif_compress']) {
  4433. clearstatcache();
  4434. $prevSize=t3lib_div::formatSize(@filesize($fileInfo[3]));
  4435. $returnCode = t3lib_div::gif_compress($fileInfo[3],'');
  4436. clearstatcache();
  4437. $curSize=t3lib_div::formatSize(@filesize($fileInfo[3]));
  4438. $note = array('Note on gif_compress() function:',"The 'gif_compress' method used was '".$returnCode."'.<br />Previous filesize: ".$prevSize.'. Current filesize:'.$curSize);
  4439. } else $note=array('Note on gif_compress() function:','<em>Not used! Disabled by [GFX][gif_compress]</em>');
  4440. $result = $this->displayTwinImage($fileInfo[3],$imageProc->IM_commands, $note);
  4441. $this->message($headCode,'Write GIF',$result[0],$result[1]);
  4442. // Writing PNG
  4443. $imageProc->IM_commands=array();
  4444. $theFile = t3lib_extMgm::extPath('install').'imgs/jesus.gif';
  4445. $imageProc->imageMagickConvert_forceFileNameBody='write_png';
  4446. $fileInfo = $imageProc->imageMagickConvert($theFile,'png',"",'',"",'',"",1);
  4447. $result = $this->displayTwinImage($fileInfo[3],$imageProc->IM_commands);
  4448. $this->message($headCode,'Write PNG',$result[0],$result[1]);
  4449. } else {
  4450. $this->message($headCode, 'Test skipped', '
  4451. <p>
  4452. Use of ImageMagick has been disabled in the
  4453. configuration.
  4454. <br />
  4455. Refer to section \'Basic Configuration\' to change
  4456. or review you configuration settings
  4457. </p>
  4458. ', 2);
  4459. }
  4460. break;
  4461. case 'scaling':
  4462. $refParseTime='650';
  4463. // Scaling
  4464. $headCode = 'Scaling images';
  4465. $this->message($headCode, 'Scaling transparent images', '
  4466. <p>
  4467. This shows how ImageMagick reacts when scaling
  4468. transparent GIF and PNG files.
  4469. </p>
  4470. ');
  4471. if ($imActive) {
  4472. // Scaling transparent image
  4473. $imageProc->IM_commands=array();
  4474. $theFile = t3lib_extMgm::extPath('install').'imgs/jesus2_transp.gif';
  4475. if (!@is_file($theFile)) die('Error: '.$theFile.' was not a file');
  4476. $imageProc->imageMagickConvert_forceFileNameBody='scale_gif';
  4477. $fileInfo = $imageProc->imageMagickConvert($theFile,'gif',"150",'',"",'',"",1);
  4478. if ($GLOBALS['TYPO3_CONF_VARS']['GFX']['gif_compress']) {
  4479. clearstatcache();
  4480. $prevSize=t3lib_div::formatSize(@filesize($fileInfo[3]));
  4481. $returnCode = t3lib_div::gif_compress($fileInfo[3],'');
  4482. clearstatcache();
  4483. $curSize=t3lib_div::formatSize(@filesize($fileInfo[3]));
  4484. $note = array('Note on gif_compress() function:',"The 'gif_compress' method used was '".$returnCode."'.<br />Previous filesize: ".$prevSize.'. Current filesize:'.$curSize);
  4485. } else $note=array('Note on gif_compress() function:','<em>Not used! Disabled by [GFX][gif_compress]</em>');
  4486. $result = $this->displayTwinImage($fileInfo[3],$imageProc->IM_commands,$note);
  4487. $this->message($headCode,'GIF to GIF, 150 pixels wide',$result[0],$result[1]);
  4488. $imageProc->IM_commands=array();
  4489. $theFile = t3lib_extMgm::extPath('install').'imgs/jesus2_transp.png';
  4490. if (!@is_file($theFile)) die('Error: '.$theFile.' was not a file');
  4491. $imageProc->imageMagickConvert_forceFileNameBody='scale_png';
  4492. $fileInfo = $imageProc->imageMagickConvert($theFile,'png',"150",'',"",'',"",1);
  4493. $result = $this->displayTwinImage($fileInfo[3],$imageProc->IM_commands);
  4494. $this->message($headCode,'PNG to PNG, 150 pixels wide',$result[0],$result[1]);
  4495. $imageProc->IM_commands=array();
  4496. $theFile = t3lib_extMgm::extPath('install').'imgs/jesus2_transp.gif';
  4497. if (!@is_file($theFile)) die('Error: '.$theFile.' was not a file');
  4498. $imageProc->imageMagickConvert_forceFileNameBody='scale_jpg';
  4499. $fileInfo = $imageProc->imageMagickConvert($theFile,'jpg',"150",'',"",'',"",1);
  4500. $result = $this->displayTwinImage($fileInfo[3],$imageProc->IM_commands);
  4501. $this->message($headCode,'GIF to JPG, 150 pixels wide',$result[0],$result[1]);
  4502. } else {
  4503. $this->message($headCode, 'Test skipped', '
  4504. <p>
  4505. Use of ImageMagick has been disabled in the
  4506. configuration.
  4507. <br />
  4508. Refer to section \'Basic Configuration\' to change
  4509. or review you configuration settings
  4510. </p>
  4511. ', 2);
  4512. }
  4513. break;
  4514. case 'combining':
  4515. $refParseTime='150'; // 4.2.9
  4516. $refParseTime='250'; // 5.2.3
  4517. // Combine
  4518. $headCode = 'Combining images';
  4519. $this->message($headCode, 'Combining images', '
  4520. <p>
  4521. This verifies that the ImageMagick tool,
  4522. \'combine\'/\'composite\', is able to combine two images
  4523. through a grayscale mask.
  4524. <br />
  4525. If the masking seems to work but inverted, that just
  4526. means you\'ll have to make sure the invert flag is set
  4527. (some combination of im_negate_mask/im_imvMaskState)
  4528. </p>
  4529. ');
  4530. if ($imActive) {
  4531. $imageProc->IM_commands=array();
  4532. $input = t3lib_extMgm::extPath('install').'imgs/greenback.gif';
  4533. $overlay = t3lib_extMgm::extPath('install').'imgs/jesus.jpg';
  4534. $mask = t3lib_extMgm::extPath('install').'imgs/blackwhite_mask.gif';
  4535. if (!@is_file($input)) die('Error: '.$input.' was not a file');
  4536. if (!@is_file($overlay)) die('Error: '.$overlay.' was not a file');
  4537. if (!@is_file($mask)) die('Error: '.$mask.' was not a file');
  4538. $output = $imageProc->tempPath.$imageProc->filenamePrefix.t3lib_div::shortMD5($imageProc->alternativeOutputKey.'combine1').'.jpg';
  4539. $imageProc->combineExec($input,$overlay,$mask,$output, true);
  4540. $fileInfo = $imageProc->getImageDimensions($output);
  4541. $result = $this->displayTwinImage($fileInfo[3],$imageProc->IM_commands);
  4542. $this->message($headCode,'Combine using a GIF mask with only black and white',$result[0],$result[1]);
  4543. // Combine
  4544. $imageProc->IM_commands=array();
  4545. $input = t3lib_extMgm::extPath('install').'imgs/combine_back.jpg';
  4546. $overlay = t3lib_extMgm::extPath('install').'imgs/jesus.jpg';
  4547. $mask = t3lib_extMgm::extPath('install').'imgs/combine_mask.jpg';
  4548. if (!@is_file($input)) die('Error: '.$input.' was not a file');
  4549. if (!@is_file($overlay)) die('Error: '.$overlay.' was not a file');
  4550. if (!@is_file($mask)) die('Error: '.$mask.' was not a file');
  4551. $output = $imageProc->tempPath.$imageProc->filenamePrefix.t3lib_div::shortMD5($imageProc->alternativeOutputKey.'combine2').'.jpg';
  4552. $imageProc->combineExec($input,$overlay,$mask,$output, true);
  4553. $fileInfo = $imageProc->getImageDimensions($output);
  4554. $result = $this->displayTwinImage($fileInfo[3],$imageProc->IM_commands);
  4555. $this->message($headCode,'Combine using a JPG mask with graylevels',$result[0],$result[1]);
  4556. } else {
  4557. $this->message($headCode, 'Test skipped', '
  4558. <p>
  4559. Use of ImageMagick has been disabled in the
  4560. configuration.
  4561. <br />
  4562. Refer to section \'Basic Configuration\' to change
  4563. or review you configuration settings
  4564. </p>
  4565. ', 2);
  4566. }
  4567. break;
  4568. case 'gdlib':
  4569. // GIF / 4.2.9 / LZW (5.2.3)
  4570. $refParseTime='1800';
  4571. // PNG / 4.2.9 / LZW (5.2.3)
  4572. $refParseTime='2700';
  4573. // GIF / 5.2.3 / LZW (5.2.3)
  4574. $refParseTime='1600';
  4575. // GDLibrary
  4576. $headCode = 'GDLib';
  4577. $this->message($headCode, 'Testing GDLib', '
  4578. <p>
  4579. This verifies that the GDLib installation works properly.
  4580. </p>
  4581. ');
  4582. if ($gdActive) {
  4583. // GD with box
  4584. $imageProc->IM_commands=array();
  4585. $im = imagecreatetruecolor(170, 136);
  4586. $Bcolor = ImageColorAllocate ($im, 0, 0, 0);
  4587. ImageFilledRectangle($im, 0, 0, 170, 136, $Bcolor);
  4588. $workArea=array(0,0,170,136);
  4589. $conf=array(
  4590. 'dimensions' => '10,50,150,36',
  4591. 'color' => 'olive'
  4592. );
  4593. $imageProc->makeBox($im,$conf,$workArea);
  4594. $output = $imageProc->tempPath.$imageProc->filenamePrefix.t3lib_div::shortMD5('GDbox').'.'.$imageProc->gifExtension;
  4595. $imageProc->ImageWrite($im,$output);
  4596. $fileInfo = $imageProc->getImageDimensions($output);
  4597. $result = $this->displayTwinImage($fileInfo[3],$imageProc->IM_commands);
  4598. $this->message($headCode,'Create simple image',$result[0],$result[1]);
  4599. // GD from image with box
  4600. $imageProc->IM_commands=array();
  4601. $input = t3lib_extMgm::extPath('install').'imgs/jesus.'.$imageProc->gifExtension;
  4602. if (!@is_file($input)) die('Error: '.$input.' was not a file');
  4603. $im = $imageProc->imageCreateFromFile($input);
  4604. $workArea=array(0,0,170,136);
  4605. $conf=array();
  4606. $conf['dimensions']='10,50,150,36';
  4607. $conf['color']='olive';
  4608. $imageProc->makeBox($im,$conf,$workArea);
  4609. $output = $imageProc->tempPath.$imageProc->filenamePrefix.t3lib_div::shortMD5('GDfromImage+box').'.'.$imageProc->gifExtension;
  4610. $imageProc->ImageWrite($im,$output);
  4611. $fileInfo = $imageProc->getImageDimensions($output);
  4612. $GDWithBox_filesize = @filesize($output);
  4613. $result = $this->displayTwinImage($fileInfo[3],$imageProc->IM_commands);
  4614. $this->message($headCode,'Create image from file',$result[0],$result[1]);
  4615. // GD with text
  4616. $imageProc->IM_commands=array();
  4617. $im = imagecreatetruecolor(170, 136);
  4618. $Bcolor = ImageColorAllocate ($im, 128,128,150);
  4619. ImageFilledRectangle($im, 0, 0, 170, 136, $Bcolor);
  4620. $workArea=array(0,0,170,136);
  4621. $conf=array(
  4622. 'iterations' => 1,
  4623. 'angle' => 0,
  4624. 'antiAlias' => 1,
  4625. 'text' => 'HELLO WORLD',
  4626. 'fontColor' => '#003366',
  4627. 'fontSize' => 18,
  4628. 'fontFile' => $this->backPath.'../t3lib/fonts/vera.ttf',
  4629. 'offset' => '17,40'
  4630. );
  4631. $conf['BBOX'] = $imageProc->calcBBox($conf);
  4632. $imageProc->makeText($im,$conf,$workArea);
  4633. $output = $imageProc->tempPath.$imageProc->filenamePrefix.t3lib_div::shortMD5('GDwithText').'.'.$imageProc->gifExtension;
  4634. $imageProc->ImageWrite($im,$output);
  4635. $fileInfo = $imageProc->getImageDimensions($output);
  4636. $result = $this->displayTwinImage($fileInfo[3],$imageProc->IM_commands);
  4637. $this->message($headCode,'Render text with TrueType font',$result[0],$result[1]);
  4638. if ($imActive) {
  4639. // extension: GD with text, niceText
  4640. $conf['offset'] = '17,65';
  4641. $conf['niceText'] = 1;
  4642. $imageProc->makeText($im,$conf,$workArea);
  4643. $output = $imageProc->tempPath.$imageProc->filenamePrefix.t3lib_div::shortMD5('GDwithText-niceText').'.'.$imageProc->gifExtension;
  4644. $imageProc->ImageWrite($im,$output);
  4645. $fileInfo = $imageProc->getImageDimensions($output);
  4646. $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'."));
  4647. $this->message($headCode, 'Render text with TrueType font using \'niceText\' option', '
  4648. <p>
  4649. (If the image has another background color than
  4650. the image above (eg. dark background color with
  4651. light text) then you will have to set
  4652. TYPO3_CONF_VARS[GFX][im_imvMaskState]=1)
  4653. </p>
  4654. ' . $result[0], $result[1]);
  4655. } else {
  4656. $this->message($headCode, 'Render text with TrueType font using \'niceText\' option', '
  4657. <p>
  4658. <strong>Test is skipped!</strong>
  4659. </p>
  4660. <p>
  4661. Use of ImageMagick has been disabled in the
  4662. configuration. ImageMagick is needed to generate
  4663. text with the niceText option.
  4664. <br />
  4665. Refer to section \'Basic Configuration\' to
  4666. change or review you configuration settings
  4667. </p>
  4668. ', 2);
  4669. }
  4670. if ($imActive) {
  4671. // extension: GD with text, niceText AND shadow
  4672. $conf['offset'] = '17,90';
  4673. $conf['niceText'] = 1;
  4674. $conf['shadow.'] = array(
  4675. 'offset'=>'2,2',
  4676. 'blur' => $imageProc->V5_EFFECTS?"20":"90",
  4677. 'opacity' => '50',
  4678. 'color' => 'black'
  4679. );
  4680. $imageProc->makeShadow($im,$conf['shadow.'],$workArea,$conf);
  4681. $imageProc->makeText($im,$conf,$workArea);
  4682. $output = $imageProc->tempPath.$imageProc->filenamePrefix.t3lib_div::shortMD5('GDwithText-niceText-shadow').'.'.$imageProc->gifExtension;
  4683. $imageProc->ImageWrite($im,$output);
  4684. $fileInfo = $imageProc->getImageDimensions($output);
  4685. $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.'));
  4686. $this->message($headCode, 'Render \'niceText\' with a shadow under', '
  4687. <p>
  4688. (This test makes sense only if the above test
  4689. had a correct output. But if so, you may not see
  4690. a soft dropshadow from the third text string as
  4691. you should. In that case you are most likely
  4692. using ImageMagick 5 and should set the flag
  4693. TYPO3_CONF_VARS[GFX][im_v5effects]. However this
  4694. may cost server performance!
  4695. </p>
  4696. ' . $result[0], $result[1]);
  4697. } else {
  4698. $this->message($headCode, 'Render \'niceText\' with a shadow under', '
  4699. <p>
  4700. <strong>Test is skipped!</strong>
  4701. </p>
  4702. <p>
  4703. Use of ImageMagick has been disabled in the
  4704. configuration. ImageMagick is needed to generate
  4705. shadows.
  4706. <br />
  4707. Refer to section \'Basic Configuration\' to
  4708. change or review you configuration settings
  4709. </p>
  4710. ', 2);
  4711. }
  4712. if ($imageProc->gifExtension=='gif') {
  4713. $buffer=20;
  4714. $assess = "This assessment is based on the filesize from 'Create image from file' test, which were ".$GDWithBox_filesize.' bytes';
  4715. $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!";
  4716. if ($GDWithBox_filesize<8784+$buffer) {
  4717. $msg = '
  4718. <p>
  4719. <strong>
  4720. Your GDLib appears to have LZW compression!
  4721. </strong>
  4722. <br />
  4723. This assessment is based on the filesize
  4724. from \'Create image from file\' test, which
  4725. were ' . $GDWithBox_filesize . ' bytes.
  4726. <br />
  4727. This is a real advantage for you because you
  4728. don\'t need to use ImageMagick for LZW
  4729. compressing. In order to make sure that
  4730. GDLib is used,
  4731. <strong>
  4732. please set the config option
  4733. [GFX][im_path_lzw] to an empty string!
  4734. </strong>
  4735. <br />
  4736. When you disable the use of ImageMagick for
  4737. LZW compressing, you\'ll see that the
  4738. gif_compress() function has a return code of
  4739. \'GD\' (for GDLib) instead of \'IM\' (for
  4740. ImageMagick)
  4741. </p>
  4742. ';
  4743. } elseif ($GDWithBox_filesize>19000) {
  4744. $msg = '
  4745. <p>
  4746. <strong>
  4747. Your GDLib appears to have no
  4748. compression at all!
  4749. </strong>
  4750. <br />
  4751. ' . $assess . '
  4752. <br />
  4753. ' . $goodNews . '
  4754. </p>
  4755. ';
  4756. } else {
  4757. $msg = '
  4758. <p>
  4759. Your GDLib appears to have RLE compression
  4760. <br />
  4761. ' . $assess . '
  4762. <br />
  4763. ' . $goodNews . '
  4764. </p>
  4765. ';
  4766. }
  4767. $this->message($headCode,'GIF compressing in GDLib',"
  4768. ".$msg."
  4769. ",1);
  4770. }
  4771. } else {
  4772. $this->message($headCode, 'Test skipped', '
  4773. <p>
  4774. Use of GDLib has been disabled in the configuration.
  4775. <br />
  4776. Refer to section \'Basic Configuration\' to change
  4777. or review you configuration settings
  4778. </p>
  4779. ', 2);
  4780. }
  4781. break;
  4782. }
  4783. if ($this->INSTALL['images_type']) {
  4784. // End info
  4785. if ($this->fatalError) {
  4786. $this->message('Info', 'Errors', '
  4787. <p>
  4788. It seems that you had some fatal errors in this test.
  4789. Please make sure that your ImageMagick and GDLib
  4790. settings are correct. Refer to the
  4791. \'Basic Configuration\' section for more information and
  4792. debugging of your settings.
  4793. </p>
  4794. ');
  4795. }
  4796. $parseMS = t3lib_div::milliseconds() - $parseStart;
  4797. $this->message('Info', 'Parsetime', '
  4798. <p>
  4799. ' . $parseMS . ' ms
  4800. </p>
  4801. ');
  4802. }
  4803. $this->output($this->outputWrapper($this->printAll()));
  4804. }
  4805. /**
  4806. * Check if image file extension is enabled
  4807. * Adds error message to the message array
  4808. *
  4809. * @param string $ext The image file extension
  4810. * @param string $headCode The header for the message
  4811. * @param string $short The short description for the message
  4812. * @return boolean TRUE if extension is enabled
  4813. */
  4814. function isExtensionEnabled($ext, $headCode, $short) {
  4815. if (!t3lib_div::inList($GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'],$ext)) {
  4816. $this->message($headCode, $short, '
  4817. <p>
  4818. Skipped - extension not in the list of allowed extensions
  4819. ([GFX][imagefile_ext]).
  4820. </p>
  4821. ',1);
  4822. } else {
  4823. return 1;
  4824. }
  4825. }
  4826. /**
  4827. * Generate the HTML after reading and converting images
  4828. * Displays the verification and the converted image if succeeded
  4829. * Adds error messages if needed
  4830. *
  4831. * @param string $imageFile The file name of the converted image
  4832. * @param array $IMcommands The ImageMagick commands used
  4833. * @param string $note Additional note for image operation
  4834. * @return array Contains content and highest error level
  4835. */
  4836. function displayTwinImage ($imageFile, $IMcommands=array(), $note='') {
  4837. // Get the template file
  4838. $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'DisplayTwinImage.html');
  4839. // Get the template part from the file
  4840. $template = t3lib_parsehtml::getSubpart($templateFile, '###TEMPLATE###');
  4841. $content = '';
  4842. $errorLevels=array(-1);
  4843. if ($imageFile) {
  4844. // Get the subpart for the images
  4845. $imageSubpart = t3lib_parsehtml::getSubpart($template, '###IMAGE###');
  4846. $verifyFile = t3lib_extMgm::extPath('install').'verify_imgs/'.basename($imageFile);
  4847. $destImg = @getImageSize($imageFile);
  4848. $destImgCode ='<img src="'.$this->backPath.'../'.substr($imageFile,strlen(PATH_site)).'" '.$destImg[3].'>';
  4849. $verifyImg = @getImageSize($verifyFile);
  4850. $verifyImgCode = '<img src="'.$this->backPath.t3lib_extMgm::extRelPath('install').'verify_imgs/'.basename($verifyFile).'" '.$verifyImg[3].'>';
  4851. clearstatcache();
  4852. $destImg['filesize'] = @filesize($imageFile);
  4853. clearstatcache();
  4854. $verifyImg['filesize'] = @filesize($verifyFile);
  4855. // Define the markers content
  4856. $imageMarkers = array(
  4857. 'destWidth' => $destImg[0],
  4858. 'destHeight' => $destImg[1],
  4859. 'destUrl' => $this->backPath . '../' . substr($imageFile, strlen(PATH_site)),
  4860. 'verifyWidth' => $verifyImg[0],
  4861. 'verifyHeight' => $verifyImg[1],
  4862. 'verifyUrl' => $this->backPath . t3lib_extMgm::extRelPath('install') . 'verify_imgs/' . basename($verifyFile),
  4863. 'yourServer' => 'Your server:',
  4864. 'yourServerInformation' => t3lib_div::formatSize($destImg['filesize']) . ', ' . $destImg[0] . 'x' . $destImg[1] . ' pixels',
  4865. 'reference' => 'Reference:',
  4866. 'referenceInformation' => t3lib_div::formatSize($verifyImg['filesize']) . ', ' . $verifyImg[0] . 'x' . $verifyImg[1] . ' pixels'
  4867. );
  4868. if ($destImg[0]!=$verifyImg[0] || $destImg[1]!=$verifyImg[1]) {
  4869. // Get the subpart for the different pixel dimensions message
  4870. $differentPixelDimensionsSubpart = t3lib_parsehtml::getSubpart($imageSubpart, '###DIFFERENTPIXELDIMENSIONS###');
  4871. // Define the markers content
  4872. $differentPixelDimensionsMarkers = array(
  4873. 'message' => 'Pixel dimension are not equal!'
  4874. );
  4875. // Fill the markers in the subpart
  4876. $differentPixelDimensionsSubpart = t3lib_parsehtml::substituteMarkerArray(
  4877. $differentPixelDimensionsSubpart,
  4878. $differentPixelDimensionsMarkers,
  4879. '###|###',
  4880. TRUE,
  4881. FALSE
  4882. );
  4883. $errorLevels[]=2;
  4884. }
  4885. // Substitute the subpart for different pixel dimensions message
  4886. $imageSubpart = t3lib_parsehtml::substituteSubpart(
  4887. $imageSubpart,
  4888. '###DIFFERENTPIXELDIMENSIONS###',
  4889. $differentPixelDimensionsSubpart
  4890. );
  4891. if ($note) {
  4892. // Get the subpart for the note
  4893. $noteSubpart = t3lib_parsehtml::getSubpart($imageSubpart, '###NOTE###');
  4894. // Define the markers content
  4895. $noteMarkers = array(
  4896. 'message' => $note[0],
  4897. 'label' => $note[1]
  4898. );
  4899. // Fill the markers in the subpart
  4900. $noteSubpart = t3lib_parsehtml::substituteMarkerArray(
  4901. $noteSubpart,
  4902. $noteMarkers,
  4903. '###|###',
  4904. TRUE,
  4905. FALSE
  4906. );
  4907. }
  4908. // Substitute the subpart for the note
  4909. $imageSubpart = t3lib_parsehtml::substituteSubpart(
  4910. $imageSubpart,
  4911. '###NOTE###',
  4912. $noteSubpart
  4913. );
  4914. if ($this->dumpImCommands && count($IMcommands)) {
  4915. $commands = $this->formatImCmds($IMcommands);
  4916. // Get the subpart for the ImageMagick commands
  4917. $imCommandsSubpart = t3lib_parsehtml::getSubpart($imageSubpart, '###IMCOMMANDS###');
  4918. // Define the markers content
  4919. $imCommandsMarkers = array(
  4920. 'message' => 'ImageMagick commands executed:',
  4921. 'rows' => t3lib_div::intInRange(count($commands), 2, 10),
  4922. 'commands' => htmlspecialchars(implode(LF, $commands))
  4923. );
  4924. // Fill the markers in the subpart
  4925. $imCommandsSubpart = t3lib_parsehtml::substituteMarkerArray(
  4926. $imCommandsSubpart,
  4927. $imCommandsMarkers,
  4928. '###|###',
  4929. TRUE,
  4930. FALSE
  4931. );
  4932. }
  4933. // Substitute the subpart for the ImageMagick commands
  4934. $imageSubpart = t3lib_parsehtml::substituteSubpart(
  4935. $imageSubpart,
  4936. '###IMCOMMANDS###',
  4937. $imCommandsSubpart
  4938. );
  4939. // Fill the markers
  4940. $imageSubpart = t3lib_parsehtml::substituteMarkerArray(
  4941. $imageSubpart,
  4942. $imageMarkers,
  4943. '###|###',
  4944. TRUE,
  4945. FALSE
  4946. );
  4947. } else {
  4948. // Get the subpart when no image has been generated
  4949. $noImageSubpart = t3lib_parsehtml::getSubpart($template, '###NOIMAGE###');
  4950. $commands = $this->formatImCmds($IMcommands);
  4951. if (count($commands)) {
  4952. // Get the subpart for the ImageMagick commands
  4953. $commandsSubpart = t3lib_parsehtml::getSubpart($noImageSubpart, '###COMMANDSAVAILABLE###');
  4954. // Define the markers content
  4955. $commandsMarkers = array(
  4956. 'rows' => t3lib_div::intInRange(count($commands), 2, 10),
  4957. 'commands' => htmlspecialchars(implode(LF, $commands))
  4958. );
  4959. // Fill the markers in the subpart
  4960. $commandsSubpart = t3lib_parsehtml::substituteMarkerArray(
  4961. $commandsSubpart,
  4962. $commandsMarkers,
  4963. '###|###',
  4964. TRUE,
  4965. FALSE
  4966. );
  4967. }
  4968. // Substitute the subpart for the ImageMagick commands
  4969. $noImageSubpart = t3lib_parsehtml::substituteSubpart(
  4970. $noImageSubpart,
  4971. '###COMMANDSAVAILABLE###',
  4972. $commandsSubpart
  4973. );
  4974. // Define the markers content
  4975. $noImageMarkers = array(
  4976. 'message' => 'There was no result from the ImageMagick operation',
  4977. 'label' => 'Below there\'s a dump of the ImageMagick commands executed:'
  4978. );
  4979. // Fill the markers
  4980. $noImageSubpart = t3lib_parsehtml::substituteMarkerArray(
  4981. $noImageSubpart,
  4982. $noImageMarkers,
  4983. '###|###',
  4984. TRUE,
  4985. FALSE
  4986. );
  4987. $errorLevels[]=3;
  4988. }
  4989. // Substitute the subpart when image has been generated
  4990. $content = t3lib_parsehtml::substituteSubpart(
  4991. $template,
  4992. '###IMAGE###',
  4993. $imageSubpart
  4994. );
  4995. // Substitute the subpart when no image has been generated
  4996. $content = t3lib_parsehtml::substituteSubpart(
  4997. $content,
  4998. '###NOIMAGE###',
  4999. $noImageSubpart
  5000. );
  5001. return array($content, max($errorLevels));
  5002. }
  5003. /**
  5004. * Format ImageMagick commands for use in HTML
  5005. *
  5006. * @param array $arr The ImageMagick commands
  5007. * @return string The formatted commands
  5008. */
  5009. function formatImCmds($arr) {
  5010. $out = array();
  5011. if (is_array($arr)) {
  5012. foreach ($arr as $k => $v) {
  5013. $out[] = $v[1];
  5014. if ($v[2]) {
  5015. $out[]=' RETURNED: ' . $v[2];
  5016. }
  5017. }
  5018. }
  5019. return $out;
  5020. }
  5021. /**
  5022. * Generate the menu for the test menu in 'image processing'
  5023. *
  5024. * @return string The HTML for the test menu
  5025. */
  5026. function imagemenu() {
  5027. // Get the template file
  5028. $template = @file_get_contents(PATH_site . $this->templateFilePath . 'ImageMenu.html');
  5029. // Get the subpart for the menu
  5030. $menuSubPart = t3lib_parsehtml::getSubpart($template, '###MENU###');
  5031. // Get the subpart for the single item in the menu
  5032. $menuItemSubPart = t3lib_parsehtml::getSubpart($menuSubPart, '###MENUITEM###');
  5033. $menuitems = array(
  5034. 'read' => 'Reading image formats',
  5035. 'write' => 'Writing GIF and PNG',
  5036. 'scaling' => 'Scaling images',
  5037. 'combining' => 'Combining images',
  5038. 'gdlib' => 'GD library functions'
  5039. );
  5040. $c = 0;
  5041. $items = array();
  5042. foreach ($menuitems as $k => $v) {
  5043. // Define the markers content
  5044. $markers = array(
  5045. 'backgroundColor' => $this->INSTALL['images_type'] == $k ? 'activeMenu' : 'generalTableBackground',
  5046. 'url' => htmlspecialchars($this->action . '&TYPO3_INSTALL[images_type]=' . $k . '#imageMenu'),
  5047. 'item' => $v
  5048. );
  5049. // Fill the markers in the subpart
  5050. $items[] = t3lib_parsehtml::substituteMarkerArray(
  5051. $menuItemSubPart,
  5052. $markers,
  5053. '###|###',
  5054. TRUE,
  5055. FALSE
  5056. );
  5057. }
  5058. // Substitute the subpart for the single item in the menu
  5059. $menuSubPart = t3lib_parsehtml::substituteSubpart(
  5060. $menuSubPart,
  5061. '###MENUITEM###',
  5062. implode(LF, $items)
  5063. );
  5064. return $menuSubPart;
  5065. }
  5066. /**********************
  5067. *
  5068. * DATABASE analysing
  5069. *
  5070. **********************/
  5071. /**
  5072. * The Database Analyzer
  5073. *
  5074. * @return void
  5075. */
  5076. function checkTheDatabase() {
  5077. if (!$this->config_array['mysqlConnect']) {
  5078. $this->message('Database Analyser', 'Your database connection failed', '
  5079. <p>
  5080. Please go to the \'Basic Configuration\' section and correct
  5081. this problem first.
  5082. </p>
  5083. ', 2);
  5084. $this->output($this->outputWrapper($this->printAll()));
  5085. return;
  5086. }
  5087. if ($this->config_array['no_database']) {
  5088. $this->message('Database Analyser', 'No database selected', '
  5089. <p>
  5090. Please go to the \'Basic Configuration\' section and correct
  5091. this problem first.
  5092. </p>
  5093. ', 2);
  5094. $this->output($this->outputWrapper($this->printAll()));
  5095. return;
  5096. }
  5097. // Getting current tables
  5098. $whichTables=$this->getListOfTables();
  5099. // Getting number of static_template records
  5100. if ($whichTables['static_template']) {
  5101. $static_template_count = $GLOBALS['TYPO3_DB']->exec_SELECTcountRows('uid', 'static_template');
  5102. }
  5103. $static_template_count=intval($static_template_count);
  5104. $headCode ='Database Analyser';
  5105. $this->message($headCode, 'What is it?', '
  5106. <p>
  5107. In this section you can get an overview of your currently
  5108. selected database compared to sql-files. You can also import
  5109. sql-data directly into the database or upgrade tables from
  5110. earlier versions of TYPO3.
  5111. </p>
  5112. ', 0);
  5113. $this->message($headCode, 'Connected to SQL database successfully', '
  5114. <dl id="t3-install-databaseconnected">
  5115. <dt>
  5116. Username:
  5117. </dt>
  5118. <dd>
  5119. ' . htmlspecialchars(TYPO3_db_username) . '
  5120. </dd>
  5121. <dt>
  5122. Host:
  5123. </dt>
  5124. <dd>
  5125. ' . htmlspecialchars(TYPO3_db_host) . '
  5126. </dd>
  5127. </dl>
  5128. ', -1, 1);
  5129. $this->message($headCode, 'Database', '
  5130. <p>
  5131. <strong>' . htmlspecialchars(TYPO3_db) . '</strong> is selected as database.
  5132. <br />
  5133. Has <strong>' . count($whichTables) . '</strong> tables.
  5134. </p>
  5135. ', -1, 1);
  5136. // Menu
  5137. $sql_files = array_merge(
  5138. t3lib_div::getFilesInDir(PATH_typo3conf,'sql',1,1),
  5139. array()
  5140. );
  5141. $action_type = $this->INSTALL['database_type'];
  5142. $actionParts = explode('|',$action_type);
  5143. if (count($actionParts)<2) {
  5144. $action_type='';
  5145. }
  5146. // Get the template file
  5147. $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'CheckTheDatabaseMenu.html');
  5148. // Get the template part from the file
  5149. $menu = t3lib_parsehtml::getSubpart($templateFile, '###MENU###');
  5150. $menuMarkers = array(
  5151. 'action' => $this->action,
  5152. 'updateRequiredTables' => 'Update required tables',
  5153. 'compare' => 'COMPARE',
  5154. 'noticeCmpFileCurrent' => ($action_type == 'cmpFile|CURRENT_TABLES' ? ' class="notice"' : ''),
  5155. 'dumpStaticData' => 'Dump static data',
  5156. 'import' => 'IMPORT',
  5157. 'noticeImportCurrent' => ($action_type == 'import|CURRENT_STATIC' ? ' class="notice"' : ''),
  5158. 'noticeCmpTca' => ($action_type == "cmpTCA|" ? ' class="notice"' : ''),
  5159. 'compareWithTca' => 'Compare with $TCA',
  5160. 'noticeAdminUser' => ($action_type == "adminUser|" ? ' class="notice"' : ''),
  5161. 'createAdminUser' => 'Create "admin" user',
  5162. 'noticeUc' => ($action_type == "UC|" ? ' class="notice"' : ''),
  5163. 'resetUserPreferences' => 'Reset user preferences',
  5164. 'noticeCache' => ($action_type == "cache|" ? ' class="notice"' : ''),
  5165. 'clearTables' => 'Clear tables'
  5166. );
  5167. // Get the subpart for extra SQL
  5168. $extraSql = t3lib_parsehtml::getSubpart($menu, '###EXTRASQL###');
  5169. $directJump='';
  5170. $extraSqlFiles = array();
  5171. foreach ($sql_files as $k => $file) {
  5172. if ($this->mode=="123" && !count($whichTables) && strstr($file,'_testsite')) {
  5173. $directJump = $this->action.'&TYPO3_INSTALL[database_type]=import|'.rawurlencode($file);
  5174. }
  5175. $lf=t3lib_div::testInt($k);
  5176. $fShortName = substr($file,strlen(PATH_site));
  5177. $spec1 = $spec2 = '';
  5178. // Define the markers content
  5179. $extraSqlMarkers = array(
  5180. 'fileShortName' => $fShortName,
  5181. 'fileSize' => t3lib_div::formatSize(filesize($file)),
  5182. 'noticeCmpFile' => ($action_type == 'cmpFile|' . $file ? ' class="notice"' : ''),
  5183. 'file' => rawurlencode($file),
  5184. 'noticeImport' => ($action_type == 'import|' . $file ? ' class="notice"' : ''),
  5185. 'specs' => $spec1 . $spec2,
  5186. 'noticeView' => ($action_type == 'view|' . $file ? ' class="notice"' : ''),
  5187. 'view' => 'VIEW'
  5188. );
  5189. // Fill the markers in the subpart
  5190. $extraSqlFiles[] = t3lib_parsehtml::substituteMarkerArray(
  5191. $extraSql,
  5192. $extraSqlMarkers,
  5193. '###|###',
  5194. TRUE,
  5195. FALSE
  5196. );
  5197. }
  5198. // Substitute the subpart for extra SQL
  5199. $menu = t3lib_parsehtml::substituteSubpart(
  5200. $menu,
  5201. '###EXTRASQL###',
  5202. implode(LF, $extraSqlFiles)
  5203. );
  5204. // Fill the markers
  5205. $menu = t3lib_parsehtml::substituteMarkerArray(
  5206. $menu,
  5207. $menuMarkers,
  5208. '###|###',
  5209. TRUE,
  5210. FALSE
  5211. );
  5212. if ($directJump) {
  5213. if (!$action_type) {
  5214. $this->message($headCode, 'Menu', '
  5215. <script language="javascript" type="text/javascript">
  5216. window.location.href = "' . $directJump . '";
  5217. </script>',
  5218. 0, 1);
  5219. }
  5220. } else {
  5221. $this->message($headCode, 'Menu', '
  5222. <p>
  5223. From this menu you can select which of the available SQL
  5224. files you want to either compare or import/merge with the
  5225. existing database.
  5226. </p>
  5227. <dl id="t3-install-checkthedatabaseexplanation">
  5228. <dt>
  5229. COMPARE:
  5230. </dt>
  5231. <dd>
  5232. Compares the tables and fields of the current database
  5233. and the selected file. It also offers to \'update\' the
  5234. difference found.
  5235. </dd>
  5236. <dt>
  5237. IMPORT:
  5238. </dt>
  5239. <dd>
  5240. Imports the SQL-dump file into the current database. You
  5241. can either dump the raw file or choose which tables to
  5242. import. In any case, you\'ll see a new screen where you
  5243. must confirm the operation.
  5244. </dd>
  5245. <dt>
  5246. VIEW:
  5247. </dt>
  5248. <dd>
  5249. Shows the content of the SQL-file, limiting characters
  5250. on a single line to a reader-friendly amount.
  5251. </dd>
  5252. </dl>
  5253. <p>
  5254. The SQL-files are selected from typo3conf/ (here you can put
  5255. your own) and t3lib/stddb/ (TYPO3 distribution). The
  5256. SQL-files should be made by the <em>mysqldump</em> tool or
  5257. at least be formatted like that tool would do.
  5258. </p>
  5259. ' . $menu, 0, 1);
  5260. }
  5261. if ($action_type) {
  5262. switch($actionParts[0]) {
  5263. case 'cmpFile':
  5264. $tblFileContent='';
  5265. if (!strcmp($actionParts[1],'CURRENT_TABLES')) {
  5266. $tblFileContent = t3lib_div::getUrl(PATH_t3lib.'stddb/tables.sql');
  5267. foreach ($GLOBALS['TYPO3_LOADED_EXT'] as $loadedExtConf) {
  5268. if (is_array($loadedExtConf) && $loadedExtConf['ext_tables.sql']) {
  5269. $tblFileContent .= LF . LF . LF . LF . t3lib_div::getUrl($loadedExtConf['ext_tables.sql']);
  5270. }
  5271. }
  5272. } elseif (@is_file($actionParts[1])) {
  5273. $tblFileContent = t3lib_div::getUrl($actionParts[1]);
  5274. }
  5275. if ($tblFileContent) {
  5276. $fileContent = implode(
  5277. LF,
  5278. $this->getStatementArray($tblFileContent,1,'^CREATE TABLE ')
  5279. );
  5280. $FDfile = $this->getFieldDefinitions_fileContent($fileContent);
  5281. if (!count($FDfile)) {
  5282. die ("Error: There were no 'CREATE TABLE' definitions in the provided file");
  5283. }
  5284. // Updating database...
  5285. if (is_array($this->INSTALL['database_update'])) {
  5286. $FDdb = $this->getFieldDefinitions_database();
  5287. $diff = $this->getDatabaseExtra($FDfile, $FDdb);
  5288. $update_statements = $this->getUpdateSuggestions($diff);
  5289. $diff = $this->getDatabaseExtra($FDdb, $FDfile);
  5290. $remove_statements = $this->getUpdateSuggestions($diff,'remove');
  5291. $results = array();
  5292. $results[] = $this->performUpdateQueries($update_statements['clear_table'], $this->INSTALL['database_update']);
  5293. $results[] = $this->performUpdateQueries($update_statements['add'], $this->INSTALL['database_update']);
  5294. $results[] = $this->performUpdateQueries($update_statements['change'], $this->INSTALL['database_update']);
  5295. $results[] = $this->performUpdateQueries($remove_statements['change'], $this->INSTALL['database_update']);
  5296. $results[] = $this->performUpdateQueries($remove_statements['drop'], $this->INSTALL['database_update']);
  5297. $results[] = $this->performUpdateQueries($update_statements['create_table'], $this->INSTALL['database_update']);
  5298. $results[] = $this->performUpdateQueries($remove_statements['change_table'], $this->INSTALL['database_update']);
  5299. $results[] = $this->performUpdateQueries($remove_statements['drop_table'], $this->INSTALL['database_update']);
  5300. $this->databaseUpdateErrorMessages = array();
  5301. foreach ($results as $resultSet) {
  5302. if (is_array($resultSet)) {
  5303. foreach ($resultSet as $key => $errorMessage) {
  5304. $this->databaseUpdateErrorMessages[$key] = $errorMessage;
  5305. }
  5306. }
  5307. }
  5308. }
  5309. // Init again / first time depending...
  5310. $FDdb = $this->getFieldDefinitions_database();
  5311. $diff = $this->getDatabaseExtra($FDfile, $FDdb);
  5312. $update_statements = $this->getUpdateSuggestions($diff);
  5313. $diff = $this->getDatabaseExtra($FDdb, $FDfile);
  5314. $remove_statements = $this->getUpdateSuggestions($diff,'remove');
  5315. $tLabel = 'Update database tables and fields';
  5316. if ($remove_statements || $update_statements) {
  5317. $formContent = $this->generateUpdateDatabaseForm('get_form',$update_statements,$remove_statements,$action_type);
  5318. $this->message($tLabel, 'Table and field definitions should be updated', '
  5319. <p>
  5320. There seems to be a number of differencies
  5321. between the database and the selected
  5322. SQL-file.
  5323. <br />
  5324. Please select which statements you want to
  5325. execute in order to update your database:
  5326. </p>
  5327. ' . $formContent, 2);
  5328. } else {
  5329. $formContent = $this->generateUpdateDatabaseForm('get_form',$update_statements,$remove_statements,$action_type);
  5330. $this->message($tLabel, 'Table and field definitions are OK.', '
  5331. <p>
  5332. The tables and fields in the current
  5333. database corresponds perfectly to the
  5334. database in the selected SQL-file.
  5335. </p>
  5336. ', -1);
  5337. }
  5338. }
  5339. break;
  5340. case 'cmpTCA':
  5341. $this->includeTCA();
  5342. $FDdb = $this->getFieldDefinitions_database();
  5343. // Displaying configured fields which are not in the database
  5344. $tLabel='Tables and fields in $TCA, but not in database';
  5345. $cmpTCA_DB = $this->compareTCAandDatabase($GLOBALS['TCA'],$FDdb);
  5346. if (!count($cmpTCA_DB['extra'])) {
  5347. $this->message($tLabel, 'Table and field definitions OK', '
  5348. <p>
  5349. All fields and tables configured in $TCA
  5350. appeared to exist in the database as well
  5351. </p>
  5352. ', -1);
  5353. } else {
  5354. $this->message($tLabel, 'Invalid table and field definitions in $TCA!', '
  5355. <p>
  5356. There are some tables and/or fields configured
  5357. in the $TCA array which do not exist in the
  5358. database!
  5359. <br />
  5360. This will most likely cause you trouble with the
  5361. TYPO3 backend interface!
  5362. </p>
  5363. ', 3);
  5364. foreach ($cmpTCA_DB['extra'] as $tableName => $conf) {
  5365. $this->message($tLabel, $tableName,$this->displayFields($conf['fields'],0,'Suggested database field:'),2);
  5366. }
  5367. }
  5368. // Displaying tables that are not setup in
  5369. $cmpDB_TCA = $this->compareDatabaseAndTCA($FDdb,$GLOBALS['TCA']);
  5370. $excludeTables='be_sessions,fe_session_data,fe_sessions';
  5371. if (TYPO3_OS=='WIN') {$excludeTables = strtolower($excludeTables);}
  5372. $excludeFields = array(
  5373. 'be_users' => 'uc,lastlogin,usergroup_cached_list',
  5374. 'fe_users' => 'uc,lastlogin,fe_cruser_id',
  5375. 'pages' => 'SYS_LASTCHANGED',
  5376. 'sys_dmail' => 'mailContent',
  5377. 'tt_board' => 'doublePostCheck',
  5378. 'tt_guest' => 'doublePostCheck',
  5379. 'tt_products' => 'ordered'
  5380. );
  5381. $tCount=0;
  5382. $fCount=0;
  5383. $tLabel="Tables from database, but not in \$TCA";
  5384. $fLabel="Fields from database, but not in \$TCA";
  5385. $this->message($tLabel);
  5386. if (is_array($cmpDB_TCA['extra'])) {
  5387. foreach ($cmpDB_TCA['extra'] as $tableName => $conf) {
  5388. if (!t3lib_div::inList($excludeTables,$tableName)
  5389. && substr($tableName,0,4)!="sys_"
  5390. && substr($tableName,-3)!="_mm"
  5391. && substr($tableName,0,6)!="index_"
  5392. && substr($tableName,0,6)!='cache_') {
  5393. if ($conf['whole_table']) {
  5394. $this->message($tLabel, $tableName,$this->displayFields($conf['fields']),1);
  5395. $tCount++;
  5396. } else {
  5397. list($theContent, $fC) = $this->displaySuggestions($conf['fields'],$excludeFields[$tableName]);
  5398. $fCount+=$fC;
  5399. if ($fC) {
  5400. $this->message($fLabel, $tableName,$theContent,1);
  5401. }
  5402. }
  5403. }
  5404. }
  5405. }
  5406. if (!$tCount) {
  5407. $this->message($tLabel, 'Correct number of tables in the database', '
  5408. <p>
  5409. There are no extra tables in the database
  5410. compared to the configured tables in the $TCA
  5411. array.
  5412. </p>
  5413. ', -1);
  5414. } else {
  5415. $this->message($tLabel, 'Extra tables in the database', '
  5416. <p>
  5417. There are some tables in the database which are
  5418. not configured in the $TCA array.
  5419. <br />
  5420. You should probably not worry about this, but
  5421. please make sure that you know what these tables
  5422. are about and why they are not configured in
  5423. $TCA.
  5424. </p>
  5425. ', 2);
  5426. }
  5427. if (!$fCount) {
  5428. $this->message($fLabel, 'Correct number of fields in the database', '
  5429. <p>
  5430. There are no additional fields in the database
  5431. tables compared to the configured fields in the
  5432. $TCA array.
  5433. </p>
  5434. ', -1);
  5435. } else {
  5436. $this->message($fLabel, 'Extra fields in the database', '
  5437. <p>
  5438. There are some additional fields the database
  5439. tables which are not configured in the $TCA
  5440. array.
  5441. <br />
  5442. You should probably not worry about this, but
  5443. please make sure that you know what these fields
  5444. are about and why they are not configured in
  5445. $TCA.
  5446. </p>
  5447. ', 2);
  5448. }
  5449. // Displaying actual and suggested field database defitions
  5450. if (is_array($cmpTCA_DB['matching'])) {
  5451. $tLabel="Comparison between database and \$TCA";
  5452. $this->message($tLabel, 'Actual and suggested field definitions', '
  5453. <p>
  5454. This table shows you the suggested field
  5455. definitions which are calculated based on the
  5456. configuration in $TCA.
  5457. <br />
  5458. If the suggested value differs from the actual
  5459. current database value, you should not panic,
  5460. but simply check if the datatype of that field
  5461. is sufficient compared to the data, you want
  5462. TYPO3 to put there.
  5463. </p>
  5464. ', 0);
  5465. foreach ($cmpTCA_DB['matching'] as $tableName => $conf) {
  5466. $this->message($tLabel, $tableName,$this->displayFieldComp($conf['fields'], $FDdb[$tableName]['fields']),1);
  5467. }
  5468. }
  5469. break;
  5470. case 'import':
  5471. $mode123Imported=0;
  5472. $tblFileContent='';
  5473. if (preg_match('/^CURRENT_/', $actionParts[1])) {
  5474. if (!strcmp($actionParts[1],'CURRENT_TABLES') || !strcmp($actionParts[1],'CURRENT_TABLES+STATIC')) {
  5475. $tblFileContent = t3lib_div::getUrl(PATH_t3lib.'stddb/tables.sql');
  5476. foreach ($GLOBALS['TYPO3_LOADED_EXT'] as $loadedExtConf) {
  5477. if (is_array($loadedExtConf) && $loadedExtConf['ext_tables.sql']) {
  5478. $tblFileContent.= LF . LF . LF . LF . t3lib_div::getUrl($loadedExtConf['ext_tables.sql']);
  5479. }
  5480. }
  5481. }
  5482. if (!strcmp($actionParts[1],'CURRENT_STATIC') || !strcmp($actionParts[1],'CURRENT_TABLES+STATIC')) {
  5483. foreach ($GLOBALS['TYPO3_LOADED_EXT'] as $loadedExtConf) {
  5484. if (is_array($loadedExtConf) && $loadedExtConf['ext_tables_static+adt.sql']) {
  5485. $tblFileContent.= LF . LF . LF . LF . t3lib_div::getUrl($loadedExtConf['ext_tables_static+adt.sql']);
  5486. }
  5487. }
  5488. }
  5489. } elseif (@is_file($actionParts[1])) {
  5490. $tblFileContent = t3lib_div::getUrl($actionParts[1]);
  5491. }
  5492. if ($tblFileContent) {
  5493. $tLabel='Import SQL dump';
  5494. // Getting statement array from
  5495. $statements = $this->getStatementArray($tblFileContent,1);
  5496. list($statements_table, $insertCount) = $this->getCreateTables($statements,1);
  5497. // Updating database...
  5498. if ($this->INSTALL['database_import_all']) {
  5499. $r=0;
  5500. foreach ($statements as $k=>$v) {
  5501. $res = $GLOBALS['TYPO3_DB']->admin_query($v);
  5502. $r++;
  5503. }
  5504. // Make a database comparison because some tables that are defined twice have
  5505. // not been created at this point. This applies to the "pages.*"
  5506. // fields defined in sysext/cms/ext_tables.sql for example.
  5507. $fileContent = implode(
  5508. LF,
  5509. $this->getStatementArray($tblFileContent,1,'^CREATE TABLE ')
  5510. );
  5511. $FDfile = $this->getFieldDefinitions_fileContent($fileContent);
  5512. $FDdb = $this->getFieldDefinitions_database();
  5513. $diff = $this->getDatabaseExtra($FDfile, $FDdb);
  5514. $update_statements = $this->getUpdateSuggestions($diff);
  5515. if (is_array($update_statements['add'])) {
  5516. foreach ($update_statements['add'] as $statement) {
  5517. $res = $GLOBALS['TYPO3_DB']->admin_query($statement);
  5518. }
  5519. }
  5520. if ($this->mode=='123') {
  5521. // Create default be_user admin/password
  5522. $username = 'admin';
  5523. $pass = 'password';
  5524. $count = $GLOBALS['TYPO3_DB']->exec_SELECTcountRows(
  5525. 'uid',
  5526. 'be_users',
  5527. 'username=' . $GLOBALS['TYPO3_DB']->fullQuoteStr($username, 'be_users')
  5528. );
  5529. if (!$count) {
  5530. $insertFields = array(
  5531. 'username' => $username,
  5532. 'password' => md5($pass),
  5533. 'admin' => 1,
  5534. 'uc' => '',
  5535. 'fileoper_perms' => 0,
  5536. 'tstamp' => $GLOBALS['EXEC_TIME'],
  5537. 'crdate' => $GLOBALS['EXEC_TIME']
  5538. );
  5539. $GLOBALS['TYPO3_DB']->exec_INSERTquery('be_users', $insertFields);
  5540. }
  5541. }
  5542. $this->message($tLabel, 'Imported ALL', '
  5543. <p>
  5544. Queries: ' . $r . '
  5545. </p>
  5546. ', 1, 1);
  5547. if (t3lib_div::_GP('goto_step')) {
  5548. $this->action.='&step='.t3lib_div::_GP('goto_step');
  5549. t3lib_utility_Http::redirect($this->action);
  5550. }
  5551. } elseif (is_array($this->INSTALL['database_import'])) {
  5552. // Traverse the tables
  5553. foreach ($this->INSTALL['database_import'] as $table => $md5str) {
  5554. if ($md5str==md5($statements_table[$table])) {
  5555. $res = $GLOBALS['TYPO3_DB']->admin_query('DROP TABLE IF EXISTS '.$table);
  5556. $res = $GLOBALS['TYPO3_DB']->admin_query($statements_table[$table]);
  5557. if ($insertCount[$table]) {
  5558. $statements_insert = $this->getTableInsertStatements($statements, $table);
  5559. foreach ($statements_insert as $k => $v) {
  5560. $res = $GLOBALS['TYPO3_DB']->admin_query($v);
  5561. }
  5562. }
  5563. $this->message($tLabel, 'Imported \'' . $table . '\'', '
  5564. <p>
  5565. Rows: ' . $insertCount[$table] . '
  5566. </p>
  5567. ', 1, 1);
  5568. }
  5569. }
  5570. }
  5571. $mode123Imported=$this->isBasicComplete($tLabel);
  5572. if (!$mode123Imported) {
  5573. // Re-Getting current tables - may have been changed during import
  5574. $whichTables=$this->getListOfTables();
  5575. if (count($statements_table)) {
  5576. reset($statements_table);
  5577. $out='';
  5578. // Get the template file
  5579. $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'CheckTheDatabaseImport.html');
  5580. // Get the template part from the file
  5581. $content = t3lib_parsehtml::getSubpart($templateFile, '###IMPORT###');
  5582. if ($this->mode!='123') {
  5583. $tables = array();
  5584. // Get the subpart for regular mode
  5585. $regularModeSubpart = t3lib_parsehtml::getSubpart($content, '###REGULARMODE###');
  5586. foreach ($statements_table as $table => $definition) {
  5587. // Get the subpart for rows
  5588. $tableSubpart = t3lib_parsehtml::getSubpart($content, '###ROWS###');
  5589. // Fill the 'table exists' part when it exists
  5590. $exist=isset($whichTables[$table]);
  5591. if ($exist) {
  5592. // Get the subpart for table exists
  5593. $existSubpart = t3lib_parsehtml::getSubpart($tableSubpart, '###EXIST###');
  5594. // Define the markers content
  5595. $existMarkers = array (
  5596. 'tableExists' => 'Table exists!',
  5597. 'backPath' => $this->backPath
  5598. );
  5599. // Fill the markers in the subpart
  5600. $existSubpart = t3lib_parsehtml::substituteMarkerArray(
  5601. $existSubpart,
  5602. $existMarkers,
  5603. '###|###',
  5604. TRUE,
  5605. FALSE
  5606. );
  5607. }
  5608. // Substitute the subpart for table exists
  5609. $tableHtml = t3lib_parsehtml::substituteSubpart(
  5610. $tableSubpart,
  5611. '###EXIST###',
  5612. $existSubpart
  5613. );
  5614. // Define the markers content
  5615. $tableMarkers = array (
  5616. 'table' => $table,
  5617. 'definition' => md5($definition),
  5618. 'count' => $insertCount[$table] ? $insertCount[$table] : '',
  5619. 'rowLabel' => $insertCount[$table] ? 'Rows: ' : '',
  5620. 'tableExists' => 'Table exists!',
  5621. 'backPath' => $this->backPath
  5622. );
  5623. // Fill the markers
  5624. $tables[] = t3lib_parsehtml::substituteMarkerArray(
  5625. $tableHtml,
  5626. $tableMarkers,
  5627. '###|###',
  5628. TRUE,
  5629. FALSE
  5630. );
  5631. }
  5632. // Substitute the subpart for the rows
  5633. $regularModeSubpart = t3lib_parsehtml::substituteSubpart(
  5634. $regularModeSubpart,
  5635. '###ROWS###',
  5636. implode(LF, $tables)
  5637. );
  5638. }
  5639. // Substitute the subpart for the regular mode
  5640. $content = t3lib_parsehtml::substituteSubpart(
  5641. $content,
  5642. '###REGULARMODE###',
  5643. $regularModeSubpart
  5644. );
  5645. // Define the markers content
  5646. $contentMarkers = array(
  5647. 'checked' => ($this->mode == '123' || t3lib_div::_GP('presetWholeTable') ? 'checked="checked"' : ''),
  5648. 'label' => 'Import the whole file \'' . basename($actionParts[1]) . '\' directly (ignores selections above)'
  5649. );
  5650. // Fill the markers
  5651. $content = t3lib_parsehtml::substituteMarkerArray(
  5652. $content,
  5653. $contentMarkers,
  5654. '###|###',
  5655. TRUE,
  5656. FALSE
  5657. );
  5658. $form = $this->getUpdateDbFormWrap($action_type, $content);
  5659. $this->message($tLabel, 'Select tables to import', '
  5660. <p>
  5661. This is an overview of the CREATE TABLE
  5662. definitions in the SQL file.
  5663. <br />
  5664. Select which tables you want to dump to
  5665. the database.
  5666. <br />
  5667. Any table you choose dump to the
  5668. database is dropped from the database
  5669. first, so you\'ll lose all data in
  5670. existing tables.
  5671. </p>
  5672. ' . $form, 1, 1);
  5673. } else {
  5674. $this->message($tLabel, 'No tables', '
  5675. <p>
  5676. There seems to be no CREATE TABLE
  5677. definitions in the SQL file.
  5678. <br />
  5679. This tool is intelligently creating one
  5680. table at a time and not just dumping the
  5681. whole content of the file uncritically.
  5682. That\'s why there must be defined tables
  5683. in the SQL file.
  5684. </p>
  5685. ', 3, 1);
  5686. }
  5687. }
  5688. }
  5689. break;
  5690. case 'view':
  5691. if (@is_file($actionParts[1])) {
  5692. $tLabel = 'Import SQL dump';
  5693. // Getting statement array from
  5694. $fileContent = t3lib_div::getUrl($actionParts[1]);
  5695. $statements = $this->getStatementArray($fileContent, 1);
  5696. $maxL = 1000;
  5697. $strLen = strlen($fileContent);
  5698. $maxlen = 200+($maxL-t3lib_div::intInRange(($strLen-20000)/100,0,$maxL));
  5699. if (count($statements)) {
  5700. $out = '';
  5701. foreach ($statements as $statement) {
  5702. $out.= '<p>' . nl2br(htmlspecialchars(t3lib_div::fixed_lgd_cs($statement,$maxlen))) . '</p>';
  5703. }
  5704. }
  5705. $this->message($tLabel,'Content of '.basename($actionParts[1]),$out,1);
  5706. }
  5707. break;
  5708. // Create admin user
  5709. case 'adminUser':
  5710. if ($whichTables['be_users']) {
  5711. if (is_array($this->INSTALL['database_adminUser'])) {
  5712. $username = preg_replace('/[^\da-z._-]/i', '', trim($this->INSTALL['database_adminUser']['username']));
  5713. $pass = trim($this->INSTALL['database_adminUser']['password']);
  5714. $pass2 = trim($this->INSTALL['database_adminUser']['password2']);
  5715. if ($username && $pass && $pass2) {
  5716. if ($pass != $pass2) {
  5717. $this->message($headCode, 'Passwords are not equal!', '
  5718. <p>
  5719. The passwords entered twice are not
  5720. equal.
  5721. </p>
  5722. ', 2, 1);
  5723. } else {
  5724. $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid', 'be_users', 'username='.$GLOBALS['TYPO3_DB']->fullQuoteStr($username, 'be_users'));
  5725. if (!$GLOBALS['TYPO3_DB']->sql_num_rows($res)) {
  5726. $insertFields = array(
  5727. 'username' => $username,
  5728. 'password' => md5($pass),
  5729. 'admin' => 1,
  5730. 'uc' => '',
  5731. 'fileoper_perms' => 0,
  5732. 'tstamp' => $GLOBALS['EXEC_TIME'],
  5733. 'crdate' => $GLOBALS['EXEC_TIME']
  5734. );
  5735. $result = $GLOBALS['TYPO3_DB']->exec_INSERTquery('be_users', $insertFields);
  5736. $this->isBasicComplete($headCode);
  5737. if ($result) {
  5738. $this->message($headCode, 'User created', '
  5739. <p>
  5740. Username:
  5741. <strong>' .
  5742. htmlspecialchars($username) . '
  5743. </strong>
  5744. </p>
  5745. ', 1, 1);
  5746. } else {
  5747. $this->message($headCode, 'User not created', '
  5748. <p>
  5749. Error:
  5750. <strong>' .
  5751. htmlspecialchars($GLOBALS['TYPO3_DB']->sql_error()) . '
  5752. </strong>
  5753. </p>
  5754. ', 3, 1);
  5755. }
  5756. } else {
  5757. $this->message($headCode, 'Username not unique!', '
  5758. <p>
  5759. The username,
  5760. <strong>' .
  5761. htmlspecialchars($username) . '
  5762. </strong>
  5763. , was not unique.
  5764. </p>
  5765. ', 2, 1);
  5766. }
  5767. }
  5768. } else {
  5769. $this->message($headCode, 'Missing data!', '
  5770. <p>
  5771. Not all required form fields have been
  5772. filled.
  5773. </p>
  5774. ', 2, 1);
  5775. }
  5776. }
  5777. // Get the template file
  5778. $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'CheckTheDatabaseAdminUser.html');
  5779. // Get the template part from the file
  5780. $content = t3lib_parsehtml::getSubpart($templateFile, '###TEMPLATE###');
  5781. // Define the markers content
  5782. $contentMarkers = array(
  5783. 'userName' => 'username - unique, no space, lowercase',
  5784. 'password' => 'password',
  5785. 'repeatPassword' => 'password (repeated)'
  5786. );
  5787. // Fill the markers
  5788. $content = t3lib_parsehtml::substituteMarkerArray(
  5789. $content,
  5790. $contentMarkers,
  5791. '###|###',
  5792. TRUE,
  5793. FALSE
  5794. );
  5795. $form = $this->getUpdateDbFormWrap($action_type, $content);
  5796. $this->message($headCode, 'Create admin user', '
  5797. <p>
  5798. Enter username and password for a new admin
  5799. user.
  5800. <br />
  5801. You should use this function only if there are
  5802. no admin users in the database, for instance if
  5803. this is a blank database.
  5804. <br />
  5805. After you\'ve created the user, log in and add
  5806. the rest of the user information, like email and
  5807. real name.
  5808. </p>
  5809. ' . $form, 0, 1);
  5810. } else {
  5811. $this->message($headCode, 'Required table not in database', '
  5812. <p>
  5813. \'be_users\' must be a table in the database!
  5814. </p>
  5815. ', 3, 1);
  5816. }
  5817. break;
  5818. // clear uc
  5819. case 'UC':
  5820. if ($whichTables['be_users']) {
  5821. if (!strcmp($this->INSTALL['database_UC'],1)) {
  5822. $GLOBALS['TYPO3_DB']->exec_UPDATEquery('be_users', '', array('uc' => ''));
  5823. $this->message($headCode, 'Clearing be_users.uc', '
  5824. <p>
  5825. Done.
  5826. </p>
  5827. ', 1);
  5828. }
  5829. // Get the template file
  5830. $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'CheckTheDatabaseUc.html');
  5831. // Get the template part from the file
  5832. $content = t3lib_parsehtml::getSubpart($templateFile, '###TEMPLATE###');
  5833. // Define the markers content
  5834. $contentMarkers = array(
  5835. 'clearBeUsers' => 'Clear be_users preferences ("uc" field)'
  5836. );
  5837. // Fill the markers
  5838. $content = t3lib_parsehtml::substituteMarkerArray(
  5839. $content,
  5840. $contentMarkers,
  5841. '###|###',
  5842. TRUE,
  5843. FALSE
  5844. );
  5845. $form = $this->getUpdateDbFormWrap($action_type, $content);
  5846. $this->message($headCode, 'Clear user preferences', '
  5847. <p>
  5848. If you press this button all backend users from
  5849. the tables be_users will have their user
  5850. preferences cleared (field \'uc\' set to an
  5851. empty string).
  5852. <br />
  5853. This may come in handy in rare cases where that
  5854. configuration may be corrupt.
  5855. <br />
  5856. Clearing this will clear all user settings from
  5857. the \'Setup\' module.
  5858. </p>
  5859. ' . $form);
  5860. } else {
  5861. $this->message($headCode, 'Required table not in database', '
  5862. <p>
  5863. \'be_users\' must be a table in the database!
  5864. </p>
  5865. ', 3);
  5866. }
  5867. break;
  5868. case 'cache':
  5869. $tableListArr = explode(',','cache_pages,cache_pagesection,cache_hash,cache_imagesizes,--div--,sys_log,sys_history,--div--,be_sessions,fe_sessions,fe_session_data'.
  5870. (t3lib_extMgm::isLoaded('indexed_search') ? ',--div--,index_words,index_rel,index_phash,index_grlist,index_section,index_fulltext' : '').
  5871. (t3lib_extMgm::isLoaded('tt_products') ? ',--div--,sys_products_orders,sys_products_orders_mm_tt_products' : '').
  5872. (t3lib_extMgm::isLoaded('direct_mail') ? ',--div--,sys_dmail_maillog' : '').
  5873. (t3lib_extMgm::isLoaded('sys_stat') ? ',--div--,sys_stat' : '')
  5874. );
  5875. if (is_array($this->INSTALL['database_clearcache'])) {
  5876. $qList = array();
  5877. // Get the template file
  5878. $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'CheckTheDatabaseCache.html');
  5879. // Get the subpart for emptied tables
  5880. $emptiedTablesSubpart = t3lib_parsehtml::getSubpart($templateFile, '###EMPTIEDTABLES###');
  5881. // Get the subpart for table
  5882. $tableSubpart = t3lib_parsehtml::getSubpart($emptiedTablesSubpart, '###TABLE###');
  5883. foreach ($tableListArr as $table) {
  5884. if ($table!='--div--') {
  5885. $table_c = TYPO3_OS=='WIN' ? strtolower($table) : $table;
  5886. if ($this->INSTALL['database_clearcache'][$table] && $whichTables[$table_c]) {
  5887. $GLOBALS['TYPO3_DB']->exec_TRUNCATEquery($table);
  5888. // Define the markers content
  5889. $emptiedTablesMarkers = array(
  5890. 'tableName' => $table
  5891. );
  5892. // Fill the markers in the subpart
  5893. $qList[] = t3lib_parsehtml::substituteMarkerArray(
  5894. $tableSubpart,
  5895. $emptiedTablesMarkers,
  5896. '###|###',
  5897. TRUE,
  5898. FALSE
  5899. );
  5900. }
  5901. }
  5902. }
  5903. // Substitute the subpart for table
  5904. $emptiedTablesSubpart = t3lib_parsehtml::substituteSubpart(
  5905. $emptiedTablesSubpart,
  5906. '###TABLE###',
  5907. implode(LF, $qList)
  5908. );
  5909. if (count($qList)) {
  5910. $this->message($headCode, 'Clearing cache', '
  5911. <p>
  5912. The following tables were emptied:
  5913. </p>
  5914. ' . $emptiedTablesSubpart, 1);
  5915. }
  5916. }
  5917. // Count entries and make checkboxes
  5918. $labelArr = array(
  5919. 'cache_pages' => 'Pages',
  5920. 'cache_pagesection' => 'TS template related information',
  5921. 'cache_hash' => 'Multipurpose md5-hash cache',
  5922. 'cache_imagesizes' => 'Cached image sizes',
  5923. 'sys_log' => 'Backend action logging',
  5924. 'sys_stat' => 'Page hit statistics',
  5925. '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.',
  5926. 'be_sessions' => 'Backend User sessions',
  5927. 'fe_sessions' => 'Frontend User sessions',
  5928. 'fe_session_data' => 'Frontend User sessions data',
  5929. 'sys_dmail_maillog' => 'Direct Mail log',
  5930. 'sys_products_orders' => 'tt_product orders',
  5931. 'sys_products_orders_mm_tt_products' => 'relations between tt_products and sys_products_orders'
  5932. );
  5933. $countEntries=array();
  5934. reset($tableListArr);
  5935. // Get the template file
  5936. $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'CheckTheDatabaseCache.html');
  5937. // Get the subpart for table list
  5938. $tableListSubpart = t3lib_parsehtml::getSubpart($templateFile, '###TABLELIST###');
  5939. // Get the subpart for the group separator
  5940. $groupSubpart = t3lib_parsehtml::getSubpart($tableListSubpart, '###GROUP###');
  5941. // Get the subpart for a single table
  5942. $singleTableSubpart = t3lib_parsehtml::getSubpart($tableListSubpart, '###SINGLETABLE###');
  5943. $checkBoxes = array();
  5944. foreach ($tableListArr as $table) {
  5945. if ($table!='--div--') {
  5946. $table_c = TYPO3_OS=='WIN' ? strtolower($table) : $table;
  5947. if ($whichTables[$table_c]) {
  5948. $countEntries[$table] = $GLOBALS['TYPO3_DB']->exec_SELECTcountRows('*', $table);
  5949. // Checkboxes:
  5950. if (
  5951. $this->INSTALL['database_clearcache'][$table] ||
  5952. $_GET['PRESET']['database_clearcache'][$table]
  5953. ) {
  5954. $checked = 'checked="checked"';
  5955. } else {
  5956. $checked = '';
  5957. }
  5958. // Define the markers content
  5959. $singleTableMarkers = array(
  5960. 'table' => $table,
  5961. 'checked' => $checked,
  5962. 'count' => '(' . $countEntries[$table] . ' rows)',
  5963. 'label' => $labelArr[$table]
  5964. );
  5965. // Fill the markers in the subpart
  5966. $checkBoxes[] = t3lib_parsehtml::substituteMarkerArray(
  5967. $singleTableSubpart,
  5968. $singleTableMarkers,
  5969. '###|###',
  5970. TRUE,
  5971. FALSE
  5972. );
  5973. }
  5974. } else {
  5975. $checkBoxes[] = $groupSubpart;
  5976. }
  5977. }
  5978. // Substitute the subpart for the single tables
  5979. $content = t3lib_parsehtml::substituteSubpart(
  5980. $tableListSubpart,
  5981. '###SINGLETABLE###',
  5982. implode(LF, $checkBoxes)
  5983. );
  5984. // Substitute the subpart for the group separator
  5985. $content = t3lib_parsehtml::substituteSubpart(
  5986. $content,
  5987. '###GROUP###',
  5988. ''
  5989. );
  5990. $form = $this->getUpdateDbFormWrap($action_type, $content);
  5991. $this->message($headCode, 'Clear out selected tables', '
  5992. <p>
  5993. Pressing this button will delete all records from
  5994. the selected tables.
  5995. </p>
  5996. ' . $form);
  5997. break;
  5998. }
  5999. }
  6000. $this->output($this->outputWrapper($this->printAll()));
  6001. }
  6002. /**
  6003. * Generates update wizard
  6004. *
  6005. * @return void
  6006. */
  6007. function updateWizard() {
  6008. // clear cache files
  6009. t3lib_extMgm::removeCacheFiles(t3lib_extMgm::getCacheFilePrefix());
  6010. // call wizard
  6011. $action = ($this->INSTALL['database_type'] ? $this->INSTALL['database_type'] : 'checkForUpdate');
  6012. $this->updateWizard_parts($action);
  6013. $this->output($this->outputWrapper($this->printAll()));
  6014. }
  6015. /**
  6016. * Implements the steps for the update wizard
  6017. *
  6018. * @param string $action Which should be done.
  6019. * @return void
  6020. */
  6021. function updateWizard_parts($action) {
  6022. $content = '';
  6023. $updateItems = array();
  6024. // Get the template file
  6025. $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'UpdateWizardParts.html');
  6026. switch ($action) {
  6027. // first step - check for updates available
  6028. case 'checkForUpdate':
  6029. // Get the subpart for check for update
  6030. $checkForUpdateSubpart = t3lib_parsehtml::getSubpart($templateFile, '###CHECKFORUPDATE###');
  6031. $title = 'Step 1 - Introduction';
  6032. $updateWizardBoxes = '';
  6033. if (!$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install']['update']) {
  6034. $updatesAvailableSubpart = '
  6035. <p>
  6036. <strong>
  6037. No updates registered!
  6038. </strong>
  6039. </p>
  6040. ';
  6041. } else {
  6042. // step through list of updates, and check if update is needed and if yes, output an explanation
  6043. $updatesAvailableSubpart = t3lib_parsehtml::getSubpart($checkForUpdateSubpart, '###UPDATESAVAILABLE###');
  6044. $updateWizardBoxesSubpart = t3lib_parsehtml::getSubpart($updatesAvailableSubpart, '###UPDATEWIZARDBOXES###');
  6045. $singleUpdateWizardBoxSubpart = t3lib_parsehtml::getSubpart($updateWizardBoxesSubpart, '###SINGLEUPDATEWIZARDBOX###');
  6046. $singleUpdate = array();
  6047. foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install']['update'] as $identifier => $className) {
  6048. $tmpObj = $this->getUpgradeObjInstance($className, $identifier);
  6049. if ($tmpObj->shouldRenderWizard()) {
  6050. $explanation = '';
  6051. $tmpObj->checkForUpdate($explanation);
  6052. $updateMarkers = array(
  6053. 'next' => '<button type="submit" name="TYPO3_INSTALL[update][###IDENTIFIER###]">
  6054. Next
  6055. <span class="t3-install-form-button-icon-positive">&nbsp;</span>
  6056. </button>',
  6057. 'identifier' => $identifier,
  6058. 'title' => $tmpObj->getTitle(),
  6059. 'explanation' => $explanation,
  6060. );
  6061. // only display the message, no button
  6062. if (!$tmpObj->shouldRenderNextButton()) {
  6063. $updateMarkers['next'] = '';
  6064. }
  6065. $singleUpdate[] = t3lib_parsehtml::substituteMarkerArray(
  6066. $singleUpdateWizardBoxSubpart,
  6067. $updateMarkers,
  6068. '###|###',
  6069. TRUE,
  6070. FALSE
  6071. );
  6072. }
  6073. }
  6074. if (!empty($singleUpdate)) {
  6075. $updateWizardBoxesSubpart = t3lib_parsehtml::substituteSubpart(
  6076. $updateWizardBoxesSubpart,
  6077. '###SINGLEUPDATEWIZARDBOX###',
  6078. implode(LF, $singleUpdate)
  6079. );
  6080. $updateWizardBoxesMarkers = array(
  6081. 'action' => $this->action
  6082. );
  6083. $updateWizardBoxesSubpart = t3lib_parsehtml::substituteMarkerArray(
  6084. $updateWizardBoxesSubpart,
  6085. $updateWizardBoxesMarkers,
  6086. '###|###',
  6087. TRUE,
  6088. FALSE
  6089. );
  6090. } else {
  6091. $updateWizardBoxesSubpart = '
  6092. <p>
  6093. <strong>
  6094. No updates to perform!
  6095. </strong>
  6096. </p>
  6097. ';
  6098. }
  6099. $updatesAvailableSubpart = t3lib_parsehtml::substituteSubpart(
  6100. $updatesAvailableSubpart,
  6101. '###UPDATEWIZARDBOXES###',
  6102. $updateWizardBoxesSubpart
  6103. );
  6104. $updatesAvailableMarkers = array(
  6105. 'finalStep' => 'Final Step',
  6106. 'finalStepExplanation' => '
  6107. <p>
  6108. When all updates are done you should check
  6109. your database for required updates.
  6110. <br />
  6111. Perform
  6112. <strong>
  6113. COMPARE DATABASE
  6114. </strong>
  6115. as often until no more changes are required.
  6116. <br />
  6117. <br />
  6118. </p>
  6119. ',
  6120. 'compareDatabase' => 'COMPARE DATABASE'
  6121. );
  6122. $updatesAvailableSubpart = t3lib_parsehtml::substituteMarkerArray(
  6123. $updatesAvailableSubpart,
  6124. $updatesAvailableMarkers,
  6125. '###|###',
  6126. TRUE,
  6127. FALSE
  6128. );
  6129. }
  6130. $content = t3lib_parsehtml::substituteSubpart(
  6131. $checkForUpdateSubpart,
  6132. '###UPDATESAVAILABLE###',
  6133. $updatesAvailableSubpart
  6134. );
  6135. break;
  6136. // second step - get user input and ask for final confirmation
  6137. case 'getUserInput':
  6138. $title = 'Step 2 - Configuration of updates';
  6139. $getUserInputSubpart = t3lib_parsehtml::getSubpart($templateFile, '###GETUSERINPUT###');
  6140. $markers = array(
  6141. 'introduction' => 'The following updates will be performed:',
  6142. 'showDatabaseQueries' => 'Show database queries performed',
  6143. 'performUpdates' => 'Perform updates!',
  6144. 'action' => $this->action
  6145. );
  6146. if (!$this->INSTALL['update']) {
  6147. $noUpdatesAvailableSubpart = t3lib_parsehtml::getSubpart($getUserInputSubpart, '###NOUPDATESAVAILABLE###');
  6148. $noUpdateMarkers['noUpdates'] = 'No updates selected!';
  6149. $noUpdatesAvailableSubpart = t3lib_parsehtml::substituteMarkerArray(
  6150. $noUpdatesAvailableSubpart,
  6151. $noUpdateMarkers,
  6152. '###|###',
  6153. TRUE,
  6154. FALSE
  6155. );
  6156. break;
  6157. } else {
  6158. // update methods might need to get custom data
  6159. $updatesAvailableSubpart = t3lib_parsehtml::getSubpart($getUserInputSubpart, '###UPDATESAVAILABLE###');
  6160. $updateItems = array();
  6161. foreach ($this->INSTALL['update'] as $identifier => $tmp) {
  6162. $updateMarkers = array();
  6163. $className = $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install']['update'][$identifier];
  6164. $tmpObj = $this->getUpgradeObjInstance($className, $identifier);
  6165. $updateMarkers['identifier'] = $identifier;
  6166. $updateMarkers['title'] = $tmpObj->getTitle();
  6167. if (method_exists($tmpObj,'getUserInput')) {
  6168. $updateMarkers['identifierMethod'] = $tmpObj->getUserInput('TYPO3_INSTALL[update][' . $identifier . ']');
  6169. }
  6170. $updateItems[] = t3lib_parsehtml::substituteMarkerArray(
  6171. $updatesAvailableSubpart,
  6172. $updateMarkers,
  6173. '###|###',
  6174. TRUE,
  6175. TRUE
  6176. );
  6177. }
  6178. $updatesAvailableSubpart = implode(LF, $updateItems);
  6179. }
  6180. $content = t3lib_parsehtml::substituteSubpart(
  6181. $getUserInputSubpart,
  6182. '###NOUPDATESAVAILABLE###',
  6183. $noUpdatesAvailableSubpart
  6184. );
  6185. $content = t3lib_parsehtml::substituteSubpart(
  6186. $content,
  6187. '###UPDATESAVAILABLE###',
  6188. $updatesAvailableSubpart
  6189. );
  6190. $content = t3lib_parsehtml::substituteMarkerArray(
  6191. $content,
  6192. $markers,
  6193. '###|###',
  6194. TRUE,
  6195. FALSE
  6196. );
  6197. break;
  6198. case 'performUpdate': // third step - perform update
  6199. $title = 'Step 3 - Perform updates';
  6200. $performUpdateSubpart = t3lib_parsehtml::getSubpart($templateFile, '###PERFORMUPDATE###');
  6201. $updateItemsSubpart = t3lib_parsehtml::getSubpart($performUpdateSubpart, '###UPDATEITEMS###');
  6202. $checkUserInputSubpart = t3lib_parsehtml::getSubpart($updateItemsSubpart, '###CHECKUSERINPUT###');
  6203. $updatePerformedSubpart = t3lib_parsehtml::getSubpart($updateItemsSubpart, '###UPDATEPERFORMED###');
  6204. $noPerformUpdateSubpart = t3lib_parsehtml::getSubpart($updateItemsSubpart, '###NOPERFORMUPDATE###');
  6205. $databaseQueriesSubpart = t3lib_parsehtml::getSubpart($updatePerformedSubpart, '###DATABASEQUERIES###');
  6206. $customOutputSubpart = t3lib_parsehtml::getSubpart($updatePerformedSubpart, '###CUSTOMOUTPUT###');
  6207. if (!$this->INSTALL['update']['extList']) { break; }
  6208. $GLOBALS['TYPO3_DB']->store_lastBuiltQuery = TRUE;
  6209. foreach ($this->INSTALL['update']['extList'] as $identifier) {
  6210. $className = $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install']['update'][$identifier];
  6211. $tmpObj = $this->getUpgradeObjInstance($className, $identifier);
  6212. $updateItemsMarkers['identifier'] = $identifier;
  6213. $updateItemsMarkers['title'] = $tmpObj->getTitle();
  6214. // check user input if testing method is available
  6215. if (method_exists($tmpObj,'checkUserInput') && !$tmpObj->checkUserInput($customOutput)) {
  6216. $customOutput = '';
  6217. $userInputMarkers = array(
  6218. 'customOutput' => ($customOutput ? $customOutput : 'Something went wrong'),
  6219. 'goBack' => 'Go back to update configuration'
  6220. );
  6221. $checkUserInput = t3lib_parsehtml::substituteMarkerArray(
  6222. $checkUserInputSubpart,
  6223. $userInputMarkers,
  6224. '###|###',
  6225. TRUE,
  6226. FALSE
  6227. );
  6228. } else {
  6229. if (method_exists($tmpObj,'performUpdate')) {
  6230. $customOutput = '';
  6231. $dbQueries = array();
  6232. $databaseQueries = array();
  6233. if ($tmpObj->performUpdate($dbQueries, $customOutput)) {
  6234. $performUpdateMarkers['updateStatus'] = 'Update successful!';
  6235. } else {
  6236. $performUpdateMarkers['updateStatus'] = 'Update FAILED!';
  6237. }
  6238. if ($this->INSTALL['update']['showDatabaseQueries']) {
  6239. $content .= '<br />' . implode('<br />',$dbQueries);
  6240. foreach($dbQueries as $query) {
  6241. $databaseQueryMarkers['query'] = $query;
  6242. $databaseQueries[] = t3lib_parsehtml::substituteMarkerArray(
  6243. $databaseQueriesSubpart,
  6244. $databaseQueryMarkers,
  6245. '###|###',
  6246. TRUE,
  6247. FALSE
  6248. );
  6249. }
  6250. }
  6251. if (strlen($customOutput)) {
  6252. $content.= '<br />' . $customOutput;
  6253. $customOutputMarkers['custom'] = $customOutput;
  6254. $customOutputItem = t3lib_parsehtml::substituteMarkerArray(
  6255. $customOutputSubpart,
  6256. $customOutputMarkers,
  6257. '###|###',
  6258. TRUE,
  6259. FALSE
  6260. );
  6261. }
  6262. $updatePerformed = t3lib_parsehtml::substituteSubpart(
  6263. $updatePerformedSubpart,
  6264. '###DATABASEQUERIES###',
  6265. implode(LF, $databaseQueries)
  6266. );
  6267. $updatePerformed = t3lib_parsehtml::substituteSubpart(
  6268. $updatePerformed,
  6269. '###CUSTOMOUTPUT###',
  6270. $customOutputItem
  6271. );
  6272. $updatePerformed = t3lib_parsehtml::substituteMarkerArray(
  6273. $updatePerformed,
  6274. $performUpdateMarkers,
  6275. '###|###',
  6276. TRUE,
  6277. FALSE
  6278. );
  6279. } else {
  6280. $noPerformUpdateMarkers['noUpdateMethod'] = 'No update method available!';
  6281. $noPerformUpdate = t3lib_parsehtml::substituteMarkerArray(
  6282. $noPerformUpdateSubpart,
  6283. $noPerformUpdateMarkers,
  6284. '###|###',
  6285. TRUE,
  6286. FALSE
  6287. );
  6288. }
  6289. }
  6290. $updateItem = t3lib_parsehtml::substituteSubpart(
  6291. $updateItemsSubpart,
  6292. '###CHECKUSERINPUT###',
  6293. $checkUserInput
  6294. );
  6295. $updateItem = t3lib_parsehtml::substituteSubpart(
  6296. $updateItem,
  6297. '###UPDATEPERFORMED###',
  6298. $updatePerformed
  6299. );
  6300. $updateItem = t3lib_parsehtml::substituteSubpart(
  6301. $updateItem,
  6302. '###NOPERFORMUPDATE###',
  6303. $noPerformUpdate
  6304. );
  6305. $updateItem = t3lib_parsehtml::substituteSubpart(
  6306. $updateItem,
  6307. '###UPDATEITEMS###',
  6308. implode(LF, $updateItems)
  6309. );
  6310. $updateItems[] = t3lib_parsehtml::substituteMarkerArray(
  6311. $updateItem,
  6312. $updateItemsMarkers,
  6313. '###|###',
  6314. TRUE,
  6315. FALSE
  6316. );
  6317. }
  6318. $content = t3lib_parsehtml::substituteSubpart(
  6319. $performUpdateSubpart,
  6320. '###UPDATEITEMS###',
  6321. implode(LF, $updateItems)
  6322. );
  6323. $GLOBALS['TYPO3_DB']->store_lastBuiltQuery = FALSE;
  6324. // also render the link to the next update wizard, if available
  6325. $nextUpdateWizard = $this->getNextUpdadeWizardInstance($tmpObj);
  6326. if ($nextUpdateWizard) {
  6327. $content = t3lib_parsehtml::substituteMarkerArray(
  6328. $content,
  6329. array('NEXTIDENTIFIER' => $nextUpdateWizard->getIdentifier()),
  6330. '###|###',
  6331. TRUE,
  6332. FALSE
  6333. );
  6334. } else {
  6335. // no next wizard, also hide the button to the next update wizard
  6336. $content = t3lib_parsehtml::substituteSubpart(
  6337. $content,
  6338. '###NEXTUPDATEWIZARD###',
  6339. ''
  6340. );
  6341. }
  6342. break;
  6343. }
  6344. $this->message('Upgrade Wizard', $title, $content);
  6345. }
  6346. /**
  6347. * Creates instance of an upgrade object, setting the pObj, versionNumber and pObj
  6348. *
  6349. * @param string $className The class name
  6350. * @param string $identifier The identifier of upgrade object - needed to fetch user input
  6351. * @return object Newly instanciated upgrade object
  6352. */
  6353. function getUpgradeObjInstance($className, $identifier) {
  6354. $tmpObj = t3lib_div::getUserObj($className);
  6355. $tmpObj->setIdentifier($identifier);
  6356. $tmpObj->versionNumber = t3lib_div::int_from_ver(TYPO3_version);
  6357. $tmpObj->pObj = $this;
  6358. $tmpObj->userInput = $this->INSTALL['update'][$identifier];
  6359. return $tmpObj;
  6360. }
  6361. /**
  6362. * Returns the next upgrade wizard object.
  6363. *
  6364. * Used to show the link/button to the next upgrade wizard
  6365. * @param object $currentObj current Upgrade Wizard Object
  6366. * @return mixed Upgrade Wizard instance or FALSE
  6367. */
  6368. protected function getNextUpdadeWizardInstance($currentObj) {
  6369. $isPreviousRecord = TRUE;
  6370. foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install']['update'] as $identifier => $className) {
  6371. // first, find the current update wizard, and then start validating the next ones
  6372. if ($currentObj->getIdentifier() == $identifier) {
  6373. $isPreviousRecord = FALSE;
  6374. continue;
  6375. }
  6376. if (!$isPreviousRecord) {
  6377. $nextUpdateWizard = $this->getUpgradeObjInstance($className, $identifier);
  6378. if ($nextUpdateWizard->shouldRenderWizard()) {
  6379. return $nextUpdateWizard;
  6380. }
  6381. }
  6382. }
  6383. return FALSE;
  6384. }
  6385. /**
  6386. * Check if at lease one backend admin user has been created
  6387. *
  6388. * @return integer Amount of backend users in the database
  6389. */
  6390. function isBackendAdminUser() {
  6391. return $GLOBALS['TYPO3_DB']->exec_SELECTcountRows('uid', 'be_users', 'admin=1');
  6392. }
  6393. /**
  6394. * Check if the basic settings are complete
  6395. * Only used by 1-2-3 mode
  6396. *
  6397. * @param string $tLabel The header for the message
  6398. * @return boolean TRUE if complete
  6399. */
  6400. function isBasicComplete($tLabel) {
  6401. if ($this->mode=='123') {
  6402. $tables = $this->getListOfTables();
  6403. if (count($tables)) {
  6404. $beuser = $this->isBackendAdminUser();
  6405. }
  6406. if (count($tables) && $beuser) {
  6407. $mode123Imported=1;
  6408. $this->message($tLabel, 'Basic Installation Completed', $this->messageBasicFinished(), -1, 1);
  6409. $this->message($tLabel,'Security Risk!',$this->securityRisk().$this->alterPasswordForm(),2,1);
  6410. } else {
  6411. $this->message($tLabel,'Still missing something?',nl2br('
  6412. You may be missing one of these points before your TYPO3 installation is complete:
  6413. '.(count($tables)?'':'- You haven\'t imported any tables yet.
  6414. ')
  6415. .($beuser?'':'- You haven\'t created an admin user yet.
  6416. ')
  6417. .'
  6418. You\'re about to import a database with a complete site in it, these three points should be met.
  6419. '),-1,1);
  6420. }
  6421. }
  6422. return $mode123Imported;
  6423. }
  6424. /**
  6425. * Generate the contents for the form for 'Database Analyzer'
  6426. * when the 'COMPARE' still contains errors
  6427. *
  6428. * @param string $type get_form if the form needs to be generated
  6429. * @param array $arr_update The tables/fields which needs an update
  6430. * @param array $arr_remove The tables/fields which needs to be removed
  6431. * @param string $action_type The action type
  6432. * @return string HTML for the form
  6433. */
  6434. function generateUpdateDatabaseForm($type, $arr_update, $arr_remove, $action_type) {
  6435. $content = '';
  6436. switch($type) {
  6437. case 'get_form':
  6438. $content.= $this->generateUpdateDatabaseForm_checkboxes($arr_update['clear_table'],'Clear tables (use with care!)',false,true);
  6439. $content.= $this->generateUpdateDatabaseForm_checkboxes($arr_update['add'],'Add fields');
  6440. $content.= $this->generateUpdateDatabaseForm_checkboxes($arr_update['change'],'Changing fields',(t3lib_extMgm::isLoaded('dbal')?0:1),0,$arr_update['change_currentValue']);
  6441. $content.= $this->generateUpdateDatabaseForm_checkboxes($arr_remove['change'],'Remove unused fields (rename with prefix)',$this->setAllCheckBoxesByDefault,1);
  6442. $content.= $this->generateUpdateDatabaseForm_checkboxes($arr_remove['drop'],'Drop fields (really!)',$this->setAllCheckBoxesByDefault);
  6443. $content.= $this->generateUpdateDatabaseForm_checkboxes($arr_update['create_table'],'Add tables');
  6444. $content.= $this->generateUpdateDatabaseForm_checkboxes($arr_remove['change_table'],'Removing tables (rename with prefix)',$this->setAllCheckBoxesByDefault,1,$arr_remove['tables_count'],1);
  6445. $content.= $this->generateUpdateDatabaseForm_checkboxes($arr_remove['drop_table'],'Drop tables (really!)',$this->setAllCheckBoxesByDefault,0,$arr_remove['tables_count'],1);
  6446. $content = $this->getUpdateDbFormWrap($action_type, $content);
  6447. break;
  6448. default:
  6449. break;
  6450. }
  6451. return $content;
  6452. }
  6453. /**
  6454. * Form wrap for 'Database Analyzer'
  6455. * when the 'COMPARE' still contains errors
  6456. *
  6457. * @param string $action_type The action type
  6458. * @param string $content The form content
  6459. * @param string $label The submit button label
  6460. * @return string HTML of the form
  6461. */
  6462. function getUpdateDbFormWrap($action_type, $content, $label='Write to database') {
  6463. // Get the template file
  6464. $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'GetUpdateDbFormWrap.html');
  6465. // Get the template part from the file
  6466. $form = t3lib_parsehtml::getSubpart($templateFile, '###TEMPLATE###');
  6467. // Define the markers content
  6468. $formMarkers = array(
  6469. 'action' => $this->action,
  6470. 'actionType' => htmlspecialchars($action_type),
  6471. 'content' => $content,
  6472. 'label' => $label
  6473. );
  6474. // Fill the markers
  6475. $form = t3lib_parsehtml::substituteMarkerArray(
  6476. $form,
  6477. $formMarkers,
  6478. '###|###',
  6479. TRUE,
  6480. FALSE
  6481. );
  6482. return $form;
  6483. }
  6484. /**
  6485. * Generates an HTML table for the setup of database tables
  6486. * Used in 'Database analyzer > Compare with $TCA'
  6487. *
  6488. * @param array $arr Description of the table with fieldname and fieldcontent
  6489. * @param boolean $pre TRUE if the field content needs to be wrapped with a <pre> tag
  6490. * @param string $label The header label
  6491. * @return string HTML of the table
  6492. */
  6493. function displayFields($arr, $pre=0, $label='') {
  6494. // Get the template file
  6495. $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'DisplayFields.html');
  6496. // Get the template part from the file
  6497. $template = t3lib_parsehtml::getSubpart($templateFile, '###TEMPLATE###');
  6498. // Define the markers content
  6499. $templateMarkers = array(
  6500. 'headerFieldName' => 'Field name:',
  6501. 'headerLabel' => $label ? $label : 'Info:'
  6502. );
  6503. if (is_array($arr)) {
  6504. $rows = array();
  6505. // Get the subpart for rows
  6506. $rowsSubpart = t3lib_parsehtml::getSubpart($template, '###ROWS###');
  6507. foreach ($arr as $fieldname => $fieldContent) {
  6508. if ($pre) {
  6509. $fieldContent = '<pre>'.trim($fieldContent).'</pre>';
  6510. }
  6511. // Define the markers content
  6512. $rowsMarkers = array(
  6513. 'fieldName' => $fieldname,
  6514. 'fieldContent' => $fieldContent
  6515. );
  6516. // Fill the markers in the subpart
  6517. $rows[] = t3lib_parsehtml::substituteMarkerArray(
  6518. $rowsSubpart,
  6519. $rowsMarkers,
  6520. '###|###',
  6521. TRUE,
  6522. FALSE
  6523. );
  6524. }
  6525. }
  6526. // Substitute the subpart for rows
  6527. $template = t3lib_parsehtml::substituteSubpart(
  6528. $template,
  6529. '###ROWS###',
  6530. implode(LF, $rows)
  6531. );
  6532. // Fill the markers
  6533. $template = t3lib_parsehtml::substituteMarkerArray(
  6534. $template,
  6535. $templateMarkers,
  6536. '###|###',
  6537. TRUE,
  6538. FALSE
  6539. );
  6540. return $template;
  6541. }
  6542. /**
  6543. * Generates an HTML table with comparison between database and $TCA
  6544. * Used in 'Database analyzer > Compare with $TCA'
  6545. *
  6546. * @param array $arr Description of the table with fieldname and fieldcontent
  6547. * @param array $arr_db The actual content of a field in the database
  6548. * @return string HTML of the table
  6549. */
  6550. function displayFieldComp($arr, $arr_db) {
  6551. // Get the template file
  6552. $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'DisplayFieldComp.html');
  6553. // Get the template part from the file
  6554. $template = t3lib_parsehtml::getSubpart($templateFile, '###TEMPLATE###');
  6555. // Define the markers content
  6556. $templateMarkers = array(
  6557. 'headerFieldName' => 'Field name:',
  6558. 'headerSuggested' => 'Suggested value from $TCA:',
  6559. 'headerActual' => 'Actual value from database:'
  6560. );
  6561. $rows = array();
  6562. if (is_array($arr)) {
  6563. // Get the subpart for rows
  6564. $rowsSubpart = t3lib_parsehtml::getSubpart($template, '###ROWS###');
  6565. foreach ($arr as $fieldname => $fieldContent) {
  6566. // This tries to equalize the types tinyint and int
  6567. $str1 = $fieldContent;
  6568. $str2 = trim($arr_db[$fieldname]);
  6569. $str1 = str_replace('tinyint(3)','tinyint(4)',$str1);
  6570. $str2 = str_replace('tinyint(3)','tinyint(4)',$str2);
  6571. $str1 = str_replace('int(10)','int(11)',$str1);
  6572. $str2 = str_replace('int(10)','int(11)',$str2);
  6573. // Compare:
  6574. if (strcmp($str1,$str2)) {
  6575. $bgcolor=' class="warning"';
  6576. } else {
  6577. $bgcolor='';
  6578. }
  6579. // Define the markers content
  6580. $rowsMarkers = array(
  6581. 'fieldName' => $fieldname,
  6582. 'fieldContent' => $fieldContent,
  6583. 'fieldContentDb' => $arr_db[$fieldname],
  6584. 'class' => $bgcolor
  6585. );
  6586. // Fill the markers in the subpart
  6587. $rows[] = t3lib_parsehtml::substituteMarkerArray(
  6588. $rowsSubpart,
  6589. $rowsMarkers,
  6590. '###|###',
  6591. TRUE,
  6592. FALSE
  6593. );
  6594. }
  6595. }
  6596. // Substitute the subpart for rows
  6597. $template = t3lib_parsehtml::substituteSubpart(
  6598. $template,
  6599. '###ROWS###',
  6600. implode(LF, $rows)
  6601. );
  6602. // Fill the markers
  6603. $out = t3lib_parsehtml::substituteMarkerArray(
  6604. $template,
  6605. $templateMarkers,
  6606. '###|###',
  6607. TRUE,
  6608. FALSE
  6609. );
  6610. return $out;
  6611. }
  6612. /**
  6613. * Generates an HTML table with $TCA suggestions looking at the type of field
  6614. * Used in 'Database analyzer > Compare with $TCA'
  6615. *
  6616. * @param array $arr Description of the table with fieldname and fieldcontent
  6617. * @param string $excludeList Comma separated list of fields which should be excluded from this table
  6618. * @return string HTML of the table
  6619. */
  6620. function displaySuggestions($arr, $excludeList='') {
  6621. // Get the template file
  6622. $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'DisplaySuggestions.html');
  6623. // Get the template part from the file
  6624. $template = t3lib_parsehtml::getSubpart($templateFile, '###TEMPLATE###');
  6625. $templateMarkers = array();
  6626. $fC=0;
  6627. $rows = array();
  6628. if (is_array($arr)) {
  6629. // Get the subpart for rows
  6630. $rowsSubpart = t3lib_parsehtml::getSubpart($template, '###ROWS###');
  6631. foreach ($arr as $fieldname => $fieldContent) {
  6632. if (!t3lib_div::inList($excludeList,$fieldname) && substr($fieldname,0,strlen($this->deletedPrefixKey))!=$this->deletedPrefixKey && substr($fieldname,-1)!='.') {
  6633. if ($arr[$fieldname.'.']) {
  6634. // Get the subpart for pre
  6635. $preSubpart = t3lib_parsehtml::getSubpart($rowsSubpart, '###PRE###');
  6636. // Define the markers content
  6637. $preMarkers = array(
  6638. 'code' => '<pre>' . trim($arr[$fieldname.'.']) . '</pre>'
  6639. );
  6640. // Fill the markers in the subpart
  6641. $preSubpart = t3lib_parsehtml::substituteMarkerArray(
  6642. $preSubpart,
  6643. $preMarkers,
  6644. '###|###',
  6645. TRUE,
  6646. FALSE
  6647. );
  6648. }
  6649. // Substitute the subpart for pre
  6650. $row = t3lib_parsehtml::substituteSubpart(
  6651. $rowsSubpart,
  6652. '###PRE###',
  6653. $preSubpart
  6654. );
  6655. // Define the markers content
  6656. $rowsMarkers = array(
  6657. 'headerFieldName' => 'Field name:',
  6658. 'headerLabel' => 'Info:',
  6659. 'headerSuggestion' => 'Suggestion for the field:',
  6660. 'fieldName' => $fieldname,
  6661. 'fieldContent' => $fieldContent,
  6662. );
  6663. // Fill the markers in the subpart
  6664. $rows[] = t3lib_parsehtml::substituteMarkerArray(
  6665. $row,
  6666. $rowsMarkers,
  6667. '###|###',
  6668. TRUE,
  6669. FALSE
  6670. );
  6671. $fC++;
  6672. }
  6673. }
  6674. }
  6675. // Substitute the subpart for rows
  6676. $template = t3lib_parsehtml::substituteSubpart(
  6677. $template,
  6678. '###ROWS###',
  6679. implode(LF, $rows)
  6680. );
  6681. // Fill the markers
  6682. $out = t3lib_parsehtml::substituteMarkerArray(
  6683. $template,
  6684. $templateMarkers,
  6685. '###|###',
  6686. TRUE,
  6687. FALSE
  6688. );
  6689. return array($out,$fC);
  6690. }
  6691. /**
  6692. * Compares an array with field definitions with $TCA array
  6693. *
  6694. * @param array $FDsrc Field definition source
  6695. * @param array $TCA The TCA array
  6696. * @param boolean $onlyFields
  6697. * @return array
  6698. */
  6699. function compareDatabaseAndTCA($FDsrc, $TCA, $onlyFields=0) {
  6700. $extraArr=array();
  6701. if (is_array($FDsrc)) {
  6702. foreach ($FDsrc as $table => $info) {
  6703. if (!isset($TCA[$table])) {
  6704. if (!$onlyFields) {
  6705. // If the table was not in the FDcomp-array, the result array is loaded with that table.
  6706. $extraArr[$table]=$info;
  6707. $extraArr[$table]['whole_table']=1;
  6708. unset($extraArr[$table]['keys']);
  6709. }
  6710. } else {
  6711. $theKey='fields';
  6712. $excludeListArr=array();
  6713. if (is_array($TCA[$table]['ctrl']['enablecolumns'])) {
  6714. $excludeListArr[]=$TCA[$table]['ctrl']['enablecolumns'];
  6715. }
  6716. $excludeListArr[]=$TCA[$table]['ctrl']['tstamp'];
  6717. $excludeListArr[]=$TCA[$table]['ctrl']['sortby'];
  6718. $excludeListArr[]=$TCA[$table]['ctrl']['delete'];
  6719. $excludeListArr[]=$TCA[$table]['ctrl']['cruser_id'];
  6720. $excludeListArr[]=$TCA[$table]['ctrl']['crdate'];
  6721. $excludeListArr[]='uid';
  6722. $excludeListArr[]='pid';
  6723. if ($table=='pages') {
  6724. $excludeListArr[]='perms_userid';
  6725. $excludeListArr[]='perms_groupid';
  6726. $excludeListArr[]='perms_user';
  6727. $excludeListArr[]='perms_group';
  6728. $excludeListArr[]='perms_everybody';
  6729. }
  6730. if ($table=='sys_dmail') {
  6731. $excludeListArr[]='scheduled';
  6732. $excludeListArr[]='scheduled_begin';
  6733. $excludeListArr[]='scheduled_end';
  6734. $excludeListArr[]='query_info';
  6735. }
  6736. if (is_array($info[$theKey])) {
  6737. foreach ($info[$theKey] as $fieldN => $fieldC) {
  6738. if (!isset($TCA[$table]['columns'][$fieldN]) && !in_array($fieldN,$excludeListArr)) {
  6739. $extraArr[$table][$theKey][$fieldN] = $info['fields'][$fieldN];
  6740. $extraArr[$table][$theKey][$fieldN.'.']=$this->suggestTCAFieldDefinition($fieldN,$fieldC);
  6741. }
  6742. }
  6743. }
  6744. }
  6745. }
  6746. }
  6747. return array('extra'=>$extraArr);
  6748. }
  6749. /**
  6750. * Compares the $TCA array with a field definition array
  6751. *
  6752. * @param array $TCA The TCA
  6753. * @param array $FDcomp Field definition comparison
  6754. * @return array
  6755. */
  6756. function compareTCAandDatabase($TCA, $FDcomp) {
  6757. $matchingArr = $extraArr = array();
  6758. if (is_array($TCA)) {
  6759. foreach ($TCA as $table => $info) {
  6760. if (!isset($FDcomp[$table])) {
  6761. // If the table was not in the FDcomp-array, the result array is loaded with that table.
  6762. //$extraArr[$table]=$info;
  6763. $extraArr[$table]['whole_table']=1;
  6764. } else {
  6765. foreach ($info['columns'] as $fieldN => $fieldC) {
  6766. $fieldDef = $this->suggestFieldDefinition($fieldC);
  6767. if (!is_array($fieldDef)) {
  6768. if (!isset($FDcomp[$table]['fields'][$fieldN])) {
  6769. $extraArr[$table]['fields'][$fieldN]=$fieldDef;
  6770. } else {
  6771. $matchingArr[$table]['fields'][$fieldN]=$fieldDef;
  6772. }
  6773. }
  6774. }
  6775. }
  6776. }
  6777. }
  6778. return array('extra'=>$extraArr, 'matching'=>$matchingArr);
  6779. }
  6780. /**
  6781. * Suggests a field definition for a TCA config array.
  6782. *
  6783. * @param array $fieldInfo Info of a field
  6784. * @return string The suggestion
  6785. */
  6786. function suggestFieldDefinition($fieldInfo) {
  6787. $out='';
  6788. switch($fieldInfo['config']['type']) {
  6789. case 'input':
  6790. if (preg_match('/date|time|int|year/',$fieldInfo['config']['eval'])) {
  6791. $out = "int(11) NOT NULL default '0'";
  6792. } else {
  6793. $max = intval($fieldInfo['config']['max']);
  6794. if ($max>0 && $max<200) {
  6795. $out = 'varchar('.$max.") NOT NULL default ''";
  6796. } else {
  6797. $out = 'tinytext';
  6798. }
  6799. }
  6800. break;
  6801. case 'text':
  6802. $out = 'text';
  6803. break;
  6804. case 'check':
  6805. if (is_array($fieldInfo['config']['items']) && count($fieldInfo['config']['items'])>8) {
  6806. $out = "int(11) NOT NULL default '0'";
  6807. } else {
  6808. $out = "tinyint(3) NOT NULL default '0'";
  6809. }
  6810. break;
  6811. case 'radio':
  6812. if (is_array($fieldInfo['config']['items'])) {
  6813. $out = $this->getItemArrayType($fieldInfo['config']['items']);
  6814. } else {
  6815. $out = 'ERROR: Radiobox did not have items!';
  6816. }
  6817. break;
  6818. case 'group':
  6819. if ($fieldInfo['config']['internal_type']=='db') {
  6820. $max = t3lib_div::intInRange($fieldInfo['config']['maxitems'],1,10000);
  6821. if (count(explode(',',$fieldInfo['config']['allowed']))>1) {
  6822. // Tablenames are 10, "_" 1, uid's 5, comma 1
  6823. $len = $max*(10+1+5+1);
  6824. $out=$this->getItemBlobSize($len);
  6825. } elseif ($max<=1) {
  6826. $out = "int(11) NOT NULL default '0'";
  6827. } else {
  6828. // uid's 5, comma 1
  6829. $len = $max*(5+1);
  6830. $out=$this->getItemBlobSize($len);
  6831. }
  6832. }
  6833. if ($fieldInfo['config']['internal_type']=='file') {
  6834. $max = t3lib_div::intInRange($fieldInfo['config']['maxitems'],1,10000);
  6835. // Filenames is 30+ chars....
  6836. $len = $max*(30+1);
  6837. $out=$this->getItemBlobSize($len);
  6838. }
  6839. break;
  6840. case 'select':
  6841. $max = t3lib_div::intInRange($fieldInfo['config']['maxitems'],1,10000);
  6842. if ($max<=1) {
  6843. if ($fieldInfo['config']['foreign_table']) {
  6844. $out = "int(11) NOT NULL default '0'";
  6845. } else {
  6846. $out = $this->getItemArrayType($fieldInfo['config']['items']);
  6847. }
  6848. } else {
  6849. // five chars (special=10) + comma:
  6850. $len = $max*(($fieldInfo['config']['special']?10:5)+1);
  6851. $out=$this->getItemBlobSize($len);
  6852. }
  6853. break;
  6854. default:
  6855. break;
  6856. }
  6857. return $out?$out:$fieldInfo;
  6858. }
  6859. /**
  6860. * Check if field needs to be varchar or int
  6861. * Private
  6862. *
  6863. * @param array $arr
  6864. * @return string The definition
  6865. */
  6866. function getItemArrayType($arr) {
  6867. if (is_array($arr)) {
  6868. $type[] = $intSize[] = 0;
  6869. foreach ($arr as $item) {
  6870. if (!t3lib_div::testInt($item[1]) && $item[1]!='--div--') {
  6871. $type[]=strlen($item[1]);
  6872. } else {
  6873. $intSize[]=$item[1];
  6874. }
  6875. }
  6876. $us = min($intSize)>=0 ? ' unsigned' : '';
  6877. if (max($type)>0) {
  6878. $out = 'varchar('.max($type).") NOT NULL default ''";
  6879. } else {
  6880. $out = "int(11) NOT NULL default '0'";
  6881. }
  6882. }
  6883. return $out;
  6884. }
  6885. /**
  6886. * Defines the blob size of an item by a given length
  6887. * Private
  6888. *
  6889. * @param integer $len The length
  6890. * @return string The blob definition
  6891. */
  6892. function getItemBlobSize($len) {
  6893. return ($len>255 ? 'tiny' : '').'blob';
  6894. }
  6895. /**
  6896. * Should suggest a TCA configuration for a specific field.
  6897. *
  6898. * @param string $fieldName The field name
  6899. * @param string $fieldInfo The field information
  6900. * @return string Suggested TCA configuration
  6901. */
  6902. function suggestTCAFieldDefinition($fieldName,$fieldInfo) {
  6903. list($type,$len) = preg_split('/ |\(|\)/', $fieldInfo, 3);
  6904. switch($type) {
  6905. case 'int':
  6906. $out="
  6907. '".$fieldName."' => array (
  6908. 'label' => '".strtoupper($fieldName).":',
  6909. 'exclude' => 0,
  6910. 'config' => array (
  6911. 'type' => 'input',
  6912. 'size' => '8',
  6913. 'max' => '20',
  6914. 'eval' => 'date',
  6915. 'default' => '0',
  6916. 'checkbox' => '0'
  6917. )
  6918. ),
  6919. ----- OR -----
  6920. '".$fieldName."' => array (
  6921. 'label' => '".strtoupper($fieldName).":',
  6922. 'exclude' => 0,
  6923. 'config' => array (
  6924. 'type' => 'select',
  6925. 'items' => array (
  6926. array('[nothing]', 0),
  6927. array('Extra choice! Only negative values here.', -1),
  6928. array('__Divider:__', '--div--')
  6929. ),
  6930. 'foreign_table' => '[some_table_name]'
  6931. )
  6932. ),";
  6933. break;
  6934. case 'varchar':
  6935. if ($len>10) {
  6936. $out="
  6937. '".$fieldName."' => array (
  6938. 'label' => '".strtoupper($fieldName).":',
  6939. 'exclude' => 0,
  6940. 'config' => array (
  6941. 'type' => 'input',
  6942. 'size' => '8',
  6943. 'max' => '".$len."',
  6944. 'eval' => 'trim',
  6945. 'default' => ''
  6946. )
  6947. ),";
  6948. } else {
  6949. $out="
  6950. '".$fieldName."' => array (
  6951. 'label' => '".strtoupper($fieldName).":',
  6952. 'exclude' => 0,
  6953. 'config' => array (
  6954. 'type' => 'select',
  6955. 'items' => array (
  6956. array('Item number 1', 'key1'),
  6957. array('Item number 2', 'key2'),
  6958. array('-----', '--div--'),
  6959. array('Item number 3', 'key3')
  6960. ),
  6961. 'default' => '1'
  6962. )
  6963. ),";
  6964. }
  6965. break;
  6966. case 'tinyint':
  6967. $out="
  6968. '".$fieldName."' => array (
  6969. 'label' => '".strtoupper($fieldName).":',
  6970. 'exclude' => 0,
  6971. 'config' => array (
  6972. 'type' => 'select',
  6973. 'items' => array (
  6974. array('Item number 1', '1'),
  6975. array('Item number 2', '2'),
  6976. array('-----', '--div--'),
  6977. array('Item number 3', '3')
  6978. ),
  6979. 'default' => '1'
  6980. )
  6981. ),
  6982. ----- OR -----
  6983. '".$fieldName."' => array (
  6984. 'label' => '".strtoupper($fieldName).":',
  6985. 'exclude' => 0,
  6986. 'config' => array (
  6987. 'type' => 'check',
  6988. 'default' => '1'
  6989. )
  6990. ),";
  6991. break;
  6992. case 'tinytext':
  6993. $out="
  6994. '".$fieldName."' => array (
  6995. 'label' => '".strtoupper($fieldName).":',
  6996. 'exclude' => 0,
  6997. 'config' => array (
  6998. 'type' => 'input',
  6999. 'size' => '40',
  7000. 'max' => '255',
  7001. 'eval' => '',
  7002. 'default' => ''
  7003. )
  7004. ),";
  7005. break;
  7006. case 'text':
  7007. case 'mediumtext':
  7008. $out="
  7009. '".$fieldName."' => array (
  7010. 'label' => '".strtoupper($fieldName).":',
  7011. 'config' => array (
  7012. 'type' => 'text',
  7013. 'cols' => '48',
  7014. 'rows' => '5'
  7015. )
  7016. ),";
  7017. break;
  7018. default:
  7019. $out="
  7020. '".$fieldName."' => array (
  7021. 'label' => '".strtoupper($fieldName).":',
  7022. 'exclude' => 0,
  7023. 'config' => array (
  7024. 'type' => 'input',
  7025. 'size' => '30',
  7026. 'max' => '',
  7027. 'eval' => '',
  7028. 'default' => ''
  7029. )
  7030. ),";
  7031. break;
  7032. }
  7033. return $out?$out:$fieldInfo;
  7034. }
  7035. /**
  7036. * Includes TCA
  7037. *
  7038. * @return void
  7039. */
  7040. function includeTCA() {
  7041. global $TCA;
  7042. include (TYPO3_tables_script ? PATH_typo3conf.TYPO3_tables_script : PATH_t3lib.'stddb/tables.php');
  7043. // Extension additions
  7044. if ($GLOBALS['TYPO3_LOADED_EXT']['_CACHEFILE']) {
  7045. include(PATH_typo3conf.$GLOBALS['TYPO3_LOADED_EXT']['_CACHEFILE'].'_ext_tables.php');
  7046. } else {
  7047. include(PATH_t3lib.'stddb/load_ext_tables.php');
  7048. }
  7049. if (TYPO3_extTableDef_script) {
  7050. include (PATH_typo3conf.TYPO3_extTableDef_script);
  7051. }
  7052. foreach ($TCA as $table => $conf) {
  7053. t3lib_div::loadTCA($table);
  7054. }
  7055. }
  7056. /**********************
  7057. *
  7058. * GENERAL FUNCTIONS
  7059. *
  7060. **********************/
  7061. /**
  7062. * Setting a message in the message-log and sets the fatalError flag if error type is 3.
  7063. *
  7064. * @param string $head Section header
  7065. * @param string $short_string A short description
  7066. * @param string $long_string A long (more detailed) description
  7067. * @param integer $type -1=OK sign, 0=message, 1=notification, 2=warning, 3=error
  7068. * @param boolean $force Print message also in "Advanced" mode (not only in 1-2-3 mode)
  7069. * @return void
  7070. */
  7071. function message($head, $short_string='', $long_string='', $type=0, $force=0) {
  7072. // Return directly if mode-123 is enabled.
  7073. if (!$force && $this->mode=='123' && $type<2) {
  7074. return;
  7075. }
  7076. if ($type==3) { $this->fatalError=1; }
  7077. $long_string = trim($long_string);
  7078. if (!$this->silent) $this->printSection($head, $short_string, $long_string, $type);
  7079. }
  7080. /**
  7081. * This "prints" a section with a message to the ->sections array
  7082. *
  7083. * @param string $head Section header
  7084. * @param string $short_string A short description
  7085. * @param string $long_string A long (more detailed) description
  7086. * @param integer $type -1=OK sign, 0=message, 1=notification, 2=warning , 3=error
  7087. * @return void
  7088. */
  7089. function printSection($head, $short_string, $long_string, $type) {
  7090. // Get the template file
  7091. $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'PrintSection.html');
  7092. // Get the template part from the file
  7093. $template = t3lib_parsehtml::getSubpart($templateFile, '###TEMPLATE###');
  7094. switch($type) {
  7095. case 3:
  7096. $messageType = 'message-error';
  7097. break;
  7098. case 2:
  7099. $messageType = 'message-warning';
  7100. break;
  7101. case 1:
  7102. $messageType = 'message-notice';
  7103. break;
  7104. case 0:
  7105. $messageType = 'message-information';
  7106. break;
  7107. case -1:
  7108. $messageType = 'message-ok';
  7109. break;
  7110. }
  7111. if (!trim($short_string)) {
  7112. $content = '';
  7113. } else {
  7114. if (trim($long_string)) {
  7115. // Get the subpart for the long string
  7116. $longStringSubpart = t3lib_parsehtml::getSubpart($template, '###LONGSTRINGAVAILABLE###');
  7117. }
  7118. // Substitute the subpart for the long string
  7119. $content = t3lib_parsehtml::substituteSubpart(
  7120. $template,
  7121. '###LONGSTRINGAVAILABLE###',
  7122. $longStringSubpart
  7123. );
  7124. // Define the markers content
  7125. $markers = array(
  7126. 'messageType' => $messageType,
  7127. 'shortString' => $short_string,
  7128. 'longString' => $long_string
  7129. );
  7130. // Fill the markers
  7131. $content = t3lib_parsehtml::substituteMarkerArray(
  7132. $content,
  7133. $markers,
  7134. '###|###',
  7135. TRUE,
  7136. FALSE
  7137. );
  7138. }
  7139. $this->sections[$head][] = $content;
  7140. }
  7141. /**
  7142. * This prints all the messages in the ->section array
  7143. *
  7144. * @return string HTML of all the messages
  7145. */
  7146. function printAll() {
  7147. // Get the template file
  7148. $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'PrintAll.html');
  7149. // Get the template part from the file
  7150. $template = t3lib_parsehtml::getSubpart($templateFile, '###TEMPLATE###');
  7151. $sections = array();
  7152. foreach ($this->sections as $header => $valArray) {
  7153. // Get the subpart for sections
  7154. $sectionSubpart = t3lib_parsehtml::getSubpart($template, '###SECTIONS###');
  7155. // Define the markers content
  7156. $sectionMarkers = array(
  7157. 'header' => $header . ':',
  7158. 'sectionContent' => implode(LF, $valArray)
  7159. );
  7160. // Fill the markers in the subpart
  7161. $sections[] = t3lib_parsehtml::substituteMarkerArray(
  7162. $sectionSubpart,
  7163. $sectionMarkers,
  7164. '###|###',
  7165. TRUE,
  7166. FALSE
  7167. );
  7168. }
  7169. // Substitute the subpart for the sections
  7170. $content = t3lib_parsehtml::substituteSubpart(
  7171. $template,
  7172. '###SECTIONS###',
  7173. implode(LF, $sections)
  7174. );
  7175. return $content;
  7176. }
  7177. /**
  7178. * This wraps and returns the main content of the page into proper html-code.
  7179. *
  7180. * @param string $content The page content
  7181. * @return string The full HTML page
  7182. */
  7183. function outputWrapper($content) {
  7184. // Get the template file
  7185. if (!$this->passwordOK) {
  7186. $this->template = @file_get_contents(PATH_site . $this->templateFilePath . 'Install_login.html');
  7187. } elseif ($this->mode == '123') {
  7188. $this->template = @file_get_contents(PATH_site . $this->templateFilePath . 'Install_123.html');
  7189. } else {
  7190. $this->template = @file_get_contents(PATH_site . $this->templateFilePath . 'Install.html');
  7191. }
  7192. // Add prototype to javascript array for output
  7193. $this->javascript[] = '<script type="text/javascript" src="' .
  7194. t3lib_div::createVersionNumberedFilename(
  7195. '../contrib/prototype/prototype.js'
  7196. ) . '"></script>';
  7197. // Add JS functions for output
  7198. $this->javascript[] = '<script type="text/javascript" src="' .
  7199. t3lib_div::createVersionNumberedFilename(
  7200. '../sysext/install/Resources/Public/Javascript/install.js'
  7201. ) . '"></script>';
  7202. // Include the default stylesheets
  7203. $this->stylesheets[] = '<link rel="stylesheet" type="text/css" href="' .
  7204. t3lib_div::createVersionNumberedFilename($this->backPath .
  7205. 'sysext/install/Resources/Public/Stylesheets/reset.css'
  7206. ) . '" />';
  7207. $this->stylesheets[] = '<link rel="stylesheet" type="text/css" href="' .
  7208. t3lib_div::createVersionNumberedFilename($this->backPath .
  7209. 'sysext/install/Resources/Public/Stylesheets/general.css'
  7210. ) . '" />';
  7211. // Get the browser info
  7212. $browserInfo = t3lib_utility_Client::getBrowserInfo(t3lib_div::getIndpEnv('HTTP_USER_AGENT'));
  7213. // Add the stylesheet for Internet Explorer
  7214. if ($browserInfo['browser'] === 'msie') {
  7215. // IE7
  7216. if (intval($browserInfo['version']) === 7) {
  7217. $this->stylesheets[] = '<link rel="stylesheet" type="text/css" href="' .
  7218. t3lib_div::createVersionNumberedFilename($this->backPath .
  7219. 'sysext/install/Resources/Public/Stylesheets/ie7.css'
  7220. ) . '" />';
  7221. // IE6
  7222. } elseif (intval($browserInfo['version']) < 7) {
  7223. $this->stylesheets[] = '<link rel="stylesheet" type="text/css" href="' .
  7224. t3lib_div::createVersionNumberedFilename($this->backPath .
  7225. 'sysext/install/Resources/Public/Stylesheets/ie6.css'
  7226. ) . '" />';
  7227. }
  7228. }
  7229. // Include the stylesheets based on screen
  7230. if ($this->mode == '123') {
  7231. $this->stylesheets[] = '<link rel="stylesheet" type="text/css" href="' .
  7232. t3lib_div::createVersionNumberedFilename($this->backPath .
  7233. 'sysext/install/Resources/Public/Stylesheets/install_123.css'
  7234. ) . '" />';
  7235. } elseif ($this->passwordOK) {
  7236. $this->stylesheets[] = '<link rel="stylesheet" type="text/css" href="' .
  7237. t3lib_div::createVersionNumberedFilename($this->backPath .
  7238. 'sysext/install/Resources/Public/Stylesheets/install.css'
  7239. ) . '" />';
  7240. } else {
  7241. $this->stylesheets[] = '<link rel="stylesheet" type="text/css" href="' .
  7242. t3lib_div::createVersionNumberedFilename($this->backPath .
  7243. 'sysext/install/Resources/Public/Stylesheets/install.css'
  7244. ) . '" />';
  7245. $this->stylesheets[] = '<link rel="stylesheet" type="text/css" href="' .
  7246. t3lib_div::createVersionNumberedFilename($this->backPath .
  7247. 'sysext/install/Resources/Public/Stylesheets/install_login.css'
  7248. ) . '" />';
  7249. }
  7250. // Define the markers content
  7251. if ($this->mode == '123') {
  7252. $this->markers['headTitle'] = 'Installing TYPO3 ' . TYPO3_branch;
  7253. } else {
  7254. $this->markers['headTitle'] = '
  7255. TYPO3 ' . TYPO3_version . '
  7256. Install Tool on site: ' . htmlspecialchars($GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename']) . '
  7257. ';
  7258. }
  7259. $this->markers['title'] = 'TYPO3 ' . TYPO3_version;
  7260. $this->markers['javascript'] = implode(LF, $this->javascript);
  7261. $this->markers['stylesheets'] = implode(LF, $this->stylesheets);
  7262. $this->markers['llErrors'] = 'The following errors occured';
  7263. $this->markers['copyright'] = $this->copyright();
  7264. $this->markers['charset'] = $GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset'] ? $GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset'] : 'iso-8859-1';
  7265. $this->markers['backendUrl'] = '../index.php';
  7266. $this->markers['backend'] = 'Backend admin';
  7267. $this->markers['frontendUrl'] = '../../index.php';
  7268. $this->markers['frontend'] = 'Frontend website';
  7269. $this->markers['metaCharset'] = 'Content-Type" content="text/html; charset=';
  7270. if (!empty($GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset'])) {
  7271. $this->markers['metaCharset'] .= $GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset'];
  7272. } else {
  7273. $this->markers['metaCharset'] .= 'iso-8859-1';
  7274. }
  7275. // Add the error messages
  7276. if (!empty($this->errorMessages)) {
  7277. // Get the subpart for all error messages
  7278. $errorMessagesSubPart = t3lib_parsehtml::getSubpart($this->template, '###ERRORMESSAGES###');
  7279. // Get the subpart for a single error message
  7280. $errorMessageSubPart = t3lib_parsehtml::getSubpart($errorMessagesSubPart, '###MESSAGES###');
  7281. $errors = array();
  7282. foreach ($this->errorMessages as $errorMessage) {
  7283. // Define the markers content
  7284. $errorMessageMarkers = array(
  7285. 'message' => $errorMessage
  7286. );
  7287. // Fill the markers in the subpart
  7288. $errors[] = t3lib_parsehtml::substituteMarkerArray(
  7289. $errorMessageSubPart,
  7290. $errorMessageMarkers,
  7291. '###|###',
  7292. TRUE,
  7293. FALSE
  7294. );
  7295. }
  7296. // Substitute the subpart for a single message
  7297. $errorMessagesSubPart = t3lib_parsehtml::substituteSubpart(
  7298. $errorMessagesSubPart,
  7299. '###MESSAGES###',
  7300. implode(LF, $errors)
  7301. );
  7302. }
  7303. // Version subpart is only allowed when password is ok
  7304. if ($this->passwordOK) {
  7305. // Get the subpart for the version
  7306. $versionSubPart = t3lib_parsehtml::getSubpart($this->template, '###VERSIONSUBPART###');
  7307. // Define the markers content
  7308. $versionSubPartMarkers['version'] = 'Version: ' . TYPO3_version;
  7309. // Fill the markers in the subpart
  7310. $versionSubPart = t3lib_parsehtml::substituteMarkerArray(
  7311. $versionSubPart,
  7312. $versionSubPartMarkers,
  7313. '###|###',
  7314. TRUE,
  7315. FALSE
  7316. );
  7317. }
  7318. // Substitute the version subpart
  7319. $this->template = t3lib_parsehtml::substituteSubpart(
  7320. $this->template,
  7321. '###VERSIONSUBPART###',
  7322. $versionSubPart
  7323. );
  7324. // Substitute the menu subpart
  7325. $this->template = t3lib_parsehtml::substituteSubpart(
  7326. $this->template,
  7327. '###MENU###',
  7328. $this->menu()
  7329. );
  7330. // Substitute the error messages subpart
  7331. $this->template = t3lib_parsehtml::substituteSubpart(
  7332. $this->template,
  7333. '###ERRORMESSAGES###',
  7334. $errorMessagesSubPart
  7335. );
  7336. // Substitute the content subpart
  7337. $this->template = t3lib_parsehtml::substituteSubpart(
  7338. $this->template,
  7339. '###CONTENT###',
  7340. $content
  7341. );
  7342. // Fill the markers
  7343. $this->template = t3lib_parsehtml::substituteMarkerArray(
  7344. $this->template,
  7345. $this->markers,
  7346. '###|###',
  7347. TRUE,
  7348. FALSE
  7349. );
  7350. return $this->template;
  7351. }
  7352. /**
  7353. * Outputs an error and dies.
  7354. * Should be used by all errors that occur before even starting the install tool process.
  7355. *
  7356. * @param string The content of the error
  7357. * @return void
  7358. */
  7359. protected function outputErrorAndExit($content, $title = 'Install Tool error') {
  7360. // Define the stylesheet
  7361. $stylesheet = '<link rel="stylesheet" type="text/css" href="' .
  7362. '../stylesheets/install/install.css" />';
  7363. $javascript = '<script type="text/javascript" src="' .
  7364. '../contrib/prototype/prototype.js"></script>' . LF;
  7365. $javascript .= '<script type="text/javascript" src="' .
  7366. '../sysext/install/Resources/Public/Javascript/install.js"></script>';
  7367. // Get the template file
  7368. $template = @file_get_contents(PATH_site . '/typo3/templates/install.html');
  7369. // Define the markers content
  7370. $markers = array(
  7371. 'styleSheet' => $stylesheet,
  7372. 'javascript' => $javascript,
  7373. 'title' => $title,
  7374. 'content' => $content,
  7375. );
  7376. // Fill the markers
  7377. $content = t3lib_parsehtml::substituteMarkerArray(
  7378. $template,
  7379. $markers,
  7380. '###|###',
  7381. 1,
  7382. 1
  7383. );
  7384. // Output the warning message and exit
  7385. header('Content-Type: text/html; charset=utf-8');
  7386. header('Cache-Control: no-cache, must-revalidate');
  7387. header('Pragma: no-cache');
  7388. echo $content;
  7389. exit();
  7390. }
  7391. /**
  7392. * Sends the page to the client.
  7393. *
  7394. * @param string $content The HTML page
  7395. * @return void
  7396. */
  7397. function output($content) {
  7398. header ('Content-Type: text/html; charset=' .
  7399. ($GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset']?$GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset']:'iso-8859-1'));
  7400. echo $content;
  7401. }
  7402. /**
  7403. * Generates the main menu
  7404. *
  7405. * @return string HTML of the main menu
  7406. */
  7407. function menu() {
  7408. if ($this->mode !='123') {
  7409. if (!$this->passwordOK) return;
  7410. $c = 0;
  7411. $items = array();
  7412. // Get the subpart for the main menu
  7413. $menuSubPart = t3lib_parsehtml::getSubpart($this->template, '###MENU###');
  7414. // Get the subpart for each single menu item
  7415. $menuItemSubPart = t3lib_parsehtml::getSubpart($this->template, '###MENUITEM###');
  7416. foreach ($this->menuitems as $k => $v) {
  7417. // Define the markers content
  7418. $markers = array(
  7419. 'class' => ($this->INSTALL['type']==$k ? 'class="act"' : ''),
  7420. 'id' => 't3-install-menu-' . $k,
  7421. 'url' => htmlspecialchars(
  7422. $this->scriptSelf .
  7423. '?TYPO3_INSTALL[type]=' .
  7424. $k .
  7425. ($this->mode ? '&mode=' . rawurlencode($this->mode) : '')
  7426. ),
  7427. 'item' => $v
  7428. );
  7429. // Fill the markers in the subpart
  7430. $items[] = t3lib_parsehtml::substituteMarkerArray(
  7431. $menuItemSubPart,
  7432. $markers,
  7433. '###|###',
  7434. TRUE,
  7435. FALSE
  7436. );
  7437. }
  7438. // Substitute the subpart for the single menu items
  7439. $menuSubPart = t3lib_parsehtml::substituteSubpart(
  7440. $menuSubPart,
  7441. '###MENUITEM###',
  7442. implode(LF, $items)
  7443. );
  7444. return $menuSubPart;
  7445. }
  7446. }
  7447. /**
  7448. * Generates the step header for 1-2-3 mode, the numbers at the top
  7449. *
  7450. * @return string HTML for the step header
  7451. */
  7452. function stepHeader() {
  7453. // Get the template file
  7454. $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'StepHeader.html');
  7455. // Get the template part from the file
  7456. $template = t3lib_parsehtml::getSubpart($templateFile, '###TEMPLATE###');
  7457. // Get the subpart for each item
  7458. $stepItemSubPart = t3lib_parsehtml::getSubpart($template, '###STEPITEM###');
  7459. $steps = array();
  7460. for ($counter = 2; $counter <= $this->totalSteps; $counter++) {
  7461. $state = '';
  7462. if ($this->step === $counter) {
  7463. $state = 'act';
  7464. } elseif ($this->step === 'go' || $counter < $this->step) {
  7465. $state = 'done';
  7466. }
  7467. // Define the markers content
  7468. $stepItemMarkers = array(
  7469. 'class' => 'class="step' . ($counter - 1) . ($state ? ' ' . $state : '') . '"',
  7470. 'url' => $this->scriptSelf . '?mode=' . $this->mode . '&amp;step=' . $counter,
  7471. 'step' => $counter
  7472. );
  7473. // Fill the markers in the subpart
  7474. $steps[] = t3lib_parsehtml::substituteMarkerArray(
  7475. $stepItemSubPart,
  7476. $stepItemMarkers,
  7477. '###|###',
  7478. TRUE,
  7479. FALSE
  7480. );
  7481. }
  7482. // Substitute the subpart for the items
  7483. $content = t3lib_parsehtml::substituteSubpart(
  7484. $template,
  7485. '###STEPITEM###',
  7486. implode(LF, $steps)
  7487. );
  7488. return $content;
  7489. }
  7490. /**
  7491. * Generate HTML for the security risk message
  7492. *
  7493. * @return string HTML for the security risk message
  7494. */
  7495. function securityRisk() {
  7496. return '
  7497. <p>
  7498. <strong>An unsecured Install Tool presents a security risk.</strong>
  7499. Minimize the risk with the following actions:
  7500. </p>
  7501. <ul>
  7502. <li>
  7503. Change the Install Tool password.
  7504. </li>
  7505. <li>
  7506. Delete the ENABLE_INSTALL_TOOL file in the /typo3conf folder. This can be done
  7507. manually or through User tools &gt; User settings in the backend.
  7508. </li>
  7509. <li>
  7510. For additional security, the /typo3/install/ folder can be
  7511. renamed, deleted, or password protected with a .htaccess file.
  7512. </li>
  7513. </ul>
  7514. ';
  7515. }
  7516. /**
  7517. * Generates the form to alter the password of the Install Tool
  7518. *
  7519. * @return string HTML of the form
  7520. */
  7521. function alterPasswordForm() {
  7522. // Get the template file
  7523. $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'AlterPasswordForm.html');
  7524. // Get the template part from the file
  7525. $template = t3lib_parsehtml::getSubpart($templateFile, '###TEMPLATE###');
  7526. // Define the markers content
  7527. $markers = array(
  7528. 'action' => $this->scriptSelf.'?TYPO3_INSTALL[type]=extConfig',
  7529. 'enterPassword' => 'Enter new password:',
  7530. 'enterAgain' => 'Enter again:',
  7531. 'submit' => 'Set new password',
  7532. 'formToken' => $this->formProtection->generateToken(
  7533. 'installToolPassword', 'change'
  7534. ),
  7535. );
  7536. // Fill the markers
  7537. $content = t3lib_parsehtml::substituteMarkerArray(
  7538. $template,
  7539. $markers,
  7540. '###|###',
  7541. TRUE,
  7542. FALSE
  7543. );
  7544. return $content;
  7545. }
  7546. /**
  7547. * Generate HTML for the copyright
  7548. *
  7549. * @return string HTML of the copyright
  7550. */
  7551. function copyright() {
  7552. $content = '
  7553. <p>
  7554. <strong>TYPO3 CMS.</strong> Copyright &copy; 1998-' . date('Y') . '
  7555. Kasper Sk&#229;rh&#248;j. Extensions are copyright of their respective
  7556. owners. Go to <a href="' . TYPO3_URL_GENERAL . '">' . TYPO3_URL_GENERAL . '</a>
  7557. for details. TYPO3 comes with ABSOLUTELY NO WARRANTY;
  7558. <a href="' . TYPO3_URL_LICENSE . '">click</a> for details.
  7559. This is free software, and you are welcome to redistribute it
  7560. under certain conditions; <a href="' . TYPO3_URL_LICENSE . '">click</a>
  7561. for details. Obstructing the appearance of this notice is prohibited by law.
  7562. </p>
  7563. <p>
  7564. <a href="' . TYPO3_URL_DONATE . '"><strong>Donate</strong></a> |
  7565. <a href="' . TYPO3_URL_ORG . '">TYPO3.org</a>
  7566. </p>
  7567. ';
  7568. return $content;
  7569. }
  7570. /**
  7571. * Generate HTML for the message that the basic setup has been finished
  7572. *
  7573. * @return string HTML of the message
  7574. */
  7575. function messageBasicFinished() {
  7576. return '
  7577. <p>
  7578. You have completed the basic setup of the TYPO3 Content Management System.
  7579. Choose between these options to continue:
  7580. </p>
  7581. <ul>
  7582. <li>
  7583. <a href="' . $this->scriptSelf . '">Configure TYPO3</a> (Recommended)
  7584. <br />
  7585. This will let you analyze and verify that everything in your
  7586. installation is in order. In addition, you can configure advanced
  7587. TYPO3 options in this step.
  7588. </li>
  7589. <li>
  7590. <a href="../../index.php">
  7591. Visit the frontend
  7592. </a>
  7593. </li>
  7594. <li>
  7595. <a href="../index.php">
  7596. Login to the backend
  7597. </a>
  7598. <br />
  7599. (Default username: <em>admin</em>, default password: <em>password</em>.)
  7600. </li>
  7601. </ul>
  7602. ';
  7603. }
  7604. /**
  7605. * Make the url of the script according to type, mode and step
  7606. *
  7607. * @param string $type The type
  7608. * @return string The url
  7609. */
  7610. function setScriptName($type) {
  7611. $value = $this->scriptSelf.'?TYPO3_INSTALL[type]='.$type.($this->mode?'&mode='.rawurlencode($this->mode):'').($this->step?'&step='.rawurlencode($this->step):'');
  7612. return $value;
  7613. }
  7614. /**
  7615. * Return the filename that will be used for the backup.
  7616. * It is important that backups of PHP files still stay as a PHP file, otherwise they could be viewed un-parsed in clear-text.
  7617. *
  7618. * @param string $filename Full path to a file
  7619. * @return string The name of the backup file (again, including the full path)
  7620. */
  7621. function getBackupFilename($filename) {
  7622. if (preg_match('/\.php$/', $filename)) {
  7623. $backupFile = str_replace('.php', '_bak.php', $filename);
  7624. } else {
  7625. $backupFile = $filename.'~';
  7626. }
  7627. return $backupFile;
  7628. }
  7629. /**
  7630. * Creates a table which checkboxes for updating database.
  7631. *
  7632. * @param array $arr Array of statements (key / value pairs where key is used for the checkboxes)
  7633. * @param string $label Label for the table.
  7634. * @param boolean $checked If set, then checkboxes are set by default.
  7635. * @param boolean $iconDis If set, then icons are shown.
  7636. * @param array $currentValue Array of "current values" for each key/value pair in $arr. Shown if given.
  7637. * @param boolean $cVfullMsg If set, will show the prefix "Current value" if $currentValue is given.
  7638. * @return string HTML table with checkboxes for update. Must be wrapped in a form.
  7639. */
  7640. function generateUpdateDatabaseForm_checkboxes($arr,$label,$checked=1,$iconDis=0,$currentValue=array(),$cVfullMsg=0) {
  7641. $out = array();
  7642. $tableId = uniqid('table');
  7643. $templateMarkers = array();
  7644. if (is_array($arr)) {
  7645. // Get the template file
  7646. $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'GenerateUpdateDatabaseFormCheckboxes.html');
  7647. // Get the template part from the file
  7648. $content = t3lib_parsehtml::getSubpart($templateFile, '###TEMPLATE###');
  7649. // Define the markers content
  7650. $templateMarkers = array(
  7651. 'label' => $label,
  7652. 'tableId' => $tableId
  7653. );
  7654. // Select/Deselect All
  7655. if (count($arr) > 1) {
  7656. // Get the subpart for multiple tables
  7657. $multipleTablesSubpart = t3lib_parsehtml::getSubpart($content, '###MULTIPLETABLES###');
  7658. // Define the markers content
  7659. $multipleTablesMarkers = array(
  7660. 'label' => $label,
  7661. 'tableId' => $tableId,
  7662. 'checked' => ($checked ? ' checked="checked"' : ''),
  7663. 'selectAllId' => 't3-install-' . $tableId . '-checkbox',
  7664. 'selectDeselectAll' => 'select/deselect all'
  7665. );
  7666. // Fill the markers in the subpart
  7667. $multipleTablesSubpart = t3lib_parsehtml::substituteMarkerArray(
  7668. $multipleTablesSubpart,
  7669. $multipleTablesMarkers,
  7670. '###|###',
  7671. TRUE,
  7672. FALSE
  7673. );
  7674. }
  7675. // Substitute the subpart for multiple tables
  7676. $content = t3lib_parsehtml::substituteSubpart(
  7677. $content,
  7678. '###MULTIPLETABLES###',
  7679. $multipleTablesSubpart
  7680. );
  7681. // Rows
  7682. foreach ($arr as $key => $string) {
  7683. // Get the subpart for rows
  7684. $rowsSubpart = t3lib_parsehtml::getSubpart($content, '###ROWS###');
  7685. $currentSubpart = '';
  7686. $ico = '';
  7687. $warnings = array();
  7688. // Define the markers content
  7689. $rowsMarkers = array(
  7690. 'checkboxId' => 't3-install-db-' . $key,
  7691. 'name' => $this->dbUpdateCheckboxPrefix . '[' . $key . ']',
  7692. 'checked' => ($checked ? 'checked="checked"' : ''),
  7693. 'string' => htmlspecialchars($string)
  7694. );
  7695. if ($iconDis) {
  7696. $iconMarkers['backPath'] = $this->backPath;
  7697. if (preg_match('/^TRUNCATE/i', $string)) {
  7698. $iconMarkers['iconText'] = '';
  7699. $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.';
  7700. } elseif (stristr($string,' user_')) {
  7701. $iconMarkers['iconText'] = '(USER)';
  7702. } elseif (stristr($string,' app_')) {
  7703. $iconMarkers['iconText'] = '(APP)';
  7704. } elseif (stristr($string,' ttx_') || stristr($string,' tx_')) {
  7705. $iconMarkers['iconText'] = '(EXT)';
  7706. }
  7707. if (!empty($iconMarkers)) {
  7708. // Get the subpart for icons
  7709. $iconSubpart = t3lib_parsehtml::getSubpart($content, '###ICONAVAILABLE###');
  7710. // Fill the markers in the subpart
  7711. $iconSubpart = t3lib_parsehtml::substituteMarkerArray(
  7712. $iconSubpart,
  7713. $iconMarkers,
  7714. '###|###',
  7715. TRUE,
  7716. TRUE
  7717. );
  7718. }
  7719. }
  7720. // Substitute the subpart for icons
  7721. $rowsSubpart = t3lib_parsehtml::substituteSubpart(
  7722. $rowsSubpart,
  7723. '###ICONAVAILABLE###',
  7724. $iconSubpart
  7725. );
  7726. if (isset($currentValue[$key])) {
  7727. // Get the subpart for current
  7728. $currentSubpart = t3lib_parsehtml::getSubpart($rowsSubpart, '###CURRENT###');
  7729. // Define the markers content
  7730. $currentMarkers = array (
  7731. 'message' => (!$cVfullMsg ? 'Current value:': ''),
  7732. 'value' => $currentValue[$key]
  7733. );
  7734. // Fill the markers in the subpart
  7735. $currentSubpart = t3lib_parsehtml::substituteMarkerArray(
  7736. $currentSubpart,
  7737. $currentMarkers,
  7738. '###|###',
  7739. TRUE,
  7740. FALSE
  7741. );
  7742. }
  7743. // Substitute the subpart for current
  7744. $rowsSubpart = t3lib_parsehtml::substituteSubpart(
  7745. $rowsSubpart,
  7746. '###CURRENT###',
  7747. $currentSubpart
  7748. );
  7749. $errorSubpart = '';
  7750. if (isset($this->databaseUpdateErrorMessages[$key])) {
  7751. // Get the subpart for current
  7752. $errorSubpart = t3lib_parsehtml::getSubpart($rowsSubpart, '###ERROR###');
  7753. // Define the markers content
  7754. $currentMarkers = array (
  7755. 'errorMessage' => $this->databaseUpdateErrorMessages[$key],
  7756. );
  7757. // Fill the markers in the subpart
  7758. $errorSubpart = t3lib_parsehtml::substituteMarkerArray(
  7759. $errorSubpart,
  7760. $currentMarkers,
  7761. '###|###',
  7762. TRUE,
  7763. FALSE
  7764. );
  7765. }
  7766. // Substitute the subpart for error messages
  7767. $rowsSubpart = t3lib_parsehtml::substituteSubpart(
  7768. $rowsSubpart,
  7769. '###ERROR###',
  7770. $errorSubpart
  7771. );
  7772. // Fill the markers in the subpart
  7773. $rowsSubpart = t3lib_parsehtml::substituteMarkerArray(
  7774. $rowsSubpart,
  7775. $rowsMarkers,
  7776. '###|###',
  7777. TRUE,
  7778. FALSE
  7779. );
  7780. $rows[] = $rowsSubpart;
  7781. }
  7782. // Substitute the subpart for rows
  7783. $content = t3lib_parsehtml::substituteSubpart(
  7784. $content,
  7785. '###ROWS###',
  7786. implode(LF, $rows)
  7787. );
  7788. if (count($warnings)) {
  7789. // Get the subpart for warnings
  7790. $warningsSubpart = t3lib_parsehtml::getSubpart($content, '###WARNINGS###');
  7791. $warningItems = array();
  7792. foreach ($warnings as $warning) {
  7793. // Get the subpart for single warning items
  7794. $warningItemSubpart = t3lib_parsehtml::getSubpart($warningsSubpart, '###WARNINGITEM###');
  7795. // Define the markers content
  7796. $warningItemMarker['warning'] = $warning;
  7797. // Fill the markers in the subpart
  7798. $warningItems[] = t3lib_parsehtml::substituteMarkerArray(
  7799. $warningItemSubpart,
  7800. $warningItemMarker,
  7801. '###|###',
  7802. TRUE,
  7803. FALSE
  7804. );
  7805. }
  7806. // Substitute the subpart for single warning items
  7807. $warningsSubpart = t3lib_parsehtml::substituteSubpart(
  7808. $warningsSubpart,
  7809. '###WARNINGITEM###',
  7810. implode(LF, $warningItems)
  7811. );
  7812. }
  7813. // Substitute the subpart for warnings
  7814. $content = t3lib_parsehtml::substituteSubpart(
  7815. $content,
  7816. '###WARNINGS###',
  7817. $warningsSubpart
  7818. );
  7819. }
  7820. // Fill the markers
  7821. $content = t3lib_parsehtml::substituteMarkerArray(
  7822. $content,
  7823. $templateMarkers,
  7824. '###|###',
  7825. TRUE,
  7826. FALSE
  7827. );
  7828. return $content;
  7829. }
  7830. /**
  7831. * Returns HTML-code, which is a visual representation of a multidimensional array
  7832. * Returns false if $array_in is not an array
  7833. *
  7834. * @param mixed $incomingValue Array to view
  7835. * @return string HTML output
  7836. */
  7837. function viewArray($incomingValue) {
  7838. // Get the template file
  7839. $templateFile = @file_get_contents(PATH_site . $this->templateFilePath . 'ViewArray.html');
  7840. if (is_array($incomingValue) && !empty($incomingValue)) {
  7841. // Get the template part from the file
  7842. $content = t3lib_parsehtml::getSubpart($templateFile, '###TEMPLATE###');
  7843. // Get the subpart for a single item
  7844. $itemSubpart = t3lib_parsehtml::getSubpart($content, '###ITEM###');
  7845. foreach ($incomingValue as $key => $value) {
  7846. if (is_array($value)) {
  7847. $description = $this->viewArray($value);
  7848. } elseif (is_object($value)) {
  7849. $description = get_class($value);
  7850. if (method_exists($value, '__toString')) {
  7851. $description .= ': ' . (string)$value;
  7852. }
  7853. } else {
  7854. if (gettype($value) == 'object') {
  7855. $description = 'Unknown object';
  7856. } else {
  7857. $description = htmlspecialchars((string) $value);
  7858. }
  7859. }
  7860. // Define the markers content
  7861. $itemMarkers = array(
  7862. 'key' => htmlspecialchars((string) $key),
  7863. 'description' => !empty($description) ? $description : '&nbsp;'
  7864. );
  7865. // Fill the markers in the subpart
  7866. $items[] = t3lib_parsehtml::substituteMarkerArray(
  7867. $itemSubpart,
  7868. $itemMarkers,
  7869. '###|###',
  7870. TRUE,
  7871. FALSE
  7872. );
  7873. }
  7874. // Substitute the subpart for single item
  7875. $content = t3lib_parsehtml::substituteSubpart(
  7876. $content,
  7877. '###ITEM###',
  7878. implode(LF, $items)
  7879. );
  7880. }
  7881. return $content;
  7882. }
  7883. /**
  7884. * Returns a newly created TYPO3 encryption key with a given length.
  7885. *
  7886. * @param integer $keyLength Desired key length
  7887. * @return string The encryption key
  7888. */
  7889. public function createEncryptionKey($keyLength = 96) {
  7890. $bytes = t3lib_div::generateRandomBytes($keyLength);
  7891. return substr(bin2hex($bytes), -96);
  7892. }
  7893. /**
  7894. * Adds an error message that should be displayed.
  7895. *
  7896. * @param string $messageText
  7897. * the text of the message to display, must not be empty
  7898. */
  7899. public function addErrorMessage($messageText) {
  7900. if ($messageText == '') {
  7901. throw new InvalidArgumentException('$messageText must not be empty.', 1294587483);
  7902. }
  7903. $this->errorMessages[] = $messageText;
  7904. }
  7905. }
  7906. if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['ext/install/mod/class.tx_install.php'])) {
  7907. include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['ext/install/mod/class.tx_install.php']);
  7908. }
  7909. ?>