|
TYPO3 API
SVNRelease
|
00001 <?php 00002 /*************************************************************** 00003 * Copyright notice 00004 * 00005 * (c) 2004-2009 Kasper Skårhøj (kasper@typo3.com) 00006 * All rights reserved 00007 * 00008 * This script is part of the TYPO3 project. The TYPO3 project is 00009 * free software; you can redistribute it and/or modify 00010 * it under the terms of the GNU General Public License as published by 00011 * the Free Software Foundation; either version 2 of the License, or 00012 * (at your option) any later version. 00013 * 00014 * The GNU General Public License can be found at 00015 * http://www.gnu.org/copyleft/gpl.html. 00016 * A copy is found in the textfile GPL.txt and important notices to the license 00017 * from the author is found in LICENSE.txt distributed with these scripts. 00018 * 00019 * 00020 * This script is distributed in the hope that it will be useful, 00021 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00022 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00023 * GNU General Public License for more details. 00024 * 00025 * This copyright notice MUST APPEAR in all copies of the script! 00026 ***************************************************************/ 00027 /** 00028 * Contains an example DBAL handler class 00029 * 00030 * $Id: class.tx_dbal_handler_xmldb.php 40828 2010-12-05 14:55:53Z xperseguers $ 00031 * 00032 * @author Kasper Skårhøj <kasper@typo3.com> 00033 */ 00034 /** 00035 * [CLASS/FUNCTION INDEX of SCRIPT] 00036 * 00037 * 00038 * 00039 * 74: class tx_dbal_handler_xmldb extends tx_dbal_sqlengine 00040 * 91: function init($config, &$pObj) 00041 * 128: function readDataSource($table) 00042 * 157: function saveDataSource($table) 00043 * 184: function xmlDB_writeStructure() 00044 * 193: function xmlDB_readStructure() 00045 * 00046 * SECTION: SQL admin functions 00047 * 217: function admin_get_tables() 00048 * 242: function admin_get_fields($tableName) 00049 * 276: function admin_get_keys($tableName) 00050 * 314: function admin_query($query) 00051 * 00052 * TOTAL FUNCTIONS: 9 00053 * (This index is automatically created/updated by the extension "extdeveval") 00054 * 00055 */ 00056 00057 00058 00059 00060 00061 00062 00063 00064 00065 00066 /** 00067 * Example DBAL handler class 00068 * Stores data in XML, not a database. 00069 * 00070 * @author Kasper Skårhøj <kasper@typo3.com> 00071 * @package TYPO3 00072 * @subpackage tx_dbal 00073 */ 00074 class tx_dbal_handler_xmldb extends tx_dbal_sqlengine { 00075 00076 var $config = array(); 00077 var $pObj; // Set from DBAL class. 00078 00079 // Database Storage directory: 00080 var $DBdir = ''; 00081 var $DBstructure = array( 00082 'tables' => array() 00083 ); 00084 00085 /** 00086 * Initialize handler 00087 * 00088 * @param array Configuration from DBAL 00089 * @param object Parent object 00090 * @return void 00091 */ 00092 function init($config, $pObj) { 00093 $this->config = $config['config']; 00094 00095 $dbStorage = t3lib_div::getFileAbsFileName($this->config['DBstorageDir']); 00096 if ($dbStorage && @is_dir($dbStorage) && ($dbStorage{strlen($dbStorage)-1} == '/')) { 00097 $this->DBdir = $dbStorage; 00098 00099 // Read structure file: 00100 if (@is_file($this->DBdir.'_STRUCTURE.xml')) { 00101 $this->xmlDB_readStructure(); 00102 if (is_array($this->DBstructure)) { 00103 return TRUE; 00104 } else { 00105 $this->errorStatus = 'The database structure array could not be loaded correctly. "_STRUCTURE.xml" may be corrupt'; 00106 } 00107 } else { 00108 $this->xmlDB_writeStructure(); 00109 if (@is_file($this->DBdir.'_STRUCTURE.xml')) { 00110 return TRUE; 00111 } else { 00112 $this->errorStatus = 'The database structure file could not be created in dir "'.$dbStorage.'"'; 00113 } 00114 } 00115 00116 00117 } else $this->errorStatus = 'The database storage dir "'.$dbStorage.'" did not exist!'; 00118 00119 debug($this->errorStatus,'XMLDB connect ERROR:'); 00120 return FALSE; 00121 } 00122 00123 /** 00124 * Setting table data (overriding function) 00125 * 00126 * @param string Table name 00127 * @return void 00128 */ 00129 function readDataSource($table) { 00130 00131 if (!$this->DBdir) { 00132 $this->errorStatus = 'XMLdatabase not connected'; 00133 return FALSE; 00134 } 00135 00136 // Reading table: 00137 if (is_array($this->DBstructure['tables'][$table])) { 00138 if (!isset($this->data[$table])) { // Checking if it has already been read 00139 $newTableFile = 'TABLE_'.$table.'.xml'; 00140 if (@is_file($this->DBdir.$newTableFile)) { 00141 $this->data[$table] = t3lib_div::xml2array(t3lib_div::getUrl($this->DBdir.$newTableFile)); 00142 if (!is_array($this->data[$table])) $this->data[$table] = array(); 00143 return TRUE; 00144 } else { 00145 $this->data[$table] = array(); 00146 $this->errorStatus = 'Tablefile for "'.$table.'" not found'; 00147 } 00148 } 00149 } else $this->errorStatus = 'Table "'.$table.'" not found'; 00150 } 00151 00152 /** 00153 * Saving data source 00154 * 00155 * @param string Table name 00156 * @return boolean True on success 00157 */ 00158 function saveDataSource($table) { 00159 00160 if (!$this->DBdir) { 00161 $this->errorStatus = 'XMLdatabase not connected'; 00162 return FALSE; 00163 } 00164 00165 // Writing table: 00166 if (is_array($this->DBstructure['tables'][$table])) { 00167 $newTableFile = 'TABLE_'.$table.'.xml'; 00168 if (t3lib_div::getFileAbsFileName($this->DBdir.$newTableFile) && @is_file($this->DBdir.$newTableFile)) { 00169 00170 $storeInCharset = $GLOBALS['LANG']->charSet; 00171 $xmlValue = t3lib_div::array2xml($this->data[$table],'',0,'T3xmlDB',0,array('useIndexTagForNum'=>'rec')); 00172 $content = '<?xml version="1.0" encoding="'.$storeInCharset.'" standalone="yes" ?>'.chr(10).$xmlValue; 00173 t3lib_div::writeFile($this->DBdir.$newTableFile,$content); 00174 00175 return TRUE; 00176 } else $this->errorStatus = 'Tablefile for "'.$table.'" not found'; 00177 } else $this->errorStatus = 'Table "'.$table.'" not found'; 00178 } 00179 00180 /** 00181 * Writing database structure 00182 * 00183 * @return void 00184 */ 00185 function xmlDB_writeStructure() { 00186 t3lib_div::writeFile($this->DBdir.'_STRUCTURE.xml', t3lib_div::array2xml($this->DBstructure,'',0,'T3xmlDBStructure',0,array('useIndexTagForNum'=>'item'))); 00187 } 00188 00189 /** 00190 * Reading database structure 00191 * 00192 * @return void 00193 */ 00194 function xmlDB_readStructure() { 00195 $this->DBstructure = t3lib_div::xml2array(t3lib_div::getUrl($this->DBdir.'_STRUCTURE.xml')); 00196 } 00197 00198 00199 00200 00201 00202 00203 00204 00205 00206 /************************************** 00207 * 00208 * SQL admin functions 00209 * (For use in the Install Tool and Extension Manager) 00210 * 00211 **************************************/ 00212 00213 /** 00214 * Returns the list of tables from the database 00215 * 00216 * @return array Tables in an array (tablename is in both key and value) 00217 * @todo Should return table details in value! see t3lib_db::admin_get_tables() 00218 */ 00219 function admin_get_tables() { 00220 00221 if (!$this->DBdir) { 00222 $this->errorStatus = 'XMLdatabase not connected'; 00223 return FALSE; 00224 } 00225 00226 $whichTables = array(); 00227 00228 // Traverse tables: 00229 if (is_array($this->DBstructure['tables'])) { 00230 foreach($this->DBstructure['tables'] as $tableName => $tableInfo) { 00231 $whichTables[$tableName] = $tableName; 00232 } 00233 } 00234 00235 return $whichTables; 00236 } 00237 00238 /** 00239 * Returns information about each field in the $table 00240 * 00241 * @param string Table name 00242 * @return array Field information in an associative array with fieldname => field row 00243 */ 00244 function admin_get_fields($tableName) { 00245 00246 if (!$this->DBdir) { 00247 $this->errorStatus = 'XMLdatabase not connected'; 00248 return FALSE; 00249 } 00250 00251 $output = array(); 00252 00253 // Traverse fields in table: 00254 if (is_array($this->DBstructure['tables'][$tableName]) && is_array($this->DBstructure['tables'][$tableName]['FIELDS'])) { 00255 foreach($this->DBstructure['tables'][$tableName]['FIELDS'] as $fieldName => $fieldInfo) { 00256 $output[$fieldName] = array( 00257 'Field' => $fieldName, 00258 'Type' => $fieldInfo['definition']['fieldType']. 00259 ($fieldInfo['definition']['value']?'('.$fieldInfo['definition']['value'].')':''). 00260 (isset($fieldInfo['definition']['featureIndex']['UNSIGNED']) ? ' '.$fieldInfo['definition']['featureIndex']['UNSIGNED']['keyword'] : ''), 00261 'Null' => isset($fieldInfo['definition']['featureIndex']['NOTNULL']) ? '' : 'Yes', 00262 'Key' => '', 00263 'Default' => $fieldInfo['definition']['featureIndex']['DEFAULT']['value'][0], 00264 'Extra' => isset($fieldInfo['definition']['featureIndex']['AUTO_INCREMENT']) ? 'auto_increment' : '', 00265 ); 00266 } 00267 } 00268 00269 return $output; 00270 } 00271 00272 /** 00273 * Returns information about each index key in the $table 00274 * 00275 * @param string Table name 00276 * @return array Key information in a numeric array 00277 */ 00278 function admin_get_keys($tableName) { 00279 00280 if (!$this->DBdir) { 00281 $this->errorStatus = 'XMLdatabase not connected'; 00282 return FALSE; 00283 } 00284 00285 $output = array(); 00286 00287 // Traverse fields in table: 00288 if (is_array($this->DBstructure['tables'][$tableName]) && is_array($this->DBstructure['tables'][$tableName]['KEYS'])) { 00289 foreach($this->DBstructure['tables'][$tableName]['KEYS'] as $keyName => $keyInfo) { 00290 foreach($keyInfo as $seq => $keyField) { 00291 $output[] = array( 00292 'Table' => $tableName, 00293 'Non_unique' => ($keyName=='PRIMARYKEY' ? 0 : 1), 00294 'Key_name' => ($keyName=='PRIMARYKEY' ? 'PRIMARY' : $keyName), 00295 'Seq_in_index' => $seq+1, 00296 'Column_name' => $keyField, 00297 'Collation' => 'A', 00298 'Cardinality' => '', 00299 'Sub_part' => '', 00300 'Packed' => '', 00301 'Comment' => '', 00302 ); 00303 } 00304 } 00305 } 00306 00307 return $output; 00308 } 00309 00310 /** 00311 * mysql() wrapper function, used by the Install Tool and EM for all queries regarding management of the database! 00312 * 00313 * @param string Query to execute 00314 * @return pointer Result pointer 00315 */ 00316 function admin_query($query) { 00317 00318 if (!$this->DBdir) { 00319 $this->errorStatus = 'XMLdatabase not connected'; 00320 return FALSE; 00321 } 00322 00323 $parsedQuery = $this->parseSQL($query); 00324 $table = $parsedQuery['TABLE']; 00325 00326 if (is_array($parsedQuery)) { 00327 // Process query based on type: 00328 switch($parsedQuery['type']) { 00329 case 'CREATETABLE': 00330 if (!is_array($this->DBstructure['tables'][$table])) { 00331 $newTableFile = 'TABLE_'.$table.'.xml'; 00332 if (!@is_file($this->DBdir.$newTableFile)) { 00333 00334 // Write table file: 00335 t3lib_div::writeFile($this->DBdir.$newTableFile, ''); // Create file 00336 if (@is_file($this->DBdir.$newTableFile)) { 00337 00338 // Set and write structure 00339 if (!is_array($this->DBstructure['tables'])) $this->DBstructure['tables']=array(); 00340 $this->DBstructure['tables'][(string)$table] = $parsedQuery; // I have some STRANGE behaviours with this variable - had to do this trick to make it work! 00341 00342 $this->xmlDB_writeStructure(); 00343 return TRUE; 00344 } else $this->errorStatus = 'Table file "'.$this->DBdir.$newTableFile.'" could not be created! Cannot create table!'; 00345 } else $this->errorStatus = 'Table file "'.$this->DBdir.$newTableFile.'" already exists! Cannot create table!'; 00346 } else $this->errorStatus = 'Table "'.$table.'" already exists!'; 00347 break; 00348 case 'ALTERTABLE': 00349 if (is_array($this->DBstructure['tables'][$table])) { 00350 switch($parsedQuery['action']) { 00351 case 'ADD': 00352 if (!is_array($this->DBstructure['tables'][$table]['FIELDS'][$parsedQuery['FIELD']])) { 00353 $this->DBstructure['tables'][$table]['FIELDS'][$parsedQuery['FIELD']]['definition'] = $parsedQuery['definition']; // Adding field in the end of list. 00354 $this->xmlDB_writeStructure(); 00355 return TRUE; 00356 00357 // TODO: Should traverse all data an add that field in arrays! 00358 } else $this->errorStatus = 'Field "'.$parsedQuery['FIELD'].'" already exists!'; 00359 break; 00360 case 'CHANGE': 00361 if (is_array($this->DBstructure['tables'][$table]['FIELDS'])) { 00362 if (is_array($this->DBstructure['tables'][$table]['FIELDS'][$parsedQuery['FIELD']])) { 00363 $newFieldInfo = array(); 00364 foreach($this->DBstructure['tables'][$table]['FIELDS'] as $fieldName => $fieldDefinition) { 00365 if (!strcmp($fieldName,$parsedQuery['FIELD'])) { 00366 00367 // New fieldname? 00368 if ($parsedQuery['newField']) { 00369 if (!is_array($this->DBstructure['tables'][$table]['FIELDS'][$parsedQuery['newField']])) { 00370 $fieldName = $parsedQuery['newField']; 00371 } else { 00372 $this->errorStatus = 'A field in the table was already named "'.$parsedQuery['newField'].'"'; 00373 return FALSE; 00374 } 00375 } 00376 // Set new field definition: 00377 $fieldDefinition['definition'] = $parsedQuery['definition']; 00378 } 00379 00380 // Set the whole thing in new var: 00381 $newFieldInfo[$fieldName] = $fieldDefinition; 00382 } 00383 $this->DBstructure['tables'][$table]['FIELDS'] = $newFieldInfo; 00384 $this->xmlDB_writeStructure(); 00385 return TRUE; 00386 00387 // TODO: Should traverse all data an remove that field in arrays! 00388 } else $this->errorStatus = 'Field "'.$parsedQuery['FIELD'].'" does not exist!'; 00389 } else $this->errorStatus = 'There are not fields in the table - strange!'; 00390 break; 00391 case 'DROP': 00392 if (is_array($this->DBstructure['tables'][$table]['FIELDS'][$parsedQuery['FIELD']])) { 00393 unset($this->DBstructure['tables'][$table]['FIELDS'][$parsedQuery['FIELD']]); // Removing it... 00394 $this->xmlDB_writeStructure(); 00395 return TRUE; 00396 00397 // TODO: Should traverse all data an remove that field in arrays! 00398 } else $this->errorStatus = 'Field "'.$parsedQuery['FIELD'].'" does not exist!'; 00399 break; 00400 } 00401 } else $this->errorStatus = 'Table "'.$table.'" does not exist!'; 00402 break; 00403 case 'DROPTABLE': 00404 00405 // TODO: 00406 debug($parsedQuery); 00407 00408 00409 break; 00410 default: 00411 $this->errorStatus = 'Query type "'.$parsedQuery['type'].'" was not supported!'; 00412 break; 00413 } 00414 00415 } else $this->errorStatus = 'SQL parse error: '.$parsedQuery; 00416 00417 return FALSE; 00418 } 00419 } 00420 00421 00422 if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['ext/dbal/handlers/class.tx_dbal_handler_xmldb.php'])) { 00423 include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['ext/dbal/handlers/class.tx_dbal_handler_xmldb.php']); 00424 } 00425 ?>
1.8.0