WordPress.org

Make WordPress Core

Ticket #11799: 11799.patch

File 11799.patch, 31.6 KB (added by hakre, 8 years ago)

First one; Fix: Query $type was not case insensitive. Fixed.

  • wp-includes/wp-db.php

    ### Eclipse Workspace Patch 1.0
    #P wordpress-trunk
     
    33 * WordPress DB Class
    44 *
    55 * Original code from {@link http://php.justinvincent.com Justin Vincent (justin@visunet.ie)}
    6  *
     6 * 
    77 * @package WordPress
    88 * @subpackage Database
    99 * @since 0.71
     
    6464        /**
    6565         * Whether to suppress errors during the DB bootstrapping.
    6666         *
     67         *
     68         * @since 2.5
    6769         * @access private
    68          * @since {@internal Version Unknown}}
    6970         * @var bool
    7071         */
    7172        var $suppress_errors = false;
     
    7374        /**
    7475         * The last error during query.
    7576         *
    76          * @since {@internal Version Unknown}}
    77          * @var string
     77         * FIXME (hakre) access violations on multiple locations in core
     78         * @see get_last_error()
     79         *
     80         * @since  2.5
     81         * @access private
     82         * @var    string
    7883         */
    7984        var $last_error = '';
    8085
    8186        /**
    8287         * Amount of queries made
    8388         *
    84          * @since 1.2.0
     89         * @since  1.2.0
    8590         * @access private
     91         * @var    int
     92         */
     93        var $num_queries = 0;
     94       
     95        /**
     96         * Amount of rows returned by last query operation
     97         *
     98         * @since 1.2
     99         * @access private
    86100         * @var int
    87101         */
    88         var $num_queries = 0;
     102        var $num_rows = 0;
    89103
    90104        /**
    91105         * Saved result of the last query made
     
    95109         * @var array
    96110         */
    97111        var $last_query;
     112       
     113        /**
     114         * Saved resultset of the last query made
     115         *
     116         * @since  {@internal Version Unknown}}
     117         * @access private
     118         * @var    array (null if unintialized)
     119         */
     120        var $last_result;
     121       
    98122
    99123        /**
    100124         * Saved info on the table column
     
    355379         * @param string $dbhost MySQL database host
    356380         */
    357381        function __construct($dbuser, $dbpassword, $dbname, $dbhost) {
    358                 register_shutdown_function(array(&$this, "__destruct"));
     382                register_shutdown_function( array( &$this, "__destruct" ) );
    359383
    360384                if ( WP_DEBUG )
    361385                        $this->show_errors();
     
    368392
    369393                $this->dbuser = $dbuser;
    370394
    371                 $this->dbh = @mysql_connect($dbhost, $dbuser, $dbpassword, true);
    372                 if (!$this->dbh) {
    373                         $this->bail(sprintf(/*WP_I18N_DB_CONN_ERROR*/"
     395                $this->dbh = @mysql_connect( $dbhost, $dbuser, $dbpassword, true );
     396                if ( !$this->dbh ) {
     397                        $this->bail( sprintf( /*WP_I18N_DB_CONN_ERROR*/"
    374398<h1>Error establishing a database connection</h1>
    375399<p>This either means that the username and password information in your <code>wp-config.php</code> file is incorrect or we can't contact the database server at <code>%s</code>. This could mean your host's database server is down.</p>
    376400<ul>
     
    379403        <li>Are you sure that the database server is running?</li>
    380404</ul>
    381405<p>If you're unsure what these terms mean you should probably contact your host. If you still need help you can always visit the <a href='http://wordpress.org/support/'>WordPress Support Forums</a>.</p>
    382 "/*/WP_I18N_DB_CONN_ERROR*/, $dbhost), 'db_connect_fail');
     406"/*/WP_I18N_DB_CONN_ERROR*/, $dbhost ), 'db_connect_fail' );
    383407                        return;
    384408                }
    385409
    386410                $this->ready = true;
    387411
    388                 if ( $this->has_cap( 'collation' ) && !empty($this->charset) ) {
    389                         if ( function_exists('mysql_set_charset') ) {
    390                                 mysql_set_charset($this->charset, $this->dbh);
     412                if ( $this->has_cap( 'collation' ) && !empty( $this->charset ) ) {
     413                        if ( function_exists( 'mysql_set_charset' ) ) {
     414                                mysql_set_charset( $this->charset, $this->dbh );
    391415                                $this->real_escape = true;
    392416                        } else {
    393                                 $collation_query = "SET NAMES '{$this->charset}'";
    394                                 if ( !empty($this->collate) )
    395                                         $collation_query .= " COLLATE '{$this->collate}'";
    396                                 $this->query($collation_query);
     417                                $query = $this->prepare( 'SET NAMES %s', $this->charset );                             
     418                                if ( !empty( $this->collate ) )
     419                                        $query .= $this->prepare( ' COLLATE %s', $this->collate );
     420                                $this->query( $query );
     421                                // @todo (hakre) still addslashes; rest disabled for now (430)) there must be a possibility to switch real_escape on here as well!
    397422                        }
    398423                }
    399424
    400                 $this->select($dbname);
     425                $this->select( $dbname );
    401426        }
    402427
    403428        /**
    404429         * PHP5 style destructor and will run when database object is destroyed.
     430         *
     431         * NOTE:
     432         *
     433         *   In difference to the PHP5 behavior of __destruct, this function will
     434         *   be called when the script shuts down. If the garbage collector will
     435         *   remove this object earlier in PHP5, this function will be called prior to
     436         *   script termination.
     437         *   
     438         *   Please see {@link __construct() class constructor} and the
     439         *   {@link register_shutdown_function() register_shutdown_function()}. for
     440         *   more details.
     441         *   
     442         * @link http://www.php.net/__destruct
     443         * @link http://www.php.net/register_shutdown_function
    405444         *
    406445         * @since 2.0.8
    407446         *
    408          * @return bool Always true
     447         * @return void
    409448         */
    410449        function __destruct() {
    411                 return true;
    412450        }
    413451
    414452        /**
     
    422460         * @param string $prefix Alphanumeric name for the new prefix.
    423461         * @return string|WP_Error Old prefix or WP_Error on error
    424462         */
    425         function set_prefix($prefix) {
     463        function set_prefix( $prefix ) {
    426464
    427                 if ( preg_match('|[^a-z0-9_]|i', $prefix) )
     465                if ( preg_match( '|[^a-z0-9_]|i', $prefix ) )
    428466                        return new WP_Error('invalid_db_prefix', /*WP_I18N_DB_BAD_PREFIX*/'Invalid database prefix'/*/WP_I18N_DB_BAD_PREFIX*/);
    429467
    430                 $old_prefix = $this->prefix;
     468                $old_prefix   = $this->prefix;
    431469                $this->prefix = $prefix;
    432470
    433                 foreach ( (array) $this->tables as $table )
     471                foreach ( $this->tables as $table )
    434472                        $this->$table = $this->prefix . $table;
    435473
    436                 if ( defined('CUSTOM_USER_TABLE') )
     474                if ( defined( 'CUSTOM_USER_TABLE' ) )
    437475                        $this->users = CUSTOM_USER_TABLE;
    438476
    439                 if ( defined('CUSTOM_USER_META_TABLE') )
     477                if ( defined( 'CUSTOM_USER_META_TABLE' ) )
    440478                        $this->usermeta = CUSTOM_USER_META_TABLE;
    441479
    442480                return $old_prefix;
     
    469507                }
    470508        }
    471509
    472         function _weak_escape($string) {
    473                 return addslashes($string);
    474         }
    475 
    476         function _real_escape($string) {
     510        /**
     511         * real escape
     512         *
     513         * escape via mysql_real_escape_string() or addslashes() 
     514         *
     515         * @since  2.8
     516         * @access private
     517         *
     518         * @param  string $string to escape
     519         * @return string escaped
     520         */
     521        function _real_escape( $string ) {
    477522                if ( $this->dbh && $this->real_escape )
    478523                        return mysql_real_escape_string( $string, $this->dbh );
    479524                else
    480525                        return addslashes( $string );
    481526        }
    482527
    483         function _escape($data) {
    484                 if ( is_array($data) ) {
    485                         foreach ( (array) $data as $k => $v ) {
    486                                 if ( is_array($v) )
    487                                         $data[$k] = $this->_escape( $v );
    488                                 else
    489                                         $data[$k] = $this->_real_escape( $v );
    490                         }
    491                 } else {
    492                         $data = $this->_real_escape( $data );
    493                 }
    494 
    495                 return $data;
     528        /**
     529         * escape
     530         *
     531         * escape data, uses {@see _real_escape()} and works
     532         * on arrays as well.
     533         *
     534         * @since  2.8
     535         * @access private
     536         *
     537         * @param  string|array $data to escape
     538         * @return string|array escaped
     539         */
     540        function _escape( $data ) {
     541                if ( is_array( $data ) )
     542                        return array_map( array( &$this, '_escape' ), $data );
     543               
     544                return $this->_real_escape( $data );
    496545        }
    497546
    498547        /**
     
    500549         *
    501550         * @since 0.71
    502551         *
    503          * @param string|array $data
    504          * @return string query safe string
     552         * @param  string|array $data to escape
     553         * @return string|array escaped as query safe string
    505554         */
    506         function escape($data) {
    507                 if ( is_array($data) ) {
    508                         foreach ( (array) $data as $k => $v ) {
    509                                 if ( is_array($v) )
    510                                         $data[$k] = $this->escape( $v );
    511                                 else
    512                                         $data[$k] = $this->_weak_escape( $v );
    513                         }
    514                 } else {
    515                         $data = $this->_weak_escape( $data );
    516                 }
    517 
    518                 return $data;
     555        function escape( $data ) {
     556                if ( is_array($data) )
     557                        return array_map( array( &$this, 'escape' ), $data );
     558                       
     559                return addslashes( $data );
    519560        }
    520561
    521562        /**
     
    523564         *
    524565         * @since 2.3.0
    525566         *
    526          * @param string $s
     567         * @param  string $string to escape
     568         * @return void
    527569         */
    528         function escape_by_ref(&$string) {
     570        function escape_by_ref( &$string ) {
    529571                $string = $this->_real_escape( $string );
    530572        }
    531573
    532574        /**
    533575         * Prepares a SQL query for safe execution.  Uses sprintf()-like syntax.
    534576         *
     577         * The following directives can be used in the query format string:
     578         *
     579         *   %d (decimal number) 
     580         *   %s (string)
     581         *   %% (literal percentage sign - no argument needed)
     582         *
     583         * Both %d and %s are to be left unquoted in the query string and   
     584         * they need an argument passed for them.
     585         * Literals (%) as parts of the query must be properly written
     586         * as %%.
     587         * 
    535588         * This function only supports a small subset of the sprintf syntax; it only supports %d (decimal number), %s (string).
    536589         * Does not support sign, padding, alignment, width or precision specifiers.
    537590         * Does not support argument numbering/swapping.
     
    542595         *
    543596         * <code>
    544597         * wpdb::prepare( "SELECT * FROM `table` WHERE `column` = %s AND `field` = %d", "foo", 1337 )
     598         * wpdb::prepare( "SELECT DATE_FORMAT(`field`, '%%c') FROM `table` WHERE `column` = %s", 'foo' );
    545599         * </code>
    546600         *
    547601         * @link http://php.net/sprintf Description of syntax.
     
    550604         * @param string $query Query statement with sprintf()-like placeholders
    551605         * @param array|mixed $args The array of variables to substitute into the query's placeholders if being called like {@link http://php.net/vsprintf vsprintf()}, or the first variable to substitute into the query's placeholders if being called like {@link http://php.net/sprintf sprintf()}.
    552606         * @param mixed $args,... further variables to substitute into the query's placeholders if being called like {@link http://php.net/sprintf sprintf()}.
    553          * @return null|string Sanitized query string
     607         * @return string|false Sanitized query string, false on error
    554608         */
    555         function prepare($query = null) { // ( $query, *$args )
     609        function prepare( $query = null ) { // ( $query, *$args )
    556610                if ( is_null( $query ) )
    557                         return;
     611                        return false;
     612                               
    558613                $args = func_get_args();
    559                 array_shift($args);
    560                 // If args were passed as an array (as in vsprintf), move them up
    561                 if ( isset($args[0]) && is_array($args[0]) )
    562                         $args = $args[0];
    563                 $query = str_replace("'%s'", '%s', $query); // in case someone mistakenly already singlequoted it
    564                 $query = str_replace('"%s"', '%s', $query); // doublequote unquoting
    565                 $query = str_replace('%s', "'%s'", $query); // quote the strings
    566                 array_walk($args, array(&$this, 'escape_by_ref'));
    567                 return @vsprintf($query, $args);
     614                array_shift( $args );
     615
     616                if ( isset( $args[0] ) && is_array( $args[0] ) )
     617                        $args = $args[0]; # re-assign args passed as array like in vsprintf
     618               
     619                // @todo (hakre) $query input can be  better sanitzed, tested code available #11608
     620
     621                $quoted = str_replace('%s', "'%s'", $query); # quote the strings
     622                $quoted = str_replace( array( "''%s''", "\"'%'\"" ), "'%s'", $quoted ); # in case someone mistakenly already single/double quoted it
     623                array_walk( $args, array( &$this, 'escape_by_ref' ) );
     624                return @vsprintf( $quoted, $args );
    568625        }
    569626
    570627        /**
     
    576633         * @param string $str The error to display
    577634         * @return bool False if the showing of errors is disabled.
    578635         */
    579         function print_error($str = '') {
     636        function print_error( $str = '' ) {             
    580637                global $EZSQL_ERROR;
    581 
     638               
    582639                if (!$str) $str = mysql_error($this->dbh);
    583640                $EZSQL_ERROR[] = array ('query' => $this->last_query, 'error_str' => $str);
    584641
     
    605662                if ( !$this->show_errors )
    606663                        return false;
    607664
    608                 $str = htmlspecialchars($str, ENT_QUOTES);
    609                 $query = htmlspecialchars($this->last_query, ENT_QUOTES);
     665                $str   = htmlspecialchars( $str, ENT_QUOTES );
     666                $query = htmlspecialchars( $this->last_query, ENT_QUOTES );
     667                $query = $query ? sprintf( '<br><code>%s</code>', $query ) : '';
    610668
    611                 // If there is an error then take note of it
    612                 print "<div id='error'>
    613                 <p class='wpdberror'><strong>WordPress database error:</strong> [$str]<br />
    614                 <code>$query</code></p>
    615                 </div>";
     669                printf('<div id="error"><p class="wpdberror"><strong>WordPress database error:</strong> [%s]%s</p>', $str, $query);
    616670        }
    617671
    618672        /**
     
    623677         * this function can be used to enable and disable showing of database
    624678         * errors.
    625679         *
    626          * @since 0.71
    627          *
    628          * @param bool $show Whether to show or hide errors
     680         * @since  0.71
     681         * @see    hide_errors()
     682         *
     683         * @param  bool $show Whether to show or hide errors
    629684         * @return bool Old value for showing errors.
    630685         */
    631686        function show_errors( $show = true ) {
     
    636691
    637692        /**
    638693         * Disables showing of database errors.
     694         *
     695         * By default database errors are not shown.
    639696         *
    640          * @since 0.71
    641          *
    642          * @return bool Whether showing of errors was active or not
     697         * @since  0.71
     698         * @see    show_errors()
     699         *
     700         * @return bool Old show errors value
    643701         */
    644702        function hide_errors() {
    645703                $show = $this->show_errors;
     
    649707
    650708        /**
    651709         * Whether to suppress database errors.
    652          *
    653          * @param unknown_type $suppress
    654          * @return unknown
     710         *
     711         * By default database errors are suppressed, with a simple
     712         * call to this function they can be enabled.
     713         *
     714         * @since  2.5
     715         * @see    hide_errors()
     716         * @param  bool $suppress (optional) new value, defaults to true
     717         * @return bool old suppress errors value
    655718         */
    656719        function suppress_errors( $suppress = true ) {
    657720                $errors = $this->suppress_errors;
    658                 $this->suppress_errors = $suppress;
     721                $this->suppress_errors = (bool) $suppress;
    659722                return $errors;
    660723        }
    661724
     
    663726         * Kill cached query results.
    664727         *
    665728         * @since 0.71
     729         *
     730         * @return void
    666731         */
    667732        function flush() {
    668733                $this->last_result = array();
    669                 $this->col_info = null;
    670                 $this->last_query = null;
     734                $this->num_rows    = 0;
     735                $this->col_info    = null;
     736                $this->last_query  = null;
    671737        }
    672738
    673739        /**
     
    677743         *
    678744         * @since 0.71
    679745         *
    680          * @param string $query
     746         * @param  string   $query database query
    681747         * @return int|false Number of rows affected/selected or false on error
    682748         */
    683         function query($query) {
     749        function query( $query ) {
    684750                if ( ! $this->ready )
    685751                        return false;
    686752
    687                 // filter the query, if filters are available
    688                 // NOTE: some queries are made before the plugins have been loaded, and thus cannot be filtered with this method
    689753                if ( function_exists('apply_filters') )
    690754                        $query = apply_filters('query', $query);
    691755
    692                 // initialise return
     756                // initi return values and objects state
    693757                $return_val = 0;
    694758                $this->flush();
    695759
     
    699763                // Keep track of the last query for debug..
    700764                $this->last_query = $query;
    701765
    702                 // Perform the query via std mysql_query function..
    703766                if ( defined('SAVEQUERIES') && SAVEQUERIES )
    704767                        $this->timer_start();
    705 
     768                       
     769                // Perform the query via std mysql_query function..
    706770                $this->result = @mysql_query($query, $this->dbh);
    707                 ++$this->num_queries;
     771                $this->num_queries++;
    708772
    709773                if ( defined('SAVEQUERIES') && SAVEQUERIES )
    710774                        $this->queries[] = array( $query, $this->timer_stop(), $this->get_caller() );
    711775
    712776                // If there is an error then take note of it..
    713                 if ( $this->last_error = mysql_error($this->dbh) ) {
     777                if ( $this->last_error = mysql_error( $this->dbh ) ) {
    714778                        $this->print_error();
    715779                        return false;
    716780                }
    717781
    718                 if ( preg_match("/^\\s*(insert|delete|update|replace|alter) /i",$query) ) {
    719                         $this->rows_affected = mysql_affected_rows($this->dbh);
    720                         // Take note of the insert_id
    721                         if ( preg_match("/^\\s*(insert|replace) /i",$query) ) {
    722                                 $this->insert_id = mysql_insert_id($this->dbh);
    723                         }
    724                         // Return number of rows affected
    725                         $return_val = $this->rows_affected;
    726                 } else {
    727                         $i = 0;
    728                         while ($i < @mysql_num_fields($this->result)) {
    729                                 $this->col_info[$i] = @mysql_fetch_field($this->result);
    730                                 $i++;
    731                         }
    732                         $num_rows = 0;
    733                         while ( $row = @mysql_fetch_object($this->result) ) {
    734                                 $this->last_result[$num_rows] = $row;
    735                                 $num_rows++;
    736                         }
     782                if ( preg_match( '(^\s*([a-z]{2,})\s+)i', $query, $matches ) )
     783                        $type = strtoupper($matches[1]);
     784                else
     785                        $type = '';
     786               
     787                switch( $type ) {
     788                        case 'INSERT':
     789                        case 'REPLACE':
     790                                $this->insert_id = mysql_insert_id( $this->dbh );                               
     791                        case 'DELETE':
     792                        case 'UPDATE':
     793                        case 'ALTER':
     794                                $this->rows_affected = mysql_affected_rows( $this->dbh );                               
     795                                $return_val = $this->rows_affected;
     796                                break;
     797                               
     798                        default:
     799                                $i = 0;
     800                                while ( $i < @mysql_num_fields( $this->result ) )
     801                                        $this->col_info[$i++] = @mysql_fetch_field( $this->result );
     802                       
     803                                $num_rows = 0;
     804                                while ( $row = @mysql_fetch_assoc( $this->result ) )                   
     805                                        $this->last_result[$num_rows++] = $row;
    737806
    738                         @mysql_free_result($this->result);
    739 
    740                         // Log number of rows the query returned
    741                         $this->num_rows = $num_rows;
    742 
    743                         // Return number of rows selected
    744                         $return_val = $this->num_rows;
     807                                @mysql_free_result( $this->result );
     808                                $this->num_rows = $num_rows;                   
     809                                $return_val = $num_rows;
    745810                }
    746 
     811               
    747812                return $return_val;
    748813        }
    749814
     
    751816         * Insert a row into a table.
    752817         *
    753818         * <code>
     819         * wpdb::insert( 'table', array( 'column' => 'foo', 'field' => 1337 ) )
    754820         * wpdb::insert( 'table', array( 'column' => 'foo', 'field' => 1337 ), array( '%s', '%d' ) )
    755821         * </code>
    756822         *
     
    762828         * @param array|string $format (optional) An array of formats to be mapped to each of the value in $data.  If string, that format will be used for all of the values in $data.  A format is one of '%d', '%s' (decimal number, string).  If omitted, all values in $data will be treated as strings.
    763829         * @return int|false The number of rows inserted, or false on error.
    764830         */
    765         function insert($table, $data, $format = null) {
    766                 $formats = $format = (array) $format;
    767                 $fields = array_keys($data);
    768                 $formatted_fields = array();
    769                 foreach ( $fields as $field ) {
    770                         if ( !empty($format) )
    771                                 $form = ( $form = array_shift($formats) ) ? $form : $format[0];
    772                         elseif ( isset($this->field_types[$field]) )
    773                                 $form = $this->field_types[$field];
    774                         else
    775                                 $form = '%s';
    776                         $formatted_fields[] = $form;
    777                 }
    778                 $sql = "INSERT INTO `$table` (`" . implode( '`,`', $fields ) . "`) VALUES ('" . implode( "','", $formatted_fields ) . "')";
    779                 return $this->query( $this->prepare( $sql, $data) );
     831        function insert( $table, $data, $format = null ) {
     832                if ( !is_array( $data ) )
     833                        return false;
     834                                                       
     835                $sql = sprintf(
     836                        'INSERT INTO `%s` SET %s'
     837                        , $table
     838                        , $this->_field_formats( array_keys( $data ), $format, ', ' )
     839                );             
     840                $values = array_values( $data );               
     841                return $this->query( $this->prepare( $sql, $values ) );
    780842        }
    781843
    782 
    783844        /**
    784845         * Update a row in the table
    785846         *
    786847         * <code>
     848         * wpdb::update( 'table', array( 'column' => 'foo', 'field' => 1337 ), array( 'ID' => 1 ) )
    787849         * wpdb::update( 'table', array( 'column' => 'foo', 'field' => 1337 ), array( 'ID' => 1 ), array( '%s', '%d' ), array( '%d' ) )
    788850         * </code>
    789851         *
     
    797859         * @param array|string $format_where (optional) An array of formats to be mapped to each of the values in $where.  If string, that format will be used for all of  the items in $where.  A format is one of '%d', '%s' (decimal number, string).  If omitted, all values in $where will be treated as strings.
    798860         * @return int|false The number of rows updated, or false on error.
    799861         */
    800         function update($table, $data, $where, $format = null, $where_format = null) {
    801                 if ( !is_array( $where ) )
     862        function update( $table, $data, $where, $format = null, $where_format = null ) {
     863                if ( !is_array( $data ) || !is_array( $where ))
    802864                        return false;
    803 
     865               
     866                $sql = sprintf(
     867                        'UPDATE `%s` SET %s WHERE %s'
     868                        , $table
     869                        , $this->_field_formats( array_keys( $data  ), $format, ', ' )
     870                        , $this->_field_formats( array_keys( $where ), $where_format, ' AND ' )
     871                );             
     872                $values = array_merge( array_values( $data ), array_values( $where ) );
     873                return $this->query( $this->prepare( $sql, $values ) );
     874        }
     875       
     876        /**
     877         * field types
     878         *
     879         * helper function to get the format string for
     880         * multiple fields.
     881         *
     882         * @param array $fields fields name => value based
     883         * @param array $format additional field-format specifier(s), compare to wpdb::update() $format parameter
     884         * @param string $concat concatination string
     885         * @param string $default (optional) default format, is %s, see wpdb::prepare() for format tokens
     886         * @return array string format token string for those fields to be used
     887         * @access private
     888         * @since 3.0
     889         */
     890        function _field_formats( $fields, $format, $concat, $default = '%s' ) {
     891                $result  = array();
    804892                $formats = $format = (array) $format;
    805                 $bits = $wheres = array();
    806                 foreach ( (array) array_keys($data) as $field ) {
    807                         if ( !empty($format) )
    808                                 $form = ( $form = array_shift($formats) ) ? $form : $format[0];
    809                         elseif ( isset($this->field_types[$field]) )
    810                                 $form = $this->field_types[$field];
    811                         else
    812                                 $form = '%s';
    813                         $bits[] = "`$field` = {$form}";
     893               
     894                foreach ( $fields as $field ) {
     895                        $token = $default;                     
     896                        if ( count( $format ) )
     897                                $token = ( $token = array_shift($formats) ) ? $token : $format[0];
     898                        elseif ( isset( $this->field_types[$field] ) )
     899                                $token = $this->field_types[$field];
     900                       
     901                        $result[] = sprintf( '`%s` = %s', $field, $token );
    814902                }
    815 
    816                 $where_formats = $where_format = (array) $where_format;
    817                 foreach ( (array) array_keys($where) as $field ) {
    818                         if ( !empty($where_format) )
    819                                 $form = ( $form = array_shift($where_formats) ) ? $form : $where_format[0];
    820                         elseif ( isset($this->field_types[$field]) )
    821                                 $form = $this->field_types[$field];
    822                         else
    823                                 $form = '%s';
    824                         $wheres[] = "`$field` = {$form}";
    825                 }
    826 
    827                 $sql = "UPDATE `$table` SET " . implode( ', ', $bits ) . ' WHERE ' . implode( ' AND ', $wheres );
    828                 return $this->query( $this->prepare( $sql, array_merge(array_values($data), array_values($where))) );
     903               
     904                return implode( $concat, $result );
    829905        }
    830906
    831907        /**
     
    837913         *
    838914         * @since 0.71
    839915         *
    840          * @param string|null $query SQL query.  If null, use the result from the previous query.
    841          * @param int $x (optional) Column of value to return.  Indexed from 0.
    842          * @param int $y (optional) Row of value to return.  Indexed from 0.
    843          * @return string Database query result
     916         * @param string       $query (optional) SQL query. Defaults to NULL the re-use of existing data.
     917         * @param int          $col  (optional) Column of value to return.  Indexed from 0.
     918         * @param int          $row  (optional) Row of value to return.  Indexed from 0.
     919         * @return string|null string value on success, NULL if a value on
    844920         */
    845         function get_var($query=null, $x = 0, $y = 0) {
    846                 $this->func_call = "\$db->get_var(\"$query\",$x,$y)";
     921        function get_var( $query = null, $col = 0, $row = 0 ) {
     922                $this->func_call = "\$db->get_var(\"$query\",$col,$row)";
    847923                if ( $query )
    848                         $this->query($query);
    849 
    850                 // Extract var out of cached results based x,y vals
    851                 if ( !empty( $this->last_result[$y] ) ) {
    852                         $values = array_values(get_object_vars($this->last_result[$y]));
     924                        $this->query( $query );
     925               
     926                if ( isset( $this->last_result[$row] )
     927                     && $values = array_values( $this->last_result[$row] )
     928                     && isset( $values[$col] ) ) {
     929                        return $values[$col];
    853930                }
    854 
    855                 // If there is a value return it else return null
    856                 return (isset($values[$x]) && $values[$x]!=='') ? $values[$x] : null;
     931               
     932                return null;
    857933        }
    858934
    859935        /**
     
    865941         *
    866942         * @param string|null $query SQL query.
    867943         * @param string $output (optional) one of ARRAY_A | ARRAY_N | OBJECT constants.  Return an associative array (column => value, ...), a numerically indexed array (0 => value, ...) or an object ( ->column = value ), respectively.
    868          * @param int $y (optional) Row to return.  Indexed from 0.
    869          * @return mixed Database query result in format specifed by $output
     944         * @param int    $row (optional) Row to return.  Indexed from 0.
     945         * @return mixed Database query result in format specifed by $output or NULL
    870946         */
    871         function get_row($query = null, $output = OBJECT, $y = 0) {
    872                 $this->func_call = "\$db->get_row(\"$query\",$output,$y)";
    873                 if ( $query )
    874                         $this->query($query);
    875                 else
    876                         return null;
     947        function &get_row( $query = null, $output = OBJECT, $row = 0) {         
     948                $this->func_call = "\$db->get_row(\"$query\",$output,$row)";
     949                $retval = null;
     950               
     951                if ( null !== $query && false === $this->query( $query ) )
     952                        return $retval;
    877953
    878                 if ( !isset($this->last_result[$y]) )
    879                         return null;
    880 
    881                 if ( $output == OBJECT ) {
    882                         return $this->last_result[$y] ? $this->last_result[$y] : null;
    883                 } elseif ( $output == ARRAY_A ) {
    884                         return $this->last_result[$y] ? get_object_vars($this->last_result[$y]) : null;
    885                 } elseif ( $output == ARRAY_N ) {
    886                         return $this->last_result[$y] ? array_values(get_object_vars($this->last_result[$y])) : null;
    887                 } else {
    888                         $this->print_error(/*WP_I18N_DB_GETROW_ERROR*/" \$db->get_row(string query, output type, int offset) -- Output type must be one of: OBJECT, ARRAY_A, ARRAY_N"/*/WP_I18N_DB_GETROW_ERROR*/);
     954                $row = absint( $row );
     955                       
     956                if ( $row >= $this->num_rows )
     957                        return $retval;
     958                       
     959                $retval =& $this->last_result[$row]; # stored as ARRAY_A, {@see query()} 
     960               
     961                switch ( $output ) {
     962                        case OBJECT:
     963                                $retval = (object) $retval;
     964                        case ARRAY_A:
     965                                break;                         
     966                        case ARRAY_N:
     967                                $retval = array_values( $retval );
     968                                break;                                                         
     969                        default:
     970                                $this->print_error(/*WP_I18N_DB_GETROW_ERROR*/" \$db->get_row(string query, output type, int offset) -- Output type must be one of: OBJECT, ARRAY_A, ARRAY_N"/*/WP_I18N_DB_GETROW_ERROR*/);     
    889971                }
     972               
     973                return $retval;
    890974        }
     975       
     976        /**
     977         * get last database error
     978         *
     979         * @return string
     980         */
     981        function get_last_error() {
     982                return $this->last_error;
     983        }
     984       
     985        /**
     986         * get number of rows
     987         *
     988         * Retrieve the number of rows of the last querty operation
     989         *
     990         * @see query()
     991         * @return int number of rows
     992         */
     993        function get_num_rows() {
     994                return $this->num_rows;
     995        }
    891996
    892997        /**
    893998         * Retrieve one column from the database.
     
    8981003         *
    8991004         * @since 0.71
    9001005         *
    901          * @param string|null $query SQL query.  If null, use the result from the previous query.
    902          * @param int $x Column to return.  Indexed from 0.
    903          * @return array Database query result.  Array indexed from 0 by SQL result row number.
     1006         * @param  string $query (optional) SQL query. If omitted it uses the result from the previous query.
     1007         * @param  int    $col   (optional) Column to return. Indexed from 0, defaults to first column.
     1008         * @return array  Array  Zero-based-row-number-keyed containing the column's value(s)
    9041009         */
    905         function get_col($query = null , $x = 0) {
     1010        function get_col( $query = null , $col = 0 ) {
    9061011                if ( $query )
    907                         $this->query($query);
     1012                        $this->query( $query );
    9081013
    9091014                $new_array = array();
    910                 // Extract the column values
    911                 for ( $i=0; $i < count($this->last_result); $i++ ) {
    912                         $new_array[$i] = $this->get_var(null, $x, $i);
    913                 }
     1015               
     1016                // get that column values of all rows
     1017                $count = $this->num_rows;
     1018                for ( $i = 0; $i < $count; $i++ )
     1019                        if ( isset( $this->last_result[$i] )
     1020                         && $values = array_values( $this->last_result[$i] )
     1021                         && isset( $values[$col] ) )
     1022                                $new_array[$i] = $values[$col];
     1023                       
    9141024                return $new_array;
    9151025        }
    9161026
     
    9181028         * Retrieve an entire SQL result set from the database (i.e., many rows)
    9191029         *
    9201030         * Executes a SQL query and returns the entire SQL result.
     1031         *
     1032         * Return Types:
     1033         *
     1034         *   ARRAY_A  : array of column name-keyed row arrays
     1035         *   ARRAY_N  : array of integer-keyed row arrays
     1036         *   OBJECT   : array of row objects
     1037         *   OBJECT_K : column-1-keyed array of row objects (duplicates are discarded)
    9211038         *
    9221039         * @since 0.71
    9231040         *
    9241041         * @param string $query SQL query.
    9251042         * @param string $output (optional) ane of ARRAY_A | ARRAY_N | OBJECT | OBJECT_K constants.  With one of the first three, return an array of rows indexed from 0 by SQL result row number.  Each row is an associative array (column => value, ...), a numerically indexed array (0 => value, ...), or an object. ( ->column = value ), respectively.  With OBJECT_K, return an associative array of row objects keyed by the value of each row's first column's value.  Duplicate keys are discarded.
    926          * @return mixed Database query results
     1043         * @return array|object|null Database query results or NULL on error
    9271044         */
    928         function get_results($query = null, $output = OBJECT) {
     1045        function &get_results( $query = null, $output = OBJECT ) {
    9291046                $this->func_call = "\$db->get_results(\"$query\", $output)";
    930 
     1047                $retval = null;
     1048               
    9311049                if ( $query )
    932                         $this->query($query);
     1050                        $this->query( $query );
    9331051                else
    934                         return null;
     1052                        return $retval;
     1053                       
     1054                $retval = $this->last_result; # Array of database rows, each of type ARRAY_A {@see query()}
    9351055
    936                 if ( $output == OBJECT ) {
    937                         // Return an integer-keyed array of row objects
    938                         return $this->last_result;
    939                 } elseif ( $output == OBJECT_K ) {
    940                         // Return an array of row objects with keys from column 1
    941                         // (Duplicates are discarded)
    942                         foreach ( $this->last_result as $row ) {
    943                                 $key = array_shift( get_object_vars( $row ) );
    944                                 if ( !isset( $new_array[ $key ] ) )
    945                                         $new_array[ $key ] = $row;
    946                         }
    947                         return $new_array;
    948                 } elseif ( $output == ARRAY_A || $output == ARRAY_N ) {
    949                         // Return an integer-keyed array of...
    950                         if ( $this->last_result ) {
    951                                 $i = 0;
    952                                 foreach( (array) $this->last_result as $row ) {
    953                                         if ( $output == ARRAY_N ) {
    954                                                 // ...integer-keyed row arrays
    955                                                 $new_array[$i] = array_values( get_object_vars( $row ) );
    956                                         } else {
    957                                                 // ...column name-keyed row arrays
    958                                                 $new_array[$i] = get_object_vars( $row );
    959                                         }
    960                                         ++$i;
    961                                 }
    962                                 return $new_array;
    963                         }
     1056                switch ( $output ) {
     1057                        case OBJECT:   # array of row objects
     1058                                foreach ( $retval as $key => $value )
     1059                                        $retval[$key] = (object) $value;                                       
     1060                                break;
     1061                                                                               
     1062                        case OBJECT_K: # column-1-keyed array of row objects (duplicates are discarded)
     1063                                $retval = array();
     1064                                foreach ($this->last_result as $value )
     1065                                        if ( !isset( $retval[$key = array_shift( array_values( $value ) )] ) )
     1066                                                $retval[$key] = (object) $value;
     1067                                break;
     1068                       
     1069                        case ARRAY_N:  # array of integer-keyed row arrays
     1070                                foreach ( $retval as $key=> $value )
     1071                                        $retval[$key] = array_values( $value );
     1072                                       
     1073                        case ARRAY_A:  # array of column name-keyed row arrays
     1074                                break;
     1075                               
     1076                        default:       # undefined return type
     1077                                $retval = null;                         
    9641078                }
     1079               
     1080                return $retval;
    9651081        }
    9661082
    9671083        /**
     
    11001216         * @return string The name of the calling function
    11011217         */
    11021218        function get_caller() {
    1103                 // requires PHP 4.3+
    1104                 if ( !is_callable('debug_backtrace') )
    1105                         return '';
    1106 
    1107                 $bt = debug_backtrace();
     1219                $trace  = array_reverse( debug_backtrace() );
    11081220                $caller = array();
    11091221
    1110                 $bt = array_reverse( $bt );
    1111                 foreach ( (array) $bt as $call ) {
    1112                         if ( @$call['class'] == __CLASS__ )
    1113                                 continue;
     1222                foreach ( $trace as $call ) {
     1223                        if ( isset( $call['class'] ) &&  __CLASS__ == $call['class'] )
     1224                                continue; # filter out function calls if this object's class
     1225                                                                                                                       
    11141226                        $function = $call['function'];
    1115                         if ( isset( $call['class'] ) )
     1227                                                                       
     1228                        if ( isset( $call['class'] ) )                 
    11161229                                $function = $call['class'] . "->$function";
     1230                               
    11171231                        $caller[] = $function;
    11181232                }
    1119                 $caller = join( ', ', $caller );
    11201233
    1121                 return $caller;
     1234                return join( ', ', $caller );
    11221235        }
    11231236
    11241237        /**
     
    11291242        function db_version() {
    11301243                return preg_replace('/[^0-9.].*/', '', mysql_get_server_info( $this->dbh ));
    11311244        }
     1245       
     1246        /**
     1247         * get tables
     1248         *
     1249         * get list of a set of tables
     1250         *
     1251         * Sets:
     1252         *
     1253         *   all     : all names
     1254         *   current : active tables
     1255         *   old     : deprecated tables
     1256         *
     1257         *
     1258         * @param  string $set (optional) 'all', 'current' or 'old'. defaults to 'current'
     1259         * @return array  list of old table names (w/o prefix), false on error
     1260         * @since  3.0
     1261         */
     1262        function get_tables( $set = 'current' ) {
     1263                $tables = false;
     1264               
     1265                switch ( $set ) {
     1266                        case 'all':
     1267                                $tables = $this->tables;
     1268                                break;                         
     1269                        case 'current':
     1270                                $tables = array_diff( $this->tables, $this->old_tables );
     1271                                break;                         
     1272                        case 'old':
     1273                                $tables = $this->old_tables;
     1274                                break;
     1275                }
     1276
     1277                return $tables;
     1278        }
    11321279}
    11331280
    11341281if ( ! isset($wpdb) ) {
     
    11391286         */
    11401287        $wpdb = new wpdb(DB_USER, DB_PASSWORD, DB_NAME, DB_HOST);
    11411288}
    1142 ?>
     1289?>
     1290 No newline at end of file