| 1 | Index: wp-includes/taxonomy.php |
|---|
| 2 | =================================================================== |
|---|
| 3 | --- wp-includes/taxonomy.php (revision 17409) |
|---|
| 4 | +++ wp-includes/taxonomy.php (working copy) |
|---|
| 5 | @@ -%ld,%ld +%ld,%ld @@ |
|---|
| 6 | |
|---|
| 7 | $order = ( 'desc' == strtolower( $order ) ) ? 'DESC' : 'ASC'; |
|---|
| 8 | |
|---|
| 9 | - $term_ids = array_map('intval', $term_ids ); |
|---|
| 10 | + $taxonomies_add = transform_array_to_sql_condition( $taxonomies ); |
|---|
| 11 | + $term_ids_add = transform_array_to_sql_condition( $term_ids, true ); |
|---|
| 12 | |
|---|
| 13 | - $taxonomies = "'" . implode( "', '", $taxonomies ) . "'"; |
|---|
| 14 | - $term_ids = "'" . implode( "', '", $term_ids ) . "'"; |
|---|
| 15 | + $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 $taxonomies_add AND tt.term_id $term_ids_add ORDER BY tr.object_id $order"); |
|---|
| 16 | |
|---|
| 17 | - $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"); |
|---|
| 18 | - |
|---|
| 19 | if ( ! $object_ids ) |
|---|
| 20 | return array(); |
|---|
| 21 | |
|---|
| 22 | @@ -%ld,%ld +%ld,%ld @@ |
|---|
| 23 | if ( empty( $terms ) ) |
|---|
| 24 | continue; |
|---|
| 25 | |
|---|
| 26 | - $terms = implode( ',', $terms ); |
|---|
| 27 | - |
|---|
| 28 | + $terms_add = transform_array_to_sql_condition( $terms, true ); |
|---|
| 29 | + |
|---|
| 30 | $where[] = "$primary_table.$primary_id_column NOT IN ( |
|---|
| 31 | SELECT object_id |
|---|
| 32 | FROM $wpdb->term_relationships |
|---|
| 33 | - WHERE term_taxonomy_id IN ($terms) |
|---|
| 34 | + WHERE term_taxonomy_id $terms_add |
|---|
| 35 | )"; |
|---|
| 36 | } elseif ( 'AND' == $operator ) { |
|---|
| 37 | |
|---|
| 38 | @@ -%ld,%ld +%ld,%ld @@ |
|---|
| 39 | |
|---|
| 40 | $num_terms = count( $terms ); |
|---|
| 41 | |
|---|
| 42 | - $terms = implode( ',', $terms ); |
|---|
| 43 | + $terms_add = transform_array_to_sql_condition( $terms, true ); |
|---|
| 44 | |
|---|
| 45 | $where[] = "$primary_table.$primary_id_column IN ( |
|---|
| 46 | SELECT object_id |
|---|
| 47 | FROM $wpdb->term_relationships |
|---|
| 48 | - WHERE term_taxonomy_id IN ($terms) |
|---|
| 49 | + WHERE term_taxonomy_id $terms_add |
|---|
| 50 | GROUP BY object_id HAVING COUNT(object_id) = $num_terms |
|---|
| 51 | )"; |
|---|
| 52 | } |
|---|
| 53 | @@ -%ld,%ld +%ld,%ld @@ |
|---|
| 54 | switch ( $field ) { |
|---|
| 55 | case 'slug': |
|---|
| 56 | case 'name': |
|---|
| 57 | - $terms = "'" . implode( "','", array_map( 'sanitize_title_for_query', $terms ) ) . "'"; |
|---|
| 58 | + $terms_add = transform_array_to_sql_condition( $terms, false, 'sanitize_title_for_query' ); |
|---|
| 59 | $terms = $wpdb->get_col( " |
|---|
| 60 | SELECT $wpdb->term_taxonomy.$resulting_field |
|---|
| 61 | FROM $wpdb->term_taxonomy |
|---|
| 62 | INNER JOIN $wpdb->terms USING (term_id) |
|---|
| 63 | WHERE taxonomy = '$taxonomy' |
|---|
| 64 | - AND $wpdb->terms.$field IN ($terms) |
|---|
| 65 | + AND $wpdb->terms.$field $terms_add |
|---|
| 66 | " ); |
|---|
| 67 | break; |
|---|
| 68 | |
|---|
| 69 | default: |
|---|
| 70 | - $terms = implode( ',', array_map( 'intval', $terms ) ); |
|---|
| 71 | + $terms_add = transform_array_to_sql_condition( $terms, true ); |
|---|
| 72 | $terms = $wpdb->get_col( " |
|---|
| 73 | SELECT $resulting_field |
|---|
| 74 | FROM $wpdb->term_taxonomy |
|---|
| 75 | WHERE taxonomy = '$taxonomy' |
|---|
| 76 | - AND term_id IN ($terms) |
|---|
| 77 | + AND term_id $terms_add |
|---|
| 78 | " ); |
|---|
| 79 | } |
|---|
| 80 | } |
|---|
| 81 | @@ -%ld,%ld +%ld,%ld @@ |
|---|
| 82 | else |
|---|
| 83 | $order = ''; |
|---|
| 84 | |
|---|
| 85 | - $where = "tt.taxonomy IN ('" . implode("', '", $taxonomies) . "')"; |
|---|
| 86 | + $taxonomies_add = transform_array_to_sql_condition( $taxonomies ); |
|---|
| 87 | + |
|---|
| 88 | + $where = "tt.taxonomy $taxonomies_add"; |
|---|
| 89 | $inclusions = ''; |
|---|
| 90 | if ( !empty($include) ) { |
|---|
| 91 | $exclude = ''; |
|---|
| 92 | @@ -%ld,%ld +%ld,%ld @@ |
|---|
| 93 | |
|---|
| 94 | foreach ( (array) $taxonomies as $taxonomy ) { |
|---|
| 95 | $tt_ids = wp_get_object_terms($object_id, $taxonomy, array('fields' => 'tt_ids')); |
|---|
| 96 | - $in_tt_ids = "'" . implode("', '", $tt_ids) . "'"; |
|---|
| 97 | + $in_tt_ids = transform_array_to_sql_condition( $tt_ids, true ); |
|---|
| 98 | + |
|---|
| 99 | do_action( 'delete_term_relationships', $object_id, $tt_ids ); |
|---|
| 100 | - $wpdb->query( $wpdb->prepare("DELETE FROM $wpdb->term_relationships WHERE object_id = %d AND term_taxonomy_id IN ($in_tt_ids)", $object_id) ); |
|---|
| 101 | + $wpdb->query( $wpdb->prepare("DELETE FROM $wpdb->term_relationships WHERE object_id = %d AND term_taxonomy_id $in_tt_ids", $object_id) ); |
|---|
| 102 | do_action( 'deleted_term_relationships', $object_id, $tt_ids ); |
|---|
| 103 | wp_update_term_count($tt_ids, $taxonomy); |
|---|
| 104 | } |
|---|
| 105 | @@ -%ld,%ld +%ld,%ld @@ |
|---|
| 106 | if ( !empty($orderby) ) |
|---|
| 107 | $orderby = "ORDER BY $orderby"; |
|---|
| 108 | |
|---|
| 109 | - $taxonomies = "'" . implode("', '", $taxonomies) . "'"; |
|---|
| 110 | - $object_ids = implode(', ', $object_ids); |
|---|
| 111 | - |
|---|
| 112 | + $taxonomies_add = transform_array_to_sql_condition( $taxonomies ); |
|---|
| 113 | + $object_ids_add = transform_array_to_sql_condition( $object_ids, true ); |
|---|
| 114 | + $object_ids = implode( ", ", $object_ids ); // left for compatibility reasons. it's used in filter below |
|---|
| 115 | + |
|---|
| 116 | $select_this = ''; |
|---|
| 117 | if ( 'all' == $fields ) |
|---|
| 118 | $select_this = 't.*, tt.*'; |
|---|
| 119 | @@ -%ld,%ld +%ld,%ld @@ |
|---|
| 120 | else if ( 'all_with_object_id' == $fields ) |
|---|
| 121 | $select_this = 't.*, tt.*, tr.object_id'; |
|---|
| 122 | |
|---|
| 123 | - $query = "SELECT $select_this FROM $wpdb->terms AS t INNER JOIN $wpdb->term_taxonomy AS tt ON tt.term_id = t.term_id INNER JOIN $wpdb->term_relationships AS tr ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tt.taxonomy IN ($taxonomies) AND tr.object_id IN ($object_ids) $orderby $order"; |
|---|
| 124 | + $query = "SELECT $select_this FROM $wpdb->terms AS t INNER JOIN $wpdb->term_taxonomy AS tt ON tt.term_id = t.term_id INNER JOIN $wpdb->term_relationships AS tr ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tt.taxonomy $taxonomies_add AND tr.object_id $object_ids_add $orderby $order"; |
|---|
| 125 | |
|---|
| 126 | if ( 'all' == $fields || 'all_with_object_id' == $fields ) { |
|---|
| 127 | $terms = array_merge($terms, $wpdb->get_results($query)); |
|---|
| 128 | @@ -%ld,%ld +%ld,%ld @@ |
|---|
| 129 | } else if ( 'ids' == $fields || 'names' == $fields ) { |
|---|
| 130 | $terms = array_merge($terms, $wpdb->get_col($query)); |
|---|
| 131 | } else if ( 'tt_ids' == $fields ) { |
|---|
| 132 | - $terms = $wpdb->get_col("SELECT tr.term_taxonomy_id FROM $wpdb->term_relationships AS tr INNER JOIN $wpdb->term_taxonomy AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tr.object_id IN ($object_ids) AND tt.taxonomy IN ($taxonomies) $orderby $order"); |
|---|
| 133 | + $terms = $wpdb->get_col("SELECT tr.term_taxonomy_id FROM $wpdb->term_relationships AS tr INNER JOIN $wpdb->term_taxonomy AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tr.object_id $object_ids_add AND tt.taxonomy $taxonomies_add $orderby $order"); |
|---|
| 134 | } |
|---|
| 135 | |
|---|
| 136 | if ( ! $terms ) |
|---|
| 137 | @@ -%ld,%ld +%ld,%ld @@ |
|---|
| 138 | if ( ! $append ) { |
|---|
| 139 | $delete_terms = array_diff($old_tt_ids, $tt_ids); |
|---|
| 140 | if ( $delete_terms ) { |
|---|
| 141 | - $in_delete_terms = "'" . implode("', '", $delete_terms) . "'"; |
|---|
| 142 | + $in_delete_terms = transform_array_to_sql_condition( $delete_terms, true ); |
|---|
| 143 | do_action( 'delete_term_relationships', $object_id, $delete_terms ); |
|---|
| 144 | - $wpdb->query( $wpdb->prepare("DELETE FROM $wpdb->term_relationships WHERE object_id = %d AND term_taxonomy_id IN ($in_delete_terms)", $object_id) ); |
|---|
| 145 | + $wpdb->query( $wpdb->prepare("DELETE FROM $wpdb->term_relationships WHERE object_id = %d AND term_taxonomy_id $in_delete_terms", $object_id) ); |
|---|
| 146 | do_action( 'deleted_term_relationships', $object_id, $delete_terms ); |
|---|
| 147 | wp_update_term_count($delete_terms, $taxonomy); |
|---|
| 148 | } |
|---|
| 149 | @@ -%ld,%ld +%ld,%ld @@ |
|---|
| 150 | $taxonomies = array(); |
|---|
| 151 | // If no taxonomy, assume tt_ids. |
|---|
| 152 | if ( empty($taxonomy) ) { |
|---|
| 153 | - $tt_ids = array_map('intval', $ids); |
|---|
| 154 | - $tt_ids = implode(', ', $tt_ids); |
|---|
| 155 | - $terms = $wpdb->get_results("SELECT term_id, taxonomy FROM $wpdb->term_taxonomy WHERE term_taxonomy_id IN ($tt_ids)"); |
|---|
| 156 | + $tt_ids = transform_array_to_sql_condition( $tt_ids, true ); |
|---|
| 157 | + $terms = $wpdb->get_results("SELECT term_id, taxonomy FROM $wpdb->term_taxonomy WHERE term_taxonomy_id $tt_ids"); |
|---|
| 158 | $ids = array(); |
|---|
| 159 | foreach ( (array) $terms as $term ) { |
|---|
| 160 | $taxonomies[] = $term->taxonomy; |
|---|
| 161 | @@ -%ld,%ld +%ld,%ld @@ |
|---|
| 162 | // Get the object and term ids and stick them in a lookup table |
|---|
| 163 | $tax_obj = get_taxonomy($taxonomy); |
|---|
| 164 | $object_types = esc_sql($tax_obj->object_type); |
|---|
| 165 | - $results = $wpdb->get_results("SELECT object_id, term_taxonomy_id FROM $wpdb->term_relationships INNER JOIN $wpdb->posts ON object_id = ID WHERE term_taxonomy_id IN (" . implode(',', array_keys($term_ids)) . ") AND post_type IN ('" . implode("', '", $object_types) . "') AND post_status = 'publish'"); |
|---|
| 166 | + $term_ids_in = transform_array_to_sql_condition( array_keys( $term_ids ), true ); |
|---|
| 167 | + |
|---|
| 168 | + $results = $wpdb->get_results("SELECT object_id, term_taxonomy_id FROM $wpdb->term_relationships INNER JOIN $wpdb->posts ON object_id = ID WHERE term_taxonomy_id $term_ids_in AND post_type IN ('" . implode("', '", $object_types) . "') AND post_status = 'publish'"); |
|---|
| 169 | foreach ( $results as $row ) { |
|---|
| 170 | $id = $term_ids[$row->term_taxonomy_id]; |
|---|
| 171 | $term_items[$id][$row->object_id] = isset($term_items[$id][$row->object_id]) ? ++$term_items[$id][$row->object_id] : 1; |
|---|
| 172 | @@ -%ld,%ld +%ld,%ld @@ |
|---|
| 173 | |
|---|
| 174 | return $parent; |
|---|
| 175 | } |
|---|
| 176 | + |
|---|
| 177 | +/** |
|---|
| 178 | + * Given an array of values this function will return a string to be put in |
|---|
| 179 | + * a sql query based on the amount of values. for multiple values it will return "IN ('val1', 'val2'..)" |
|---|
| 180 | + * while for single values it will return "= 'val1'" in order to avoid the creation of temporary |
|---|
| 181 | + * tables and improve performance |
|---|
| 182 | + * |
|---|
| 183 | + * @param array $values |
|---|
| 184 | + * @param bool $treat_as_integer would make sure to skip "'" escaping and cast all values as integers |
|---|
| 185 | + * @param mixed $array_map_sanitation a function name or callback to be used to sanitize $values via array_map() before usage |
|---|
| 186 | + * @return string |
|---|
| 187 | + */ |
|---|
| 188 | +function transform_array_to_sql_condition( $values, $treat_as_integer = false, $array_map_sanitation = NULL ) { |
|---|
| 189 | + $values = (array) $values; |
|---|
| 190 | + if ( !is_null( $array_map_sanitation ) ) |
|---|
| 191 | + $values = array_map( $array_map_sanitation, $values ); |
|---|
| 192 | + |
|---|
| 193 | + if ( true === $treat_as_integer ) { |
|---|
| 194 | + $glue = ", "; |
|---|
| 195 | + $pre_glue = $post_glue = ""; |
|---|
| 196 | + $values = array_map( 'intval', $values ); |
|---|
| 197 | + } else { |
|---|
| 198 | + $glue = "',' "; |
|---|
| 199 | + $pre_glue = $post_glue = "'"; |
|---|
| 200 | + } |
|---|
| 201 | + if ( count( $values ) > 1 ) { |
|---|
| 202 | + $vals = $pre_glue . implode( $glue, $values ) . $post_glue; |
|---|
| 203 | + $vals_sql_add = "IN ($vals)"; |
|---|
| 204 | + } else { |
|---|
| 205 | + $vals_sql_add = "= '" . array_shift( $values ) . "'"; |
|---|
| 206 | + } |
|---|
| 207 | + return $vals_sql_add; |
|---|
| 208 | +} |
|---|
| 209 | \ No newline at end of file |
|---|