[ Index ]
 

Code source de Joomla 1.0.13

Accédez au Source d'autres logiciels libres

title

Body

[fermer]

/includes/ -> database.mysqli.php (source)

   1  <?php
   2  /**
   3  * @version $Id: database.mysqli.php 4994 2006-09-10 15:04:50Z friesengeist $
   4  * @package Joomla
   5  * @subpackage Database
   6  * @copyright Copyright (C) 2005 Open Source Matters. All rights reserved.
   7  * @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.php
   8  * Joomla! is free software. This version may have been modified pursuant
   9  * to the GNU General Public License, and as distributed it includes or
  10  * is derivative of works licensed under the GNU General Public License or
  11  * other free or open source software licenses.
  12  * See COPYRIGHT.php for copyright notices and details.
  13  */
  14  
  15  // no direct access
  16  defined( '_VALID_MOS' ) or die( 'Restricted access' );
  17  
  18  /**
  19  * Database connector class
  20  * @subpackage Database
  21  * @package Joomla
  22  */
  23  class database {
  24      /** @var string Internal variable to hold the query sql */
  25      var $_sql            = '';
  26      /** @var int Internal variable to hold the database error number */
  27      var $_errorNum        = 0;
  28      /** @var string Internal variable to hold the database error message */
  29      var $_errorMsg        = '';
  30      /** @var string Internal variable to hold the prefix used on all database tables */
  31      var $_table_prefix    = '';
  32      /** @var Internal variable to hold the connector resource */
  33      var $_resource        = '';
  34      /** @var Internal variable to hold the last query cursor */
  35      var $_cursor        = null;
  36      /** @var boolean Debug option */
  37      var $_debug            = 0;
  38      /** @var int The limit for the query */
  39      var $_limit            = 0;
  40      /** @var int The for offset for the limit */
  41      var $_offset        = 0;
  42      /** @var int A counter for the number of queries performed by the object instance */
  43      var $_ticker        = 0;
  44      /** @var array A log of queries */
  45      var $_log            = null;
  46      /** @var string The null/zero date string */
  47      var $_nullDate        = '0000-00-00 00:00:00';
  48      /** @var string Quote for named objects */
  49      var $_nameQuote        = '`';
  50  
  51      /**
  52      * Database object constructor
  53      * @param string Database host
  54      * @param string Database user name
  55      * @param string Database user password
  56      * @param string Database name
  57      * @param string Common prefix for all tables
  58      * @param boolean If true and there is an error, go offline
  59      */
  60  	function database( $host='localhost', $user, $pass, $db='', $table_prefix='', $goOffline=true ) {
  61          // perform a number of fatality checks, then die gracefully
  62          if (!function_exists( 'mysqli_connect' )) {
  63              $mosSystemError = 1;
  64              if ($goOffline) {
  65                  $basePath = dirname( __FILE__ );
  66                  include $basePath . '/../configuration.php';
  67                  include $basePath . '/../offline.php';
  68                  exit();
  69              }
  70          }
  71          if (!($this->_resource = @mysqli_connect( $host, $user, $pass ))) {
  72              $mosSystemError = 2;
  73              if ($goOffline) {
  74                  $basePath = dirname( __FILE__ );
  75                  include $basePath . '/../configuration.php';
  76                  include $basePath . '/../offline.php';
  77                  exit();
  78              }
  79          }
  80          if ($db != '' && !mysqli_select_db($this->_resource, $db)) {
  81              $mosSystemError = 3;
  82              if ($goOffline) {
  83                  $basePath = dirname( __FILE__ );
  84                  include $basePath . '/../configuration.php';
  85                  include $basePath . '/../offline.php';
  86                  exit();
  87              }
  88          }
  89          $this->_table_prefix = $table_prefix;
  90          $this->_ticker = 0;
  91          $this->_log = array();
  92      }
  93      /**
  94       * @param int
  95       */
  96  	function debug( $level ) {
  97          $this->_debug = intval( $level );
  98      }
  99      /**
 100       * @return int The error number for the most recent query
 101       */
 102  	function getErrorNum() {
 103          return $this->_errorNum;
 104      }
 105      /**
 106      * @return string The error message for the most recent query
 107      */
 108  	function getErrorMsg() {
 109          return str_replace( array( "\n", "'" ), array( '\n', "\'" ), $this->_errorMsg );
 110      }
 111      /**
 112      * Get a database escaped string
 113      * @return string
 114      */
 115  	function getEscaped( $text ) {
 116          return mysqli_real_escape_string( $this->_resource, $text );
 117      }
 118      /**
 119      * Get a quoted database escaped string
 120      * @return string
 121      */
 122  	function Quote( $text ) {
 123          return '\'' . $this->getEscaped( $text ) . '\'';
 124      }
 125      /**
 126       * Quote an identifier name (field, table, etc)
 127       * @param string The name
 128       * @return string The quoted name
 129       */
 130  	function NameQuote( $s ) {
 131          $q = $this->_nameQuote;
 132          if (strlen( $q ) == 1) {
 133              return $q . $s . $q;
 134          } else {
 135              return $q{0} . $s . $q{1};
 136          }
 137      }
 138      /**
 139       * @return string The database prefix
 140       */
 141  	function getPrefix() {
 142          return $this->_table_prefix;
 143      }
 144      /**
 145       * @return string Quoted null/zero date string
 146       */
 147  	function getNullDate() {
 148          return $this->_nullDate;
 149      }
 150      /**
 151      * Sets the SQL query string for later execution.
 152      *
 153      * This function replaces a string identifier <var>$prefix</var> with the
 154      * string held is the <var>_table_prefix</var> class variable.
 155      *
 156      * @param string The SQL query
 157      * @param string The offset to start selection
 158      * @param string The number of results to return
 159      * @param string The common table prefix
 160      */
 161  	function setQuery( $sql, $offset = 0, $limit = 0, $prefix='#__' ) {
 162          $this->_sql = $this->replacePrefix( $sql, $prefix );
 163          $this->_limit = intval( $limit );
 164          $this->_offset = intval( $offset );
 165      }
 166  
 167      /**
 168       * This function replaces a string identifier <var>$prefix</var> with the
 169       * string held is the <var>_table_prefix</var> class variable.
 170       *
 171       * @param string The SQL query
 172       * @param string The common table prefix
 173       * @author thede, David McKinnis
 174       */
 175  	function replacePrefix( $sql, $prefix='#__' ) {
 176          $sql = trim( $sql );
 177  
 178          $escaped = false;
 179          $quoteChar = '';
 180  
 181          $n = strlen( $sql );
 182  
 183          $startPos = 0;
 184          $literal = '';
 185          while ($startPos < $n) {
 186              $ip = strpos($sql, $prefix, $startPos);
 187              if ($ip === false) {
 188                  break;
 189              }
 190  
 191              $j = strpos( $sql, "'", $startPos );
 192              $k = strpos( $sql, '"', $startPos );
 193              if (($k !== FALSE) && (($k < $j) || ($j === FALSE))) {
 194                  $quoteChar    = '"';
 195                  $j            = $k;
 196              } else {
 197                  $quoteChar    = "'";
 198              }
 199  
 200              if ($j === false) {
 201                  $j = $n;
 202              }
 203  
 204              $literal .= str_replace( $prefix, $this->_table_prefix, substr( $sql, $startPos, $j - $startPos ) );
 205              $startPos = $j;
 206  
 207              $j = $startPos + 1;
 208  
 209              if ($j >= $n) {
 210                  break;
 211              }
 212  
 213              // quote comes first, find end of quote
 214              while (TRUE) {
 215                  $k = strpos( $sql, $quoteChar, $j );
 216                  $escaped = false;
 217                  if ($k === false) {
 218                      break;
 219                  }
 220                  $l = $k - 1;
 221                  while ($l >= 0 && $sql{$l} == '\\') {
 222                      $l--;
 223                      $escaped = !$escaped;
 224                  }
 225                  if ($escaped) {
 226                      $j    = $k+1;
 227                      continue;
 228                  }
 229                  break;
 230              }
 231              if ($k === FALSE) {
 232                  // error in the query - no end quote; ignore it
 233                  break;
 234              }
 235              $literal .= substr( $sql, $startPos, $k - $startPos + 1 );
 236              $startPos = $k+1;
 237          }
 238          if ($startPos < $n) {
 239              $literal .= substr( $sql, $startPos, $n - $startPos );
 240          }
 241          return $literal;
 242      }
 243      /**
 244      * @return string The current value of the internal SQL vairable
 245      */
 246  	function getQuery() {
 247          return "<pre>" . htmlspecialchars( $this->_sql ) . "</pre>";
 248      }
 249      /**
 250      * Execute the query
 251      * @return mixed A database resource if successful, FALSE if not.
 252      */
 253  	function query() {
 254          global $mosConfig_debug;
 255          if ($this->_limit > 0 || $this->_offset > 0) {
 256              $this->_sql .= "\nLIMIT $this->_offset, $this->_limit";
 257          }
 258          if ($this->_debug) {
 259              $this->_ticker++;
 260                $this->_log[] = $this->_sql;
 261          }
 262          $this->_errorNum = 0;
 263          $this->_errorMsg = '';
 264          $this->_cursor = mysqli_query( $this->_resource, $this->_sql );
 265          if (!$this->_cursor) {
 266              $this->_errorNum = mysqli_errno( $this->_resource );
 267              $this->_errorMsg = mysqli_error( $this->_resource ) . " SQL=$this->_sql";
 268              if ($this->_debug) {
 269                  trigger_error( mysqli_error( $this->_resource ), E_USER_NOTICE );
 270                  //echo "<pre>" . $this->_sql . "</pre>\n";
 271                  if (function_exists( 'debug_backtrace' )) {
 272                      foreach( debug_backtrace() as $back) {
 273                          if (@$back['file']) {
 274                              echo '<br />'.$back['file'].':'.$back['line'];
 275                          }
 276                      }
 277                  }
 278              }
 279              return false;
 280          }
 281          return $this->_cursor;
 282      }
 283  
 284      /**
 285       * @return int The number of affected rows in the previous operation
 286       */
 287  	function getAffectedRows() {
 288          return mysqli_affected_rows( $this->_resource );
 289      }
 290  
 291  	function query_batch( $abort_on_error=true, $p_transaction_safe = false) {
 292          $this->_errorNum = 0;
 293          $this->_errorMsg = '';
 294          if ($p_transaction_safe) {
 295              $si = mysqli_get_server_info();
 296              preg_match_all( "/(\d+)\.(\d+)\.(\d+)/i", $si, $m );
 297              if ($m[1] >= 4) {
 298                  $this->_sql = 'START TRANSACTION;' . $this->_sql . '; COMMIT;';
 299              } else if ($m[2] >= 23 && $m[3] >= 19) {
 300                  $this->_sql = 'BEGIN WORK;' . $this->_sql . '; COMMIT;';
 301              } else if ($m[2] >= 23 && $m[3] >= 17) {
 302                  $this->_sql = 'BEGIN;' . $this->_sql . '; COMMIT;';
 303              }
 304          }
 305          $query_split = preg_split ("/[;]+/", $this->_sql);
 306          $error = 0;
 307          foreach ($query_split as $command_line) {
 308              $command_line = trim( $command_line );
 309              if ($command_line != '') {
 310                  $this->_cursor = mysqli_query( $command_line, $this->_resource );
 311                  if (!$this->_cursor) {
 312                      $error = 1;
 313                      $this->_errorNum .= mysqli_errno( $this->_resource ) . ' ';
 314                      $this->_errorMsg .= mysqli_error( $this->_resource )." SQL=$command_line <br />";
 315                      if ($abort_on_error) {
 316                          return $this->_cursor;
 317                      }
 318                  }
 319              }
 320          }
 321          return $error ? false : true;
 322      }
 323  
 324      /**
 325      * Diagnostic function
 326      */
 327  	function explain() {
 328          $temp = $this->_sql;
 329          $this->_sql = "EXPLAIN $this->_sql";
 330          $this->query();
 331  
 332          if (!($cur = $this->query())) {
 333              return null;
 334          }
 335          $first = true;
 336  
 337          $buf = "<table cellspacing=\"1\" cellpadding=\"2\" border=\"0\" bgcolor=\"#000000\" align=\"center\">";
 338          $buf .= $this->getQuery();
 339          while ($row = mysqli_fetch_assoc( $cur )) {
 340              if ($first) {
 341                  $buf .= "<tr>";
 342                  foreach ($row as $k=>$v) {
 343                      $buf .= "<th bgcolor=\"#ffffff\">$k</th>";
 344                  }
 345                  $buf .= "</tr>";
 346                  $first = false;
 347              }
 348              $buf .= "<tr>";
 349              foreach ($row as $k=>$v) {
 350                  $buf .= "<td bgcolor=\"#ffffff\">$v</td>";
 351              }
 352              $buf .= "</tr>";
 353          }
 354          $buf .= "</table><br />&nbsp;";
 355          mysqli_free_result( $cur );
 356  
 357          $this->_sql = $temp;
 358  
 359          return "<div style=\"background-color:#FFFFCC\" align=\"left\">$buf</div>";
 360      }
 361      /**
 362      * @return int The number of rows returned from the most recent query.
 363      */
 364  	function getNumRows( $cur=null ) {
 365          return mysqli_num_rows( $cur ? $cur : $this->_cursor );
 366      }
 367  
 368      /**
 369      * This method loads the first field of the first row returned by the query.
 370      *
 371      * @return The value returned in the query or null if the query failed.
 372      */
 373  	function loadResult() {
 374          if (!($cur = $this->query())) {
 375              return null;
 376          }
 377          $ret = null;
 378          if ($row = mysqli_fetch_row( $cur )) {
 379              $ret = $row[0];
 380          }
 381          mysqli_free_result( $cur );
 382          return $ret;
 383      }
 384      /**
 385      * Load an array of single field results into an array
 386      */
 387  	function loadResultArray($numinarray = 0) {
 388          if (!($cur = $this->query())) {
 389              return null;
 390          }
 391          $array = array();
 392          while ($row = mysqli_fetch_row( $cur )) {
 393              $array[] = $row[$numinarray];
 394          }
 395          mysqli_free_result( $cur );
 396          return $array;
 397      }
 398      /**
 399      * Load a assoc list of database rows
 400      * @param string The field name of a primary key
 401      * @return array If <var>key</var> is empty as sequential list of returned records.
 402      */
 403  	function loadAssocList( $key='' ) {
 404          if (!($cur = $this->query())) {
 405              return null;
 406          }
 407          $array = array();
 408          while ($row = mysqli_fetch_assoc( $cur )) {
 409              if ($key) {
 410                  $array[$row[$key]] = $row;
 411              } else {
 412                  $array[] = $row;
 413              }
 414          }
 415          mysqli_free_result( $cur );
 416          return $array;
 417      }
 418      /**
 419      * This global function loads the first row of a query into an object
 420      *
 421      * If an object is passed to this function, the returned row is bound to the existing elements of <var>object</var>.
 422      * If <var>object</var> has a value of null, then all of the returned query fields returned in the object.
 423      * @param string The SQL query
 424      * @param object The address of variable
 425      */
 426  	function loadObject( &$object ) {
 427          if ($object != null) {
 428              if (!($cur = $this->query())) {
 429                  return false;
 430              }
 431              if ($array = mysqli_fetch_assoc( $cur )) {
 432                  mysqli_free_result( $cur );
 433                  mosBindArrayToObject( $array, $object, null, null, false );
 434                  return true;
 435              } else {
 436                  return false;
 437              }
 438          } else {
 439              if ($cur = $this->query()) {
 440                  if ($object = mysqli_fetch_object( $cur )) {
 441                      mysqli_free_result( $cur );
 442                      return true;
 443                  } else {
 444                      $object = null;
 445                      return false;
 446                  }
 447              } else {
 448                  return false;
 449              }
 450          }
 451      }
 452      /**
 453      * Load a list of database objects
 454      * @param string The field name of a primary key
 455      * @return array If <var>key</var> is empty as sequential list of returned records.
 456      * If <var>key</var> is not empty then the returned array is indexed by the value
 457      * the database key.  Returns <var>null</var> if the query fails.
 458      */
 459  	function loadObjectList( $key='' ) {
 460          if (!($cur = $this->query())) {
 461              return null;
 462          }
 463          $array = array();
 464          while ($row = mysqli_fetch_object( $cur )) {
 465              if ($key) {
 466                  $array[$row->$key] = $row;
 467              } else {
 468                  $array[] = $row;
 469              }
 470          }
 471          mysqli_free_result( $cur );
 472          return $array;
 473      }
 474      /**
 475      * @return The first row of the query.
 476      */
 477  	function loadRow() {
 478          if (!($cur = $this->query())) {
 479              return null;
 480          }
 481          $ret = null;
 482          if ($row = mysqli_fetch_row( $cur )) {
 483              $ret = $row;
 484          }
 485          mysqli_free_result( $cur );
 486          return $ret;
 487      }
 488      /**
 489      * Load a list of database rows (numeric column indexing)
 490      * @param string The field name of a primary key
 491      * @return array If <var>key</var> is empty as sequential list of returned records.
 492      * If <var>key</var> is not empty then the returned array is indexed by the value
 493      * the database key.  Returns <var>null</var> if the query fails.
 494      */
 495  	function loadRowList( $key='' ) {
 496          if (!($cur = $this->query())) {
 497              return null;
 498          }
 499          $array = array();
 500          while ($row = mysqli_fetch_row( $cur )) {
 501              if ($key) {
 502                  $array[$row[$key]] = $row;
 503              } else {
 504                  $array[] = $row;
 505              }
 506          }
 507          mysqli_free_result( $cur );
 508          return $array;
 509      }
 510      /**
 511      * Document::db_insertObject()
 512      *
 513      * { Description }
 514      *
 515      * @param string $table This is expected to be a valid (and safe!) table name
 516      * @param [type] $keyName
 517      * @param [type] $verbose
 518      */
 519  	function insertObject( $table, &$object, $keyName = NULL, $verbose=false ) {
 520          $fmtsql = "INSERT INTO $table ( %s ) VALUES ( %s ) ";
 521          $fields = array();
 522          foreach (get_object_vars( $object ) as $k => $v) {
 523              if (is_array($v) or is_object($v) or $v === NULL) {
 524                  continue;
 525              }
 526              if ($k[0] == '_') { // internal field
 527                  continue;
 528              }
 529              $fields[] = $this->NameQuote( $k );
 530              $values[] = $this->Quote( $v );
 531          }
 532          $this->setQuery( sprintf( $fmtsql, implode( ",", $fields ) ,  implode( ",", $values ) ) );
 533          ($verbose) && print "$sql<br />\n";
 534          if (!$this->query()) {
 535              return false;
 536          }
 537          $id = mysqli_insert_id( $this->_resource );
 538          ($verbose) && print "id=[$id]<br />\n";
 539          if ($keyName && $id) {
 540              $object->$keyName = $id;
 541          }
 542          return true;
 543      }
 544  
 545      /**
 546      * Document::db_updateObject()
 547      *
 548      * { Description }
 549      *
 550      * @param string $table This is expected to be a valid (and safe!) table name
 551      * @param [type] $updateNulls
 552      */
 553  	function updateObject( $table, &$object, $keyName, $updateNulls=true ) {
 554          $fmtsql = "UPDATE $table SET %s WHERE %s";
 555          $tmp = array();
 556          foreach (get_object_vars( $object ) as $k => $v) {
 557              if( is_array($v) or is_object($v) or $k[0] == '_' ) { // internal or NA field
 558                  continue;
 559              }
 560              if( $k == $keyName ) { // PK not to be updated
 561                  $where = $keyName . '=' . $this->Quote( $v );
 562                  continue;
 563              }
 564              if ($v === NULL && !$updateNulls) {
 565                  continue;
 566              }
 567              if( $v == '' ) {
 568                  $val = "''";
 569              } else {
 570                  $val = $this->Quote( $v );
 571              }
 572              $tmp[] = $this->NameQuote( $k ) . '=' . $val;
 573          }
 574          $this->setQuery( sprintf( $fmtsql, implode( ",", $tmp ) , $where ) );
 575          return $this->query();
 576      }
 577  
 578      /**
 579      * @param boolean If TRUE, displays the last SQL statement sent to the database
 580      * @return string A standised error message
 581      */
 582  	function stderr( $showSQL = false ) {
 583          return "DB function failed with error number $this->_errorNum"
 584          ."<br /><font color=\"red\">$this->_errorMsg</font>"
 585          .($showSQL ? "<br />SQL = <pre>$this->_sql</pre>" : '');
 586      }
 587  
 588  	function insertid() {
 589          return mysqli_insert_id( $this->_resource );
 590      }
 591  
 592  	function getVersion() {
 593          return mysqli_get_server_info( $this->_resource );
 594      }
 595  
 596      /**
 597       * @return array A list of all the tables in the database
 598       */
 599  	function getTableList() {
 600          $this->setQuery( 'SHOW TABLES' );
 601          return $this->loadResultArray();
 602      }
 603      /**
 604       * @param array A list of valid (and safe!) table names
 605       * @return array A list the create SQL for the tables
 606       */
 607  	function getTableCreate( $tables ) {
 608          $result = array();
 609  
 610          foreach ($tables as $tblval) {
 611              $this->setQuery( 'SHOW CREATE table ' . $this->getEscaped( $tblval ) );
 612              $rows = $this->loadRowList();
 613              foreach ($rows as $row) {
 614                  $result[$tblval] = $row[1];
 615              }
 616          }
 617  
 618          return $result;
 619      }
 620      /**
 621       * @param array A list of valid (and safe!) table names
 622       * @return array An array of fields by table
 623       */
 624  	function getTableFields( $tables ) {
 625          $result = array();
 626  
 627          foreach ($tables as $tblval) {
 628              $this->setQuery( 'SHOW FIELDS FROM ' . $tblval );
 629              $fields = $this->loadObjectList();
 630              foreach ($fields as $field) {
 631                  $result[$tblval][$field->Field] = preg_replace("/[(0-9)]/",'', $field->Type );
 632              }
 633          }
 634  
 635          return $result;
 636      }
 637  
 638      /**
 639      * Fudge method for ADOdb compatibility
 640      */
 641  	function GenID( $foo1=null, $foo2=null ) {
 642          return '0';
 643      }
 644  }
 645  
 646  /**
 647  * mosDBTable Abstract Class.
 648  * @abstract
 649  * @package Joomla
 650  * @subpackage Database
 651  *
 652  * Parent classes to all database derived objects.  Customisation will generally
 653  * not involve tampering with this object.
 654  * @package Joomla
 655  * @author Andrew Eddie <eddieajau@users.sourceforge.net
 656  */
 657  class mosDBTable {
 658      /** @var string Name of the table in the db schema relating to child class */
 659      var $_tbl         = '';
 660      /** @var string Name of the primary key field in the table */
 661      var $_tbl_key     = '';
 662      /** @var string Error message */
 663      var $_error     = '';
 664      /** @var mosDatabase Database connector */
 665      var $_db         = null;
 666  
 667      /**
 668      *    Object constructor to set table and key field
 669      *
 670      *    Can be overloaded/supplemented by the child class
 671      *    @param string $table name of the table in the db schema relating to child class
 672      *    @param string $key name of the primary key field in the table
 673      */
 674  	function mosDBTable( $table, $key, &$db ) {
 675          $this->_tbl = $table;
 676          $this->_tbl_key = $key;
 677          $this->_db =& $db;
 678      }
 679  
 680      /**
 681       * Returns an array of public properties
 682       * @return array
 683       */
 684  	function getPublicProperties() {
 685          static $cache = null;
 686          if (is_null( $cache )) {
 687              $cache = array();
 688              foreach (get_class_vars( get_class( $this ) ) as $key=>$val) {
 689                  if (substr( $key, 0, 1 ) != '_') {
 690                      $cache[] = $key;
 691                  }
 692              }
 693          }
 694          return $cache;
 695      }
 696      /**
 697       * Filters public properties
 698       * @access protected
 699       * @param array List of fields to ignore
 700       */
 701  	function filter( $ignoreList=null ) {
 702          $ignore = is_array( $ignoreList );
 703  
 704          $iFilter = new InputFilter();
 705          foreach ($this->getPublicProperties() as $k) {
 706              if ($ignore && in_array( $k, $ignoreList ) ) {
 707                  continue;
 708              }
 709              $this->$k = $iFilter->process( $this->$k );
 710          }
 711      }
 712      /**
 713       *    @return string Returns the error message
 714       */
 715  	function getError() {
 716          return $this->_error;
 717      }
 718      /**
 719      * Gets the value of the class variable
 720      * @param string The name of the class variable
 721      * @return mixed The value of the class var (or null if no var of that name exists)
 722      */
 723  	function get( $_property ) {
 724          if(isset( $this->$_property )) {
 725              return $this->$_property;
 726          } else {
 727              return null;
 728          }
 729      }
 730  
 731      /**
 732      * Set the value of the class variable
 733      * @param string The name of the class variable
 734      * @param mixed The value to assign to the variable
 735      */
 736  	function set( $_property, $_value ) {
 737          $this->$_property = $_value;
 738      }
 739  
 740      /**
 741       * Resets public properties
 742       * @param mixed The value to set all properties to, default is null
 743       */
 744  	function reset( $value=null ) {
 745          $keys = $this->getPublicProperties();
 746          foreach ($keys as $k) {
 747              $this->$k = $value;
 748          }
 749      }
 750      /**
 751      *    binds a named array/hash to this object
 752      *
 753      *    can be overloaded/supplemented by the child class
 754      *    @param array $hash named array
 755      *    @return null|string    null is operation was satisfactory, otherwise returns an error
 756      */
 757  	function bind( $array, $ignore='' ) {
 758          if (!is_array( $array )) {
 759              $this->_error = strtolower(get_class( $this ))."::bind failed.";
 760              return false;
 761          } else {
 762              return mosBindArrayToObject( $array, $this, $ignore );
 763          }
 764      }
 765  
 766      /**
 767      *    binds an array/hash to this object
 768      *    @param int $oid optional argument, if not specifed then the value of current key is used
 769      *    @return any result from the database operation
 770      */
 771  	function load( $oid=null ) {
 772          $k = $this->_tbl_key;
 773          
 774          if ($oid !== null) {
 775              $this->$k = $oid;
 776          }
 777          
 778          $oid = $this->$k;
 779          
 780          if ($oid === null) {
 781              return false;
 782          }
 783          //Note: Prior to PHP 4.2.0, Uninitialized class variables will not be reported by get_class_vars().
 784          $class_vars = get_class_vars(get_class($this));
 785          foreach ($class_vars as $name => $value) {
 786              if (($name != $k) and ($name != "_db") and ($name != "_tbl") and ($name != "_tbl_key")) {
 787                  $this->$name = $value;
 788              }
 789          }
 790  
 791          $this->reset();
 792          
 793          $query = "SELECT *"
 794          . "\n FROM $this->_tbl"
 795          . "\n WHERE $this->_tbl_key = " . $this->_db->Quote( $oid )
 796          ;
 797          $this->_db->setQuery( $query );
 798          
 799          return $this->_db->loadObject( $this );
 800      }
 801  
 802      /**
 803      *    generic check method
 804      *
 805      *    can be overloaded/supplemented by the child class
 806      *    @return boolean True if the object is ok
 807      */
 808  	function check() {
 809          return true;
 810      }
 811  
 812      /**
 813      * Inserts a new row if id is zero or updates an existing row in the database table
 814      *
 815      * Can be overloaded/supplemented by the child class
 816      * @param boolean If false, null object variables are not updated
 817      * @return null|string null if successful otherwise returns and error message
 818      */
 819  	function store( $updateNulls=false ) {
 820          $k = $this->_tbl_key;
 821  
 822          if ($this->$k) {
 823              $ret = $this->_db->updateObject( $this->_tbl, $this, $this->_tbl_key, $updateNulls );
 824          } else {
 825              $ret = $this->_db->insertObject( $this->_tbl, $this, $this->_tbl_key );
 826          }
 827          if( !$ret ) {
 828              $this->_error = strtolower(get_class( $this ))."::store failed <br />" . $this->_db->getErrorMsg();
 829              return false;
 830          } else {
 831              return true;
 832          }
 833      }
 834      /**
 835      * @param string $where This is expected to be a valid (and safe!) SQL expression
 836      */
 837  	function move( $dirn, $where='' ) {
 838          $k = $this->_tbl_key;
 839  
 840          $sql = "SELECT $this->_tbl_key, ordering FROM $this->_tbl";
 841  
 842          if ($dirn < 0) {
 843              $sql .= "\n WHERE ordering < " . (int) $this->ordering;
 844              $sql .= ($where ? "\n    AND $where" : '');
 845              $sql .= "\n ORDER BY ordering DESC";
 846              $sql .= "\n LIMIT 1";
 847          } else if ($dirn > 0) {
 848              $sql .= "\n WHERE ordering > " . (int) $this->ordering;
 849              $sql .= ($where ? "\n    AND $where" : '');
 850              $sql .= "\n ORDER BY ordering";
 851              $sql .= "\n LIMIT 1";
 852          } else {
 853              $sql .= "\nWHERE ordering = " . (int) $this->ordering;
 854              $sql .= ($where ? "\n AND $where" : '');
 855              $sql .= "\n ORDER BY ordering";
 856              $sql .= "\n LIMIT 1";
 857          }
 858  
 859          $this->_db->setQuery( $sql );
 860  //echo 'A: ' . $this->_db->getQuery();
 861  
 862  
 863          $row = null;
 864          if ($this->_db->loadObject( $row )) {
 865              $query = "UPDATE $this->_tbl"
 866              . "\n SET ordering = " . (int) $row->ordering
 867              . "\n WHERE $this->_tbl_key = " . $this->_db->Quote( $this->$k )
 868              ;
 869              $this->_db->setQuery( $query );
 870  
 871              if (!$this->_db->query()) {
 872                  $err = $this->_db->getErrorMsg();
 873                  die( $err );
 874              }
 875  //echo 'B: ' . $this->_db->getQuery();
 876  
 877              $query = "UPDATE $this->_tbl"
 878              . "\n SET ordering = " . (int) $this->ordering
 879              . "\n WHERE $this->_tbl_key = " . $this->_db->Quote( $row->$k )
 880              ;
 881              $this->_db->setQuery( $query );
 882  //echo 'C: ' . $this->_db->getQuery();
 883  
 884              if (!$this->_db->query()) {
 885                  $err = $this->_db->getErrorMsg();
 886                  die( $err );
 887              }
 888  
 889              $this->ordering = $row->ordering;
 890          } else {
 891              $query = "UPDATE $this->_tbl"
 892              . "\n SET ordering = " . (int) $this->ordering
 893              . "\n WHERE $this->_tbl_key = " . $this->_db->Quote( $this->$k )
 894              ;
 895              $this->_db->setQuery( $query );
 896  //echo 'D: ' . $this->_db->getQuery();
 897  
 898  
 899              if (!$this->_db->query()) {
 900                  $err = $this->_db->getErrorMsg();
 901                  die( $err );
 902              }
 903          }
 904      }
 905      /**
 906      * Compacts the ordering sequence of the selected records
 907      * @param string Additional where query to limit ordering to a particular subset of records. This is expected to be a valid (and safe!) SQL expression
 908      */
 909  	function updateOrder( $where='' ) {
 910          $k = $this->_tbl_key;
 911  
 912          if (!array_key_exists( 'ordering', get_class_vars( strtolower(get_class( $this )) ) )) {
 913              $this->_error = "WARNING: ".strtolower(get_class( $this ))." does not support ordering.";
 914              return false;
 915          }
 916  
 917          if ($this->_tbl == "#__content_frontpage") {
 918              $order2 = ", content_id DESC";
 919          } else {
 920              $order2 = '';
 921          }
 922  
 923          $query = "SELECT $this->_tbl_key, ordering"
 924          . "\n FROM $this->_tbl"
 925          . ( $where ? "\n WHERE $where" : '' )
 926          . "\n ORDER BY ordering$order2 "
 927          ;
 928          $this->_db->setQuery( $query );
 929          if (!($orders = $this->_db->loadObjectList())) {
 930              $this->_error = $this->_db->getErrorMsg();
 931              return false;
 932          }
 933          // first pass, compact the ordering numbers
 934          for ($i=0, $n=count( $orders ); $i < $n; $i++) {
 935              if ($orders[$i]->ordering >= 0) {
 936                  $orders[$i]->ordering = $i+1;
 937              }
 938          }
 939  
 940          $shift = 0;
 941          $n=count( $orders );
 942          for ($i=0; $i < $n; $i++) {
 943              //echo "i=$i id=".$orders[$i]->$k." order=".$orders[$i]->ordering;
 944              if ($orders[$i]->$k == $this->$k) {
 945                  // place 'this' record in the desired location
 946                  $orders[$i]->ordering = min( $this->ordering, $n );
 947                  $shift = 1;
 948              } else if ($orders[$i]->ordering >= $this->ordering && $this->ordering > 0) {
 949                  $orders[$i]->ordering++;
 950              }
 951          }
 952      //echo '<pre>';print_r($orders);echo '</pre>';
 953          // compact once more until I can find a better algorithm
 954          for ($i=0, $n=count( $orders ); $i < $n; $i++) {
 955              if ($orders[$i]->ordering >= 0) {
 956                  $orders[$i]->ordering = $i+1;
 957                  $query = "UPDATE $this->_tbl"
 958                  . "\n SET ordering = " . (int) $orders[$i]->ordering
 959                  . "\n WHERE $k = " . $this->_db->Quote( $orders[$i]->$k )
 960                  ;
 961                  $this->_db->setQuery( $query);
 962                  $this->_db->query();
 963      //echo '<br />'.$this->_db->getQuery();
 964              }
 965          }
 966  
 967          // if we didn't reorder the current record, make it last
 968          if ($shift == 0) {
 969              $order = $n+1;
 970              $query = "UPDATE $this->_tbl"
 971              . "\n SET ordering = " . (int) $order
 972              . "\n WHERE $k = " . $this->_db->Quote( $this->$k )
 973              ;
 974              $this->_db->setQuery( $query );
 975              $this->_db->query();
 976      //echo '<br />'.$this->_db->getQuery();
 977          }
 978          return true;
 979      }
 980      /**
 981      *    Generic check for whether dependancies exist for this object in the db schema
 982      *
 983      *    can be overloaded/supplemented by the child class
 984      *    @param string $msg Error message returned
 985      *    @param int Optional key index
 986      *    @param array Optional array to compiles standard joins: format [label=>'Label',name=>'table name',idfield=>'field',joinfield=>'field']. This is expected to hold only valid (and safe!) SQL expressions
 987      *    @return true|false
 988      */
 989  	function canDelete( $oid=null, $joins=null ) {
 990          $k = $this->_tbl_key;
 991          if ($oid) {
 992              $this->$k = $oid;
 993          }
 994          if (is_array( $joins )) {
 995              $select = $k;
 996              $join = '';
 997              foreach( $joins as $table ) {
 998                  $tblName = $this->getEscaped( $table['name'] );
 999                  $idField = $this->getEscaped( $table['idfield'] );
1000                  $jnField = $this->getEscaped( $table['joinfield'] );
1001                  $select .= ",\n COUNT(DISTINCT `$tblName`.`$idField`) AS `count_".substr($tblName, 3)."_$idField`";
1002                  $join .= "\n LEFT JOIN `$tblName` ON `$tblName`.`$jnField` = `$this->_tbl`.`$k`";
1003              }
1004  
1005              $query = "SELECT $select"
1006              . "\n FROM `$this->_tbl`"
1007              . $join
1008              . "\n WHERE `$this->_tbl`.`$k` = ". (int) $this->$k
1009              . "\n GROUP BY `$this->_tbl`.`$k`"
1010              ;
1011              $this->_db->setQuery( $query );
1012  
1013              $obj = null;
1014              if (!$this->_db->loadObject($obj)) {
1015                  $this->_error = $this->_db->getErrorMsg();
1016                  return false;
1017              }
1018              $msg = array();
1019              foreach( $joins as $table ) {
1020                  $tblName = $this->getEscaped( $table['name'] );
1021                  $idField = $this->getEscaped( $table['idfield'] );
1022                  $k = 'count_'.substr($tblName, 3).'_'.$idField;
1023                  if ($obj->$k) {
1024                      $msg[] = $table['label'];
1025                  }
1026              }
1027  
1028              if (count( $msg )) {
1029                  $this->_error = "noDeleteRecord" . ": " . implode( ', ', $msg );
1030                  return false;
1031              } else {
1032                  return true;
1033              }
1034          }
1035  
1036          return true;
1037      }
1038  
1039      /**
1040      *    Default delete method
1041      *
1042      *    can be overloaded/supplemented by the child class
1043      *    @return true if successful otherwise returns and error message
1044      */
1045  	function delete( $oid=null ) {
1046          //if (!$this->canDelete( $msg )) {
1047          //    return $msg;
1048          //}
1049  
1050          $k = $this->_tbl_key;
1051          if ($oid) {
1052              $this->$k = intval( $oid );
1053          }
1054  
1055          $query = "DELETE FROM $this->_tbl"
1056          . "\n WHERE $this->_tbl_key = " . $this->_db->Quote( $this->$k )
1057          ;
1058          $this->_db->setQuery( $query );
1059  
1060          if ($this->_db->query()) {
1061              return true;
1062          } else {
1063              $this->_error = $this->_db->getErrorMsg();
1064              return false;
1065          }
1066      }
1067  
1068      /**
1069       * Checks out an object
1070       * @param int User id
1071       * @param int Object id
1072       */
1073  	function checkout( $user_id, $oid=null ) {
1074          if (!array_key_exists( 'checked_out', get_class_vars( strtolower(get_class( $this )) ) )) {
1075              $this->_error = "WARNING: ".strtolower(get_class( $this ))." does not support checkouts.";
1076              return false;
1077          }
1078          $k = $this->_tbl_key;
1079          if ($oid !== null) {
1080              $this->$k = $oid;
1081          }
1082  
1083          $time = date( 'Y-m-d H:i:s' );
1084          if (intval( $user_id )) {
1085              $user_id = intval( $user_id );
1086              // new way of storing editor, by id
1087              $query = "UPDATE $this->_tbl"
1088              . "\n SET checked_out = $user_id, checked_out_time = " . $this->_db->Quote( $time )
1089              . "\n WHERE $this->_tbl_key = " . $this->_db->Quote( $this->$k )
1090              ;
1091              $this->_db->setQuery( $query );
1092  
1093              $this->checked_out = $user_id;
1094              $this->checked_out_time = $time;
1095          } else {
1096              $user_id = $this->_db->Quote( $user_id );
1097              // old way of storing editor, by name
1098              $query = "UPDATE $this->_tbl"
1099              . "\n SET checked_out = 1, checked_out_time = " . $this->_db->Quote( $time ) . ", editor = $user_id"
1100              . "\n WHERE $this->_tbl_key = " . $this->_db->Quote( $this->$k )
1101              ;
1102              $this->_db->setQuery( $query );
1103  
1104              $this->checked_out = 1;
1105              $this->checked_out_time = $time;
1106              $this->checked_out_editor = $user_id;
1107          }
1108  
1109          return $this->_db->query();
1110      }
1111  
1112      /**
1113       * Checks in an object
1114       * @param int Object id
1115       */
1116  	function checkin( $oid=null ) {
1117          if (!array_key_exists( 'checked_out', get_class_vars( strtolower(get_class( $this )) ) )) {
1118              $this->_error = "WARNING: ".strtolower(get_class( $this ))." does not support checkin.";
1119              return false;
1120          }
1121          
1122          $k             = $this->_tbl_key;
1123          $nullDate     = $this->_db->getNullDate();
1124  
1125          if ($oid !== null) {
1126              $this->$k = intval( $oid );
1127          }
1128          if ($this->$k == NULL) {
1129              return false;
1130          }
1131  
1132          $query = "UPDATE $this->_tbl"
1133          . "\n SET checked_out = 0, checked_out_time = " . $this->_db->Quote( $nullDate )
1134          . "\n WHERE $this->_tbl_key = " . $this->_db->Quote( $this->$k )
1135          ;
1136          $this->_db->setQuery( $query );
1137  
1138          $this->checked_out = 0;
1139          $this->checked_out_time = '';
1140  
1141          return $this->_db->query();
1142      }
1143  
1144      /**
1145       * Increments the hit counter for an object
1146       * @param int Object id
1147       */
1148  	function hit( $oid=null ) {
1149          global $mosConfig_enable_log_items;
1150  
1151          $k = $this->_tbl_key;
1152          if ($oid !== null) {
1153              $this->$k = intval( $oid );
1154          }
1155  
1156          $query = "UPDATE $this->_tbl"
1157          . "\n SET hits = ( hits + 1 )"
1158          . "\n WHERE $this->_tbl_key = " . $this->_db->Quote( $this->id )
1159          ;
1160          $this->_db->setQuery( $query );
1161          $this->_db->query();
1162  
1163          if (@$mosConfig_enable_log_items) {
1164              $now = date( 'Y-m-d' );
1165              $query = "SELECT hits"
1166              . "\n FROM #__core_log_items"
1167              . "\n WHERE time_stamp = " . $this->_db->Quote( $now )
1168              . "\n AND item_table = " . $this->_db->Quote( $this->_tbl )
1169              . "\n AND item_id = " . $this->_db->Quote( $this->$k )
1170              ;
1171              $this->_db->setQuery( $query );
1172              $hits = intval( $this->_db->loadResult() );
1173              if ($hits) {
1174                  $query = "UPDATE #__core_log_items"
1175                  . "\n SET hits = ( hits + 1 )"
1176                  . "\n WHERE time_stamp = " . $this->_db->Quote( $now )
1177                  . "\n AND item_table = " . $this->_db->Quote( $this->_tbl )
1178                  . "\n AND item_id = " . $this->_db->Quote( $this->$k )
1179                  ;
1180                  $this->_db->setQuery( $query );
1181                  $this->_db->query();
1182              } else {
1183                  $query = "INSERT INTO #__core_log_items"
1184                  . "\n VALUES ( " . $this->_db->Quote( $now ) . ", " . $this->_db->Quote( $this->_tbl ) . ", " . $this->_db->Quote( $this->$k ) . ", 1 )"
1185                  ;
1186                  $this->_db->setQuery( $query );
1187                  $this->_db->query();
1188              }
1189          }
1190      }
1191  
1192      /**
1193       * Tests if item is checked out
1194       * @param int A user id
1195       * @return boolean
1196       */
1197  	function isCheckedOut( $user_id=0 ) {
1198          if ($user_id) {
1199              return ($this->checked_out && $this->checked_out != $user_id);
1200          } else {
1201              return $this->checked_out;
1202          }
1203      }
1204  
1205      /**
1206      * Generic save function
1207      * @param array Source array for binding to class vars
1208      * @param string Filter for the order updating. This is expected to be a valid (and safe!) SQL expression
1209      * @returns TRUE if completely successful, FALSE if partially or not succesful
1210      * NOTE: Filter will be deprecated in verion 1.1
1211      */
1212  	function save( $source, $order_filter='' ) {
1213          if (!$this->bind( $source )) {
1214              return false;
1215          }
1216          if (!$this->check()) {
1217              return false;
1218          }
1219          if (!$this->store()) {
1220              return false;
1221          }
1222          if (!$this->checkin()) {
1223              return false;
1224          }
1225          
1226          if ($order_filter) {
1227              $filter_value = $this->$order_filter;
1228              $this->updateOrder( $order_filter ? "`$order_filter` = " . $this->_db->Quote( $filter_value ) : '' );
1229          }
1230          $this->_error = '';
1231          return true;
1232      }
1233  
1234      /**
1235       * @deprecated As of 1.0.3, replaced by publish
1236       */
1237  	function publish_array( $cid=null, $publish=1, $user_id=0 ) {
1238          $this->publish( $cid, $publish, $user_id );
1239      }
1240  
1241      /**
1242       * Generic Publish/Unpublish function
1243       * @param    array    An array of id numbers
1244       * @param    integer    0 if unpublishing, 1 if publishing
1245       * @param    integer    The id of the user performnig the operation
1246       * @since    1.0.4
1247       */
1248  	function publish( $cid=null, $publish=1, $user_id=0 ) {
1249          mosArrayToInts( $cid, array() );
1250          $user_id    = (int) $user_id;
1251          $publish    = (int) $publish;
1252          $k            = $this->_tbl_key;
1253  
1254          if (count( $cid ) < 1) {
1255              $this->_error = "No items selected.";
1256              return false;
1257          }
1258  
1259          $cids = $this->_tbl_key . '=' . implode( ' OR ' . $this->_tbl_key . '=', $cid );
1260  
1261          $query = "UPDATE $this->_tbl"
1262          . "\n SET published = " . (int) $publish
1263          . "\n WHERE ($cids)"
1264          . "\n AND (checked_out = 0 OR checked_out = " . (int) $user_id . ")"
1265          ;
1266          $this->_db->setQuery( $query );
1267          if (!$this->_db->query()) {
1268              $this->_error = $this->_db->getErrorMsg();
1269              return false;
1270          }
1271  
1272          if (count( $cid ) == 1) {
1273              $this->checkin( $cid[0] );
1274          }
1275          $this->_error = '';
1276          return true;
1277      }
1278  
1279      /**
1280      * Export item list to xml
1281      * @param boolean Map foreign keys to text values
1282      */
1283  	function toXML( $mapKeysToText=false ) {
1284          $xml = '<record table="' . $this->_tbl . '"';
1285  
1286          if ($mapKeysToText) {
1287              $xml .= ' mapkeystotext="true"';
1288          }
1289          $xml .= '>';
1290          foreach (get_object_vars( $this ) as $k => $v) {
1291              if (is_array($v) or is_object($v) or $v === NULL) {
1292                  continue;
1293              }
1294              if ($k[0] == '_') { // internal field
1295                  continue;
1296              }
1297              $xml .= '<' . $k . '><![CDATA[' . $v . ']]></' . $k . '>';
1298          }
1299          $xml .= '</record>';
1300  
1301          return $xml;
1302      }
1303  }
1304  ?>


Généré le : Wed Nov 21 14:43:32 2007 par Balluche grâce à PHPXref 0.7
  Clicky Web Analytics