WordPress.org

Make WordPress Core

Ticket #11799: 11799.patch

File 11799.patch, 31.6 KB (added by hakre, 4 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