WordPressを読む 27-4 /blog/wp-includes/query.php 4
2014/12/11
目次
/blog/wp-includes/query.php 4
WP_Query::parse_tax_query()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 | /** * Parses various taxonomy related query vars. * * For BC, this method is not marked as protected. See [28987]. * * @access protected * @since 3.1.0 * * @param array &$q The query variables */ function parse_tax_query( &$q ) { if ( ! empty( $q['tax_query'] ) && is_array( $q['tax_query'] ) ) { $tax_query = $q['tax_query']; } else { $tax_query = array(); } if ( !empty($q['taxonomy']) && !empty($q['term']) ) { $tax_query[] = array( 'taxonomy' => $q['taxonomy'], 'terms' => array( $q['term'] ), 'field' => 'slug', ); } foreach ( get_taxonomies( array() , 'objects' ) as $taxonomy => $t ) { if ( 'post_tag' == $taxonomy ) continue; // Handled further down in the $q['tag'] block if ( $t->query_var && !empty( $q[$t->query_var] ) ) { $tax_query_defaults = array( 'taxonomy' => $taxonomy, 'field' => 'slug', ); if ( isset( $t->rewrite['hierarchical'] ) && $t->rewrite['hierarchical'] ) { $q[$t->query_var] = wp_basename( $q[$t->query_var] ); } $term = $q[$t->query_var]; if ( strpos($term, '+') !== false ) { $terms = preg_split( '/[+]+/', $term ); foreach ( $terms as $term ) { $tax_query[] = array_merge( $tax_query_defaults, array( 'terms' => array( $term ) ) ); } } else { $tax_query[] = array_merge( $tax_query_defaults, array( 'terms' => preg_split( '/[,]+/', $term ) ) ); } } } // Category stuff if ( ! empty( $q['cat'] ) && ! $this->is_singular ) { $cat_in = $cat_not_in = array(); $cat_array = preg_split( '/[,\s]+/', urldecode( $q['cat'] ) ); $cat_array = array_map( 'intval', $cat_array ); $q['cat'] = implode( ',', $cat_array ); foreach ( $cat_array as $cat ) { if ( $cat > 0 ) $cat_in[] = $cat; elseif ( $cat < 0 ) $cat_not_in[] = abs( $cat ); } if ( ! empty( $cat_in ) ) { $tax_query[] = array( 'taxonomy' => 'category', 'terms' => $cat_in, 'field' => 'term_id', 'include_children' => true ); } if ( ! empty( $cat_not_in ) ) { $tax_query[] = array( 'taxonomy' => 'category', 'terms' => $cat_not_in, 'field' => 'term_id', 'operator' => 'NOT IN', 'include_children' => true ); } unset( $cat_array, $cat_in, $cat_not_in ); } if ( ! empty( $q['category__and'] ) && 1 === count( (array) $q['category__and'] ) ) { $q['category__and'] = (array) $q['category__and']; if ( ! isset( $q['category__in'] ) ) $q['category__in'] = array(); $q['category__in'][] = absint( reset( $q['category__and'] ) ); unset( $q['category__and'] ); } if ( ! empty( $q['category__in'] ) ) { $q['category__in'] = array_map( 'absint', array_unique( (array) $q['category__in'] ) ); $tax_query[] = array( 'taxonomy' => 'category', 'terms' => $q['category__in'], 'field' => 'term_id', 'include_children' => false ); } if ( ! empty($q['category__not_in']) ) { $q['category__not_in'] = array_map( 'absint', array_unique( (array) $q['category__not_in'] ) ); $tax_query[] = array( 'taxonomy' => 'category', 'terms' => $q['category__not_in'], 'operator' => 'NOT IN', 'include_children' => false ); } if ( ! empty($q['category__and']) ) { $q['category__and'] = array_map( 'absint', array_unique( (array) $q['category__and'] ) ); $tax_query[] = array( 'taxonomy' => 'category', 'terms' => $q['category__and'], 'field' => 'term_id', 'operator' => 'AND', 'include_children' => false ); } // Tag stuff if ( '' != $q['tag'] && !$this->is_singular && $this->query_vars_changed ) { if ( strpos($q['tag'], ',') !== false ) { $tags = preg_split('/[,\r\n\t ]+/', $q['tag']); foreach ( (array) $tags as $tag ) { $tag = sanitize_term_field('slug', $tag, 0, 'post_tag', 'db'); $q['tag_slug__in'][] = $tag; } } else if ( preg_match('/[+\r\n\t ]+/', $q['tag']) || !empty($q['cat']) ) { $tags = preg_split('/[+\r\n\t ]+/', $q['tag']); foreach ( (array) $tags as $tag ) { $tag = sanitize_term_field('slug', $tag, 0, 'post_tag', 'db'); $q['tag_slug__and'][] = $tag; } } else { $q['tag'] = sanitize_term_field('slug', $q['tag'], 0, 'post_tag', 'db'); $q['tag_slug__in'][] = $q['tag']; } } if ( !empty($q['tag_id']) ) { $q['tag_id'] = absint( $q['tag_id'] ); $tax_query[] = array( 'taxonomy' => 'post_tag', 'terms' => $q['tag_id'] ); } if ( !empty($q['tag__in']) ) { $q['tag__in'] = array_map('absint', array_unique( (array) $q['tag__in'] ) ); $tax_query[] = array( 'taxonomy' => 'post_tag', 'terms' => $q['tag__in'] ); } if ( !empty($q['tag__not_in']) ) { $q['tag__not_in'] = array_map('absint', array_unique( (array) $q['tag__not_in'] ) ); $tax_query[] = array( 'taxonomy' => 'post_tag', 'terms' => $q['tag__not_in'], 'operator' => 'NOT IN' ); } if ( !empty($q['tag__and']) ) { $q['tag__and'] = array_map('absint', array_unique( (array) $q['tag__and'] ) ); $tax_query[] = array( 'taxonomy' => 'post_tag', 'terms' => $q['tag__and'], 'operator' => 'AND' ); } if ( !empty($q['tag_slug__in']) ) { $q['tag_slug__in'] = array_map('sanitize_title_for_query', array_unique( (array) $q['tag_slug__in'] ) ); $tax_query[] = array( 'taxonomy' => 'post_tag', 'terms' => $q['tag_slug__in'], 'field' => 'slug' ); } if ( !empty($q['tag_slug__and']) ) { $q['tag_slug__and'] = array_map('sanitize_title_for_query', array_unique( (array) $q['tag_slug__and'] ) ); $tax_query[] = array( 'taxonomy' => 'post_tag', 'terms' => $q['tag_slug__and'], 'field' => 'slug', 'operator' => 'AND' ); } $this->tax_query = new WP_Tax_Query( $tax_query ); /** * Fires after taxonomy-related query vars have been parsed. * * @since 3.7.0 * * @param WP_Query $this The WP_Query instance. */ do_action( 'parse_tax_query', $this ); } |
WP_Query::parse_search()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | /** * Generate SQL for the WHERE clause based on passed search terms. * * @since 3.7.0 * * @global wpdb $wpdb * @param array $q Query variables. * @return string WHERE clause. */ protected function parse_search( &$q ) { global $wpdb; $search = ''; // added slashes screw with quote grouping when done early, so done later $q['s'] = stripslashes( $q['s'] ); if ( empty( $_GET['s'] ) && $this->is_main_query() ) $q['s'] = urldecode( $q['s'] ); // there are no line breaks in <input /> fields $q['s'] = str_replace( array( "\r", "\n" ), '', $q['s'] ); $q['search_terms_count'] = 1; if ( ! empty( $q['sentence'] ) ) { $q['search_terms'] = array( $q['s'] ); } else { if ( preg_match_all( '/".*?("|$)|((?<=[\t ",+])|^)[^\t ",+]+/', $q['s'], $matches ) ) { $q['search_terms_count'] = count( $matches[0] ); $q['search_terms'] = $this->parse_search_terms( $matches[0] ); // if the search string has only short terms or stopwords, or is 10+ terms long, match it as sentence if ( empty( $q['search_terms'] ) || count( $q['search_terms'] ) > 9 ) $q['search_terms'] = array( $q['s'] ); } else { $q['search_terms'] = array( $q['s'] ); } } $n = ! empty( $q['exact'] ) ? '' : '%'; $searchand = ''; $q['search_orderby_title'] = array(); foreach ( $q['search_terms'] as $term ) { if ( $n ) { $like = '%' . $wpdb->esc_like( $term ) . '%'; $q['search_orderby_title'][] = $wpdb->prepare( "$wpdb->posts.post_title LIKE %s", $like ); } $like = $n . $wpdb->esc_like( $term ) . $n; $search .= $wpdb->prepare( "{$searchand}(($wpdb->posts.post_title LIKE %s) OR ($wpdb->posts.post_content LIKE %s))", $like, $like ); $searchand = ' AND '; } if ( ! empty( $search ) ) { $search = " AND ({$search}) "; if ( ! is_user_logged_in() ) $search .= " AND ($wpdb->posts.post_password = '') "; } return $search; } |
WP_Query::parse_search_terms()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | /** * Check if the terms are suitable for searching. * * Uses an array of stopwords (terms) that are excluded from the separate * term matching when searching for posts. The list of English stopwords is * the approximate search engines list, and is translatable. * * @since 3.7.0 * * @param array Terms to check. * @return array Terms that are not stopwords. */ protected function parse_search_terms( $terms ) { $strtolower = function_exists( 'mb_strtolower' ) ? 'mb_strtolower' : 'strtolower'; $checked = array(); $stopwords = $this->get_search_stopwords(); foreach ( $terms as $term ) { // keep before/after spaces when term is for exact match if ( preg_match( '/^".+"$/', $term ) ) $term = trim( $term, "\"'" ); else $term = trim( $term, "\"' " ); // Avoid single A-Z. if ( ! $term || ( 1 === strlen( $term ) && preg_match( '/^[a-z]$/i', $term ) ) ) continue; if ( in_array( call_user_func( $strtolower, $term ), $stopwords, true ) ) continue; $checked[] = $term; } return $checked; } |
WP_Query::get_search_stopwords()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | /** * Retrieve stopwords used when parsing search terms. * * @since 3.7.0 * * @return array Stopwords. */ protected function get_search_stopwords() { if ( isset( $this->stopwords ) ) return $this->stopwords; /* translators: This is a comma-separated list of very common words that should be excluded from a search, * like a, an, and the. These are usually called "stopwords". You should not simply translate these individual * words into your language. Instead, look for and provide commonly accepted stopwords in your language. */ $words = explode( ',', _x( 'about,an,are,as,at,be,by,com,for,from,how,in,is,it,of,on,or,that,the,this,to,was,what,when,where,who,will,with,www', 'Comma-separated list of search stopwords in your language' ) ); $stopwords = array(); foreach( $words as $word ) { $word = trim( $word, "\r\n\t " ); if ( $word ) $stopwords[] = $word; } /** * Filter stopwords used when parsing search terms. * * @since 3.7.0 * * @param array $stopwords Stopwords. */ $this->stopwords = apply_filters( 'wp_search_stopwords', $stopwords ); return $this->stopwords; } |
WP_Query::parse_search_order()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | /** * Generate SQL for the ORDER BY condition based on passed search terms. * * @global wpdb $wpdb * @param array $q Query variables. * @return string ORDER BY clause. */ protected function parse_search_order( &$q ) { global $wpdb; if ( $q['search_terms_count'] > 1 ) { $num_terms = count( $q['search_orderby_title'] ); $like = '%' . $wpdb->esc_like( $q['s'] ) . '%'; $search_orderby = '(CASE '; // sentence match in 'post_title' $search_orderby .= $wpdb->prepare( "WHEN $wpdb->posts.post_title LIKE %s THEN 1 ", $like ); // sanity limit, sort as sentence when more than 6 terms // (few searches are longer than 6 terms and most titles are not) if ( $num_terms < 7 ) { // all words in title $search_orderby .= 'WHEN ' . implode( ' AND ', $q['search_orderby_title'] ) . ' THEN 2 '; // any word in title, not needed when $num_terms == 1 if ( $num_terms > 1 ) $search_orderby .= 'WHEN ' . implode( ' OR ', $q['search_orderby_title'] ) . ' THEN 3 '; } // sentence match in 'post_content' $search_orderby .= $wpdb->prepare( "WHEN $wpdb->posts.post_content LIKE %s THEN 4 ", $like ); $search_orderby .= 'ELSE 5 END)'; } else { // single word or sentence search $search_orderby = reset( $q['search_orderby_title'] ) . ' DESC'; } return $search_orderby; } |