class-wp-term.php 5.2 KB

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