|
TYPO3 API
SVNRelease
|
00001 <?php 00002 /*************************************************************** 00003 * Copyright notice 00004 * 00005 * (c) 2010 Marcus Krause <marcus#exp2010@t3sec.info> 00006 * (c) 2010 Steffen Kamper <info@sk-typo3.de> 00007 * All rights reserved 00008 * 00009 * This script is part of the TYPO3 project. The TYPO3 project is 00010 * free software; you can redistribute it and/or modify 00011 * it under the terms of the GNU General Public License as published by 00012 * the Free Software Foundation; either version 2 of the License, or 00013 * (at your option) any later version. 00014 * 00015 * The GNU General Public License can be found at 00016 * http://www.gnu.org/copyleft/gpl.html. 00017 * 00018 * This script is distributed in the hope that it will be useful, 00019 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00020 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00021 * GNU General Public License for more details. 00022 * 00023 * This copyright notice MUST APPEAR in all copies of the script! 00024 ***************************************************************/ 00025 /** 00026 * class.tx_em_database.php 00027 * 00028 * Module: Extension manager - DB access 00029 * 00030 * $Id: class.tx_em_database.php 2082 2010-03-21 17:19:42Z steffenk $ 00031 * 00032 * @author Marcus Krause <marcus#exp2010@t3sec.info> 00033 * @author Steffen Kamper <info@sk-typo3.de> 00034 */ 00035 00036 /** 00037 * DB access class for extension manager. 00038 * 00039 * Contains static methods for DB operations. 00040 * 00041 * @author Marcus Krause <marcus#exp2010@t3sec.info> 00042 * @author Steffen Kamper <info@sk-typo3.de> 00043 * 00044 * @since 2010-02-27 00045 * @package TYPO3 00046 * @subpackage EM 00047 */ 00048 final class tx_em_Database { 00049 00050 const MULTI_LINEBREAKS = "\n\n\n"; 00051 00052 const TABLE_REPOSITORY = 'sys_ter'; 00053 00054 const TABLE_EXTENSION = 'cache_extensions'; 00055 00056 00057 /** 00058 * Get the count of extensions in cache_extensions from a repository. 00059 * 00060 * If $repository parameter is obmitted, sum of all extensions will be 00061 * returned. 00062 * 00063 * @access public 00064 * @param integer $repository (optional) repository uid of extensions to count 00065 * @return integer sum of extensions in database 00066 */ 00067 public function getExtensionCountFromRepository($repository = NULL) { 00068 if (is_null($repository)) { 00069 return $GLOBALS['TYPO3_DB']->exec_SELECTcountRows( 00070 'DISTINCT extkey', 00071 self::TABLE_EXTENSION 00072 ); 00073 } else { 00074 return $GLOBALS['TYPO3_DB']->exec_SELECTcountRows( 00075 'DISTINCT extkey', 00076 self::TABLE_EXTENSION, 00077 'repository=' . intval($repository) 00078 ); 00079 } 00080 } 00081 00082 /** 00083 * Get extension list from cache_extensions 00084 * 00085 * @param int $repository 00086 * @param string $addFields 00087 * @param string $andWhere 00088 * @param string $order 00089 * @param string $limit 00090 * @return array 00091 */ 00092 public function getExtensionListFromRepository($repository, $addFields = '', $andWhere = '', $order = '', $limit = '') { 00093 $ret = array(); 00094 $temp = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows( 00095 'count(*) AS count', 00096 'cache_extensions', 00097 'repository=' . intval($repository) . $andWhere, 00098 'extkey' 00099 ); 00100 $ret['count'] = count($temp); 00101 00102 $ret['results'] = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows( 00103 'cache_extensions.*, count(*) AS versions, cache_extensions.intversion AS maxintversion' . 00104 ($addFields === '' ? '' : ',' . $addFields), 00105 'cache_extensions JOIN cache_extensions AS ce ON cache_extensions.extkey = ce.extkey', 00106 'cache_extensions.lastversion=1 AND cache_extensions.repository=' . intval($repository) . $andWhere, 00107 'ce.extkey', 00108 $order, 00109 $limit 00110 ); 00111 //debug($GLOBALS['TYPO3_DB']->debug_lastBuiltQuery); 00112 return $ret; 00113 } 00114 00115 /** 00116 * Get versions of extension 00117 * 00118 * @param int $repository 00119 * @param string $extKey 00120 * @return array $versions 00121 */ 00122 public function getExtensionVersionsFromRepository($repository, $extKey) { 00123 $versions = array(); 00124 //TODO: implement 00125 return $versions; 00126 } 00127 00128 /** 00129 * Function inserts a repository object into database. 00130 * 00131 * @access public 00132 * @param tx_em_Repository $repository repository object 00133 * @return void 00134 */ 00135 public function updateRepository(tx_em_Repository $repository) { 00136 $repositoryData = array( 00137 'title' => $repository->getTitle(), 00138 'description' => $repository->getDescription(), 00139 'wsdl_url' => $repository->getWsdlUrl(), 00140 'mirror_url' => $repository->getMirrorListUrl(), 00141 'lastUpdated' => $repository->getLastUpdate(), 00142 'extCount' => $repository->getExtensionCount(), 00143 ); 00144 $GLOBALS['TYPO3_DB']->exec_UPDATEquery( 00145 self::TABLE_REPOSITORY, 00146 'uid=' . $repository->getId(), 00147 $repositoryData 00148 ); 00149 00150 } 00151 00152 00153 /** 00154 * Function inserts a repository object into database. 00155 * 00156 * @access public 00157 * @param tx_em_Repository $repository repository object 00158 * @return integer UID of the newly inserted repository object 00159 */ 00160 public function insertRepository(tx_em_Repository $repository) { 00161 $repositoryData = array( 00162 'title' => $repository->getTitle(), 00163 'description' => $repository->getDescription(), 00164 'wsdl_url' => $repository->getWsdlUrl(), 00165 'mirror_url' => $repository->getMirrorListUrl(), 00166 'lastUpdated' => $repository->getLastUpdate(), 00167 'extCount' => $repository->getExtensionCount(), 00168 ); 00169 $GLOBALS['TYPO3_DB']->exec_INSERTquery( 00170 self::TABLE_REPOSITORY, 00171 $repositoryData 00172 ); 00173 return $GLOBALS['TYPO3_DB']->sql_insert_id(); 00174 } 00175 00176 /** 00177 * Deletes given Repository 00178 * 00179 * @param tx_em_Repository $repository repository object 00180 * @return void 00181 */ 00182 public function deleteRepository(tx_em_Repository $repository) { 00183 $GLOBALS['TYPO3_DB']->exec_DELETEquery( 00184 self::TABLE_REPOSITORY, 00185 'uid=' . $repository->getId() 00186 ); 00187 } 00188 00189 /** 00190 * Updates ExtCount and lastUpdated in Repository eg after import 00191 * @param int $extCount 00192 * @param int $uid 00193 * @return void 00194 */ 00195 public function updateRepositoryCount($extCount, $uid = 1) { 00196 $GLOBALS['TYPO3_DB']->exec_UPDATEquery( 00197 self::TABLE_REPOSITORY, 00198 'uid=' . intval($uid), 00199 array ( 00200 'lastUpdated' => time(), 00201 'extCount' => intval($extCount) 00202 )); 00203 } 00204 00205 /** 00206 * Insert version 00207 * 00208 * @param $arrFields 00209 * @return void 00210 */ 00211 public function insertVersion(array $arrFields) { 00212 $GLOBALS['TYPO3_DB']->exec_INSERTquery(self::TABLE_EXTENSION, $arrFields); 00213 } 00214 00215 /** 00216 * Update the lastversion field after update 00217 * 00218 * @param int $repositoryUid 00219 * @return void 00220 */ 00221 public function insertLastVersion($repositoryUid = 1) { 00222 $groupedRows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows( 00223 'extkey, version, max(intversion) maxintversion', 00224 'cache_extensions', 00225 'repository=' . intval($repositoryUid), 00226 'extkey' 00227 ); 00228 $extensions = count($groupedRows); 00229 00230 if ($extensions > 0) { 00231 // set all to 0 00232 $GLOBALS['TYPO3_DB']->exec_UPDATEquery( 00233 'cache_extensions', 00234 'lastversion=1 AND repository=' . intval($repositoryUid), 00235 array('lastversion' => 0) 00236 ); 00237 00238 // Find latest version of extensions and set lastversion to 1 for these 00239 foreach ($groupedRows as $row) { 00240 $GLOBALS['TYPO3_DB']->exec_UPDATEquery( 00241 'cache_extensions', 00242 'extkey="' . $row['extkey'] . '" AND intversion="' . $row['maxintversion'] . '" AND repository=' . intval($repositoryUid), 00243 array('lastversion' => 1) 00244 ); 00245 } 00246 } 00247 00248 return $extensions; 00249 } 00250 00251 00252 /** 00253 * Method finds and returns repository fields identified by its UID. 00254 * 00255 * @access public 00256 * @param int $uid repository UID 00257 */ 00258 public function getRepositoryByUID($uid) { 00259 $row = $GLOBALS['TYPO3_DB']->exec_SELECTgetSingleRow('*', self::TABLE_REPOSITORY, 'uid=' . intval($uid)); 00260 00261 return $row; 00262 } 00263 00264 /** 00265 * Method finds and returns repository identified by its title 00266 * 00267 * @param $title 00268 * @return 00269 */ 00270 public function getRepositoryByTitle($title) { 00271 return $GLOBALS['TYPO3_DB']->exec_SELECTgetRows( 00272 '*', 00273 self::TABLE_REPOSITORY, 00274 'title=' . $GLOBALS['TYPO3_DB']->fullQuoteStr($title, 00275 self::TABLE_REPOSITORY) 00276 ); 00277 } 00278 00279 /** 00280 * Get available repositories 00281 * 00282 * @param string $where 00283 * @return array 00284 */ 00285 public function getRepositories($where = NULL) { 00286 return $GLOBALS['TYPO3_DB']->exec_SELECTgetRows( 00287 '*', 00288 self::TABLE_REPOSITORY, 00289 $where ? $where : '' 00290 ); 00291 } 00292 00293 /** 00294 * Dump table content 00295 * Is DBAL compliant, but the dump format is written as MySQL standard. If the INSERT statements should be imported in a DBMS using other quoting than MySQL they must first be translated. t3lib_sqlengine can parse these queries correctly and translate them somehow. 00296 * 00297 * @param string Table name 00298 * @param array Field structure 00299 * @return string SQL Content of dump (INSERT statements) 00300 */ 00301 function dumpTableContent($table, $fieldStructure) { 00302 00303 // Substitution of certain characters (borrowed from phpMySQL): 00304 $search = array('\\', '\'', "\x00", "\x0a", "\x0d", "\x1a"); 00305 $replace = array('\\\\', '\\\'', '\0', '\n', '\r', '\Z'); 00306 00307 $lines = array(); 00308 00309 // Select all rows from the table: 00310 $result = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', $table, ''); 00311 00312 // Traverse the selected rows and dump each row as a line in the file: 00313 while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($result)) { 00314 $values = array(); 00315 foreach ($fieldStructure as $field) { 00316 $values[] = isset($row[$field]) ? "'" . str_replace($search, $replace, $row[$field]) . "'" : 'NULL'; 00317 } 00318 $lines[] = 'INSERT INTO ' . $table . ' VALUES (' . implode(', ', $values) . ');'; 00319 } 00320 00321 // Free DB result: 00322 $GLOBALS['TYPO3_DB']->sql_free_result($result); 00323 00324 // Implode lines and return: 00325 return implode(LF, $lines); 00326 } 00327 00328 /** 00329 * Gets the table and field structure from database. 00330 * Which fields and which tables are determined from the ext_tables.sql file 00331 * 00332 * @param string Array with table.field values 00333 * @return array Array of tables and fields splitted. 00334 */ 00335 function getTableAndFieldStructure($parts) { 00336 // Instance of install tool 00337 $instObj = new t3lib_install(); 00338 $dbFields = $instObj->getFieldDefinitions_database(TYPO3_db); 00339 00340 $outTables = array(); 00341 foreach ($parts as $table) { 00342 $sub = explode('.', $table); 00343 if ($sub[0] && isset($dbFields[$sub[0]])) { 00344 if ($sub[1]) { 00345 $key = explode('KEY:', $sub[1], 2); 00346 if (count($key) == 2 && !$key[0]) { // key: 00347 if (isset($dbFields[$sub[0]]['keys'][$key[1]])) { 00348 $outTables[$sub[0]]['keys'][$key[1]] = $dbFields[$sub[0]]['keys'][$key[1]]; 00349 } 00350 } else { 00351 if (isset($dbFields[$sub[0]]['fields'][$sub[1]])) { 00352 $outTables[$sub[0]]['fields'][$sub[1]] = $dbFields[$sub[0]]['fields'][$sub[1]]; 00353 } 00354 } 00355 } else { 00356 $outTables[$sub[0]] = $dbFields[$sub[0]]; 00357 } 00358 } 00359 } 00360 00361 return $outTables; 00362 } 00363 00364 00365 /** 00366 * Makes a dump of the tables/fields definitions for an extension 00367 * 00368 * @param array Array with table => field/key definition arrays in 00369 * @return string SQL for the table definitions 00370 * @see dumpStaticTables() 00371 */ 00372 function dumpTableAndFieldStructure($arr) { 00373 $tables = array(); 00374 00375 if (count($arr)) { 00376 00377 // Get file header comment: 00378 $tables[] = self::dumpHeader(); 00379 00380 // Traverse tables, write each table/field definition: 00381 foreach ($arr as $table => $fieldKeyInfo) { 00382 $tables[] = self::dumpTableHeader($table, $fieldKeyInfo); 00383 } 00384 } 00385 00386 // Return result: 00387 return implode(LF . LF . LF, $tables); 00388 } 00389 00390 /** 00391 * Link to dump of database tables 00392 * 00393 * @param array $tablesArray 00394 * @param string $extKey 00395 * @param array $additionalLinkParameter 00396 * @return string HTML 00397 */ 00398 function dumpDataTablesLine($tablesArray, $extKey, $additionalLinkParameter = array()) { 00399 $tables = array(); 00400 $tablesNA = array(); 00401 $allTables = array_keys($GLOBALS['TYPO3_DB']->admin_get_tables()); 00402 00403 foreach ($tablesArray as $tableName) { 00404 if (in_array($tableName, $allTables)) { 00405 $count = $GLOBALS['TYPO3_DB']->exec_SELECTcountRows('*', $tableName); 00406 $tables[$tableName] = '<tr><td> </td><td> 00407 <a class="t3-link dumpLink" href="' . 00408 htmlspecialchars(t3lib_div::linkThisScript( 00409 array_merge(array( 00410 'CMD[dumpTables]' => $tableName, 00411 'CMD[showExt]' => $extKey, 00412 ), $additionalLinkParameter) 00413 )) . 00414 '" title="' . 00415 sprintf($GLOBALS['LANG']->sL('LLL:EXT:em/language/locallang.xml:extBackup_dump_table'), 00416 $tableName) . 00417 '">' . $tableName . '</a></td><td> </td><td>' . 00418 sprintf($GLOBALS['LANG']->sL('LLL:EXT:em/language/locallang.xml:extBackup_number_of_records'), 00419 $count) . '</td></tr>'; 00420 } else { 00421 $tablesNA[$tableName] = '<tr><td> </td><td>' . $tableName . '</td><td> </td><td>' . 00422 $GLOBALS['LANG']->sL('LLL:EXT:em/language/locallang.xml:extBackup_table_not_there') . '</td></tr>'; 00423 } 00424 } 00425 $label = '<table border="0" cellpadding="0" cellspacing="0">' . 00426 implode('', array_merge($tables, $tablesNA)) . 00427 '</table>'; 00428 if (count($tables)) { 00429 $label = '<a class="t3-link dumpLink" href="' . 00430 htmlspecialchars(t3lib_div::linkThisScript( 00431 array_merge(array( 00432 'CMD[dumpTables]' => implode(',', array_keys($tables)), 00433 'CMD[showExt]' => $extKey 00434 ), $additionalLinkParameter) 00435 )) . 00436 '" title="' . $GLOBALS['LANG']->sL('LLL:EXT:em/language/locallang.xml:extBackup_dump_all_tables') . '">' . 00437 $GLOBALS['LANG']->sL('LLL:EXT:em/language/locallang.xml:extBackup_download_all_data') . '</a><br /><br />' . $label; 00438 } 00439 else { 00440 $label = $GLOBALS['LANG']->sL('LLL:EXT:em/language/locallang.xml:extBackup_nothing_to_dump') . '<br /><br />' . $label; 00441 } 00442 return $label; 00443 } 00444 00445 /** 00446 * Dump content for static tables 00447 * 00448 * @param string Comma list of tables from which to dump content 00449 * @return string Returns the content 00450 * @see dumpTableAndFieldStructure() 00451 */ 00452 function dumpStaticTables($tableList) { 00453 $instObj = t3lib_div::makeInstance('t3lib_install'); 00454 $dbFields = $instObj->getFieldDefinitions_database(TYPO3_db); 00455 00456 $out = ''; 00457 $parts = t3lib_div::trimExplode(',', $tableList, TRUE); 00458 00459 // Traverse the table list and dump each: 00460 foreach ($parts as $table) { 00461 if (is_array($dbFields[$table]['fields'])) { 00462 $header = self::dumpHeader(); 00463 $tableHeader = self::dumpTableHeader($table, $dbFields[$table], TRUE); 00464 $insertStatements = self::dumpTableContent($table, $dbFields[$table]['fields']); 00465 $out .= $header . self::MULTI_LINEBREAKS . 00466 $tableHeader . self::MULTI_LINEBREAKS . 00467 $insertStatements . self::MULTI_LINEBREAKS; 00468 } else { 00469 throw new RuntimeException( 00470 'TYPO3 Fatal Error: ' . $GLOBALS['LANG']->getLL('dumpStaticTables_table_not_found'), 00471 1270853983 00472 ); 00473 } 00474 } 00475 unset($instObj); 00476 return $out; 00477 } 00478 00479 /** 00480 * Header comments of the SQL dump file 00481 * 00482 * @return string Table header 00483 */ 00484 function dumpHeader() { 00485 return trim(' 00486 # TYPO3 Extension Manager dump 1.1 00487 # 00488 # Host: ' . TYPO3_db_host . ' Database: ' . TYPO3_db . ' 00489 #-------------------------------------------------------- 00490 '); 00491 } 00492 00493 /** 00494 * Dump CREATE TABLE definition 00495 * 00496 * @param string Table name 00497 * @param array Field and key information (as provided from Install Tool class!) 00498 * @param boolean If true, add "DROP TABLE IF EXISTS" 00499 * @return string Table definition SQL 00500 */ 00501 function dumpTableHeader($table, $fieldKeyInfo, $dropTableIfExists = 0) { 00502 $lines = array(); 00503 $dump = ''; 00504 00505 // Create field definitions 00506 if (is_array($fieldKeyInfo['fields'])) { 00507 foreach ($fieldKeyInfo['fields'] as $fieldN => $data) { 00508 $lines[] = ' ' . $fieldN . ' ' . $data; 00509 } 00510 } 00511 00512 // Create index key definitions 00513 if (is_array($fieldKeyInfo['keys'])) { 00514 foreach ($fieldKeyInfo['keys'] as $fieldN => $data) { 00515 $lines[] = ' ' . $data; 00516 } 00517 } 00518 00519 // Compile final output: 00520 if (count($lines)) { 00521 $dump = trim(' 00522 # 00523 # Table structure for table "' . $table . '" 00524 # 00525 ' . ($dropTableIfExists ? 'DROP TABLE IF EXISTS ' . $table . '; 00526 ' : '') . 'CREATE TABLE ' . $table . ' ( 00527 ' . implode(',' . LF, $lines) . ' 00528 );'); 00529 } 00530 00531 return $dump; 00532 } 00533 00534 } 00535 00536 ?>
1.8.0