class-wp-term.php 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. <?php
  2. /**
  3. * Taxonomy API: WP_Term class
  4. *
  5. * @package WordPress
  6. * @subpackage Taxonomy
  7. * @since 4.4.0
  8. */
  9. /**
  10. * Core class used to implement the WP_Term object.
  11. *
  12. * @since 4.4.0
  13. *
  14. * @property-read object $data Sanitized term data.
  15. */
  16. final class WP_Term {
  17. /**
  18. * Term ID.
  19. *
  20. * @since 4.4.0
  21. * @var int
  22. */
  23. public $term_id;
  24. /**
  25. * The term's name.
  26. *
  27. * @since 4.4.0
  28. * @var string
  29. */
  30. public $name = '';
  31. /**
  32. * The term's slug.
  33. *
  34. * @since 4.4.0
  35. * @var string
  36. */
  37. public $slug = '';
  38. /**
  39. * The term's term_group.
  40. *
  41. * @since 4.4.0
  42. * @var string
  43. */
  44. public $term_group = '';
  45. /**
  46. * Term Taxonomy ID.
  47. *
  48. * @since 4.4.0
  49. * @var int
  50. */
  51. public $term_taxonomy_id = 0;
  52. /**
  53. * The term's taxonomy name.
  54. *
  55. * @since 4.4.0
  56. * @var string
  57. */
  58. public $taxonomy = '';
  59. /**
  60. * The term's description.
  61. *
  62. * @since 4.4.0
  63. * @var string
  64. */
  65. public $description = '';
  66. /**
  67. * ID of a term's parent term.
  68. *
  69. * @since 4.4.0
  70. * @var int
  71. */
  72. public $parent = 0;
  73. /**
  74. * Cached object count for this term.
  75. *
  76. * @since 4.4.0
  77. * @var int
  78. */
  79. public $count = 0;
  80. /**
  81. * Stores the term object's sanitization level.
  82. *
  83. * Does not correspond to a database field.
  84. *
  85. * @since 4.4.0
  86. * @var string
  87. */
  88. public $filter = 'raw';
  89. /**
  90. * Retrieve WP_Term instance.
  91. *
  92. * @since 4.4.0
  93. *
  94. * @global wpdb $wpdb WordPress database abstraction object.
  95. *
  96. * @param int $term_id Term ID.
  97. * @param string $taxonomy Optional. Limit matched terms to those matching `$taxonomy`. Only used for
  98. * disambiguating potentially shared terms.
  99. * @return WP_Term|WP_Error|false Term object, if found. WP_Error if `$term_id` is shared between taxonomies and
  100. * there's insufficient data to distinguish which term is intended.
  101. * False for other failures.
  102. */
  103. public static function get_instance( $term_id, $taxonomy = null ) {
  104. global $wpdb;
  105. $term_id = (int) $term_id;
  106. if ( ! $term_id ) {
  107. return false;
  108. }
  109. $_term = wp_cache_get( $term_id, 'terms' );
  110. // If there isn't a cached version, hit the database.
  111. if ( ! $_term || ( $taxonomy && $taxonomy !== $_term->taxonomy ) ) {
  112. // Any term found in the cache is not a match, so don't use it.
  113. $_term = false;
  114. // Grab all matching terms, in case any are shared between taxonomies.
  115. $terms = $wpdb->get_results( $wpdb->prepare( "SELECT t.*, tt.* FROM $wpdb->terms AS t INNER JOIN $wpdb->term_taxonomy AS tt ON t.term_id = tt.term_id WHERE t.term_id = %d", $term_id ) );
  116. if ( ! $terms ) {
  117. return false;
  118. }
  119. // If a taxonomy was specified, find a match.
  120. if ( $taxonomy ) {
  121. foreach ( $terms as $match ) {
  122. if ( $taxonomy === $match->taxonomy ) {
  123. $_term = $match;
  124. break;
  125. }
  126. }
  127. // If only one match was found, it's the one we want.
  128. } elseif ( 1 === count( $terms ) ) {
  129. $_term = reset( $terms );
  130. // Otherwise, the term must be shared between taxonomies.
  131. } else {
  132. // If the term is shared only with invalid taxonomies, return the one valid term.
  133. foreach ( $terms as $t ) {
  134. if ( ! taxonomy_exists( $t->taxonomy ) ) {
  135. continue;
  136. }
  137. // Only hit if we've already identified a term in a valid taxonomy.
  138. if ( $_term ) {
  139. return new WP_Error( 'ambiguous_term_id', __( 'Term ID is shared between multiple taxonomies' ), $term_id );
  140. }
  141. $_term = $t;
  142. }
  143. }
  144. if ( ! $_term ) {
  145. return false;
  146. }
  147. // Don't return terms from invalid taxonomies.
  148. if ( ! taxonomy_exists( $_term->taxonomy ) ) {
  149. return new WP_Error( 'invalid_taxonomy', __( 'Invalid taxonomy.' ) );
  150. }
  151. $_term = sanitize_term( $_term, $_term->taxonomy, 'raw' );
  152. // Don't cache terms that are shared between taxonomies.
  153. if ( 1 === count( $terms ) ) {
  154. wp_cache_add( $term_id, $_term, 'terms' );
  155. }
  156. }
  157. $term_obj = new WP_Term( $_term );
  158. $term_obj->filter( $term_obj->filter );
  159. return $term_obj;
  160. }
  161. /**
  162. * Constructor.
  163. *
  164. * @since 4.4.0
  165. *
  166. * @param WP_Term|object $term Term object.
  167. */
  168. public function __construct( $term ) {
  169. foreach ( get_object_vars( $term ) as $key => $value ) {
  170. $this->$key = $value;
  171. }
  172. }
  173. /**
  174. * Sanitizes term fields, according to the filter type provided.
  175. *
  176. * @since 4.4.0
  177. *
  178. * @param string $filter Filter context. Accepts 'edit', 'db', 'display', 'attribute', 'js', 'raw'.
  179. */
  180. public function filter( $filter ) {
  181. sanitize_term( $this, $this->taxonomy, $filter );
  182. }
  183. /**
  184. * Converts an object to array.
  185. *
  186. * @since 4.4.0
  187. *
  188. * @return array Object as array.
  189. */
  190. public function to_array() {
  191. return get_object_vars( $this );
  192. }
  193. /**
  194. * Getter.
  195. *
  196. * @since 4.4.0
  197. *
  198. * @param string $key Property to get.
  199. * @return mixed Property value.
  200. */
  201. public function __get( $key ) {
  202. switch ( $key ) {
  203. case 'data':
  204. $data = new stdClass();
  205. $columns = array( 'term_id', 'name', 'slug', 'term_group', 'term_taxonomy_id', 'taxonomy', 'description', 'parent', 'count' );
  206. foreach ( $columns as $column ) {
  207. $data->{$column} = isset( $this->{$column} ) ? $this->{$column} : null;
  208. }
  209. return sanitize_term( $data, $data->taxonomy, 'raw' );
  210. }
  211. }
  212. }