Ticket #11799: 11799.2.patch
| File 11799.2.patch, 44.5 KB (added by , 16 years ago) |
|---|
-
wp-includes/wp-db.php
64 64 /** 65 65 * Whether to suppress errors during the DB bootstrapping. 66 66 * 67 * 68 * @since 2.5 67 69 * @access private 68 * @since {@internal Version Unknown}}69 70 * @var bool 70 71 */ 71 72 var $suppress_errors = false; … … 73 74 /** 74 75 * The last error during query. 75 76 * 76 * @since {@internal Version Unknown}} 77 * @var string 77 * FIXME (hakre) access violations on multiple locations in core 78 * @see get_last_error() 79 * 80 * @since 2.5 81 * @access private 82 * @var string 78 83 */ 79 84 var $last_error = ''; 80 85 81 86 /** 82 87 * Amount of queries made 83 88 * 84 * @since 1.2.089 * @since 1.2.0 85 90 * @access private 86 * @var int91 * @var int 87 92 */ 88 93 var $num_queries = 0; 89 94 90 95 /** 96 * Amount of rows returned by last query operation 97 * 98 * @since 1.2 99 * @access private 100 * @var int 101 */ 102 var $num_rows = 0; 103 104 /** 105 * Number of affected rows by last query operation 106 * 107 * @since 0.71 108 * @access private 109 * @var integer 110 */ 111 var $rows_affected = 0; 112 113 114 /** 91 115 * Saved result of the last query made 92 116 * 93 117 * @since 1.2.0 … … 97 121 var $last_query; 98 122 99 123 /** 124 * Saved resultset of the last query made 125 * 126 * @todo (hakre) get version number 127 * 128 * @since {@internal Version Unknown} 129 * @access private 130 * @var array (null if unintialized) 131 */ 132 var $last_result; 133 134 135 /** 100 136 * Saved info on the table column 101 137 * 102 138 * @since 1.2.0 … … 135 171 * @var bool 136 172 */ 137 173 var $ready = false; 138 var $blogid = 0;139 var $siteid = 0;140 var $blogs;141 var $signups;142 var $site;143 var $sitemeta;144 var $sitecategories;145 var $global_tables = array('blogs', 'signups', 'site', 'sitemeta', 'users', 'usermeta', 'sitecategories', 'registration_log', 'blog_versions');146 174 147 175 /** 148 176 * WordPress Posts table … … 264 292 /** 265 293 * List of WordPress tables 266 294 * 295 * @todo (hakre) get revision number 296 * 267 297 * @since {@internal Version Unknown}} 268 298 * @access private 269 299 * @var array 270 300 */ 271 var $tables = array(' posts', 'categories', 'post2cat', 'comments', 'links', 'link2cat', 'options',301 var $tables = array('users', 'usermeta', 'posts', 'categories', 'post2cat', 'comments', 'links', 'link2cat', 'options', 272 302 'postmeta', 'terms', 'term_taxonomy', 'term_relationships', 'commentmeta'); 273 303 274 304 /** … … 280 310 */ 281 311 var $old_tables = array('categories', 'post2cat', 'link2cat'); 282 312 283 284 313 /** 285 314 * Format specifiers for DB columns. Columns not listed here default to %s. Initialized in wp-settings.php. 286 315 * … … 345 374 * @param string $dbhost MySQL database host 346 375 */ 347 376 function wpdb($dbuser, $dbpassword, $dbname, $dbhost) { 348 if( defined( "WP_USE_MULTIPLE_DB" ) && CONSTANT( "WP_USE_MULTIPLE_DB" ) == true )349 $this->db_connect();350 377 return $this->__construct($dbuser, $dbpassword, $dbname, $dbhost); 351 378 } 352 379 … … 365 392 * @param string $dbhost MySQL database host 366 393 */ 367 394 function __construct($dbuser, $dbpassword, $dbname, $dbhost) { 368 register_shutdown_function( array(&$this, "__destruct"));395 register_shutdown_function( array( &$this, "__destruct" ) ); 369 396 370 397 if ( WP_DEBUG ) 371 398 $this->show_errors(); 372 399 373 if( is_multisite() ) {374 $this->charset = 'utf8';375 if( defined( 'DB_COLLATE' ) && constant( 'DB_COLLATE' ) != '' ) {376 $this->collate = constant( 'DB_COLLATE' );377 } else {378 $this->collate = 'utf8_general_ci';379 }380 }381 382 400 if ( defined('DB_CHARSET') ) 383 401 $this->charset = DB_CHARSET; 384 402 … … 387 405 388 406 $this->dbuser = $dbuser; 389 407 390 $this->dbh = @mysql_connect( $dbhost, $dbuser, $dbpassword, true);391 if ( !$this->dbh) {392 $this->bail( sprintf(/*WP_I18N_DB_CONN_ERROR*/"408 $this->dbh = @mysql_connect( $dbhost, $dbuser, $dbpassword, true ); 409 if ( !$this->dbh ) { 410 $this->bail( sprintf( /*WP_I18N_DB_CONN_ERROR*/" 393 411 <h1>Error establishing a database connection</h1> 394 412 <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> 395 413 <ul> … … 398 416 <li>Are you sure that the database server is running?</li> 399 417 </ul> 400 418 <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> 401 "/*/WP_I18N_DB_CONN_ERROR*/, $dbhost ), 'db_connect_fail');419 "/*/WP_I18N_DB_CONN_ERROR*/, $dbhost ), 'db_connect_fail' ); 402 420 return; 403 421 } 404 422 405 423 $this->ready = true; 406 424 407 if ( $this->has_cap( 'collation' ) && !empty( $this->charset) ) {408 if ( function_exists( 'mysql_set_charset') ) {409 mysql_set_charset( $this->charset, $this->dbh);425 if ( $this->has_cap( 'collation' ) && !empty( $this->charset ) ) { 426 if ( function_exists( 'mysql_set_charset' ) ) { 427 mysql_set_charset( $this->charset, $this->dbh ); 410 428 $this->real_escape = true; 411 429 } else { 412 $collation_query = "SET NAMES '{$this->charset}'"; 413 if ( !empty($this->collate) ) 414 $collation_query .= " COLLATE '{$this->collate}'"; 415 $this->query($collation_query); 430 $query = $this->prepare( 'SET NAMES %s', $this->charset ); 431 if ( !empty( $this->collate ) ) 432 $query .= $this->prepare( ' COLLATE %s', $this->collate ); 433 $this->query( $query ); 434 // @todo (hakre) still addslashes; rest disabled for now (430)) there must be a possibility to switch real_escape on here as well! 416 435 } 417 436 } 418 437 419 $this->select( $dbname, $this->dbh);438 $this->select( $dbname, $this->dbh ); 420 439 } 421 440 422 441 /** 423 442 * PHP5 style destructor and will run when database object is destroyed. 424 443 * 444 * NOTE: 445 * 446 * In difference to the PHP5 behavior of __destruct, this function will 447 * be called when the script shuts down. If the garbage collector will 448 * remove this object earlier in PHP5, this function will be called prior to 449 * script termination. 450 * 451 * Please see {@link __construct() class constructor} and the 452 * {@link register_shutdown_function() register_shutdown_function()}. for 453 * more details. 454 * 455 * @link http://www.php.net/__destruct 456 * @link http://www.php.net/register_shutdown_function 457 * 425 458 * @since 2.0.8 426 459 * 427 * @return bool Always true460 * @return void 428 461 */ 429 462 function __destruct() { 430 return true;431 463 } 432 464 433 465 /** … … 441 473 * @param string $prefix Alphanumeric name for the new prefix. 442 474 * @return string|WP_Error Old prefix or WP_Error on error 443 475 */ 444 function set_prefix( $prefix) {476 function set_prefix( $prefix ) { 445 477 446 if ( preg_match( '|[^a-z0-9_]|i', $prefix) )478 if ( preg_match( '|[^a-z0-9_]|i', $prefix ) ) 447 479 return new WP_Error('invalid_db_prefix', /*WP_I18N_DB_BAD_PREFIX*/'Invalid database prefix'/*/WP_I18N_DB_BAD_PREFIX*/); 448 480 449 if( is_multisite() ) { 450 $old_prefix = ''; 451 } else { 452 $old_prefix = $prefix; 453 } 454 if( isset( $this->base_prefix ) ) 455 $old_prefix = $this->base_prefix; 456 $this->base_prefix = $prefix; 457 foreach ( $this->global_tables as $table ) 458 $this->$table = $prefix . $table; 481 $old_prefix = $this->prefix; 482 $this->prefix = $prefix; 459 483 460 if ( defined('VHOST') && empty($this->blogid) ) 461 return $old_prefix; 462 463 $this->prefix = $this->get_blog_prefix( $this->blogid ); 464 465 foreach ( (array) $this->tables as $table ) 484 foreach ( $this->tables as $table ) 466 485 $this->$table = $this->prefix . $table; 467 486 468 if ( defined( 'CUSTOM_USER_TABLE') )487 if ( defined( 'CUSTOM_USER_TABLE' ) ) 469 488 $this->users = CUSTOM_USER_TABLE; 470 489 471 if ( defined( 'CUSTOM_USER_META_TABLE') )490 if ( defined( 'CUSTOM_USER_META_TABLE' ) ) 472 491 $this->usermeta = CUSTOM_USER_META_TABLE; 473 492 474 493 return $old_prefix; 475 494 } 476 495 477 function set_blog_id($blog_id, $site_id = '') {478 if ( !empty($site_id) )479 $this->siteid = $site_id;480 481 $old_blog_id = $this->blogid;482 $this->blogid = $blog_id;483 484 $this->prefix = $this->get_blog_prefix( $this->blogid );485 486 foreach ( $this->tables as $table )487 $this->$table = $this->prefix . $table;488 489 return $old_blog_id;490 }491 492 function get_blog_prefix( $blog_id = '' ) {493 if ( $blog_id ) {494 if( defined('MULTISITE') && ( $blog_id == 0 || $blog_id == 1) ) {495 return $this->prefix;496 } else {497 return $this->base_prefix . $blog_id . '_';498 }499 } else {500 return $this->base_prefix;501 }502 }503 504 496 /** 505 497 * Selects a database using the current database connection. 506 498 * … … 512 504 * @param string $db MySQL database name 513 505 * @return null Always null. 514 506 */ 515 function select($db , &$dbh) {516 if (!@mysql_select_db($db, $ dbh)) {507 function select($db) { 508 if (!@mysql_select_db($db, $this->dbh)) { 517 509 $this->ready = false; 518 510 $this->bail(sprintf(/*WP_I18N_DB_SELECT_DB*/' 519 511 <h1>Can’t select database</h1> … … 528 520 } 529 521 } 530 522 531 function _weak_escape($string) { 532 return addslashes($string); 533 } 534 535 function _real_escape($string) { 523 /** 524 * real escape 525 * 526 * escape via mysql_real_escape_string() or addslashes() 527 * 528 * @since 2.8 529 * @access private 530 * 531 * @param string $string to escape 532 * @return string escaped 533 */ 534 function _real_escape( $string ) { 536 535 if ( $this->dbh && $this->real_escape ) 537 536 return mysql_real_escape_string( $string, $this->dbh ); 538 537 else 539 538 return addslashes( $string ); 540 539 } 541 540 542 function _escape($data) { 543 if ( is_array($data) ) { 544 foreach ( (array) $data as $k => $v ) { 545 if ( is_array($v) ) 546 $data[$k] = $this->_escape( $v ); 547 else 548 $data[$k] = $this->_real_escape( $v ); 549 } 550 } else { 551 $data = $this->_real_escape( $data ); 552 } 541 /** 542 * escape 543 * 544 * escape data, uses {@see _real_escape()} and works 545 * on arrays as well. 546 * 547 * @since 2.8 548 * @access private 549 * 550 * @param string|array $data to escape 551 * @return string|array escaped 552 */ 553 function _escape( $data ) { 554 if ( is_array( $data ) ) 555 return array_map( array( &$this, '_escape' ), $data ); 553 556 554 return $ data;557 return $this->_real_escape( $data ); 555 558 } 556 559 557 560 /** … … 559 562 * 560 563 * @since 0.71 561 564 * 562 * @param string|array $data563 * @return string query safe string565 * @param string|array $data to escape 566 * @return string|array escaped as query safe string 564 567 */ 565 function escape($data) { 566 if ( is_array($data) ) { 567 foreach ( (array) $data as $k => $v ) { 568 if ( is_array($v) ) 569 $data[$k] = $this->escape( $v ); 570 else 571 $data[$k] = $this->_weak_escape( $v ); 572 } 573 } else { 574 $data = $this->_weak_escape( $data ); 575 } 568 function escape( $data ) { 569 if ( is_array($data) ) 570 return array_map( array( &$this, 'escape' ), $data ); 576 571 577 return $data;572 return addslashes( $data ); 578 573 } 579 574 580 575 /** … … 582 577 * 583 578 * @since 2.3.0 584 579 * 585 * @param string $s 580 * @param string $string to escape 581 * @return void 586 582 */ 587 function escape_by_ref( &$string) {583 function escape_by_ref( &$string ) { 588 584 $string = $this->_real_escape( $string ); 589 585 } 590 586 591 587 /** 592 588 * Prepares a SQL query for safe execution. Uses sprintf()-like syntax. 593 589 * 590 * The following directives can be used in the query format string: 591 * 592 * %d (decimal number) 593 * %s (string) 594 * %% (literal percentage sign - no argument needed) 595 * 596 * Both %d and %s are to be left unquoted in the query string and 597 * they need an argument passed for them. 598 * Literals (%) as parts of the query must be properly written 599 * as %%. 600 * 594 601 * This function only supports a small subset of the sprintf syntax; it only supports %d (decimal number), %s (string). 595 602 * Does not support sign, padding, alignment, width or precision specifiers. 596 603 * Does not support argument numbering/swapping. … … 601 608 * 602 609 * <code> 603 610 * wpdb::prepare( "SELECT * FROM `table` WHERE `column` = %s AND `field` = %d", "foo", 1337 ) 611 * wpdb::prepare( "SELECT DATE_FORMAT(`field`, '%%c') FROM `table` WHERE `column` = %s", 'foo' ); 604 612 * </code> 605 613 * 606 614 * @link http://php.net/sprintf Description of syntax. 607 615 * @since 2.3.0 608 616 * 609 * @param string $query Query statement with sprintf()-like placeholders610 * @param array|mixed $argsThe 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()}.611 * @param mixed$args,... further variables to substitute into the query's placeholders if being called like {@link http://php.net/sprintf sprintf()}.612 * @return null|string Sanitized query string617 * @param string $query Query statement with sprintf()-like placeholders 618 * @param 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()}. 619 * @param mixed $args,... further variables to substitute into the query's placeholders if being called like {@link http://php.net/sprintf sprintf()}. 620 * @return string|false Sanitized query string, false on error 613 621 */ 614 function prepare( $query = null) { // ( $query, *$args )622 function prepare( $query = null ) { // ( $query, *$args ) 615 623 if ( is_null( $query ) ) 616 return; 624 return false; 625 617 626 $args = func_get_args(); 618 array_shift($args); 619 // If args were passed as an array (as in vsprintf), move them up 620 if ( isset($args[0]) && is_array($args[0]) ) 621 $args = $args[0]; 622 $query = str_replace("'%s'", '%s', $query); // in case someone mistakenly already singlequoted it 623 $query = str_replace('"%s"', '%s', $query); // doublequote unquoting 624 $query = str_replace('%s', "'%s'", $query); // quote the strings 625 array_walk($args, array(&$this, 'escape_by_ref')); 626 return @vsprintf($query, $args); 627 array_shift( $args ); 628 629 if ( isset( $args[0] ) && is_array( $args[0] ) ) 630 $args = $args[0]; # re-assign args passed as array like in vsprintf 631 632 // @todo (hakre) $query input can be better sanitzed, tested code available #11608 633 634 $quoted = str_replace('%s', "'%s'", $query); # quote the strings 635 $quoted = str_replace( array( "''%s''", "\"'%'\"" ), "'%s'", $quoted ); # in case someone mistakenly already single/double quoted it 636 array_walk( $args, array( &$this, 'escape_by_ref' ) ); 637 return @vsprintf( $quoted, $args ); 627 638 } 628 639 629 640 /** … … 635 646 * @param string $str The error to display 636 647 * @return bool False if the showing of errors is disabled. 637 648 */ 638 function print_error( $str = '') {649 function print_error( $str = '' ) { 639 650 global $EZSQL_ERROR; 640 651 641 652 if (!$str) $str = mysql_error($this->dbh); … … 649 660 else 650 661 $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); 651 662 652 $log_error = true; 653 if ( ! function_exists('error_log') ) 654 $log_error = false; 663 trigger_error( $error_str, E_USER_WARNING ); 655 664 656 $log_file = @ini_get('error_log'); 657 if ( !empty($log_file) && ('syslog' != $log_file) && !@is_writable($log_file) ) 658 $log_error = false; 665 if ( function_exists( 'error_log' ) 666 && !( $log_file = ini_get( 'error_log' ) ) 667 && ( 'syslog' != $log_file ) 668 && @is_writable( $log_file ) ) 669 @error_log( $error_str ); 659 670 660 if ( $log_error )661 @error_log($error_str, 0);662 663 671 // Is error output turned on or not.. 664 672 if ( !$this->show_errors ) 665 673 return false; 666 674 667 // If there is an error then take note of it 668 if( is_multisite() ) { 669 $msg = "WordPress database error: [$str]\n{$this->last_query}\n"; 670 if( defined( 'ERRORLOGFILE' ) ) 671 error_log( $msg, 3, CONSTANT( 'ERRORLOGFILE' ) ); 672 if( defined( 'DIEONDBERROR' ) ) 673 die( $msg ); 674 } else { 675 $str = htmlspecialchars($str, ENT_QUOTES); 676 $query = htmlspecialchars($this->last_query, ENT_QUOTES); 677 678 print "<div id='error'> 679 <p class='wpdberror'><strong>WordPress database error:</strong> [$str]<br /> 680 <code>$query</code></p> 681 </div>"; 682 } 675 $str = htmlspecialchars( $str, ENT_QUOTES ); 676 $query = $this->last_query ? sprintf( '<br><code>%s</code>', htmlspecialchars( $this->last_query, ENT_QUOTES ) ) : ''; 677 printf('<div id="error"><p class="wpdberror"><strong>WordPress database error:</strong> [%s]%s</p>', $str, $query); 683 678 } 684 679 685 680 /** … … 690 685 * this function can be used to enable and disable showing of database 691 686 * errors. 692 687 * 693 * @since 0.71 694 * 695 * @param bool $show Whether to show or hide errors 688 * @since 0.71 689 * @see hide_errors() 690 * 691 * @param bool $show Whether to show or hide errors 696 692 * @return bool Old value for showing errors. 697 693 */ 698 694 function show_errors( $show = true ) { … … 703 699 704 700 /** 705 701 * Disables showing of database errors. 702 * 703 * By default database errors are not shown. 706 704 * 707 * @since 0.71 705 * @since 0.71 706 * @see show_errors() 708 707 * 709 * @return bool Whether showing of errors was active or not708 * @return bool Old show errors value 710 709 */ 711 710 function hide_errors() { 712 711 $show = $this->show_errors; … … 717 716 /** 718 717 * Whether to suppress database errors. 719 718 * 720 * @param unknown_type $suppress 721 * @return unknown 719 * By default database errors are suppressed, with a simple 720 * call to this function they can be enabled. 721 * 722 * @since 2.5 723 * @see hide_errors() 724 * @param bool $suppress (optional) new value, defaults to true 725 * @return bool old suppress errors value 722 726 */ 723 727 function suppress_errors( $suppress = true ) { 724 728 $errors = $this->suppress_errors; 725 $this->suppress_errors = $suppress;729 $this->suppress_errors = (bool) $suppress; 726 730 return $errors; 727 731 } 728 732 … … 730 734 * Kill cached query results. 731 735 * 732 736 * @since 0.71 737 * 738 * @return void 733 739 */ 734 740 function flush() { 735 $this->last_result = array(); 736 $this->col_info = null; 737 $this->last_query = null; 741 $this->last_result = array(); 742 $this->num_rows = 0; 743 $this->rows_affected = 0; 744 $this->col_info = null; 745 $this->last_query = null; 738 746 } 739 747 740 function db_connect( $query = "SELECT" ) {741 global $db_list, $global_db_list;742 if( is_array( $db_list ) == false )743 return true;744 745 if( $this->blogs != '' && preg_match("/(" . $this->blogs . "|" . $this->users . "|" . $this->usermeta . "|" . $this->site . "|" . $this->sitemeta . "|" . $this->sitecategories . ")/i",$query) ) {746 $action = 'global';747 $details = $global_db_list[ mt_rand( 0, count( $global_db_list ) -1 ) ];748 $this->db_global = $details;749 } elseif ( preg_match("/^\\s*(alter table|create|insert|delete|update|replace) /i",$query) ) {750 $action = 'write';751 $details = $db_list[ 'write' ][ mt_rand( 0, count( $db_list[ 'write' ] ) -1 ) ];752 $this->db_write = $details;753 } else {754 $action = '';755 $details = $db_list[ 'read' ][ mt_rand( 0, count( $db_list[ 'read' ] ) -1 ) ];756 $this->db_read = $details;757 }758 759 $dbhname = "dbh" . $action;760 $this->$dbhname = @mysql_connect( $details[ 'db_host' ], $details[ 'db_user' ], $details[ 'db_password' ] );761 if (!$this->$dbhname ) {762 $this->bail("763 <h1>Error establishing a database connection</h1>764 <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>$dbhost</code>. This could mean your host's database server is down.</p>765 <ul>766 <li>Are you sure you have the correct username and password?</li>767 <li>Are you sure that you have typed the correct hostname?</li>768 <li>Are you sure that the database server is running?</li>769 </ul>770 <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>771 ");772 }773 $this->select( $details[ 'db_name' ], $this->$dbhname );774 }775 776 748 /** 777 749 * Perform a MySQL database query, using current database connection. 778 750 * … … 780 752 * 781 753 * @since 0.71 782 754 * 783 * @param string $query755 * @param string $query database query 784 756 * @return int|false Number of rows affected/selected or false on error 785 757 */ 786 function query( $query) {758 function query( $query ) { 787 759 if ( ! $this->ready ) 788 760 return false; 789 761 790 // filter the query, if filters are available791 // NOTE: some queries are made before the plugins have been loaded, and thus cannot be filtered with this method792 762 if ( function_exists('apply_filters') ) 793 763 $query = apply_filters('query', $query); 794 764 795 // init ialise return765 // init return values and objects state 796 766 $return_val = 0; 797 767 $this->flush(); 798 768 … … 802 772 // Keep track of the last query for debug.. 803 773 $this->last_query = $query; 804 774 805 // Perform the query via std mysql_query function..806 775 if ( defined('SAVEQUERIES') && SAVEQUERIES ) 807 776 $this->timer_start(); 808 809 // use $this->dbh for read ops, and $this->dbhwrite for write ops810 // use $this->dbhglobal for gloal table ops811 unset( $dbh );812 if( defined( "WP_USE_MULTIPLE_DB" ) && CONSTANT( "WP_USE_MULTIPLE_DB" ) == true ) {813 if( $this->blogs != '' && preg_match("/(" . $this->blogs . "|" . $this->users . "|" . $this->usermeta . "|" . $this->site . "|" . $this->sitemeta . "|" . $this->sitecategories . ")/i",$query) ) {814 if( false == isset( $this->dbhglobal ) ) {815 $this->db_connect( $query );816 }817 $dbh =& $this->dbhglobal;818 $this->last_db_used = "global";819 } elseif ( preg_match("/^\\s*(alter table|create|insert|delete|update|replace) /i",$query) ) {820 if( false == isset( $this->dbhwrite ) ) {821 $this->db_connect( $query );822 }823 $dbh =& $this->dbhwrite;824 $this->last_db_used = "write";825 } else {826 $dbh =& $this->dbh;827 $this->last_db_used = "read";828 }829 } else {830 $dbh =& $this->dbh;831 $this->last_db_used = "other/read";832 }833 777 834 $this->result = @mysql_query($query, $dbh); 835 ++$this->num_queries; 778 // Perform the query via std mysql_query function.. 779 $this->result = @mysql_query($query, $this->dbh); 780 $this->num_queries++; 836 781 837 782 if ( defined('SAVEQUERIES') && SAVEQUERIES ) 838 783 $this->queries[] = array( $query, $this->timer_stop(), $this->get_caller() ); 839 784 840 785 // If there is an error then take note of it.. 841 if ( $this->last_error = mysql_error( $dbh) ) {786 if ( $this->last_error = mysql_error( $this->dbh ) ) { 842 787 $this->print_error(); 843 788 return false; 844 789 } 845 790 846 if ( preg_match("/^\\s*(insert|delete|update|replace|alter) /i",$query) ) { 847 $this->rows_affected = mysql_affected_rows($dbh); 848 // Take note of the insert_id 849 if ( preg_match("/^\\s*(insert|replace) /i",$query) ) { 850 $this->insert_id = mysql_insert_id($dbh); 851 } 852 // Return number of rows affected 853 $return_val = $this->rows_affected; 854 } else { 855 $i = 0; 856 while ($i < @mysql_num_fields($this->result)) { 857 $this->col_info[$i] = @mysql_fetch_field($this->result); 858 $i++; 859 } 860 $num_rows = 0; 861 while ( $row = @mysql_fetch_object($this->result) ) { 862 $this->last_result[$num_rows] = $row; 863 $num_rows++; 864 } 791 if ( preg_match( '(^\s*([a-z]{2,})\s+)i', $query, $matches ) ) 792 $type = strtoupper($matches[1]); 793 else 794 $type = ''; 865 795 866 @mysql_free_result($this->result); 796 switch( $type ) { 797 case 'INSERT': 798 case 'REPLACE': 799 $this->insert_id = mysql_insert_id( $this->dbh ); 800 case 'DELETE': 801 case 'UPDATE': 802 case 'ALTER': 803 $this->rows_affected = mysql_affected_rows( $this->dbh ); 804 $return_val = $this->rows_affected; 805 break; 867 806 868 // Log number of rows the query returned 869 $this->num_rows = $num_rows; 807 default: 808 $i = 0; 809 while ( $i < @mysql_num_fields( $this->result ) ) 810 $this->col_info[$i++] = @mysql_fetch_field( $this->result ); 870 811 871 // Return number of rows selected 872 $return_val = $this->num_rows; 812 $num_rows = 0; 813 while ( $row = @mysql_fetch_assoc( $this->result ) ) 814 $this->last_result[$num_rows++] = $row; 815 816 @mysql_free_result( $this->result ); 817 $this->num_rows = $num_rows; 818 $return_val = $num_rows; 873 819 } 874 820 875 821 return $return_val; 876 822 } 877 823 … … 879 825 * Insert a row into a table. 880 826 * 881 827 * <code> 828 * wpdb::insert( 'table', array( 'column' => 'foo', 'field' => 1337 ) ) 882 829 * wpdb::insert( 'table', array( 'column' => 'foo', 'field' => 1337 ), array( '%s', '%d' ) ) 883 830 * </code> 884 831 * 885 832 * @since 2.5.0 886 * @see wpdb::prepare()833 * @see prepare() 887 834 * 888 * @param string $tabletable name889 * @param array $dataData to insert (in column => value pairs). Both $data columns and $data values should be "raw" (neither should be SQL escaped).890 * @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.891 * @return int|false The number of rows inserted, or false on error.835 * @param string $table table name 836 * @param array $data Data to insert (in column => value pairs). Both $data columns and $data values should be "raw" (neither should be SQL escaped). 837 * @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. 838 * @return int|false The number of rows inserted, or false on error. 892 839 */ 893 function insert($table, $data, $format = null) { 894 $formats = $format = (array) $format; 895 $fields = array_keys($data); 896 $formatted_fields = array(); 897 foreach ( $fields as $field ) { 898 if ( !empty($format) ) 899 $form = ( $form = array_shift($formats) ) ? $form : $format[0]; 900 elseif ( isset($this->field_types[$field]) ) 901 $form = $this->field_types[$field]; 902 else 903 $form = '%s'; 904 $formatted_fields[] = $form; 905 } 906 $sql = "INSERT INTO `$table` (`" . implode( '`,`', $fields ) . "`) VALUES ('" . implode( "','", $formatted_fields ) . "')"; 907 return $this->query( $this->prepare( $sql, $data) ); 840 function insert( $table, $data, $format = null ) { 841 if ( !is_array( $data ) ) 842 return false; 843 844 $sql = sprintf( 845 'INSERT INTO `%s` SET %s' 846 , $table 847 , $this->_field_formats( array_keys( $data ), $format, ', ' ) 848 ); 849 $values = array_values( $data ); 850 return $this->query( $this->prepare( $sql, $values ) ); 908 851 } 909 852 910 911 853 /** 912 854 * Update a row in the table 913 855 * 914 856 * <code> 857 * wpdb::update( 'table', array( 'column' => 'foo', 'field' => 1337 ), array( 'ID' => 1 ) ) 915 858 * wpdb::update( 'table', array( 'column' => 'foo', 'field' => 1337 ), array( 'ID' => 1 ), array( '%s', '%d' ), array( '%d' ) ) 916 859 * </code> 917 860 * 918 861 * @since 2.5.0 919 * @see wpdb::prepare()862 * @see prepare() 920 863 * 921 * @param string $tabletable name922 * @param array $dataData to update (in column => value pairs). Both $data columns and $data values should be "raw" (neither should be SQL escaped).923 * @param array $whereA 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".924 * @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.864 * @param string $table table name 865 * @param array $data Data to update (in column => value pairs). Both $data columns and $data values should be "raw" (neither should be SQL escaped). 866 * @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". 867 * @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. 925 868 * @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. 926 * @return int|false The number of rows updated, or false on error.869 * @return int|false The number of rows updated, or false on error. 927 870 */ 928 function update( $table, $data, $where, $format = null, $where_format = null) {929 if ( !is_array( $ where ))871 function update( $table, $data, $where, $format = null, $where_format = null ) { 872 if ( !is_array( $data ) || !is_array( $where )) 930 873 return false; 931 874 875 $sql = sprintf( 876 'UPDATE `%s` SET %s WHERE %s' 877 , $table 878 , $this->_field_formats( array_keys( $data ), $format, ', ' ) 879 , $this->_field_formats( array_keys( $where ), $where_format, ' AND ' ) 880 ); 881 $values = array_merge( array_values( $data ), array_values( $where ) ); 882 return $this->query( $this->prepare( $sql, $values ) ); 883 } 884 885 /** 886 * field types 887 * 888 * helper function to get the format string for 889 * multiple fields. 890 * 891 * @param array $fields fields name => value based 892 * @param array $format additional field-format specifier(s), compare to wpdb::update() $format parameter 893 * @param string $concat concatination string 894 * @param string $default (optional) default format, is %s, see wpdb::prepare() for format tokens 895 * @return array string format token string for those fields to be used 896 * @access private 897 * @since 3.0 898 */ 899 function _field_formats( $fields, $format, $concat, $default = '%s' ) { 900 $result = array(); 932 901 $formats = $format = (array) $format; 933 $bits = $wheres = array();934 foreach ( (array) array_keys($data) as $field ) {935 if ( !empty($format) )936 $form = ( $form = array_shift($formats) ) ? $form : $format[0];937 elseif ( isset($this->field_types[$field]) )938 $form = $this->field_types[$field];939 else940 $form = '%s';941 $bits[] = "`$field` = {$form}";942 }943 902 944 $where_formats = $where_format = (array) $where_format; 945 foreach ( (array) array_keys($where) as $field ) { 946 if ( !empty($where_format) ) 947 $form = ( $form = array_shift($where_formats) ) ? $form : $where_format[0]; 948 elseif ( isset($this->field_types[$field]) ) 949 $form = $this->field_types[$field]; 950 else 951 $form = '%s'; 952 $wheres[] = "`$field` = {$form}"; 903 foreach ( $fields as $field ) { 904 $token = $default; 905 if ( count( $format ) ) 906 $token = ( $token = array_shift($formats) ) ? $token : $format[0]; 907 elseif ( isset( $this->field_types[$field] ) ) 908 $token = $this->field_types[$field]; 909 910 $result[] = sprintf( '`%s` = %s', $field, $token ); 953 911 } 954 912 955 $sql = "UPDATE `$table` SET " . implode( ', ', $bits ) . ' WHERE ' . implode( ' AND ', $wheres ); 956 return $this->query( $this->prepare( $sql, array_merge(array_values($data), array_values($where))) ); 913 return implode( $concat, $result ); 957 914 } 958 915 959 916 /** … … 965 922 * 966 923 * @since 0.71 967 924 * 968 * @param string |null $query SQL query. If null, use the result from the previous query.969 * @param int $x(optional) Column of value to return. Indexed from 0.970 * @param int $y(optional) Row of value to return. Indexed from 0.971 * @return string Database query result925 * @param string $query (optional) SQL query. Defaults to NULL the re-use of existing data. 926 * @param int $col (optional) Column of value to return. Indexed from 0. 927 * @param int $row (optional) Row of value to return. Indexed from 0. 928 * @return string|null string value on success, NULL if a value on 972 929 */ 973 function get_var( $query=null, $x = 0, $y = 0) {974 $this->func_call = "\$db->get_var(\"$query\",$ x,$y)";930 function get_var( $query = null, $col = 0, $row = 0 ) { 931 $this->func_call = "\$db->get_var(\"$query\",$col,$row)"; 975 932 if ( $query ) 976 $this->query( $query);933 $this->query( $query ); 977 934 978 // Extract var out of cached results based x,y vals 979 if ( !empty( $this->last_result[$y] ) ) { 980 $values = array_values(get_object_vars($this->last_result[$y])); 935 if ( isset( $this->last_result[$row] ) 936 && ( $values = array_values( $this->last_result[$row] ) ) 937 && isset( $values[$col] ) ) { 938 return $values[$col]; 981 939 } 982 940 983 // If there is a value return it else return null 984 return (isset($values[$x]) && $values[$x]!=='') ? $values[$x] : null; 941 return null; 985 942 } 986 943 987 944 /** … … 993 950 * 994 951 * @param string|null $query SQL query. 995 952 * @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. 996 * @param int $y(optional) Row to return. Indexed from 0.997 * @return mixed Database query result in format specifed by $output 953 * @param int $row (optional) Row to return. Indexed from 0. 954 * @return mixed Database query result in format specifed by $output or NULL 998 955 */ 999 function get_row($query = null, $output = OBJECT, $y = 0) { 1000 $this->func_call = "\$db->get_row(\"$query\",$output,$y)"; 1001 if ( $query ) 1002 $this->query($query); 1003 else 1004 return null; 956 function &get_row( $query = null, $output = OBJECT, $row = 0) { 957 $this->func_call = "\$db->get_row(\"$query\",$output,$row)"; 958 $retval = null; 1005 959 1006 if ( !isset($this->last_result[$y]) )1007 return null;960 if ( null !== $query && false === $this->query( $query ) ) 961 return $retval; 1008 962 1009 if ( $output == OBJECT ) { 1010 return $this->last_result[$y] ? $this->last_result[$y] : null; 1011 } elseif ( $output == ARRAY_A ) { 1012 return $this->last_result[$y] ? get_object_vars($this->last_result[$y]) : null; 1013 } elseif ( $output == ARRAY_N ) { 1014 return $this->last_result[$y] ? array_values(get_object_vars($this->last_result[$y])) : null; 1015 } else { 1016 $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*/); 963 $row = absint( $row ); 964 965 if ( $row >= $this->num_rows ) 966 return $retval; 967 968 $retval = $this->last_result[$row]; # stored as ARRAY_A, {@see query()} 969 970 switch ( $output ) { 971 case OBJECT: 972 $retval = (object) $retval; 973 case ARRAY_A: 974 break; 975 case ARRAY_N: 976 $retval = array_values( $retval ); 977 break; 978 default: 979 $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*/); 1017 980 } 981 982 return $retval; 1018 983 } 984 985 /** 986 * get last database error 987 * 988 * @since 3.0 989 * 990 * @return string last mysql database error 991 */ 992 function get_last_error() { 993 return $this->last_error; 994 } 995 996 /** 997 * get number of rows 998 * 999 * Retrieve the number of rows of the last querty operation 1000 * 1001 * @since 3.0 1002 * @see query() 1003 * 1004 * @return int number of rows 1005 */ 1006 function get_num_rows() { 1007 return $this->num_rows; 1008 } 1019 1009 1020 1010 /** 1021 1011 * Retrieve one column from the database. … … 1026 1016 * 1027 1017 * @since 0.71 1028 1018 * 1029 * @param string|null $query SQL query. If null, usethe result from the previous query.1030 * @param int $x Column to return. Indexed from 0.1031 * @return array Database query result. Array indexed from 0 by SQL result row number.1019 * @param string $query (optional) SQL query. If omitted it uses the result from the previous query. 1020 * @param int $col (optional) Column to return. Indexed from 0, defaults to first column. 1021 * @return array Array Zero-based-row-number-keyed containing the column's value(s) 1032 1022 */ 1033 function get_col( $query = null , $x = 0) {1023 function get_col( $query = null , $col = 0 ) { 1034 1024 if ( $query ) 1035 $this->query( $query);1025 $this->query( $query ); 1036 1026 1037 1027 $new_array = array(); 1038 // Extract the column values 1039 for ( $i=0; $i < count($this->last_result); $i++ ) { 1040 $new_array[$i] = $this->get_var(null, $x, $i); 1041 } 1028 1029 // get that column values of all rows 1030 $count = $this->num_rows; 1031 for ( $i = 0; $i < $count; $i++ ) 1032 if ( isset( $this->last_result[$i] ) 1033 && $values = array_values( $this->last_result[$i] ) 1034 && isset( $values[$col] ) ) 1035 $new_array[$i] = $values[$col]; 1036 1042 1037 return $new_array; 1043 1038 } 1044 1039 … … 1046 1041 * Retrieve an entire SQL result set from the database (i.e., many rows) 1047 1042 * 1048 1043 * Executes a SQL query and returns the entire SQL result. 1044 * 1045 * Return Types: 1046 * 1047 * ARRAY_A : array of column name-keyed row arrays 1048 * ARRAY_N : array of integer-keyed row arrays 1049 * OBJECT : array of row objects 1050 * OBJECT_K : column-1-keyed array of row objects (duplicates are discarded) 1049 1051 * 1050 1052 * @since 0.71 1051 1053 * 1052 1054 * @param string $query SQL query. 1053 1055 * @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. 1054 * @return mixed Database query results1056 * @return array|object|null Database query results or NULL on error 1055 1057 */ 1056 function get_results($query = null, $output = OBJECT) {1058 function &get_results( $query = null, $output = OBJECT ) { 1057 1059 $this->func_call = "\$db->get_results(\"$query\", $output)"; 1058 1060 $retval = null; 1061 1059 1062 if ( $query ) 1060 $this->query( $query);1063 $this->query( $query ); 1061 1064 else 1062 return null;1065 return $retval; 1063 1066 1064 if ( $output == OBJECT ) { 1065 // Return an integer-keyed array of row objects 1066 return $this->last_result; 1067 } elseif ( $output == OBJECT_K ) { 1068 // Return an array of row objects with keys from column 1 1069 // (Duplicates are discarded) 1070 foreach ( $this->last_result as $row ) { 1071 $key = array_shift( get_object_vars( $row ) ); 1072 if ( !isset( $new_array[ $key ] ) ) 1073 $new_array[ $key ] = $row; 1074 } 1075 return $new_array; 1076 } elseif ( $output == ARRAY_A || $output == ARRAY_N ) { 1077 // Return an integer-keyed array of... 1078 if ( $this->last_result ) { 1079 $i = 0; 1080 foreach( (array) $this->last_result as $row ) { 1081 if ( $output == ARRAY_N ) { 1082 // ...integer-keyed row arrays 1083 $new_array[$i] = array_values( get_object_vars( $row ) ); 1084 } else { 1085 // ...column name-keyed row arrays 1086 $new_array[$i] = get_object_vars( $row ); 1087 } 1088 ++$i; 1089 } 1090 return $new_array; 1091 } 1067 $retval = $this->last_result; # Array of database rows, each of type ARRAY_A {@see query()} 1068 1069 switch ( $output ) { 1070 case OBJECT: # array of row objects 1071 foreach ( $retval as $key => $value ) 1072 $retval[$key] = (object) $value; 1073 break; 1074 1075 case OBJECT_K: # column-1-keyed array of row objects (duplicates are discarded) 1076 $retval = array(); 1077 foreach ($this->last_result as $value ) 1078 if ( !isset( $retval[$key = array_shift( array_values( $value ) )] ) ) 1079 $retval[$key] = (object) $value; 1080 break; 1081 1082 case ARRAY_N: # array of integer-keyed row arrays 1083 foreach ( $retval as $key=> $value ) 1084 $retval[$key] = array_values( $value ); 1085 1086 case ARRAY_A: # array of column name-keyed row arrays 1087 break; 1088 1089 default: # undefined return type 1090 $retval = null; 1092 1091 } 1092 1093 return $retval; 1093 1094 } 1094 1095 1095 1096 /** … … 1172 1173 * 1173 1174 * @since 2.5.0 1174 1175 * @uses $wp_version 1176 * @uses $required_mysql_version 1175 1177 * 1176 1178 * @return WP_Error 1177 1179 */ … … 1197 1199 } 1198 1200 1199 1201 /** 1200 * Generic function to determine if a database supports a particular feature 1201 * @param string $db_cap the feature 1202 * @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. 1202 * has capability 1203 * 1204 * Determine if a database supports a particular feature 1205 * 1206 * Features are (since version): 1207 * 1208 * 'collation' 2.5.0 1209 * 'group_concat' 2.7 1210 * 'subqueries' 2.7 1211 * 1212 * ADDITIONAL PARAMETER NOTICE 1213 * 1214 * there once was a proposed second parameter which has never been 1215 * implemented. It was describben as "Which database to test" ($dbh_or_table) 1216 * 1217 * It would have had three different types: 1218 * 1219 * false : currently selected database 1220 * string : database containing this table 1221 * resource : database by mysql resource 1222 * 1223 * regarding that third parameter please see {@see db_version()} as well 1224 * 1225 * @since 2.7 1226 * @see db_version() 1227 * 1228 * @param string $db_cap the feature 1203 1229 * @return bool 1204 1230 */ 1205 1231 function has_cap( $db_cap ) { 1206 $ version = $this->db_version();1232 $db_cap = strtolower( $db_cap ); 1207 1233 1208 switch ( strtolower( $db_cap ) ) :1209 case 'collation' : //@since 2.5.01210 case 'group_concat' : //@since 2.71211 case 'subqueries' : //@since 2.71212 return version_compare($version, '4.1', '>=');1213 break;1214 endswitch;1215 1216 return false;1234 switch ( $db_cap ) { 1235 case 'collation' : # @since 2.5.0 1236 case 'group_concat' : # @since 2.7 1237 case 'subqueries' : # @since 2.7 1238 $version = $this->db_version(); 1239 return version_compare( $version, '4.1', '>=' ); 1240 default: 1241 return false; 1242 } 1217 1243 } 1218 1244 1219 1245 /** … … 1227 1253 * @return string The name of the calling function 1228 1254 */ 1229 1255 function get_caller() { 1230 // requires PHP 4.3+ 1231 if ( !is_callable('debug_backtrace') ) 1232 return ''; 1233 1234 $bt = debug_backtrace(); 1256 $trace = array_reverse( debug_backtrace() ); 1235 1257 $caller = array(); 1236 1258 1237 $bt = array_reverse( $bt );1238 foreach ( (array) $bt as $call ) {1239 if ( @$call['class'] == __CLASS__ )1240 continue; 1259 foreach ( $trace as $call ) { 1260 if ( isset( $call['class'] ) && __CLASS__ == $call['class'] ) 1261 continue; # filter out function calls if this object's class 1262 1241 1263 $function = $call['function']; 1264 1242 1265 if ( isset( $call['class'] ) ) 1243 1266 $function = $call['class'] . "->$function"; 1267 1244 1268 $caller[] = $function; 1245 1269 } 1246 $caller = join( ', ', $caller );1247 1270 1248 return $caller;1271 return join( ', ', $caller ); 1249 1272 } 1250 1273 1251 1274 /** 1252 * The database version number 1253 * @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. 1275 * get database version number 1276 * 1277 * ADDITIONAL PARAMETER NOTICE 1278 * 1279 * there once was a proposed second parameter which has never been 1280 * implemented. It was describben as "Which database to test" ($dbh_or_table) 1281 * 1282 * It would have had three different types: 1283 * 1284 * false : currently selected database 1285 * string : database containing this table 1286 * resource : database by mysql resource 1287 * 1288 * regarding that third parameter please see {@see db_version()} as well 1289 * 1290 * @since 2.7 1291 * @see has_cap() 1292 * 1254 1293 * @return false|string false on failure, version number on success 1255 1294 */ 1256 1295 function db_version() { 1257 1296 return preg_replace('/[^0-9.].*/', '', mysql_get_server_info( $this->dbh )); 1258 1297 } 1298 1299 /** 1300 * get tables 1301 * 1302 * get list of a set of tables 1303 * 1304 * Sets: 1305 * 1306 * all : all names 1307 * current : active tables 1308 * old : deprecated tables 1309 * 1310 * @since 3.0 1311 * 1312 * @param string $set (optional) 'all', 'current' or 'old'. defaults to 'current' 1313 * @return array list of old table names (w/o prefix), false on error 1314 */ 1315 function get_tables( $set = 'current' ) { 1316 $tables = false; 1317 1318 switch ( $set ) { 1319 case 'all': 1320 $tables = $this->tables; 1321 break; 1322 case 'current': 1323 $tables = array_diff( $this->tables, $this->old_tables ); 1324 break; 1325 case 'old': 1326 $tables = $this->old_tables; 1327 break; 1328 } 1329 1330 return $tables; 1331 } 1259 1332 } 1260 1333 1261 1334 if ( ! isset($wpdb) ) { … … 1266 1339 */ 1267 1340 $wpdb = new wpdb(DB_USER, DB_PASSWORD, DB_NAME, DB_HOST); 1268 1341 } 1269 ?> 1342 ?> 1343 No newline at end of file