|
TYPO3 API
SVNRelease
|
00001 <?php 00002 /*************************************************************** 00003 * Copyright notice 00004 * 00005 * (c) 2010 Xavier Perseguers <typo3@perseguers.ch> 00006 * All rights reserved 00007 * 00008 * This script is part of the TYPO3 project. The TYPO3 project is 00009 * free software; you can redistribute it and/or modify 00010 * it under the terms of the GNU General Public License as published by 00011 * the Free Software Foundation; either version 2 of the License, or 00012 * (at your option) any later version. 00013 * 00014 * The GNU General Public License can be found at 00015 * http://www.gnu.org/copyleft/gpl.html. 00016 * A copy is found in the textfile GPL.txt and important notices to the license 00017 * from the author is found in LICENSE.txt distributed with these scripts. 00018 * 00019 * 00020 * This script is distributed in the hope that it will be useful, 00021 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00022 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00023 * GNU General Public License for more details. 00024 * 00025 * This copyright notice MUST APPEAR in all copies of the script! 00026 ***************************************************************/ 00027 00028 /** 00029 * Hooks for TYPO3 Install Tool. 00030 * 00031 * $Id$ 00032 * 00033 * @author Xavier Perseguers <typo3@perseguers.ch> 00034 * 00035 * @package TYPO3 00036 * @subpackage dbal 00037 */ 00038 class tx_dbal_installtool { 00039 00040 /** 00041 * @var string 00042 */ 00043 protected $templateFilePath = 'res/Templates/'; 00044 00045 /** 00046 * @var array 00047 */ 00048 protected $supportedDrivers; 00049 00050 /** 00051 * @var array 00052 */ 00053 protected $availableDrivers; 00054 00055 /** 00056 * @var string 00057 */ 00058 protected $driver; 00059 00060 /** 00061 * Default constructor. 00062 */ 00063 public function __construct() { 00064 $this->supportedDrivers = $this->getSupportedDrivers(); 00065 $this->availableDrivers = $this->getAvailableDrivers(); 00066 00067 $configDriver =& $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['dbal']['handlerCfg']['_DEFAULT']['config']['driver']; 00068 $this->driver = t3lib_div::_GET('driver'); 00069 if (!$this->driver && $configDriver) { 00070 $this->driver = $configDriver; 00071 } 00072 } 00073 00074 /** 00075 * Hooks into Installer to set required PHP modules. 00076 * 00077 * @param array $modules 00078 * @param tx_install $instObj 00079 * @return array modules 00080 */ 00081 public function setRequiredPhpModules(array &$modules, tx_install $instObj) { 00082 foreach ($modules as $key => $module) { 00083 if ($module === 'mysql') { 00084 $dbModules = array(); 00085 foreach ($this->supportedDrivers as $abstractionLayer => $drivers) { 00086 $dbModules = array_merge($dbModules, array_keys($drivers)); 00087 } 00088 $module = $dbModules; 00089 } 00090 $modifiedModules[] = $module; 00091 } 00092 return $modifiedModules; 00093 } 00094 00095 /** 00096 * Hooks into Installer to let a non-MySQL database to be configured. 00097 * 00098 * @param array $markers 00099 * @param integer $step 00100 * @param tx_install $instObj 00101 * @return void 00102 */ 00103 public function executeStepOutput(array &$markers, $step, tx_install $instObj) { 00104 switch ($step) { 00105 case 2: 00106 $this->createConnectionForm($markers, $instObj); 00107 break; 00108 case 3: 00109 $this->createDatabaseForm($markers, $instObj); 00110 break; 00111 } 00112 } 00113 00114 /** 00115 * Hooks into Installer to modify lines to be written to localconf.php. 00116 * 00117 * @param array $lines 00118 * @param integer $step 00119 * @param tx_install $instObj 00120 * @return void 00121 */ 00122 public function executeWriteLocalconf(array &$lines, $step, tx_install $instObj) { 00123 switch ($step) { 00124 case 3: 00125 case 4: 00126 $driver = $instObj->INSTALL['localconf.php']['typo_db_driver']; 00127 if (!$driver && $this->driver) { 00128 // Driver was already configured 00129 break; 00130 } 00131 $driverConfig = ''; 00132 switch ($driver) { 00133 case 'oci8': 00134 $driverConfig = '\'driverOptions\' => array(' . 00135 '\'connectSID\' => ' . ($instObj->INSTALL['localconf.php']['typo_db_type'] === 'sid' ? 'TRUE' : 'FALSE') . 00136 ')'; 00137 break; 00138 case 'mssql': 00139 case 'odbc_mssql': 00140 $driverConfig = '\'useNameQuote\' => TRUE'; 00141 break; 00142 case 'mysql': 00143 return; 00144 } 00145 $config = 'array(' . 00146 '\'_DEFAULT\' => array(' . 00147 '\'type\' => \'adodb\',' . 00148 '\'config\' => array(' . 00149 '\'driver\' => \'' . $driver . '\',' . 00150 $driverConfig . 00151 ')' . 00152 ')' . 00153 ');'; 00154 $instObj->setValueInLocalconfFile($lines, '$TYPO3_CONF_VARS[\'EXTCONF\'][\'dbal\'][\'handlerCfg\']', $config, FALSE); 00155 break; 00156 } 00157 } 00158 00159 /** 00160 * Creates a specialized form to configure the DBMS connection. 00161 * 00162 * @param array $markers 00163 * @param tx_install $instObj 00164 * @return void 00165 */ 00166 protected function createConnectionForm(array &$markers, tx_install $instObj) { 00167 // Normalize current driver 00168 if (!$this->driver) { 00169 $this->driver = $this->getDefaultDriver(); 00170 } 00171 00172 // Get the template file 00173 $templateFile = @file_get_contents( 00174 t3lib_extMgm::extPath('dbal') . $this->templateFilePath . 'install.html' 00175 ); 00176 // Get the template part from the file 00177 $template = t3lib_parsehtml::getSubpart( 00178 $templateFile, '###TEMPLATE###' 00179 ); 00180 00181 // Get the subpart for the connection form 00182 $formSubPart = t3lib_parsehtml::getSubpart( 00183 $template, '###CONNECTION_FORM###' 00184 ); 00185 if ($this->getNumberOfAvailableDrivers() == 1 && $this->getDefaultDriver() === 'mysql') { 00186 // Only MySQL is actually available (PDO support may be compiled in 00187 // PHP itself and as such DBAL was activated, behaves as if DBAL were 00188 // not activated 00189 $driverSubPart = '<input type="hidden" name="TYPO3_INSTALL[localconf.php][typo_db_driver]" value="mysql" />'; 00190 } else { 00191 $driverTemplate = t3lib_parsehtml::getSubpart( 00192 $formSubPart, '###DATABASE_DRIVER###' 00193 ); 00194 $driverSubPart = $this->prepareDatabaseDrivers($driverTemplate); 00195 } 00196 $formSubPart = t3lib_parsehtml::substituteSubpart( 00197 $formSubPart, 00198 '###DATABASE_DRIVER###', 00199 $driverSubPart 00200 ); 00201 00202 // Get the subpart related to selected database driver 00203 if ($this->driver === '' || $this->driver === 'mysql') { 00204 $driverOptionsSubPart = t3lib_parsehtml::getSubpart( 00205 $template, '###DRIVER_MYSQL###' 00206 ); 00207 } else { 00208 $driverOptionsSubPart = t3lib_parsehtml::getSubpart( 00209 $template, '###DRIVER_' . t3lib_div::strtoupper($this->driver) . '###' 00210 ); 00211 if ($driverOptionsSubPart === '') { 00212 $driverOptionsSubPart = t3lib_parsehtml::getSubpart( 00213 $template, '###DRIVER_DEFAULT###' 00214 ); 00215 } 00216 } 00217 00218 // Define driver-specific markers 00219 $driverMarkers = array(); 00220 switch ($this->driver) { 00221 case 'mssql': 00222 $driverMarkers = array( 00223 'labelUsername' => 'Username', 00224 'username' => TYPO3_db_username, 00225 'labelPassword' => 'Password', 00226 'password' => TYPO3_db_password, 00227 'labelHost' => 'Host', 00228 'host' => TYPO3_db_host ? TYPO3_db_host : 'windows', 00229 'labelDatabase' => 'Database', 00230 'database' => TYPO3_db, 00231 ); 00232 $nextStep = $instObj->step + 2; 00233 break; 00234 case 'odbc_mssql': 00235 $driverMarkers = array( 00236 'labelUsername' => 'Username', 00237 'username' => TYPO3_db_username, 00238 'labelPassword' => 'Password', 00239 'password' => TYPO3_db_password, 00240 'labelHost' => 'Host', 00241 'host' => TYPO3_db_host ? TYPO3_db_host : 'windows', 00242 'database' => 'dummy_string', 00243 ); 00244 $nextStep = $instObj->step + 2; 00245 break; 00246 case 'oci8': 00247 $driverMarkers = array( 00248 'labelUsername' => 'Username', 00249 'username' => TYPO3_db_username, 00250 'labelPassword' => 'Password', 00251 'password' => TYPO3_db_password, 00252 'labelHost' => 'Host', 00253 'host' => TYPO3_db_host ? TYPO3_db_host : 'localhost', 00254 'labelType' => 'Type', 00255 'labelSID' => 'SID', 00256 'labelServiceName' => 'Service Name', 00257 'labelDatabase' => 'Name', 00258 'database' => TYPO3_db, 00259 ); 00260 $nextStep = $instObj->step + 2; 00261 break; 00262 case 'postgres': 00263 $driverMarkers = array( 00264 'labelUsername' => 'Username', 00265 'username' => TYPO3_db_username, 00266 'labelPassword' => 'Password', 00267 'password' => TYPO3_db_password, 00268 'labelHost' => 'Host', 00269 'host' => TYPO3_db_host ? TYPO3_db_host : 'localhost', 00270 'labelDatabase' => 'Database', 00271 'database' => TYPO3_db, 00272 ); 00273 $nextStep = $instObj->step + 2; 00274 break; 00275 default: 00276 $driverMarkers = array( 00277 'labelUsername' => 'Username', 00278 'username' => TYPO3_db_username, 00279 'labelPassword' => 'Password', 00280 'password' => TYPO3_db_password, 00281 'labelHost' => 'Host', 00282 'host' => TYPO3_db_host ? TYPO3_db_host : 'localhost', 00283 'labelDatabase' => 'Database', 00284 'database' => TYPO3_db, 00285 ); 00286 $nextStep = $instObj->step + 1; 00287 break; 00288 } 00289 00290 // Add header marker for main template 00291 $markers['header'] = 'Connect to your database host'; 00292 // Define the markers content for the subpart 00293 $subPartMarkers = array( 00294 'step' => $nextStep, 00295 'action' => htmlspecialchars($instObj->action), 00296 'encryptionKey' => $instObj->createEncryptionKey(), 00297 'branch' => TYPO3_branch, 00298 'driver_options' => $driverOptionsSubPart, 00299 'continue' => 'Continue', 00300 '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.' 00301 ); 00302 $subPartMarkers = array_merge($subPartMarkers, $driverMarkers); 00303 00304 // Add step marker for main template 00305 $markers['step'] = t3lib_parsehtml::substituteMarkerArray( 00306 $formSubPart, 00307 $subPartMarkers, 00308 '###|###', 00309 1, 00310 1 00311 ); 00312 } 00313 00314 /** 00315 * Prepares the list of database drivers for step 2. 00316 * 00317 * @param string $template 00318 * @return string 00319 */ 00320 protected function prepareDatabaseDrivers($template) { 00321 $subParts = array( 00322 'abstractionLayer' => t3lib_parsehtml::getSubpart($template, '###ABSTRACTION_LAYER###'), 00323 'vendor' => t3lib_parsehtml::getSubpart($template, '###VENDOR###'), 00324 ); 00325 00326 // Create the drop-down list of available drivers 00327 $dropdown = ''; 00328 foreach ($this->availableDrivers as $abstractionLayer => $drivers) { 00329 $options = array(); 00330 foreach ($drivers as $driver => $label) { 00331 $markers = array( 00332 'driver' => $driver, 00333 'labelvendor' => $label, 00334 'onclick' => 'document.location=\'index.php?TYPO3_INSTALL[type]=config&mode=123&step=2&driver=' . $driver . '\';', 00335 'selected' => '', 00336 ); 00337 if ($driver === $this->driver) { 00338 $markers['selected'] .= ' selected="selected"'; 00339 } 00340 $options[] = t3lib_parsehtml::substituteMarkerArray( 00341 $subParts['vendor'], 00342 $markers, 00343 '###|###', 00344 1 00345 ); 00346 } 00347 $subPart = t3lib_parsehtml::substituteSubpart( 00348 $subParts['abstractionLayer'], 00349 '###VENDOR###', 00350 implode("\n", $options) 00351 ); 00352 $dropdown .= t3lib_parsehtml::substituteMarker( 00353 $subPart, 00354 '###LABELABSTRACTIONLAYER###', 00355 $abstractionLayer 00356 ); 00357 } 00358 $form = t3lib_parsehtml::substituteSubpart( 00359 $template, 00360 '###ABSTRACTION_LAYER###', 00361 $dropdown 00362 ); 00363 $form = t3lib_parsehtml::substituteMarker( 00364 $form, 00365 '###LABELDRIVER###', 00366 'Driver' 00367 ); 00368 return $form; 00369 } 00370 00371 /** 00372 * Returns a list of DBAL supported database drivers, with a user-friendly name 00373 * and any PHP module dependency. 00374 * 00375 * @return array 00376 */ 00377 protected function getSupportedDrivers() { 00378 $supportedDrivers = array( 00379 'Native' => array( 00380 'mysql' => array( 00381 'label' => 'MySQL/MySQLi (recommended)', 00382 'combine' => 'OR', 00383 'extensions' => array('mysql', 'mysqli'), 00384 ), 00385 'mssql' => array( 00386 'label' => 'Microsoft SQL Server', 00387 'extensions' => array('mssql'), 00388 ), 00389 'oci8' => array( 00390 'label' => 'Oracle OCI8', 00391 'extensions' => array('oci8'), 00392 ), 00393 'postgres' => array( 00394 'label' => 'PostgreSQL', 00395 'extensions' => array('pgsql'), 00396 ) 00397 ), 00398 'ODBC' => array( 00399 'odbc_mssql' => array( 00400 'label' => 'Microsoft SQL Server', 00401 'extensions' => array('odbc', 'mssql'), 00402 ), 00403 ), 00404 ); 00405 return $supportedDrivers; 00406 } 00407 00408 /** 00409 * Returns a list of database drivers that are available on current server. 00410 * 00411 * @return array 00412 */ 00413 protected function getAvailableDrivers() { 00414 $availableDrivers = array(); 00415 foreach ($this->supportedDrivers as $abstractionLayer => $drivers) { 00416 foreach ($drivers as $driver => $info) { 00417 if (isset($info['combine']) && $info['combine'] === 'OR') { 00418 $isAvailable = FALSE; 00419 } else { 00420 $isAvailable = TRUE; 00421 } 00422 00423 // Loop through each PHP module dependency to ensure it is loaded 00424 foreach ($info['extensions'] as $extension) { 00425 if (isset($info['combine']) && $info['combine'] === 'OR') { 00426 $isAvailable |= extension_loaded($extension); 00427 } else { 00428 $isAvailable &= extension_loaded($extension); 00429 } 00430 } 00431 00432 if ($isAvailable) { 00433 if (!isset($availableDrivers[$abstractionLayer])) { 00434 $availableDrivers[$abstractionLayer] = array(); 00435 } 00436 $availableDrivers[$abstractionLayer][$driver] = $info['label']; 00437 } 00438 } 00439 } 00440 return $availableDrivers; 00441 } 00442 00443 /** 00444 * Returns the number of available drivers. 00445 * 00446 * @return boolean 00447 */ 00448 protected function getNumberOfAvailableDrivers() { 00449 $count = 0; 00450 foreach ($this->availableDrivers as $drivers) { 00451 $count += count($drivers); 00452 } 00453 return $count; 00454 } 00455 00456 /** 00457 * Returns the driver that is selected by default in the 00458 * Install Tool dropdown list. 00459 * 00460 * @return string 00461 */ 00462 protected function getDefaultDriver() { 00463 $defaultDriver = ''; 00464 if (count($this->availableDrivers)) { 00465 $abstractionLayers = array_keys($this->availableDrivers); 00466 $drivers = array_keys($this->availableDrivers[$abstractionLayers[0]]); 00467 $defaultDriver = $drivers[0]; 00468 } 00469 return $defaultDriver; 00470 } 00471 00472 /** 00473 * Creates a specialized form to configure the database. 00474 * 00475 * @param array $markers 00476 * @param tx_install $instObj 00477 */ 00478 protected function createDatabaseForm(array &$markers, tx_install $instObj) { 00479 $error_missingConnect = ' 00480 <p class="typo3-message message-error"> 00481 <strong> 00482 There is no connection to the database! 00483 </strong> 00484 <br /> 00485 (Username: <em>' . TYPO3_db_username . '</em>, 00486 Host: <em>' . TYPO3_db_host . '</em>, 00487 Using Password: YES) 00488 <br /> 00489 Go to Step 1 and enter a valid username and password! 00490 </p> 00491 '; 00492 00493 // Add header marker for main template 00494 $markers['header'] = 'Select database'; 00495 // There should be a database host connection at this point 00496 if ($result = $GLOBALS['TYPO3_DB']->sql_pconnect( 00497 TYPO3_db_host, TYPO3_db_username, TYPO3_db_password 00498 )) { 00499 // Get the template file 00500 $templateFile = @file_get_contents( 00501 t3lib_extMgm::extPath('dbal') . $this->templateFilePath . 'install.html' 00502 ); 00503 // Get the template part from the file 00504 $template = t3lib_parsehtml::getSubpart( 00505 $templateFile, '###TEMPLATE###' 00506 ); 00507 // Get the subpart for the database choice step 00508 $formSubPart = t3lib_parsehtml::getSubpart( 00509 $template, '###DATABASE_FORM###' 00510 ); 00511 // Get the subpart for the database options 00512 $step3DatabaseOptionsSubPart = t3lib_parsehtml::getSubpart( 00513 $formSubPart, '###DATABASEOPTIONS###' 00514 ); 00515 00516 $dbArr = $instObj->getDatabaseList(); 00517 $dbIncluded = FALSE; 00518 foreach ($dbArr as $dbname) { 00519 // Define the markers content for database options 00520 $step3DatabaseOptionMarkers = array( 00521 'databaseValue' => htmlspecialchars($dbname), 00522 'databaseSelected' => ($dbname === TYPO3_db) ? 'selected="selected"' : '', 00523 'databaseName' => htmlspecialchars($dbname) 00524 ); 00525 // Add the option HTML to an array 00526 $step3DatabaseOptions[] = t3lib_parsehtml::substituteMarkerArray( 00527 $step3DatabaseOptionsSubPart, 00528 $step3DatabaseOptionMarkers, 00529 '###|###', 00530 1, 00531 1 00532 ); 00533 if ($dbname === TYPO3_db) { 00534 $dbIncluded = TRUE; 00535 } 00536 } 00537 if (!$dbIncluded && TYPO3_db) { 00538 // // Define the markers content when no access 00539 $step3DatabaseOptionMarkers = array( 00540 'databaseValue' => htmlspecialchars(TYPO3_db), 00541 'databaseSelected' => 'selected="selected"', 00542 'databaseName' => htmlspecialchars(TYPO3_db) . ' (NO ACCESS!)' 00543 ); 00544 // Add the option HTML to an array 00545 $step3DatabaseOptions[] = t3lib_parsehtml::substituteMarkerArray( 00546 $step3DatabaseOptionsSubPart, 00547 $step3DatabaseOptionMarkers, 00548 '###|###', 00549 1, 00550 1 00551 ); 00552 } 00553 // Substitute the subpart for the database options 00554 $content = t3lib_parsehtml::substituteSubpart( 00555 $formSubPart, 00556 '###DATABASEOPTIONS###', 00557 implode(chr(10), $step3DatabaseOptions) 00558 ); 00559 // Define the markers content 00560 $step3SubPartMarkers = array( 00561 'step' => $instObj->step + 1, 00562 'action' => htmlspecialchars($instObj->action), 00563 'llOption2' => 'Select an EMPTY existing database:', 00564 'llRemark2' => 'Any tables used by TYPO3 will be overwritten.', 00565 'continue' => 'Continue' 00566 ); 00567 // Add step marker for main template 00568 $markers['step'] = t3lib_parsehtml::substituteMarkerArray( 00569 $content, 00570 $step3SubPartMarkers, 00571 '###|###', 00572 1, 00573 1 00574 ); 00575 } else { 00576 // Add step marker for main template when no connection 00577 $markers['step'] = $error_missingConnect; 00578 } 00579 } 00580 00581 } 00582 00583 00584 if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['ext/dbal/class.tx_dbal_installtool.php'])) { 00585 include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['ext/dbal/class.tx_dbal_installtool.php']); 00586 } 00587 ?>
1.8.0