56 | | * Whether to show SQL/DB errors |
57 | | * |
58 | | * @since 0.71 |
59 | | * @access private |
60 | | * @var bool |
61 | | */ |
62 | | var $show_errors = false; |
63 | | |
64 | | /** |
65 | | * Whether to suppress errors during the DB bootstrapping. |
66 | | * |
67 | | * @access private |
68 | | * @since {@internal Version Unknown}} |
69 | | * @var bool |
70 | | */ |
71 | | var $suppress_errors = false; |
72 | | |
73 | | /** |
74 | | * The last error during query. |
75 | | * |
76 | | * @since {@internal Version Unknown}} |
77 | | * @var string |
78 | | */ |
79 | | var $last_error = ''; |
80 | | |
81 | | /** |
82 | | * Amount of queries made |
83 | | * |
84 | | * @since 1.2.0 |
85 | | * @access private |
86 | | * @var int |
87 | | */ |
88 | | var $num_queries = 0; |
89 | | |
90 | | /** |
91 | | * Saved result of the last query made |
92 | | * |
93 | | * @since 1.2.0 |
94 | | * @access private |
95 | | * @var array |
96 | | */ |
97 | | var $last_query; |
98 | | |
99 | | /** |
100 | | * Saved info on the table column |
101 | | * |
102 | | * @since 1.2.0 |
103 | | * @access private |
104 | | * @var array |
105 | | */ |
106 | | var $col_info; |
107 | | |
108 | | /** |
109 | | * Saved queries that were executed |
110 | | * |
111 | | * @since 1.5.0 |
112 | | * @access private |
113 | | * @var array |
114 | | */ |
115 | | var $queries; |
116 | | |
117 | | /** |
118 | | * WordPress table prefix |
119 | | * |
120 | | * You can set this to have multiple WordPress installations |
121 | | * in a single database. The second reason is for possible |
122 | | * security precautions. |
123 | | * |
124 | | * @since 0.71 |
125 | | * @access private |
126 | | * @var string |
127 | | */ |
128 | | var $prefix = ''; |
129 | | |
130 | | /** |
131 | | * Whether the database queries are ready to start executing. |
132 | | * |
133 | | * @since 2.5.0 |
134 | | * @access private |
135 | | * @var bool |
136 | | */ |
137 | | var $ready = false; |
138 | | |
139 | | /** |
140 | | * WordPress Posts table |
141 | | * |
142 | | * @since 1.5.0 |
143 | | * @access public |
144 | | * @var string |
145 | | */ |
146 | | var $posts; |
147 | | |
148 | | /** |
149 | | * WordPress Users table |
150 | | * |
151 | | * @since 1.5.0 |
152 | | * @access public |
153 | | * @var string |
154 | | */ |
155 | | var $users; |
156 | | |
157 | | /** |
158 | | * WordPress Categories table |
159 | | * |
160 | | * @since 1.5.0 |
161 | | * @access public |
162 | | * @var string |
163 | | */ |
164 | | var $categories; |
165 | | |
166 | | /** |
167 | | * WordPress Post to Category table |
168 | | * |
169 | | * @since 1.5.0 |
170 | | * @access public |
171 | | * @var string |
172 | | */ |
173 | | var $post2cat; |
174 | | |
175 | | /** |
176 | | * WordPress Comments table |
177 | | * |
178 | | * @since 1.5.0 |
179 | | * @access public |
180 | | * @var string |
181 | | */ |
182 | | var $comments; |
183 | | |
184 | | /** |
185 | | * WordPress Links table |
186 | | * |
187 | | * @since 1.5.0 |
188 | | * @access public |
189 | | * @var string |
190 | | */ |
191 | | var $links; |
192 | | |
193 | | /** |
194 | | * WordPress Options table |
195 | | * |
196 | | * @since 1.5.0 |
197 | | * @access public |
198 | | * @var string |
199 | | */ |
200 | | var $options; |
201 | | |
202 | | /** |
203 | | * WordPress Post Metadata table |
204 | | * |
205 | | * @since {@internal Version Unknown}} |
206 | | * @access public |
207 | | * @var string |
208 | | */ |
209 | | var $postmeta; |
210 | | |
211 | | /** |
212 | | * WordPress Comment Metadata table |
213 | | * |
214 | | * @since 2.9 |
215 | | * @access public |
216 | | * @var string |
217 | | */ |
218 | | var $commentmeta; |
219 | | |
220 | | /** |
221 | | * WordPress User Metadata table |
222 | | * |
223 | | * @since 2.3.0 |
224 | | * @access public |
225 | | * @var string |
226 | | */ |
227 | | var $usermeta; |
228 | | |
229 | | /** |
230 | | * WordPress Terms table |
231 | | * |
232 | | * @since 2.3.0 |
233 | | * @access public |
234 | | * @var string |
235 | | */ |
236 | | var $terms; |
237 | | |
238 | | /** |
239 | | * WordPress Term Taxonomy table |
240 | | * |
241 | | * @since 2.3.0 |
242 | | * @access public |
243 | | * @var string |
244 | | */ |
245 | | var $term_taxonomy; |
246 | | |
247 | | /** |
248 | | * WordPress Term Relationships table |
249 | | * |
250 | | * @since 2.3.0 |
251 | | * @access public |
252 | | * @var string |
253 | | */ |
254 | | var $term_relationships; |
255 | | |
256 | | /** |
257 | | * List of WordPress tables |
258 | | * |
259 | | * @since {@internal Version Unknown}} |
260 | | * @access private |
261 | | * @var array |
262 | | */ |
263 | | var $tables = array('users', 'usermeta', 'posts', 'categories', 'post2cat', 'comments', 'links', 'link2cat', 'options', |
264 | | 'postmeta', 'terms', 'term_taxonomy', 'term_relationships', 'commentmeta'); |
265 | | |
266 | | /** |
267 | | * List of deprecated WordPress tables |
268 | | * |
269 | | * @since 2.9.0 |
270 | | * @access private |
271 | | * @var array |
272 | | */ |
273 | | var $old_tables = array('categories', 'post2cat', 'link2cat'); |
274 | | |
275 | | |
276 | | /** |
277 | | * Format specifiers for DB columns. Columns not listed here default to %s. Initialized in wp-settings.php. |
278 | | * |
279 | | * Keys are colmn names, values are format types: 'ID' => '%d' |
280 | | * |
281 | | * @since 2.8.0 |
282 | | * @see wpdb:prepare() |
283 | | * @see wpdb:insert() |
284 | | * @see wpdb:update() |
285 | | * @access public |
286 | | * @war array |
287 | | */ |
288 | | var $field_types = array(); |
289 | | |
290 | | /** |
291 | | * Database table columns charset |
292 | | * |
293 | | * @since 2.2.0 |
294 | | * @access public |
295 | | * @var string |
296 | | */ |
297 | | var $charset; |
298 | | |
299 | | /** |
300 | | * Database table columns collate |
301 | | * |
302 | | * @since 2.2.0 |
303 | | * @access public |
304 | | * @var string |
305 | | */ |
306 | | var $collate; |
307 | | |
308 | | /** |
309 | | * Whether to use mysql_real_escape_string |
310 | | * |
311 | | * @since 2.8.0 |
312 | | * @access public |
313 | | * @var bool |
314 | | */ |
315 | | var $real_escape = false; |
316 | | |
317 | | /** |
318 | | * Database Username |
319 | | * |
320 | | * @since 2.9.0 |
321 | | * @access private |
322 | | * @var string |
323 | | */ |
324 | | var $dbuser; |
325 | | |
326 | | /** |
327 | | * Connects to the database server and selects a database |
328 | | * |
329 | | * PHP4 compatibility layer for calling the PHP5 constructor. |
330 | | * |
331 | | * @uses wpdb::__construct() Passes parameters and returns result |
332 | | * @since 0.71 |
333 | | * |
334 | | * @param string $dbuser MySQL database user |
335 | | * @param string $dbpassword MySQL database password |
336 | | * @param string $dbname MySQL database name |
337 | | * @param string $dbhost MySQL database host |
338 | | */ |
339 | | function wpdb($dbuser, $dbpassword, $dbname, $dbhost) { |
340 | | return $this->__construct($dbuser, $dbpassword, $dbname, $dbhost); |
341 | | } |
342 | | |
343 | | /** |
344 | | * Connects to the database server and selects a database |
345 | | * |
346 | | * PHP5 style constructor for compatibility with PHP5. Does |
347 | | * the actual setting up of the class properties and connection |
348 | | * to the database. |
349 | | * |
350 | | * @since 2.0.8 |
351 | | * |
352 | | * @param string $dbuser MySQL database user |
353 | | * @param string $dbpassword MySQL database password |
354 | | * @param string $dbname MySQL database name |
355 | | * @param string $dbhost MySQL database host |
356 | | */ |
357 | | function __construct($dbuser, $dbpassword, $dbname, $dbhost) { |
358 | | register_shutdown_function(array(&$this, "__destruct")); |
359 | | |
360 | | if ( defined('WP_DEBUG') and WP_DEBUG == true ) |
361 | | $this->show_errors(); |
362 | | |
363 | | if ( defined('DB_CHARSET') ) |
364 | | $this->charset = DB_CHARSET; |
365 | | |
366 | | if ( defined('DB_COLLATE') ) |
367 | | $this->collate = DB_COLLATE; |
368 | | |
369 | | $this->dbuser = $dbuser; |
370 | | |
371 | | $this->dbh = @mysql_connect($dbhost, $dbuser, $dbpassword, true); |
372 | | if (!$this->dbh) { |
373 | | $this->bail(sprintf(/*WP_I18N_DB_CONN_ERROR*/" |
374 | | <h1>Error establishing a database connection</h1> |
375 | | <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> |
376 | | <ul> |
377 | | <li>Are you sure you have the correct username and password?</li> |
378 | | <li>Are you sure that you have typed the correct hostname?</li> |
379 | | <li>Are you sure that the database server is running?</li> |
380 | | </ul> |
381 | | <p>If you're unsure what these terms mean you should probably contact your host. If you still need help you can always visit the <a href='http://wordpress.org/support/'>WordPress Support Forums</a>.</p> |
382 | | "/*/WP_I18N_DB_CONN_ERROR*/, $dbhost), 'db_connect_fail'); |
383 | | return; |
384 | | } |
385 | | |
386 | | $this->ready = true; |
387 | | |
388 | | if ( $this->has_cap( 'collation' ) ) { |
389 | | if ( !empty($this->charset) ) { |
390 | | if ( function_exists('mysql_set_charset') ) { |
391 | | mysql_set_charset($this->charset, $this->dbh); |
392 | | $this->real_escape = true; |
393 | | } else { |
394 | | $collation_query = "SET NAMES '{$this->charset}'"; |
395 | | if ( !empty($this->collate) ) |
396 | | $collation_query .= " COLLATE '{$this->collate}'"; |
397 | | $this->query($collation_query); |
398 | | } |
399 | | } |
400 | | } |
401 | | |
402 | | $this->select($dbname); |
403 | | } |
404 | | |
405 | | /** |
406 | | * PHP5 style destructor and will run when database object is destroyed. |
407 | | * |
408 | | * @since 2.0.8 |
409 | | * |
410 | | * @return bool Always true |
411 | | */ |
412 | | function __destruct() { |
413 | | return true; |
414 | | } |
415 | | |
416 | | /** |
417 | | * Sets the table prefix for the WordPress tables. |
418 | | * |
419 | | * Also allows for the CUSTOM_USER_TABLE and CUSTOM_USER_META_TABLE to |
420 | | * override the WordPress users and usersmeta tables that would otherwise be determined by the $prefix. |
421 | | * |
422 | | * @since 2.5.0 |
423 | | * |
424 | | * @param string $prefix Alphanumeric name for the new prefix. |
425 | | * @return string|WP_Error Old prefix or WP_Error on error |
426 | | */ |
427 | | function set_prefix($prefix) { |
428 | | |
429 | | if ( preg_match('|[^a-z0-9_]|i', $prefix) ) |
430 | | return new WP_Error('invalid_db_prefix', /*WP_I18N_DB_BAD_PREFIX*/'Invalid database prefix'/*/WP_I18N_DB_BAD_PREFIX*/); |
431 | | |
432 | | $old_prefix = $this->prefix; |
433 | | $this->prefix = $prefix; |
434 | | |
435 | | foreach ( (array) $this->tables as $table ) |
436 | | $this->$table = $this->prefix . $table; |
437 | | |
438 | | if ( defined('CUSTOM_USER_TABLE') ) |
439 | | $this->users = CUSTOM_USER_TABLE; |
440 | | |
441 | | if ( defined('CUSTOM_USER_META_TABLE') ) |
442 | | $this->usermeta = CUSTOM_USER_META_TABLE; |
443 | | |
444 | | return $old_prefix; |
445 | | } |
446 | | |
447 | | /** |
448 | | * Selects a database using the current database connection. |
449 | | * |
450 | | * The database name will be changed based on the current database |
451 | | * connection. On failure, the execution will bail and display an DB error. |
452 | | * |
453 | | * @since 0.71 |
454 | | * |
455 | | * @param string $db MySQL database name |
456 | | * @return null Always null. |
457 | | */ |
458 | | function select($db) { |
459 | | if (!@mysql_select_db($db, $this->dbh)) { |
460 | | $this->ready = false; |
461 | | $this->bail(sprintf(/*WP_I18N_DB_SELECT_DB*/' |
462 | | <h1>Can’t select database</h1> |
463 | | <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> |
464 | | <ul> |
465 | | <li>Are you sure it exists?</li> |
466 | | <li>Does the user <code>%2$s</code> have permission to use the <code>%1$s</code> database?</li> |
467 | | <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> |
468 | | </ul> |
469 | | <p>If you don\'t know how to setup a database you should <strong>contact your host</strong>. If all else fails you may find help at the <a href="http://wordpress.org/support/">WordPress Support Forums</a>.</p>'/*/WP_I18N_DB_SELECT_DB*/, $db, $this->dbuser), 'db_select_fail'); |
470 | | return; |
471 | | } |
472 | | } |
473 | | |
474 | | function _weak_escape($string) { |
475 | | return addslashes($string); |
476 | | } |
477 | | |
478 | | function _real_escape($string) { |
479 | | if ( $this->dbh && $this->real_escape ) |
480 | | return mysql_real_escape_string( $string, $this->dbh ); |
481 | | else |
482 | | return addslashes( $string ); |
483 | | } |
484 | | |
485 | | function _escape($data) { |
486 | | if ( is_array($data) ) { |
487 | | foreach ( (array) $data as $k => $v ) { |
488 | | if ( is_array($v) ) |
489 | | $data[$k] = $this->_escape( $v ); |
490 | | else |
491 | | $data[$k] = $this->_real_escape( $v ); |
492 | | } |
493 | | } else { |
494 | | $data = $this->_real_escape( $data ); |
495 | | } |
496 | | |
497 | | return $data; |
498 | | } |
499 | | |
500 | | /** |
501 | | * Escapes content for insertion into the database using addslashes(), for security |
502 | | * |
503 | | * @since 0.71 |
504 | | * |
505 | | * @param string|array $data |
506 | | * @return string query safe string |
507 | | */ |
508 | | function escape($data) { |
509 | | if ( is_array($data) ) { |
510 | | foreach ( (array) $data as $k => $v ) { |
511 | | if ( is_array($v) ) |
512 | | $data[$k] = $this->escape( $v ); |
513 | | else |
514 | | $data[$k] = $this->_weak_escape( $v ); |
515 | | } |
516 | | } else { |
517 | | $data = $this->_weak_escape( $data ); |
518 | | } |
519 | | |
520 | | return $data; |
521 | | } |
522 | | |
523 | | /** |
524 | | * Escapes content by reference for insertion into the database, for security |
525 | | * |
526 | | * @since 2.3.0 |
527 | | * |
528 | | * @param string $s |
529 | | */ |
530 | | function escape_by_ref(&$string) { |
531 | | $string = $this->_real_escape( $string ); |
532 | | } |
533 | | |
534 | | /** |
535 | | * Prepares a SQL query for safe execution. Uses sprintf()-like syntax. |
536 | | * |
537 | | * This function only supports a small subset of the sprintf syntax; it only supports %d (decimal number), %s (string). |
538 | | * Does not support sign, padding, alignment, width or precision specifiers. |
539 | | * Does not support argument numbering/swapping. |
540 | | * |
541 | | * May be called like {@link http://php.net/sprintf sprintf()} or like {@link http://php.net/vsprintf vsprintf()}. |
542 | | * |
543 | | * Both %d and %s should be left unquoted in the query string. |
544 | | * |
545 | | * <code> |
546 | | * wpdb::prepare( "SELECT * FROM `table` WHERE `column` = %s AND `field` = %d", "foo", 1337 ) |
547 | | * </code> |
548 | | * |
549 | | * @link http://php.net/sprintf Description of syntax. |
550 | | * @since 2.3.0 |
551 | | * |
552 | | * @param string $query Query statement with sprintf()-like placeholders |
553 | | * @param array|mixed $args The array of variables to substitute into the query's placeholders if being called like {@link http://php.net/vsprintf vsprintf()}, or the first variable to substitute into the query's placeholders if being called like {@link http://php.net/sprintf sprintf()}. |
554 | | * @param mixed $args,... further variables to substitute into the query's placeholders if being called like {@link http://php.net/sprintf sprintf()}. |
555 | | * @return null|string Sanitized query string |
556 | | */ |
557 | | function prepare($query = null) { // ( $query, *$args ) |
558 | | if ( is_null( $query ) ) |
559 | | return; |
560 | | $args = func_get_args(); |
561 | | array_shift($args); |
562 | | // If args were passed as an array (as in vsprintf), move them up |
563 | | if ( isset($args[0]) && is_array($args[0]) ) |
564 | | $args = $args[0]; |
565 | | $query = str_replace("'%s'", '%s', $query); // in case someone mistakenly already singlequoted it |
566 | | $query = str_replace('"%s"', '%s', $query); // doublequote unquoting |
567 | | $query = str_replace('%s', "'%s'", $query); // quote the strings |
568 | | array_walk($args, array(&$this, 'escape_by_ref')); |
569 | | return @vsprintf($query, $args); |
570 | | } |
571 | | |
572 | | /** |
573 | | * Print SQL/DB error. |
574 | | * |
575 | | * @since 0.71 |
576 | | * @global array $EZSQL_ERROR Stores error information of query and error string |
577 | | * |
578 | | * @param string $str The error to display |
579 | | * @return bool False if the showing of errors is disabled. |
580 | | */ |
581 | | function print_error($str = '') { |
582 | | global $EZSQL_ERROR; |
583 | | |
584 | | if (!$str) $str = mysql_error($this->dbh); |
585 | | $EZSQL_ERROR[] = array ('query' => $this->last_query, 'error_str' => $str); |
586 | | |
587 | | if ( $this->suppress_errors ) |
588 | | return false; |
589 | | |
590 | | if ( $caller = $this->get_caller() ) |
591 | | $error_str = sprintf(/*WP_I18N_DB_QUERY_ERROR_FULL*/'WordPress database error %1$s for query %2$s made by %3$s'/*/WP_I18N_DB_QUERY_ERROR_FULL*/, $str, $this->last_query, $caller); |
592 | | else |
593 | | $error_str = sprintf(/*WP_I18N_DB_QUERY_ERROR*/'WordPress database error %1$s for query %2$s'/*/WP_I18N_DB_QUERY_ERROR*/, $str, $this->last_query); |
594 | | |
595 | | $log_error = true; |
596 | | if ( ! function_exists('error_log') ) |
597 | | $log_error = false; |
598 | | |
599 | | $log_file = @ini_get('error_log'); |
600 | | if ( !empty($log_file) && ('syslog' != $log_file) && !@is_writable($log_file) ) |
601 | | $log_error = false; |
602 | | |
603 | | if ( $log_error ) |
604 | | @error_log($error_str, 0); |
605 | | |
606 | | // Is error output turned on or not.. |
607 | | if ( !$this->show_errors ) |
608 | | return false; |
609 | | |
610 | | $str = htmlspecialchars($str, ENT_QUOTES); |
611 | | $query = htmlspecialchars($this->last_query, ENT_QUOTES); |
612 | | |
613 | | // If there is an error then take note of it |
614 | | print "<div id='error'> |
615 | | <p class='wpdberror'><strong>WordPress database error:</strong> [$str]<br /> |
616 | | <code>$query</code></p> |
617 | | </div>"; |
618 | | } |
619 | | |
620 | | /** |
621 | | * Enables showing of database errors. |
622 | | * |
623 | | * This function should be used only to enable showing of errors. |
624 | | * wpdb::hide_errors() should be used instead for hiding of errors. However, |
625 | | * this function can be used to enable and disable showing of database |
626 | | * errors. |
627 | | * |
628 | | * @since 0.71 |
629 | | * |
630 | | * @param bool $show Whether to show or hide errors |
631 | | * @return bool Old value for showing errors. |
632 | | */ |
633 | | function show_errors( $show = true ) { |
634 | | $errors = $this->show_errors; |
635 | | $this->show_errors = $show; |
636 | | return $errors; |
637 | | } |
638 | | |
639 | | /** |
640 | | * Disables showing of database errors. |
641 | | * |
642 | | * @since 0.71 |
643 | | * |
644 | | * @return bool Whether showing of errors was active or not |
645 | | */ |
646 | | function hide_errors() { |
647 | | $show = $this->show_errors; |
648 | | $this->show_errors = false; |
649 | | return $show; |
650 | | } |
651 | | |
652 | | /** |
653 | | * Whether to suppress database errors. |
654 | | * |
655 | | * @param unknown_type $suppress |
656 | | * @return unknown |
657 | | */ |
658 | | function suppress_errors( $suppress = true ) { |
659 | | $errors = $this->suppress_errors; |
660 | | $this->suppress_errors = $suppress; |
661 | | return $errors; |
662 | | } |
663 | | |
664 | | /** |
665 | | * Kill cached query results. |
666 | | * |
667 | | * @since 0.71 |
668 | | */ |
669 | | function flush() { |
670 | | $this->last_result = array(); |
671 | | $this->col_info = null; |
672 | | $this->last_query = null; |
673 | | } |
674 | | |
675 | | /** |
676 | | * Perform a MySQL database query, using current database connection. |
677 | | * |
678 | | * More information can be found on the codex page. |
679 | | * |
680 | | * @since 0.71 |
681 | | * |
682 | | * @param string $query |
683 | | * @return int|false Number of rows affected/selected or false on error |
684 | | */ |
685 | | function query($query) { |
686 | | if ( ! $this->ready ) |
687 | | return false; |
688 | | |
689 | | // filter the query, if filters are available |
690 | | // NOTE: some queries are made before the plugins have been loaded, and thus cannot be filtered with this method |
691 | | if ( function_exists('apply_filters') ) |
692 | | $query = apply_filters('query', $query); |
693 | | |
694 | | // initialise return |
695 | | $return_val = 0; |
696 | | $this->flush(); |
697 | | |
698 | | // Log how the function was called |
699 | | $this->func_call = "\$db->query(\"$query\")"; |
700 | | |
701 | | // Keep track of the last query for debug.. |
702 | | $this->last_query = $query; |
703 | | |
704 | | // Perform the query via std mysql_query function.. |
705 | | if ( defined('SAVEQUERIES') && SAVEQUERIES ) |
706 | | $this->timer_start(); |
707 | | |
708 | | $this->result = @mysql_query($query, $this->dbh); |
709 | | ++$this->num_queries; |
710 | | |
711 | | if ( defined('SAVEQUERIES') && SAVEQUERIES ) |
712 | | $this->queries[] = array( $query, $this->timer_stop(), $this->get_caller() ); |
713 | | |
714 | | // If there is an error then take note of it.. |
715 | | if ( $this->last_error = mysql_error($this->dbh) ) { |
716 | | $this->print_error(); |
717 | | return false; |
718 | | } |
719 | | |
720 | | if ( preg_match("/^\\s*(insert|delete|update|replace|alter) /i",$query) ) { |
721 | | $this->rows_affected = mysql_affected_rows($this->dbh); |
722 | | // Take note of the insert_id |
723 | | if ( preg_match("/^\\s*(insert|replace) /i",$query) ) { |
724 | | $this->insert_id = mysql_insert_id($this->dbh); |
725 | | } |
726 | | // Return number of rows affected |
727 | | $return_val = $this->rows_affected; |
728 | | } else { |
729 | | $i = 0; |
730 | | while ($i < @mysql_num_fields($this->result)) { |
731 | | $this->col_info[$i] = @mysql_fetch_field($this->result); |
732 | | $i++; |
733 | | } |
734 | | $num_rows = 0; |
735 | | while ( $row = @mysql_fetch_object($this->result) ) { |
736 | | $this->last_result[$num_rows] = $row; |
737 | | $num_rows++; |
738 | | } |
739 | | |
740 | | @mysql_free_result($this->result); |
741 | | |
742 | | // Log number of rows the query returned |
743 | | $this->num_rows = $num_rows; |
744 | | |
745 | | // Return number of rows selected |
746 | | $return_val = $this->num_rows; |
747 | | } |
748 | | |
749 | | return $return_val; |
750 | | } |
751 | | |
752 | | /** |
753 | | * Insert a row into a table. |
754 | | * |
755 | | * <code> |
756 | | * wpdb::insert( 'table', array( 'column' => 'foo', 'field' => 1337 ), array( '%s', '%d' ) ) |
757 | | * </code> |
758 | | * |
759 | | * @since 2.5.0 |
760 | | * @see wpdb::prepare() |
761 | | * |
762 | | * @param string $table table name |
763 | | * @param array $data Data to insert (in column => value pairs). Both $data columns and $data values should be "raw" (neither should be SQL escaped). |
764 | | * @param array|string $format (optional) An array of formats to be mapped to each of the value in $data. If string, that format will be used for all of the values in $data. A format is one of '%d', '%s' (decimal number, string). If omitted, all values in $data will be treated as strings. |
765 | | * @return int|false The number of rows inserted, or false on error. |
766 | | */ |
767 | | function insert($table, $data, $format = null) { |
768 | | $formats = $format = (array) $format; |
769 | | $fields = array_keys($data); |
770 | | $formatted_fields = array(); |
771 | | foreach ( $fields as $field ) { |
772 | | if ( !empty($format) ) |
773 | | $form = ( $form = array_shift($formats) ) ? $form : $format[0]; |
774 | | elseif ( isset($this->field_types[$field]) ) |
775 | | $form = $this->field_types[$field]; |
776 | | else |
777 | | $form = '%s'; |
778 | | $formatted_fields[] = $form; |
779 | | } |
780 | | $sql = "INSERT INTO `$table` (`" . implode( '`,`', $fields ) . "`) VALUES ('" . implode( "','", $formatted_fields ) . "')"; |
781 | | return $this->query( $this->prepare( $sql, $data) ); |
782 | | } |
783 | | |
784 | | |
785 | | /** |
786 | | * Update a row in the table |
787 | | * |
788 | | * <code> |
789 | | * wpdb::update( 'table', array( 'column' => 'foo', 'field' => 1337 ), array( 'ID' => 1 ), array( '%s', '%d' ), array( '%d' ) ) |
790 | | * </code> |
791 | | * |
792 | | * @since 2.5.0 |
793 | | * @see wpdb::prepare() |
794 | | * |
795 | | * @param string $table table name |
796 | | * @param array $data Data to update (in column => value pairs). Both $data columns and $data values should be "raw" (neither should be SQL escaped). |
797 | | * @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". |
798 | | * @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. A format is one of '%d', '%s' (decimal number, string). If omitted, all values in $data will be treated as strings. |
799 | | * @param array|string $format_where (optional) An array of formats to be mapped to each of the values in $where. If string, that format will be used for all of the items in $where. A format is one of '%d', '%s' (decimal number, string). If omitted, all values in $where will be treated as strings. |
800 | | * @return int|false The number of rows updated, or false on error. |
801 | | */ |
802 | | function update($table, $data, $where, $format = null, $where_format = null) { |
803 | | if ( !is_array( $where ) ) |
804 | | return false; |
805 | | |
806 | | $formats = $format = (array) $format; |
807 | | $bits = $wheres = array(); |
808 | | foreach ( (array) array_keys($data) as $field ) { |
809 | | if ( !empty($format) ) |
810 | | $form = ( $form = array_shift($formats) ) ? $form : $format[0]; |
811 | | elseif ( isset($this->field_types[$field]) ) |
812 | | $form = $this->field_types[$field]; |
813 | | else |
814 | | $form = '%s'; |
815 | | $bits[] = "`$field` = {$form}"; |
816 | | } |
817 | | |
818 | | $where_formats = $where_format = (array) $where_format; |
819 | | foreach ( (array) array_keys($where) as $field ) { |
820 | | if ( !empty($where_format) ) |
821 | | $form = ( $form = array_shift($where_formats) ) ? $form : $where_format[0]; |
822 | | elseif ( isset($this->field_types[$field]) ) |
823 | | $form = $this->field_types[$field]; |
824 | | else |
825 | | $form = '%s'; |
826 | | $wheres[] = "`$field` = {$form}"; |
827 | | } |
828 | | |
829 | | $sql = "UPDATE `$table` SET " . implode( ', ', $bits ) . ' WHERE ' . implode( ' AND ', $wheres ); |
830 | | return $this->query( $this->prepare( $sql, array_merge(array_values($data), array_values($where))) ); |
831 | | } |
832 | | |
833 | | /** |
834 | | * Retrieve one variable from the database. |
835 | | * |
836 | | * Executes a SQL query and returns the value from the SQL result. |
837 | | * 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. |
838 | | * If $query is null, this function returns the value in the specified column and row from the previous SQL result. |
839 | | * |
840 | | * @since 0.71 |
841 | | * |
842 | | * @param string|null $query SQL query. If null, use the result from the previous query. |
843 | | * @param int $x (optional) Column of value to return. Indexed from 0. |
844 | | * @param int $y (optional) Row of value to return. Indexed from 0. |
845 | | * @return string Database query result |
846 | | */ |
847 | | function get_var($query=null, $x = 0, $y = 0) { |
848 | | $this->func_call = "\$db->get_var(\"$query\",$x,$y)"; |
849 | | if ( $query ) |
850 | | $this->query($query); |
851 | | |
852 | | // Extract var out of cached results based x,y vals |
853 | | if ( !empty( $this->last_result[$y] ) ) { |
854 | | $values = array_values(get_object_vars($this->last_result[$y])); |
855 | | } |
856 | | |
857 | | // If there is a value return it else return null |
858 | | return (isset($values[$x]) && $values[$x]!=='') ? $values[$x] : null; |
859 | | } |
860 | | |
861 | | /** |
862 | | * Retrieve one row from the database. |
863 | | * |
864 | | * Executes a SQL query and returns the row from the SQL result. |
865 | | * |
866 | | * @since 0.71 |
867 | | * |
868 | | * @param string|null $query SQL query. |
869 | | * @param string $output (optional) one of ARRAY_A | ARRAY_N | OBJECT constants. Return an associative array (column => value, ...), a numerically indexed array (0 => value, ...) or an object ( ->column = value ), respectively. |
870 | | * @param int $y (optional) Row to return. Indexed from 0. |
871 | | * @return mixed Database query result in format specifed by $output |
872 | | */ |
873 | | function get_row($query = null, $output = OBJECT, $y = 0) { |
874 | | $this->func_call = "\$db->get_row(\"$query\",$output,$y)"; |
875 | | if ( $query ) |
876 | | $this->query($query); |
877 | | else |
878 | | return null; |
879 | | |
880 | | if ( !isset($this->last_result[$y]) ) |
881 | | return null; |
882 | | |
883 | | if ( $output == OBJECT ) { |
884 | | return $this->last_result[$y] ? $this->last_result[$y] : null; |
885 | | } elseif ( $output == ARRAY_A ) { |
886 | | return $this->last_result[$y] ? get_object_vars($this->last_result[$y]) : null; |
887 | | } elseif ( $output == ARRAY_N ) { |
888 | | return $this->last_result[$y] ? array_values(get_object_vars($this->last_result[$y])) : null; |
889 | | } else { |
890 | | $this->print_error(/*WP_I18N_DB_GETROW_ERROR*/" \$db->get_row(string query, output type, int offset) -- Output type must be one of: OBJECT, ARRAY_A, ARRAY_N"/*/WP_I18N_DB_GETROW_ERROR*/); |
891 | | } |
892 | | } |
893 | | |
894 | | /** |
895 | | * Retrieve one column from the database. |
896 | | * |
897 | | * Executes a SQL query and returns the column from the SQL result. |
898 | | * If the SQL result contains more than one column, this function returns the column specified. |
899 | | * If $query is null, this function returns the specified column from the previous SQL result. |
900 | | * |
901 | | * @since 0.71 |
902 | | * |
903 | | * @param string|null $query SQL query. If null, use the result from the previous query. |
904 | | * @param int $x Column to return. Indexed from 0. |
905 | | * @return array Database query result. Array indexed from 0 by SQL result row number. |
906 | | */ |
907 | | function get_col($query = null , $x = 0) { |
908 | | if ( $query ) |
909 | | $this->query($query); |
910 | | |
911 | | $new_array = array(); |
912 | | // Extract the column values |
913 | | for ( $i=0; $i < count($this->last_result); $i++ ) { |
914 | | $new_array[$i] = $this->get_var(null, $x, $i); |
915 | | } |
916 | | return $new_array; |
917 | | } |
918 | | |
919 | | /** |
920 | | * Retrieve an entire SQL result set from the database (i.e., many rows) |
921 | | * |
922 | | * Executes a SQL query and returns the entire SQL result. |
923 | | * |
924 | | * @since 0.71 |
925 | | * |
926 | | * @param string $query SQL query. |
927 | | * @param string $output (optional) ane of ARRAY_A | ARRAY_N | OBJECT | OBJECT_K constants. With one of the first three, return an array of rows indexed from 0 by SQL result row number. Each row is an associative array (column => value, ...), a numerically indexed array (0 => value, ...), or an object. ( ->column = value ), respectively. With OBJECT_K, return an associative array of row objects keyed by the value of each row's first column's value. Duplicate keys are discarded. |
928 | | * @return mixed Database query results |
929 | | */ |
930 | | function get_results($query = null, $output = OBJECT) { |
931 | | $this->func_call = "\$db->get_results(\"$query\", $output)"; |
932 | | |
933 | | if ( $query ) |
934 | | $this->query($query); |
935 | | else |
936 | | return null; |
937 | | |
938 | | if ( $output == OBJECT ) { |
939 | | // Return an integer-keyed array of row objects |
940 | | return $this->last_result; |
941 | | } elseif ( $output == OBJECT_K ) { |
942 | | // Return an array of row objects with keys from column 1 |
943 | | // (Duplicates are discarded) |
944 | | foreach ( $this->last_result as $row ) { |
945 | | $key = array_shift( get_object_vars( $row ) ); |
946 | | if ( !isset( $new_array[ $key ] ) ) |
947 | | $new_array[ $key ] = $row; |
948 | | } |
949 | | return $new_array; |
950 | | } elseif ( $output == ARRAY_A || $output == ARRAY_N ) { |
951 | | // Return an integer-keyed array of... |
952 | | if ( $this->last_result ) { |
953 | | $i = 0; |
954 | | foreach( (array) $this->last_result as $row ) { |
955 | | if ( $output == ARRAY_N ) { |
956 | | // ...integer-keyed row arrays |
957 | | $new_array[$i] = array_values( get_object_vars( $row ) ); |
958 | | } else { |
959 | | // ...column name-keyed row arrays |
960 | | $new_array[$i] = get_object_vars( $row ); |
961 | | } |
962 | | ++$i; |
963 | | } |
964 | | return $new_array; |
965 | | } |
966 | | } |
967 | | } |
968 | | |
969 | | /** |
970 | | * Retrieve column metadata from the last query. |
971 | | * |
972 | | * @since 0.71 |
973 | | * |
974 | | * @param string $info_type one of name, table, def, max_length, not_null, primary_key, multiple_key, unique_key, numeric, blob, type, unsigned, zerofill |
975 | | * @param int $col_offset 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 |
976 | | * @return mixed Column Results |
977 | | */ |
978 | | function get_col_info($info_type = 'name', $col_offset = -1) { |
979 | | if ( $this->col_info ) { |
980 | | if ( $col_offset == -1 ) { |
981 | | $i = 0; |
982 | | foreach( (array) $this->col_info as $col ) { |
983 | | $new_array[$i] = $col->{$info_type}; |
984 | | $i++; |
985 | | } |
986 | | return $new_array; |
987 | | } else { |
988 | | return $this->col_info[$col_offset]->{$info_type}; |
989 | | } |
990 | | } |
991 | | } |
992 | | |
993 | | /** |
994 | | * Starts the timer, for debugging purposes. |
995 | | * |
996 | | * @since 1.5.0 |
997 | | * |
998 | | * @return true |
999 | | */ |
1000 | | function timer_start() { |
1001 | | $mtime = microtime(); |
1002 | | $mtime = explode(' ', $mtime); |
1003 | | $this->time_start = $mtime[1] + $mtime[0]; |
1004 | | return true; |
1005 | | } |
1006 | | |
1007 | | /** |
1008 | | * Stops the debugging timer. |
1009 | | * |
1010 | | * @since 1.5.0 |
1011 | | * |
1012 | | * @return int Total time spent on the query, in milliseconds |
1013 | | */ |
1014 | | function timer_stop() { |
1015 | | $mtime = microtime(); |
1016 | | $mtime = explode(' ', $mtime); |
1017 | | $time_end = $mtime[1] + $mtime[0]; |
1018 | | $time_total = $time_end - $this->time_start; |
1019 | | return $time_total; |
1020 | | } |
1021 | | |
1022 | | /** |
1023 | | * Wraps errors in a nice header and footer and dies. |
1024 | | * |
1025 | | * Will not die if wpdb::$show_errors is true |
1026 | | * |
1027 | | * @since 1.5.0 |
1028 | | * |
1029 | | * @param string $message The Error message |
1030 | | * @param string $error_code (optional) A Computer readable string to identify the error. |
1031 | | * @return false|void |
1032 | | */ |
1033 | | function bail($message, $error_code = '500') { |
1034 | | if ( !$this->show_errors ) { |
1035 | | if ( class_exists('WP_Error') ) |
1036 | | $this->error = new WP_Error($error_code, $message); |
1037 | | else |
1038 | | $this->error = $message; |
1039 | | return false; |
1040 | | } |
1041 | | wp_die($message); |
1042 | | } |
1043 | | |
1044 | | /** |
1045 | | * Whether or not MySQL database is at least the required minimum version. |
1046 | | * |
1047 | | * @since 2.5.0 |
1048 | | * @uses $wp_version |
1049 | | * |
1050 | | * @return WP_Error |
1051 | | */ |
1052 | | function check_database_version() |
1053 | | { |
1054 | | global $wp_version; |
1055 | | // Make sure the server has MySQL 4.0 |
1056 | | if ( version_compare($this->db_version(), '4.0.0', '<') ) |
1057 | | return new WP_Error('database_version',sprintf(__('<strong>ERROR</strong>: WordPress %s requires MySQL 4.0.0 or higher'), $wp_version)); |
1058 | | } |
1059 | | |
1060 | | /** |
1061 | | * Whether of not the database supports collation. |
1062 | | * |
1063 | | * Called when WordPress is generating the table scheme. |
1064 | | * |
1065 | | * @since 2.5.0 |
1066 | | * |
1067 | | * @return bool True if collation is supported, false if version does not |
1068 | | */ |
1069 | | function supports_collation() { |
1070 | | return $this->has_cap( 'collation' ); |
1071 | | } |
1072 | | |
1073 | | /** |
1074 | | * Generic function to determine if a database supports a particular feature |
1075 | | * @param string $db_cap the feature |
1076 | | * @param false|string|resource $dbh_or_table (not implemented) Which database to test. False = the currently selected database, string = the database containing the specified table, resource = the database corresponding to the specified mysql resource. |
1077 | | * @return bool |
1078 | | */ |
1079 | | function has_cap( $db_cap ) { |
1080 | | $version = $this->db_version(); |
1081 | | |
1082 | | switch ( strtolower( $db_cap ) ) : |
1083 | | case 'collation' : // @since 2.5.0 |
1084 | | case 'group_concat' : // @since 2.7 |
1085 | | case 'subqueries' : // @since 2.7 |
1086 | | return version_compare($version, '4.1', '>='); |
1087 | | break; |
1088 | | endswitch; |
1089 | | |
1090 | | return false; |
1091 | | } |
1092 | | |
1093 | | /** |
1094 | | * Retrieve the name of the function that called wpdb. |
1095 | | * |
1096 | | * Requires PHP 4.3 and searches up the list of functions until it reaches |
1097 | | * the one that would most logically had called this method. |
1098 | | * |
1099 | | * @since 2.5.0 |
1100 | | * |
1101 | | * @return string The name of the calling function |
1102 | | */ |
1103 | | function get_caller() { |
1104 | | // requires PHP 4.3+ |
1105 | | if ( !is_callable('debug_backtrace') ) |
1106 | | return ''; |
1107 | | |
1108 | | $bt = debug_backtrace(); |
1109 | | $caller = array(); |
1110 | | |
1111 | | $bt = array_reverse( $bt ); |
1112 | | foreach ( (array) $bt as $call ) { |
1113 | | if ( @$call['class'] == __CLASS__ ) |
1114 | | continue; |
1115 | | $function = $call['function']; |
1116 | | if ( isset( $call['class'] ) ) |
1117 | | $function = $call['class'] . "->$function"; |
1118 | | $caller[] = $function; |
1119 | | } |
1120 | | $caller = join( ', ', $caller ); |
1121 | | |
1122 | | return $caller; |
1123 | | } |
1124 | | |
1125 | | /** |
1126 | | * The database version number |
1127 | | * @param false|string|resource $dbh_or_table (not implemented) Which database to test. False = the currently selected database, string = the database containing the specified table, resource = the database corresponding to the specified mysql resource. |
1128 | | * @return false|string false on failure, version number on success |
1129 | | */ |
1130 | | function db_version() { |
1131 | | return preg_replace('/[^0-9.].*/', '', mysql_get_server_info( $this->dbh )); |
1132 | | } |
1133 | | } |
1134 | | |
1135 | | if ( ! isset($wpdb) ) { |
1136 | | /** |
1137 | | * WordPress Database Object, if it isn't set already in wp-content/db.php |
1138 | | * @global object $wpdb Creates a new wpdb object based on wp-config.php Constants for the database |
1139 | | * @since 0.71 |
1140 | | */ |
| 11 | * WordPress Database Object, if it isn't set already in wp-content/db.php |
| 12 | * @global object $wpdb Creates a new wpdb object based on wp-config.php Constants for the database |
| 13 | * @since 0.71 |
| 14 | */ |