]> scripts.mit.edu Git - autoinstalls/wordpress.git/blob - wp-includes/wp-db.php
WordPress 3.9.2-scripts
[autoinstalls/wordpress.git] / wp-includes / wp-db.php
1 <?php
2 /**
3  * WordPress DB Class
4  *
5  * Original code from {@link http://php.justinvincent.com Justin Vincent (justin@visunet.ie)}
6  *
7  * @package WordPress
8  * @subpackage Database
9  * @since 0.71
10  */
11
12 /**
13  * @since 0.71
14  */
15 define( 'EZSQL_VERSION', 'WP1.25' );
16
17 /**
18  * @since 0.71
19  */
20 define( 'OBJECT', 'OBJECT' );
21 define( 'object', 'OBJECT' ); // Back compat.
22
23 /**
24  * @since 2.5.0
25  */
26 define( 'OBJECT_K', 'OBJECT_K' );
27
28 /**
29  * @since 0.71
30  */
31 define( 'ARRAY_A', 'ARRAY_A' );
32
33 /**
34  * @since 0.71
35  */
36 define( 'ARRAY_N', 'ARRAY_N' );
37
38 /**
39  * WordPress Database Access Abstraction Object
40  *
41  * It is possible to replace this class with your own
42  * by setting the $wpdb global variable in wp-content/db.php
43  * file to your class. The wpdb class will still be included,
44  * so you can extend it or simply use your own.
45  *
46  * @link http://codex.wordpress.org/Function_Reference/wpdb_Class
47  *
48  * @package WordPress
49  * @subpackage Database
50  * @since 0.71
51  */
52 class wpdb {
53
54         /**
55          * Whether to show SQL/DB errors
56          *
57          * @since 0.71
58          * @access private
59          * @var bool
60          */
61         var $show_errors = false;
62
63         /**
64          * Whether to suppress errors during the DB bootstrapping.
65          *
66          * @access private
67          * @since 2.5.0
68          * @var bool
69          */
70         var $suppress_errors = false;
71
72         /**
73          * The last error during query.
74          *
75          * @since 2.5.0
76          * @var string
77          */
78         var $last_error = '';
79
80         /**
81          * Amount of queries made
82          *
83          * @since 1.2.0
84          * @access private
85          * @var int
86          */
87         var $num_queries = 0;
88
89         /**
90          * Count of rows returned by previous query
91          *
92          * @since 0.71
93          * @access private
94          * @var int
95          */
96         var $num_rows = 0;
97
98         /**
99          * Count of affected rows by previous query
100          *
101          * @since 0.71
102          * @access private
103          * @var int
104          */
105         var $rows_affected = 0;
106
107         /**
108          * The ID generated for an AUTO_INCREMENT column by the previous query (usually INSERT).
109          *
110          * @since 0.71
111          * @access public
112          * @var int
113          */
114         var $insert_id = 0;
115
116         /**
117          * Last query made
118          *
119          * @since 0.71
120          * @access private
121          * @var array
122          */
123         var $last_query;
124
125         /**
126          * Results of the last query made
127          *
128          * @since 0.71
129          * @access private
130          * @var array|null
131          */
132         var $last_result;
133
134         /**
135          * MySQL result, which is either a resource or boolean.
136          *
137          * @since 0.71
138          * @access protected
139          * @var mixed
140          */
141         protected $result;
142
143         /**
144          * Saved info on the table column
145          *
146          * @since 0.71
147          * @access protected
148          * @var array
149          */
150         protected $col_info;
151
152         /**
153          * Saved queries that were executed
154          *
155          * @since 1.5.0
156          * @access private
157          * @var array
158          */
159         var $queries;
160
161         /**
162          * The number of times to retry reconnecting before dying.
163          *
164          * @since 3.9.0
165          * @access protected
166          * @see wpdb::check_connection()
167          * @var int
168          */
169         protected $reconnect_retries = 5;
170
171         /**
172          * WordPress table prefix
173          *
174          * You can set this to have multiple WordPress installations
175          * in a single database. The second reason is for possible
176          * security precautions.
177          *
178          * @since 2.5.0
179          * @access private
180          * @var string
181          */
182         var $prefix = '';
183
184         /**
185          * WordPress base table prefix.
186          *
187          * @since 3.0.0
188          * @access public
189          * @var string
190          */
191          public $base_prefix;
192
193         /**
194          * Whether the database queries are ready to start executing.
195          *
196          * @since 2.3.2
197          * @access private
198          * @var bool
199          */
200         var $ready = false;
201
202         /**
203          * {@internal Missing Description}}
204          *
205          * @since 3.0.0
206          * @access public
207          * @var int
208          */
209         var $blogid = 0;
210
211         /**
212          * {@internal Missing Description}}
213          *
214          * @since 3.0.0
215          * @access public
216          * @var int
217          */
218         var $siteid = 0;
219
220         /**
221          * List of WordPress per-blog tables
222          *
223          * @since 2.5.0
224          * @access private
225          * @see wpdb::tables()
226          * @var array
227          */
228         var $tables = array( 'posts', 'comments', 'links', 'options', 'postmeta',
229                 'terms', 'term_taxonomy', 'term_relationships', 'commentmeta' );
230
231         /**
232          * List of deprecated WordPress tables
233          *
234          * categories, post2cat, and link2cat were deprecated in 2.3.0, db version 5539
235          *
236          * @since 2.9.0
237          * @access private
238          * @see wpdb::tables()
239          * @var array
240          */
241         var $old_tables = array( 'categories', 'post2cat', 'link2cat' );
242
243         /**
244          * List of WordPress global tables
245          *
246          * @since 3.0.0
247          * @access private
248          * @see wpdb::tables()
249          * @var array
250          */
251         var $global_tables = array( 'users', 'usermeta' );
252
253         /**
254          * List of Multisite global tables
255          *
256          * @since 3.0.0
257          * @access private
258          * @see wpdb::tables()
259          * @var array
260          */
261         var $ms_global_tables = array( 'blogs', 'signups', 'site', 'sitemeta',
262                 'sitecategories', 'registration_log', 'blog_versions' );
263
264         /**
265          * WordPress Comments table
266          *
267          * @since 1.5.0
268          * @access public
269          * @var string
270          */
271         var $comments;
272
273         /**
274          * WordPress Comment Metadata table
275          *
276          * @since 2.9.0
277          * @access public
278          * @var string
279          */
280         var $commentmeta;
281
282         /**
283          * WordPress Links table
284          *
285          * @since 1.5.0
286          * @access public
287          * @var string
288          */
289         var $links;
290
291         /**
292          * WordPress Options table
293          *
294          * @since 1.5.0
295          * @access public
296          * @var string
297          */
298         var $options;
299
300         /**
301          * WordPress Post Metadata table
302          *
303          * @since 1.5.0
304          * @access public
305          * @var string
306          */
307         var $postmeta;
308
309         /**
310          * WordPress Posts table
311          *
312          * @since 1.5.0
313          * @access public
314          * @var string
315          */
316         var $posts;
317
318         /**
319          * WordPress Terms table
320          *
321          * @since 2.3.0
322          * @access public
323          * @var string
324          */
325         var $terms;
326
327         /**
328          * WordPress Term Relationships table
329          *
330          * @since 2.3.0
331          * @access public
332          * @var string
333          */
334         var $term_relationships;
335
336         /**
337          * WordPress Term Taxonomy table
338          *
339          * @since 2.3.0
340          * @access public
341          * @var string
342          */
343         var $term_taxonomy;
344
345         /*
346          * Global and Multisite tables
347          */
348
349         /**
350          * WordPress User Metadata table
351          *
352          * @since 2.3.0
353          * @access public
354          * @var string
355          */
356         var $usermeta;
357
358         /**
359          * WordPress Users table
360          *
361          * @since 1.5.0
362          * @access public
363          * @var string
364          */
365         var $users;
366
367         /**
368          * Multisite Blogs table
369          *
370          * @since 3.0.0
371          * @access public
372          * @var string
373          */
374         var $blogs;
375
376         /**
377          * Multisite Blog Versions table
378          *
379          * @since 3.0.0
380          * @access public
381          * @var string
382          */
383         var $blog_versions;
384
385         /**
386          * Multisite Registration Log table
387          *
388          * @since 3.0.0
389          * @access public
390          * @var string
391          */
392         var $registration_log;
393
394         /**
395          * Multisite Signups table
396          *
397          * @since 3.0.0
398          * @access public
399          * @var string
400          */
401         var $signups;
402
403         /**
404          * Multisite Sites table
405          *
406          * @since 3.0.0
407          * @access public
408          * @var string
409          */
410         var $site;
411
412         /**
413          * Multisite Sitewide Terms table
414          *
415          * @since 3.0.0
416          * @access public
417          * @var string
418          */
419         var $sitecategories;
420
421         /**
422          * Multisite Site Metadata table
423          *
424          * @since 3.0.0
425          * @access public
426          * @var string
427          */
428         var $sitemeta;
429
430         /**
431          * Format specifiers for DB columns. Columns not listed here default to %s. Initialized during WP load.
432          *
433          * Keys are column names, values are format types: 'ID' => '%d'
434          *
435          * @since 2.8.0
436          * @see wpdb::prepare()
437          * @see wpdb::insert()
438          * @see wpdb::update()
439          * @see wpdb::delete()
440          * @see wp_set_wpdb_vars()
441          * @access public
442          * @var array
443          */
444         var $field_types = array();
445
446         /**
447          * Database table columns charset
448          *
449          * @since 2.2.0
450          * @access public
451          * @var string
452          */
453         var $charset;
454
455         /**
456          * Database table columns collate
457          *
458          * @since 2.2.0
459          * @access public
460          * @var string
461          */
462         var $collate;
463
464         /**
465          * Database Username
466          *
467          * @since 2.9.0
468          * @access protected
469          * @var string
470          */
471         protected $dbuser;
472
473         /**
474          * Database Password
475          *
476          * @since 3.1.0
477          * @access protected
478          * @var string
479          */
480         protected $dbpassword;
481
482         /**
483          * Database Name
484          *
485          * @since 3.1.0
486          * @access protected
487          * @var string
488          */
489         protected $dbname;
490
491         /**
492          * Database Host
493          *
494          * @since 3.1.0
495          * @access protected
496          * @var string
497          */
498         protected $dbhost;
499
500         /**
501          * Database Handle
502          *
503          * @since 0.71
504          * @access protected
505          * @var string
506          */
507         protected $dbh;
508
509         /**
510          * A textual description of the last query/get_row/get_var call
511          *
512          * @since 3.0.0
513          * @access public
514          * @var string
515          */
516         var $func_call;
517
518         /**
519          * Whether MySQL is used as the database engine.
520          *
521          * Set in WPDB::db_connect() to true, by default. This is used when checking
522          * against the required MySQL version for WordPress. Normally, a replacement
523          * database drop-in (db.php) will skip these checks, but setting this to true
524          * will force the checks to occur.
525          *
526          * @since 3.3.0
527          * @access public
528          * @var bool
529          */
530         public $is_mysql = null;
531
532         /**
533          * A list of incompatible SQL modes.
534          *
535          * @since 3.9.0
536          * @access protected
537          * @var array
538          */
539         protected $incompatible_modes = array( 'NO_ZERO_DATE', 'ONLY_FULL_GROUP_BY',
540                 'STRICT_TRANS_TABLES', 'STRICT_ALL_TABLES', 'TRADITIONAL' );
541
542         /**
543          * Whether to use mysqli over mysql.
544          *
545          * @since 3.9.0
546          * @access private
547          * @var bool
548          */
549         private $use_mysqli = false;
550
551         /**
552          * Whether we've managed to successfully connect at some point
553          *
554          * @since 3.9.0
555          * @access private
556          * @var bool
557          */
558         private $has_connected = false;
559
560         /**
561          * Connects to the database server and selects a database
562          *
563          * PHP5 style constructor for compatibility with PHP5. Does
564          * the actual setting up of the class properties and connection
565          * to the database.
566          *
567          * @link http://core.trac.wordpress.org/ticket/3354
568          * @since 2.0.8
569          *
570          * @param string $dbuser MySQL database user
571          * @param string $dbpassword MySQL database password
572          * @param string $dbname MySQL database name
573          * @param string $dbhost MySQL database host
574          */
575         function __construct( $dbuser, $dbpassword, $dbname, $dbhost ) {
576                 register_shutdown_function( array( $this, '__destruct' ) );
577
578                 if ( WP_DEBUG && WP_DEBUG_DISPLAY )
579                         $this->show_errors();
580
581                 /* Use ext/mysqli if it exists and:
582                  *  - WP_USE_EXT_MYSQL is defined as false, or
583                  *  - We are a development version of WordPress, or
584                  *  - We are running PHP 5.5 or greater, or
585                  *  - ext/mysql is not loaded.
586                  */
587                 if ( function_exists( 'mysqli_connect' ) ) {
588                         if ( defined( 'WP_USE_EXT_MYSQL' ) ) {
589                                 $this->use_mysqli = ! WP_USE_EXT_MYSQL;
590                         } elseif ( version_compare( phpversion(), '5.5', '>=' ) || ! function_exists( 'mysql_connect' ) ) {
591                                 $this->use_mysqli = true;
592                         } elseif ( false !== strpos( $GLOBALS['wp_version'], '-' ) ) {
593                                 $this->use_mysqli = true;
594                         }
595                 }
596
597                 $this->init_charset();
598
599                 $this->dbuser = $dbuser;
600                 $this->dbpassword = $dbpassword;
601                 $this->dbname = $dbname;
602                 $this->dbhost = $dbhost;
603
604                 $this->db_connect();
605         }
606
607         /**
608          * PHP5 style destructor and will run when database object is destroyed.
609          *
610          * @see wpdb::__construct()
611          * @since 2.0.8
612          * @return bool true
613          */
614         function __destruct() {
615                 return true;
616         }
617
618         /**
619          * PHP5 style magic getter, used to lazy-load expensive data.
620          *
621          * @since 3.5.0
622          *
623          * @param string $name The private member to get, and optionally process
624          * @return mixed The private member
625          */
626         function __get( $name ) {
627                 if ( 'col_info' == $name )
628                         $this->load_col_info();
629
630                 return $this->$name;
631         }
632
633         /**
634          * Magic function, for backwards compatibility
635          *
636          * @since 3.5.0
637          *
638          * @param string $name  The private member to set
639          * @param mixed  $value The value to set
640          */
641         function __set( $name, $value ) {
642                 $this->$name = $value;
643         }
644
645         /**
646          * Magic function, for backwards compatibility
647          *
648          * @since 3.5.0
649          *
650          * @param string $name  The private member to check
651          *
652          * @return bool If the member is set or not
653          */
654         function __isset( $name ) {
655                 return isset( $this->$name );
656         }
657
658         /**
659          * Magic function, for backwards compatibility
660          *
661          * @since 3.5.0
662          *
663          * @param string $name  The private member to unset
664          */
665         function __unset( $name ) {
666                 unset( $this->$name );
667         }
668
669         /**
670          * Set $this->charset and $this->collate
671          *
672          * @since 3.1.0
673          */
674         function init_charset() {
675                 if ( function_exists('is_multisite') && is_multisite() ) {
676                         $this->charset = 'utf8';
677                         if ( defined( 'DB_COLLATE' ) && DB_COLLATE )
678                                 $this->collate = DB_COLLATE;
679                         else
680                                 $this->collate = 'utf8_general_ci';
681                 } elseif ( defined( 'DB_COLLATE' ) ) {
682                         $this->collate = DB_COLLATE;
683                 }
684
685                 if ( defined( 'DB_CHARSET' ) )
686                         $this->charset = DB_CHARSET;
687         }
688
689         /**
690          * Sets the connection's character set.
691          *
692          * @since 3.1.0
693          *
694          * @param resource $dbh     The resource given by mysql_connect
695          * @param string   $charset The character set (optional)
696          * @param string   $collate The collation (optional)
697          */
698         function set_charset( $dbh, $charset = null, $collate = null ) {
699                 if ( ! isset( $charset ) )
700                         $charset = $this->charset;
701                 if ( ! isset( $collate ) )
702                         $collate = $this->collate;
703                 if ( $this->has_cap( 'collation' ) && ! empty( $charset ) ) {
704                         if ( $this->use_mysqli ) {
705                                 if ( function_exists( 'mysqli_set_charset' ) && $this->has_cap( 'set_charset' ) ) {
706                                         mysqli_set_charset( $dbh, $charset );
707                                 } else {
708                                         $query = $this->prepare( 'SET NAMES %s', $charset );
709                                         if ( ! empty( $collate ) )
710                                                 $query .= $this->prepare( ' COLLATE %s', $collate );
711                                         mysqli_query( $query, $dbh );
712                                 }
713                         } else {
714                                 if ( function_exists( 'mysql_set_charset' ) && $this->has_cap( 'set_charset' ) ) {
715                                         mysql_set_charset( $charset, $dbh );
716                                 } else {
717                                         $query = $this->prepare( 'SET NAMES %s', $charset );
718                                         if ( ! empty( $collate ) )
719                                                 $query .= $this->prepare( ' COLLATE %s', $collate );
720                                         mysql_query( $query, $dbh );
721                                 }
722                         }
723                 }
724         }
725
726         /**
727          * Change the current SQL mode, and ensure its WordPress compatibility.
728          *
729          * If no modes are passed, it will ensure the current MySQL server
730          * modes are compatible.
731          *
732          * @since 3.9.0
733          *
734          * @param array $modes Optional. A list of SQL modes to set.
735          */
736         function set_sql_mode( $modes = array() ) {
737                 if ( empty( $modes ) ) {
738                         if ( $this->use_mysqli ) {
739                                 $res = mysqli_query( $this->dbh, 'SELECT @@SESSION.sql_mode' );
740                         } else {
741                                 $res = mysql_query( 'SELECT @@SESSION.sql_mode', $this->dbh );
742                         }
743
744                         if ( empty( $res ) ) {
745                                 return;
746                         }
747
748                         if ( $this->use_mysqli ) {
749                                 $modes_array = mysqli_fetch_array( $res );
750                                 if ( empty( $modes_array[0] ) ) {
751                                         return;
752                                 }
753                                 $modes_str = $modes_array[0];
754                         } else {
755                                 $modes_str = mysql_result( $res, 0 );
756                         }
757
758                         if ( empty( $modes_str ) ) {
759                                 return;
760                         }
761
762                         $modes = explode( ',', $modes_str );
763                 }
764
765                 $modes = array_change_key_case( $modes, CASE_UPPER );
766
767                 /**
768                  * Filter the list of incompatible SQL modes to exclude.
769                  *
770                  * @since 3.9.0
771                  *
772                  * @see wpdb::$incompatible_modes
773                  *
774                  * @param array $incompatible_modes An array of incompatible modes.
775                  */
776                 $incompatible_modes = (array) apply_filters( 'incompatible_sql_modes', $this->incompatible_modes );
777
778                 foreach( $modes as $i => $mode ) {
779                         if ( in_array( $mode, $incompatible_modes ) ) {
780                                 unset( $modes[ $i ] );
781                         }
782                 }
783
784                 $modes_str = implode( ',', $modes );
785
786                 if ( $this->use_mysqli ) {
787                         mysqli_query( $this->dbh, "SET SESSION sql_mode='$modes_str'" );
788                 } else {
789                         mysql_query( "SET SESSION sql_mode='$modes_str'", $this->dbh );
790                 }
791         }
792
793         /**
794          * Sets the table prefix for the WordPress tables.
795          *
796          * @since 2.5.0
797          *
798          * @param string $prefix Alphanumeric name for the new prefix.
799          * @param bool $set_table_names Optional. Whether the table names, e.g. wpdb::$posts, should be updated or not.
800          * @return string|WP_Error Old prefix or WP_Error on error
801          */
802         function set_prefix( $prefix, $set_table_names = true ) {
803
804                 if ( preg_match( '|[^a-z0-9_]|i', $prefix ) )
805                         return new WP_Error('invalid_db_prefix', 'Invalid database prefix' );
806
807                 $old_prefix = is_multisite() ? '' : $prefix;
808
809                 if ( isset( $this->base_prefix ) )
810                         $old_prefix = $this->base_prefix;
811
812                 $this->base_prefix = $prefix;
813
814                 if ( $set_table_names ) {
815                         foreach ( $this->tables( 'global' ) as $table => $prefixed_table )
816                                 $this->$table = $prefixed_table;
817
818                         if ( is_multisite() && empty( $this->blogid ) )
819                                 return $old_prefix;
820
821                         $this->prefix = $this->get_blog_prefix();
822
823                         foreach ( $this->tables( 'blog' ) as $table => $prefixed_table )
824                                 $this->$table = $prefixed_table;
825
826                         foreach ( $this->tables( 'old' ) as $table => $prefixed_table )
827                                 $this->$table = $prefixed_table;
828                 }
829                 return $old_prefix;
830         }
831
832         /**
833          * Sets blog id.
834          *
835          * @since 3.0.0
836          * @access public
837          * @param int $blog_id
838          * @param int $site_id Optional.
839          * @return string previous blog id
840          */
841         function set_blog_id( $blog_id, $site_id = 0 ) {
842                 if ( ! empty( $site_id ) )
843                         $this->siteid = $site_id;
844
845                 $old_blog_id  = $this->blogid;
846                 $this->blogid = $blog_id;
847
848                 $this->prefix = $this->get_blog_prefix();
849
850                 foreach ( $this->tables( 'blog' ) as $table => $prefixed_table )
851                         $this->$table = $prefixed_table;
852
853                 foreach ( $this->tables( 'old' ) as $table => $prefixed_table )
854                         $this->$table = $prefixed_table;
855
856                 return $old_blog_id;
857         }
858
859         /**
860          * Gets blog prefix.
861          *
862          * @uses is_multisite()
863          * @since 3.0.0
864          * @param int $blog_id Optional.
865          * @return string Blog prefix.
866          */
867         function get_blog_prefix( $blog_id = null ) {
868                 if ( is_multisite() ) {
869                         if ( null === $blog_id )
870                                 $blog_id = $this->blogid;
871                         $blog_id = (int) $blog_id;
872                         if ( defined( 'MULTISITE' ) && ( 0 == $blog_id || 1 == $blog_id ) )
873                                 return $this->base_prefix;
874                         else
875                                 return $this->base_prefix . $blog_id . '_';
876                 } else {
877                         return $this->base_prefix;
878                 }
879         }
880
881         /**
882          * Returns an array of WordPress tables.
883          *
884          * Also allows for the CUSTOM_USER_TABLE and CUSTOM_USER_META_TABLE to
885          * override the WordPress users and usermeta tables that would otherwise
886          * be determined by the prefix.
887          *
888          * The scope argument can take one of the following:
889          *
890          * 'all' - returns 'all' and 'global' tables. No old tables are returned.
891          * 'blog' - returns the blog-level tables for the queried blog.
892          * 'global' - returns the global tables for the installation, returning multisite tables only if running multisite.
893          * 'ms_global' - returns the multisite global tables, regardless if current installation is multisite.
894          * 'old' - returns tables which are deprecated.
895          *
896          * @since 3.0.0
897          * @uses wpdb::$tables
898          * @uses wpdb::$old_tables
899          * @uses wpdb::$global_tables
900          * @uses wpdb::$ms_global_tables
901          * @uses is_multisite()
902          *
903          * @param string $scope Optional. Can be all, global, ms_global, blog, or old tables. Defaults to all.
904          * @param bool $prefix Optional. Whether to include table prefixes. Default true. If blog
905          *      prefix is requested, then the custom users and usermeta tables will be mapped.
906          * @param int $blog_id Optional. The blog_id to prefix. Defaults to wpdb::$blogid. Used only when prefix is requested.
907          * @return array Table names. When a prefix is requested, the key is the unprefixed table name.
908          */
909         function tables( $scope = 'all', $prefix = true, $blog_id = 0 ) {
910                 switch ( $scope ) {
911                         case 'all' :
912                                 $tables = array_merge( $this->global_tables, $this->tables );
913                                 if ( is_multisite() )
914                                         $tables = array_merge( $tables, $this->ms_global_tables );
915                                 break;
916                         case 'blog' :
917                                 $tables = $this->tables;
918                                 break;
919                         case 'global' :
920                                 $tables = $this->global_tables;
921                                 if ( is_multisite() )
922                                         $tables = array_merge( $tables, $this->ms_global_tables );
923                                 break;
924                         case 'ms_global' :
925                                 $tables = $this->ms_global_tables;
926                                 break;
927                         case 'old' :
928                                 $tables = $this->old_tables;
929                                 break;
930                         default :
931                                 return array();
932                                 break;
933                 }
934
935                 if ( $prefix ) {
936                         if ( ! $blog_id )
937                                 $blog_id = $this->blogid;
938                         $blog_prefix = $this->get_blog_prefix( $blog_id );
939                         $base_prefix = $this->base_prefix;
940                         $global_tables = array_merge( $this->global_tables, $this->ms_global_tables );
941                         foreach ( $tables as $k => $table ) {
942                                 if ( in_array( $table, $global_tables ) )
943                                         $tables[ $table ] = $base_prefix . $table;
944                                 else
945                                         $tables[ $table ] = $blog_prefix . $table;
946                                 unset( $tables[ $k ] );
947                         }
948
949                         if ( isset( $tables['users'] ) && defined( 'CUSTOM_USER_TABLE' ) )
950                                 $tables['users'] = CUSTOM_USER_TABLE;
951
952                         if ( isset( $tables['usermeta'] ) && defined( 'CUSTOM_USER_META_TABLE' ) )
953                                 $tables['usermeta'] = CUSTOM_USER_META_TABLE;
954                 }
955
956                 return $tables;
957         }
958
959         /**
960          * Selects a database using the current database connection.
961          *
962          * The database name will be changed based on the current database
963          * connection. On failure, the execution will bail and display an DB error.
964          *
965          * @since 0.71
966          *
967          * @param string $db MySQL database name
968          * @param resource $dbh Optional link identifier.
969          * @return null Always null.
970          */
971         function select( $db, $dbh = null ) {
972                 if ( is_null($dbh) )
973                         $dbh = $this->dbh;
974
975                 if ( $this->use_mysqli ) {
976                         $success = @mysqli_select_db( $dbh, $db );
977                 } else {
978                         $success = @mysql_select_db( $db, $dbh );
979                 }
980                 if ( ! $success ) {
981                         $this->ready = false;
982                         if ( ! did_action( 'template_redirect' ) ) {
983                                 wp_load_translations_early();
984                                 $this->bail( sprintf( __( '<h1>Can&#8217;t select database</h1>
985 <p>We were able to connect to the database server (which means your username and password is okay) but not able to select the <code>%1$s</code> database.</p>
986 <ul>
987 <li>Are you sure it exists?</li>
988 <li>Does the user <code>%2$s</code> have permission to use the <code>%1$s</code> database?</li>
989 <li>On some systems the name of your database is prefixed with your username, so it would be like <code>username_%1$s</code>. Could that be the problem?</li>
990 </ul>
991 <p>If you don\'t know how to set up a database you should <strong>contact your host</strong>. If all else fails you may find help at the <a href="https://wordpress.org/support/">WordPress Support Forums</a>.</p>' ), htmlspecialchars( $db, ENT_QUOTES ), htmlspecialchars( $this->dbuser, ENT_QUOTES ) ), 'db_select_fail' );
992                         }
993                         return;
994                 }
995         }
996
997         /**
998          * Do not use, deprecated.
999          *
1000          * Use esc_sql() or wpdb::prepare() instead.
1001          *
1002          * @since 2.8.0
1003          * @deprecated 3.6.0
1004          * @see wpdb::prepare
1005          * @see esc_sql()
1006          * @access private
1007          *
1008          * @param string $string
1009          * @return string
1010          */
1011         function _weak_escape( $string ) {
1012                 if ( func_num_args() === 1 && function_exists( '_deprecated_function' ) )
1013                         _deprecated_function( __METHOD__, '3.6', 'wpdb::prepare() or esc_sql()' );
1014                 return addslashes( $string );
1015         }
1016
1017         /**
1018          * Real escape, using mysqli_real_escape_string() or mysql_real_escape_string()
1019          *
1020          * @see mysqli_real_escape_string()
1021          * @see mysql_real_escape_string()
1022          * @since 2.8.0
1023          * @access private
1024          *
1025          * @param  string $string to escape
1026          * @return string escaped
1027          */
1028         function _real_escape( $string ) {
1029                 if ( $this->dbh ) {
1030                         if ( $this->use_mysqli ) {
1031                                 return mysqli_real_escape_string( $this->dbh, $string );
1032                         } else {
1033                                 return mysql_real_escape_string( $string, $this->dbh );
1034                         }
1035                 }
1036
1037                 $class = get_class( $this );
1038                 _doing_it_wrong( $class, "$class must set a database connection for use with escaping.", E_USER_NOTICE );
1039                 return addslashes( $string );
1040         }
1041
1042         /**
1043          * Escape data. Works on arrays.
1044          *
1045          * @uses wpdb::_real_escape()
1046          * @since  2.8.0
1047          * @access private
1048          *
1049          * @param  string|array $data
1050          * @return string|array escaped
1051          */
1052         function _escape( $data ) {
1053                 if ( is_array( $data ) ) {
1054                         foreach ( $data as $k => $v ) {
1055                                 if ( is_array($v) )
1056                                         $data[$k] = $this->_escape( $v );
1057                                 else
1058                                         $data[$k] = $this->_real_escape( $v );
1059                         }
1060                 } else {
1061                         $data = $this->_real_escape( $data );
1062                 }
1063
1064                 return $data;
1065         }
1066
1067         /**
1068          * Do not use, deprecated.
1069          *
1070          * Use esc_sql() or wpdb::prepare() instead.
1071          *
1072          * @since 0.71
1073          * @deprecated 3.6.0
1074          * @see wpdb::prepare()
1075          * @see esc_sql()
1076          *
1077          * @param mixed $data
1078          * @return mixed
1079          */
1080         function escape( $data ) {
1081                 if ( func_num_args() === 1 && function_exists( '_deprecated_function' ) )
1082                         _deprecated_function( __METHOD__, '3.6', 'wpdb::prepare() or esc_sql()' );
1083                 if ( is_array( $data ) ) {
1084                         foreach ( $data as $k => $v ) {
1085                                 if ( is_array( $v ) )
1086                                         $data[$k] = $this->escape( $v, 'recursive' );
1087                                 else
1088                                         $data[$k] = $this->_weak_escape( $v, 'internal' );
1089                         }
1090                 } else {
1091                         $data = $this->_weak_escape( $data, 'internal' );
1092                 }
1093
1094                 return $data;
1095         }
1096
1097         /**
1098          * Escapes content by reference for insertion into the database, for security
1099          *
1100          * @uses wpdb::_real_escape()
1101          * @since 2.3.0
1102          * @param string $string to escape
1103          * @return void
1104          */
1105         function escape_by_ref( &$string ) {
1106                 if ( ! is_float( $string ) )
1107                         $string = $this->_real_escape( $string );
1108         }
1109
1110         /**
1111          * Prepares a SQL query for safe execution. Uses sprintf()-like syntax.
1112          *
1113          * The following directives can be used in the query format string:
1114          *   %d (integer)
1115          *   %f (float)
1116          *   %s (string)
1117          *   %% (literal percentage sign - no argument needed)
1118          *
1119          * All of %d, %f, and %s are to be left unquoted in the query string and they need an argument passed for them.
1120          * Literals (%) as parts of the query must be properly written as %%.
1121          *
1122          * This function only supports a small subset of the sprintf syntax; it only supports %d (integer), %f (float), and %s (string).
1123          * Does not support sign, padding, alignment, width or precision specifiers.
1124          * Does not support argument numbering/swapping.
1125          *
1126          * May be called like {@link http://php.net/sprintf sprintf()} or like {@link http://php.net/vsprintf vsprintf()}.
1127          *
1128          * Both %d and %s should be left unquoted in the query string.
1129          *
1130          * <code>
1131          * wpdb::prepare( "SELECT * FROM `table` WHERE `column` = %s AND `field` = %d", 'foo', 1337 )
1132          * wpdb::prepare( "SELECT DATE_FORMAT(`field`, '%%c') FROM `table` WHERE `column` = %s", 'foo' );
1133          * </code>
1134          *
1135          * @link http://php.net/sprintf Description of syntax.
1136          * @since 2.3.0
1137          *
1138          * @param string $query Query statement with sprintf()-like placeholders
1139          * @param array|mixed $args The array of variables to substitute into the query's placeholders if being called like
1140          *      {@link http://php.net/vsprintf vsprintf()}, or the first variable to substitute into the query's placeholders if
1141          *      being called like {@link http://php.net/sprintf sprintf()}.
1142          * @param mixed $args,... further variables to substitute into the query's placeholders if being called like
1143          *      {@link http://php.net/sprintf sprintf()}.
1144          * @return null|false|string Sanitized query string, null if there is no query, false if there is an error and string
1145          *      if there was something to prepare
1146          */
1147         function prepare( $query, $args ) {
1148                 if ( is_null( $query ) )
1149                         return;
1150
1151                 // This is not meant to be foolproof -- but it will catch obviously incorrect usage.
1152                 if ( strpos( $query, '%' ) === false ) {
1153                         _doing_it_wrong( 'wpdb::prepare', sprintf( __( 'The query argument of %s must have a placeholder.' ), 'wpdb::prepare()' ), '3.9' );
1154                 }
1155
1156                 $args = func_get_args();
1157                 array_shift( $args );
1158                 // If args were passed as an array (as in vsprintf), move them up
1159                 if ( isset( $args[0] ) && is_array($args[0]) )
1160                         $args = $args[0];
1161                 $query = str_replace( "'%s'", '%s', $query ); // in case someone mistakenly already singlequoted it
1162                 $query = str_replace( '"%s"', '%s', $query ); // doublequote unquoting
1163                 $query = preg_replace( '|(?<!%)%f|' , '%F', $query ); // Force floats to be locale unaware
1164                 $query = preg_replace( '|(?<!%)%s|', "'%s'", $query ); // quote the strings, avoiding escaped strings like %%s
1165                 array_walk( $args, array( $this, 'escape_by_ref' ) );
1166                 return @vsprintf( $query, $args );
1167         }
1168
1169         /**
1170          * Print SQL/DB error.
1171          *
1172          * @since 0.71
1173          * @global array $EZSQL_ERROR Stores error information of query and error string
1174          *
1175          * @param string $str The error to display
1176          * @return bool False if the showing of errors is disabled.
1177          */
1178         function print_error( $str = '' ) {
1179                 global $EZSQL_ERROR;
1180
1181                 if ( !$str ) {
1182                         if ( $this->use_mysqli ) {
1183                                 $str = mysqli_error( $this->dbh );
1184                         } else {
1185                                 $str = mysql_error( $this->dbh );
1186                         }
1187                 }
1188                 $EZSQL_ERROR[] = array( 'query' => $this->last_query, 'error_str' => $str );
1189
1190                 if ( $this->suppress_errors )
1191                         return false;
1192
1193                 wp_load_translations_early();
1194
1195                 if ( $caller = $this->get_caller() )
1196                         $error_str = sprintf( __( 'WordPress database error %1$s for query %2$s made by %3$s' ), $str, $this->last_query, $caller );
1197                 else
1198                         $error_str = sprintf( __( 'WordPress database error %1$s for query %2$s' ), $str, $this->last_query );
1199
1200                 error_log( $error_str );
1201
1202                 // Are we showing errors?
1203                 if ( ! $this->show_errors )
1204                         return false;
1205
1206                 // If there is an error then take note of it
1207                 if ( is_multisite() ) {
1208                         $msg = "WordPress database error: [$str]\n{$this->last_query}\n";
1209                         if ( defined( 'ERRORLOGFILE' ) )
1210                                 error_log( $msg, 3, ERRORLOGFILE );
1211                         if ( defined( 'DIEONDBERROR' ) )
1212                                 wp_die( $msg );
1213                 } else {
1214                         $str   = htmlspecialchars( $str, ENT_QUOTES );
1215                         $query = htmlspecialchars( $this->last_query, ENT_QUOTES );
1216
1217                         print "<div id='error'>
1218                         <p class='wpdberror'><strong>WordPress database error:</strong> [$str]<br />
1219                         <code>$query</code></p>
1220                         </div>";
1221                 }
1222         }
1223
1224         /**
1225          * Enables showing of database errors.
1226          *
1227          * This function should be used only to enable showing of errors.
1228          * wpdb::hide_errors() should be used instead for hiding of errors. However,
1229          * this function can be used to enable and disable showing of database
1230          * errors.
1231          *
1232          * @since 0.71
1233          * @see wpdb::hide_errors()
1234          *
1235          * @param bool $show Whether to show or hide errors
1236          * @return bool Old value for showing errors.
1237          */
1238         function show_errors( $show = true ) {
1239                 $errors = $this->show_errors;
1240                 $this->show_errors = $show;
1241                 return $errors;
1242         }
1243
1244         /**
1245          * Disables showing of database errors.
1246          *
1247          * By default database errors are not shown.
1248          *
1249          * @since 0.71
1250          * @see wpdb::show_errors()
1251          *
1252          * @return bool Whether showing of errors was active
1253          */
1254         function hide_errors() {
1255                 $show = $this->show_errors;
1256                 $this->show_errors = false;
1257                 return $show;
1258         }
1259
1260         /**
1261          * Whether to suppress database errors.
1262          *
1263          * By default database errors are suppressed, with a simple
1264          * call to this function they can be enabled.
1265          *
1266          * @since 2.5.0
1267          * @see wpdb::hide_errors()
1268          * @param bool $suppress Optional. New value. Defaults to true.
1269          * @return bool Old value
1270          */
1271         function suppress_errors( $suppress = true ) {
1272                 $errors = $this->suppress_errors;
1273                 $this->suppress_errors = (bool) $suppress;
1274                 return $errors;
1275         }
1276
1277         /**
1278          * Kill cached query results.
1279          *
1280          * @since 0.71
1281          * @return void
1282          */
1283         function flush() {
1284                 $this->last_result = array();
1285                 $this->col_info    = null;
1286                 $this->last_query  = null;
1287                 $this->rows_affected = $this->num_rows = 0;
1288                 $this->last_error  = '';
1289
1290                 if ( is_resource( $this->result ) ) {
1291                         if ( $this->use_mysqli ) {
1292                                 mysqli_free_result( $this->result );
1293                         } else {
1294                                 mysql_free_result( $this->result );
1295                         }
1296                 }
1297         }
1298
1299         /**
1300          * Connect to and select database.
1301          *
1302          * If $allow_bail is false, the lack of database connection will need
1303          * to be handled manually.
1304          *
1305          * @since 3.0.0
1306          * @since 3.9.0 $allow_bail parameter added.
1307          *
1308          * @param bool $allow_bail Optional. Allows the function to bail. Default true.
1309          * @return bool True with a successful connection, false on failure.
1310          */
1311         function db_connect( $allow_bail = true ) {
1312
1313                 $this->is_mysql = true;
1314
1315                 $new_link = defined( 'MYSQL_NEW_LINK' ) ? MYSQL_NEW_LINK : true;
1316                 $client_flags = defined( 'MYSQL_CLIENT_FLAGS' ) ? MYSQL_CLIENT_FLAGS : 0;
1317
1318                 if ( $this->use_mysqli ) {
1319                         $this->dbh = mysqli_init();
1320
1321                         // mysqli_real_connect doesn't support the host param including a port or socket
1322                         // like mysql_connect does. This duplicates how mysql_connect detects a port and/or socket file.
1323                         $port = null;
1324                         $socket = null;
1325                         $host = $this->dbhost;
1326                         $port_or_socket = strstr( $host, ':' );
1327                         if ( ! empty( $port_or_socket ) ) {
1328                                 $host = substr( $host, 0, strpos( $host, ':' ) );
1329                                 $port_or_socket = substr( $port_or_socket, 1 );
1330                                 if ( 0 !== strpos( $port_or_socket, '/' ) ) {
1331                                         $port = intval( $port_or_socket );
1332                                         $maybe_socket = strstr( $port_or_socket, ':' );
1333                                         if ( ! empty( $maybe_socket ) ) {
1334                                                 $socket = substr( $maybe_socket, 1 );
1335                                         }
1336                                 } else {
1337                                         $socket = $port_or_socket;
1338                                 }
1339                         }
1340
1341                         if ( WP_DEBUG ) {
1342                                 mysqli_real_connect( $this->dbh, $host, $this->dbuser, $this->dbpassword, null, $port, $socket, $client_flags );
1343                         } else {
1344                                 @mysqli_real_connect( $this->dbh, $host, $this->dbuser, $this->dbpassword, null, $port, $socket, $client_flags );
1345                         }
1346
1347                         if ( $this->dbh->connect_errno ) {
1348                                 $this->dbh = null;
1349
1350                                 /* It's possible ext/mysqli is misconfigured. Fall back to ext/mysql if:
1351                                  *  - We haven't previously connected, and
1352                                  *  - WP_USE_EXT_MYSQL isn't set to false, and
1353                                  *  - ext/mysql is loaded.
1354                                  */
1355                                 $attempt_fallback = true;
1356
1357                                 if ( $this->has_connected ) {
1358                                         $attempt_fallback = false;
1359                                 } else if ( defined( 'WP_USE_EXT_MYSQL' ) && ! WP_USE_EXT_MYSQL ) {
1360                                         $attempt_fallback = false;
1361                                 } else if ( ! function_exists( 'mysql_connect' ) ) {
1362                                         $attempt_fallback = false;
1363                                 }
1364
1365                                 if ( $attempt_fallback ) {
1366                                         $this->use_mysqli = false;
1367                                         $this->db_connect();
1368                                 }
1369                         }
1370                 } else {
1371                         if ( WP_DEBUG ) {
1372                                 $this->dbh = mysql_connect( $this->dbhost, $this->dbuser, $this->dbpassword, $new_link, $client_flags );
1373                         } else {
1374                                 $this->dbh = @mysql_connect( $this->dbhost, $this->dbuser, $this->dbpassword, $new_link, $client_flags );
1375                         }
1376                 }
1377
1378                 if ( ! $this->dbh && $allow_bail ) {
1379                         wp_load_translations_early();
1380
1381                         // Load custom DB error template, if present.
1382                         if ( file_exists( WP_CONTENT_DIR . '/db-error.php' ) ) {
1383                                 require_once( WP_CONTENT_DIR . '/db-error.php' );
1384                                 die();
1385                         }
1386
1387                         $this->bail( sprintf( __( "
1388 <h1>Error establishing a database connection</h1>
1389 <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>
1390 <ul>
1391         <li>Are you sure you have the correct username and password?</li>
1392         <li>Are you sure that you have typed the correct hostname?</li>
1393         <li>Are you sure that the database server is running?</li>
1394 </ul>
1395 <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='https://wordpress.org/support/'>WordPress Support Forums</a>.</p>
1396 " ), htmlspecialchars( $this->dbhost, ENT_QUOTES ) ), 'db_connect_fail' );
1397
1398                         return false;
1399                 } else if ( $this->dbh ) {
1400                         $this->has_connected = true;
1401                         $this->set_charset( $this->dbh );
1402                         $this->set_sql_mode();
1403                         $this->ready = true;
1404                         $this->select( $this->dbname, $this->dbh );
1405
1406                         return true;
1407                 }
1408
1409                 return false;
1410         }
1411
1412         /**
1413          * Check that the connection to the database is still up. If not, try to reconnect.
1414          *
1415          * If this function is unable to reconnect, it will forcibly die, or if after the
1416          * the template_redirect hook has been fired, return false instead.
1417          *
1418          * If $allow_bail is false, the lack of database connection will need
1419          * to be handled manually.
1420          *
1421          * @since 3.9.0
1422          *
1423          * @param bool $allow_bail Optional. Allows the function to bail. Default true.
1424          * @return bool True if the connection is up.
1425          */
1426         function check_connection( $allow_bail = true ) {
1427                 if ( $this->use_mysqli ) {
1428                         if ( @mysqli_ping( $this->dbh ) ) {
1429                                 return true;
1430                         }
1431                 } else {
1432                         if ( @mysql_ping( $this->dbh ) ) {
1433                                 return true;
1434                         }
1435                 }
1436
1437                 $error_reporting = false;
1438
1439                 // Disable warnings, as we don't want to see a multitude of "unable to connect" messages
1440                 if ( WP_DEBUG ) {
1441                         $error_reporting = error_reporting();
1442                         error_reporting( $error_reporting & ~E_WARNING );
1443                 }
1444
1445                 for ( $tries = 1; $tries <= $this->reconnect_retries; $tries++ ) {
1446                         // On the last try, re-enable warnings. We want to see a single instance of the
1447                         // "unable to connect" message on the bail() screen, if it appears.
1448                         if ( $this->reconnect_retries === $tries && WP_DEBUG ) {
1449                                 error_reporting( $error_reporting );
1450                         }
1451
1452                         if ( $this->db_connect( false ) ) {
1453                                 if ( $error_reporting ) {
1454                                         error_reporting( $error_reporting );
1455                                 }
1456
1457                                 return true;
1458                         }
1459
1460                         sleep( 1 );
1461                 }
1462
1463                 // If template_redirect has already happened, it's too late for wp_die()/dead_db().
1464                 // Let's just return and hope for the best.
1465                 if ( did_action( 'template_redirect' ) ) {
1466                         return false;
1467                 }
1468
1469                 if ( ! $allow_bail ) {
1470                         return false;
1471                 }
1472
1473                 // We weren't able to reconnect, so we better bail.
1474                 $this->bail( sprintf( ( "
1475 <h1>Error reconnecting to the database</h1>
1476 <p>This means that we lost contact with the database server at <code>%s</code>. This could mean your host's database server is down.</p>
1477 <ul>
1478         <li>Are you sure that the database server is running?</li>
1479         <li>Are you sure that the database server is not under particularly heavy load?</li>
1480 </ul>
1481 <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='https://wordpress.org/support/'>WordPress Support Forums</a>.</p>
1482 " ), htmlspecialchars( $this->dbhost, ENT_QUOTES ) ), 'db_connect_fail' );
1483
1484                 // Call dead_db() if bail didn't die, because this database is no more. It has ceased to be (at least temporarily).
1485                 dead_db();
1486         }
1487
1488         /**
1489          * Perform a MySQL database query, using current database connection.
1490          *
1491          * More information can be found on the codex page.
1492          *
1493          * @since 0.71
1494          *
1495          * @param string $query Database query
1496          * @return int|false Number of rows affected/selected or false on error
1497          */
1498         function query( $query ) {
1499                 if ( ! $this->ready )
1500                         return false;
1501
1502                 /**
1503                  * Filter the database query.
1504                  *
1505                  * Some queries are made before the plugins have been loaded,
1506                  * and thus cannot be filtered with this method.
1507                  *
1508                  * @since 2.1.0
1509                  *
1510                  * @param string $query Database query.
1511                  */
1512                 $query = apply_filters( 'query', $query );
1513
1514                 $return_val = 0;
1515                 $this->flush();
1516
1517                 // Log how the function was called
1518                 $this->func_call = "\$db->query(\"$query\")";
1519
1520                 // Keep track of the last query for debug..
1521                 $this->last_query = $query;
1522
1523                 $this->_do_query( $query );
1524
1525                 // MySQL server has gone away, try to reconnect
1526                 $mysql_errno = 0;
1527                 if ( ! empty( $this->dbh ) ) {
1528                         if ( $this->use_mysqli ) {
1529                                 $mysql_errno = mysqli_errno( $this->dbh );
1530                         } else {
1531                                 $mysql_errno = mysql_errno( $this->dbh );
1532                         }
1533                 }
1534
1535                 if ( empty( $this->dbh ) || 2006 == $mysql_errno ) {
1536                         if ( $this->check_connection() ) {
1537                                 $this->_do_query( $query );
1538                         } else {
1539                                 $this->insert_id = 0;
1540                                 return false;
1541                         }
1542                 }
1543
1544                 // If there is an error then take note of it..
1545                 if ( $this->use_mysqli ) {
1546                         $this->last_error = mysqli_error( $this->dbh );
1547                 } else {
1548                         $this->last_error = mysql_error( $this->dbh );
1549                 }
1550
1551                 if ( $this->last_error ) {
1552                         // Clear insert_id on a subsequent failed insert.
1553                         if ( $this->insert_id && preg_match( '/^\s*(insert|replace)\s/i', $query ) )
1554                                 $this->insert_id = 0;
1555
1556                         $this->print_error();
1557                         return false;
1558                 }
1559
1560                 if ( preg_match( '/^\s*(create|alter|truncate|drop)\s/i', $query ) ) {
1561                         $return_val = $this->result;
1562                 } elseif ( preg_match( '/^\s*(insert|delete|update|replace)\s/i', $query ) ) {
1563                         if ( $this->use_mysqli ) {
1564                                 $this->rows_affected = mysqli_affected_rows( $this->dbh );
1565                         } else {
1566                                 $this->rows_affected = mysql_affected_rows( $this->dbh );
1567                         }
1568                         // Take note of the insert_id
1569                         if ( preg_match( '/^\s*(insert|replace)\s/i', $query ) ) {
1570                                 if ( $this->use_mysqli ) {
1571                                         $this->insert_id = mysqli_insert_id( $this->dbh );
1572                                 } else {
1573                                         $this->insert_id = mysql_insert_id( $this->dbh );
1574                                 }
1575                         }
1576                         // Return number of rows affected
1577                         $return_val = $this->rows_affected;
1578                 } else {
1579                         $num_rows = 0;
1580                         if ( $this->use_mysqli ) {
1581                                 while ( $row = @mysqli_fetch_object( $this->result ) ) {
1582                                         $this->last_result[$num_rows] = $row;
1583                                         $num_rows++;
1584                                 }
1585                         } else {
1586                                 while ( $row = @mysql_fetch_object( $this->result ) ) {
1587                                         $this->last_result[$num_rows] = $row;
1588                                         $num_rows++;
1589                                 }
1590                         }
1591
1592                         // Log number of rows the query returned
1593                         // and return number of rows selected
1594                         $this->num_rows = $num_rows;
1595                         $return_val     = $num_rows;
1596                 }
1597
1598                 return $return_val;
1599         }
1600
1601         /**
1602          * Internal function to perform the mysql_query() call.
1603          *
1604          * @since 3.9.0
1605          *
1606          * @access private
1607          * @see wpdb::query()
1608          *
1609          * @param string $query The query to run.
1610          */
1611         private function _do_query( $query ) {
1612                 if ( defined( 'SAVEQUERIES' ) && SAVEQUERIES ) {
1613                         $this->timer_start();
1614                 }
1615
1616                 if ( $this->use_mysqli ) {
1617                         $this->result = @mysqli_query( $this->dbh, $query );
1618                 } else {
1619                         $this->result = @mysql_query( $query, $this->dbh );
1620                 }
1621                 $this->num_queries++;
1622
1623                 if ( defined( 'SAVEQUERIES' ) && SAVEQUERIES ) {
1624                         $this->queries[] = array( $query, $this->timer_stop(), $this->get_caller() );
1625                 }
1626         }
1627
1628         /**
1629          * Insert a row into a table.
1630          *
1631          * <code>
1632          * wpdb::insert( 'table', array( 'column' => 'foo', 'field' => 'bar' ) )
1633          * wpdb::insert( 'table', array( 'column' => 'foo', 'field' => 1337 ), array( '%s', '%d' ) )
1634          * </code>
1635          *
1636          * @since 2.5.0
1637          * @see wpdb::prepare()
1638          * @see wpdb::$field_types
1639          * @see wp_set_wpdb_vars()
1640          *
1641          * @param string $table table name
1642          * @param array $data Data to insert (in column => value pairs). Both $data columns and $data values should be "raw" (neither should be SQL escaped).
1643          * @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.
1644          *      A format is one of '%d', '%f', '%s' (integer, float, string). If omitted, all values in $data will be treated as strings unless otherwise specified in wpdb::$field_types.
1645          * @return int|false The number of rows inserted, or false on error.
1646          */
1647         function insert( $table, $data, $format = null ) {
1648                 return $this->_insert_replace_helper( $table, $data, $format, 'INSERT' );
1649         }
1650
1651         /**
1652          * Replace a row into a table.
1653          *
1654          * <code>
1655          * wpdb::replace( 'table', array( 'column' => 'foo', 'field' => 'bar' ) )
1656          * wpdb::replace( 'table', array( 'column' => 'foo', 'field' => 1337 ), array( '%s', '%d' ) )
1657          * </code>
1658          *
1659          * @since 3.0.0
1660          * @see wpdb::prepare()
1661          * @see wpdb::$field_types
1662          * @see wp_set_wpdb_vars()
1663          *
1664          * @param string $table table name
1665          * @param array $data Data to insert (in column => value pairs). Both $data columns and $data values should be "raw" (neither should be SQL escaped).
1666          * @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.
1667          *      A format is one of '%d', '%f', '%s' (integer, float, string). If omitted, all values in $data will be treated as strings unless otherwise specified in wpdb::$field_types.
1668          * @return int|false The number of rows affected, or false on error.
1669          */
1670         function replace( $table, $data, $format = null ) {
1671                 return $this->_insert_replace_helper( $table, $data, $format, 'REPLACE' );
1672         }
1673
1674         /**
1675          * Helper function for insert and replace.
1676          *
1677          * Runs an insert or replace query based on $type argument.
1678          *
1679          * @access private
1680          * @since 3.0.0
1681          * @see wpdb::prepare()
1682          * @see wpdb::$field_types
1683          * @see wp_set_wpdb_vars()
1684          *
1685          * @param string $table table name
1686          * @param array $data Data to insert (in column => value pairs). Both $data columns and $data values should be "raw" (neither should be SQL escaped).
1687          * @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.
1688          *      A format is one of '%d', '%f', '%s' (integer, float, string). If omitted, all values in $data will be treated as strings unless otherwise specified in wpdb::$field_types.
1689          * @param string $type Optional. What type of operation is this? INSERT or REPLACE. Defaults to INSERT.
1690          * @return int|false The number of rows affected, or false on error.
1691          */
1692         function _insert_replace_helper( $table, $data, $format = null, $type = 'INSERT' ) {
1693                 if ( ! in_array( strtoupper( $type ), array( 'REPLACE', 'INSERT' ) ) )
1694                         return false;
1695                 $this->insert_id = 0;
1696                 $formats = $format = (array) $format;
1697                 $fields = array_keys( $data );
1698                 $formatted_fields = array();
1699                 foreach ( $fields as $field ) {
1700                         if ( !empty( $format ) )
1701                                 $form = ( $form = array_shift( $formats ) ) ? $form : $format[0];
1702                         elseif ( isset( $this->field_types[$field] ) )
1703                                 $form = $this->field_types[$field];
1704                         else
1705                                 $form = '%s';
1706                         $formatted_fields[] = $form;
1707                 }
1708                 $sql = "{$type} INTO `$table` (`" . implode( '`,`', $fields ) . "`) VALUES (" . implode( ",", $formatted_fields ) . ")";
1709                 return $this->query( $this->prepare( $sql, $data ) );
1710         }
1711
1712         /**
1713          * Update a row in the table
1714          *
1715          * <code>
1716          * wpdb::update( 'table', array( 'column' => 'foo', 'field' => 'bar' ), array( 'ID' => 1 ) )
1717          * wpdb::update( 'table', array( 'column' => 'foo', 'field' => 1337 ), array( 'ID' => 1 ), array( '%s', '%d' ), array( '%d' ) )
1718          * </code>
1719          *
1720          * @since 2.5.0
1721          * @see wpdb::prepare()
1722          * @see wpdb::$field_types
1723          * @see wp_set_wpdb_vars()
1724          *
1725          * @param string $table table name
1726          * @param array $data Data to update (in column => value pairs). Both $data columns and $data values should be "raw" (neither should be SQL escaped).
1727          * @param array $where A named array of WHERE clauses (in column => value pairs). Multiple clauses will be joined with ANDs. Both $where columns and $where values should be "raw".
1728          * @param array|string $format Optional. An array of formats to be mapped to each of the values in $data. If string, that format will be used for all of the values in $data.
1729          *      A format is one of '%d', '%f', '%s' (integer, float, string). If omitted, all values in $data will be treated as strings unless otherwise specified in wpdb::$field_types.
1730          * @param array|string $where_format 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', '%f', '%s' (integer, float, string). If omitted, all values in $where will be treated as strings.
1731          * @return int|false The number of rows updated, or false on error.
1732          */
1733         function update( $table, $data, $where, $format = null, $where_format = null ) {
1734                 if ( ! is_array( $data ) || ! is_array( $where ) )
1735                         return false;
1736
1737                 $formats = $format = (array) $format;
1738                 $bits = $wheres = array();
1739                 foreach ( (array) array_keys( $data ) as $field ) {
1740                         if ( !empty( $format ) )
1741                                 $form = ( $form = array_shift( $formats ) ) ? $form : $format[0];
1742                         elseif ( isset($this->field_types[$field]) )
1743                                 $form = $this->field_types[$field];
1744                         else
1745                                 $form = '%s';
1746                         $bits[] = "`$field` = {$form}";
1747                 }
1748
1749                 $where_formats = $where_format = (array) $where_format;
1750                 foreach ( (array) array_keys( $where ) as $field ) {
1751                         if ( !empty( $where_format ) )
1752                                 $form = ( $form = array_shift( $where_formats ) ) ? $form : $where_format[0];
1753                         elseif ( isset( $this->field_types[$field] ) )
1754                                 $form = $this->field_types[$field];
1755                         else
1756                                 $form = '%s';
1757                         $wheres[] = "`$field` = {$form}";
1758                 }
1759
1760                 $sql = "UPDATE `$table` SET " . implode( ', ', $bits ) . ' WHERE ' . implode( ' AND ', $wheres );
1761                 return $this->query( $this->prepare( $sql, array_merge( array_values( $data ), array_values( $where ) ) ) );
1762         }
1763
1764         /**
1765          * Delete a row in the table
1766          *
1767          * <code>
1768          * wpdb::delete( 'table', array( 'ID' => 1 ) )
1769          * wpdb::delete( 'table', array( 'ID' => 1 ), array( '%d' ) )
1770          * </code>
1771          *
1772          * @since 3.4.0
1773          * @see wpdb::prepare()
1774          * @see wpdb::$field_types
1775          * @see wp_set_wpdb_vars()
1776          *
1777          * @param string $table table name
1778          * @param array $where A named array of WHERE clauses (in column => value pairs). Multiple clauses will be joined with ANDs. Both $where columns and $where values should be "raw".
1779          * @param array|string $where_format 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', '%f', '%s' (integer, float, string). If omitted, all values in $where will be treated as strings unless otherwise specified in wpdb::$field_types.
1780          * @return int|false The number of rows updated, or false on error.
1781          */
1782         function delete( $table, $where, $where_format = null ) {
1783                 if ( ! is_array( $where ) )
1784                         return false;
1785
1786                 $bits = $wheres = array();
1787
1788                 $where_formats = $where_format = (array) $where_format;
1789
1790                 foreach ( array_keys( $where ) as $field ) {
1791                         if ( !empty( $where_format ) ) {
1792                                 $form = ( $form = array_shift( $where_formats ) ) ? $form : $where_format[0];
1793                         } elseif ( isset( $this->field_types[ $field ] ) ) {
1794                                 $form = $this->field_types[ $field ];
1795                         } else {
1796                                 $form = '%s';
1797                         }
1798
1799                         $wheres[] = "$field = $form";
1800                 }
1801
1802                 $sql = "DELETE FROM $table WHERE " . implode( ' AND ', $wheres );
1803                 return $this->query( $this->prepare( $sql, $where ) );
1804         }
1805
1806
1807         /**
1808          * Retrieve one variable from the database.
1809          *
1810          * Executes a SQL query and returns the value from the SQL result.
1811          * If the SQL result contains more than one column and/or more than one row, this function returns the value in the column and row specified.
1812          * If $query is null, this function returns the value in the specified column and row from the previous SQL result.
1813          *
1814          * @since 0.71
1815          *
1816          * @param string|null $query Optional. SQL query. Defaults to null, use the result from the previous query.
1817          * @param int $x Optional. Column of value to return. Indexed from 0.
1818          * @param int $y Optional. Row of value to return. Indexed from 0.
1819          * @return string|null Database query result (as string), or null on failure
1820          */
1821         function get_var( $query = null, $x = 0, $y = 0 ) {
1822                 $this->func_call = "\$db->get_var(\"$query\", $x, $y)";
1823                 if ( $query )
1824                         $this->query( $query );
1825
1826                 // Extract var out of cached results based x,y vals
1827                 if ( !empty( $this->last_result[$y] ) ) {
1828                         $values = array_values( get_object_vars( $this->last_result[$y] ) );
1829                 }
1830
1831                 // If there is a value return it else return null
1832                 return ( isset( $values[$x] ) && $values[$x] !== '' ) ? $values[$x] : null;
1833         }
1834
1835         /**
1836          * Retrieve one row from the database.
1837          *
1838          * Executes a SQL query and returns the row from the SQL result.
1839          *
1840          * @since 0.71
1841          *
1842          * @param string|null $query SQL query.
1843          * @param string $output Optional. one of ARRAY_A | ARRAY_N | OBJECT constants. Return an associative array (column => value, ...),
1844          *      a numerically indexed array (0 => value, ...) or an object ( ->column = value ), respectively.
1845          * @param int $y Optional. Row to return. Indexed from 0.
1846          * @return mixed Database query result in format specified by $output or null on failure
1847          */
1848         function get_row( $query = null, $output = OBJECT, $y = 0 ) {
1849                 $this->func_call = "\$db->get_row(\"$query\",$output,$y)";
1850                 if ( $query )
1851                         $this->query( $query );
1852                 else
1853                         return null;
1854
1855                 if ( !isset( $this->last_result[$y] ) )
1856                         return null;
1857
1858                 if ( $output == OBJECT ) {
1859                         return $this->last_result[$y] ? $this->last_result[$y] : null;
1860                 } elseif ( $output == ARRAY_A ) {
1861                         return $this->last_result[$y] ? get_object_vars( $this->last_result[$y] ) : null;
1862                 } elseif ( $output == ARRAY_N ) {
1863                         return $this->last_result[$y] ? array_values( get_object_vars( $this->last_result[$y] ) ) : null;
1864                 } elseif ( strtoupper( $output ) === OBJECT ) {
1865                         // Back compat for OBJECT being previously case insensitive.
1866                         return $this->last_result[$y] ? $this->last_result[$y] : null;
1867                 } else {
1868                         $this->print_error( " \$db->get_row(string query, output type, int offset) -- Output type must be one of: OBJECT, ARRAY_A, ARRAY_N" );
1869                 }
1870         }
1871
1872         /**
1873          * Retrieve one column from the database.
1874          *
1875          * Executes a SQL query and returns the column from the SQL result.
1876          * If the SQL result contains more than one column, this function returns the column specified.
1877          * If $query is null, this function returns the specified column from the previous SQL result.
1878          *
1879          * @since 0.71
1880          *
1881          * @param string|null $query Optional. SQL query. Defaults to previous query.
1882          * @param int $x Optional. Column to return. Indexed from 0.
1883          * @return array Database query result. Array indexed from 0 by SQL result row number.
1884          */
1885         function get_col( $query = null , $x = 0 ) {
1886                 if ( $query )
1887                         $this->query( $query );
1888
1889                 $new_array = array();
1890                 // Extract the column values
1891                 for ( $i = 0, $j = count( $this->last_result ); $i < $j; $i++ ) {
1892                         $new_array[$i] = $this->get_var( null, $x, $i );
1893                 }
1894                 return $new_array;
1895         }
1896
1897         /**
1898          * Retrieve an entire SQL result set from the database (i.e., many rows)
1899          *
1900          * Executes a SQL query and returns the entire SQL result.
1901          *
1902          * @since 0.71
1903          *
1904          * @param string $query SQL query.
1905          * @param string $output Optional. Any 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.
1906          *      Each row is an associative array (column => value, ...), a numerically indexed array (0 => value, ...), or an object. ( ->column = value ), respectively.
1907          *      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.
1908          * @return mixed Database query results
1909          */
1910         function get_results( $query = null, $output = OBJECT ) {
1911                 $this->func_call = "\$db->get_results(\"$query\", $output)";
1912
1913                 if ( $query )
1914                         $this->query( $query );
1915                 else
1916                         return null;
1917
1918                 $new_array = array();
1919                 if ( $output == OBJECT ) {
1920                         // Return an integer-keyed array of row objects
1921                         return $this->last_result;
1922                 } elseif ( $output == OBJECT_K ) {
1923                         // Return an array of row objects with keys from column 1
1924                         // (Duplicates are discarded)
1925                         foreach ( $this->last_result as $row ) {
1926                                 $var_by_ref = get_object_vars( $row );
1927                                 $key = array_shift( $var_by_ref );
1928                                 if ( ! isset( $new_array[ $key ] ) )
1929                                         $new_array[ $key ] = $row;
1930                         }
1931                         return $new_array;
1932                 } elseif ( $output == ARRAY_A || $output == ARRAY_N ) {
1933                         // Return an integer-keyed array of...
1934                         if ( $this->last_result ) {
1935                                 foreach( (array) $this->last_result as $row ) {
1936                                         if ( $output == ARRAY_N ) {
1937                                                 // ...integer-keyed row arrays
1938                                                 $new_array[] = array_values( get_object_vars( $row ) );
1939                                         } else {
1940                                                 // ...column name-keyed row arrays
1941                                                 $new_array[] = get_object_vars( $row );
1942                                         }
1943                                 }
1944                         }
1945                         return $new_array;
1946                 } elseif ( strtoupper( $output ) === OBJECT ) {
1947                         // Back compat for OBJECT being previously case insensitive.
1948                         return $this->last_result;
1949                 }
1950                 return null;
1951         }
1952
1953         /**
1954          * Load the column metadata from the last query.
1955          *
1956          * @since 3.5.0
1957          *
1958          * @access protected
1959          */
1960         protected function load_col_info() {
1961                 if ( $this->col_info )
1962                         return;
1963
1964                 if ( $this->use_mysqli ) {
1965                         for ( $i = 0; $i < @mysqli_num_fields( $this->result ); $i++ ) {
1966                                 $this->col_info[ $i ] = @mysqli_fetch_field( $this->result );
1967                         }
1968                 } else {
1969                         for ( $i = 0; $i < @mysql_num_fields( $this->result ); $i++ ) {
1970                                 $this->col_info[ $i ] = @mysql_fetch_field( $this->result, $i );
1971                         }
1972                 }
1973         }
1974
1975         /**
1976          * Retrieve column metadata from the last query.
1977          *
1978          * @since 0.71
1979          *
1980          * @param string $info_type Optional. Type one of name, table, def, max_length, not_null, primary_key, multiple_key, unique_key, numeric, blob, type, unsigned, zerofill
1981          * @param int $col_offset Optional. 0: col name. 1: which table the col's in. 2: col's max length. 3: if the col is numeric. 4: col's type
1982          * @return mixed Column Results
1983          */
1984         function get_col_info( $info_type = 'name', $col_offset = -1 ) {
1985                 $this->load_col_info();
1986
1987                 if ( $this->col_info ) {
1988                         if ( $col_offset == -1 ) {
1989                                 $i = 0;
1990                                 $new_array = array();
1991                                 foreach( (array) $this->col_info as $col ) {
1992                                         $new_array[$i] = $col->{$info_type};
1993                                         $i++;
1994                                 }
1995                                 return $new_array;
1996                         } else {
1997                                 return $this->col_info[$col_offset]->{$info_type};
1998                         }
1999                 }
2000         }
2001
2002         /**
2003          * Starts the timer, for debugging purposes.
2004          *
2005          * @since 1.5.0
2006          *
2007          * @return true
2008          */
2009         function timer_start() {
2010                 $this->time_start = microtime( true );
2011                 return true;
2012         }
2013
2014         /**
2015          * Stops the debugging timer.
2016          *
2017          * @since 1.5.0
2018          *
2019          * @return float Total time spent on the query, in seconds
2020          */
2021         function timer_stop() {
2022                 return ( microtime( true ) - $this->time_start );
2023         }
2024
2025         /**
2026          * Wraps errors in a nice header and footer and dies.
2027          *
2028          * Will not die if wpdb::$show_errors is false.
2029          *
2030          * @since 1.5.0
2031          *
2032          * @param string $message The Error message
2033          * @param string $error_code Optional. A Computer readable string to identify the error.
2034          * @return false|void
2035          */
2036         function bail( $message, $error_code = '500' ) {
2037                 if ( !$this->show_errors ) {
2038                         if ( class_exists( 'WP_Error' ) )
2039                                 $this->error = new WP_Error($error_code, $message);
2040                         else
2041                                 $this->error = $message;
2042                         return false;
2043                 }
2044                 wp_die($message);
2045         }
2046
2047         /**
2048          * Whether MySQL database is at least the required minimum version.
2049          *
2050          * @since 2.5.0
2051          * @uses $wp_version
2052          * @uses $required_mysql_version
2053          *
2054          * @return WP_Error
2055          */
2056         function check_database_version() {
2057                 global $wp_version, $required_mysql_version;
2058                 // Make sure the server has the required MySQL version
2059                 if ( version_compare($this->db_version(), $required_mysql_version, '<') )
2060                         return new WP_Error('database_version', sprintf( __( '<strong>ERROR</strong>: WordPress %1$s requires MySQL %2$s or higher' ), $wp_version, $required_mysql_version ));
2061         }
2062
2063         /**
2064          * Whether the database supports collation.
2065          *
2066          * Called when WordPress is generating the table scheme.
2067          *
2068          * @since 2.5.0
2069          * @deprecated 3.5.0
2070          * @deprecated Use wpdb::has_cap( 'collation' )
2071          *
2072          * @return bool True if collation is supported, false if version does not
2073          */
2074         function supports_collation() {
2075                 _deprecated_function( __FUNCTION__, '3.5', 'wpdb::has_cap( \'collation\' )' );
2076                 return $this->has_cap( 'collation' );
2077         }
2078
2079         /**
2080          * The database character collate.
2081          *
2082          * @since 3.5.0
2083          *
2084          * @return string The database character collate.
2085          */
2086         public function get_charset_collate() {
2087                 $charset_collate = '';
2088
2089                 if ( ! empty( $this->charset ) )
2090                         $charset_collate = "DEFAULT CHARACTER SET $this->charset";
2091                 if ( ! empty( $this->collate ) )
2092                         $charset_collate .= " COLLATE $this->collate";
2093
2094                 return $charset_collate;
2095         }
2096
2097         /**
2098          * Determine if a database supports a particular feature.
2099          *
2100          * @since 2.7.0
2101          * @see wpdb::db_version()
2102          *
2103          * @param string $db_cap The feature to check for.
2104          * @return bool
2105          */
2106         function has_cap( $db_cap ) {
2107                 $version = $this->db_version();
2108
2109                 switch ( strtolower( $db_cap ) ) {
2110                         case 'collation' :    // @since 2.5.0
2111                         case 'group_concat' : // @since 2.7.0
2112                         case 'subqueries' :   // @since 2.7.0
2113                                 return version_compare( $version, '4.1', '>=' );
2114                         case 'set_charset' :
2115                                 return version_compare( $version, '5.0.7', '>=' );
2116                 };
2117
2118                 return false;
2119         }
2120
2121         /**
2122          * Retrieve the name of the function that called wpdb.
2123          *
2124          * Searches up the list of functions until it reaches
2125          * the one that would most logically had called this method.
2126          *
2127          * @since 2.5.0
2128          *
2129          * @return string The name of the calling function
2130          */
2131         function get_caller() {
2132                 return wp_debug_backtrace_summary( __CLASS__ );
2133         }
2134
2135         /**
2136          * The database version number.
2137          *
2138          * @since 2.7.0
2139          *
2140          * @return false|string false on failure, version number on success
2141          */
2142         function db_version() {
2143                 if ( $this->use_mysqli ) {
2144                         $server_info = mysqli_get_server_info( $this->dbh );
2145                 } else {
2146                         $server_info = mysql_get_server_info( $this->dbh );
2147                 }
2148                 return preg_replace( '/[^0-9.].*/', '', $server_info );
2149         }
2150 }