Ticket #12891: scale.12891.3.diff

File scale.12891.3.diff, 7.3 KB (added by scribu, 3 years ago)

Use term_taxonomy_id directly

Line 
1Index: wp-includes/taxonomy.php
2===================================================================
3--- wp-includes/taxonomy.php    (revision 16403)
4+++ wp-includes/taxonomy.php    (working copy)
5@@ -460,98 +460,43 @@
6  * @uses $wpdb
7  * @uses wp_parse_args() Creates an array from string $args.
8  *
9- * @param mixed $terms Term id/slug/name or array of such to match against
10+ * @param int|array $term_ids Term id or array of term ids of terms that will be used
11  * @param string|array $taxonomies String of taxonomy name or Array of string values of taxonomy names
12- * @param array|string $args
13- *   'include_children' bool Whether to include term children (hierarchical taxonomies only)
14- *   'field' string Which term field is being used. Can be 'term_id', 'slug' or 'name'
15- *   'operator' string Can be 'IN' and 'NOT IN'
16- *   'do_query' bool Whether to execute the query or return the SQL string
17- *
18- * @return WP_Error If the taxonomy does not exist
19- * @return array The list of found object_ids
20- * @return string The SQL string, if do_query is set to false
21+ * @param array|string $args Change the order of the object_ids, either ASC or DESC
22+ * @return WP_Error|array If the taxonomy does not exist, then WP_Error will be returned. On success
23+ *     the array can be empty meaning that there are no $object_ids found or it will return the $object_ids found.
24  */
25-function get_objects_in_term( $terms, $taxonomies, $args = array() ) {
26+function get_objects_in_term( $term_ids, $taxonomies, $args = array() ) {
27        global $wpdb;
28 
29-       extract( wp_parse_args( $args, array(
30-               'include_children' => false,
31-               'field' => 'term_id',
32-               'operator' => 'IN',
33-               'do_query' => true,
34-       ) ), EXTR_SKIP );
35+       if ( ! is_array( $term_ids ) )
36+               $term_ids = array( $term_ids );
37 
38-       $taxonomies = (array) $taxonomies;
39+       if ( ! is_array( $taxonomies ) )
40+               $taxonomies = array( $taxonomies );
41 
42-       foreach ( $taxonomies as $taxonomy ) {
43+       foreach ( (array) $taxonomies as $taxonomy ) {
44                if ( ! taxonomy_exists( $taxonomy ) )
45-                       return new WP_Error( 'invalid_taxonomy', sprintf( __( 'Invalid Taxonomy: %s' ), $taxonomy ) );
46+                       return new WP_Error( 'invalid_taxonomy', __( 'Invalid Taxonomy' ) );
47        }
48 
49-       if ( !in_array( $field, array( 'term_id', 'slug', 'name' ) ) )
50-               $field = 'term_id';
51+       $defaults = array( 'order' => 'ASC' );
52+       $args = wp_parse_args( $args, $defaults );
53+       extract( $args, EXTR_SKIP );
54 
55-       if ( !in_array( $operator, array( 'IN', 'NOT IN' ) ) )
56-               $operator = 'IN';
57+       $order = ( 'desc' == strtolower( $order ) ) ? 'DESC' : 'ASC';
58 
59-       $terms = array_unique( (array) $terms );
60+       $term_ids = array_map('intval', $term_ids );
61 
62-       if ( is_taxonomy_hierarchical( $taxonomy ) && $include_children ) {
63-               $children = array();
64-               foreach ( $terms as $term ) {
65-                       if ( 'term_id' != $field ) {
66-                               if ( $term = get_term_by( $field, $term, $taxonomy ) )
67-                                       $term = $term->term_id;
68-                               else
69-                                       continue;
70-                       }
71-                       $children = array_merge( $children, get_term_children( $term, $taxonomy ) );
72-                       $children[] = $term;
73-               }
74-               $terms = $children;
75-               $field = 'term_id';
76-       }
77-
78-       if ( empty( $terms ) )
79-               return $do_query ? array() : '';
80-
81        $taxonomies = "'" . implode( "', '", $taxonomies ) . "'";
82+       $term_ids = "'" . implode( "', '", $term_ids ) . "'";
83 
84-       switch ( $field ) {
85-               case 'term_id':
86-                       $terms = array_map( 'intval', $terms );
87+       $object_ids = $wpdb->get_col("SELECT tr.object_id FROM $wpdb->term_relationships AS tr INNER JOIN $wpdb->term_taxonomy AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tt.taxonomy IN ($taxonomies) AND tt.term_id IN ($term_ids) ORDER BY tr.object_id $order");
88 
89-                       $terms = implode( ',', $terms );
90-                       $sql = "
91-                               SELECT object_id
92-                               FROM $wpdb->term_relationships
93-                               INNER JOIN $wpdb->term_taxonomy USING (term_taxonomy_id)
94-                               WHERE taxonomy IN ($taxonomies)
95-                               AND term_id $operator ($terms)
96-                       ";
97-               break;
98+       if ( ! $object_ids )
99+               return array();
100 
101-               case 'slug':
102-               case 'name':
103-                       foreach ( $terms as $i => $term ) {
104-                               $terms[$i] = sanitize_title_for_query( $term );
105-                       }
106-                       $terms = array_filter($terms);
107-
108-                       $terms = "'" . implode( "','", $terms ) . "'";
109-                       $sql = "
110-                               SELECT object_id
111-                               FROM $wpdb->term_relationships
112-                               INNER JOIN $wpdb->term_taxonomy USING (term_taxonomy_id)
113-                               INNER JOIN $wpdb->terms USING (term_id)
114-                               WHERE taxonomy IN ($taxonomies)
115-                               AND $field $operator ($terms)
116-                       ";
117-               break;
118-       }
119-
120-       return $do_query ? $wpdb->get_col( $sql ) : $sql;
121+       return $object_ids;
122 }
123 
124 /*
125@@ -579,36 +524,96 @@
126 
127        $sql = array();
128        foreach ( $tax_query as $query ) {
129-               if ( !isset( $query['include_children'] ) )
130-                       $query['include_children'] = true;
131+               extract( wp_parse_args( $query, array(
132+                       'taxonomy' => array(),
133+                       'terms' => array(),
134+                       'include_children' => true,
135+                       'field' => 'term_id',
136+                       'operator' => 'IN',
137+               ) ) );
138 
139-               $query['do_query'] = false;
140+               $taxonomies = (array) $taxonomy;
141 
142-               $sql_single = get_objects_in_term( $query['terms'], $query['taxonomy'], $query );
143+               foreach ( $taxonomies as $taxonomy ) {
144+                       if ( ! taxonomy_exists( $taxonomy ) )
145+                               return ' AND 0 = 1';
146+               }
147 
148-               if ( empty( $sql_single ) || is_wp_error( $sql_single ) )
149-                       return ' AND 0 = 1';
150+               if ( !in_array( $operator, array( 'IN', 'NOT IN' ) ) )
151+                       $operator = 'IN';
152 
153-               $sql[] = $sql_single;
154-       }
155+               $taxonomies = "'" . implode( "', '", $taxonomies ) . "'";
156 
157-       if ( 1 == count( $sql ) ) {
158-               $ids = $wpdb->get_col( $sql[0] );
159-       } else {
160-               $r = "SELECT object_id FROM $wpdb->term_relationships WHERE 1=1";
161-               foreach ( $sql as $query )
162-                       $r .= " AND object_id IN ($query)";
163+               $terms = array_unique( (array) $terms );
164 
165-               $ids = $wpdb->get_col( $r );
166+               if ( empty( $terms ) )
167+                       continue;
168+
169+               if ( is_taxonomy_hierarchical( $taxonomy ) && $include_children ) {
170+                       $terms = _get_existing_terms( $field, $terms, $taxonomies, 'term_id' );
171+
172+                       if ( empty( $terms ) )
173+                               continue;
174+
175+                       $children = array();
176+                       foreach ( $terms as $term ) {
177+                               $children = array_merge( $children, get_term_children( $term, $taxonomy ) );
178+                               $children[] = $term;
179+                       }
180+                       $terms = _get_existing_terms( 'term_id', $children, $taxonomies, 'term_taxonomy_id' );
181+               }
182+               else {
183+                       $terms = _get_existing_terms( $field, $terms, $taxonomies, 'term_taxonomy_id' );
184+               }
185+
186+               $terms = implode( ',', $terms );
187+
188+               $sql[] = "
189+                       SELECT object_id
190+                       FROM $wpdb->term_relationships
191+                       WHERE term_taxonomy_id $operator ($terms)
192+               ";
193        }
194 
195-       if ( !empty( $ids ) )
196-               return " AND $object_id_column IN(" . implode( ', ', $ids ) . ")";
197-       else
198-               return ' AND 0 = 1';
199+       $where = '';
200+       $join = '';
201+
202+       $r = '';
203+       foreach ( $sql as $query )
204+               $r .= " AND $object_id_column IN ($query)";
205+
206+       return $r;
207 }
208 
209+function _get_existing_terms( $field, &$terms, $taxonomies, $resulting_field ) {
210+       global $wpdb;
211 
212+       $resulting_field = esc_sql( $resulting_field );
213+
214+       switch ( $field ) {
215+               case 'slug':
216+               case 'name':
217+                       $terms = "'" . implode( "','", array_map( 'sanitize_title_for_query', $terms ) ) . "'";
218+                       return $wpdb->get_col( "
219+                               SELECT $resulting_field
220+                               FROM $wpdb->term_taxonomy
221+                               INNER JOIN $wpdb->terms USING (term_id)
222+                               WHERE taxonomy IN ($taxonomies)
223+                               AND $field IN ($terms)
224+                       " );
225+                       break;
226+
227+               default:
228+                       $terms = implode( ',', array_map( 'intval', $terms ) );
229+                       return $wpdb->get_col( "
230+                               SELECT $resulting_field
231+                               FROM $wpdb->term_taxonomy
232+                               WHERE taxonomy IN ($taxonomies)
233+                               AND term_id IN ($terms)
234+                       " );
235+       }
236+}
237+
238 /**
239  * Get all Term data from database by Term ID.
240  *