angelovcom.net

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

class-wp-taxonomy.php (13344B)


      1 <?php
      2 /**
      3  * Taxonomy API: WP_Taxonomy class
      4  *
      5  * @package WordPress
      6  * @subpackage Taxonomy
      7  * @since 4.7.0
      8  */
      9 
     10 /**
     11  * Core class used for interacting with taxonomies.
     12  *
     13  * @since 4.7.0
     14  */
     15 final class WP_Taxonomy {
     16 	/**
     17 	 * Taxonomy key.
     18 	 *
     19 	 * @since 4.7.0
     20 	 * @var string
     21 	 */
     22 	public $name;
     23 
     24 	/**
     25 	 * Name of the taxonomy shown in the menu. Usually plural.
     26 	 *
     27 	 * @since 4.7.0
     28 	 * @var string
     29 	 */
     30 	public $label;
     31 
     32 	/**
     33 	 * Labels object for this taxonomy.
     34 	 *
     35 	 * If not set, tag labels are inherited for non-hierarchical types
     36 	 * and category labels for hierarchical ones.
     37 	 *
     38 	 * @see get_taxonomy_labels()
     39 	 *
     40 	 * @since 4.7.0
     41 	 * @var stdClass
     42 	 */
     43 	public $labels;
     44 
     45 	/**
     46 	 * A short descriptive summary of what the taxonomy is for.
     47 	 *
     48 	 * @since 4.7.0
     49 	 * @var string
     50 	 */
     51 	public $description = '';
     52 
     53 	/**
     54 	 * Whether a taxonomy is intended for use publicly either via the admin interface or by front-end users.
     55 	 *
     56 	 * @since 4.7.0
     57 	 * @var bool
     58 	 */
     59 	public $public = true;
     60 
     61 	/**
     62 	 * Whether the taxonomy is publicly queryable.
     63 	 *
     64 	 * @since 4.7.0
     65 	 * @var bool
     66 	 */
     67 	public $publicly_queryable = true;
     68 
     69 	/**
     70 	 * Whether the taxonomy is hierarchical.
     71 	 *
     72 	 * @since 4.7.0
     73 	 * @var bool
     74 	 */
     75 	public $hierarchical = false;
     76 
     77 	/**
     78 	 * Whether to generate and allow a UI for managing terms in this taxonomy in the admin.
     79 	 *
     80 	 * @since 4.7.0
     81 	 * @var bool
     82 	 */
     83 	public $show_ui = true;
     84 
     85 	/**
     86 	 * Whether to show the taxonomy in the admin menu.
     87 	 *
     88 	 * If true, the taxonomy is shown as a submenu of the object type menu. If false, no menu is shown.
     89 	 *
     90 	 * @since 4.7.0
     91 	 * @var bool
     92 	 */
     93 	public $show_in_menu = true;
     94 
     95 	/**
     96 	 * Whether the taxonomy is available for selection in navigation menus.
     97 	 *
     98 	 * @since 4.7.0
     99 	 * @var bool
    100 	 */
    101 	public $show_in_nav_menus = true;
    102 
    103 	/**
    104 	 * Whether to list the taxonomy in the tag cloud widget controls.
    105 	 *
    106 	 * @since 4.7.0
    107 	 * @var bool
    108 	 */
    109 	public $show_tagcloud = true;
    110 
    111 	/**
    112 	 * Whether to show the taxonomy in the quick/bulk edit panel.
    113 	 *
    114 	 * @since 4.7.0
    115 	 * @var bool
    116 	 */
    117 	public $show_in_quick_edit = true;
    118 
    119 	/**
    120 	 * Whether to display a column for the taxonomy on its post type listing screens.
    121 	 *
    122 	 * @since 4.7.0
    123 	 * @var bool
    124 	 */
    125 	public $show_admin_column = false;
    126 
    127 	/**
    128 	 * The callback function for the meta box display.
    129 	 *
    130 	 * @since 4.7.0
    131 	 * @var bool|callable
    132 	 */
    133 	public $meta_box_cb = null;
    134 
    135 	/**
    136 	 * The callback function for sanitizing taxonomy data saved from a meta box.
    137 	 *
    138 	 * @since 5.1.0
    139 	 * @var callable
    140 	 */
    141 	public $meta_box_sanitize_cb = null;
    142 
    143 	/**
    144 	 * An array of object types this taxonomy is registered for.
    145 	 *
    146 	 * @since 4.7.0
    147 	 * @var array
    148 	 */
    149 	public $object_type = null;
    150 
    151 	/**
    152 	 * Capabilities for this taxonomy.
    153 	 *
    154 	 * @since 4.7.0
    155 	 * @var stdClass
    156 	 */
    157 	public $cap;
    158 
    159 	/**
    160 	 * Rewrites information for this taxonomy.
    161 	 *
    162 	 * @since 4.7.0
    163 	 * @var array|false
    164 	 */
    165 	public $rewrite;
    166 
    167 	/**
    168 	 * Query var string for this taxonomy.
    169 	 *
    170 	 * @since 4.7.0
    171 	 * @var string|false
    172 	 */
    173 	public $query_var;
    174 
    175 	/**
    176 	 * Function that will be called when the count is updated.
    177 	 *
    178 	 * @since 4.7.0
    179 	 * @var callable
    180 	 */
    181 	public $update_count_callback;
    182 
    183 	/**
    184 	 * Whether this taxonomy should appear in the REST API.
    185 	 *
    186 	 * Default false. If true, standard endpoints will be registered with
    187 	 * respect to $rest_base and $rest_controller_class.
    188 	 *
    189 	 * @since 4.7.4
    190 	 * @var bool $show_in_rest
    191 	 */
    192 	public $show_in_rest;
    193 
    194 	/**
    195 	 * The base path for this taxonomy's REST API endpoints.
    196 	 *
    197 	 * @since 4.7.4
    198 	 * @var string|bool $rest_base
    199 	 */
    200 	public $rest_base;
    201 
    202 	/**
    203 	 * The controller for this taxonomy's REST API endpoints.
    204 	 *
    205 	 * Custom controllers must extend WP_REST_Controller.
    206 	 *
    207 	 * @since 4.7.4
    208 	 * @var string|bool $rest_controller_class
    209 	 */
    210 	public $rest_controller_class;
    211 
    212 	/**
    213 	 * The controller instance for this taxonomy's REST API endpoints.
    214 	 *
    215 	 * Lazily computed. Should be accessed using {@see WP_Taxonomy::get_rest_controller()}.
    216 	 *
    217 	 * @since 5.5.0
    218 	 * @var WP_REST_Controller $rest_controller
    219 	 */
    220 	public $rest_controller;
    221 
    222 	/**
    223 	 * The default term name for this taxonomy. If you pass an array you have
    224 	 * to set 'name' and optionally 'slug' and 'description'.
    225 	 *
    226 	 * @since 5.5.0
    227 	 * @var array|string
    228 	 */
    229 	public $default_term;
    230 
    231 	/**
    232 	 * Whether terms in this taxonomy should be sorted in the order they are provided to `wp_set_object_terms()`.
    233 	 *
    234 	 * Use this in combination with `'orderby' => 'term_order'` when fetching terms.
    235 	 *
    236 	 * @since 2.5.0
    237 	 * @var bool|null
    238 	 */
    239 	public $sort = null;
    240 
    241 	/**
    242 	 * Array of arguments to automatically use inside `wp_get_object_terms()` for this taxonomy.
    243 	 *
    244 	 * @since 2.6.0
    245 	 * @var array|null
    246 	 */
    247 	public $args = null;
    248 
    249 	/**
    250 	 * Whether it is a built-in taxonomy.
    251 	 *
    252 	 * @since 4.7.0
    253 	 * @var bool
    254 	 */
    255 	public $_builtin;
    256 
    257 	/**
    258 	 * Constructor.
    259 	 *
    260 	 * See the register_taxonomy() function for accepted arguments for `$args`.
    261 	 *
    262 	 * @since 4.7.0
    263 	 *
    264 	 * @global WP $wp Current WordPress environment instance.
    265 	 *
    266 	 * @param string       $taxonomy    Taxonomy key, must not exceed 32 characters.
    267 	 * @param array|string $object_type Name of the object type for the taxonomy object.
    268 	 * @param array|string $args        Optional. Array or query string of arguments for registering a taxonomy.
    269 	 *                                  Default empty array.
    270 	 */
    271 	public function __construct( $taxonomy, $object_type, $args = array() ) {
    272 		$this->name = $taxonomy;
    273 
    274 		$this->set_props( $object_type, $args );
    275 	}
    276 
    277 	/**
    278 	 * Sets taxonomy properties.
    279 	 *
    280 	 * See the register_taxonomy() function for accepted arguments for `$args`.
    281 	 *
    282 	 * @since 4.7.0
    283 	 *
    284 	 * @param array|string $object_type Name of the object type for the taxonomy object.
    285 	 * @param array|string $args        Array or query string of arguments for registering a taxonomy.
    286 	 */
    287 	public function set_props( $object_type, $args ) {
    288 		$args = wp_parse_args( $args );
    289 
    290 		/**
    291 		 * Filters the arguments for registering a taxonomy.
    292 		 *
    293 		 * @since 4.4.0
    294 		 *
    295 		 * @param array    $args        Array of arguments for registering a taxonomy.
    296 		 *                              See the register_taxonomy() function for accepted arguments.
    297 		 * @param string   $taxonomy    Taxonomy key.
    298 		 * @param string[] $object_type Array of names of object types for the taxonomy.
    299 		 */
    300 		$args = apply_filters( 'register_taxonomy_args', $args, $this->name, (array) $object_type );
    301 
    302 		$defaults = array(
    303 			'labels'                => array(),
    304 			'description'           => '',
    305 			'public'                => true,
    306 			'publicly_queryable'    => null,
    307 			'hierarchical'          => false,
    308 			'show_ui'               => null,
    309 			'show_in_menu'          => null,
    310 			'show_in_nav_menus'     => null,
    311 			'show_tagcloud'         => null,
    312 			'show_in_quick_edit'    => null,
    313 			'show_admin_column'     => false,
    314 			'meta_box_cb'           => null,
    315 			'meta_box_sanitize_cb'  => null,
    316 			'capabilities'          => array(),
    317 			'rewrite'               => true,
    318 			'query_var'             => $this->name,
    319 			'update_count_callback' => '',
    320 			'show_in_rest'          => false,
    321 			'rest_base'             => false,
    322 			'rest_controller_class' => false,
    323 			'default_term'          => null,
    324 			'sort'                  => null,
    325 			'args'                  => null,
    326 			'_builtin'              => false,
    327 		);
    328 
    329 		$args = array_merge( $defaults, $args );
    330 
    331 		// If not set, default to the setting for 'public'.
    332 		if ( null === $args['publicly_queryable'] ) {
    333 			$args['publicly_queryable'] = $args['public'];
    334 		}
    335 
    336 		if ( false !== $args['query_var'] && ( is_admin() || false !== $args['publicly_queryable'] ) ) {
    337 			if ( true === $args['query_var'] ) {
    338 				$args['query_var'] = $this->name;
    339 			} else {
    340 				$args['query_var'] = sanitize_title_with_dashes( $args['query_var'] );
    341 			}
    342 		} else {
    343 			// Force 'query_var' to false for non-public taxonomies.
    344 			$args['query_var'] = false;
    345 		}
    346 
    347 		if ( false !== $args['rewrite'] && ( is_admin() || get_option( 'permalink_structure' ) ) ) {
    348 			$args['rewrite'] = wp_parse_args(
    349 				$args['rewrite'],
    350 				array(
    351 					'with_front'   => true,
    352 					'hierarchical' => false,
    353 					'ep_mask'      => EP_NONE,
    354 				)
    355 			);
    356 
    357 			if ( empty( $args['rewrite']['slug'] ) ) {
    358 				$args['rewrite']['slug'] = sanitize_title_with_dashes( $this->name );
    359 			}
    360 		}
    361 
    362 		// If not set, default to the setting for 'public'.
    363 		if ( null === $args['show_ui'] ) {
    364 			$args['show_ui'] = $args['public'];
    365 		}
    366 
    367 		// If not set, default to the setting for 'show_ui'.
    368 		if ( null === $args['show_in_menu'] || ! $args['show_ui'] ) {
    369 			$args['show_in_menu'] = $args['show_ui'];
    370 		}
    371 
    372 		// If not set, default to the setting for 'public'.
    373 		if ( null === $args['show_in_nav_menus'] ) {
    374 			$args['show_in_nav_menus'] = $args['public'];
    375 		}
    376 
    377 		// If not set, default to the setting for 'show_ui'.
    378 		if ( null === $args['show_tagcloud'] ) {
    379 			$args['show_tagcloud'] = $args['show_ui'];
    380 		}
    381 
    382 		// If not set, default to the setting for 'show_ui'.
    383 		if ( null === $args['show_in_quick_edit'] ) {
    384 			$args['show_in_quick_edit'] = $args['show_ui'];
    385 		}
    386 
    387 		$default_caps = array(
    388 			'manage_terms' => 'manage_categories',
    389 			'edit_terms'   => 'manage_categories',
    390 			'delete_terms' => 'manage_categories',
    391 			'assign_terms' => 'edit_posts',
    392 		);
    393 
    394 		$args['cap'] = (object) array_merge( $default_caps, $args['capabilities'] );
    395 		unset( $args['capabilities'] );
    396 
    397 		$args['object_type'] = array_unique( (array) $object_type );
    398 
    399 		// If not set, use the default meta box.
    400 		if ( null === $args['meta_box_cb'] ) {
    401 			if ( $args['hierarchical'] ) {
    402 				$args['meta_box_cb'] = 'post_categories_meta_box';
    403 			} else {
    404 				$args['meta_box_cb'] = 'post_tags_meta_box';
    405 			}
    406 		}
    407 
    408 		$args['name'] = $this->name;
    409 
    410 		// Default meta box sanitization callback depends on the value of 'meta_box_cb'.
    411 		if ( null === $args['meta_box_sanitize_cb'] ) {
    412 			switch ( $args['meta_box_cb'] ) {
    413 				case 'post_categories_meta_box':
    414 					$args['meta_box_sanitize_cb'] = 'taxonomy_meta_box_sanitize_cb_checkboxes';
    415 					break;
    416 
    417 				case 'post_tags_meta_box':
    418 				default:
    419 					$args['meta_box_sanitize_cb'] = 'taxonomy_meta_box_sanitize_cb_input';
    420 					break;
    421 			}
    422 		}
    423 
    424 		// Default taxonomy term.
    425 		if ( ! empty( $args['default_term'] ) ) {
    426 			if ( ! is_array( $args['default_term'] ) ) {
    427 				$args['default_term'] = array( 'name' => $args['default_term'] );
    428 			}
    429 			$args['default_term'] = wp_parse_args(
    430 				$args['default_term'],
    431 				array(
    432 					'name'        => '',
    433 					'slug'        => '',
    434 					'description' => '',
    435 				)
    436 			);
    437 		}
    438 
    439 		foreach ( $args as $property_name => $property_value ) {
    440 			$this->$property_name = $property_value;
    441 		}
    442 
    443 		$this->labels = get_taxonomy_labels( $this );
    444 		$this->label  = $this->labels->name;
    445 	}
    446 
    447 	/**
    448 	 * Adds the necessary rewrite rules for the taxonomy.
    449 	 *
    450 	 * @since 4.7.0
    451 	 *
    452 	 * @global WP $wp Current WordPress environment instance.
    453 	 */
    454 	public function add_rewrite_rules() {
    455 		/* @var WP $wp */
    456 		global $wp;
    457 
    458 		// Non-publicly queryable taxonomies should not register query vars, except in the admin.
    459 		if ( false !== $this->query_var && $wp ) {
    460 			$wp->add_query_var( $this->query_var );
    461 		}
    462 
    463 		if ( false !== $this->rewrite && ( is_admin() || get_option( 'permalink_structure' ) ) ) {
    464 			if ( $this->hierarchical && $this->rewrite['hierarchical'] ) {
    465 				$tag = '(.+?)';
    466 			} else {
    467 				$tag = '([^/]+)';
    468 			}
    469 
    470 			add_rewrite_tag( "%$this->name%", $tag, $this->query_var ? "{$this->query_var}=" : "taxonomy=$this->name&term=" );
    471 			add_permastruct( $this->name, "{$this->rewrite['slug']}/%$this->name%", $this->rewrite );
    472 		}
    473 	}
    474 
    475 	/**
    476 	 * Removes any rewrite rules, permastructs, and rules for the taxonomy.
    477 	 *
    478 	 * @since 4.7.0
    479 	 *
    480 	 * @global WP $wp Current WordPress environment instance.
    481 	 */
    482 	public function remove_rewrite_rules() {
    483 		/* @var WP $wp */
    484 		global $wp;
    485 
    486 		// Remove query var.
    487 		if ( false !== $this->query_var ) {
    488 			$wp->remove_query_var( $this->query_var );
    489 		}
    490 
    491 		// Remove rewrite tags and permastructs.
    492 		if ( false !== $this->rewrite ) {
    493 			remove_rewrite_tag( "%$this->name%" );
    494 			remove_permastruct( $this->name );
    495 		}
    496 	}
    497 
    498 	/**
    499 	 * Registers the ajax callback for the meta box.
    500 	 *
    501 	 * @since 4.7.0
    502 	 */
    503 	public function add_hooks() {
    504 		add_filter( 'wp_ajax_add-' . $this->name, '_wp_ajax_add_hierarchical_term' );
    505 	}
    506 
    507 	/**
    508 	 * Removes the ajax callback for the meta box.
    509 	 *
    510 	 * @since 4.7.0
    511 	 */
    512 	public function remove_hooks() {
    513 		remove_filter( 'wp_ajax_add-' . $this->name, '_wp_ajax_add_hierarchical_term' );
    514 	}
    515 
    516 	/**
    517 	 * Gets the REST API controller for this taxonomy.
    518 	 *
    519 	 * Will only instantiate the controller class once per request.
    520 	 *
    521 	 * @since 5.5.0
    522 	 *
    523 	 * @return WP_REST_Controller|null The controller instance, or null if the taxonomy
    524 	 *                                 is set not to show in rest.
    525 	 */
    526 	public function get_rest_controller() {
    527 		if ( ! $this->show_in_rest ) {
    528 			return null;
    529 		}
    530 
    531 		$class = $this->rest_controller_class ? $this->rest_controller_class : WP_REST_Terms_Controller::class;
    532 
    533 		if ( ! class_exists( $class ) ) {
    534 			return null;
    535 		}
    536 
    537 		if ( ! is_subclass_of( $class, WP_REST_Controller::class ) ) {
    538 			return null;
    539 		}
    540 
    541 		if ( ! $this->rest_controller ) {
    542 			$this->rest_controller = new $class( $this->name );
    543 		}
    544 
    545 		if ( ! ( $this->rest_controller instanceof $class ) ) {
    546 			return null;
    547 		}
    548 
    549 		return $this->rest_controller;
    550 	}
    551 }