WordPress.org

Make WordPress Core

Changeset 16051


Ignore:
Timestamp:
10/28/10 16:27:18 (3 years ago)
Author:
scribu
Message:

Move WP_Object_Query to it's own file. See #15032

Location:
trunk
Files:
2 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/wp-includes/class.wp-object-query.php

    r16048 r16051  
    1010 * @package WordPress 
    1111 */ 
    12  
    13 /** 
    14  * WordPress environment setup class. 
    15  * 
    16  * @package WordPress 
    17  * @since 2.0.0 
    18  */ 
    19 class WP { 
    20     /** 
    21      * Public query variables. 
    22      * 
    23      * Long list of public query variables. 
    24      * 
    25      * @since 2.0.0 
    26      * @access public 
    27      * @var array 
    28      */ 
    29     var $public_query_vars = array('m', 'p', 'posts', 'w', 'cat', 'withcomments', 'withoutcomments', 's', 'search', 'exact', 'sentence', 'debug', 'calendar', 'page', 'paged', 'more', 'tb', 'pb', 'author', 'order', 'orderby', 'year', 'monthnum', 'day', 'hour', 'minute', 'second', 'name', 'category_name', 'tag', 'feed', 'author_name', 'static', 'pagename', 'page_id', 'error', 'comments_popup', 'attachment', 'attachment_id', 'subpost', 'subpost_id', 'preview', 'robots', 'taxonomy', 'term', 'cpage', 'post_type'); 
    30  
    31     /** 
    32      * Private query variables. 
    33      * 
    34      * Long list of private query variables. 
    35      * 
    36      * @since 2.0.0 
    37      * @var array 
    38      */ 
    39     var $private_query_vars = array('offset', 'posts_per_page', 'posts_per_archive_page', 'showposts', 'nopaging', 'post_type', 'post_status', 'category__in', 'category__not_in', 'category__and', 'tag__in', 'tag__not_in', 'tag__and', 'tag_slug__in', 'tag_slug__and', 'tag_id', 'post_mime_type', 'perm', 'comments_per_page', 'post__in', 'post__not_in'); 
    40  
    41     /** 
    42      * Extra query variables set by the user. 
    43      * 
    44      * @since 2.1.0 
    45      * @var array 
    46      */ 
    47     var $extra_query_vars = array(); 
    48  
    49     /** 
    50      * Query variables for setting up the WordPress Query Loop. 
    51      * 
    52      * @since 2.0.0 
    53      * @var array 
    54      */ 
    55     var $query_vars; 
    56  
    57     /** 
    58      * String parsed to set the query variables. 
    59      * 
    60      * @since 2.0.0 
    61      * @var string 
    62      */ 
    63     var $query_string; 
    64  
    65     /** 
    66      * Permalink or requested URI. 
    67      * 
    68      * @since 2.0.0 
    69      * @var string 
    70      */ 
    71     var $request; 
    72  
    73     /** 
    74      * Rewrite rule the request matched. 
    75      * 
    76      * @since 2.0.0 
    77      * @var string 
    78      */ 
    79     var $matched_rule; 
    80  
    81     /** 
    82      * Rewrite query the request matched. 
    83      * 
    84      * @since 2.0.0 
    85      * @var string 
    86      */ 
    87     var $matched_query; 
    88  
    89     /** 
    90      * Whether already did the permalink. 
    91      * 
    92      * @since 2.0.0 
    93      * @var bool 
    94      */ 
    95     var $did_permalink = false; 
    96  
    97     /** 
    98      * Add name to list of public query variables. 
    99      * 
    100      * @since 2.1.0 
    101      * 
    102      * @param string $qv Query variable name. 
    103      */ 
    104     function add_query_var($qv) { 
    105         if ( !in_array($qv, $this->public_query_vars) ) 
    106             $this->public_query_vars[] = $qv; 
    107     } 
    108  
    109     /** 
    110      * Set the value of a query variable. 
    111      * 
    112      * @since 2.3.0 
    113      * 
    114      * @param string $key Query variable name. 
    115      * @param mixed $value Query variable value. 
    116      */ 
    117     function set_query_var($key, $value) { 
    118         $this->query_vars[$key] = $value; 
    119     } 
    120  
    121     /** 
    122      * Parse request to find correct WordPress query. 
    123      * 
    124      * Sets up the query variables based on the request. There are also many 
    125      * filters and actions that can be used to further manipulate the result. 
    126      * 
    127      * @since 2.0.0 
    128      * 
    129      * @param array|string $extra_query_vars Set the extra query variables. 
    130      */ 
    131     function parse_request($extra_query_vars = '') { 
    132         global $wp_rewrite; 
    133  
    134         $this->query_vars = array(); 
    135         $post_type_query_vars = array(); 
    136  
    137         if ( is_array($extra_query_vars) ) 
    138             $this->extra_query_vars = & $extra_query_vars; 
    139         else if (! empty($extra_query_vars)) 
    140             parse_str($extra_query_vars, $this->extra_query_vars); 
    141  
    142         // Process PATH_INFO, REQUEST_URI, and 404 for permalinks. 
    143  
    144         // Fetch the rewrite rules. 
    145         $rewrite = $wp_rewrite->wp_rewrite_rules(); 
    146  
    147         if ( ! empty($rewrite) ) { 
    148             // If we match a rewrite rule, this will be cleared. 
    149             $error = '404'; 
    150             $this->did_permalink = true; 
    151  
    152             if ( isset($_SERVER['PATH_INFO']) ) 
    153                 $pathinfo = $_SERVER['PATH_INFO']; 
    154             else 
    155                 $pathinfo = ''; 
    156             $pathinfo_array = explode('?', $pathinfo); 
    157             $pathinfo = str_replace("%", "%25", $pathinfo_array[0]); 
    158             $req_uri = $_SERVER['REQUEST_URI']; 
    159             $req_uri_array = explode('?', $req_uri); 
    160             $req_uri = $req_uri_array[0]; 
    161             $self = $_SERVER['PHP_SELF']; 
    162             $home_path = parse_url(home_url()); 
    163             if ( isset($home_path['path']) ) 
    164                 $home_path = $home_path['path']; 
    165             else 
    166                 $home_path = ''; 
    167             $home_path = trim($home_path, '/'); 
    168  
    169             // Trim path info from the end and the leading home path from the 
    170             // front.  For path info requests, this leaves us with the requesting 
    171             // filename, if any.  For 404 requests, this leaves us with the 
    172             // requested permalink. 
    173             $req_uri = str_replace($pathinfo, '', $req_uri); 
    174             $req_uri = trim($req_uri, '/'); 
    175             $req_uri = preg_replace("|^$home_path|", '', $req_uri); 
    176             $req_uri = trim($req_uri, '/'); 
    177             $pathinfo = trim($pathinfo, '/'); 
    178             $pathinfo = preg_replace("|^$home_path|", '', $pathinfo); 
    179             $pathinfo = trim($pathinfo, '/'); 
    180             $self = trim($self, '/'); 
    181             $self = preg_replace("|^$home_path|", '', $self); 
    182             $self = trim($self, '/'); 
    183  
    184             // The requested permalink is in $pathinfo for path info requests and 
    185             //  $req_uri for other requests. 
    186             if ( ! empty($pathinfo) && !preg_match('|^.*' . $wp_rewrite->index . '$|', $pathinfo) ) { 
    187                 $request = $pathinfo; 
    188             } else { 
    189                 // If the request uri is the index, blank it out so that we don't try to match it against a rule. 
    190                 if ( $req_uri == $wp_rewrite->index ) 
    191                     $req_uri = ''; 
    192                 $request = $req_uri; 
    193             } 
    194  
    195             $this->request = $request; 
    196  
    197             // Look for matches. 
    198             $request_match = $request; 
    199             foreach ( (array) $rewrite as $match => $query) { 
    200                 // Don't try to match against AtomPub calls 
    201                 if ( $req_uri == 'wp-app.php' ) 
    202                     break; 
    203  
    204                 // If the requesting file is the anchor of the match, prepend it 
    205                 // to the path info. 
    206                 if ( (! empty($req_uri)) && (strpos($match, $req_uri) === 0) && ($req_uri != $request) ) 
    207                     $request_match = $req_uri . '/' . $request; 
    208  
    209                 if ( preg_match("#^$match#", $request_match, $matches) || 
    210                     preg_match("#^$match#", urldecode($request_match), $matches) ) { 
    211                     // Got a match. 
    212                     $this->matched_rule = $match; 
    213  
    214                     // Trim the query of everything up to the '?'. 
    215                     $query = preg_replace("!^.+\?!", '', $query); 
    216  
    217                     // Substitute the substring matches into the query. 
    218                     $query = addslashes(WP_MatchesMapRegex::apply($query, $matches)); 
    219  
    220                     $this->matched_query = $query; 
    221  
    222                     // Parse the query. 
    223                     parse_str($query, $perma_query_vars); 
    224  
    225                     // If we're processing a 404 request, clear the error var 
    226                     // since we found something. 
    227                     if ( isset($_GET['error']) ) 
    228                         unset($_GET['error']); 
    229  
    230                     if ( isset($error) ) 
    231                         unset($error); 
    232  
    233                     break; 
    234                 } 
    235             } 
    236  
    237             // If req_uri is empty or if it is a request for ourself, unset error. 
    238             if ( empty($request) || $req_uri == $self || strpos($_SERVER['PHP_SELF'], 'wp-admin/') !== false ) { 
    239                 if ( isset($_GET['error']) ) 
    240                     unset($_GET['error']); 
    241  
    242                 if ( isset($error) ) 
    243                     unset($error); 
    244  
    245                 if ( isset($perma_query_vars) && strpos($_SERVER['PHP_SELF'], 'wp-admin/') !== false ) 
    246                     unset($perma_query_vars); 
    247  
    248                 $this->did_permalink = false; 
    249             } 
    250         } 
    251  
    252         $this->public_query_vars = apply_filters('query_vars', $this->public_query_vars); 
    253  
    254         foreach ( $GLOBALS['wp_post_types'] as $post_type => $t ) 
    255             if ( $t->query_var ) 
    256                 $post_type_query_vars[$t->query_var] = $post_type; 
    257  
    258         foreach ( $this->public_query_vars as $wpvar ) { 
    259             if ( isset( $this->extra_query_vars[$wpvar] ) ) 
    260                 $this->query_vars[$wpvar] = $this->extra_query_vars[$wpvar]; 
    261             elseif ( isset( $_POST[$wpvar] ) ) 
    262                 $this->query_vars[$wpvar] = $_POST[$wpvar]; 
    263             elseif ( isset( $_GET[$wpvar] ) ) 
    264                 $this->query_vars[$wpvar] = $_GET[$wpvar]; 
    265             elseif ( isset( $perma_query_vars[$wpvar] ) ) 
    266                 $this->query_vars[$wpvar] = $perma_query_vars[$wpvar]; 
    267  
    268             if ( !empty( $this->query_vars[$wpvar] ) ) { 
    269                 if ( ! is_array( $this->query_vars[$wpvar] ) ) { 
    270                     $this->query_vars[$wpvar] = (string) $this->query_vars[$wpvar]; 
    271                 } else { 
    272                     foreach ( $this->query_vars[$wpvar] as $vkey => $v ) { 
    273                         if ( !is_object( $v ) ) { 
    274                             $this->query_vars[$wpvar][$vkey] = (string) $v; 
    275                         } 
    276                     } 
    277                 } 
    278  
    279                 if ( isset($post_type_query_vars[$wpvar] ) ) { 
    280                     $this->query_vars['post_type'] = $post_type_query_vars[$wpvar]; 
    281                     $this->query_vars['name'] = $this->query_vars[$wpvar]; 
    282                 } 
    283             } 
    284         } 
    285  
    286         // Limit publicly queried post_types to those that are publicly_queryable 
    287         if ( isset( $this->query_vars['post_type']) ) { 
    288             $queryable_post_types = get_post_types( array('publicly_queryable' => true) ); 
    289             if ( ! is_array( $this->query_vars['post_type'] ) ) { 
    290                 if ( ! in_array( $this->query_vars['post_type'], $queryable_post_types ) ) 
    291                     unset( $this->query_vars['post_type'] ); 
    292             } else { 
    293                 $this->query_vars['post_type'] = array_intersect( $this->query_vars['post_type'], $queryable_post_types ); 
    294             } 
    295         } 
    296  
    297         foreach ( (array) $this->private_query_vars as $var) { 
    298             if ( isset($this->extra_query_vars[$var]) ) 
    299                 $this->query_vars[$var] = $this->extra_query_vars[$var]; 
    300         } 
    301  
    302         if ( isset($error) ) 
    303             $this->query_vars['error'] = $error; 
    304  
    305         $this->query_vars = apply_filters('request', $this->query_vars); 
    306  
    307         do_action_ref_array('parse_request', array(&$this)); 
    308     } 
    309  
    310     /** 
    311      * Send additional HTTP headers for caching, content type, etc. 
    312      * 
    313      * Sets the X-Pingback header, 404 status (if 404), Content-type. If showing 
    314      * a feed, it will also send last-modified, etag, and 304 status if needed. 
    315      * 
    316      * @since 2.0.0 
    317      */ 
    318     function send_headers() { 
    319         $headers = array('X-Pingback' => get_bloginfo('pingback_url')); 
    320         $status = null; 
    321         $exit_required = false; 
    322  
    323         if ( is_user_logged_in() ) 
    324             $headers = array_merge($headers, wp_get_nocache_headers()); 
    325         if ( !empty($this->query_vars['error']) && '404' == $this->query_vars['error'] ) { 
    326             $status = 404; 
    327             if ( !is_user_logged_in() ) 
    328                 $headers = array_merge($headers, wp_get_nocache_headers()); 
    329             $headers['Content-Type'] = get_option('html_type') . '; charset=' . get_option('blog_charset'); 
    330         } else if ( empty($this->query_vars['feed']) ) { 
    331             $headers['Content-Type'] = get_option('html_type') . '; charset=' . get_option('blog_charset'); 
    332         } else { 
    333             // We're showing a feed, so WP is indeed the only thing that last changed 
    334             if ( !empty($this->query_vars['withcomments']) 
    335                 || ( empty($this->query_vars['withoutcomments']) 
    336                     && ( !empty($this->query_vars['p']) 
    337                         || !empty($this->query_vars['name']) 
    338                         || !empty($this->query_vars['page_id']) 
    339                         || !empty($this->query_vars['pagename']) 
    340                         || !empty($this->query_vars['attachment']) 
    341                         || !empty($this->query_vars['attachment_id']) 
    342                     ) 
    343                 ) 
    344             ) 
    345                 $wp_last_modified = mysql2date('D, d M Y H:i:s', get_lastcommentmodified('GMT'), 0).' GMT'; 
    346             else 
    347                 $wp_last_modified = mysql2date('D, d M Y H:i:s', get_lastpostmodified('GMT'), 0).' GMT'; 
    348             $wp_etag = '"' . md5($wp_last_modified) . '"'; 
    349             $headers['Last-Modified'] = $wp_last_modified; 
    350             $headers['ETag'] = $wp_etag; 
    351  
    352             // Support for Conditional GET 
    353             if (isset($_SERVER['HTTP_IF_NONE_MATCH'])) 
    354                 $client_etag = stripslashes(stripslashes($_SERVER['HTTP_IF_NONE_MATCH'])); 
    355             else $client_etag = false; 
    356  
    357             $client_last_modified = empty($_SERVER['HTTP_IF_MODIFIED_SINCE']) ? '' : trim($_SERVER['HTTP_IF_MODIFIED_SINCE']); 
    358             // If string is empty, return 0. If not, attempt to parse into a timestamp 
    359             $client_modified_timestamp = $client_last_modified ? strtotime($client_last_modified) : 0; 
    360  
    361             // Make a timestamp for our most recent modification... 
    362             $wp_modified_timestamp = strtotime($wp_last_modified); 
    363  
    364             if ( ($client_last_modified && $client_etag) ? 
    365                      (($client_modified_timestamp >= $wp_modified_timestamp) && ($client_etag == $wp_etag)) : 
    366                      (($client_modified_timestamp >= $wp_modified_timestamp) || ($client_etag == $wp_etag)) ) { 
    367                 $status = 304; 
    368                 $exit_required = true; 
    369             } 
    370         } 
    371  
    372         $headers = apply_filters('wp_headers', $headers, $this); 
    373  
    374         if ( ! empty( $status ) ) 
    375             status_header( $status ); 
    376         foreach( (array) $headers as $name => $field_value ) 
    377             @header("{$name}: {$field_value}"); 
    378  
    379         if ( $exit_required ) 
    380             exit(); 
    381  
    382         do_action_ref_array('send_headers', array(&$this)); 
    383     } 
    384  
    385     /** 
    386      * Sets the query string property based off of the query variable property. 
    387      * 
    388      * The 'query_string' filter is deprecated, but still works. Plugins should 
    389      * use the 'request' filter instead. 
    390      * 
    391      * @since 2.0.0 
    392      */ 
    393     function build_query_string() { 
    394         $this->query_string = ''; 
    395         foreach ( (array) array_keys($this->query_vars) as $wpvar) { 
    396             if ( '' != $this->query_vars[$wpvar] ) { 
    397                 $this->query_string .= (strlen($this->query_string) < 1) ? '' : '&'; 
    398                 if ( !is_scalar($this->query_vars[$wpvar]) ) // Discard non-scalars. 
    399                     continue; 
    400                 $this->query_string .= $wpvar . '=' . rawurlencode($this->query_vars[$wpvar]); 
    401             } 
    402         } 
    403  
    404         // query_string filter deprecated.  Use request filter instead. 
    405         if ( has_filter('query_string') ) {  // Don't bother filtering and parsing if no plugins are hooked in. 
    406             $this->query_string = apply_filters('query_string', $this->query_string); 
    407             parse_str($this->query_string, $this->query_vars); 
    408         } 
    409     } 
    410  
    411     /** 
    412      * Set up the WordPress Globals. 
    413      * 
    414      * The query_vars property will be extracted to the GLOBALS. So care should 
    415      * be taken when naming global variables that might interfere with the 
    416      * WordPress environment. 
    417      * 
    418      * @global string $query_string Query string for the loop. 
    419      * @global int $more Only set, if single page or post. 
    420      * @global int $single If single page or post. Only set, if single page or post. 
    421      * 
    422      * @since 2.0.0 
    423      */ 
    424     function register_globals() { 
    425         global $wp_query; 
    426         // Extract updated query vars back into global namespace. 
    427         foreach ( (array) $wp_query->query_vars as $key => $value) { 
    428             $GLOBALS[$key] = $value; 
    429         } 
    430  
    431         $GLOBALS['query_string'] = $this->query_string; 
    432         $GLOBALS['posts'] = & $wp_query->posts; 
    433         $GLOBALS['post'] = (isset($wp_query->post)) ? $wp_query->post : null; 
    434         $GLOBALS['request'] = $wp_query->request; 
    435  
    436         if ( is_single() || is_page() ) { 
    437             $GLOBALS['more'] = 1; 
    438             $GLOBALS['single'] = 1; 
    439         } 
    440     } 
    441  
    442     /** 
    443      * Set up the current user. 
    444      * 
    445      * @since 2.0.0 
    446      */ 
    447     function init() { 
    448         wp_get_current_user(); 
    449     } 
    450  
    451     /** 
    452      * Set up the Loop based on the query variables. 
    453      * 
    454      * @uses WP::$query_vars 
    455      * @since 2.0.0 
    456      */ 
    457     function query_posts() { 
    458         global $wp_the_query; 
    459         $this->build_query_string(); 
    460         $wp_the_query->query($this->query_vars); 
    461     } 
    462  
    463     /** 
    464      * Set the Headers for 404, if nothing is found for requested URL. 
    465      * 
    466      * Issue a 404 if a request doesn't match any posts and doesn't match 
    467      * any object (e.g. an existing-but-empty category, tag, author) and a 404 was not already 
    468      * issued, and if the request was not a search or the homepage. 
    469      * 
    470      * Otherwise, issue a 200. 
    471      * 
    472      * @since 2.0.0 
    473      */ 
    474     function handle_404() { 
    475         global $wp_query; 
    476  
    477         if ( !is_admin() && ( 0 == count( $wp_query->posts ) ) && !is_404() && !is_robots() && !is_search() && !is_home() ) { 
    478             // Don't 404 for these queries if they matched an object. 
    479             if ( ( is_tag() || is_category() || is_tax() || is_author() ) && $wp_query->get_queried_object() && !is_paged() ) { 
    480                 if ( !is_404() ) 
    481                     status_header( 200 ); 
    482                 return; 
    483             } 
    484             $wp_query->set_404(); 
    485             status_header( 404 ); 
    486             nocache_headers(); 
    487         } elseif ( !is_404() ) { 
    488             status_header( 200 ); 
    489         } 
    490     } 
    491  
    492     /** 
    493      * Sets up all of the variables required by the WordPress environment. 
    494      * 
    495      * The action 'wp' has one parameter that references the WP object. It 
    496      * allows for accessing the properties and methods to further manipulate the 
    497      * object. 
    498      * 
    499      * @since 2.0.0 
    500      * 
    501      * @param string|array $query_args Passed to {@link parse_request()} 
    502      */ 
    503     function main($query_args = '') { 
    504         $this->init(); 
    505         $this->parse_request($query_args); 
    506         $this->send_headers(); 
    507         $this->query_posts(); 
    508         $this->handle_404(); 
    509         $this->register_globals(); 
    510         do_action_ref_array('wp', array(&$this)); 
    511     } 
    512  
    513     /** 
    514      * PHP4 Constructor - Does nothing. 
    515      * 
    516      * Call main() method when ready to run setup. 
    517      * 
    518      * @since 2.0.0 
    519      * 
    520      * @return WP 
    521      */ 
    522     function WP() { 
    523         // Empty. 
    524     } 
    525 } 
    52612 
    52713/** 
     
    761247} 
    762248 
    763 /** 
    764  * WordPress Error class. 
    765  * 
    766  * Container for checking for WordPress errors and error messages. Return 
    767  * WP_Error and use {@link is_wp_error()} to check if this class is returned. 
    768  * Many core WordPress functions pass this class in the event of an error and 
    769  * if not handled properly will result in code errors. 
    770  * 
    771  * @package WordPress 
    772  * @since 2.1.0 
    773  */ 
    774 class WP_Error { 
    775     /** 
    776      * Stores the list of errors. 
    777      * 
    778      * @since 2.1.0 
    779      * @var array 
    780      * @access private 
    781      */ 
    782     var $errors = array(); 
    783  
    784     /** 
    785      * Stores the list of data for error codes. 
    786      * 
    787      * @since 2.1.0 
    788      * @var array 
    789      * @access private 
    790      */ 
    791     var $error_data = array(); 
    792  
    793     /** 
    794      * PHP4 Constructor - Sets up error message. 
    795      * 
    796      * If code parameter is empty then nothing will be done. It is possible to 
    797      * add multiple messages to the same code, but with other methods in the 
    798      * class. 
    799      * 
    800      * All parameters are optional, but if the code parameter is set, then the 
    801      * data parameter is optional. 
    802      * 
    803      * @since 2.1.0 
    804      * 
    805      * @param string|int $code Error code 
    806      * @param string $message Error message 
    807      * @param mixed $data Optional. Error data. 
    808      * @return WP_Error 
    809      */ 
    810     function WP_Error($code = '', $message = '', $data = '') { 
    811         if ( empty($code) ) 
    812             return; 
    813  
    814         $this->errors[$code][] = $message; 
    815  
    816         if ( ! empty($data) ) 
    817             $this->error_data[$code] = $data; 
    818     } 
    819  
    820     /** 
    821      * Retrieve all error codes. 
    822      * 
    823      * @since 2.1.0 
    824      * @access public 
    825      * 
    826      * @return array List of error codes, if avaiable. 
    827      */ 
    828     function get_error_codes() { 
    829         if ( empty($this->errors) ) 
    830             return array(); 
    831  
    832         return array_keys($this->errors); 
    833     } 
    834  
    835     /** 
    836      * Retrieve first error code available. 
    837      * 
    838      * @since 2.1.0 
    839      * @access public 
    840      * 
    841      * @return string|int Empty string, if no error codes. 
    842      */ 
    843     function get_error_code() { 
    844         $codes = $this->get_error_codes(); 
    845  
    846         if ( empty($codes) ) 
    847             return ''; 
    848  
    849         return $codes[0]; 
    850     } 
    851  
    852     /** 
    853      * Retrieve all error messages or error messages matching code. 
    854      * 
    855      * @since 2.1.0 
    856      * 
    857      * @param string|int $code Optional. Retrieve messages matching code, if exists. 
    858      * @return array Error strings on success, or empty array on failure (if using codee parameter). 
    859      */ 
    860     function get_error_messages($code = '') { 
    861         // Return all messages if no code specified. 
    862         if ( empty($code) ) { 
    863             $all_messages = array(); 
    864             foreach ( (array) $this->errors as $code => $messages ) 
    865                 $all_messages = array_merge($all_messages, $messages); 
    866  
    867             return $all_messages; 
    868         } 
    869  
    870         if ( isset($this->errors[$code]) ) 
    871             return $this->errors[$code]; 
    872         else 
    873             return array(); 
    874     } 
    875  
    876     /** 
    877      * Get single error message. 
    878      * 
    879      * This will get the first message available for the code. If no code is 
    880      * given then the first code available will be used. 
    881      * 
    882      * @since 2.1.0 
    883      * 
    884      * @param string|int $code Optional. Error code to retrieve message. 
    885      * @return string 
    886      */ 
    887     function get_error_message($code = '') { 
    888         if ( empty($code) ) 
    889             $code = $this->get_error_code(); 
    890         $messages = $this->get_error_messages($code); 
    891         if ( empty($messages) ) 
    892             return ''; 
    893         return $messages[0]; 
    894     } 
    895  
    896     /** 
    897      * Retrieve error data for error code. 
    898      * 
    899      * @since 2.1.0 
    900      * 
    901      * @param string|int $code Optional. Error code. 
    902      * @return mixed Null, if no errors. 
    903      */ 
    904     function get_error_data($code = '') { 
    905         if ( empty($code) ) 
    906             $code = $this->get_error_code(); 
    907  
    908         if ( isset($this->error_data[$code]) ) 
    909             return $this->error_data[$code]; 
    910         return null; 
    911     } 
    912  
    913     /** 
    914      * Append more error messages to list of error messages. 
    915      * 
    916      * @since 2.1.0 
    917      * @access public 
    918      * 
    919      * @param string|int $code Error code. 
    920      * @param string $message Error message. 
    921      * @param mixed $data Optional. Error data. 
    922      */ 
    923     function add($code, $message, $data = '') { 
    924         $this->errors[$code][] = $message; 
    925         if ( ! empty($data) ) 
    926             $this->error_data[$code] = $data; 
    927     } 
    928  
    929     /** 
    930      * Add data for error code. 
    931      * 
    932      * The error code can only contain one error data. 
    933      * 
    934      * @since 2.1.0 
    935      * 
    936      * @param mixed $data Error data. 
    937      * @param string|int $code Error code. 
    938      */ 
    939     function add_data($data, $code = '') { 
    940         if ( empty($code) ) 
    941             $code = $this->get_error_code(); 
    942  
    943         $this->error_data[$code] = $data; 
    944     } 
    945 } 
    946  
    947 /** 
    948  * Check whether variable is a WordPress Error. 
    949  * 
    950  * Looks at the object and if a WP_Error class. Does not check to see if the 
    951  * parent is also WP_Error, so can't inherit WP_Error and still use this 
    952  * function. 
    953  * 
    954  * @since 2.1.0 
    955  * 
    956  * @param mixed $thing Check if unknown variable is WordPress Error object. 
    957  * @return bool True, if WP_Error. False, if not WP_Error. 
    958  */ 
    959 function is_wp_error($thing) { 
    960     if ( is_object($thing) && is_a($thing, 'WP_Error') ) 
    961         return true; 
    962     return false; 
    963 } 
    964  
    965 /** 
    966  * A class for displaying various tree-like structures. 
    967  * 
    968  * Extend the Walker class to use it, see examples at the below. Child classes 
    969  * do not need to implement all of the abstract methods in the class. The child 
    970  * only needs to implement the methods that are needed. Also, the methods are 
    971  * not strictly abstract in that the parameter definition needs to be followed. 
    972  * The child classes can have additional parameters. 
    973  * 
    974  * @package WordPress 
    975  * @since 2.1.0 
    976  * @abstract 
    977  */ 
    978 class Walker { 
    979     /** 
    980      * What the class handles. 
    981      * 
    982      * @since 2.1.0 
    983      * @var string 
    984      * @access public 
    985      */ 
    986     var $tree_type; 
    987  
    988     /** 
    989      * DB fields to use. 
    990      * 
    991      * @since 2.1.0 
    992      * @var array 
    993      * @access protected 
    994      */ 
    995     var $db_fields; 
    996  
    997     /** 
    998      * Max number of pages walked by the paged walker 
    999      * 
    1000      * @since 2.7.0 
    1001      * @var int 
    1002      * @access protected 
    1003      */ 
    1004     var $max_pages = 1; 
    1005  
    1006     /** 
    1007      * Starts the list before the elements are added. 
    1008      * 
    1009      * Additional parameters are used in child classes. The args parameter holds 
    1010      * additional values that may be used with the child class methods. This 
    1011      * method is called at the start of the output list. 
    1012      * 
    1013      * @since 2.1.0 
    1014      * @abstract 
    1015      * 
    1016      * @param string $output Passed by reference. Used to append additional content. 
    1017      */ 
    1018     function start_lvl(&$output) {} 
    1019  
    1020     /** 
    1021      * Ends the list of after the elements are added. 
    1022      * 
    1023      * Additional parameters are used in child classes. The args parameter holds 
    1024      * additional values that may be used with the child class methods. This 
    1025      * method finishes the list at the end of output of the elements. 
    1026      * 
    1027      * @since 2.1.0 
    1028      * @abstract 
    1029      * 
    1030      * @param string $output Passed by reference. Used to append additional content. 
    1031      */ 
    1032     function end_lvl(&$output)   {} 
    1033  
    1034     /** 
    1035      * Start the element output. 
    1036      * 
    1037      * Additional parameters are used in child classes. The args parameter holds 
    1038      * additional values that may be used with the child class methods. Includes 
    1039      * the element output also. 
    1040      * 
    1041      * @since 2.1.0 
    1042      * @abstract 
    1043      * 
    1044      * @param string $output Passed by reference. Used to append additional content. 
    1045      */ 
    1046     function start_el(&$output)  {} 
    1047  
    1048     /** 
    1049      * Ends the element output, if needed. 
    1050      * 
    1051      * Additional parameters are used in child classes. The args parameter holds 
    1052      * additional values that may be used with the child class methods. 
    1053      * 
    1054      * @since 2.1.0 
    1055      * @abstract 
    1056      * 
    1057      * @param string $output Passed by reference. Used to append additional content. 
    1058      */ 
    1059     function end_el(&$output)    {} 
    1060  
    1061     /** 
    1062      * Traverse elements to create list from elements. 
    1063      * 
    1064      * Display one element if the element doesn't have any children otherwise, 
    1065      * display the element and its children. Will only traverse up to the max 
    1066      * depth and no ignore elements under that depth. It is possible to set the 
    1067      * max depth to include all depths, see walk() method. 
    1068      * 
    1069      * This method shouldn't be called directly, use the walk() method instead. 
    1070      * 
    1071      * @since 2.5.0 
    1072      * 
    1073      * @param object $element Data object 
    1074      * @param array $children_elements List of elements to continue traversing. 
    1075      * @param int $max_depth Max depth to traverse. 
    1076      * @param int $depth Depth of current element. 
    1077      * @param array $args 
    1078      * @param string $output Passed by reference. Used to append additional content. 
    1079      * @return null Null on failure with no changes to parameters. 
    1080      */ 
    1081     function display_element( $element, &$children_elements, $max_depth, $depth=0, $args, &$output ) { 
    1082  
    1083         if ( !$element ) 
    1084             return; 
    1085  
    1086         $id_field = $this->db_fields['id']; 
    1087  
    1088         //display this element 
    1089         if ( is_array( $args[0] ) ) 
    1090             $args[0]['has_children'] = ! empty( $children_elements[$element->$id_field] ); 
    1091         $cb_args = array_merge( array(&$output, $element, $depth), $args); 
    1092         call_user_func_array(array(&$this, 'start_el'), $cb_args); 
    1093  
    1094         $id = $element->$id_field; 
    1095  
    1096         // descend only when the depth is right and there are childrens for this element 
    1097         if ( ($max_depth == 0 || $max_depth > $depth+1 ) && isset( $children_elements[$id]) ) { 
    1098  
    1099             foreach( $children_elements[ $id ] as $child ){ 
    1100  
    1101                 if ( !isset($newlevel) ) { 
    1102                     $newlevel = true; 
    1103                     //start the child delimiter 
    1104                     $cb_args = array_merge( array(&$output, $depth), $args); 
    1105                     call_user_func_array(array(&$this, 'start_lvl'), $cb_args); 
    1106                 } 
    1107                 $this->display_element( $child, $children_elements, $max_depth, $depth + 1, $args, $output ); 
    1108             } 
    1109             unset( $children_elements[ $id ] ); 
    1110         } 
    1111  
    1112         if ( isset($newlevel) && $newlevel ){ 
    1113             //end the child delimiter 
    1114             $cb_args = array_merge( array(&$output, $depth), $args); 
    1115             call_user_func_array(array(&$this, 'end_lvl'), $cb_args); 
    1116         } 
    1117  
    1118         //end this element 
    1119         $cb_args = array_merge( array(&$output, $element, $depth), $args); 
    1120         call_user_func_array(array(&$this, 'end_el'), $cb_args); 
    1121     } 
    1122  
    1123     /** 
    1124      * Display array of elements hierarchically. 
    1125      * 
    1126      * It is a generic function which does not assume any existing order of 
    1127      * elements. max_depth = -1 means flatly display every element. max_depth = 
    1128      * 0 means display all levels. max_depth > 0  specifies the number of 
    1129      * display levels. 
    1130      * 
    1131      * @since 2.1.0 
    1132      * 
    1133      * @param array $elements 
    1134      * @param int $max_depth 
    1135      * @return string 
    1136      */ 
    1137     function walk( $elements, $max_depth) { 
    1138  
    1139         $args = array_slice(func_get_args(), 2); 
    1140         $output = ''; 
    1141  
    1142         if ($max_depth < -1) //invalid parameter 
    1143             return $output; 
    1144  
    1145         if (empty($elements)) //nothing to walk 
    1146             return $output; 
    1147  
    1148         $id_field = $this->db_fields['id']; 
    1149         $parent_field = $this->db_fields['parent']; 
    1150  
    1151         // flat display 
    1152         if ( -1 == $max_depth ) { 
    1153             $empty_array = array(); 
    1154             foreach ( $elements as $e ) 
    1155                 $this->display_element( $e, $empty_array, 1, 0, $args, $output ); 
    1156             return $output; 
    1157         } 
    1158  
    1159         /* 
    1160          * need to display in hierarchical order 
    1161          * separate elements into two buckets: top level and children elements 
    1162          * children_elements is two dimensional array, eg. 
    1163          * children_elements[10][] contains all sub-elements whose parent is 10. 
    1164          */ 
    1165         $top_level_elements = array(); 
    1166         $children_elements  = array(); 
    1167         foreach ( $elements as $e) { 
    1168             if ( 0 == $e->$parent_field ) 
    1169                 $top_level_elements[] = $e; 
    1170             else 
    1171                 $children_elements[ $e->$parent_field ][] = $e; 
    1172         } 
    1173  
    1174         /* 
    1175          * when none of the elements is top level 
    1176          * assume the first one must be root of the sub elements 
    1177          */ 
    1178         if ( empty($top_level_elements) ) { 
    1179  
    1180             $first = array_slice( $elements, 0, 1 ); 
    1181             $root = $first[0]; 
    1182  
    1183             $top_level_elements = array(); 
    1184             $children_elements  = array(); 
    1185             foreach ( $elements as $e) { 
    1186                 if ( $root->$parent_field == $e->$parent_field ) 
    1187                     $top_level_elements[] = $e; 
    1188                 else 
    1189                     $children_elements[ $e->$parent_field ][] = $e; 
    1190             } 
    1191         } 
    1192  
    1193         foreach ( $top_level_elements as $e ) 
    1194             $this->display_element( $e, $children_elements, $max_depth, 0, $args, $output ); 
    1195  
    1196         /* 
    1197          * if we are displaying all levels, and remaining children_elements is not empty, 
    1198          * then we got orphans, which should be displayed regardless 
    1199          */ 
    1200         if ( ( $max_depth == 0 ) && count( $children_elements ) > 0 ) { 
    1201             $empty_array = array(); 
    1202             foreach ( $children_elements as $orphans ) 
    1203                 foreach( $orphans as $op ) 
    1204                     $this->display_element( $op, $empty_array, 1, 0, $args, $output ); 
    1205          } 
    1206  
    1207          return $output; 
    1208     } 
    1209  
    1210     /** 
    1211      * paged_walk() - produce a page of nested elements 
    1212      * 
    1213      * Given an array of hierarchical elements, the maximum depth, a specific page number, 
    1214      * and number of elements per page, this function first determines all top level root elements 
    1215      * belonging to that page, then lists them and all of their children in hierarchical order. 
    1216      * 
    1217      * @package WordPress 
    1218      * @since 2.7 
    1219      * @param int $max_depth = 0 means display all levels; $max_depth > 0 specifies the number of display levels. 
    1220      * @param int $page_num the specific page number, beginning with 1. 
    1221      * @return XHTML of the specified page of elements 
    1222      */ 
    1223     function paged_walk( $elements, $max_depth, $page_num, $per_page ) { 
    1224  
    1225         /* sanity check */ 
    1226         if ( empty($elements) || $max_depth < -1 ) 
    1227             return ''; 
    1228  
    1229         $args = array_slice( func_get_args(), 4 ); 
    1230         $output = ''; 
    1231  
    1232         $id_field = $this->db_fields['id']; 
    1233         $parent_field = $this->db_fields['parent']; 
    1234  
    1235         $count = -1; 
    1236         if ( -1 == $max_depth ) 
    1237             $total_top = count( $elements ); 
    1238         if ( $page_num < 1 || $per_page < 0  ) { 
    1239             // No paging 
    1240             $paging = false; 
    1241             $start = 0; 
    1242             if ( -1 == $max_depth ) 
    1243                 $end = $total_top; 
    1244             $this->max_pages = 1; 
    1245         } else { 
    1246             $paging = true; 
    1247             $start = ( (int)$page_num - 1 ) * (int)$per_page; 
    1248             $end   = $start + $per_page; 
    1249             if ( -1 == $max_depth ) 
    1250                 $this->max_pages = ceil($total_top / $per_page); 
    1251         } 
    1252  
    1253         // flat display 
    1254         if ( -1 == $max_depth ) { 
    1255             if ( !empty($args[0]['reverse_top_level']) ) { 
    1256                 $elements = array_reverse( $elements ); 
    1257                 $oldstart = $start; 
    1258                 $start = $total_top - $end; 
    1259                 $end = $total_top - $oldstart; 
    1260             } 
    1261  
    1262             $empty_array = array(); 
    1263             foreach ( $elements as $e ) { 
    1264                 $count++; 
    1265                 if ( $count < $start ) 
    1266                     continue; 
    1267                 if ( $count >= $end ) 
    1268                     break; 
    1269                 $this->display_element( $e, $empty_array, 1, 0, $args, $output ); 
    1270             } 
    1271             return $output; 
    1272         } 
    1273  
    1274         /* 
    1275          * separate elements into two buckets: top level and children elements 
    1276          * children_elements is two dimensional array, eg. 
    1277          * children_elements[10][] contains all sub-elements whose parent is 10. 
    1278          */ 
    1279         $top_level_elements = array(); 
    1280         $children_elements  = array(); 
    1281         foreach ( $elements as $e) { 
    1282             if ( 0 == $e->$parent_field ) 
    1283                 $top_level_elements[] = $e; 
    1284             else 
    1285                 $children_elements[ $e->$parent_field ][] = $e; 
    1286         } 
    1287  
    1288         $total_top = count( $top_level_elements ); 
    1289         if ( $paging ) 
    1290             $this->max_pages = ceil($total_top / $per_page); 
    1291         else 
    1292             $end = $total_top; 
    1293  
    1294         if ( !empty($args[0]['reverse_top_level']) ) { 
    1295             $top_level_elements = array_reverse( $top_level_elements ); 
    1296             $oldstart = $start; 
    1297             $start = $total_top - $end; 
    1298             $end = $total_top - $oldstart; 
    1299         } 
    1300         if ( !empty($args[0]['reverse_children']) ) { 
    1301             foreach ( $children_elements as $parent => $children ) 
    1302                 $children_elements[$parent] = array_reverse( $children ); 
    1303         } 
    1304  
    1305         foreach ( $top_level_elements as $e ) { 
    1306             $count++; 
    1307  
    1308             //for the last page, need to unset earlier children in order to keep track of orphans 
    1309             if ( $end >= $total_top && $count < $start ) 
    1310                     $this->unset_children( $e, $children_elements ); 
    1311  
    1312             if ( $count < $start ) 
    1313                 continue; 
    1314  
    1315             if ( $count >= $end ) 
    1316                 break; 
    1317  
    1318             $this->display_element( $e, $children_elements, $max_depth, 0, $args, $output ); 
    1319         } 
    1320  
    1321         if ( $end >= $total_top && count( $children_elements ) > 0 ) { 
    1322             $empty_array = array(); 
    1323             foreach ( $children_elements as $orphans ) 
    1324                 foreach( $orphans as $op ) 
    1325                     $this->display_element( $op, $empty_array, 1, 0, $args, $output ); 
    1326         } 
    1327  
    1328         return $output; 
    1329     } 
    1330  
    1331     function get_number_of_root_elements( $elements ){ 
    1332  
    1333         $num = 0; 
    1334         $parent_field = $this->db_fields['parent']; 
    1335  
    1336         foreach ( $elements as $e) { 
    1337             if ( 0 == $e->$parent_field ) 
    1338                 $num++; 
    1339         } 
    1340         return $num; 
    1341     } 
    1342  
    1343     // unset all the children for a given top level element 
    1344     function unset_children( $e, &$children_elements ){ 
    1345  
    1346         if ( !$e || !$children_elements ) 
    1347             return; 
    1348  
    1349         $id_field = $this->db_fields['id']; 
    1350         $id = $e->$id_field; 
    1351  
    1352         if ( !empty($children_elements[$id]) && is_array($children_elements[$id]) ) 
    1353             foreach ( (array) $children_elements[$id] as $child ) 
    1354                 $this->unset_children( $child, $children_elements ); 
    1355  
    1356         if ( isset($children_elements[$id]) ) 
    1357             unset( $children_elements[$id] ); 
    1358  
    1359     } 
    1360 } 
    1361  
    1362 /** 
    1363  * Create HTML list of pages. 
    1364  * 
    1365  * @package WordPress 
    1366  * @since 2.1.0 
    1367  * @uses Walker 
    1368  */ 
    1369 class Walker_Page extends Walker { 
    1370     /** 
    1371      * @see Walker::$tree_type 
    1372      * @since 2.1.0 
    1373      * @var string 
    1374      */ 
    1375     var $tree_type = 'page'; 
    1376  
    1377     /** 
    1378      * @see Walker::$db_fields 
    1379      * @since 2.1.0 
    1380      * @todo Decouple this. 
    1381      * @var array 
    1382      */ 
    1383     var $db_fields = array ('parent' => 'post_parent', 'id' => 'ID'); 
    1384  
    1385     /** 
    1386      * @see Walker::start_lvl() 
    1387      * @since 2.1.0 
    1388      * 
    1389      * @param string $output Passed by reference. Used to append additional content. 
    1390      * @param int $depth Depth of page. Used for padding. 
    1391      */ 
    1392     function start_lvl(&$output, $depth) { 
    1393         $indent = str_repeat("\t", $depth); 
    1394         $output .= "\n$indent<ul class='children'>\n"; 
    1395     } 
    1396  
    1397     /** 
    1398      * @see Walker::end_lvl() 
    1399      * @since 2.1.0 
    1400      * 
    1401      * @param string $output Passed by reference. Used to append additional content. 
    1402      * @param int $depth Depth of page. Used for padding. 
    1403      */ 
    1404     function end_lvl(&$output, $depth) { 
    1405         $indent = str_repeat("\t", $depth); 
    1406         $output .= "$indent</ul>\n"; 
    1407     } 
    1408  
    1409     /** 
    1410      * @see Walker::start_el() 
    1411      * @since 2.1.0 
    1412      * 
    1413      * @param string $output Passed by reference. Used to append additional content. 
    1414      * @param object $page Page data object. 
    1415      * @param int $depth Depth of page. Used for padding. 
    1416      * @param int $current_page Page ID. 
    1417      * @param array $args 
    1418      */ 
    1419     function start_el(&$output, $page, $depth, $args, $current_page) { 
    1420         if ( $depth ) 
    1421             $indent = str_repeat("\t", $depth); 
    1422         else 
    1423             $indent = ''; 
    1424  
    1425         extract($args, EXTR_SKIP); 
    1426         $css_class = array('page_item', 'page-item-'.$page->ID); 
    1427         if ( !empty($current_page) ) { 
    1428             $_current_page = get_page( $current_page ); 
    1429             if ( isset($_current_page->ancestors) && in_array($page->ID, (array) $_current_page->ancestors) ) 
    1430                 $css_class[] = 'current_page_ancestor'; 
    1431             if ( $page->ID == $current_page ) 
    1432                 $css_class[] = 'current_page_item'; 
    1433             elseif ( $_current_page && $page->ID == $_current_page->post_parent ) 
    1434                 $css_class[] = 'current_page_parent'; 
    1435         } elseif ( $page->ID == get_option('page_for_posts') ) { 
    1436             $css_class[] = 'current_page_parent'; 
    1437         } 
    1438  
    1439         $css_class = implode(' ', apply_filters('page_css_class', $css_class, $page)); 
    1440  
    1441         $output .= $indent . '<li class="' . $css_class . '"><a href="' . get_permalink($page->ID) . '" title="' . esc_attr( wp_strip_all_tags( apply_filters( 'the_title', $page->post_title, $page->ID ) ) ) . '">' . $link_before . apply_filters( 'the_title', $page->post_title, $page->ID ) . $link_after . '</a>'; 
    1442  
    1443         if ( !empty($show_date) ) { 
    1444             if ( 'modified' == $show_date ) 
    1445                 $time = $page->post_modified; 
    1446             else 
    1447                 $time = $page->post_date; 
    1448  
    1449             $output .= " " . mysql2date($date_format, $time); 
    1450         } 
    1451     } 
    1452  
    1453     /** 
    1454      * @see Walker::end_el() 
    1455      * @since 2.1.0 
    1456      * 
    1457      * @param string $output Passed by reference. Used to append additional content. 
    1458      * @param object $page Page data object. Not used. 
    1459      * @param int $depth Depth of page. Not Used. 
    1460      */ 
    1461     function end_el(&$output, $page, $depth) { 
    1462         $output .= "</li>\n"; 
    1463     } 
    1464  
    1465 } 
    1466  
    1467 /** 
    1468  * Create HTML dropdown list of pages. 
    1469  * 
    1470  * @package WordPress 
    1471  * @since 2.1.0 
    1472  * @uses Walker 
    1473  */ 
    1474 class Walker_PageDropdown extends Walker { 
    1475     /** 
    1476      * @see Walker::$tree_type 
    1477      * @since 2.1.0 
    1478      * @var string 
    1479      */ 
    1480     var $tree_type = 'page'; 
    1481  
    1482     /** 
    1483      * @see Walker::$db_fields 
    1484      * @since 2.1.0 
    1485      * @todo Decouple this 
    1486      * @var array 
    1487      */ 
    1488     var $db_fields = array ('parent' => 'post_parent', 'id' => 'ID'); 
    1489  
    1490     /** 
    1491      * @see Walker::start_el() 
    1492      * @since 2.1.0 
    1493      * 
    1494      * @param string $output Passed by reference. Used to append additional content. 
    1495      * @param object $page Page data object. 
    1496      * @param int $depth Depth of page in reference to parent pages. Used for padding. 
    1497      * @param array $args Uses 'selected' argument for selected page to set selected HTML attribute for option element. 
    1498      */ 
    1499     function start_el(&$output, $page, $depth, $args) { 
    1500         $pad = str_repeat('&nbsp;', $depth * 3); 
    1501  
    1502         $output .= "\t<option class=\"level-$depth\" value=\"$page->ID\""; 
    1503         if ( $page->ID == $args['selected'] ) 
    1504             $output .= ' selected="selected"'; 
    1505         $output .= '>'; 
    1506         $title = esc_html($page->post_title); 
    1507         $output .= "$pad$title"; 
    1508         $output .= "</option>\n"; 
    1509     } 
    1510 } 
    1511  
    1512 /** 
    1513  * Create HTML list of categories. 
    1514  * 
    1515  * @package WordPress 
    1516  * @since 2.1.0 
    1517  * @uses Walker 
    1518  */ 
    1519 class Walker_Category extends Walker { 
    1520     /** 
    1521      * @see Walker::$tree_type 
    1522      * @since 2.1.0 
    1523      * @var string 
    1524      */ 
    1525     var $tree_type = 'category'; 
    1526  
    1527     /** 
    1528      * @see Walker::$db_fields 
    1529      * @since 2.1.0 
    1530      * @todo Decouple this 
    1531      * @var array 
    1532      */ 
    1533     var $db_fields = array ('parent' => 'parent', 'id' => 'term_id'); 
    1534  
    1535     /** 
    1536      * @see Walker::start_lvl() 
    1537      * @since 2.1.0 
    1538      * 
    1539      * @param string $output Passed by reference. Used to append additional content. 
    1540      * @param int $depth Depth of category. Used for tab indentation. 
    1541      * @param array $args Will only append content if style argument value is 'list'. 
    1542      */ 
    1543     function start_lvl(&$output, $depth, $args) { 
    1544         if ( 'list' != $args['style'] ) 
    1545             return; 
    1546  
    1547         $indent = str_repeat("\t", $depth); 
    1548         $output .= "$indent<ul class='children'>\n"; 
    1549     } 
    1550  
    1551     /** 
    1552      * @see Walker::end_lvl() 
    1553      * @since 2.1.0 
    1554      * 
    1555      * @param string $output Passed by reference. Used to append additional content. 
    1556      * @param int $depth Depth of category. Used for tab indentation. 
    1557      * @param array $args Will only append content if style argument value is 'list'. 
    1558      */ 
    1559     function end_lvl(&$output, $depth, $args) { 
    1560         if ( 'list' != $args['style'] ) 
    1561             return; 
    1562  
    1563         $indent = str_repeat("\t", $depth); 
    1564         $output .= "$indent</ul>\n"; 
    1565     } 
    1566  
    1567     /** 
    1568      * @see Walker::start_el() 
    1569      * @since 2.1.0 
    1570      * 
    1571      * @param string $output Passed by reference. Used to append additional content. 
    1572      * @param object $category Category data object. 
    1573      * @param int $depth Depth of category in reference to parents. 
    1574      * @param array $args 
    1575      */ 
    1576     function start_el(&$output, $category, $depth, $args) { 
    1577         extract($args); 
    1578  
    1579         $cat_name = esc_attr( $category->name ); 
    1580         $cat_name = apply_filters( 'list_cats', $cat_name, $category ); 
    1581         $link = '<a href="' . esc_attr( get_term_link($category) ) . '" '; 
    1582         if ( $use_desc_for_title == 0 || empty($category->description) ) 
    1583             $link .= 'title="' . sprintf(__( 'View all posts filed under %s' ), $cat_name) . '"'; 
    1584         else 
    1585             $link .= 'title="' . esc_attr( strip_tags( apply_filters( 'category_description', $category->description, $category ) ) ) . '"'; 
    1586         $link .= '>'; 
    1587         $link .= $cat_name . '</a>'; 
    1588  
    1589         if ( !empty($feed_image) || !empty($feed) ) { 
    1590             $link .= ' '; 
    1591  
    1592             if ( empty($feed_image) ) 
    1593                 $link .= '('; 
    1594  
    1595             $link .= '<a href="' . get_term_feed_link( $category->term_id, $category->taxonomy, $feed_type ) . '"'; 
    1596  
    1597             if ( empty($feed) ) { 
    1598                 $alt = ' alt="' . sprintf(__( 'Feed for all posts filed under %s' ), $cat_name ) . '"'; 
    1599             } else { 
    1600                 $title = ' title="' . $feed . '"'; 
    1601                 $alt = ' alt="' . $feed . '"'; 
    1602                 $name = $feed; 
    1603                 $link .= $title; 
    1604             } 
    1605  
    1606             $link .= '>'; 
    1607  
    1608             if ( empty($feed_image) ) 
    1609                 $link .= $name; 
    1610             else 
    1611                 $link .= "<img src='$feed_image'$alt$title" . ' />'; 
    1612  
    1613             $link .= '</a>'; 
    1614  
    1615             if ( empty($feed_image) ) 
    1616                 $link .= ')'; 
    1617         } 
    1618  
    1619         if ( !empty($show_count) ) 
    1620             $link .= ' (' . intval($category->count) . ')'; 
    1621  
    1622         if ( !empty($show_date) ) 
    1623             $link .= ' ' . gmdate('Y-m-d', $category->last_update_timestamp); 
    1624  
    1625         if ( 'list' == $args['style'] ) { 
    1626             $output .= "\t<li"; 
    1627             $class = 'cat-item cat-item-' . $category->term_id; 
    1628             if ( !empty($current_category) ) { 
    1629                 $_current_category = get_term( $current_category, $category->taxonomy ); 
    1630                 if ( $category->term_id == $current_category ) 
    1631                     $class .=  ' current-cat'; 
    1632                 elseif ( $category->term_id == $_current_category->parent ) 
    1633                     $class .=  ' current-cat-parent'; 
    1634             } 
    1635             $output .=  ' class="' . $class . '"'; 
    1636             $output .= ">$link\n"; 
    1637         } else { 
    1638             $output .= "\t$link<br />\n"; 
    1639         } 
    1640     } 
    1641  
    1642     /** 
    1643      * @see Walker::end_el() 
    1644      * @since 2.1.0 
    1645      * 
    1646      * @param string $output Passed by reference. Used to append additional content. 
    1647      * @param object $page Not used. 
    1648      * @param int $depth Depth of category. Not used. 
    1649      * @param array $args Only uses 'list' for whether should append to output. 
    1650      */ 
    1651     function end_el(&$output, $page, $depth, $args) { 
    1652         if ( 'list' != $args['style'] ) 
    1653             return; 
    1654  
    1655         $output .= "</li>\n"; 
    1656     } 
    1657  
    1658 } 
    1659  
    1660 /** 
    1661  * Create HTML dropdown list of Categories. 
    1662  * 
    1663  * @package WordPress 
    1664  * @since 2.1.0 
    1665  * @uses Walker 
    1666  */ 
    1667 class Walker_CategoryDropdown extends Walker { 
    1668     /** 
    1669      * @see Walker::$tree_type 
    1670      * @since 2.1.0 
    1671      * @var string 
    1672      */ 
    1673     var $tree_type = 'category'; 
    1674  
    1675     /** 
    1676      * @see Walker::$db_fields 
    1677      * @since 2.1.0 
    1678      * @todo Decouple this 
    1679      * @var array 
    1680      */ 
    1681     var $db_fields = array ('parent' => 'parent', 'id' => 'term_id'); 
    1682  
    1683     /** 
    1684      * @see Walker::start_el() 
    1685      * @since 2.1.0 
    1686      * 
    1687      * @param string $output Passed by reference. Used to append additional content. 
    1688      * @param object $category Category data object. 
    1689      * @param int $depth Depth of category. Used for padding. 
    1690      * @param array $args Uses 'selected', 'show_count', and 'show_last_update' keys, if they exist. 
    1691      */ 
    1692     function start_el(&$output, $category, $depth, $args) { 
    1693         $pad = str_repeat('&nbsp;', $depth * 3); 
    1694  
    1695         $cat_name = apply_filters('list_cats', $category->name, $category); 
    1696         $output .= "\t<option class=\"level-$depth\" value=\"".$category->term_id."\""; 
    1697         if ( $category->term_id == $args['selected'] ) 
    1698             $output .= ' selected="selected"'; 
    1699         $output .= '>'; 
    1700         $output .= $pad.$cat_name; 
    1701         if ( $args['show_count'] ) 
    1702             $output .= '&nbsp;&nbsp;('. $category->count .')'; 
    1703         if ( $args['show_last_update'] ) { 
    1704             $format = 'Y-m-d'; 
    1705             $output .= '&nbsp;&nbsp;' . gmdate($format, $category->last_update_timestamp); 
    1706         } 
    1707         $output .= "</option>\n"; 
    1708     } 
    1709 } 
    1710  
    1711 /** 
    1712  * Send XML response back to AJAX request. 
    1713  * 
    1714  * @package WordPress 
    1715  * @since 2.1.0 
    1716  */ 
    1717 class WP_Ajax_Response { 
    1718     /** 
    1719      * Store XML responses to send. 
    1720      * 
    1721      * @since 2.1.0 
    1722      * @var array 
    1723      * @access private 
    1724      */ 
    1725     var $responses = array(); 
    1726  
    1727     /** 
    1728      * PHP4 Constructor - Passes args to {@link WP_Ajax_Response::add()}. 
    1729      * 
    1730      * @since 2.1.0 
    1731      * @see WP_Ajax_Response::add() 
    1732      * 
    1733      * @param string|array $args Optional. Will be passed to add() method. 
    1734      * @return WP_Ajax_Response 
    1735      */ 
    1736     function WP_Ajax_Response( $args = '' ) { 
    1737         if ( !empty($args) ) 
    1738             $this->add($args); 
    1739     } 
    1740  
    1741     /** 
    1742      * Append to XML response based on given arguments. 
    1743      * 
    1744      * The arguments that can be passed in the $args parameter are below. It is 
    1745      * also possible to pass a WP_Error object in either the 'id' or 'data' 
    1746      * argument. The parameter isn't actually optional, content should be given 
    1747      * in order to send the correct response. 
    1748      * 
    1749      * 'what' argument is a string that is the XMLRPC response type. 
    1750      * 'action' argument is a boolean or string that acts like a nonce. 
    1751      * 'id' argument can be WP_Error or an integer. 
    1752      * 'old_id' argument is false by default or an integer of the previous ID. 
    1753      * 'position' argument is an integer or a string with -1 = top, 1 = bottom, 
    1754      * html ID = after, -html ID = before. 
    1755      * 'data' argument is a string with the content or message. 
    1756      * 'supplemental' argument is an array of strings that will be children of 
    1757      * the supplemental element. 
    1758      * 
    1759      * @since 2.1.0 
    1760      * 
    1761      * @param string|array $args Override defaults. 
    1762      * @return string XML response. 
    1763      */ 
    1764     function add( $args = '' ) { 
    1765         $defaults = array( 
    1766             'what' => 'object', 'action' => false, 
    1767             'id' => '0', 'old_id' => false, 
    1768             'position' => 1, 
    1769             'data' => '', 'supplemental' => array() 
    1770         ); 
    1771  
    1772         $r = wp_parse_args( $args, $defaults ); 
    1773         extract( $r, EXTR_SKIP ); 
    1774         $position = preg_replace( '/[^a-z0-9:_-]/i', '', $position ); 
    1775  
    1776         if ( is_wp_error($id) ) { 
    1777             $data = $id; 
    1778             $id = 0; 
    1779         } 
    1780  
    1781         $response = ''; 
    1782         if ( is_wp_error($data) ) { 
    1783             foreach ( (array) $data->get_error_codes() as $code ) { 
    1784                 $response .= "<wp_error code='$code'><![CDATA[" . $data->get_error_message($code) . "]]></wp_error>"; 
    1785                 if ( !$error_data = $data->get_error_data($code) ) 
    1786                     continue; 
    1787                 $class = ''; 
    1788                 if ( is_object($error_data) ) { 
    1789                     $class = ' class="' . get_class($error_data) . '"'; 
    1790                     $error_data = get_object_vars($error_data); 
    1791                 } 
    1792  
    1793                 $response .= "<wp_error_data code='$code'$class>"; 
    1794  
    1795                 if ( is_scalar($error_data) ) { 
    1796                     $response .= "<![CDATA[$error_data]]>"; 
    1797                 } elseif ( is_array($error_data) ) { 
    1798                     foreach ( $error_data as $k => $v ) 
    1799                         $response .= "<$k><![CDATA[$v]]></$k>"; 
    1800                 } 
    1801  
    1802                 $response .= "</wp_error_data>"; 
    1803             } 
    1804         } else { 
    1805             $response = "<response_data><![CDATA[$data]]></response_data>"; 
    1806         } 
    1807  
    1808         $s = ''; 
    1809         if ( is_array($supplemental) ) { 
    1810             foreach ( $supplemental as $k => $v ) 
    1811                 $s .= "<$k><![CDATA[$v]]></$k>"; 
    1812             $s = "<supplemental>$s</supplemental>"; 
    1813         } 
    1814  
    1815         if ( false === $action ) 
    1816             $action = $_POST['action']; 
    1817  
    1818         $x = ''; 
    1819         $x .= "<response action='{$action}_$id'>"; // The action attribute in the xml output is formatted like a nonce action 
    1820         $x .=   "<$what id='$id' " . ( false === $old_id ? '' : "old_id='$old_id' " ) . "position='$position'>"; 
    1821         $x .=       $response; 
    1822         $x .=       $s; 
    1823         $x .=   "</$what>"; 
    1824         $x .= "</response>"; 
    1825  
    1826         $this->responses[] = $x; 
    1827         return $x; 
    1828     } 
    1829  
    1830     /** 
    1831      * Display XML formatted responses. 
    1832      * 
    1833      * Sets the content type header to text/xml. 
    1834      * 
    1835      * @since 2.1.0 
    1836      */ 
    1837     function send() { 
    1838         header('Content-Type: text/xml'); 
    1839         echo "<?xml version='1.0' standalone='yes'?><wp_ajax>"; 
    1840         foreach ( (array) $this->responses as $response ) 
    1841             echo $response; 
    1842         echo '</wp_ajax>'; 
    1843         die(); 
    1844     } 
    1845 } 
    1846  
    1847 /** 
    1848  * Helper class to remove the need to use eval to replace $matches[] in query strings. 
    1849  * 
    1850  * @since 2.9.0 
    1851  */ 
    1852 class WP_MatchesMapRegex { 
    1853     /** 
    1854      * store for matches 
    1855      * 
    1856      * @access private 
    1857      * @var array 
    1858      */ 
    1859     var $_matches; 
    1860  
    1861     /** 
    1862      * store for mapping result 
    1863      * 
    1864      * @access public 
    1865      * @var string 
    1866      */ 
    1867     var $output; 
    1868  
    1869     /** 
    1870      * subject to perform mapping on (query string containing $matches[] references 
    1871      * 
    1872      * @access private 
    1873      * @var string 
    1874      */ 
    1875     var $_subject; 
    1876  
    1877     /** 
    1878      * regexp pattern to match $matches[] references 
    1879      * 
    1880      * @var string 
    1881      */ 
    1882     var $_pattern = '(\$matches\[[1-9]+[0-9]*\])'; // magic number 
    1883  
    1884     /** 
    1885      * constructor 
    1886      * 
    1887      * @param string $subject subject if regex 
    1888      * @param array  $matches data to use in map 
    1889      * @return self 
    1890      */ 
    1891     function WP_MatchesMapRegex($subject, $matches) { 
    1892         $this->_subject = $subject; 
    1893         $this->_matches = $matches; 
    1894         $this->output = $this->_map(); 
    1895     } 
    1896  
    1897     /** 
    1898      * Substitute substring matches in subject. 
    1899      * 
    1900      * static helper function to ease use 
    1901      * 
    1902      * @access public 
    1903      * @param string $subject subject 
    1904      * @param array  $matches data used for subsitution 
    1905      * @return string 
    1906      */ 
    1907     function apply($subject, $matches) { 
    1908         $oSelf =& new WP_MatchesMapRegex($subject, $matches); 
    1909         return $oSelf->output; 
    1910     } 
    1911  
    1912     /** 
    1913      * do the actual mapping 
    1914      * 
    1915      * @access private 
    1916      * @return string 
    1917      */ 
    1918     function _map() { 
    1919         $callback = array(&$this, 'callback'); 
    1920         return preg_replace_callback($this->_pattern, $callback, $this->_subject); 
    1921     } 
    1922  
    1923     /** 
    1924      * preg_replace_callback hook 
    1925      * 
    1926      * @access public 
    1927      * @param  array $matches preg_replace regexp matches 
    1928      * @return string 
    1929      */ 
    1930     function callback($matches) { 
    1931         $index = intval(substr($matches[0], 9, -1)); 
    1932         return ( isset( $this->_matches[$index] ) ? urlencode($this->_matches[$index]) : '' ); 
    1933     } 
    1934  
    1935 } 
    1936  
    1937249?> 
  • trunk/wp-includes/classes.php

    r16018 r16051  
    526526 
    527527/** 
    528  * WordPress Query class. 
    529  * 
    530  * Abstract class for handling advanced queries 
    531  * 
    532  * @package WordPress 
    533  * @since 3.1.0 
    534  */ 
    535 class WP_Object_Query { 
    536  
    537     /** 
    538      * Query vars, after parsing 
    539      * 
    540      * @since 3.1.0 
    541      * @access public 
    542      * @var array 
    543      */ 
    544     var $query_vars; 
    545  
    546     /** 
    547      * Retrieve query variable. 
    548      * 
    549      * @since 3.1.0 
    550      * @access public 
    551      * 
    552      * @param string $query_var Query variable key. 
    553      * @return mixed 
    554      */ 
    555     function get( $query_var ) { 
    556         if ( isset( $this->query_vars[$query_var] ) ) 
    557             return $this->query_vars[$query_var]; 
    558  
    559         return ''; 
    560     } 
    561  
    562     /** 
    563      * Set query variable. 
    564      * 
    565      * @since 3.1.0 
    566      * @access public 
    567      * 
    568      * @param string $query_var Query variable key. 
    569      * @param mixed $value Query variable value. 
    570      */ 
    571     function set( $query_var, $value ) { 
    572         $this->query_vars[ $query_var ] = $value; 
    573     } 
    574  
    575     /* 
    576      * Populates the $meta_query property 
    577      * 
    578      * @access protected 
    579      * @since 3.1.0 
    580      * 
    581      * @param array $qv The query variables 
    582      */ 
    583     function parse_meta_query( &$qv ) { 
    584         $meta_query = array(); 
    585  
    586         // Simple query needs to be first for orderby=meta_value to work correctly 
    587         foreach ( array( 'key', 'value', 'compare', 'type' ) as $key ) { 
    588             if ( !empty( $qv[ "meta_$key" ] ) ) 
    589                 $meta_query[0][ $key ] = $qv[ "meta_$key" ]; 
    590         } 
    591  
    592         if ( !empty( $qv['meta_query'] ) && is_array( $qv['meta_query'] ) ) { 
    593             $meta_query = array_merge( $meta_query, $qv['meta_query'] ); 
    594         } 
    595  
    596         $qv['meta_query'] = $meta_query; 
    597     } 
    598  
    599     /* 
    600      * Used internally to generate an SQL string for searching across multiple meta key = value pairs 
    601      * 
    602      * @access protected 
    603      * @since 3.1.0 
    604      * 
    605      * @param array $meta_query List of metadata queries. A single query is an associative array: 
    606      * - 'key' string The meta key 
    607      * - 'value' string|array The meta value 
    608      * - 'compare' (optional) string How to compare the key to the value. 
    609      *      Possible values: '=', '!=', '>', '>=', '<', '<=', 'LIKE', 'NOT LIKE', 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN'. 
    610      *      Default: '=' 
    611      * - 'type' string (optional) The type of the value. 
    612      *      Possible values: 'NUMERIC', 'BINARY', 'CHAR', 'DATE', 'DATETIME', 'DECIMAL', 'SIGNED', 'TIME', 'UNSIGNED'. 
    613      *      Default: 'CHAR' 
    614      * 
    615      * @param string $primary_table 
    616      * @param string $primary_id_column 
    617      * @param string $meta_table 
    618      * @param string $meta_id_column 
    619      * @return array( $join_sql, $where_sql ) 
    620      */ 
    621     function get_meta_sql( $meta_query, $primary_table, $primary_id_column, $meta_table, $meta_id_column ) { 
    622         global $wpdb; 
    623  
    624         $clauses = array(); 
    625  
    626         $join = ''; 
    627         $where = ''; 
    628         $i = 0; 
    629         foreach ( $meta_query as $q ) { 
    630             $meta_key = isset( $q['key'] ) ? trim( $q['key'] ) : ''; 
    631             $meta_value = isset( $q['value'] ) ? $q['value'] : ''; 
    632             $meta_compare = isset( $q['compare'] ) ? strtoupper( $q['compare'] ) : '='; 
    633             $meta_type = isset( $q['type'] ) ? strtoupper( $q['type'] ) : 'CHAR'; 
    634  
    635             if ( ! in_array( $meta_compare, array( '=', '!=', '>', '>=', '<', '<=', 'LIKE', 'NOT LIKE', 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN' ) ) ) 
    636                 $meta_compare = '='; 
    637  
    638             if ( 'NUMERIC' == $meta_type ) 
    639                 $meta_type = 'SIGNED'; 
    640             elseif ( ! in_array( $meta_type, array( 'BINARY', 'CHAR', 'DATE', 'DATETIME', 'DECIMAL', 'SIGNED', 'TIME', 'UNSIGNED' ) ) ) 
    641                 $meta_type = 'CHAR'; 
    642  
    643             if ( empty( $meta_key ) && empty( $meta_value ) ) 
    644                 continue; 
    645  
    646             $alias = $i ? 'mt' . $i : $meta_table; 
    647  
    648             $join .= "\nINNER JOIN $meta_table"; 
    649             $join .= $i ? " AS $alias" : ''; 
    650             $join .= " ON ($primary_table.$primary_id_column = $alias.$meta_id_column)"; 
    651  
    652             $i++; 
    653  
    654             if ( !empty( $meta_key ) ) 
    655                 $where .= $wpdb->prepare( " AND $alias.meta_key = %s", $meta_key ); 
    656  
    657             if ( in_array( $meta_compare, array( 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN' ) ) ) { 
    658                 if ( ! is_array( $meta_value ) ) 
    659                     $meta_value = preg_split( '/[,\s]+/', $meta_value ); 
    660             } else { 
    661                 $meta_value = trim( $meta_value ); 
    662             } 
    663  
    664             if ( empty( $meta_value ) ) 
    665                 continue; 
    666  
    667             if ( 'IN' == substr( $meta_compare, -2) ) { 
    668                 $meta_field_types = substr( str_repeat( ',%s', count( $meta_value ) ), 1 ); 
    669                 $meta_compare_string = "($meta_field_types)"; 
    670                 unset( $meta_field_types ); 
    671             } elseif ( 'BETWEEN' == substr( $meta_compare, -7) ) { 
    672                 $meta_value = array_slice( $meta_value, 0, 2 ); 
    673                 $meta_compare_string = '%s AND %s'; 
    674             } elseif ( 'LIKE' == substr( $meta_compare, -4 ) ) { 
    675                 $meta_value = '%' . like_escape( $meta_value ) . '%'; 
    676                 $meta_compare_string = '%s'; 
    677             } else { 
    678                 $meta_compare_string = '%s'; 
    679             } 
    680             $where .= $wpdb->prepare( " AND CAST($alias.meta_value AS {$meta_type}) {$meta_compare} {$meta_compare_string}", $meta_value ); 
    681             unset($meta_compare_string); 
    682         } 
    683  
    684         return array( $join, $where ); 
    685     } 
    686  
    687     /* 
    688      * Used internally to generate an SQL string for searching across multiple taxonomies 
    689      * 
    690      * @access protected 
    691      * @since 3.1.0 
    692      * 
    693      * @param array $tax_query List of taxonomy queries. A single taxonomy query is an associative array: 
    694      * - 'taxonomy' string|array The taxonomy being queried 
    695      * - 'terms' string|array The list of terms 
    696      * - 'field' string (optional) Which term field is being used. 
    697      *      Possible values: 'term_id', 'slug' or 'name' 
    698      *      Default: 'slug' 
    699      * - 'operator' string (optional) 
    700      *      Possible values: 'IN' and 'NOT IN'. 
    701      *      Default: 'IN' 
    702      * - 'include_children' bool (optional) Whether to include child terms. 
    703      *      Default: true 
    704      * 
    705      * @param string $object_id_column 
    706      * @return string 
    707      */ 
    708     function get_tax_sql( $tax_query, $object_id_column ) { 
    709         global $wpdb; 
    710  
    711         $sql = array(); 
    712         foreach ( $tax_query as $query ) { 
    713             if ( !isset( $query['include_children'] ) ) 
    714                 $query['include_children'] = true; 
    715  
    716             $query['do_query'] = false; 
    717  
    718             $sql_single = get_objects_in_term( $query['terms'], $query['taxonomy'], $query ); 
    719  
    720             if ( empty( $sql_single ) ) 
    721                 return ' AND 0 = 1'; 
    722  
    723             $sql[] = $sql_single; 
    724         } 
    725  
    726         if ( 1 == count( $sql ) ) { 
    727             $ids = $wpdb->get_col( $sql[0] ); 
    728         } else { 
    729             $r = "SELECT object_id FROM $wpdb->term_relationships WHERE 1=1"; 
    730             foreach ( $sql as $query ) 
    731                 $r .= " AND object_id IN ($query)"; 
    732  
    733             $ids = $wpdb->get_col( $r ); 
    734         } 
    735  
    736         if ( !empty( $ids ) ) 
    737             return " AND $object_id_column IN(" . implode( ', ', $ids ) . ")"; 
    738         else 
    739             return ' AND 0 = 1'; 
    740     } 
    741  
    742     /* 
    743      * Used internally to generate an SQL string for searching across multiple columns 
    744      * 
    745      * @access protected 
    746      * @since 3.1.0 
    747      * 
    748      * @param string $string 
    749      * @param array $cols 
    750      * @return string 
    751      */ 
    752     function get_search_sql( $string, $cols ) { 
    753         $string = esc_sql( $string ); 
    754  
    755         $searches = array(); 
    756         foreach ( $cols as $col ) 
    757             $searches[] = "$col LIKE '%$string%'"; 
    758  
    759         return ' AND (' . implode(' OR ', $searches) . ')'; 
    760     } 
    761 } 
    762  
    763 /** 
    764528 * WordPress Error class. 
    765529 * 
  • trunk/wp-settings.php

    r15811 r16051  
    103103require( ABSPATH . WPINC . '/formatting.php' ); 
    104104require( ABSPATH . WPINC . '/capabilities.php' ); 
     105require( ABSPATH . WPINC . '/class.wp-object-query.php' ); 
    105106require( ABSPATH . WPINC . '/query.php' ); 
    106107require( ABSPATH . WPINC . '/theme.php' ); 
Note: See TracChangeset for help on using the changeset viewer.