Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.11.x will end 14 Nov 2022 (12 months plus 6 months extension).
  • Bug fixes for security issues in 3.11.x will end 13 Nov 2023 (18 months plus 12 months extension).
  • PHP version: minimum PHP 7.3.0 Note: minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is supported too.

Differences Between: [Versions 310 and 311] [Versions 311 and 400] [Versions 311 and 401] [Versions 311 and 402] [Versions 311 and 403] [Versions 39 and 311]

   1  <?php
   2  /*
   3  
   4  @version   v5.21.0  2021-02-27
   5  @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
   6  @copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
   7    Latest version is available at https://adodb.org/
   8  
   9    Released under both BSD license and Lesser GPL library license.
  10    Whenever there is any discrepancy between the two licenses,
  11    the BSD license will take precedence.
  12  
  13    Active Record implementation. Superset of Zend Framework's.
  14  
  15    Version 0.92
  16  
  17    See http://www-128.ibm.com/developerworks/java/library/j-cb03076/?ca=dgr-lnxw01ActiveRecord
  18    	 for info on Ruby on Rails Active Record implementation
  19  */
  20  
  21  
  22  global $_ADODB_ACTIVE_DBS;
  23  global $ADODB_ACTIVE_CACHESECS; // set to true to enable caching of metadata such as field info
  24  global $ACTIVE_RECORD_SAFETY; // set to false to disable safety checks
  25  global $ADODB_ACTIVE_DEFVALS; // use default values of table definition when creating new active record.
  26  
  27  // array of ADODB_Active_DB's, indexed by ADODB_Active_Record->_dbat
  28  $_ADODB_ACTIVE_DBS = array();
  29  $ACTIVE_RECORD_SAFETY = true;
  30  $ADODB_ACTIVE_DEFVALS = false;
  31  $ADODB_ACTIVE_CACHESECS = 0;
  32  
  33  class ADODB_Active_DB {
  34  	 var $db; // ADOConnection
  35  	 var $tables; // assoc array of ADODB_Active_Table objects, indexed by tablename
  36  }
  37  
  38  class ADODB_Active_Table {
  39  	 var $name; // table name
  40  	 var $flds; // assoc array of adofieldobjs, indexed by fieldname
  41  	 var $keys; // assoc array of primary keys, indexed by fieldname
  42  	 var $_created; // only used when stored as a cached file
  43  	 var $_belongsTo = array();
  44  	 var $_hasMany = array();
  45  }
  46  
  47  // $db = database connection
  48  // $index = name of index - can be associative, for an example see
  49  //    PHPLens Issue No: 17790
  50  // returns index into $_ADODB_ACTIVE_DBS
  51  function ADODB_SetDatabaseAdapter(&$db, $index=false)
  52  {
  53  	 global $_ADODB_ACTIVE_DBS;
  54  
  55  	 foreach($_ADODB_ACTIVE_DBS as $k => $d) {
  56  	 	 if($d->db === $db) {
  57  	 	 	 return $k;
  58  	 	 }
  59  	 }
  60  
  61  	 $obj = new ADODB_Active_DB();
  62  	 $obj->db = $db;
  63  	 $obj->tables = array();
  64  
  65  	 if ($index == false) {
  66  	 	 $index = sizeof($_ADODB_ACTIVE_DBS);
  67  	 }
  68  
  69  	 $_ADODB_ACTIVE_DBS[$index] = $obj;
  70  
  71  	 return sizeof($_ADODB_ACTIVE_DBS)-1;
  72  }
  73  
  74  
  75  class ADODB_Active_Record {
  76  	 static $_changeNames = true; // dynamically pluralize table names
  77  	 /*
  78  	 * Optional parameter that duplicates the ADODB_QUOTE_FIELDNAMES
  79  	 */
  80  	 static $_quoteNames = false;
  81  
  82  	 static $_foreignSuffix = '_id'; //
  83  	 var $_dbat; // associative index pointing to ADODB_Active_DB eg. $ADODB_Active_DBS[_dbat]
  84  	 var $_table; // tablename, if set in class definition then use it as table name
  85  	 var $_tableat; // associative index pointing to ADODB_Active_Table, eg $ADODB_Active_DBS[_dbat]->tables[$this->_tableat]
  86  	 var $_where; // where clause set in Load()
  87  	 var $_saved = false; // indicates whether data is already inserted.
  88  	 var $_lasterr = false; // last error message
  89  	 var $_original = false; // the original values loaded or inserted, refreshed on update
  90  
  91  	 var $foreignName; // CFR: class name when in a relationship
  92  
  93  	 var $lockMode = ' for update '; // you might want to change to
  94  
  95  	static function UseDefaultValues($bool=null)
  96  	 {
  97  	 global $ADODB_ACTIVE_DEFVALS;
  98  	 	 if (isset($bool)) {
  99  	 	 	 $ADODB_ACTIVE_DEFVALS = $bool;
 100  	 	 }
 101  	 	 return $ADODB_ACTIVE_DEFVALS;
 102  	 }
 103  
 104  	 // should be static
 105  	static function SetDatabaseAdapter(&$db, $index=false)
 106  	 {
 107  	 	 return ADODB_SetDatabaseAdapter($db, $index);
 108  	 }
 109  
 110  
 111  	public function __set($name, $value)
 112  	 {
 113  	 	 $name = str_replace(' ', '_', $name);
 114  	 	 $this->$name = $value;
 115  	 }
 116  
 117  	 // php5 constructor
 118  	function __construct($table = false, $pkeyarr=false, $db=false)
 119  	 {
 120  	 global $_ADODB_ACTIVE_DBS;
 121  
 122  	 	 if ($db == false && is_object($pkeyarr)) {
 123  	 	 	 $db = $pkeyarr;
 124  	 	 	 $pkeyarr = false;
 125  	 	 }
 126  
 127  	 	 if (!$table) {
 128  	 	 	 if (!empty($this->_table)) {
 129  	 	 	 	 $table = $this->_table;
 130  	 	 	 }
 131  	 	 	 else $table = $this->_pluralize(get_class($this));
 132  	 	 }
 133  	 	 $this->foreignName = strtolower(get_class($this)); // CFR: default foreign name
 134  	 	 if ($db) {
 135  	 	 	 $this->_dbat = ADODB_Active_Record::SetDatabaseAdapter($db);
 136  	 	 } else if (!isset($this->_dbat)) {
 137  	 	 	 if (sizeof($_ADODB_ACTIVE_DBS) == 0) {
 138  	 	 	 	 $this->Error(
 139  	 	 	 	 	 "No database connection set; use ADOdb_Active_Record::SetDatabaseAdapter(\$db)",
 140  	 	 	 	 	 'ADODB_Active_Record::__constructor'
 141  	 	 	 	 );
 142  	 	 	 }
 143  	 	 	 end($_ADODB_ACTIVE_DBS);
 144  	 	 	 $this->_dbat = key($_ADODB_ACTIVE_DBS);
 145  	 	 }
 146  
 147  	 	 $this->_table = $table;
 148  	 	 $this->_tableat = $table; # reserved for setting the assoc value to a non-table name, eg. the sql string in future
 149  
 150  	 	 $this->UpdateActiveTable($pkeyarr);
 151  	 }
 152  
 153  	function __wakeup()
 154  	 {
 155    	 	 $class = get_class($this);
 156    	 	 new $class;
 157  	 }
 158  
 159  	function _pluralize($table)
 160  	 {
 161  	 	 if (!ADODB_Active_Record::$_changeNames) {
 162  	 	 	 return $table;
 163  	 	 }
 164  
 165  	 	 $ut = strtoupper($table);
 166  	 	 $len = strlen($table);
 167  	 	 $lastc = $ut[$len-1];
 168  	 	 $lastc2 = substr($ut,$len-2);
 169  	 	 switch ($lastc) {
 170  	 	 case 'S':
 171  	 	 	 return $table.'es';
 172  	 	 case 'Y':
 173  	 	 	 return substr($table,0,$len-1).'ies';
 174  	 	 case 'X':
 175  	 	 	 return $table.'es';
 176  	 	 case 'H':
 177  	 	 	 if ($lastc2 == 'CH' || $lastc2 == 'SH') {
 178  	 	 	 	 return $table.'es';
 179  	 	 	 }
 180  	 	 default:
 181  	 	 	 return $table.'s';
 182  	 	 }
 183  	 }
 184  
 185  	 // CFR Lamest singular inflector ever - @todo Make it real!
 186  	 // Note: There is an assumption here...and it is that the argument's length >= 4
 187  	function _singularize($tables)
 188  	 {
 189  
 190  	 	 if (!ADODB_Active_Record::$_changeNames) {
 191  	 	 	 return $table;
 192  	 	 }
 193  
 194  	 	 $ut = strtoupper($tables);
 195  	 	 $len = strlen($tables);
 196  	 	 if($ut[$len-1] != 'S') {
 197  	 	 	 return $tables; // I know...forget oxen
 198  	 	 }
 199  	 	 if($ut[$len-2] != 'E') {
 200  	 	 	 return substr($tables, 0, $len-1);
 201  	 	 }
 202  	 	 switch($ut[$len-3]) {
 203  	 	 	 case 'S':
 204  	 	 	 case 'X':
 205  	 	 	 	 return substr($tables, 0, $len-2);
 206  	 	 	 case 'I':
 207  	 	 	 	 return substr($tables, 0, $len-3) . 'y';
 208  	 	 	 case 'H';
 209  	 	 	 	 if($ut[$len-4] == 'C' || $ut[$len-4] == 'S') {
 210  	 	 	 	 	 return substr($tables, 0, $len-2);
 211  	 	 	 	 }
 212  	 	 	 default:
 213  	 	 	 	 return substr($tables, 0, $len-1); // ?
 214  	 	 }
 215  	 }
 216  
 217  	function hasMany($foreignRef, $foreignKey = false, $foreignClass = 'ADODB_Active_Record')
 218  	 {
 219  	 	 $ar = new $foreignClass($foreignRef);
 220  	 	 $ar->foreignName = $foreignRef;
 221  	 	 $ar->UpdateActiveTable();
 222  	 	 $ar->foreignKey = ($foreignKey) ? $foreignKey : $foreignRef.ADODB_Active_Record::$_foreignSuffix;
 223  	 	 $table =& $this->TableInfo();
 224  	 	 $table->_hasMany[$foreignRef] = $ar;
 225  	 #	 $this->$foreignRef = $this->_hasMany[$foreignRef]; // WATCHME Removed assignment by ref. to please __get()
 226  	 }
 227  
 228  	 // use when you don't want ADOdb to auto-pluralize tablename
 229  	static function TableHasMany($table, $foreignRef, $foreignKey = false, $foreignClass = 'ADODB_Active_Record')
 230  	 {
 231  	 	 $ar = new ADODB_Active_Record($table);
 232  	 	 $ar->hasMany($foreignRef, $foreignKey, $foreignClass);
 233  	 }
 234  
 235  	 // use when you don't want ADOdb to auto-pluralize tablename
 236  	static function TableKeyHasMany($table, $tablePKey, $foreignRef, $foreignKey = false, $foreignClass = 'ADODB_Active_Record')
 237  	 {
 238  	 	 if (!is_array($tablePKey)) {
 239  	 	 	 $tablePKey = array($tablePKey);
 240  	 	 }
 241  	 	 $ar = new ADODB_Active_Record($table,$tablePKey);
 242  	 	 $ar->hasMany($foreignRef, $foreignKey, $foreignClass);
 243  	 }
 244  
 245  
 246  	 // use when you want ADOdb to auto-pluralize tablename for you. Note that the class must already be defined.
 247  	 // e.g. class Person will generate relationship for table Persons
 248  	static function ClassHasMany($parentclass, $foreignRef, $foreignKey = false, $foreignClass = 'ADODB_Active_Record')
 249  	 {
 250  	 	 $ar = new $parentclass();
 251  	 	 $ar->hasMany($foreignRef, $foreignKey, $foreignClass);
 252  	 }
 253  
 254  
 255  	function belongsTo($foreignRef,$foreignKey=false, $parentKey='', $parentClass = 'ADODB_Active_Record')
 256  	 {
 257  	 	 global $inflector;
 258  
 259  	 	 $ar = new $parentClass($this->_pluralize($foreignRef));
 260  	 	 $ar->foreignName = $foreignRef;
 261  	 	 $ar->parentKey = $parentKey;
 262  	 	 $ar->UpdateActiveTable();
 263  	 	 $ar->foreignKey = ($foreignKey) ? $foreignKey : $foreignRef.ADODB_Active_Record::$_foreignSuffix;
 264  
 265  	 	 $table =& $this->TableInfo();
 266  	 	 $table->_belongsTo[$foreignRef] = $ar;
 267  	 #	 $this->$foreignRef = $this->_belongsTo[$foreignRef];
 268  	 }
 269  
 270  	static function ClassBelongsTo($class, $foreignRef, $foreignKey=false, $parentKey='', $parentClass = 'ADODB_Active_Record')
 271  	 {
 272  	 	 $ar = new $class();
 273  	 	 $ar->belongsTo($foreignRef, $foreignKey, $parentKey, $parentClass);
 274  	 }
 275  
 276  	static function TableBelongsTo($table, $foreignRef, $foreignKey=false, $parentKey='', $parentClass = 'ADODB_Active_Record')
 277  	 {
 278  	 	 $ar = new ADOdb_Active_Record($table);
 279  	 	 $ar->belongsTo($foreignRef, $foreignKey, $parentKey, $parentClass);
 280  	 }
 281  
 282  	static function TableKeyBelongsTo($table, $tablePKey, $foreignRef, $foreignKey=false, $parentKey='', $parentClass = 'ADODB_Active_Record')
 283  	 {
 284  	 	 if (!is_array($tablePKey)) {
 285  	 	 	 $tablePKey = array($tablePKey);
 286  	 	 }
 287  	 	 $ar = new ADOdb_Active_Record($table, $tablePKey);
 288  	 	 $ar->belongsTo($foreignRef, $foreignKey, $parentKey, $parentClass);
 289  	 }
 290  
 291  
 292  	 /**
 293  	  * __get Access properties - used for lazy loading
 294  	  *
 295  	  * @param mixed $name
 296  	  * @access protected
 297  	  * @return mixed
 298  	  */
 299  	 function __get($name)
 300  	 {
 301  	 	 return $this->LoadRelations($name, '', -1, -1);
 302  	 }
 303  
 304  	 /**
 305  	  * @param string $name
 306  	  * @param string $whereOrderBy : eg. ' AND field1 = value ORDER BY field2'
 307  	  * @param offset
 308  	  * @param limit
 309  	  * @return mixed
 310  	  */
 311  	function LoadRelations($name, $whereOrderBy='', $offset=-1,$limit=-1)
 312  	 {
 313  	 	 $extras = array();
 314  	 	 $table = $this->TableInfo();
 315  	 	 if ($limit >= 0) {
 316  	 	 	 $extras['limit'] = $limit;
 317  	 	 }
 318  	 	 if ($offset >= 0) {
 319  	 	 	 $extras['offset'] = $offset;
 320  	 	 }
 321  
 322  	 	 if (strlen($whereOrderBy)) {
 323  	 	 	 if (!preg_match('/^[ \n\r]*AND/i', $whereOrderBy)) {
 324  	 	 	 	 if (!preg_match('/^[ \n\r]*ORDER[ \n\r]/i', $whereOrderBy)) {
 325  	 	 	 	 	 $whereOrderBy = 'AND ' . $whereOrderBy;
 326  	 	 	 	 }
 327  	 	 	 }
 328  	 	 }
 329  
 330  	 	 if(!empty($table->_belongsTo[$name])) {
 331  	 	 	 $obj = $table->_belongsTo[$name];
 332  	 	 	 $columnName = $obj->foreignKey;
 333  	 	 	 if(empty($this->$columnName)) {
 334  	 	 	 	 $this->$name = null;
 335  	 	 	 }
 336  	 	 	 else {
 337  	 	 	 	 if ($obj->parentKey) {
 338  	 	 	 	 	 $key = $obj->parentKey;
 339  	 	 	 	 }
 340  	 	 	 	 else {
 341  	 	 	 	 	 $key = reset($table->keys);
 342  	 	 	 	 }
 343  
 344  	 	 	 	 $arrayOfOne = $obj->Find($key.'='.$this->$columnName.' '.$whereOrderBy,false,false,$extras);
 345  	 	 	 	 if ($arrayOfOne) {
 346  	 	 	 	 	 $this->$name = $arrayOfOne[0];
 347  	 	 	 	 	 return $arrayOfOne[0];
 348  	 	 	 	 }
 349  	 	 	 }
 350  	 	 }
 351  	 	 if(!empty($table->_hasMany[$name])) {
 352  	 	 	 $obj = $table->_hasMany[$name];
 353  	 	 	 $key = reset($table->keys);
 354  	 	 	 $id = @$this->$key;
 355  	 	 	 if (!is_numeric($id)) {
 356  	 	 	 	 $db = $this->DB();
 357  	 	 	 	 $id = $db->qstr($id);
 358  	 	 	 }
 359  	 	 	 $objs = $obj->Find($obj->foreignKey.'='.$id. ' '.$whereOrderBy,false,false,$extras);
 360  	 	 	 if (!$objs) {
 361  	 	 	 	 $objs = array();
 362  	 	 	 }
 363  	 	 	 $this->$name = $objs;
 364  	 	 	 return $objs;
 365  	 	 }
 366  
 367  	 	 return array();
 368  	 }
 369  	 //////////////////////////////////
 370  
 371  	 // update metadata
 372  	function UpdateActiveTable($pkeys=false,$forceUpdate=false)
 373  	 {
 374  	 global $_ADODB_ACTIVE_DBS , $ADODB_CACHE_DIR, $ADODB_ACTIVE_CACHESECS;
 375  	 global $ADODB_ACTIVE_DEFVALS,$ADODB_FETCH_MODE;
 376  
 377  	 	 $activedb = $_ADODB_ACTIVE_DBS[$this->_dbat];
 378  
 379  	 	 $table = $this->_table;
 380  	 	 $tables = $activedb->tables;
 381  	 	 $tableat = $this->_tableat;
 382  	 	 if (!$forceUpdate && !empty($tables[$tableat])) {
 383  
 384  	 	 	 $acttab = $tables[$tableat];
 385  	 	 	 foreach($acttab->flds as $name => $fld) {
 386  	 	 	 	 if ($ADODB_ACTIVE_DEFVALS && isset($fld->default_value)) {
 387  	 	 	 	 	 $this->$name = $fld->default_value;
 388  	 	 	 	 }
 389  	 	 	 	 else {
 390  	 	 	 	 	 $this->$name = null;
 391  	 	 	 	 }
 392  	 	 	 }
 393  	 	 	 return;
 394  	 	 }
 395  	 	 $db = $activedb->db;
 396  	 	 $fname = $ADODB_CACHE_DIR . '/adodb_' . $db->databaseType . '_active_'. $table . '.cache';
 397  	 	 if (!$forceUpdate && $ADODB_ACTIVE_CACHESECS && $ADODB_CACHE_DIR && file_exists($fname)) {
 398  	 	 	 $fp = fopen($fname,'r');
 399  	 	 	 @flock($fp, LOCK_SH);
 400  	 	 	 $acttab = unserialize(fread($fp,100000));
 401  	 	 	 fclose($fp);
 402  	 	 	 if ($acttab->_created + $ADODB_ACTIVE_CACHESECS - (abs(rand()) % 16) > time()) {
 403  	 	 	 	 // abs(rand()) randomizes deletion, reducing contention to delete/refresh file
 404  	 	 	 	 // ideally, you should cache at least 32 secs
 405  
 406  	 	 	 	 foreach($acttab->flds as $name => $fld) {
 407  	 	 	 	 	 if ($ADODB_ACTIVE_DEFVALS && isset($fld->default_value)) {
 408  	 	 	 	 	 	 $this->$name = $fld->default_value;
 409  	 	 	 	 	 }
 410  	 	 	 	 	 else {
 411  	 	 	 	 	 	 $this->$name = null;
 412  	 	 	 	 	 }
 413  	 	 	 	 }
 414  
 415  	 	 	 	 $activedb->tables[$table] = $acttab;
 416  
 417  	 	 	 	 //if ($db->debug) ADOConnection::outp("Reading cached active record file: $fname");
 418  	 	 	   	 return;
 419  	 	 	 } else if ($db->debug) {
 420  	 	 	 	 ADOConnection::outp("Refreshing cached active record file: $fname");
 421  	 	 	 }
 422  	 	 }
 423  	 	 $activetab = new ADODB_Active_Table();
 424  	 	 $activetab->name = $table;
 425  
 426  	 	 $save = $ADODB_FETCH_MODE;
 427  	 	 $ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
 428  	 	 if ($db->fetchMode !== false) {
 429  	 	 	 $savem = $db->SetFetchMode(false);
 430  	 	 }
 431  
 432  	 	 $cols = $db->MetaColumns($table);
 433  
 434  	 	 if (isset($savem)) {
 435  	 	 	 $db->SetFetchMode($savem);
 436  	 	 }
 437  	 	 $ADODB_FETCH_MODE = $save;
 438  
 439  	 	 if (!$cols) {
 440  	 	 	 $this->Error("Invalid table name: $table",'UpdateActiveTable');
 441  	 	 	 return false;
 442  	 	 }
 443  	 	 $fld = reset($cols);
 444  	 	 if (!$pkeys) {
 445  	 	 	 if (isset($fld->primary_key)) {
 446  	 	 	 	 $pkeys = array();
 447  	 	 	 	 foreach($cols as $name => $fld) {
 448  	 	 	 	 	 if (!empty($fld->primary_key)) {
 449  	 	 	 	 	 	 $pkeys[] = $name;
 450  	 	 	 	 	 }
 451  	 	 	 	 }
 452  	 	 	 } else
 453  	 	 	 	 $pkeys = $this->GetPrimaryKeys($db, $table);
 454  	 	 }
 455  	 	 if (empty($pkeys)) {
 456  	 	 	 $this->Error("No primary key found for table $table",'UpdateActiveTable');
 457  	 	 	 return false;
 458  	 	 }
 459  
 460  	 	 $attr = array();
 461  	 	 $keys = array();
 462  
 463  	 	 switch (ADODB_ASSOC_CASE) {
 464  	 	 case ADODB_ASSOC_CASE_LOWER:
 465  	 	 	 foreach($cols as $name => $fldobj) {
 466  	 	 	 	 $name = strtolower($name);
 467  	 	 	 	 if ($ADODB_ACTIVE_DEFVALS && isset($fldobj->default_value)) {
 468  	 	 	 	 	 $this->$name = $fldobj->default_value;
 469  	 	 	 	 }
 470  	 	 	 	 else {
 471  	 	 	 	 	 $this->$name = null;
 472  	 	 	 	 }
 473  	 	 	 	 $attr[$name] = $fldobj;
 474  	 	 	 }
 475  	 	 	 foreach($pkeys as $k => $name) {
 476  	 	 	 	 $keys[strtolower($name)] = strtolower($name);
 477  	 	 	 }
 478  	 	 	 break;
 479  
 480  	 	 case ADODB_ASSOC_CASE_UPPER:
 481  	 	 	 foreach($cols as $name => $fldobj) {
 482  	 	 	 	 $name = strtoupper($name);
 483  
 484  	 	 	 	 if ($ADODB_ACTIVE_DEFVALS && isset($fldobj->default_value)) {
 485  	 	 	 	 	 $this->$name = $fldobj->default_value;
 486  	 	 	 	 }
 487  	 	 	 	 else {
 488  	 	 	 	 	 $this->$name = null;
 489  	 	 	 	 }
 490  	 	 	 	 $attr[$name] = $fldobj;
 491  	 	 	 }
 492  
 493  	 	 	 foreach($pkeys as $k => $name) {
 494  	 	 	 	 $keys[strtoupper($name)] = strtoupper($name);
 495  	 	 	 }
 496  	 	 	 break;
 497  	 	 default:
 498  	 	 	 foreach($cols as $name => $fldobj) {
 499  
 500  	 	 	 	 if ($ADODB_ACTIVE_DEFVALS && isset($fldobj->default_value)) {
 501  	 	 	 	 	 $this->$name = $fldobj->default_value;
 502  	 	 	 	 }
 503  	 	 	 	 else {
 504  	 	 	 	 	 $this->$name = null;
 505  	 	 	 	 }
 506  	 	 	 	 $attr[$name] = $fldobj;
 507  	 	 	 }
 508  	 	 	 foreach($pkeys as $k => $name) {
 509  	 	 	 	 $keys[$name] = $cols[strtoupper($name)]->name;
 510  	 	 	 }
 511  	 	 	 break;
 512  	 	 }
 513  
 514  	 	 $activetab->keys = $keys;
 515  	 	 $activetab->flds = $attr;
 516  
 517  	 	 if ($ADODB_ACTIVE_CACHESECS && $ADODB_CACHE_DIR) {
 518  	 	 	 $activetab->_created = time();
 519  	 	 	 $s = serialize($activetab);
 520  	 	 	 if (!function_exists('adodb_write_file')) {
 521  	 	 	 	 include_once (ADODB_DIR.'/adodb-csvlib.inc.php');
 522  	 	 	 }
 523  	 	 	 adodb_write_file($fname,$s);
 524  	 	 }
 525  	 	 if (isset($activedb->tables[$table])) {
 526  	 	 	 $oldtab = $activedb->tables[$table];
 527  
 528  	 	 	 if ($oldtab) {
 529  	 	 	 	 $activetab->_belongsTo = $oldtab->_belongsTo;
 530  	 	 	 	 $activetab->_hasMany = $oldtab->_hasMany;
 531  	 	 	 }
 532  	 	 }
 533  	 	 $activedb->tables[$table] = $activetab;
 534  	 }
 535  
 536  	function GetPrimaryKeys(&$db, $table)
 537  	 {
 538  	 	 return $db->MetaPrimaryKeys($table);
 539  	 }
 540  
 541  	 // error handler for both PHP4+5.
 542  	function Error($err,$fn)
 543  	 {
 544  	 global $_ADODB_ACTIVE_DBS;
 545  
 546  	 	 $fn = get_class($this).'::'.$fn;
 547  	 	 $this->_lasterr = $fn.': '.$err;
 548  
 549  	 	 if ($this->_dbat < 0) {
 550  	 	 	 $db = false;
 551  	 	 }
 552  	 	 else {
 553  	 	 	 $activedb = $_ADODB_ACTIVE_DBS[$this->_dbat];
 554  	 	 	 $db = $activedb->db;
 555  	 	 }
 556  
 557  	 	 if (function_exists('adodb_throw')) {
 558  	 	 	 if (!$db) {
 559  	 	 	 	 adodb_throw('ADOdb_Active_Record', $fn, -1, $err, 0, 0, false);
 560  	 	 	 }
 561  	 	 	 else {
 562  	 	 	 	 adodb_throw($db->databaseType, $fn, -1, $err, 0, 0, $db);
 563  	 	 	 }
 564  	 	 } else {
 565  	 	 	 if (!$db || $db->debug) {
 566  	 	 	 	 ADOConnection::outp($this->_lasterr);
 567  	 	 	 }
 568  	 	 }
 569  
 570  	 }
 571  
 572  	 // return last error message
 573  	function ErrorMsg()
 574  	 {
 575  	 	 if (!function_exists('adodb_throw')) {
 576  	 	 	 if ($this->_dbat < 0) {
 577  	 	 	 	 $db = false;
 578  	 	 	 }
 579  	 	 	 else {
 580  	 	 	 	 $db = $this->DB();
 581  	 	 	 }
 582  
 583  	 	 	 // last error could be database error too
 584  	 	 	 if ($db && $db->ErrorMsg()) {
 585  	 	 	 	 return $db->ErrorMsg();
 586  	 	 	 }
 587  	 	 }
 588  	 	 return $this->_lasterr;
 589  	 }
 590  
 591  	function ErrorNo()
 592  	 {
 593  	 	 if ($this->_dbat < 0) {
 594  	 	 	 return -9999; // no database connection...
 595  	 	 }
 596  	 	 $db = $this->DB();
 597  
 598  	 	 return (int) $db->ErrorNo();
 599  	 }
 600  
 601  
 602  	 // retrieve ADOConnection from _ADODB_Active_DBs
 603  	 function DB()
 604  	 {
 605  	 global $_ADODB_ACTIVE_DBS;
 606  
 607  	 	 if ($this->_dbat < 0) {
 608  	 	 	 $false = false;
 609  	 	 	 $this->Error("No database connection set: use ADOdb_Active_Record::SetDatabaseAdaptor(\$db)", "DB");
 610  	 	 	 return $false;
 611  	 	 }
 612  	 	 $activedb = $_ADODB_ACTIVE_DBS[$this->_dbat];
 613  	 	 $db = $activedb->db;
 614  	 	 return $db;
 615  	 }
 616  
 617  	 // retrieve ADODB_Active_Table
 618  	 function &TableInfo()
 619  	 {
 620  	 global $_ADODB_ACTIVE_DBS;
 621  	 	 $activedb = $_ADODB_ACTIVE_DBS[$this->_dbat];
 622  	 	 $table = $activedb->tables[$this->_tableat];
 623  	 	 return $table;
 624  	 }
 625  
 626  
 627  	 // I have an ON INSERT trigger on a table that sets other columns in the table.
 628  	 // So, I find that for myTable, I want to reload an active record after saving it. -- Malcolm Cook
 629  	function Reload()
 630  	 {
 631  	 	 $db = $this->DB();
 632  	 	 if (!$db) {
 633  	 	 	 return false;
 634  	 	 }
 635  	 	 $table = $this->TableInfo();
 636  	 	 $where = $this->GenWhere($db, $table);
 637  	 	 return($this->Load($where));
 638  	 }
 639  
 640  
 641  	 // set a numeric array (using natural table field ordering) as object properties
 642  	function Set(&$row)
 643  	 {
 644  	 global $ACTIVE_RECORD_SAFETY;
 645  
 646  	 	 $db = $this->DB();
 647  
 648  	 	 if (!$row) {
 649  	 	 	 $this->_saved = false;
 650  	 	 	 return false;
 651  	 	 }
 652  
 653  	 	 $this->_saved = true;
 654  
 655  	 	 $table = $this->TableInfo();
 656  	 	 if ($ACTIVE_RECORD_SAFETY && sizeof($table->flds) != sizeof($row)) {
 657  	 	 	 # <AP>
 658  	 	 	 $bad_size = TRUE;
 659  	 	 	 if (sizeof($row) == 2 * sizeof($table->flds)) {
 660  	 	 	 	 // Only keep string keys
 661  	 	 	 	 $keys = array_filter(array_keys($row), 'is_string');
 662  	 	 	 	 if (sizeof($keys) == sizeof($table->flds)) {
 663  	 	 	 	 	 $bad_size = FALSE;
 664  	 	 	 	 }
 665  	 	 	 }
 666  	 	 	 if ($bad_size) {
 667  	 	 	 $this->Error("Table structure of $this->_table has changed","Load");
 668  	 	 	 return false;
 669  	 	 }
 670  	 	 	 # </AP>
 671  	 	 }
 672  	 	 else
 673  	 	 	 $keys = array_keys($row);
 674  
 675  	 	 # <AP>
 676  	 	 reset($keys);
 677  	 	 $this->_original = array();
 678  	 	 foreach($table->flds as $name=>$fld) {
 679  	 	 	 $value = $row[current($keys)];
 680  	 	 	 $this->$name = $value;
 681  	 	 	 $this->_original[] = $value;
 682  	 	 	 next($keys);
 683  	 	 }
 684  
 685  	 	 # </AP>
 686  	 	 return true;
 687  	 }
 688  
 689  	 // get last inserted id for INSERT
 690  	function LastInsertID(&$db,$fieldname)
 691  	 {
 692  	 	 if ($db->hasInsertID) {
 693  	 	 	 $val = $db->Insert_ID($this->_table,$fieldname);
 694  	 	 }
 695  	 	 else {
 696  	 	 	 $val = false;
 697  	 	 }
 698  
 699  	 	 if (is_null($val) || $val === false)
 700  	 	 {
 701  	 	 	 $SQL = sprintf("SELECT MAX(%s) FROM %s",
 702  	 	 	 	 	 	    $this->nameQuoter($db,$fieldname),
 703  	 	 	 	 	 	    $this->nameQuoter($db,$this->_table)
 704  	 	 	 	 	 	    );
 705  	 	 	 // this might not work reliably in multi-user environment
 706  	 	 	 return $db->GetOne($SQL);
 707  	 	 }
 708  	 	 return $val;
 709  	 }
 710  
 711  	 // quote data in where clause
 712  	function doquote(&$db, $val,$t)
 713  	 {
 714  	 	 switch($t) {
 715  	 	 case 'L':
 716  	 	 	 if (strpos($db->databaseType,'postgres') !== false) {
 717  	 	 	 	 return $db->qstr($val);
 718  	 	 	 }
 719  	 	 case 'D':
 720  	 	 case 'T':
 721  	 	 	 if (empty($val)) {
 722  	 	 	 	 return 'null';
 723  	 	 	 }
 724  	 	 case 'B':
 725  	 	 case 'N':
 726  	 	 case 'C':
 727  	 	 case 'X':
 728  	 	 	 if (is_null($val)) {
 729  	 	 	 	 return 'null';
 730  	 	 	 }
 731  
 732  	 	 	 if (strlen($val)>0 &&
 733  	 	 	 	 (strncmp($val,"'",1) != 0 || substr($val,strlen($val)-1,1) != "'")
 734  	 	 	 ) {
 735  	 	 	 	 return $db->qstr($val);
 736  	 	 	 	 break;
 737  	 	 	 }
 738  	 	 default:
 739  	 	 	 return $val;
 740  	 	 	 break;
 741  	 	 }
 742  	 }
 743  
 744  	 // generate where clause for an UPDATE/SELECT
 745  	function GenWhere(&$db, &$table)
 746  	 {
 747  	 	 $keys = $table->keys;
 748  	 	 $parr = array();
 749  
 750  	 	 foreach($keys as $k) {
 751  	 	 	 $f = $table->flds[$k];
 752  	 	 	 if ($f) {
 753  	 	 	 	 $columnName = $this->nameQuoter($db,$k);
 754  	 	 	 	 $parr[] = $columnName.' = '.$this->doquote($db,$this->$k,$db->MetaType($f->type));
 755  	 	 	 }
 756  	 	 }
 757  	 	 return implode(' AND ', $parr);
 758  	 }
 759  
 760  
 761  	function _QName($n,$db=false)
 762  	 {
 763  	 	 if (!ADODB_Active_Record::$_quoteNames) {
 764  	 	 	 return $n;
 765  	 	 }
 766  	 	 if (!$db) {
 767  	 	 	 $db = $this->DB();
 768  	 	 	 if (!$db) {
 769  	 	 	 	 return false;
 770  	 	 	 }
 771  	 	 }
 772  	 	 return $db->nameQuote.$n.$db->nameQuote;
 773  	 }
 774  
 775  	 //------------------------------------------------------------ Public functions below
 776  
 777  	function Load($where=null,$bindarr=false, $lock = false)
 778  	 {
 779  	 	 global $ADODB_FETCH_MODE;
 780  
 781  	 	 $db = $this->DB();
 782  	 	 if (!$db) {
 783  	 	 	 return false;
 784  	 	 }
 785  	 	 $this->_where = $where;
 786  
 787  	 	 $save = $ADODB_FETCH_MODE;
 788  	 	 $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
 789  	 	 if ($db->fetchMode !== false) {
 790  	 	 	 $savem = $db->SetFetchMode(false);
 791  	 	 }
 792  
 793  	 	 $qry = sprintf("SELECT * FROM %s",
 794  	 	 	 	 	    $this->nameQuoter($db,$this->_table)
 795  	 	 	 	 	    );
 796  
 797  	 	 if($where) {
 798  	 	 	 $qry .= ' WHERE '.$where;
 799  	 	 }
 800  	 	 if ($lock) {
 801  	 	 	 $qry .= $this->lockMode;
 802  	 	 }
 803  
 804  	 	 $row = $db->GetRow($qry,$bindarr);
 805  
 806  	 	 if (isset($savem)) {
 807  	 	 	 $db->SetFetchMode($savem);
 808  	 	 }
 809  	 	 $ADODB_FETCH_MODE = $save;
 810  
 811  	 	 return $this->Set($row);
 812  	 }
 813  
 814  	function LoadLocked($where=null, $bindarr=false)
 815  	 {
 816  	 	 $this->Load($where,$bindarr,true);
 817  	 }
 818  
 819  	 # useful for multiple record inserts
 820  	 # see PHPLens Issue No: 17795
 821  	function Reset()
 822  	 {
 823  	 	 $this->_where=null;
 824  	 	 $this->_saved = false;
 825  	 	 $this->_lasterr = false;
 826  	 	 $this->_original = false;
 827  	 	 $vars=get_object_vars($this);
 828  	 	 foreach($vars as $k=>$v){
 829  	 	 	 if(substr($k,0,1)!=='_'){
 830  	 	 	 	 $this->{$k}=null;
 831  	 	 	 }
 832  	 	 }
 833  	 	 $this->foreignName=strtolower(get_class($this));
 834  	 	 return true;
 835  	 }
 836  
 837  	 // false on error
 838  	function Save()
 839  	 {
 840  	 	 if ($this->_saved) {
 841  	 	 	 $ok = $this->Update();
 842  	 	 }
 843  	 	 else {
 844  	 	 	 $ok = $this->Insert();
 845  	 	 }
 846  
 847  	 	 return $ok;
 848  	 }
 849  
 850  
 851  	 // false on error
 852  	function Insert()
 853  	 {
 854  	 	 $db = $this->DB();
 855  	 	 if (!$db) {
 856  	 	 	 return false;
 857  	 	 }
 858  	 	 $cnt = 0;
 859  	 	 $table = $this->TableInfo();
 860  
 861  	 	 $valarr = array();
 862  	 	 $names = array();
 863  	 	 $valstr = array();
 864  
 865  	 	 foreach($table->flds as $name=>$fld) {
 866  	 	 	 $val = $this->$name;
 867  	 	 	 if(!is_array($val) || !is_null($val) || !array_key_exists($name, $table->keys)) {
 868  	 	 	 	 $valarr[] = $val;
 869  	 	 	 	 $names[] = $this->nameQuoter($db,$name);
 870  	 	 	 	 $valstr[] = $db->Param($cnt);
 871  	 	 	 	 $cnt += 1;
 872  	 	 	 }
 873  	 	 }
 874  
 875  	 	 if (empty($names)){
 876  	 	 	 foreach($table->flds as $name=>$fld) {
 877  	 	 	 	 $valarr[] = null;
 878  	 	 	 	 $names[] = $this->nameQuoter($db,$name);
 879  	 	 	 	 $valstr[] = $db->Param($cnt);
 880  	 	 	 	 $cnt += 1;
 881  	 	 	 }
 882  	 	 }
 883  	 	 
 884  	 	 $tableName = $this->nameQuoter($db,$this->_table);
 885  	 	 $sql = sprintf('INSERT INTO %s (%s) VALUES (%s)',
 886  	 	 	 	 	    $tableName,
 887  	 	 	 	 	    implode(',',$names),
 888  	 	 	 	 	    implode(',',$valstr)
 889  	 	 	 	 	    );
 890  	 	 $ok = $db->Execute($sql,$valarr);
 891  
 892  	 	 if ($ok) {
 893  	 	 	 $this->_saved = true;
 894  	 	 	 $autoinc = false;
 895  	 	 	 foreach($table->keys as $k) {
 896  	 	 	 	 if (is_null($this->$k)) {
 897  	 	 	 	 	 $autoinc = true;
 898  	 	 	 	 	 break;
 899  	 	 	 	 }
 900  	 	 	 }
 901  	 	 	 if ($autoinc && sizeof($table->keys) == 1) {
 902  	 	 	 	 $k = reset($table->keys);
 903  	 	 	 	 $this->$k = $this->LastInsertID($db,$k);
 904  	 	 	 }
 905  	 	 }
 906  
 907  	 	 $this->_original = $valarr;
 908  	 	 return !empty($ok);
 909  	 }
 910  
 911  	function Delete()
 912  	 {
 913  	 	 $db = $this->DB();
 914  	 	 if (!$db) {
 915  	 	 	 return false;
 916  	 	 }
 917  	 	 $table = $this->TableInfo();
 918  
 919  	 	 $where = $this->GenWhere($db,$table);
 920  
 921  	 	 $tableName = $this->nameQuoter($db,$this->_table);
 922  	 	 
 923  	 	 $sql = sprintf('DELETE FROM %s WHERE %s',
 924  	 	 	 	 	    $tableName,
 925  	 	 	 	 	    $where
 926  	 	 	 	 	    );
 927  
 928  	 	 $ok = $db->Execute($sql);
 929  
 930  	 	 return $ok ? true : false;
 931  	 }
 932  
 933  	 // returns an array of active record objects
 934  	function Find($whereOrderBy,$bindarr=false,$pkeysArr=false,$extra=array())
 935  	 {
 936  	 	 $db = $this->DB();
 937  	 	 if (!$db || empty($this->_table)) {
 938  	 	 	 return false;
 939  	 	 }
 940  	 	 $arr = $db->GetActiveRecordsClass(get_class($this),$this->_table, $whereOrderBy,$bindarr,$pkeysArr,$extra);
 941  	 	 return $arr;
 942  	 }
 943  
 944  	 // returns 0 on error, 1 on update, 2 on insert
 945  	function Replace()
 946  	 {
 947  	 	 $db = $this->DB();
 948  	 	 if (!$db) {
 949  	 	 	 return false;
 950  	 	 }
 951  	 	 $table = $this->TableInfo();
 952  
 953  	 	 $pkey = $table->keys;
 954  
 955  	 	 foreach($table->flds as $name=>$fld) {
 956  	 	 	 $val = $this->$name;
 957  	 	 	 /*
 958  	 	 	 if (is_null($val)) {
 959  	 	 	 	 if (isset($fld->not_null) && $fld->not_null) {
 960  	 	 	 	 	 if (isset($fld->default_value) && strlen($fld->default_value)) {
 961  	 	 	 	 	 	 continue;
 962  	 	 	 	 	 }
 963  	 	 	 	 	 else {
 964  	 	 	 	 	 	 $this->Error("Cannot update null into $name","Replace");
 965  	 	 	 	 	 	 return false;
 966  	 	 	 	 	 }
 967  	 	 	 	 }
 968  	 	 	 }*/
 969  	 	 	 if (is_null($val) && !empty($fld->auto_increment)) {
 970  	 	 	 	 continue;
 971  	 	 	 }
 972  
 973  	 	 	 if (is_array($val)) {
 974  	 	 	 	 continue;
 975  	 	 	 }
 976  
 977  	 	 	 $t = $db->MetaType($fld->type);
 978  	 	 	 $arr[$name] = $this->doquote($db,$val,$t);
 979  	 	 	 $valarr[] = $val;
 980  	 	 }
 981  
 982  	 	 if (!is_array($pkey)) {
 983  	 	 	 $pkey = array($pkey);
 984  	 	 }
 985  
 986  	 	 switch (ADODB_ASSOC_CASE) {
 987  	 	 	 case ADODB_ASSOC_CASE_LOWER:
 988  	 	 	 	 foreach ($pkey as $k => $v) {
 989  	 	 	 	 	 $pkey[$k] = strtolower($v);
 990  	 	 	 	 }
 991  	 	 	 	 break;
 992  	 	 	 case ADODB_ASSOC_CASE_UPPER:
 993  	 	 	 	 foreach ($pkey as $k => $v) {
 994  	 	 	 	 	 $pkey[$k] = strtoupper($v);
 995  	 	 	 	 }
 996  	 	 	 	 break;
 997  	 	 }
 998  	 	 
 999  	 	 $newArr = array();
1000  	 	 foreach($arr as $k=>$v)
1001  	 	 	 $newArr[$this->nameQuoter($db,$k)] = $v;
1002  	 	 $arr = $newArr;
1003  	 	 
1004  	 	 $newPkey = array();
1005  	 	 foreach($pkey as $k=>$v)
1006  	 	 	 $newPkey[$k] = $this->nameQuoter($db,$v);
1007  	 	 $pkey = $newPkey;
1008  	 	 
1009  	 	 $tableName = $this->nameQuoter($db,$this->_table);
1010  	 	 
1011  	 	 $ok = $db->Replace($tableName,$arr,$pkey);
1012  	 	 if ($ok) {
1013  	 	 	 $this->_saved = true; // 1= update 2=insert
1014  	 	 	 if ($ok == 2) {
1015  	 	 	 	 $autoinc = false;
1016  	 	 	 	 foreach($table->keys as $k) {
1017  	 	 	 	 	 if (is_null($this->$k)) {
1018  	 	 	 	 	 	 $autoinc = true;
1019  	 	 	 	 	 	 break;
1020  	 	 	 	 	 }
1021  	 	 	 	 }
1022  	 	 	 	 if ($autoinc && sizeof($table->keys) == 1) {
1023  	 	 	 	 	 $k = reset($table->keys);
1024  	 	 	 	 	 $this->$k = $this->LastInsertID($db,$k);
1025  	 	 	 	 }
1026  	 	 	 }
1027  
1028  	 	 	 $this->_original = $valarr;
1029  	 	 }
1030  	 	 return $ok;
1031  	 }
1032  
1033  	 // returns 0 on error, 1 on update, -1 if no change in data (no update)
1034  	function Update()
1035  	 {
1036  	 	 $db = $this->DB();
1037  	 	 if (!$db) {
1038  	 	 	 return false;
1039  	 	 }
1040  	 	 $table = $this->TableInfo();
1041  
1042  	 	 $where = $this->GenWhere($db, $table);
1043  
1044  	 	 if (!$where) {
1045  	 	 	 $this->error("Where missing for table $table", "Update");
1046  	 	 	 return false;
1047  	 	 }
1048  	 	 $valarr = array();
1049  	 	 $neworig = array();
1050  	 	 $pairs = array();
1051  	 	 $i = -1;
1052  	 	 $cnt = 0;
1053  	 	 foreach($table->flds as $name=>$fld) {
1054  	 	 	 $i += 1;
1055  	 	 	 $val = $this->$name;
1056  	 	 	 $neworig[] = $val;
1057  
1058  	 	 	 if (isset($table->keys[$name]) || is_array($val)) {
1059  	 	 	 	 continue;
1060  	 	 	 }
1061  
1062  	 	 	 if (is_null($val)) {
1063  	 	 	 	 if (isset($fld->not_null) && $fld->not_null) {
1064  	 	 	 	 	 if (isset($fld->default_value) && strlen($fld->default_value)) {
1065  	 	 	 	 	 	 continue;
1066  	 	 	 	 	 }
1067  	 	 	 	 	 else {
1068  	 	 	 	 	 	 $this->Error("Cannot set field $name to NULL","Update");
1069  	 	 	 	 	 	 return false;
1070  	 	 	 	 	 }
1071  	 	 	 	 }
1072  	 	 	 }
1073  
1074  	 	 	 if (isset($this->_original[$i]) && strcmp($val,$this->_original[$i]) == 0) {
1075  	 	 	 	 continue;
1076  	 	 	 }
1077  
1078  	 	 	 if (is_null($this->_original[$i]) && is_null($val)) {
1079  	 	 	 	 continue;
1080  	 	 	 }
1081  
1082  	 	 	 $valarr[] = $val;
1083  	 	 	 $pairs[] = $this->nameQuoter($db,$name).'='.$db->Param($cnt);
1084  	 	 	 $cnt += 1;
1085  	 	 }
1086  
1087  
1088  	 	 if (!$cnt) {
1089  	 	 	 return -1;
1090  	 	 }
1091  
1092  	 	 $tableName = $this->nameQuoter($db,$this->_table);
1093  
1094  	 	 $sql = sprintf('UPDATE %s SET %s WHERE %s',
1095  	 	 	 	 	    $tableName,
1096  	 	 	 	 	    implode(',',$pairs),
1097  	 	 	 	 	    $where);
1098  	 	 
1099  	 	 $ok = $db->Execute($sql,$valarr);
1100  	 	 if ($ok) {
1101  	 	 	 $this->_original = $neworig;
1102  	 	 	 return 1;
1103  	 	 }
1104  	 	 return 0;
1105  	 }
1106  
1107  	function GetAttributeNames()
1108  	 {
1109  	 	 $table = $this->TableInfo();
1110  	 	 if (!$table) {
1111  	 	 	 return false;
1112  	 	 }
1113  	 	 return array_keys($table->flds);
1114  	 }
1115  
1116  	 /**
1117  	 * Quotes the table and column and field names
1118  	 *
1119  	 * this honours the ADODB_QUOTE_FIELDNAMES directive. The routines that
1120  	 * use it should really just call _adodb_getinsertsql and _adodb_getupdatesql
1121  	 * which is a nice easy project if you are interested
1122  	 *
1123  	 * @param	 obj	 	 $db	 	 The database connection
1124  	 * @param	 string	 $name	 The table or column name to quote
1125  	 *
1126  	 * @return	 string	 The quoted name
1127  	 */
1128  	private function nameQuoter($db,$string)
1129  	 {
1130  	 	 global $ADODB_QUOTE_FIELDNAMES;
1131  	 	 
1132  	 	 if (!$ADODB_QUOTE_FIELDNAMES && !$this->_quoteNames)
1133  	 	 	 /*
1134  	 	 	 * Nothing to be done
1135  	 	 	 */
1136  	 	 	 return $string;
1137  	 	 
1138  	 	 if ($this->_quoteNames == 'NONE')
1139  	 	 	 /*
1140  	 	 	 * Force no quoting when ADODB_QUOTE_FIELDNAMES is set
1141  	 	 	 */
1142  	 	 	 return $string;
1143  	 	 
1144  	 	 if ($this->_quoteNames)
1145  	 	 	 /*
1146  	 	 	 * Internal setting takes precedence
1147  	 	 	 */
1148  	 	 	 $quoteMethod = $this->_quoteNames;
1149  	 	 	 
1150  	 	 else
1151  	 	 	 $quoteMethod = $ADODB_QUOTE_FIELDNAMES;
1152  	 	 
1153  	 	 switch ($quoteMethod)
1154  	 	 {
1155  	 	 case 'LOWER':
1156  	 	 	 $string = strtolower($string);
1157  	 	 	 break;
1158  	 	 case 'NATIVE':
1159  	 	 	 /*
1160  	 	 	 * Nothing to be done
1161  	 	 	 */
1162  	 	 	 break;
1163  	 	 case 'UPPER':
1164  	 	 default:
1165  	 	 	 $string = strtoupper($string);
1166  	 	 }
1167  	 	 	 
1168  	 	 $string = sprintf(	 '%s%s%s',
1169  	 	 	 	 	 	 	 $db->nameQuote,
1170  	 	 	 	 	 	 	 $string,
1171  	 	 	 	 	 	 	 $db->nameQuote
1172  	 	 	 	 	   );
1173  	 	 return $string;
1174  	 }
1175  
1176  };
1177  
1178  function adodb_GetActiveRecordsClass(&$db, $class, $table,$whereOrderBy,$bindarr, $primkeyArr,
1179  	 	 	 $extra)
1180  {
1181  global $_ADODB_ACTIVE_DBS;
1182  
1183  
1184  	 $save = $db->SetFetchMode(ADODB_FETCH_NUM);
1185  	 
1186  	 $qry = "select * from ".$table;
1187  
1188  	 if (!empty($whereOrderBy)) {
1189  	 	 $qry .= ' WHERE '.$whereOrderBy;
1190  	 }
1191  	 if(isset($extra['limit'])) {
1192  	 	 $rows = false;
1193  	 	 if(isset($extra['offset'])) {
1194  	 	 	 $rs = $db->SelectLimit($qry, $extra['limit'], $extra['offset'],$bindarr);
1195  	 	 } else {
1196  	 	 	 $rs = $db->SelectLimit($qry, $extra['limit'],-1,$bindarr);
1197  	 	 }
1198  	 	 if ($rs) {
1199  	 	 	 while (!$rs->EOF) {
1200  	 	 	 	 $rows[] = $rs->fields;
1201  	 	 	 	 $rs->MoveNext();
1202  	 	 	 }
1203  	 	 }
1204  	 } else
1205  	 	 $rows = $db->GetAll($qry,$bindarr);
1206  
1207  	 $db->SetFetchMode($save);
1208  
1209  	 $false = false;
1210  
1211  	 if ($rows === false) {
1212  	 	 return $false;
1213  	 }
1214  
1215  
1216  	 if (!class_exists($class)) {
1217  	 	 $db->outp_throw("Unknown class $class in GetActiveRecordsClass()",'GetActiveRecordsClass');
1218  	 	 return $false;
1219  	 }
1220  	 $arr = array();
1221  	 // arrRef will be the structure that knows about our objects.
1222  	 // It is an associative array.
1223  	 // We will, however, return arr, preserving regular 0.. order so that
1224  	 // obj[0] can be used by app developers.
1225  	 $arrRef = array();
1226  	 $bTos = array(); // Will store belongTo's indices if any
1227  	 foreach($rows as $row) {
1228  
1229  	 	 $obj = new $class($table,$primkeyArr,$db);
1230  	 	 if ($obj->ErrorNo()){
1231  	 	 	 $db->_errorMsg = $obj->ErrorMsg();
1232  	 	 	 return $false;
1233  	 	 }
1234  	 	 $obj->Set($row);
1235  	 	 $arr[] = $obj;
1236  	 } // foreach($rows as $row)
1237  
1238  	 return $arr;
1239  }