Ticket #41956: 41956.diff
File 41956.diff, 61.0 KB (added by , 7 years ago) |
---|
-
src/wp-includes/wp-db.php
208 208 * @since 3.0.0 209 209 * @var string 210 210 */ 211 211 public $base_prefix; 212 212 213 213 /** 214 214 * Whether the database queries are ready to start executing. … … 241 241 * @see wpdb::tables() 242 242 * @var array 243 243 */ 244 var $tables = array( 'posts', 'comments', 'links', 'options', 'postmeta', 245 'terms', 'term_taxonomy', 'term_relationships', 'termmeta', 'commentmeta' ); 244 var $tables = array( 245 'posts', 246 'comments', 247 'links', 248 'options', 249 'postmeta', 250 'terms', 251 'term_taxonomy', 252 'term_relationships', 253 'termmeta', 254 'commentmeta' 255 ); 246 256 247 257 /** 248 258 * List of deprecated WordPress tables … … 271 281 * @see wpdb::tables() 272 282 * @var array 273 283 */ 274 var $ms_global_tables = array( 'blogs', 'signups', 'site', 'sitemeta', 275 'sitecategories', 'registration_log', 'blog_versions' ); 284 var $ms_global_tables = array( 285 'blogs', 286 'signups', 287 'site', 288 'sitemeta', 289 'sitecategories', 290 'registration_log', 291 'blog_versions' 292 ); 276 293 277 294 /** 278 295 * WordPress Comments table … … 528 545 * @since 3.9.0 529 546 * @var array 530 547 */ 531 protected $incompatible_modes = array( 'NO_ZERO_DATE', 'ONLY_FULL_GROUP_BY', 532 'STRICT_TRANS_TABLES', 'STRICT_ALL_TABLES', 'TRADITIONAL' ); 548 protected $incompatible_modes = array( 549 'NO_ZERO_DATE', 550 'ONLY_FULL_GROUP_BY', 551 'STRICT_TRANS_TABLES', 552 'STRICT_ALL_TABLES', 553 'TRADITIONAL' 554 ); 533 555 534 556 /** 535 557 * Whether to use mysqli over mysql. … … 559 581 * 560 582 * @global string $wp_version 561 583 * 562 * @param string $dbuser 584 * @param string $dbuser MySQL database user 563 585 * @param string $dbpassword MySQL database password 564 * @param string $dbname 565 * @param string $dbhost 586 * @param string $dbname MySQL database name 587 * @param string $dbhost MySQL database host 566 588 */ 567 589 public function __construct( $dbuser, $dbpassword, $dbname, $dbhost ) { 568 590 register_shutdown_function( array( $this, '__destruct' ) ); 569 591 570 if ( WP_DEBUG && WP_DEBUG_DISPLAY ) 592 if ( WP_DEBUG && WP_DEBUG_DISPLAY ) { 571 593 $this->show_errors(); 594 } 572 595 573 596 /* Use ext/mysqli if it exists and: 574 597 * - WP_USE_EXT_MYSQL is defined as false, or … … 586 609 } 587 610 } 588 611 589 $this->dbuser = $dbuser;612 $this->dbuser = $dbuser; 590 613 $this->dbpassword = $dbpassword; 591 $this->dbname = $dbname;592 $this->dbhost = $dbhost;614 $this->dbname = $dbname; 615 $this->dbhost = $dbhost; 593 616 594 617 // wp-config.php creation will manually connect when ready. 595 618 if ( defined( 'WP_SETUP_CONFIG' ) ) { … … 616 639 * @since 3.5.0 617 640 * 618 641 * @param string $name The private member to get, and optionally process 642 * 619 643 * @return mixed The private member 620 644 */ 621 645 public function __get( $name ) { 622 if ( 'col_info' === $name ) 646 if ( 'col_info' === $name ) { 623 647 $this->load_col_info(); 648 } 624 649 625 650 return $this->$name; 626 651 } … … 630 655 * 631 656 * @since 3.5.0 632 657 * 633 * @param string $name 634 * @param mixed 658 * @param string $name The private member to set 659 * @param mixed $value The value to set 635 660 */ 636 661 public function __set( $name, $value ) { 637 662 $protected_members = array( … … 639 664 'table_charset', 640 665 'check_current_query', 641 666 ); 642 if ( 667 if ( in_array( $name, $protected_members, true ) ) { 643 668 return; 644 669 } 645 670 $this->$name = $value; … … 650 675 * 651 676 * @since 3.5.0 652 677 * 653 * @param string $name 678 * @param string $name The private member to check 654 679 * 655 680 * @return bool If the member is set or not 656 681 */ … … 663 688 * 664 689 * @since 3.5.0 665 690 * 666 * @param string $name 691 * @param string $name The private member to unset 667 692 */ 668 693 public function __unset( $name ) { 669 694 unset( $this->$name ); … … 678 703 $charset = ''; 679 704 $collate = ''; 680 705 681 if ( function_exists( 'is_multisite') && is_multisite() ) {706 if ( function_exists( 'is_multisite' ) && is_multisite() ) { 682 707 $charset = 'utf8'; 683 708 if ( defined( 'DB_COLLATE' ) && DB_COLLATE ) { 684 709 $collate = DB_COLLATE; … … 708 733 * 709 734 * @param string $charset The character set to check. 710 735 * @param string $collate The collation to check. 736 * 711 737 * @return array The most appropriate character set and collation to use. 712 738 */ 713 739 public function determine_charset( $charset, $collate ) { … … 746 772 * 747 773 * @since 3.1.0 748 774 * 749 * @param resource $dbh 750 * @param string 751 * @param string 775 * @param resource $dbh The resource given by mysql_connect 776 * @param string $charset Optional. The character set. Default null. 777 * @param string $collate Optional. The collation. Default null. 752 778 */ 753 779 public function set_charset( $dbh, $charset = null, $collate = null ) { 754 if ( ! isset( $charset ) ) 780 if ( ! isset( $charset ) ) { 755 781 $charset = $this->charset; 756 if ( ! isset( $collate ) ) 782 } 783 if ( ! isset( $collate ) ) { 757 784 $collate = $this->collate; 785 } 758 786 if ( $this->has_cap( 'collation' ) && ! empty( $charset ) ) { 759 787 $set_charset_succeeded = true; 760 788 … … 765 793 766 794 if ( $set_charset_succeeded ) { 767 795 $query = $this->prepare( 'SET NAMES %s', $charset ); 768 if ( ! empty( $collate ) ) 796 if ( ! empty( $collate ) ) { 769 797 $query .= $this->prepare( ' COLLATE %s', $collate ); 798 } 770 799 mysqli_query( $dbh, $query ); 771 800 } 772 801 } else { … … 775 804 } 776 805 if ( $set_charset_succeeded ) { 777 806 $query = $this->prepare( 'SET NAMES %s', $charset ); 778 if ( ! empty( $collate ) ) 807 if ( ! empty( $collate ) ) { 779 808 $query .= $this->prepare( ' COLLATE %s', $collate ); 809 } 780 810 mysql_query( $query, $dbh ); 781 811 } 782 812 } … … 853 883 * 854 884 * @since 2.5.0 855 885 * 856 * @param string $prefix Alphanumeric name for the new prefix. 857 * @param bool $set_table_names Optional. Whether the table names, e.g. wpdb::$posts, should be updated or not. 886 * @param string $prefix Alphanumeric name for the new prefix. 887 * @param bool $set_table_names Optional. Whether the table names, e.g. wpdb::$posts, should be updated or not. 888 * 858 889 * @return string|WP_Error Old prefix or WP_Error on error 859 890 */ 860 891 public function set_prefix( $prefix, $set_table_names = true ) { 861 892 862 if ( preg_match( '|[^a-z0-9_]|i', $prefix ) ) 863 return new WP_Error('invalid_db_prefix', 'Invalid database prefix' ); 893 if ( preg_match( '|[^a-z0-9_]|i', $prefix ) ) { 894 return new WP_Error( 'invalid_db_prefix', 'Invalid database prefix' ); 895 } 864 896 865 897 $old_prefix = is_multisite() ? '' : $prefix; 866 898 867 if ( isset( $this->base_prefix ) ) 899 if ( isset( $this->base_prefix ) ) { 868 900 $old_prefix = $this->base_prefix; 901 } 869 902 870 903 $this->base_prefix = $prefix; 871 904 872 905 if ( $set_table_names ) { 873 foreach ( $this->tables( 'global' ) as $table => $prefixed_table ) 906 foreach ( $this->tables( 'global' ) as $table => $prefixed_table ) { 874 907 $this->$table = $prefixed_table; 908 } 875 909 876 if ( is_multisite() && empty( $this->blogid ) ) 910 if ( is_multisite() && empty( $this->blogid ) ) { 877 911 return $old_prefix; 912 } 878 913 879 914 $this->prefix = $this->get_blog_prefix(); 880 915 881 foreach ( $this->tables( 'blog' ) as $table => $prefixed_table ) 916 foreach ( $this->tables( 'blog' ) as $table => $prefixed_table ) { 882 917 $this->$table = $prefixed_table; 918 } 883 919 884 foreach ( $this->tables( 'old' ) as $table => $prefixed_table ) 920 foreach ( $this->tables( 'old' ) as $table => $prefixed_table ) { 885 921 $this->$table = $prefixed_table; 922 } 886 923 } 924 887 925 return $old_prefix; 888 926 } 889 927 … … 894 932 * 895 933 * @param int $blog_id 896 934 * @param int $network_id Optional. 935 * 897 936 * @return int previous blog id 898 937 */ 899 938 public function set_blog_id( $blog_id, $network_id = 0 ) { … … 906 945 907 946 $this->prefix = $this->get_blog_prefix(); 908 947 909 foreach ( $this->tables( 'blog' ) as $table => $prefixed_table ) 948 foreach ( $this->tables( 'blog' ) as $table => $prefixed_table ) { 910 949 $this->$table = $prefixed_table; 950 } 911 951 912 foreach ( $this->tables( 'old' ) as $table => $prefixed_table ) 952 foreach ( $this->tables( 'old' ) as $table => $prefixed_table ) { 913 953 $this->$table = $prefixed_table; 954 } 914 955 915 956 return $old_blog_id; 916 957 } … … 919 960 * Gets blog prefix. 920 961 * 921 962 * @since 3.0.0 963 * 922 964 * @param int $blog_id Optional. 965 * 923 966 * @return string Blog prefix. 924 967 */ 925 968 public function get_blog_prefix( $blog_id = null ) { 926 969 if ( is_multisite() ) { 927 if ( null === $blog_id ) 970 if ( null === $blog_id ) { 928 971 $blog_id = $this->blogid; 972 } 929 973 $blog_id = (int) $blog_id; 930 if ( defined( 'MULTISITE' ) && ( 0 == $blog_id || 1 == $blog_id ) ) 974 if ( defined( 'MULTISITE' ) && ( 0 == $blog_id || 1 == $blog_id ) ) { 931 975 return $this->base_prefix; 932 else976 } else { 933 977 return $this->base_prefix . $blog_id . '_'; 978 } 934 979 } else { 935 980 return $this->base_prefix; 936 981 } … … 957 1002 * @uses wpdb::$global_tables 958 1003 * @uses wpdb::$ms_global_tables 959 1004 * 960 * @param string $scope 961 * @param bool $prefixOptional. Whether to include table prefixes. Default true. If blog1005 * @param string $scope Optional. Can be all, global, ms_global, blog, or old tables. Defaults to all. 1006 * @param bool $prefix Optional. Whether to include table prefixes. Default true. If blog 962 1007 * prefix is requested, then the custom users and usermeta tables will be mapped. 963 * @param int $blog_id Optional. The blog_id to prefix. Defaults to wpdb::$blogid. Used only when prefix is requested. 1008 * @param int $blog_id Optional. The blog_id to prefix. Defaults to wpdb::$blogid. Used only when prefix is requested. 1009 * 964 1010 * @return array Table names. When a prefix is requested, the key is the unprefixed table name. 965 1011 */ 966 1012 public function tables( $scope = 'all', $prefix = true, $blog_id = 0 ) { … … 967 1013 switch ( $scope ) { 968 1014 case 'all' : 969 1015 $tables = array_merge( $this->global_tables, $this->tables ); 970 if ( is_multisite() ) 1016 if ( is_multisite() ) { 971 1017 $tables = array_merge( $tables, $this->ms_global_tables ); 1018 } 972 1019 break; 973 1020 case 'blog' : 974 1021 $tables = $this->tables; … … 975 1022 break; 976 1023 case 'global' : 977 1024 $tables = $this->global_tables; 978 if ( is_multisite() ) 1025 if ( is_multisite() ) { 979 1026 $tables = array_merge( $tables, $this->ms_global_tables ); 1027 } 980 1028 break; 981 1029 case 'ms_global' : 982 1030 $tables = $this->ms_global_tables; … … 989 1037 } 990 1038 991 1039 if ( $prefix ) { 992 if ( ! $blog_id ) 1040 if ( ! $blog_id ) { 993 1041 $blog_id = $this->blogid; 994 $blog_prefix = $this->get_blog_prefix( $blog_id ); 995 $base_prefix = $this->base_prefix; 1042 } 1043 $blog_prefix = $this->get_blog_prefix( $blog_id ); 1044 $base_prefix = $this->base_prefix; 996 1045 $global_tables = array_merge( $this->global_tables, $this->ms_global_tables ); 997 1046 foreach ( $tables as $k => $table ) { 998 if ( in_array( $table, $global_tables ) ) 1047 if ( in_array( $table, $global_tables ) ) { 999 1048 $tables[ $table ] = $base_prefix . $table; 1000 else1049 } else { 1001 1050 $tables[ $table ] = $blog_prefix . $table; 1051 } 1002 1052 unset( $tables[ $k ] ); 1003 1053 } 1004 1054 1005 if ( isset( $tables['users'] ) && defined( 'CUSTOM_USER_TABLE' ) ) 1055 if ( isset( $tables['users'] ) && defined( 'CUSTOM_USER_TABLE' ) ) { 1006 1056 $tables['users'] = CUSTOM_USER_TABLE; 1057 } 1007 1058 1008 if ( isset( $tables['usermeta'] ) && defined( 'CUSTOM_USER_META_TABLE' ) ) 1059 if ( isset( $tables['usermeta'] ) && defined( 'CUSTOM_USER_META_TABLE' ) ) { 1009 1060 $tables['usermeta'] = CUSTOM_USER_META_TABLE; 1061 } 1010 1062 } 1011 1063 1012 1064 return $tables; … … 1020 1072 * 1021 1073 * @since 0.71 1022 1074 * 1023 * @param string $dbMySQL database name1075 * @param string $db MySQL database name 1024 1076 * @param resource|null $dbh Optional link identifier. 1025 1077 */ 1026 1078 public function select( $db, $dbh = null ) { 1027 if ( is_null( $dbh) )1079 if ( is_null( $dbh ) ) { 1028 1080 $dbh = $this->dbh; 1081 } 1029 1082 1030 1083 if ( $this->use_mysqli ) { 1031 1084 $success = mysqli_select_db( $dbh, $db ); … … 1041 1094 1042 1095 $message .= '<p>' . sprintf( 1043 1096 /* translators: %s: database name */ 1044 __( 'We were able to connect to the database server (which means your username and password is okay) but not able to select the %s database.' ),1045 '<code>' . htmlspecialchars( $db, ENT_QUOTES ) . '</code>'1046 ) . "</p>\n";1097 __( 'We were able to connect to the database server (which means your username and password is okay) but not able to select the %s database.' ), 1098 '<code>' . htmlspecialchars( $db, ENT_QUOTES ) . '</code>' 1099 ) . "</p>\n"; 1047 1100 1048 1101 $message .= "<ul>\n"; 1049 1102 $message .= '<li>' . __( 'Are you sure it exists?' ) . "</li>\n"; … … 1050 1103 1051 1104 $message .= '<li>' . sprintf( 1052 1105 /* translators: 1: database user, 2: database name */ 1053 __( 'Does the user %1$s have permission to use the %2$s database?' ),1054 '<code>' . htmlspecialchars( $this->dbuser, ENT_QUOTES ). '</code>',1055 '<code>' . htmlspecialchars( $db, ENT_QUOTES ) . '</code>'1056 ) . "</li>\n";1106 __( 'Does the user %1$s have permission to use the %2$s database?' ), 1107 '<code>' . htmlspecialchars( $this->dbuser, ENT_QUOTES ) . '</code>', 1108 '<code>' . htmlspecialchars( $db, ENT_QUOTES ) . '</code>' 1109 ) . "</li>\n"; 1057 1110 1058 1111 $message .= '<li>' . sprintf( 1059 1112 /* translators: %s: database name */ 1060 __( '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?' ),1061 htmlspecialchars( $db, ENT_QUOTES )1062 ). "</li>\n";1113 __( '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?' ), 1114 htmlspecialchars( $db, ENT_QUOTES ) 1115 ) . "</li>\n"; 1063 1116 1064 1117 $message .= "</ul>\n"; 1065 1118 1066 1119 $message .= '<p>' . sprintf( 1067 1120 /* translators: %s: support forums URL */ 1068 __( '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="%s">WordPress Support Forums</a>.' ),1069 __( 'https://wordpress.org/support/' )1070 ) . "</p>\n";1121 __( '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="%s">WordPress Support Forums</a>.' ), 1122 __( 'https://wordpress.org/support/' ) 1123 ) . "</p>\n"; 1071 1124 1072 1125 $this->bail( $message, 'db_select_fail' ); 1073 1126 } … … 1085 1138 * @see esc_sql() 1086 1139 * 1087 1140 * @param string $string 1141 * 1088 1142 * @return string 1089 1143 */ 1090 1144 function _weak_escape( $string ) { 1091 if ( func_num_args() === 1 && function_exists( '_deprecated_function' ) ) 1145 if ( func_num_args() === 1 && function_exists( '_deprecated_function' ) ) { 1092 1146 _deprecated_function( __METHOD__, '3.6.0', 'wpdb::prepare() or esc_sql()' ); 1147 } 1148 1093 1149 return addslashes( $string ); 1094 1150 } 1095 1151 … … 1101 1157 * @since 2.8.0 1102 1158 * 1103 1159 * @param string $string to escape 1160 * 1104 1161 * @return string escaped 1105 1162 */ 1106 1163 function _real_escape( $string ) { … … 1119 1176 } else { 1120 1177 _doing_it_wrong( $class, sprintf( '%s must set a database connection for use with escaping.', $class ), '3.6.0' ); 1121 1178 } 1179 1122 1180 return addslashes( $string ); 1123 1181 } 1124 1182 … … 1129 1187 * @since 2.8.0 1130 1188 * 1131 1189 * @param string|array $data 1190 * 1132 1191 * @return string|array escaped 1133 1192 */ 1134 1193 public function _escape( $data ) { … … 1135 1194 if ( is_array( $data ) ) { 1136 1195 foreach ( $data as $k => $v ) { 1137 1196 if ( is_array( $v ) ) { 1138 $data[ $k] = $this->_escape( $v );1197 $data[ $k ] = $this->_escape( $v ); 1139 1198 } else { 1140 $data[ $k] = $this->_real_escape( $v );1199 $data[ $k ] = $this->_real_escape( $v ); 1141 1200 } 1142 1201 } 1143 1202 } else { … … 1158 1217 * @see esc_sql() 1159 1218 * 1160 1219 * @param mixed $data 1220 * 1161 1221 * @return mixed 1162 1222 */ 1163 1223 public function escape( $data ) { 1164 if ( func_num_args() === 1 && function_exists( '_deprecated_function' ) ) 1224 if ( func_num_args() === 1 && function_exists( '_deprecated_function' ) ) { 1165 1225 _deprecated_function( __METHOD__, '3.6.0', 'wpdb::prepare() or esc_sql()' ); 1226 } 1166 1227 if ( is_array( $data ) ) { 1167 1228 foreach ( $data as $k => $v ) { 1168 if ( is_array( $v ) ) 1169 $data[$k] = $this->escape( $v, 'recursive' ); 1170 else 1171 $data[$k] = $this->_weak_escape( $v, 'internal' ); 1229 if ( is_array( $v ) ) { 1230 $data[ $k ] = $this->escape( $v, 'recursive' ); 1231 } else { 1232 $data[ $k ] = $this->_weak_escape( $v, 'internal' ); 1233 } 1172 1234 } 1173 1235 } else { 1174 1236 $data = $this->_weak_escape( $data, 'internal' ); … … 1187 1249 * @param string $string to escape 1188 1250 */ 1189 1251 public function escape_by_ref( &$string ) { 1190 if ( ! is_float( $string ) ) 1252 if ( ! is_float( $string ) ) { 1191 1253 $string = $this->_real_escape( $string ); 1254 } 1192 1255 } 1193 1256 1194 1257 /** … … 1217 1280 * @link https://secure.php.net/sprintf Description of syntax. 1218 1281 * @since 2.3.0 1219 1282 * 1220 * @param string $queryQuery statement with sprintf()-like placeholders1221 * @param array|mixed $args 1283 * @param string $query Query statement with sprintf()-like placeholders 1284 * @param array|mixed $args The array of variables to substitute into the query's placeholders if being called like 1222 1285 * {@link https://secure.php.net/vsprintf vsprintf()}, or the first variable to substitute into the query's placeholders if 1223 1286 * being called like {@link https://secure.php.net/sprintf sprintf()}. 1224 * @param mixed 1287 * @param mixed $args,... further variables to substitute into the query's placeholders if being called like 1225 1288 * {@link https://secure.php.net/sprintf sprintf()}. 1289 * 1226 1290 * @return string|void Sanitized query string, if there is a query to prepare. 1227 1291 */ 1228 1292 public function prepare( $query, $args ) { 1229 if ( is_null( $query ) ) 1293 if ( is_null( $query ) ) { 1230 1294 return; 1295 } 1231 1296 1232 1297 // This is not meant to be foolproof -- but it will catch obviously incorrect usage. 1233 1298 if ( strpos( $query, '%' ) === false ) { … … 1250 1315 1251 1316 $query = str_replace( "'%s'", '%s', $query ); // in case someone mistakenly already singlequoted it 1252 1317 $query = str_replace( '"%s"', '%s', $query ); // doublequote unquoting 1253 $query = preg_replace( '|(?<!%)%f|' 1318 $query = preg_replace( '|(?<!%)%f|', '%F', $query ); // Force floats to be locale unaware 1254 1319 $query = preg_replace( '|(?<!%)%s|', "'%s'", $query ); // quote the strings, avoiding escaped strings like %%s 1255 1320 $query = preg_replace( '/%(?:%|$|([^dsF]))/', '%%\\1', $query ); // escape any unescaped percents 1256 1321 array_walk( $args, array( $this, 'escape_by_ref' ) ); 1322 1257 1323 return @vsprintf( $query, $args ); 1258 1324 } 1259 1325 … … 1277 1343 * 1278 1344 * @param string $text The raw text to be escaped. The input typed by the user should have no 1279 1345 * extra or deleted slashes. 1346 * 1280 1347 * @return string Text in the form of a LIKE phrase. The output is not SQL safe. Call $wpdb::prepare() 1281 1348 * or real_escape next. 1282 1349 */ … … 1291 1358 * @global array $EZSQL_ERROR Stores error information of query and error string 1292 1359 * 1293 1360 * @param string $str The error to display 1361 * 1294 1362 * @return false|void False if the showing of errors is disabled. 1295 1363 */ 1296 1364 public function print_error( $str = '' ) { 1297 1365 global $EZSQL_ERROR; 1298 1366 1299 if ( ! $str ) {1367 if ( ! $str ) { 1300 1368 if ( $this->use_mysqli ) { 1301 $str = mysqli_error( $this->dbh);1369 $str = $this->get_error(); 1302 1370 } else { 1303 1371 $str = mysql_error( $this->dbh ); 1304 1372 } … … 1305 1373 } 1306 1374 $EZSQL_ERROR[] = array( 'query' => $this->last_query, 'error_str' => $str ); 1307 1375 1308 if ( $this->suppress_errors ) 1376 if ( $this->suppress_errors ) { 1309 1377 return false; 1378 } 1310 1379 1311 1380 wp_load_translations_early(); 1312 1381 … … 1321 1390 error_log( $error_str ); 1322 1391 1323 1392 // Are we showing errors? 1324 if ( ! $this->show_errors ) 1393 if ( ! $this->show_errors ) { 1325 1394 return false; 1395 } 1326 1396 1327 1397 // If there is an error then take note of it 1328 1398 if ( is_multisite() ) { … … 1353 1423 } 1354 1424 1355 1425 /** 1426 * Gets database error. 1427 * 1428 * @return string Error code and message. 1429 */ 1430 public function get_error() { 1431 $error_code = mysqli_errno( $this->dbh ); 1432 $error = ''; 1433 if ( $error_code !== 0 ) { 1434 $error = sprintf( 'code:"%s",message:"%s"', 1435 mysqli_errno( $this->dbh ), 1436 mysqli_error( $this->dbh ) 1437 ); 1438 } 1439 1440 return $error; 1441 } 1442 1443 /** 1356 1444 * Enables showing of database errors. 1357 1445 * 1358 1446 * This function should be used only to enable showing of errors. … … 1364 1452 * @see wpdb::hide_errors() 1365 1453 * 1366 1454 * @param bool $show Whether to show or hide errors 1455 * 1367 1456 * @return bool Old value for showing errors. 1368 1457 */ 1369 1458 public function show_errors( $show = true ) { 1370 $errors = $this->show_errors;1459 $errors = $this->show_errors; 1371 1460 $this->show_errors = $show; 1461 1372 1462 return $errors; 1373 1463 } 1374 1464 … … 1383 1473 * @return bool Whether showing of errors was active 1384 1474 */ 1385 1475 public function hide_errors() { 1386 $show = $this->show_errors;1476 $show = $this->show_errors; 1387 1477 $this->show_errors = false; 1478 1388 1479 return $show; 1389 1480 } 1390 1481 … … 1396 1487 * 1397 1488 * @since 2.5.0 1398 1489 * @see wpdb::hide_errors() 1490 * 1399 1491 * @param bool $suppress Optional. New value. Defaults to true. 1492 * 1400 1493 * @return bool Old value 1401 1494 */ 1402 1495 public function suppress_errors( $suppress = true ) { 1403 $errors = $this->suppress_errors;1496 $errors = $this->suppress_errors; 1404 1497 $this->suppress_errors = (bool) $suppress; 1498 1405 1499 return $errors; 1406 1500 } 1407 1501 … … 1411 1505 * @since 0.71 1412 1506 */ 1413 1507 public function flush() { 1414 $this->last_result = array();1415 $this->col_info = null;1416 $this->last_query = null;1508 $this->last_result = array(); 1509 $this->col_info = null; 1510 $this->last_query = null; 1417 1511 $this->rows_affected = $this->num_rows = 0; 1418 $this->last_error = '';1512 $this->last_error = ''; 1419 1513 1420 1514 if ( $this->use_mysqli && $this->result instanceof mysqli_result ) { 1421 1515 mysqli_free_result( $this->result ); … … 1422 1516 $this->result = null; 1423 1517 1424 1518 // Sanity check before using the handle 1425 if ( empty( $this->dbh ) || ! ( $this->dbh instanceof mysqli ) ) {1519 if ( empty( $this->dbh ) || ! ( $this->dbh instanceof mysqli ) ) { 1426 1520 return; 1427 1521 } 1428 1522 … … 1445 1539 * @since 3.9.0 $allow_bail parameter added. 1446 1540 * 1447 1541 * @param bool $allow_bail Optional. Allows the function to bail. Default true. 1542 * 1448 1543 * @return bool True with a successful connection, false on failure. 1449 1544 */ 1450 1545 public function db_connect( $allow_bail = true ) { … … 1454 1549 * Deprecated in 3.9+ when using MySQLi. No equivalent 1455 1550 * $new_link parameter exists for mysqli_* functions. 1456 1551 */ 1457 $new_link = defined( 'MYSQL_NEW_LINK' ) ? MYSQL_NEW_LINK : true;1552 $new_link = defined( 'MYSQL_NEW_LINK' ) ? MYSQL_NEW_LINK : true; 1458 1553 $client_flags = defined( 'MYSQL_CLIENT_FLAGS' ) ? MYSQL_CLIENT_FLAGS : 0; 1459 1554 1460 1555 if ( $this->use_mysqli ) { … … 1462 1557 1463 1558 // mysqli_real_connect doesn't support the host param including a port or socket 1464 1559 // like mysql_connect does. This duplicates how mysql_connect detects a port and/or socket file. 1465 $port = null;1466 $socket = null;1467 $host = $this->dbhost;1560 $port = null; 1561 $socket = null; 1562 $host = $this->dbhost; 1468 1563 $port_or_socket = strstr( $host, ':' ); 1469 1564 if ( ! empty( $port_or_socket ) ) { 1470 $host = substr( $host, 0, strpos( $host, ':' ) );1565 $host = substr( $host, 0, strpos( $host, ':' ) ); 1471 1566 $port_or_socket = substr( $port_or_socket, 1 ); 1472 1567 if ( 0 !== strpos( $port_or_socket, '/' ) ) { 1473 $port = intval( $port_or_socket );1568 $port = intval( $port_or_socket ); 1474 1569 $maybe_socket = strstr( $port_or_socket, ':' ); 1475 1570 if ( ! empty( $maybe_socket ) ) { 1476 1571 $socket = substr( $maybe_socket, 1 ); … … 1506 1601 1507 1602 if ( $attempt_fallback ) { 1508 1603 $this->use_mysqli = false; 1604 1509 1605 return $this->db_connect( $allow_bail ); 1510 1606 } 1511 1607 } … … 1530 1626 1531 1627 $message .= '<p>' . sprintf( 1532 1628 /* translators: 1: wp-config.php. 2: database host */ 1533 __( 'This either means that the username and password information in your %1$s file is incorrect or we can’t contact the database server at %2$s. This could mean your host’s database server is down.' ),1534 '<code>wp-config.php</code>',1535 '<code>' . htmlspecialchars( $this->dbhost, ENT_QUOTES ) . '</code>'1536 ) . "</p>\n";1629 __( 'This either means that the username and password information in your %1$s file is incorrect or we can’t contact the database server at %2$s. This could mean your host’s database server is down.' ), 1630 '<code>wp-config.php</code>', 1631 '<code>' . htmlspecialchars( $this->dbhost, ENT_QUOTES ) . '</code>' 1632 ) . "</p>\n"; 1537 1633 1538 1634 $message .= "<ul>\n"; 1539 1635 $message .= '<li>' . __( 'Are you sure you have the correct username and password?' ) . "</li>\n"; … … 1543 1639 1544 1640 $message .= '<p>' . sprintf( 1545 1641 /* translators: %s: support forums URL */ 1546 __( '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="%s">WordPress Support Forums</a>.' ),1547 __( 'https://wordpress.org/support/' )1548 ) . "</p>\n";1642 __( '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="%s">WordPress Support Forums</a>.' ), 1643 __( 'https://wordpress.org/support/' ) 1644 ) . "</p>\n"; 1549 1645 1550 1646 $this->bail( $message, 'db_connect_fail' ); 1551 1647 … … 1581 1677 * @since 3.9.0 1582 1678 * 1583 1679 * @param bool $allow_bail Optional. Allows the function to bail. Default true. 1680 * 1584 1681 * @return bool|void True if the connection is up. 1585 1682 */ 1586 1683 public function check_connection( $allow_bail = true ) { … … 1602 1699 error_reporting( $error_reporting & ~E_WARNING ); 1603 1700 } 1604 1701 1605 for ( $tries = 1; $tries <= $this->reconnect_retries; $tries ++ ) {1702 for ( $tries = 1; $tries <= $this->reconnect_retries; $tries ++ ) { 1606 1703 // On the last try, re-enable warnings. We want to see a single instance of the 1607 1704 // "unable to connect" message on the bail() screen, if it appears. 1608 1705 if ( $this->reconnect_retries === $tries && WP_DEBUG ) { … … 1636 1733 1637 1734 $message .= '<p>' . sprintf( 1638 1735 /* translators: %s: database host */ 1639 __( 'This means that we lost contact with the database server at %s. This could mean your host’s database server is down.' ),1640 '<code>' . htmlspecialchars( $this->dbhost, ENT_QUOTES ) . '</code>'1641 ) . "</p>\n";1736 __( 'This means that we lost contact with the database server at %s. This could mean your host’s database server is down.' ), 1737 '<code>' . htmlspecialchars( $this->dbhost, ENT_QUOTES ) . '</code>' 1738 ) . "</p>\n"; 1642 1739 1643 1740 $message .= "<ul>\n"; 1644 1741 $message .= '<li>' . __( 'Are you sure that the database server is running?' ) . "</li>\n"; … … 1647 1744 1648 1745 $message .= '<p>' . sprintf( 1649 1746 /* translators: %s: support forums URL */ 1650 __( '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="%s">WordPress Support Forums</a>.' ),1651 __( 'https://wordpress.org/support/' )1652 ) . "</p>\n";1747 __( '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="%s">WordPress Support Forums</a>.' ), 1748 __( 'https://wordpress.org/support/' ) 1749 ) . "</p>\n"; 1653 1750 1654 1751 // We weren't able to reconnect, so we better bail. 1655 1752 $this->bail( $message, 'db_connect_fail' ); … … 1666 1763 * @since 0.71 1667 1764 * 1668 1765 * @param string $query Database query 1766 * 1669 1767 * @return int|false Number of rows affected/selected or false on error 1670 1768 */ 1671 1769 public function query( $query ) { 1672 1770 if ( ! $this->ready ) { 1673 1771 $this->check_current_query = true; 1772 1674 1773 return false; 1675 1774 } 1676 1775 … … 1699 1798 $this->flush(); 1700 1799 if ( $stripped_query !== $query ) { 1701 1800 $this->insert_id = 0; 1801 1702 1802 return false; 1703 1803 } 1704 1804 } … … 1735 1835 $this->_do_query( $query ); 1736 1836 } else { 1737 1837 $this->insert_id = 0; 1838 1738 1839 return false; 1739 1840 } 1740 1841 } … … 1742 1843 // If there is an error then take note of it. 1743 1844 if ( $this->use_mysqli ) { 1744 1845 if ( $this->dbh instanceof mysqli ) { 1745 $this->last_error = mysqli_error( $this->dbh);1846 $this->last_error = $this->get_error(); 1746 1847 } else { 1747 1848 $this->last_error = __( 'Unable to retrieve the error message from MySQL' ); 1748 1849 } … … 1756 1857 1757 1858 if ( $this->last_error ) { 1758 1859 // Clear insert_id on a subsequent failed insert. 1759 if ( $this->insert_id && preg_match( '/^\s*(insert|replace)\s/i', $query ) ) 1860 if ( $this->insert_id && preg_match( '/^\s*(insert|replace)\s/i', $query ) ) { 1760 1861 $this->insert_id = 0; 1862 } 1761 1863 1762 1864 $this->print_error(); 1865 1763 1866 return false; 1764 1867 } 1765 1868 … … 1785 1888 $num_rows = 0; 1786 1889 if ( $this->use_mysqli && $this->result instanceof mysqli_result ) { 1787 1890 while ( $row = mysqli_fetch_object( $this->result ) ) { 1788 $this->last_result[ $num_rows] = $row;1789 $num_rows ++;1891 $this->last_result[ $num_rows ] = $row; 1892 $num_rows ++; 1790 1893 } 1791 1894 } elseif ( is_resource( $this->result ) ) { 1792 1895 while ( $row = mysql_fetch_object( $this->result ) ) { 1793 $this->last_result[ $num_rows] = $row;1794 $num_rows ++;1896 $this->last_result[ $num_rows ] = $row; 1897 $num_rows ++; 1795 1898 } 1796 1899 } 1797 1900 … … 1823 1926 } elseif ( ! empty( $this->dbh ) ) { 1824 1927 $this->result = mysql_query( $query, $this->dbh ); 1825 1928 } 1826 $this->num_queries ++;1929 $this->num_queries ++; 1827 1930 1828 1931 if ( defined( 'SAVEQUERIES' ) && SAVEQUERIES ) { 1829 1932 $this->queries[] = array( $query, $this->timer_stop(), $this->get_caller() ); … … 1841 1944 * @see wpdb::$field_types 1842 1945 * @see wp_set_wpdb_vars() 1843 1946 * 1844 * @param string $tableTable name1845 * @param array $dataData to insert (in column => value pairs).1947 * @param string $table Table name 1948 * @param array $data Data to insert (in column => value pairs). 1846 1949 * Both $data columns and $data values should be "raw" (neither should be SQL escaped). 1847 1950 * Sending a null value will cause the column to be set to NULL - the corresponding format is ignored in this case. 1848 1951 * @param array|string $format Optional. An array of formats to be mapped to each of the value in $data. … … 1849 1952 * If string, that format will be used for all of the values in $data. 1850 1953 * A format is one of '%d', '%f', '%s' (integer, float, string). 1851 1954 * If omitted, all values in $data will be treated as strings unless otherwise specified in wpdb::$field_types. 1955 * 1852 1956 * @return int|false The number of rows inserted, or false on error. 1853 1957 */ 1854 1958 public function insert( $table, $data, $format = null ) { … … 1866 1970 * @see wpdb::$field_types 1867 1971 * @see wp_set_wpdb_vars() 1868 1972 * 1869 * @param string $tableTable name1870 * @param array $dataData to insert (in column => value pairs).1973 * @param string $table Table name 1974 * @param array $data Data to insert (in column => value pairs). 1871 1975 * Both $data columns and $data values should be "raw" (neither should be SQL escaped). 1872 1976 * Sending a null value will cause the column to be set to NULL - the corresponding format is ignored in this case. 1873 1977 * @param array|string $format Optional. An array of formats to be mapped to each of the value in $data. … … 1874 1978 * If string, that format will be used for all of the values in $data. 1875 1979 * A format is one of '%d', '%f', '%s' (integer, float, string). 1876 1980 * If omitted, all values in $data will be treated as strings unless otherwise specified in wpdb::$field_types. 1981 * 1877 1982 * @return int|false The number of rows affected, or false on error. 1878 1983 */ 1879 1984 public function replace( $table, $data, $format = null ) { … … 1890 1995 * @see wpdb::$field_types 1891 1996 * @see wp_set_wpdb_vars() 1892 1997 * 1893 * @param string $tableTable name1894 * @param array $dataData to insert (in column => value pairs).1998 * @param string $table Table name 1999 * @param array $data Data to insert (in column => value pairs). 1895 2000 * Both $data columns and $data values should be "raw" (neither should be SQL escaped). 1896 2001 * Sending a null value will cause the column to be set to NULL - the corresponding format is ignored in this case. 1897 2002 * @param array|string $format Optional. An array of formats to be mapped to each of the value in $data. … … 1898 2003 * If string, that format will be used for all of the values in $data. 1899 2004 * A format is one of '%d', '%f', '%s' (integer, float, string). 1900 2005 * If omitted, all values in $data will be treated as strings unless otherwise specified in wpdb::$field_types. 1901 * @param string $type Optional. What type of operation is this? INSERT or REPLACE. Defaults to INSERT. 2006 * @param string $type Optional. What type of operation is this? INSERT or REPLACE. Defaults to INSERT. 2007 * 1902 2008 * @return int|false The number of rows affected, or false on error. 1903 2009 */ 1904 2010 function _insert_replace_helper( $table, $data, $format = null, $type = 'INSERT' ) { … … 1930 2036 $sql = "$type INTO `$table` ($fields) VALUES ($formats)"; 1931 2037 1932 2038 $this->check_current_query = false; 2039 1933 2040 return $this->query( $this->prepare( $sql, $values ) ); 1934 2041 } 1935 2042 … … 1944 2051 * @see wpdb::$field_types 1945 2052 * @see wp_set_wpdb_vars() 1946 2053 * 1947 * @param string $tableTable name1948 * @param array $dataData to update (in column => value pairs).2054 * @param string $table Table name 2055 * @param array $data Data to update (in column => value pairs). 1949 2056 * Both $data columns and $data values should be "raw" (neither should be SQL escaped). 1950 2057 * Sending a null value will cause the column to be set to NULL - the corresponding 1951 2058 * format is ignored in this case. 1952 * @param array $whereA named array of WHERE clauses (in column => value pairs).2059 * @param array $where A named array of WHERE clauses (in column => value pairs). 1953 2060 * Multiple clauses will be joined with ANDs. 1954 2061 * Both $where columns and $where values should be "raw". 1955 2062 * Sending a null value will create an IS NULL comparison - the corresponding format will be ignored in this case. 1956 * @param array|string $format 2063 * @param array|string $format Optional. An array of formats to be mapped to each of the values in $data. 1957 2064 * If string, that format will be used for all of the values in $data. 1958 2065 * A format is one of '%d', '%f', '%s' (integer, float, string). 1959 2066 * If omitted, all values in $data will be treated as strings unless otherwise specified in wpdb::$field_types. … … 1961 2068 * If string, that format will be used for all of the items in $where. 1962 2069 * A format is one of '%d', '%f', '%s' (integer, float, string). 1963 2070 * If omitted, all values in $where will be treated as strings. 2071 * 1964 2072 * @return int|false The number of rows updated, or false on error. 1965 2073 */ 1966 2074 public function update( $table, $data, $where, $format = null, $where_format = null ) { … … 1994 2102 } 1995 2103 1996 2104 $conditions[] = "`$field` = " . $value['format']; 1997 $values[] = $value['value'];2105 $values[] = $value['value']; 1998 2106 } 1999 2107 2000 $fields = implode( ', ', $fields );2108 $fields = implode( ', ', $fields ); 2001 2109 $conditions = implode( ' AND ', $conditions ); 2002 2110 2003 2111 $sql = "UPDATE `$table` SET $fields WHERE $conditions"; 2004 2112 2005 2113 $this->check_current_query = false; 2114 2006 2115 return $this->query( $this->prepare( $sql, $values ) ); 2007 2116 } 2008 2117 … … 2017 2126 * @see wpdb::$field_types 2018 2127 * @see wp_set_wpdb_vars() 2019 2128 * 2020 * @param string $tableTable name2021 * @param array $whereA named array of WHERE clauses (in column => value pairs).2129 * @param string $table Table name 2130 * @param array $where A named array of WHERE clauses (in column => value pairs). 2022 2131 * Multiple clauses will be joined with ANDs. 2023 2132 * Both $where columns and $where values should be "raw". 2024 2133 * Sending a null value will create an IS NULL comparison - the corresponding format will be ignored in this case. … … 2026 2135 * If string, that format will be used for all of the items in $where. 2027 2136 * A format is one of '%d', '%f', '%s' (integer, float, string). 2028 2137 * If omitted, all values in $where will be treated as strings unless otherwise specified in wpdb::$field_types. 2138 * 2029 2139 * @return int|false The number of rows updated, or false on error. 2030 2140 */ 2031 2141 public function delete( $table, $where, $where_format = null ) { … … 2046 2156 } 2047 2157 2048 2158 $conditions[] = "`$field` = " . $value['format']; 2049 $values[] = $value['value'];2159 $values[] = $value['value']; 2050 2160 } 2051 2161 2052 2162 $conditions = implode( ' AND ', $conditions ); … … 2054 2164 $sql = "DELETE FROM `$table` WHERE $conditions"; 2055 2165 2056 2166 $this->check_current_query = false; 2167 2057 2168 return $this->query( $this->prepare( $sql, $values ) ); 2058 2169 } 2059 2170 … … 2068 2179 * 2069 2180 * @since 4.2.0 2070 2181 * 2071 * @param string $table Table name. 2072 * @param array $data Field/value pair. 2073 * @param mixed $format Format for each field. 2182 * @param string $table Table name. 2183 * @param array $data Field/value pair. 2184 * @param mixed $format Format for each field. 2185 * 2074 2186 * @return array|false Returns an array of fields that contain paired values 2075 2187 * and formats. Returns false for invalid values. 2076 2188 */ … … 2104 2216 * 2105 2217 * @since 4.2.0 2106 2218 * 2107 * @param array $data 2219 * @param array $data Array of fields to values. 2108 2220 * @param mixed $format Formats to be mapped to the values in $data. 2221 * 2109 2222 * @return array Array, keyed by field names with values being an array 2110 2223 * of 'value' and 'format' keys. 2111 2224 */ … … 2139 2252 * 2140 2253 * @since 4.2.0 2141 2254 * 2142 * @param array $dataAs it comes from the wpdb::process_field_formats() method.2255 * @param array $data As it comes from the wpdb::process_field_formats() method. 2143 2256 * @param string $table Table name. 2257 * 2144 2258 * @return array|false The same array as $data with additional 'charset' keys. 2145 2259 */ 2146 2260 protected function process_field_charsets( $data, $table ) { … … 2169 2283 * 2170 2284 * @since 4.2.1 2171 2285 * 2172 * @param array $dataAs it comes from the wpdb::process_field_charsets() method.2286 * @param array $data As it comes from the wpdb::process_field_charsets() method. 2173 2287 * @param string $table Table name. 2288 * 2174 2289 * @return array|false The same array as $data with additional 'length' keys, or false if 2175 2290 * any of the values were too long for their corresponding field. 2176 2291 */ … … 2205 2320 * @since 0.71 2206 2321 * 2207 2322 * @param string|null $query Optional. SQL query. Defaults to null, use the result from the previous query. 2208 * @param int $x Optional. Column of value to return. Indexed from 0. 2209 * @param int $y Optional. Row of value to return. Indexed from 0. 2323 * @param int $x Optional. Column of value to return. Indexed from 0. 2324 * @param int $y Optional. Row of value to return. Indexed from 0. 2325 * 2210 2326 * @return string|null Database query result (as string), or null on failure 2211 2327 */ 2212 2328 public function get_var( $query = null, $x = 0, $y = 0 ) { … … 2221 2337 } 2222 2338 2223 2339 // Extract var out of cached results based x,y vals 2224 if ( ! empty( $this->last_result[$y] ) ) {2225 $values = array_values( get_object_vars( $this->last_result[ $y] ) );2340 if ( ! empty( $this->last_result[ $y ] ) ) { 2341 $values = array_values( get_object_vars( $this->last_result[ $y ] ) ); 2226 2342 } 2227 2343 2228 2344 // If there is a value return it else return null 2229 return ( isset( $values[ $x] ) && $values[$x] !== '' ) ? $values[$x] : null;2345 return ( isset( $values[ $x ] ) && $values[ $x ] !== '' ) ? $values[ $x ] : null; 2230 2346 } 2231 2347 2232 2348 /** … … 2236 2352 * 2237 2353 * @since 0.71 2238 2354 * 2239 * @param string|null $query 2240 * @param string 2355 * @param string|null $query SQL query. 2356 * @param string $output Optional. The required return type. One of OBJECT, ARRAY_A, or ARRAY_N, which correspond to 2241 2357 * an stdClass object, an associative array, or a numeric array, respectively. Default OBJECT. 2242 * @param int $y Optional. Row to return. Indexed from 0. 2358 * @param int $y Optional. Row to return. Indexed from 0. 2359 * 2243 2360 * @return array|object|null|void Database query result in format specified by $output or null on failure 2244 2361 */ 2245 2362 public function get_row( $query = null, $output = OBJECT, $y = 0 ) { … … 2255 2372 return null; 2256 2373 } 2257 2374 2258 if ( ! isset( $this->last_result[$y] ) )2375 if ( ! isset( $this->last_result[ $y ] ) ) { 2259 2376 return null; 2377 } 2260 2378 2261 2379 if ( $output == OBJECT ) { 2262 return $this->last_result[ $y] ? $this->last_result[$y] : null;2380 return $this->last_result[ $y ] ? $this->last_result[ $y ] : null; 2263 2381 } elseif ( $output == ARRAY_A ) { 2264 return $this->last_result[ $y] ? get_object_vars( $this->last_result[$y] ) : null;2382 return $this->last_result[ $y ] ? get_object_vars( $this->last_result[ $y ] ) : null; 2265 2383 } elseif ( $output == ARRAY_N ) { 2266 return $this->last_result[ $y] ? array_values( get_object_vars( $this->last_result[$y] ) ) : null;2384 return $this->last_result[ $y ] ? array_values( get_object_vars( $this->last_result[ $y ] ) ) : null; 2267 2385 } elseif ( strtoupper( $output ) === OBJECT ) { 2268 2386 // Back compat for OBJECT being previously case insensitive. 2269 return $this->last_result[ $y] ? $this->last_result[$y] : null;2387 return $this->last_result[ $y ] ? $this->last_result[ $y ] : null; 2270 2388 } else { 2271 2389 $this->print_error( " \$db->get_row(string query, output type, int offset) -- Output type must be one of: OBJECT, ARRAY_A, ARRAY_N" ); 2272 2390 } … … 2282 2400 * @since 0.71 2283 2401 * 2284 2402 * @param string|null $query Optional. SQL query. Defaults to previous query. 2285 * @param int $x Optional. Column to return. Indexed from 0. 2403 * @param int $x Optional. Column to return. Indexed from 0. 2404 * 2286 2405 * @return array Database query result. Array indexed from 0 by SQL result row number. 2287 2406 */ 2288 public function get_col( $query = null 2407 public function get_col( $query = null, $x = 0 ) { 2289 2408 if ( $this->check_current_query && $this->check_safe_collation( $query ) ) { 2290 2409 $this->check_current_query = false; 2291 2410 } … … 2296 2415 2297 2416 $new_array = array(); 2298 2417 // Extract the column values 2299 for ( $i = 0, $j = count( $this->last_result ); $i < $j; $i ++ ) {2300 $new_array[ $i] = $this->get_var( null, $x, $i );2418 for ( $i = 0, $j = count( $this->last_result ); $i < $j; $i ++ ) { 2419 $new_array[ $i ] = $this->get_var( null, $x, $i ); 2301 2420 } 2421 2302 2422 return $new_array; 2303 2423 } 2304 2424 … … 2309 2429 * 2310 2430 * @since 0.71 2311 2431 * 2312 * @param string $query 2432 * @param string $query SQL query. 2313 2433 * @param string $output Optional. Any of ARRAY_A | ARRAY_N | OBJECT | OBJECT_K constants. 2314 2434 * With one of the first three, return an array of rows indexed from 0 by SQL result row number. 2315 2435 * Each row is an associative array (column => value, ...), a numerically indexed array (0 => value, ...), or an object. ( ->column = value ), respectively. 2316 2436 * With OBJECT_K, return an associative array of row objects keyed by the value of each row's first column's value. 2317 2437 * Duplicate keys are discarded. 2438 * 2318 2439 * @return array|object|null Database query results 2319 2440 */ 2320 2441 public function get_results( $query = null, $output = OBJECT ) { … … 2339 2460 // (Duplicates are discarded) 2340 2461 foreach ( $this->last_result as $row ) { 2341 2462 $var_by_ref = get_object_vars( $row ); 2342 $key = array_shift( $var_by_ref );2343 if ( ! isset( $new_array[ $key ] ) ) 2463 $key = array_shift( $var_by_ref ); 2464 if ( ! isset( $new_array[ $key ] ) ) { 2344 2465 $new_array[ $key ] = $row; 2466 } 2345 2467 } 2468 2346 2469 return $new_array; 2347 2470 } elseif ( $output == ARRAY_A || $output == ARRAY_N ) { 2348 2471 // Return an integer-keyed array of... … … 2357 2480 } 2358 2481 } 2359 2482 } 2483 2360 2484 return $new_array; 2361 2485 } elseif ( strtoupper( $output ) === OBJECT ) { 2362 2486 // Back compat for OBJECT being previously case insensitive. 2363 2487 return $this->last_result; 2364 2488 } 2489 2365 2490 return null; 2366 2491 } 2367 2492 … … 2371 2496 * @since 4.2.0 2372 2497 * 2373 2498 * @param string $table Table name. 2499 * 2374 2500 * @return string|WP_Error Table character set, WP_Error object if it couldn't be found. 2375 2501 */ 2376 2502 protected function get_table_charset( $table ) { … … 2385 2511 * @since 4.2.0 2386 2512 * 2387 2513 * @param string $charset The character set to use. Default null. 2388 * @param string $table 2514 * @param string $table The name of the table being checked. 2389 2515 */ 2390 2516 $charset = apply_filters( 'pre_get_table_charset', null, $table ); 2391 2517 if ( null !== $charset ) { … … 2399 2525 $charsets = $columns = array(); 2400 2526 2401 2527 $table_parts = explode( '.', $table ); 2402 $table = '`' . implode( '`.`', $table_parts ) . '`';2403 $results = $this->get_results( "SHOW FULL COLUMNS FROM $table" );2528 $table = '`' . implode( '`.`', $table_parts ) . '`'; 2529 $results = $this->get_results( "SHOW FULL COLUMNS FROM $table" ); 2404 2530 if ( ! $results ) { 2405 2531 return new WP_Error( 'wpdb_get_table_charset_failure' ); 2406 2532 } … … 2426 2552 list( $type ) = explode( '(', $column->Type ); 2427 2553 2428 2554 // A binary/blob means the whole query gets treated like this. 2429 if ( in_array( strtoupper( $type ), array( 'BINARY', 'VARBINARY', 'TINYBLOB', 'MEDIUMBLOB', 'BLOB', 'LONGBLOB' ) ) ) { 2555 if ( in_array( strtoupper( $type ), array( 2556 'BINARY', 2557 'VARBINARY', 2558 'TINYBLOB', 2559 'MEDIUMBLOB', 2560 'BLOB', 2561 'LONGBLOB' 2562 ) ) ) { 2430 2563 $this->table_charset[ $tablekey ] = 'binary'; 2564 2431 2565 return 'binary'; 2432 2566 } 2433 2567 } … … 2462 2596 } 2463 2597 2464 2598 $this->table_charset[ $tablekey ] = $charset; 2599 2465 2600 return $charset; 2466 2601 } 2467 2602 … … 2470 2605 * 2471 2606 * @since 4.2.0 2472 2607 * 2473 * @param string $table 2608 * @param string $table Table name. 2474 2609 * @param string $column Column name. 2610 * 2475 2611 * @return string|false|WP_Error Column character set as a string. False if the column has no 2476 2612 * character set. WP_Error object if there was an error. 2477 2613 */ 2478 2614 public function get_col_charset( $table, $column ) { 2479 $tablekey = strtolower( $table );2615 $tablekey = strtolower( $table ); 2480 2616 $columnkey = strtolower( $column ); 2481 2617 2482 2618 /** … … 2488 2624 * @since 4.2.0 2489 2625 * 2490 2626 * @param string $charset The character set to use. Default null. 2491 * @param string $table 2492 * @param string $column 2627 * @param string $table The name of the table being checked. 2628 * @param string $column The name of the column being checked. 2493 2629 */ 2494 2630 $charset = apply_filters( 'pre_get_col_charset', null, $table, $column ); 2495 2631 if ( null !== $charset ) { … … 2525 2661 } 2526 2662 2527 2663 list( $charset ) = explode( '_', $this->col_meta[ $tablekey ][ $columnkey ]->Collation ); 2664 2528 2665 return $charset; 2529 2666 } 2530 2667 … … 2534 2671 * 2535 2672 * @since 4.2.1 2536 2673 * 2537 * @param string $table 2674 * @param string $table Table name. 2538 2675 * @param string $column Column name. 2676 * 2539 2677 * @return array|false|WP_Error array( 'length' => (int), 'type' => 'byte' | 'char' ) 2540 2678 * false if the column has no length (for example, numeric column) 2541 2679 * WP_Error object if there was an error. 2542 2680 */ 2543 2681 public function get_col_length( $table, $column ) { 2544 $tablekey = strtolower( $table );2682 $tablekey = strtolower( $table ); 2545 2683 $columnkey = strtolower( $column ); 2546 2684 2547 2685 // Skip this entirely if this isn't a MySQL database. … … 2570 2708 $length = false; 2571 2709 } 2572 2710 2573 switch ( $type ) {2711 switch ( $type ) { 2574 2712 case 'char': 2575 2713 case 'varchar': 2576 2714 return array( … … 2627 2765 * @since 4.2.0 2628 2766 * 2629 2767 * @param string $string String to check. 2768 * 2630 2769 * @return bool True if ASCII, false if not. 2631 2770 */ 2632 2771 protected function check_ascii( $string ) { … … 2647 2786 * @since 4.2.0 2648 2787 * 2649 2788 * @param string $query The query to check. 2789 * 2650 2790 * @return bool True if the collation is safe, false if it isn't. 2651 2791 */ 2652 2792 protected function check_safe_collation( $query ) { … … 2671 2811 } 2672 2812 2673 2813 $this->checking_collation = true; 2674 $collation = $this->get_table_charset( $table );2814 $collation = $this->get_table_charset( $table ); 2675 2815 $this->checking_collation = false; 2676 2816 2677 2817 // Tables with no collation, or latin1 only, don't need extra checking. … … 2690 2830 continue; 2691 2831 } 2692 2832 2693 if ( ! in_array( $col->Collation, array( 'utf8_general_ci', 'utf8_bin', 'utf8mb4_general_ci', 'utf8mb4_bin' ), true ) ) { 2833 if ( ! in_array( $col->Collation, array( 2834 'utf8_general_ci', 2835 'utf8_bin', 2836 'utf8mb4_general_ci', 2837 'utf8mb4_bin' 2838 ), true ) ) { 2694 2839 return false; 2695 2840 } 2696 2841 } … … 2706 2851 * @param array $data Array of value arrays. Each value array has the keys 2707 2852 * 'value' and 'charset'. An optional 'ascii' key can be 2708 2853 * set to false to avoid redundant ASCII checks. 2854 * 2709 2855 * @return array|WP_Error The $data parameter, with invalid characters removed from 2710 2856 * each value. This works as a passthrough: any additional keys 2711 2857 * such as 'field' are retained in each value array. If we cannot … … 2718 2864 $charset = $value['charset']; 2719 2865 2720 2866 if ( is_array( $value['length'] ) ) { 2721 $length = $value['length']['length'];2867 $length = $value['length']['length']; 2722 2868 $truncate_by_byte_length = 'byte' === $value['length']['type']; 2723 2869 } else { 2724 2870 $length = false; … … 2742 2888 if ( 2743 2889 // latin1 can store any byte sequence 2744 2890 'latin1' === $charset 2745 ||2891 || 2746 2892 // ASCII is always OK. 2747 2893 ( ! isset( $value['ascii'] ) && $this->check_ascii( $value['value'] ) ) 2748 2894 ) { 2749 2895 $truncate_by_byte_length = true; 2750 $needs_validation = false;2896 $needs_validation = false; 2751 2897 } 2752 2898 2753 2899 if ( $truncate_by_byte_length ) { … … 2781 2927 '; 2782 2928 } 2783 2929 2784 $regex .= '){1,40} # ...one or more times2930 $regex .= '){1,40} # ...one or more times 2785 2931 ) 2786 2932 | . # anything else 2787 2933 /x'; … … 2822 2968 } 2823 2969 2824 2970 if ( is_array( $value['length'] ) ) { 2825 $length = sprintf( '%.0f', $value['length']['length'] );2971 $length = sprintf( '%.0f', $value['length']['length'] ); 2826 2972 $queries[ $col ] = $this->prepare( "CONVERT( LEFT( CONVERT( %s USING $charset ), $length ) USING $connection_charset )", $value['value'] ); 2827 2973 } else if ( 'binary' !== $charset ) { 2828 2974 // If we don't have a length, there's no need to convert binary - it will always return the same result. … … 2843 2989 } 2844 2990 2845 2991 $this->check_current_query = false; 2846 $row = $this->get_row( "SELECT " . implode( ', ', $sql ), ARRAY_A );2992 $row = $this->get_row( "SELECT " . implode( ', ', $sql ), ARRAY_A ); 2847 2993 if ( ! $row ) { 2848 2994 return new WP_Error( 'wpdb_strip_invalid_text_failure' ); 2849 2995 } … … 2864 3010 * @since 4.2.0 2865 3011 * 2866 3012 * @param string $query Query to convert. 3013 * 2867 3014 * @return string|WP_Error The converted query, or a WP_Error object if the conversion fails. 2868 3015 */ 2869 3016 protected function strip_invalid_text_from_query( $query ) { … … 2908 3055 * 2909 3056 * @since 4.2.0 2910 3057 * 2911 * @param string $table 3058 * @param string $table Table name. 2912 3059 * @param string $column Column name. 2913 * @param string $value The text to check. 3060 * @param string $value The text to check. 3061 * 2914 3062 * @return string|WP_Error The converted string, or a WP_Error object if the conversion fails. 2915 3063 */ 2916 3064 public function strip_invalid_text_for_column( $table, $column, $value ) { … … 2949 3097 * @since 4.2.0 2950 3098 * 2951 3099 * @param string $query The query to search. 3100 * 2952 3101 * @return string|false $table The table name found, or false if a table couldn't be found. 2953 3102 */ 2954 3103 protected function get_table_from_query( $query ) { … … 2963 3112 2964 3113 // Quickly match most common queries. 2965 3114 if ( preg_match( '/^\s*(?:' 2966 2967 2968 2969 2970 2971 3115 . 'SELECT.*?\s+FROM' 3116 . '|INSERT(?:\s+LOW_PRIORITY|\s+DELAYED|\s+HIGH_PRIORITY)?(?:\s+IGNORE)?(?:\s+INTO)?' 3117 . '|REPLACE(?:\s+LOW_PRIORITY|\s+DELAYED)?(?:\s+INTO)?' 3118 . '|UPDATE(?:\s+LOW_PRIORITY)?(?:\s+IGNORE)?' 3119 . '|DELETE(?:\s+LOW_PRIORITY|\s+QUICK|\s+IGNORE)*(?:.+?FROM)?' 3120 . ')\s+((?:[0-9a-zA-Z$_.`-]|[\xC2-\xDF][\x80-\xBF])+)/is', $query, $maybe ) ) { 2972 3121 return str_replace( '`', '', $maybe[1] ); 2973 3122 } 2974 3123 … … 2988 3137 2989 3138 // Big pattern for the rest of the table-related queries. 2990 3139 if ( preg_match( '/^\s*(?:' 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3140 . '(?:EXPLAIN\s+(?:EXTENDED\s+)?)?SELECT.*?\s+FROM' 3141 . '|DESCRIBE|DESC|EXPLAIN|HANDLER' 3142 . '|(?:LOCK|UNLOCK)\s+TABLE(?:S)?' 3143 . '|(?:RENAME|OPTIMIZE|BACKUP|RESTORE|CHECK|CHECKSUM|ANALYZE|REPAIR).*\s+TABLE' 3144 . '|TRUNCATE(?:\s+TABLE)?' 3145 . '|CREATE(?:\s+TEMPORARY)?\s+TABLE(?:\s+IF\s+NOT\s+EXISTS)?' 3146 . '|ALTER(?:\s+IGNORE)?\s+TABLE' 3147 . '|DROP\s+TABLE(?:\s+IF\s+EXISTS)?' 3148 . '|CREATE(?:\s+\w+)?\s+INDEX.*\s+ON' 3149 . '|DROP\s+INDEX.*\s+ON' 3150 . '|LOAD\s+DATA.*INFILE.*INTO\s+TABLE' 3151 . '|(?:GRANT|REVOKE).*ON\s+TABLE' 3152 . '|SHOW\s+(?:.*FROM|.*TABLE)' 3153 . ')\s+\(*\s*((?:[0-9a-zA-Z$_.`-]|[\xC2-\xDF][\x80-\xBF])+)\s*\)*/is', $query, $maybe ) ) { 3005 3154 return str_replace( '`', '', $maybe[1] ); 3006 3155 } 3007 3156 … … 3015 3164 * 3016 3165 */ 3017 3166 protected function load_col_info() { 3018 if ( $this->col_info ) 3167 if ( $this->col_info ) { 3019 3168 return; 3169 } 3020 3170 3021 3171 if ( $this->use_mysqli ) { 3022 3172 $num_fields = mysqli_num_fields( $this->result ); 3023 for ( $i = 0; $i < $num_fields; $i ++ ) {3173 for ( $i = 0; $i < $num_fields; $i ++ ) { 3024 3174 $this->col_info[ $i ] = mysqli_fetch_field( $this->result ); 3025 3175 } 3026 3176 } else { 3027 3177 $num_fields = mysql_num_fields( $this->result ); 3028 for ( $i = 0; $i < $num_fields; $i ++ ) {3178 for ( $i = 0; $i < $num_fields; $i ++ ) { 3029 3179 $this->col_info[ $i ] = mysql_fetch_field( $this->result, $i ); 3030 3180 } 3031 3181 } … … 3036 3186 * 3037 3187 * @since 0.71 3038 3188 * 3039 * @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 3040 * @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 3189 * @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 3190 * @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 3191 * 3041 3192 * @return mixed Column Results 3042 3193 */ 3043 public function get_col_info( $info_type = 'name', $col_offset = - 1 ) {3194 public function get_col_info( $info_type = 'name', $col_offset = - 1 ) { 3044 3195 $this->load_col_info(); 3045 3196 3046 3197 if ( $this->col_info ) { 3047 if ( $col_offset == - 1 ) {3048 $i = 0;3198 if ( $col_offset == - 1 ) { 3199 $i = 0; 3049 3200 $new_array = array(); 3050 3201 foreach ( (array) $this->col_info as $col ) { 3051 $new_array[ $i] = $col->{$info_type};3052 $i ++;3202 $new_array[ $i ] = $col->{$info_type}; 3203 $i ++; 3053 3204 } 3205 3054 3206 return $new_array; 3055 3207 } else { 3056 return $this->col_info[ $col_offset]->{$info_type};3208 return $this->col_info[ $col_offset ]->{$info_type}; 3057 3209 } 3058 3210 } 3059 3211 } … … 3067 3219 */ 3068 3220 public function timer_start() { 3069 3221 $this->time_start = microtime( true ); 3222 3070 3223 return true; 3071 3224 } 3072 3225 … … 3088 3241 * 3089 3242 * @since 1.5.0 3090 3243 * 3091 * @param string $message 3244 * @param string $message The Error message 3092 3245 * @param string $error_code Optional. A Computer readable string to identify the error. 3246 * 3093 3247 * @return false|void 3094 3248 */ 3095 3249 public function bail( $message, $error_code = '500' ) { 3096 if ( ! $this->show_errors ) {3250 if ( ! $this->show_errors ) { 3097 3251 if ( class_exists( 'WP_Error', false ) ) { 3098 $this->error = new WP_Error( $error_code, $message);3252 $this->error = new WP_Error( $error_code, $message ); 3099 3253 } else { 3100 3254 $this->error = $message; 3101 3255 } 3256 3102 3257 return false; 3103 3258 } 3104 wp_die( $message);3259 wp_die( $message ); 3105 3260 } 3106 3261 3107 3262 … … 3125 3280 } 3126 3281 3127 3282 if ( $closed ) { 3128 $this->dbh = null;3129 $this->ready = false;3283 $this->dbh = null; 3284 $this->ready = false; 3130 3285 $this->has_connected = false; 3131 3286 } 3132 3287 … … 3146 3301 public function check_database_version() { 3147 3302 global $wp_version, $required_mysql_version; 3148 3303 // Make sure the server has the required MySQL version 3149 if ( version_compare( $this->db_version(), $required_mysql_version, '<') ) {3304 if ( version_compare( $this->db_version(), $required_mysql_version, '<' ) ) { 3150 3305 /* translators: 1: WordPress version number, 2: Minimum required MySQL version number */ 3151 return new WP_Error( 'database_version', sprintf( __( '<strong>ERROR</strong>: WordPress %1$s requires MySQL %2$s or higher' ), $wp_version, $required_mysql_version ));3306 return new WP_Error( 'database_version', sprintf( __( '<strong>ERROR</strong>: WordPress %1$s requires MySQL %2$s or higher' ), $wp_version, $required_mysql_version ) ); 3152 3307 } 3153 3308 } 3154 3309 … … 3166 3321 */ 3167 3322 public function supports_collation() { 3168 3323 _deprecated_function( __FUNCTION__, '3.5.0', 'wpdb::has_cap( \'collation\' )' ); 3324 3169 3325 return $this->has_cap( 'collation' ); 3170 3326 } 3171 3327 … … 3179 3335 public function get_charset_collate() { 3180 3336 $charset_collate = ''; 3181 3337 3182 if ( ! empty( $this->charset ) ) 3338 if ( ! empty( $this->charset ) ) { 3183 3339 $charset_collate = "DEFAULT CHARACTER SET $this->charset"; 3184 if ( ! empty( $this->collate ) ) 3340 } 3341 if ( ! empty( $this->collate ) ) { 3185 3342 $charset_collate .= " COLLATE $this->collate"; 3343 } 3186 3344 3187 3345 return $charset_collate; 3188 3346 } … … 3199 3357 * @param string $db_cap The feature to check for. Accepts 'collation', 3200 3358 * 'group_concat', 'subqueries', 'set_charset', 3201 3359 * 'utf8mb4', or 'utf8mb4_520'. 3360 * 3202 3361 * @return int|false Whether the database feature is supported, false otherwise. 3203 3362 */ 3204 3363 public function has_cap( $db_cap ) { … … 3227 3386 */ 3228 3387 if ( false !== strpos( $client_version, 'mysqlnd' ) ) { 3229 3388 $client_version = preg_replace( '/^\D+([\d.]+).*/', '$1', $client_version ); 3389 3230 3390 return version_compare( $client_version, '5.0.9', '>=' ); 3231 3391 } else { 3232 3392 return version_compare( $client_version, '5.5.3', '>=' ); … … 3265 3425 } else { 3266 3426 $server_info = mysql_get_server_info( $this->dbh ); 3267 3427 } 3428 3268 3429 return preg_replace( '/[^0-9.].*/', '', $server_info ); 3269 3430 } 3270 3431 }