Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.2.x will end 22 April 2024 (12 months).
  • Bug fixes for security issues in 4.2.x will end 7 October 2024 (18 months).
  • PHP version: minimum PHP 8.0.0 Note: minimum PHP version has increased since Moodle 4.1. PHP 8.1.x is supported too.

Differences Between: [Versions 311 and 402]

   1  <?php
   2  /**
   3   * ADOdb Plain Text driver
   4   *
   5   * @deprecated
   6   *
   7   * This file is part of ADOdb, a Database Abstraction Layer library for PHP.
   8   *
   9   * @package ADOdb
  10   * @link https://adodb.org Project's web site and documentation
  11   * @link https://github.com/ADOdb/ADOdb Source code and issue tracker
  12   *
  13   * The ADOdb Library is dual-licensed, released under both the BSD 3-Clause
  14   * and the GNU Lesser General Public Licence (LGPL) v2.1 or, at your option,
  15   * any later version. This means you can use it in proprietary products.
  16   * See the LICENSE.md file distributed with this source code for details.
  17   * @license BSD-3-Clause
  18   * @license LGPL-2.1-or-later
  19   *
  20   * @copyright 2000-2013 John Lim
  21   * @copyright 2014 Damien Regad, Mark Newnham and the ADOdb community
  22   */
  23  
  24  // security - hide paths
  25  if (!defined('ADODB_DIR')) die();
  26  
  27  if (! defined("_ADODB_TEXT_LAYER")) {
  28   define("_ADODB_TEXT_LAYER", 1 );
  29  
  30  // for sorting in _query()
  31  function adodb_cmp($a, $b) {
  32  	 if ($a[0] == $b[0]) return 0;
  33  	 return ($a[0] < $b[0]) ? -1 : 1;
  34  }
  35  // for sorting in _query()
  36  function adodb_cmpr($a, $b) {
  37  	 if ($a[0] == $b[0]) return 0;
  38  	 return ($a[0] > $b[0]) ? -1 : 1;
  39  }
  40  class ADODB_text extends ADOConnection {
  41  	 var $databaseType = 'text';
  42  
  43  	 var $_origarray; // original data
  44  	 var $_types;
  45  	 var $_proberows = 8;
  46  	 var $_colnames;
  47  	 var $_skiprow1=false;
  48  	 var $readOnly = true;
  49  	 var $hasTransactions = false;
  50  
  51  	 var $_rezarray;
  52  	 var $_reznames;
  53  	 var $_reztypes;
  54  
  55  	function RSRecordCount()
  56  	 {
  57  	 	 if (!empty($this->_rezarray)) return sizeof($this->_rezarray);
  58  
  59  	 	 return sizeof($this->_origarray);
  60  	 }
  61  
  62  	function _affectedrows()
  63  	 {
  64  	 	 	 return false;
  65  	 }
  66  
  67  	 	 // returns true or false
  68  	function PConnect(&$array, $types = false, $colnames = false)
  69  	 {
  70  	 	 return $this->Connect($array, $types, $colnames);
  71  	 }
  72  	 	 // returns true or false
  73  	function Connect(&$array, $types = false, $colnames = false)
  74  	 {
  75  	 	 if (is_string($array) and $array === 'iluvphplens') return 'me2';
  76  
  77  	 	 if (!$array) {
  78  	 	 	 $this->_origarray = false;
  79  	 	 	 return true;
  80  	 	 }
  81  	 	 $row = $array[0];
  82  	 	 $cols = sizeof($row);
  83  
  84  
  85  	 	 if ($colnames) $this->_colnames = $colnames;
  86  	 	 else {
  87  	 	 	 $this->_colnames = $array[0];
  88  	 	 	 $this->_skiprow1 = true;
  89  	 	 }
  90  	 	 if (!$types) {
  91  	 	 // probe and guess the type
  92  	 	 	 $types = array();
  93  	 	 	 $firstrow = true;
  94  	 	 	 if ($this->_proberows > sizeof($array)) $max = sizeof($array);
  95  	 	 	 else $max = $this->_proberows;
  96  	 	 	 for ($j=($this->_skiprow1)?1:0;$j < $max; $j++) {
  97  	 	 	 	 $row = $array[$j];
  98  	 	 	 	 if (!$row) break;
  99  	 	 	 	 $i = -1;
 100  	 	 	 	 foreach($row as $v) {
 101  	 	 	 	 	 $i += 1;
 102  	 	 	 	 	 //print " ($i ".$types[$i]. "$v) ";
 103  	 	 	 	 	 $v = trim($v);
 104  	  	 	 	 	 if (!preg_match('/^[+-]{0,1}[0-9\.]+$/',$v)) {
 105  	 	 	 	 	 	 $types[$i] = 'C'; // once C, always C
 106  	 	 	 	 	 	 continue;
 107  	 	 	 	 	 }
 108  	 	 	 	 	 if (isset($types[$i]) && $types[$i]=='C') continue;
 109  	 	 	 	 	 if ($firstrow) {
 110  	 	 	 	 	 // If empty string, we presume is character
 111  	 	 	 	 	 // test for integer for 1st row only
 112  	 	 	 	 	 // after that it is up to testing other rows to prove
 113  	 	 	 	 	 // that it is not an integer
 114  	 	 	 	 	 	 if (strlen($v) == 0) $types[0] = 'C';
 115  	 	 	 	 	 	 if (strpos($v,'.') !== false) $types[0] = 'N';
 116  	 	 	 	 	 	 else  $types[$i] = 'I';
 117  	 	 	 	 	 	 continue;
 118  	 	 	 	 	 }
 119  
 120  	 	 	 	 	 if (strpos($v,'.') !== false) $types[$i] = 'N';
 121  
 122  	 	 	 	 }
 123  	 	 	 	 $firstrow = false;
 124  	 	 	 }
 125  	 	 }
 126  	 	 //print_r($types);
 127  	 	 $this->_origarray = $array;
 128  	 	 $this->_types = $types;
 129  	 	 return true;
 130  	 }
 131  
 132  
 133  
 134  	 // returns queryID or false
 135  	 // We presume that the select statement is on the same table (what else?),
 136  	 // with the only difference being the order by.
 137  	 //You can filter by using $eval and each clause is stored in $arr .eg. $arr[1] == 'name'
 138  	 // also supports SELECT [DISTINCT] COL FROM ... -- only 1 col supported
 139  	function _query($sql,$input_arr,$eval=false)
 140  	 {
 141  	 	 if ($this->_origarray === false) return false;
 142  
 143  	 	 $eval = $this->evalAll;
 144  	 	 $usql = strtoupper(trim($sql));
 145  	 	 $usql = preg_replace("/[\t\n\r]/",' ',$usql);
 146  	 	 $usql = preg_replace('/ *BY/i',' BY',strtoupper($usql));
 147  
 148  	 	 $eregword ='([A-Z_0-9]*)';
 149  	 	 //print "<BR> $sql $eval ";
 150  	 	 if ($eval) {
 151  	 	 	 $i = 0;
 152  	 	 	 foreach($this->_colnames as $n) {
 153  	 	 	 	 $n = strtoupper(trim($n));
 154  	 	 	 	 $eval = str_replace("\$$n","\$arr[$i]",$eval);
 155  
 156  	 	 	 	 $i += 1;
 157  	 	 	 }
 158  
 159  	 	 	 $i = 0;
 160  	 	 	 $eval = "\$rez=($eval);";
 161  	 	 	 //print "<p>Eval string = $eval </p>";
 162  	 	 	 $where_arr = array();
 163  
 164  	 	 	 reset($this->_origarray);
 165  	 	 	 foreach ($this->_origarray as $arr) {
 166  
 167  	 	 	 	 if ($i == 0 && $this->_skiprow1)
 168  	 	 	 	 	 $where_arr[] = $arr;
 169  	 	 	 	 else {
 170  	 	 	 	 	 eval($eval);
 171  	 	 	 	 	 //print " $i: result=$rez arr[0]={$arr[0]} arr[1]={$arr[1]} <BR>\n ";
 172  	 	 	 	 	 if ($rez) $where_arr[] = $arr;
 173  	 	 	 	 }
 174  	 	 	 	 $i += 1;
 175  	 	 	 }
 176  	 	 	 $this->_rezarray = $where_arr;
 177  	 	 }else
 178  	 	 	 $where_arr = $this->_origarray;
 179  
 180  	 	 // THIS PROJECTION CODE ONLY WORKS FOR 1 COLUMN,
 181  	 	 // OTHERWISE IT RETURNS ALL COLUMNS
 182  	 	 if (substr($usql,0,7) == 'SELECT ') {
 183  	 	 	 $at = strpos($usql,' FROM ');
 184  	 	 	 $sel = trim(substr($usql,7,$at-7));
 185  
 186  	 	 	 $distinct = false;
 187  	 	 	 if (substr($sel,0,8) == 'DISTINCT') {
 188  	 	 	 	 $distinct = true;
 189  	 	 	 	 $sel = trim(substr($sel,8,$at));
 190  	 	 	 }
 191  
 192  	 	 	 // $sel holds the selection clause, comma delimited
 193  	 	 	 // currently we only project if one column is involved
 194  	 	 	 // this is to support popups in PHPLens
 195  	 	 	 if (strpos(',',$sel)===false) {
 196  	 	 	 	 $colarr = array();
 197  
 198  	 	 	 	 preg_match("/$eregword/",$sel,$colarr);
 199  	 	 	 	 $col = $colarr[1];
 200  	 	 	 	 $i = 0;
 201  	 	 	 	 $n = '';
 202  	 	 	 	 reset($this->_colnames);
 203  	 	 	 	 foreach ($this->_colnames as $n) {
 204  
 205  	 	 	 	 	 if ($col == strtoupper(trim($n))) break;
 206  	 	 	 	 	 $i += 1;
 207  	 	 	 	 }
 208  
 209  	 	 	 	 if ($n && $col) {
 210  	 	 	 	 	 $distarr = array();
 211  	 	 	 	 	 $projarray = array();
 212  	 	 	 	 	 $projtypes = array($this->_types[$i]);
 213  	 	 	 	 	 $projnames = array($n);
 214  
 215  	 	 	 	 	 foreach ($where_arr as $a) {
 216  	 	 	 	 	 	 if ($i == 0 && $this->_skiprow1) {
 217  	 	 	 	 	 	 	 $projarray[] = array($n);
 218  	 	 	 	 	 	 	 continue;
 219  	 	 	 	 	 	 }
 220  
 221  	 	 	 	 	 	 if ($distinct) {
 222  	 	 	 	 	 	 	 $v = strtoupper($a[$i]);
 223  	 	 	 	 	 	 	 if (! $distarr[$v]) {
 224  	 	 	 	 	 	 	 	 $projarray[] = array($a[$i]);
 225  	 	 	 	 	 	 	 	 $distarr[$v] = 1;
 226  	 	 	 	 	 	 	 }
 227  	 	 	 	 	 	 } else
 228  	 	 	 	 	 	 	 $projarray[] = array($a[$i]);
 229  
 230  	 	 	 	 	 } //foreach
 231  	 	 	 	 	 //print_r($projarray);
 232  	 	 	 	 }
 233  	 	 	 } // check 1 column in projection
 234  	 	 }  // is SELECT
 235  
 236  	 	 if (empty($projarray)) {
 237  	 	 	 $projtypes = $this->_types;
 238  	 	 	 $projarray = $where_arr;
 239  	 	 	 $projnames = $this->_colnames;
 240  	 	 }
 241  	 	 $this->_rezarray = $projarray;
 242  	 	 $this->_reztypes = $projtypes;
 243  	 	 $this->_reznames = $projnames;
 244  
 245  
 246  	 	 $pos = strpos($usql,' ORDER BY ');
 247  	 	 if ($pos === false) return $this;
 248  	 	 $orderby = trim(substr($usql,$pos+10));
 249  
 250  	 	 preg_match("/$eregword/",$orderby,$arr);
 251  	 	 if (sizeof($arr) < 2) return $this; // actually invalid sql
 252  	 	 $col = $arr[1];
 253  	 	 $at = (integer) $col;
 254  	 	 if ($at == 0) {
 255  	 	 	 $i = 0;
 256  	 	 	 reset($projnames);
 257  	 	 	 foreach ($projnames as $n) {
 258  	 	 	 	 if (strtoupper(trim($n)) == $col) {
 259  	 	 	 	 	 $at = $i+1;
 260  	 	 	 	 	 break;
 261  	 	 	 	 }
 262  	 	 	 	 $i += 1;
 263  	 	 	 }
 264  	 	 }
 265  
 266  	 	 if ($at <= 0 || $at > sizeof($projarray[0])) return $this; // cannot find sort column
 267  	 	 $at -= 1;
 268  
 269  	 	 // generate sort array consisting of (sortval1, row index1) (sortval2, row index2)...
 270  	 	 $sorta = array();
 271  	 	 $t = $projtypes[$at];
 272  	 	 $num = ($t == 'I' || $t == 'N');
 273  	 	 for ($i=($this->_skiprow1)?1:0, $max = sizeof($projarray); $i < $max; $i++) {
 274  	 	 	 $row = $projarray[$i];
 275  	 	 	 $val = ($num)?(float)$row[$at]:$row[$at];
 276  	 	 	 $sorta[]=array($val,$i);
 277  	 	 }
 278  
 279  	 	 // check for desc sort
 280  	 	 $orderby = substr($orderby,strlen($col)+1);
 281  	 	 $arr = array();
 282  	 	 preg_match('/([A-Z_0-9]*)/i',$orderby,$arr);
 283  
 284  	 	 if (trim($arr[1]) == 'DESC') $sortf = 'adodb_cmpr';
 285  	 	 else $sortf = 'adodb_cmp';
 286  
 287  	 	 // hasta la sorta babe
 288  	 	 usort($sorta, $sortf);
 289  
 290  	 	 // rearrange original array
 291  	 	 $arr2 = array();
 292  	 	 if ($this->_skiprow1) $arr2[] = $projarray[0];
 293  	 	 foreach($sorta as $v) {
 294  	 	 	 $arr2[] = $projarray[$v[1]];
 295  	 	 }
 296  
 297  	 	 $this->_rezarray = $arr2;
 298  	 	 return $this;
 299  	 }
 300  
 301  	 /*	 Returns: the last error message from previous database operation	 */
 302  	function ErrorMsg()
 303  	 {
 304  	 	 	 return '';
 305  	 }
 306  
 307  	 /*	 Returns: the last error number from previous database operation	 */
 308  	function ErrorNo()
 309  	 {
 310  	 	 return 0;
 311  	 }
 312  
 313  	 // returns true or false
 314  	function _close()
 315  	 {
 316  	 }
 317  
 318  
 319  }
 320  
 321  /*--------------------------------------------------------------------------------------
 322  	  Class Name: Recordset
 323  --------------------------------------------------------------------------------------*/
 324  
 325  
 326  class ADORecordSet_text extends ADORecordSet_array
 327  {
 328  
 329  	 var $databaseType = "text";
 330  
 331  	function __construct( $conn,$mode=false)
 332  	 {
 333  	 	 parent::__construct();
 334  	 	 $this->InitArray($conn->_rezarray,$conn->_reztypes,$conn->_reznames);
 335  	 	 $conn->_rezarray = false;
 336  	 }
 337  
 338  } // class ADORecordSet_text
 339  
 340  
 341  } // defined