|
TYPO3 API
SVNRelease
|
00001 <?php 00002 /*************************************************************** 00003 * Copyright notice 00004 * 00005 * (c) 2009-2010 Xavier Perseguers <typo3@perseguers.ch> 00006 * (c) 2004-2009 Kasper Skårhøj <kasperYYYY@typo3.com> 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 * A copy is found in the textfile GPL.txt and important notices to the license 00018 * from the author is found in LICENSE.txt distributed with these scripts. 00019 * 00020 * 00021 * This script is distributed in the hope that it will be useful, 00022 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00023 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00024 * GNU General Public License for more details. 00025 * 00026 * This copyright notice MUST APPEAR in all copies of the script! 00027 ***************************************************************/ 00028 00029 00030 /** 00031 * PHP SQL engine 00032 * 00033 * $Id: class.tx_dbal_sqlengine.php 40828 2010-12-05 14:55:53Z xperseguers $ 00034 * 00035 * @author Kasper Skårhøj <kasperYYYY@typo3.com> 00036 * @author Xavier Perseguers <typo3@perseguers.ch> 00037 */ 00038 /** 00039 * [CLASS/FUNCTION INDEX of SCRIPT] 00040 * 00041 * 00042 * 00043 * 106: class tx_dbal_sqlengine extends ux_t3lib_sqlparser 00044 * 128: public function init($config, $pObj) 00045 * 136: public function resetStatusVars() 00046 * 152: private function processAccordingToConfig(&$value, $fInfo) 00047 * 00048 * SECTION: SQL queries 00049 * 207: public function exec_INSERTquery($table, $fields_values) 00050 * 275: public function exec_UPDATEquery($table, $where, $fields_values) 00051 * 334: public function exec_DELETEquery($table, $where) 00052 * 385: public function exec_SELECTquery($select_fields, $from_table, $where_clause, $groupBy, $orderBy, $limit) 00053 * 428: public function sql_query($query) 00054 * 439: public function sql_error() 00055 * 448: public function sql_insert_id() 00056 * 457: public function sql_affected_rows() 00057 * 467: public function quoteStr($str) 00058 * 00059 * SECTION: SQL admin functions 00060 * 493: public function admin_get_tables() 00061 * 504: public function admin_get_fields($tableName) 00062 * 515: public function admin_get_keys($tableName) 00063 * 526: public function admin_query($query) 00064 * 00065 * SECTION: Data Source I/O 00066 * 551: public function readDataSource($table) 00067 * 563: public function saveDataSource($table) 00068 * 00069 * SECTION: SQL engine functions (PHP simulation of SQL) - still experimental 00070 * 593: public function selectFromData($table, $where) 00071 * 631: public function select_evalSingle($table,$config,&$itemKeys) 00072 * 750: public function getResultSet($keys, $table, $fieldList) 00073 * 00074 * SECTION: Debugging 00075 * 793: public function debug_printResultSet($array) 00076 * 00077 * 00078 * 832: class tx_dbal_sqlengine_resultobj 00079 * 846: public function sql_num_rows() 00080 * 855: public function sql_fetch_assoc() 00081 * 866: public function sql_fetch_row() 00082 * 884: public function sql_data_seek($pointer) 00083 * 897: public function sql_field_type() 00084 * 00085 * TOTAL FUNCTIONS: 27 00086 * (This index is automatically created/updated by the extension "extdeveval") 00087 * 00088 */ 00089 00090 00091 /** 00092 * PHP SQL engine / server 00093 * Basically this is trying to emulation SQL record selection by PHP, thus allowing SQL queries into alternative data storages managed by PHP. 00094 * EXPERIMENTAL! 00095 * 00096 * @author Kasper Skårhøj <kasperYYYY@typo3.com> 00097 * @package TYPO3 00098 * @subpackage t3lib 00099 */ 00100 class tx_dbal_sqlengine extends ux_t3lib_sqlparser { 00101 00102 // array with data records: [table name][num.index] = records 00103 var $data = array(); // Data source storage 00104 00105 00106 // Internal, SQL Status vars: 00107 var $errorStatus = ''; // Set with error message of last operation 00108 var $lastInsertedId = 0; // Set with last inserted unique ID 00109 var $lastAffectedRows = 0; // Set with last number of affected rows. 00110 00111 00112 /** 00113 * Dummy function for initializing SQL handler. Create you own in derived classes. 00114 * 00115 * @param array Configuration array from handler 00116 * @param object Parent object 00117 * @return void 00118 */ 00119 public function init($config, $pObj) { 00120 } 00121 00122 /** 00123 * Reset SQL engine status variables (insert id, affected rows, error status) 00124 * 00125 * @return void 00126 */ 00127 public function resetStatusVars() { 00128 $this->errorStatus = ''; 00129 $this->lastInsertedId = 0; 00130 $this->lastAffectedRows = 0; 00131 } 00132 00133 /** 00134 * Processing of update/insert values based on field type. 00135 * 00136 * The input value is typecast and trimmed/shortened according to the field 00137 * type and the configuration options from the $fInfo parameter. 00138 * 00139 * @param mixed $value The input value to process 00140 * @param array $fInfo Field configuration data 00141 * @return mixed The processed input value 00142 */ 00143 private function processAccordingToConfig(&$value, $fInfo) { 00144 $options = $this->parseFieldDef($fInfo['Type']); 00145 00146 switch (strtolower($options['fieldType'])) { 00147 case 'int': 00148 case 'smallint': 00149 case 'tinyint': 00150 case 'mediumint': 00151 $value = intval($value); 00152 if ($options['featureIndex']['UNSIGNED']) { 00153 $value = t3lib_div::intInRange($value, 0); 00154 } 00155 break; 00156 case 'double': 00157 $value = (double) $value; 00158 break; 00159 case 'varchar': 00160 case 'char': 00161 $value = substr($value, 0, trim($options['value'])); 00162 break; 00163 case 'text': 00164 case 'blob': 00165 $value = substr($value, 0, 65536); 00166 break; 00167 case 'tinytext': 00168 case 'tinyblob': 00169 $value = substr($value, 0, 256); 00170 break; 00171 case 'mediumtext': 00172 case 'mediumblob': 00173 // ?? 00174 break; 00175 } 00176 } 00177 00178 00179 /******************************** 00180 * 00181 * SQL queries 00182 * This is the SQL access functions used when this class is instantiated as a SQL handler with DBAL. Override these in derived classes. 00183 * 00184 ********************************/ 00185 00186 /** 00187 * Execute an INSERT query 00188 * 00189 * @param string Table name 00190 * @param array Field values as key=>value pairs. 00191 * @return boolean TRUE on success and FALSE on failure (error is set internally) 00192 */ 00193 public function exec_INSERTquery($table, $fields_values) { 00194 00195 // Initialize 00196 $this->resetStatusVars(); 00197 00198 // Reading Data Source if not done already. 00199 $this->readDataSource($table); 00200 00201 // If data source is set: 00202 if (is_array($this->data[$table])) { 00203 00204 $fieldInformation = $this->admin_get_fields($table); // Should cache this...! 00205 00206 // Looking for unique keys: 00207 $saveArray = array(); 00208 foreach ($fieldInformation as $fInfo) { 00209 00210 // Field name: 00211 $fN = $fInfo['Field']; 00212 00213 // Set value: 00214 // FIXME $options not defined 00215 $saveArray[$fN] = isset($fields_values[$fN]) ? $fields_values[$fN] : $options['Default']; 00216 00217 // Process value: 00218 $this->processAccordingToConfig($saveArray[$fN], $fInfo); 00219 00220 // If an auto increment field is found, find the largest current uid: 00221 if ($fInfo['Extra'] == 'auto_increment') { 00222 00223 // Get all UIDs: 00224 $uidArray = array(); 00225 foreach ($this->data[$table] as $r) { 00226 $uidArray[] = $r[$fN]; 00227 } 00228 00229 // If current value is blank or already in array, we create a new: 00230 if (!$saveArray[$fN] || in_array(intval($saveArray[$fN]), $uidArray)) { 00231 if (count($uidArray)) { 00232 $saveArray[$fN] = max($uidArray) + 1; 00233 } else $saveArray[$fN] = 1; 00234 } 00235 00236 // Update "last inserted id": 00237 $this->lastInsertedId = $saveArray[$fN]; 00238 } 00239 } 00240 00241 // Insert row in table: 00242 $this->data[$table][] = $saveArray; 00243 00244 // Save data source 00245 $this->saveDataSource($table); 00246 00247 return TRUE; 00248 } else $this->errorStatus = 'No data loaded.'; 00249 00250 return FALSE; 00251 } 00252 00253 /** 00254 * Execute UPDATE query on table 00255 * 00256 * @param string Table name 00257 * @param string WHERE clause 00258 * @param array Field values as key=>value pairs. 00259 * @return boolean TRUE on success and FALSE on failure (error is set internally) 00260 */ 00261 public function exec_UPDATEquery($table, $where, $fields_values) { 00262 00263 // Initialize: 00264 $this->resetStatusVars(); 00265 00266 // Reading Data Source if not done already. 00267 $this->readDataSource($table); 00268 00269 // If anything is there: 00270 if (is_array($this->data[$table])) { 00271 00272 // Parse WHERE clause: 00273 $where = $this->parseWhereClause($where); 00274 00275 if (is_array($where)) { 00276 00277 // Field information 00278 $fieldInformation = $this->admin_get_fields($table); // Should cache this...! 00279 00280 // Traverse fields to update: 00281 foreach ($fields_values as $fName => $fValue) { 00282 $this->processAccordingToConfig($fields_values[$fName], $fieldInformation[$fName]); 00283 } 00284 00285 // Do query, returns array with keys to the data array of the result: 00286 $itemKeys = $this->selectFromData($table, $where); 00287 00288 // Set "last affected rows": 00289 $this->lastAffectedRows = count($itemKeys); 00290 00291 // Update rows: 00292 if ($this->lastAffectedRows) { 00293 // Traverse result set here: 00294 foreach ($itemKeys as $dataArrayKey) { 00295 00296 // Traverse fields to update: 00297 foreach ($fields_values as $fName => $fValue) { 00298 $this->data[$table][$dataArrayKey][$fName] = $fValue; 00299 } 00300 } 00301 00302 // Save data source 00303 $this->saveDataSource($table); 00304 } 00305 00306 return TRUE; 00307 } else $this->errorStatus = 'WHERE clause contained errors: ' . $where; 00308 } else $this->errorStatus = 'No data loaded.'; 00309 00310 return FALSE; 00311 } 00312 00313 /** 00314 * Execute DELETE query 00315 * 00316 * @param string Table to delete from 00317 * @param string WHERE clause 00318 * @return boolean TRUE on success and FALSE on failure (error is set internally) 00319 */ 00320 public function exec_DELETEquery($table, $where) { 00321 00322 // Initialize: 00323 $this->resetStatusVars(); 00324 00325 // Reading Data Source if not done already. 00326 $this->readDataSource($table); 00327 00328 // If anything is there: 00329 if (is_array($this->data[$table])) { 00330 00331 // Parse WHERE clause: 00332 $where = $this->parseWhereClause($where); 00333 00334 if (is_array($where)) { 00335 00336 // Do query, returns array with keys to the data array of the result: 00337 $itemKeys = $this->selectFromData($table, $where); 00338 00339 // Set "last affected rows": 00340 $this->lastAffectedRows = count($itemKeys); 00341 00342 // Remove rows: 00343 if ($this->lastAffectedRows) { 00344 // Traverse result set: 00345 foreach ($itemKeys as $dataArrayKey) { 00346 unset($this->data[$table][$dataArrayKey]); 00347 } 00348 00349 // Saving data source 00350 $this->saveDataSource($table); 00351 } 00352 00353 return TRUE; 00354 } else $this->errorStatus = 'WHERE clause contained errors: ' . $where; 00355 } else $this->errorStatus = 'No data loaded.'; 00356 00357 return FALSE; 00358 } 00359 00360 /** 00361 * Execute SELECT query 00362 * 00363 * @param string List of fields to select from the table. This is what comes right after "SELECT ...". Required value. 00364 * @param string Table(s) from which to select. This is what comes right after "FROM ...". Required value. 00365 * @param string Optional additional WHERE clauses put in the end of the query. NOTICE: You must escape values in this argument with $this->fullQuoteStr() yourself! DO NOT PUT IN GROUP BY, ORDER BY or LIMIT! 00366 * @param string Optional GROUP BY field(s), if none, supply blank string. 00367 * @param string Optional ORDER BY field(s), if none, supply blank string. 00368 * @param string Optional LIMIT value ([begin,]max), if none, supply blank string. 00369 * @return object Returns result object, but if errors, returns false 00370 */ 00371 public function exec_SELECTquery($select_fields, $from_table, $where_clause, $groupBy, $orderBy, $limit) { 00372 00373 // Initialize: 00374 $this->resetStatusVars(); 00375 00376 // Create result object 00377 $sqlObj = t3lib_div::makeInstance('tx_dbal_sqlengine_resultobj'); 00378 $sqlObj->result = array(); // Empty result as a beginning 00379 00380 // Get table list: 00381 $tableArray = $this->parseFromTables($from_table); 00382 $table = $tableArray[0]['table']; 00383 00384 // Reading Data Source if not done already. 00385 $this->readDataSource($table); 00386 00387 // If anything is there: 00388 if (is_array($this->data[$table])) { 00389 00390 // Parse WHERE clause: 00391 $where = $this->parseWhereClause($where_clause); 00392 if (is_array($where)) { 00393 00394 // Do query, returns array with keys to the data array of the result: 00395 $itemKeys = $this->selectFromData($table, $where); 00396 00397 // Finally, read the result rows into this variable: 00398 $sqlObj->result = $this->getResultSet($itemKeys, $table, '*'); 00399 // Reset and return result: 00400 reset($sqlObj->result); 00401 return $sqlObj; 00402 } else $this->errorStatus = 'WHERE clause contained errors: ' . $where; 00403 } else $this->errorStatus = 'No data loaded: ' . $this->errorStatus; 00404 00405 return FALSE; 00406 } 00407 00408 /** 00409 * Performs an SQL query on the "database" 00410 * 00411 * @param string Query to execute 00412 * @return object Result object or false if error 00413 */ 00414 public function sql_query($query) { 00415 $res = t3lib_div::makeInstance('tx_dbal_sqlengine_resultobj'); 00416 $res->result = array(); 00417 return $res; 00418 } 00419 00420 /** 00421 * Returns most recent error 00422 * 00423 * @return string Error message, if any 00424 */ 00425 public function sql_error() { 00426 return $this->errorStatus; 00427 } 00428 00429 /** 00430 * Returns most recently create unique ID (of INSERT queries) 00431 * 00432 * @return integer Last unique id created. 00433 */ 00434 public function sql_insert_id() { 00435 return $this->lastInsertedId; 00436 } 00437 00438 /** 00439 * Returns affected rows (of UPDATE and DELETE queries) 00440 * 00441 * @return integer Last amount of affected rows. 00442 */ 00443 public function sql_affected_rows() { 00444 return $this->lastAffectedRows; 00445 } 00446 00447 /** 00448 * Quoting strings for insertion in SQL queries 00449 * 00450 * @param string Input String 00451 * @return string String, with quotes escaped 00452 */ 00453 public function quoteStr($str) { 00454 return addslashes($str); 00455 } 00456 00457 00458 /************************************** 00459 * 00460 * SQL admin functions 00461 * (For use in the Install Tool and Extension Manager) 00462 * 00463 **************************************/ 00464 00465 /** 00466 * (DUMMY) Returns the list of tables from the database 00467 * 00468 * @return array Tables in an array (tablename is in both key and value) 00469 * @todo Should return table details in value! see t3lib_db::admin_get_tables() 00470 */ 00471 public function admin_get_tables() { 00472 $whichTables = array(); 00473 return $whichTables; 00474 } 00475 00476 /** 00477 * (DUMMY) Returns information about each field in the $table 00478 * 00479 * @param string Table name 00480 * @return array Field information in an associative array with fieldname => field row 00481 */ 00482 public function admin_get_fields($tableName) { 00483 $output = array(); 00484 return $output; 00485 } 00486 00487 /** 00488 * (DUMMY) Returns information about each index key in the $table 00489 * 00490 * @param string Table name 00491 * @return array Key information in a numeric array 00492 */ 00493 public function admin_get_keys($tableName) { 00494 $output = array(); 00495 return $output; 00496 } 00497 00498 /** 00499 * (DUMMY) mysql() wrapper function, used by the Install Tool and EM for all queries regarding management of the database! 00500 * 00501 * @param string Query to execute 00502 * @return pointer Result pointer 00503 */ 00504 public function admin_query($query) { 00505 return $this->sql_query($query); 00506 } 00507 00508 00509 /******************************** 00510 * 00511 * Data Source I/O 00512 * 00513 ********************************/ 00514 00515 /** 00516 * Dummy function for setting table data. Create your own. 00517 * NOTICE: Handler to "table-locking" needs to be made probably! 00518 * 00519 * @param string Table name 00520 * @return void 00521 * @todo Table locking tools? 00522 */ 00523 public function readDataSource($table) { 00524 $this->data[$table] = array(); 00525 } 00526 00527 /** 00528 * Dummy function for setting table data. Create your own. 00529 * NOTICE: Handler to "table-locking" needs to be made probably! 00530 * 00531 * @param string Table name 00532 * @return void 00533 * @todo Table locking tools? 00534 */ 00535 public function saveDataSource($table) { 00536 debug($this->data[$table]); 00537 } 00538 00539 00540 /******************************** 00541 * 00542 * SQL engine functions (PHP simulation of SQL) - still experimental 00543 * 00544 ********************************/ 00545 00546 /** 00547 * PHP simulation of SQL "SELECT" 00548 * Yet EXPERIMENTAL! 00549 * 00550 * @param string Table name 00551 * @param array Where clause parsed into array 00552 * @return array Array of keys pointing to result rows in $this->data[$table] 00553 */ 00554 public function selectFromData($table, $where) { 00555 00556 $output = array(); 00557 if (is_array($this->data[$table])) { 00558 00559 // All keys: 00560 $OR_index = 0; 00561 00562 foreach ($where as $config) { 00563 00564 if (strtoupper($config['operator']) == 'OR') { 00565 $OR_index++; 00566 } 00567 // FIXME: unknown variable $itemKeys 00568 if (!isset($itemKeys[$OR_index])) $itemKeys[$OR_index] = array_keys($this->data[$table]); 00569 00570 $this->select_evalSingle($table, $config, $itemKeys[$OR_index]); 00571 } 00572 00573 foreach ($itemKeys as $uidKeys) { 00574 $output = array_merge($output, $uidKeys); 00575 } 00576 $output = array_unique($output); 00577 } 00578 00579 return $output; 00580 } 00581 00582 /** 00583 * Evalutaion of a WHERE-clause-array. 00584 * Yet EXPERIMENTAL 00585 * 00586 * @param string Tablename 00587 * @param array WHERE-configuration array 00588 * @param array Data array to work on. 00589 * @return void Data array passed by reference 00590 * @see selectFromData() 00591 */ 00592 public function select_evalSingle($table, $config, &$itemKeys) { 00593 $neg = preg_match('/^AND[[:space:]]+NOT$/', trim($config['operator'])); 00594 00595 if (is_array($config['sub'])) { 00596 $subSelKeys = $this->selectFromData($table, $config['sub']); 00597 if ($neg) { 00598 foreach ($itemKeys as $kk => $vv) { 00599 if (in_array($vv, $subSelKeys)) { 00600 unset($itemKeys[$kk]); 00601 } 00602 } 00603 } else { 00604 $itemKeys = array_intersect($itemKeys, $subSelKeys); 00605 } 00606 } else { 00607 $comp = strtoupper(str_replace(array(' ', "\t", "\r", "\n"), '', $config['comparator'])); 00608 $mod = strtoupper($config['modifier']); 00609 switch ($comp) { 00610 case 'NOTLIKE': 00611 case 'LIKE': 00612 $like_value = strtolower($config['value'][0]); 00613 if (substr($like_value, 0, 1) == '%') { 00614 $wildCard_begin = TRUE; 00615 $like_value = substr($like_value, 1); 00616 } 00617 if (substr($like_value, -1) == '%') { 00618 $wildCard_end = TRUE; 00619 $like_value = substr($like_value, 0, -1); 00620 } 00621 break; 00622 case 'NOTIN': 00623 case 'IN': 00624 $in_valueArray = array(); 00625 foreach ($config['value'] as $vParts) { 00626 $in_valueArray[] = (string) $vParts[0]; 00627 } 00628 break; 00629 } 00630 00631 foreach ($itemKeys as $kk => $v) { 00632 $field_value = $this->data[$table][$v][$config['field']]; 00633 00634 // Calculate it: 00635 if ($config['calc'] == '&') { 00636 $field_value &= intval($config['calc_value']); 00637 } 00638 00639 // Compare it: 00640 switch ($comp) { 00641 case '<=': 00642 $bool = $field_value <= $config['value'][0]; 00643 break; 00644 case '>=': 00645 $bool = $field_value >= $config['value'][0]; 00646 break; 00647 case '<': 00648 $bool = $field_value < $config['value'][0]; 00649 break; 00650 case '>': 00651 $bool = $field_value > $config['value'][0]; 00652 break; 00653 case '=': 00654 $bool = !strcmp($field_value, $config['value'][0]); 00655 break; 00656 case '!=': 00657 $bool = strcmp($field_value, $config['value'][0]); 00658 break; 00659 case 'NOTIN': 00660 case 'IN': 00661 $bool = in_array((string) $field_value, $in_valueArray); 00662 if ($comp == 'NOTIN') $bool = !$bool; 00663 break; 00664 case 'NOTLIKE': 00665 case 'LIKE': 00666 if (!strlen($like_value)) { 00667 $bool = TRUE; 00668 } elseif ($wildCard_begin && !$wildCard_end) { 00669 $bool = !strcmp(substr(strtolower($field_value), -strlen($like_value)), $like_value); 00670 } elseif (!$wildCard_begin && $wildCard_end) { 00671 $bool = !strcmp(substr(strtolower($field_value), 0, strlen($like_value)), $like_value); 00672 } elseif ($wildCard_begin && $wildCard_end) { 00673 $bool = strstr($field_value, $like_value); 00674 } else { 00675 $bool = !strcmp(strtolower($field_value), $like_value); 00676 } 00677 if ($comp == 'NOTLIKE') $bool = !$bool; 00678 break; 00679 default: 00680 $bool = $field_value ? TRUE : FALSE; 00681 break; 00682 } 00683 00684 // General negation: 00685 if ($neg) $bool = !$bool; 00686 00687 // Modify? 00688 switch ($mod) { 00689 case 'NOT': 00690 case '!': 00691 $bool = !$bool; 00692 break; 00693 } 00694 00695 // Action: 00696 if (!$bool) { 00697 unset($itemKeys[$kk]); 00698 } 00699 } 00700 } 00701 } 00702 00703 /** 00704 * Returning result set based on result keys, table and field list 00705 * 00706 * @param array Result keys 00707 * @param string Tablename 00708 * @param string Fieldlist (commaseparated) 00709 * @return array Result array with "rows" 00710 */ 00711 public function getResultSet($keys, $table, $fieldList) { 00712 $fields = t3lib_div::trimExplode(',', $fieldList); 00713 00714 $output = array(); 00715 foreach ($keys as $kValue) { 00716 if ($fieldList == '*') { 00717 $output[$kValue] = $this->data[$table][$kValue]; 00718 } else { 00719 foreach ($fields as $fieldName) { 00720 $output[$kValue][$fieldName] = $this->data[$table][$kValue][$fieldName]; 00721 } 00722 } 00723 } 00724 00725 return $output; 00726 } 00727 00728 00729 /************************* 00730 * 00731 * Debugging 00732 * 00733 *************************/ 00734 00735 /** 00736 * Returns the result set (in array) as HTML table. For debugging. 00737 * 00738 * @param array Result set array (array of rows) 00739 * @return string HTML table 00740 */ 00741 public function debug_printResultSet($array) { 00742 00743 if (count($array)) { 00744 $tRows = array(); 00745 $fields = array_keys(current($array)); 00746 $tCell[] = ' 00747 <td>IDX</td>'; 00748 foreach ($fields as $fieldName) { 00749 $tCell[] = ' 00750 <td>' . htmlspecialchars($fieldName) . '</td>'; 00751 } 00752 $tRows[] = '<tr>' . implode('', $tCell) . '</tr>'; 00753 00754 00755 foreach ($array as $index => $rec) { 00756 00757 $tCell = array(); 00758 $tCell[] = ' 00759 <td>' . htmlspecialchars($index) . '</td>'; 00760 foreach ($fields as $fieldName) { 00761 $tCell[] = ' 00762 <td>' . htmlspecialchars($rec[$fieldName]) . '</td>'; 00763 } 00764 $tRows[] = '<tr>' . implode('', $tCell) . '</tr>'; 00765 } 00766 00767 return '<table border="1">' . implode('', $tRows) . '</table>'; 00768 } else 'Empty resultset'; 00769 } 00770 } 00771 00772 00773 /** 00774 * PHP SQL engine, result object 00775 * 00776 * @author Kasper Skårhøj <kasperYYYY@typo3.com> 00777 * @package TYPO3 00778 * @subpackage dbal 00779 */ 00780 class tx_dbal_sqlengine_resultobj { 00781 00782 // Result array, must contain the fields in the order they were selected in the SQL statement (for sql_fetch_row()) 00783 var $result = array(); 00784 00785 var $TYPO3_DBAL_handlerType = ''; 00786 var $TYPO3_DBAL_tableList = ''; 00787 00788 00789 /** 00790 * Counting number of rows 00791 * 00792 * @return integer 00793 */ 00794 public function sql_num_rows() { 00795 return count($this->result); 00796 } 00797 00798 /** 00799 * Fetching next row in result array 00800 * 00801 * @return array Associative array 00802 */ 00803 public function sql_fetch_assoc() { 00804 $row = current($this->result); 00805 next($this->result); 00806 return $row; 00807 } 00808 00809 /** 00810 * Fetching next row, numerical indices 00811 * 00812 * @return array Numerical array 00813 */ 00814 public function sql_fetch_row() { 00815 $resultRow = $this->sql_fetch_assoc(); 00816 00817 if (is_array($resultRow)) { 00818 $numArray = array(); 00819 foreach ($resultRow as $value) { 00820 $numArray[] = $value; 00821 } 00822 return $numArray; 00823 } 00824 } 00825 00826 /** 00827 * Seeking position in result 00828 * 00829 * @param integer Position pointer. 00830 * @return boolean Returns true on success 00831 */ 00832 public function sql_data_seek($pointer) { 00833 reset($this->result); 00834 for ($a = 0; $a < $pointer; $a++) { 00835 next($this->result); 00836 } 00837 return TRUE; 00838 } 00839 00840 /** 00841 * Returning SQL field type 00842 * 00843 * @return string Blank string, not supported (it seems) 00844 */ 00845 public function sql_field_type() { 00846 return ''; 00847 } 00848 } 00849 00850 00851 if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['ext/dbal/lib/class.tx_dbal_sqlengine.php'])) { 00852 include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['ext/dbal/lib/class.tx_dbal_sqlengine.php']); 00853 } 00854 00855 ?>
1.8.0