WordPress.org

Make WordPress Core

Ticket #4189: taxonomy.php

File taxonomy.php, 6.8 KB (added by majelbstoat, 15 years ago)

WPTaxonomy skeleton

Line 
1<?php
2
3class WPTaxonomy {
4
5        // This will look like (1 => 'post_category', 2 => 'link_category') etc.
6        var $taxonomies;
7       
8        function WPTaxonomy() {
9                // Gets the taxonomies out of the options table.
10                $this->taxonomies = get_option('_wp_taxonomies');
11        }
12
13        /**
14         * Adds a new taxonomy type and updates the options.
15         */
16        function add_taxonomy($taxonomy) {
17                global $wpdb;
18                $wpdb->query("INSERT INTO $wpdb->taxonomies (taxonomy) VALUES ('$taxonomy')");
19                $index = $wpdb->get_var("SELECT taxonomy_id FROM $wpdb->taxonomies WHERE taxonomy = '$taxonomy' LIMIT 1");
20                $this->taxonomies[$index] = $taxonomy;
21                update_option('_wp_taxonomies', $this->taxonomies);
22        }
23
24        /**
25         * Removes a taxonomy type.
26         */
27        function remove_taxonomy($taxonomy) {
28                // Removes an entry from wpdb->taxonomies.
29                // What do we do with terms that are associated in this taxonomy?
30                // Updates the _wp_taxonomies option.
31        }
32
33        /**
34         * Adds a new term to the database.  Optionally marks it as an alias of an existing term.
35         * @param string $term The term to add.
36         * @param int|string $alias_of The id or slug of the new term's alias.
37         */
38        function add_term($term, $alias_of = '') {
39                global $wpdb;
40                $term_slug = sanitize_title($term);             
41                if ($alias_of) {
42                        $clause = (is_int($alias_of)) ? "term_id = $alias_of" : "term_slug = '$alias_of'";
43                        $alias = $wpdb->fetch_row("SELECT term_id, term_group FROM $wpdb->terms WHERE $clause");
44                        if ($alias->term_group)
45                                // The alias we want is already in a group, so let's use that one.
46                                $term_group = $alias->term_group;
47                        } else {
48                                // The alias isn't in a group, so let's create a new one and firstly add the alias term to it.
49                                $term_group = $wpdb->get_var("SELECT MAX() term_group FROM $wpdb->terms GROUP BY term_group") + 1;
50                                $wpdb->query("UPDATE $wpdb->terms SET term_group = $term_group WHERE term_id = $alias->term_id");
51                        }
52                } else {
53                        $term_group = 0;
54                }
55                // Now add or replace the term.  This works because we have a UNIQUE key on term_slug.
56                $wpdb->query("REPLACE INTO $wpdb->terms (term_name, term_slug, term_group) VALUES ($term, $term_slug, $term_group)");
57        }
58       
59        /**
60         * Returns the index of a defined term, or 0 (false) if the term doesn't exist.
61         */
62        function is_defined_term($term) {
63                global $wpdb;
64                return $wpdb->get_var("SELECT term_id FROM $wpdb->terms WHERE term_slug = '$term'");
65        }
66       
67        /**
68         * Given an array of terms, returns those that are defined term slugs.  Ignores integers.
69         * @param array $terms The term slugs to check for a definition.
70         */
71        function get_defined_terms($terms) {
72                global $wpdb;
73                foreach ($terms as $term) {
74                        if (!is_int($term)) {
75                                $searches[] = $term;
76                        }
77                }
78                $terms = "'" . implode("', '", $searches) . "'";
79                return $wpdb->get_col("SELECT term_slug FROM $wpdb->terms WHERE term_slug IN ($terms)");
80        }
81       
82        /**
83         * Returns the index of the specified taxonomy, or false if it doesn't exist.
84         *
85         * This function can return 0 or false - evaluate the return value using ===
86         */
87        function get_taxonomy_index($taxonomy) {
88                $flipped_taxonomies = array_flip($this->taxonomies);
89                return (isset($flipped_taxonomies[$taxonomy])) ? $flipped_taxonomies[$taxonomy] : false;
90        }
91       
92        /**
93         * Adds a term taxonomy entry or increments the count if it already exists.
94         * @param int|string $term The term to add.
95         * @param int|string $taxonomy The context.
96         * @param string $description An optional description of the relationship.
97         * @param int $parent The parent of the term in this context.
98         */
99        function add_term_taxonomy($term, $taxonomy, $description = '', $parent = 0) {
100                if (!is_int($taxonomy)) {
101                        // Get ourselves an integer taxonomy, if the taxonomy name was used.
102                        $taxonomy = $this->get_taxonomy_index($taxonomy);
103                }
104                $clause = (is_int($term)) ? "t.term_id = $term" : "t.term_slug = '$term'";
105                if ($count = $wpdb->query("SELECT tt.count FROM $wpdb->term_taxonomy AS tt INNER JOIN $wpdb->terms AS t ON tt.term_id = t.term_id WHERE tt.taxonomy_id = $taxonomy AND $clause")) {
106      // We'll be updating whatever's there, and incrementing the count.
107      $count++;
108                        $wpdb->query("UPDATE $wpdb->term_taxonomy SET count = $count");
109                } else {
110      // There was no existing entry for this term and taxonomy type, so add a new one, using the supplied description and parent, with a count of 1.
111      $wpdb->query("INSERT INTO $wpdb->term_taxonomy (term_id, taxonomy_id, term_description, parent, count) SELECT term_id, $taxonomy, '$description', $parent, 1 FROM $wpdb->terms AS t1 WHERE $clause");
112                }
113        }       
114       
115        /**
116         * Relates an object (post, link etc) to a term and taxonomy type.  Creates the term and taxonomy
117         * relationship if it doesn't already exist.  Creates a term if it doesn't exist (using the term_slug).
118         * @param array|int|string $term The slug or id of the term.
119         * @param int $object_id The object to relate to.
120         * @param array|int|string $taxonomies The context(s) in which to relate the term to the object.
121         */
122        function add_term_relationship($terms, $object_id, $taxonomies) {
123                global $wpdb;
124               
125                if (!is_array($taxonomies)) {
126                        $taxonomies = array($taxonomies);
127                }
128               
129                foreach ($taxonomies as $taxonomy) {
130                        if (!is_int($taxonomy)) {
131                                // Get ourselves an integer taxonomy, if the taxonomy name was used.
132                                $taxonomy = $this->get_taxonomy_index($taxonomy);
133                        }
134                        $buffered_taxonomies[] = $taxonomy;                     
135                }
136                $taxonomies = $buffered_taxonomies;
137               
138                if (!is_array($terms)) {
139                        $terms = array($terms);
140                }
141               
142                $defined_terms = $this->get_defined_terms($terms);
143
144                foreach ($terms as $term) {
145                        if (!is_int($term)) {
146                                if (!isset($defined_terms[$term])) {
147                                        $new_terms[] = $term;
148                                }
149                                $term_slugs[] = $term;
150                        } else {
151                                $term_ids[] = $term;
152                        }
153                }
154               
155                if (isset($new_terms) {
156                        // At least one of the terms specified doesn't exist, so add any new ones, using the term_slug as the name.
157                        $this->add_terms($new_terms);
158                }
159
160                $term_clause = (isset($term_ids)) 'tt.term_id IN (' . implode(', ', $term_ids) . ')' ? : '';
161                if (isset($term_slugs)) {
162                        if ($term_clause) {
163                                $term_clause .= ' OR ';
164                        }
165                        $term_clause .= "t.term_slug IN ('" . implode("', '", $term_slugs) . "')";
166                        $term_join = "INNER JOIN $wpdb->terms AS t ON tt.term_id = t.term_id";
167                } else {
168                        $term_join = '';
169                }
170               
171                // Now add or increment the term taxonomy relationships.  This is inefficient at the moment.
172                foreach ($taxonomies as $taxonomy) {
173                        foreach ($terms as $term) {
174                                $this->add_term_taxonomy($term, $taxonomy);
175                        }
176                }
177               
178                $taxonomies = "'" . implode("', '", $taxonomies) . "'";
179               
180                // Finally, relate the term and taxonomy to the object.
181                $wpdb->query("INSERT INTO $wpdb->term_relationships(object_id, term_taxonomy_id) SELECT $object_id, term_taxonomy_id FROM $wpdb->term_taxonomy AS tt $term_join WHERE ($term_clause) AND tt.taxonomy_id IN ($taxonomies)");
182        }
183}
184
185?>