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

https://bitbucket.org/linxpinx/mercurial · PHP · 8293 lines · 6508 code · 514 blank · 1271 comment · 691 complexity · 41346c6ea0247517b44398a615973399 MD5 · raw file

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