Make WordPress Core


Ignore:
Timestamp:
08/26/2015 12:48:11 PM (9 years ago)
Author:
wonderboymusic
Message:

Taxonomy: move WP_Tax_Query into its own file. taxonomy.php loads the new files, so this is 100% BC if someone is loading taxonomy.php directly. New files created using svn cp.

Creates:
class-wp-tax-query.php
taxonomy-functions.php

taxonomy.php contains only top-level code. Class file only contains the class. Functions file only contains functions.

See #33413.

File:
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/taxonomy-functions.php

    r33758 r33760  
    652652    $tax_query_obj = new WP_Tax_Query( $tax_query );
    653653    return $tax_query_obj->get_sql( $primary_table, $primary_id_column );
    654 }
    655 
    656 /**
    657  * Class for generating SQL clauses that filter a primary query according to object taxonomy terms.
    658  *
    659  * `WP_Tax_Query` is a helper that allows primary query classes, such as WP_Query, to filter
    660  * their results by object metadata, by generating `JOIN` and `WHERE` subclauses to be attached
    661  * to the primary SQL query string.
    662  *
    663  * @since 3.1.0
    664  */
    665 class WP_Tax_Query {
    666 
    667     /**
    668      * Array of taxonomy queries.
    669      *
    670      * See {@see WP_Tax_Query::__construct()} for information on tax query arguments.
    671      *
    672      * @since 3.1.0
    673      * @access public
    674      * @var array
    675      */
    676     public $queries = array();
    677 
    678     /**
    679      * The relation between the queries. Can be one of 'AND' or 'OR'.
    680      *
    681      * @since 3.1.0
    682      * @access public
    683      * @var string
    684      */
    685     public $relation;
    686 
    687     /**
    688      * Standard response when the query should not return any rows.
    689      *
    690      * @since 3.2.0
    691      *
    692      * @static
    693      * @access private
    694      * @var string
    695      */
    696     private static $no_results = array( 'join' => array( '' ), 'where' => array( '0 = 1' ) );
    697 
    698     /**
    699      * A flat list of table aliases used in the JOIN clauses.
    700      *
    701      * @since 4.1.0
    702      * @access protected
    703      * @var array
    704      */
    705     protected $table_aliases = array();
    706 
    707     /**
    708      * Terms and taxonomies fetched by this query.
    709      *
    710      * We store this data in a flat array because they are referenced in a
    711      * number of places by WP_Query.
    712      *
    713      * @since 4.1.0
    714      * @access public
    715      * @var array
    716      */
    717     public $queried_terms = array();
    718 
    719     /**
    720      * Database table that where the metadata's objects are stored (eg $wpdb->users).
    721      *
    722      * @since 4.1.0
    723      * @access public
    724      * @var string
    725      */
    726     public $primary_table;
    727 
    728     /**
    729      * Column in 'primary_table' that represents the ID of the object.
    730      *
    731      * @since 4.1.0
    732      * @access public
    733      * @var string
    734      */
    735     public $primary_id_column;
    736 
    737     /**
    738      * Constructor.
    739      *
    740      * @since 3.1.0
    741      * @since 4.1.0 Added support for `$operator` 'NOT EXISTS' and 'EXISTS' values.
    742      * @access public
    743      *
    744      * @param array $tax_query {
    745      *     Array of taxonomy query clauses.
    746      *
    747      *     @type string $relation Optional. The MySQL keyword used to join
    748      *                            the clauses of the query. Accepts 'AND', or 'OR'. Default 'AND'.
    749      *     @type array {
    750      *         Optional. An array of first-order clause parameters, or another fully-formed tax query.
    751      *
    752      *         @type string           $taxonomy         Taxonomy being queried. Optional when field=term_taxonomy_id.
    753      *         @type string|int|array $terms            Term or terms to filter by.
    754      *         @type string           $field            Field to match $terms against. Accepts 'term_id', 'slug',
    755      *                                                 'name', or 'term_taxonomy_id'. Default: 'term_id'.
    756      *         @type string           $operator         MySQL operator to be used with $terms in the WHERE clause.
    757      *                                                  Accepts 'AND', 'IN', 'NOT IN', 'EXISTS', 'NOT EXISTS'.
    758      *                                                  Default: 'IN'.
    759      *         @type bool             $include_children Optional. Whether to include child terms.
    760      *                                                  Requires a $taxonomy. Default: true.
    761      *     }
    762      * }
    763      */
    764     public function __construct( $tax_query ) {
    765         if ( isset( $tax_query['relation'] ) ) {
    766             $this->relation = $this->sanitize_relation( $tax_query['relation'] );
    767         } else {
    768             $this->relation = 'AND';
    769         }
    770 
    771         $this->queries = $this->sanitize_query( $tax_query );
    772     }
    773 
    774     /**
    775      * Ensure the 'tax_query' argument passed to the class constructor is well-formed.
    776      *
    777      * Ensures that each query-level clause has a 'relation' key, and that
    778      * each first-order clause contains all the necessary keys from `$defaults`.
    779      *
    780      * @since 4.1.0
    781      * @access public
    782      *
    783      * @param array $queries Array of queries clauses.
    784      * @return array Sanitized array of query clauses.
    785      */
    786     public function sanitize_query( $queries ) {
    787         $cleaned_query = array();
    788 
    789         $defaults = array(
    790             'taxonomy' => '',
    791             'terms' => array(),
    792             'field' => 'term_id',
    793             'operator' => 'IN',
    794             'include_children' => true,
    795         );
    796 
    797         foreach ( $queries as $key => $query ) {
    798             if ( 'relation' === $key ) {
    799                 $cleaned_query['relation'] = $this->sanitize_relation( $query );
    800 
    801             // First-order clause.
    802             } elseif ( self::is_first_order_clause( $query ) ) {
    803 
    804                 $cleaned_clause = array_merge( $defaults, $query );
    805                 $cleaned_clause['terms'] = (array) $cleaned_clause['terms'];
    806                 $cleaned_query[] = $cleaned_clause;
    807 
    808                 /*
    809                  * Keep a copy of the clause in the flate
    810                  * $queried_terms array, for use in WP_Query.
    811                  */
    812                 if ( ! empty( $cleaned_clause['taxonomy'] ) && 'NOT IN' !== $cleaned_clause['operator'] ) {
    813                     $taxonomy = $cleaned_clause['taxonomy'];
    814                     if ( ! isset( $this->queried_terms[ $taxonomy ] ) ) {
    815                         $this->queried_terms[ $taxonomy ] = array();
    816                     }
    817 
    818                     /*
    819                      * Backward compatibility: Only store the first
    820                      * 'terms' and 'field' found for a given taxonomy.
    821                      */
    822                     if ( ! empty( $cleaned_clause['terms'] ) && ! isset( $this->queried_terms[ $taxonomy ]['terms'] ) ) {
    823                         $this->queried_terms[ $taxonomy ]['terms'] = $cleaned_clause['terms'];
    824                     }
    825 
    826                     if ( ! empty( $cleaned_clause['field'] ) && ! isset( $this->queried_terms[ $taxonomy ]['field'] ) ) {
    827                         $this->queried_terms[ $taxonomy ]['field'] = $cleaned_clause['field'];
    828                     }
    829                 }
    830 
    831             // Otherwise, it's a nested query, so we recurse.
    832             } elseif ( is_array( $query ) ) {
    833                 $cleaned_subquery = $this->sanitize_query( $query );
    834 
    835                 if ( ! empty( $cleaned_subquery ) ) {
    836                     // All queries with children must have a relation.
    837                     if ( ! isset( $cleaned_subquery['relation'] ) ) {
    838                         $cleaned_subquery['relation'] = 'AND';
    839                     }
    840 
    841                     $cleaned_query[] = $cleaned_subquery;
    842                 }
    843             }
    844         }
    845 
    846         return $cleaned_query;
    847     }
    848 
    849     /**
    850      * Sanitize a 'relation' operator.
    851      *
    852      * @since 4.1.0
    853      * @access public
    854      *
    855      * @param string $relation Raw relation key from the query argument.
    856      * @return string Sanitized relation ('AND' or 'OR').
    857      */
    858     public function sanitize_relation( $relation ) {
    859         if ( 'OR' === strtoupper( $relation ) ) {
    860             return 'OR';
    861         } else {
    862             return 'AND';
    863         }
    864     }
    865 
    866     /**
    867      * Determine whether a clause is first-order.
    868      *
    869      * A "first-order" clause is one that contains any of the first-order
    870      * clause keys ('terms', 'taxonomy', 'include_children', 'field',
    871      * 'operator'). An empty clause also counts as a first-order clause,
    872      * for backward compatibility. Any clause that doesn't meet this is
    873      * determined, by process of elimination, to be a higher-order query.
    874      *
    875      * @since 4.1.0
    876      *
    877      * @static
    878      * @access protected
    879      *
    880      * @param array $query Tax query arguments.
    881      * @return bool Whether the query clause is a first-order clause.
    882      */
    883     protected static function is_first_order_clause( $query ) {
    884         return is_array( $query ) && ( empty( $query ) || array_key_exists( 'terms', $query ) || array_key_exists( 'taxonomy', $query ) || array_key_exists( 'include_children', $query ) || array_key_exists( 'field', $query ) || array_key_exists( 'operator', $query ) );
    885     }
    886 
    887     /**
    888      * Generates SQL clauses to be appended to a main query.
    889      *
    890      * @since 3.1.0
    891      *
    892      * @static
    893      * @access public
    894      *
    895      * @param string $primary_table     Database table where the object being filtered is stored (eg wp_users).
    896      * @param string $primary_id_column ID column for the filtered object in $primary_table.
    897      * @return array {
    898      *     Array containing JOIN and WHERE SQL clauses to append to the main query.
    899      *
    900      *     @type string $join  SQL fragment to append to the main JOIN clause.
    901      *     @type string $where SQL fragment to append to the main WHERE clause.
    902      * }
    903      */
    904     public function get_sql( $primary_table, $primary_id_column ) {
    905         $this->primary_table = $primary_table;
    906         $this->primary_id_column = $primary_id_column;
    907 
    908         return $this->get_sql_clauses();
    909     }
    910 
    911     /**
    912      * Generate SQL clauses to be appended to a main query.
    913      *
    914      * Called by the public WP_Tax_Query::get_sql(), this method
    915      * is abstracted out to maintain parity with the other Query classes.
    916      *
    917      * @since 4.1.0
    918      * @access protected
    919      *
    920      * @return array {
    921      *     Array containing JOIN and WHERE SQL clauses to append to the main query.
    922      *
    923      *     @type string $join  SQL fragment to append to the main JOIN clause.
    924      *     @type string $where SQL fragment to append to the main WHERE clause.
    925      * }
    926      */
    927     protected function get_sql_clauses() {
    928         /*
    929          * $queries are passed by reference to get_sql_for_query() for recursion.
    930          * To keep $this->queries unaltered, pass a copy.
    931          */
    932         $queries = $this->queries;
    933         $sql = $this->get_sql_for_query( $queries );
    934 
    935         if ( ! empty( $sql['where'] ) ) {
    936             $sql['where'] = ' AND ' . $sql['where'];
    937         }
    938 
    939         return $sql;
    940     }
    941 
    942     /**
    943      * Generate SQL clauses for a single query array.
    944      *
    945      * If nested subqueries are found, this method recurses the tree to
    946      * produce the properly nested SQL.
    947      *
    948      * @since 4.1.0
    949      * @access protected
    950      *
    951      * @param array $query Query to parse, passed by reference.
    952      * @param int   $depth Optional. Number of tree levels deep we currently are.
    953      *                     Used to calculate indentation. Default 0.
    954      * @return array {
    955      *     Array containing JOIN and WHERE SQL clauses to append to a single query array.
    956      *
    957      *     @type string $join  SQL fragment to append to the main JOIN clause.
    958      *     @type string $where SQL fragment to append to the main WHERE clause.
    959      * }
    960      */
    961     protected function get_sql_for_query( &$query, $depth = 0 ) {
    962         $sql_chunks = array(
    963             'join'  => array(),
    964             'where' => array(),
    965         );
    966 
    967         $sql = array(
    968             'join'  => '',
    969             'where' => '',
    970         );
    971 
    972         $indent = '';
    973         for ( $i = 0; $i < $depth; $i++ ) {
    974             $indent .= "  ";
    975         }
    976 
    977         foreach ( $query as $key => &$clause ) {
    978             if ( 'relation' === $key ) {
    979                 $relation = $query['relation'];
    980             } elseif ( is_array( $clause ) ) {
    981 
    982                 // This is a first-order clause.
    983                 if ( $this->is_first_order_clause( $clause ) ) {
    984                     $clause_sql = $this->get_sql_for_clause( $clause, $query );
    985 
    986                     $where_count = count( $clause_sql['where'] );
    987                     if ( ! $where_count ) {
    988                         $sql_chunks['where'][] = '';
    989                     } elseif ( 1 === $where_count ) {
    990                         $sql_chunks['where'][] = $clause_sql['where'][0];
    991                     } else {
    992                         $sql_chunks['where'][] = '( ' . implode( ' AND ', $clause_sql['where'] ) . ' )';
    993                     }
    994 
    995                     $sql_chunks['join'] = array_merge( $sql_chunks['join'], $clause_sql['join'] );
    996                 // This is a subquery, so we recurse.
    997                 } else {
    998                     $clause_sql = $this->get_sql_for_query( $clause, $depth + 1 );
    999 
    1000                     $sql_chunks['where'][] = $clause_sql['where'];
    1001                     $sql_chunks['join'][]  = $clause_sql['join'];
    1002                 }
    1003             }
    1004         }
    1005 
    1006         // Filter to remove empties.
    1007         $sql_chunks['join']  = array_filter( $sql_chunks['join'] );
    1008         $sql_chunks['where'] = array_filter( $sql_chunks['where'] );
    1009 
    1010         if ( empty( $relation ) ) {
    1011             $relation = 'AND';
    1012         }
    1013 
    1014         // Filter duplicate JOIN clauses and combine into a single string.
    1015         if ( ! empty( $sql_chunks['join'] ) ) {
    1016             $sql['join'] = implode( ' ', array_unique( $sql_chunks['join'] ) );
    1017         }
    1018 
    1019         // Generate a single WHERE clause with proper brackets and indentation.
    1020         if ( ! empty( $sql_chunks['where'] ) ) {
    1021             $sql['where'] = '( ' . "\n  " . $indent . implode( ' ' . "\n  " . $indent . $relation . ' ' . "\n  " . $indent, $sql_chunks['where'] ) . "\n" . $indent . ')';
    1022         }
    1023 
    1024         return $sql;
    1025     }
    1026 
    1027     /**
    1028      * Generate SQL JOIN and WHERE clauses for a "first-order" query clause.
    1029      *
    1030      * @since 4.1.0
    1031      * @access public
    1032      *
    1033      * @global wpdb $wpdb The WordPress database abstraction object.
    1034      *
    1035      * @param array $clause       Query clause, passed by reference.
    1036      * @param array $parent_query Parent query array.
    1037      * @return array {
    1038      *     Array containing JOIN and WHERE SQL clauses to append to a first-order query.
    1039      *
    1040      *     @type string $join  SQL fragment to append to the main JOIN clause.
    1041      *     @type string $where SQL fragment to append to the main WHERE clause.
    1042      * }
    1043      */
    1044     public function get_sql_for_clause( &$clause, $parent_query ) {
    1045         global $wpdb;
    1046 
    1047         $sql = array(
    1048             'where' => array(),
    1049             'join'  => array(),
    1050         );
    1051 
    1052         $join = $where = '';
    1053 
    1054         $this->clean_query( $clause );
    1055 
    1056         if ( is_wp_error( $clause ) ) {
    1057             return self::$no_results;
    1058         }
    1059 
    1060         $terms = $clause['terms'];
    1061         $operator = strtoupper( $clause['operator'] );
    1062 
    1063         if ( 'IN' == $operator ) {
    1064 
    1065             if ( empty( $terms ) ) {
    1066                 return self::$no_results;
    1067             }
    1068 
    1069             $terms = implode( ',', $terms );
    1070 
    1071             /*
    1072              * Before creating another table join, see if this clause has a
    1073              * sibling with an existing join that can be shared.
    1074              */
    1075             $alias = $this->find_compatible_table_alias( $clause, $parent_query );
    1076             if ( false === $alias ) {
    1077                 $i = count( $this->table_aliases );
    1078                 $alias = $i ? 'tt' . $i : $wpdb->term_relationships;
    1079 
    1080                 // Store the alias as part of a flat array to build future iterators.
    1081                 $this->table_aliases[] = $alias;
    1082 
    1083                 // Store the alias with this clause, so later siblings can use it.
    1084                 $clause['alias'] = $alias;
    1085 
    1086                 $join .= " INNER JOIN $wpdb->term_relationships";
    1087                 $join .= $i ? " AS $alias" : '';
    1088                 $join .= " ON ($this->primary_table.$this->primary_id_column = $alias.object_id)";
    1089             }
    1090 
    1091 
    1092             $where = "$alias.term_taxonomy_id $operator ($terms)";
    1093 
    1094         } elseif ( 'NOT IN' == $operator ) {
    1095 
    1096             if ( empty( $terms ) ) {
    1097                 return $sql;
    1098             }
    1099 
    1100             $terms = implode( ',', $terms );
    1101 
    1102             $where = "$this->primary_table.$this->primary_id_column NOT IN (
    1103                 SELECT object_id
    1104                 FROM $wpdb->term_relationships
    1105                 WHERE term_taxonomy_id IN ($terms)
    1106             )";
    1107 
    1108         } elseif ( 'AND' == $operator ) {
    1109 
    1110             if ( empty( $terms ) ) {
    1111                 return $sql;
    1112             }
    1113 
    1114             $num_terms = count( $terms );
    1115 
    1116             $terms = implode( ',', $terms );
    1117 
    1118             $where = "(
    1119                 SELECT COUNT(1)
    1120                 FROM $wpdb->term_relationships
    1121                 WHERE term_taxonomy_id IN ($terms)
    1122                 AND object_id = $this->primary_table.$this->primary_id_column
    1123             ) = $num_terms";
    1124 
    1125         } elseif ( 'NOT EXISTS' === $operator || 'EXISTS' === $operator ) {
    1126 
    1127             $where = $wpdb->prepare( "$operator (
    1128                 SELECT 1
    1129                 FROM $wpdb->term_relationships
    1130                 INNER JOIN $wpdb->term_taxonomy
    1131                 ON $wpdb->term_taxonomy.term_taxonomy_id = $wpdb->term_relationships.term_taxonomy_id
    1132                 WHERE $wpdb->term_taxonomy.taxonomy = %s
    1133                 AND $wpdb->term_relationships.object_id = $this->primary_table.$this->primary_id_column
    1134             )", $clause['taxonomy'] );
    1135 
    1136         }
    1137 
    1138         $sql['join'][]  = $join;
    1139         $sql['where'][] = $where;
    1140         return $sql;
    1141     }
    1142 
    1143     /**
    1144      * Identify an existing table alias that is compatible with the current query clause.
    1145      *
    1146      * We avoid unnecessary table joins by allowing each clause to look for
    1147      * an existing table alias that is compatible with the query that it
    1148      * needs to perform.
    1149      *
    1150      * An existing alias is compatible if (a) it is a sibling of `$clause`
    1151      * (ie, it's under the scope of the same relation), and (b) the combination
    1152      * of operator and relation between the clauses allows for a shared table
    1153      * join. In the case of WP_Tax_Query, this only applies to 'IN'
    1154      * clauses that are connected by the relation 'OR'.
    1155      *
    1156      * @since 4.1.0
    1157      * @access protected
    1158      *
    1159      * @param array       $clause       Query clause.
    1160      * @param array       $parent_query Parent query of $clause.
    1161      * @return string|false Table alias if found, otherwise false.
    1162      */
    1163     protected function find_compatible_table_alias( $clause, $parent_query ) {
    1164         $alias = false;
    1165 
    1166         // Sanity check. Only IN queries use the JOIN syntax .
    1167         if ( ! isset( $clause['operator'] ) || 'IN' !== $clause['operator'] ) {
    1168             return $alias;
    1169         }
    1170 
    1171         // Since we're only checking IN queries, we're only concerned with OR relations.
    1172         if ( ! isset( $parent_query['relation'] ) || 'OR' !== $parent_query['relation'] ) {
    1173             return $alias;
    1174         }
    1175 
    1176         $compatible_operators = array( 'IN' );
    1177 
    1178         foreach ( $parent_query as $sibling ) {
    1179             if ( ! is_array( $sibling ) || ! $this->is_first_order_clause( $sibling ) ) {
    1180                 continue;
    1181             }
    1182 
    1183             if ( empty( $sibling['alias'] ) || empty( $sibling['operator'] ) ) {
    1184                 continue;
    1185             }
    1186 
    1187             // The sibling must both have compatible operator to share its alias.
    1188             if ( in_array( strtoupper( $sibling['operator'] ), $compatible_operators ) ) {
    1189                 $alias = $sibling['alias'];
    1190                 break;
    1191             }
    1192         }
    1193 
    1194         return $alias;
    1195     }
    1196 
    1197     /**
    1198      * Validates a single query.
    1199      *
    1200      * @since 3.2.0
    1201      * @access private
    1202      *
    1203      * @param array &$query The single query.
    1204      */
    1205     private function clean_query( &$query ) {
    1206         if ( empty( $query['taxonomy'] ) ) {
    1207             if ( 'term_taxonomy_id' !== $query['field'] ) {
    1208                 $query = new WP_Error( 'Invalid taxonomy' );
    1209                 return;
    1210             }
    1211 
    1212             // so long as there are shared terms, include_children requires that a taxonomy is set
    1213             $query['include_children'] = false;
    1214         } elseif ( ! taxonomy_exists( $query['taxonomy'] ) ) {
    1215             $query = new WP_Error( 'Invalid taxonomy' );
    1216             return;
    1217         }
    1218 
    1219         $query['terms'] = array_unique( (array) $query['terms'] );
    1220 
    1221         if ( is_taxonomy_hierarchical( $query['taxonomy'] ) && $query['include_children'] ) {
    1222             $this->transform_query( $query, 'term_id' );
    1223 
    1224             if ( is_wp_error( $query ) )
    1225                 return;
    1226 
    1227             $children = array();
    1228             foreach ( $query['terms'] as $term ) {
    1229                 $children = array_merge( $children, get_term_children( $term, $query['taxonomy'] ) );
    1230                 $children[] = $term;
    1231             }
    1232             $query['terms'] = $children;
    1233         }
    1234 
    1235         $this->transform_query( $query, 'term_taxonomy_id' );
    1236     }
    1237 
    1238     /**
    1239      * Transforms a single query, from one field to another.
    1240      *
    1241      * @since 3.2.0
    1242      *
    1243      * @global wpdb $wpdb The WordPress database abstraction object.
    1244      *
    1245      * @param array  &$query          The single query.
    1246      * @param string $resulting_field The resulting field. Accepts 'slug', 'name', 'term_taxonomy_id',
    1247      *                                or 'term_id'. Default 'term_id'.
    1248      */
    1249     public function transform_query( &$query, $resulting_field ) {
    1250         global $wpdb;
    1251 
    1252         if ( empty( $query['terms'] ) )
    1253             return;
    1254 
    1255         if ( $query['field'] == $resulting_field )
    1256             return;
    1257 
    1258         $resulting_field = sanitize_key( $resulting_field );
    1259 
    1260         switch ( $query['field'] ) {
    1261             case 'slug':
    1262             case 'name':
    1263                 foreach ( $query['terms'] as &$term ) {
    1264                     /*
    1265                      * 0 is the $term_id parameter. We don't have a term ID yet, but it doesn't
    1266                      * matter because `sanitize_term_field()` ignores the $term_id param when the
    1267                      * context is 'db'.
    1268                      */
    1269                     $term = "'" . esc_sql( sanitize_term_field( $query['field'], $term, 0, $query['taxonomy'], 'db' ) ) . "'";
    1270                 }
    1271 
    1272                 $terms = implode( ",", $query['terms'] );
    1273 
    1274                 $terms = $wpdb->get_col( "
    1275                     SELECT $wpdb->term_taxonomy.$resulting_field
    1276                     FROM $wpdb->term_taxonomy
    1277                     INNER JOIN $wpdb->terms USING (term_id)
    1278                     WHERE taxonomy = '{$query['taxonomy']}'
    1279                     AND $wpdb->terms.{$query['field']} IN ($terms)
    1280                 " );
    1281                 break;
    1282             case 'term_taxonomy_id':
    1283                 $terms = implode( ',', array_map( 'intval', $query['terms'] ) );
    1284                 $terms = $wpdb->get_col( "
    1285                     SELECT $resulting_field
    1286                     FROM $wpdb->term_taxonomy
    1287                     WHERE term_taxonomy_id IN ($terms)
    1288                 " );
    1289                 break;
    1290             default:
    1291                 $terms = implode( ',', array_map( 'intval', $query['terms'] ) );
    1292                 $terms = $wpdb->get_col( "
    1293                     SELECT $resulting_field
    1294                     FROM $wpdb->term_taxonomy
    1295                     WHERE taxonomy = '{$query['taxonomy']}'
    1296                     AND term_id IN ($terms)
    1297                 " );
    1298         }
    1299 
    1300         if ( 'AND' == $query['operator'] && count( $terms ) < count( $query['terms'] ) ) {
    1301             $query = new WP_Error( 'Inexistent terms' );
    1302             return;
    1303         }
    1304 
    1305         $query['terms'] = $terms;
    1306         $query['field'] = $resulting_field;
    1307     }
    1308654}
    1309655
Note: See TracChangeset for help on using the changeset viewer.