274 lines
8.7 KiB
PHP
274 lines
8.7 KiB
PHP
<?php
|
|
declare( strict_types=1 );
|
|
|
|
namespace ExtCPTs;
|
|
|
|
class Taxonomy {
|
|
|
|
/**
|
|
* Default arguments for custom taxonomies.
|
|
* Several of these differ from the defaults in WordPress' register_taxonomy() function.
|
|
*
|
|
* @var array<string,mixed>
|
|
*/
|
|
protected array $defaults = [
|
|
'public' => true,
|
|
'show_ui' => true,
|
|
'hierarchical' => true,
|
|
'query_var' => true,
|
|
'exclusive' => false, # Custom arg
|
|
'allow_hierarchy' => false, # Custom arg
|
|
];
|
|
|
|
public string $taxonomy;
|
|
|
|
/**
|
|
* @var array<int,string>
|
|
*/
|
|
public array $object_type;
|
|
|
|
public string $tax_slug;
|
|
|
|
public string $tax_singular;
|
|
|
|
public string $tax_plural;
|
|
|
|
public string $tax_singular_low;
|
|
|
|
public string $tax_plural_low;
|
|
|
|
/**
|
|
* @var array<string,mixed>
|
|
*/
|
|
public array $args;
|
|
|
|
/**
|
|
* Class constructor.
|
|
*
|
|
* @see register_extended_taxonomy()
|
|
*
|
|
* @param string $taxonomy The taxonomy name.
|
|
* @param array<int,string> $object_type Names of the object types for the taxonomy.
|
|
* @param array<string,mixed> $args Optional. The taxonomy arguments.
|
|
* @param array<string,string> $names Optional. An associative array of the plural, singular, and slug names.
|
|
* @phpstan-param array{
|
|
* plural?: string,
|
|
* singular?: string,
|
|
* slug?: string,
|
|
* } $names
|
|
*/
|
|
public function __construct( string $taxonomy, array $object_type, array $args = [], array $names = [] ) {
|
|
/**
|
|
* Filter the arguments for a taxonomy.
|
|
*
|
|
* @since 4.4.1
|
|
*
|
|
* @param array<string,mixed> $args The taxonomy arguments.
|
|
* @param string $taxonomy The taxonomy name.
|
|
*/
|
|
$args = apply_filters( 'ext-taxos/args', $args, $taxonomy );
|
|
|
|
/**
|
|
* Filter the arguments for this taxonomy.
|
|
*
|
|
* @since 2.0.0
|
|
*
|
|
* @param array<string,mixed> $args The taxonomy arguments.
|
|
*/
|
|
$args = apply_filters( "ext-taxos/{$taxonomy}/args", $args );
|
|
|
|
/**
|
|
* Filter the plural, singular, and slug for a taxonomy.
|
|
*
|
|
* @since 4.4.1
|
|
*
|
|
* @param array<string,string> $names The plural, singular, and slug names (if any were specified).
|
|
* @param string $taxonomy The taxonomy name.
|
|
*/
|
|
$names = apply_filters( 'ext-taxos/names', $names, $taxonomy );
|
|
|
|
/**
|
|
* Filter the plural, singular, and slug for this taxonomy.
|
|
*
|
|
* @since 2.0.0
|
|
*
|
|
* @param array<string,string> $names The plural, singular, and slug names (if any were specified).
|
|
*/
|
|
$names = apply_filters( "ext-taxos/{$taxonomy}/names", $names );
|
|
|
|
if ( isset( $names['singular'] ) ) {
|
|
$this->tax_singular = $names['singular'];
|
|
} else {
|
|
$this->tax_singular = ucwords( str_replace( [ '-', '_' ], ' ', $taxonomy ) );
|
|
}
|
|
|
|
if ( isset( $names['slug'] ) ) {
|
|
$this->tax_slug = $names['slug'];
|
|
} elseif ( isset( $names['plural'] ) ) {
|
|
$this->tax_slug = $names['plural'];
|
|
} else {
|
|
$this->tax_slug = $taxonomy . 's';
|
|
}
|
|
|
|
if ( isset( $names['plural'] ) ) {
|
|
$this->tax_plural = $names['plural'];
|
|
} else {
|
|
$this->tax_plural = ucwords( str_replace( [ '-', '_' ], ' ', $this->tax_slug ) );
|
|
}
|
|
|
|
$this->object_type = $object_type;
|
|
$this->taxonomy = strtolower( $taxonomy );
|
|
$this->tax_slug = strtolower( $this->tax_slug );
|
|
|
|
# Build our base taxonomy names:
|
|
# Lower-casing is not forced if the name looks like an initialism, eg. FAQ.
|
|
if ( ! preg_match( '/[A-Z]{2,}/', $this->tax_singular ) ) {
|
|
$this->tax_singular_low = strtolower( $this->tax_singular );
|
|
} else {
|
|
$this->tax_singular_low = $this->tax_singular;
|
|
}
|
|
|
|
if ( ! preg_match( '/[A-Z]{2,}/', $this->tax_plural ) ) {
|
|
$this->tax_plural_low = strtolower( $this->tax_plural );
|
|
} else {
|
|
$this->tax_plural_low = $this->tax_plural;
|
|
}
|
|
|
|
# Build our labels:
|
|
$this->defaults['labels'] = [
|
|
'menu_name' => $this->tax_plural,
|
|
'name' => $this->tax_plural,
|
|
'singular_name' => $this->tax_singular,
|
|
'name_admin_bar' => $this->tax_singular,
|
|
'search_items' => sprintf( 'Search %s', $this->tax_plural ),
|
|
'popular_items' => sprintf( 'Popular %s', $this->tax_plural ),
|
|
'all_items' => sprintf( 'All %s', $this->tax_plural ),
|
|
'archives' => sprintf( '%s Archives', $this->tax_plural ),
|
|
'parent_item' => sprintf( 'Parent %s', $this->tax_singular ),
|
|
'parent_item_colon' => sprintf( 'Parent %s:', $this->tax_singular ),
|
|
'edit_item' => sprintf( 'Edit %s', $this->tax_singular ),
|
|
'view_item' => sprintf( 'View %s', $this->tax_singular ),
|
|
'update_item' => sprintf( 'Update %s', $this->tax_singular ),
|
|
'add_new_item' => sprintf( 'Add New %s', $this->tax_singular ),
|
|
'new_item_name' => sprintf( 'New %s Name', $this->tax_singular ),
|
|
'separate_items_with_commas' => sprintf( 'Separate %s with commas', $this->tax_plural_low ),
|
|
'add_or_remove_items' => sprintf( 'Add or remove %s', $this->tax_plural_low ),
|
|
'choose_from_most_used' => sprintf( 'Choose from most used %s', $this->tax_plural_low ),
|
|
'not_found' => sprintf( 'No %s found', $this->tax_plural_low ),
|
|
'no_terms' => sprintf( 'No %s', $this->tax_plural_low ),
|
|
'filter_by_item' => sprintf( 'Filter by %s', $this->tax_singular_low ),
|
|
'items_list_navigation' => sprintf( '%s list navigation', $this->tax_plural ),
|
|
'items_list' => sprintf( '%s list', $this->tax_plural ),
|
|
'most_used' => 'Most Used',
|
|
'back_to_items' => sprintf( '← Back to %s', $this->tax_plural ),
|
|
'item_link' => sprintf( '%s Link', $this->tax_singular ),
|
|
'item_link_description' => sprintf( 'A link to a %s.', $this->tax_singular_low ),
|
|
'template_name' => sprintf( '%s Archives', $this->tax_singular ),
|
|
'no_item' => sprintf( 'No %s', $this->tax_singular_low ), # Custom label
|
|
'filter_by' => sprintf( 'Filter by %s', $this->tax_singular_low ), # Custom label
|
|
];
|
|
|
|
# Only set rewrites if we need them
|
|
if ( isset( $args['public'] ) && ! $args['public'] ) {
|
|
$this->defaults['rewrite'] = false;
|
|
} else {
|
|
$this->defaults['rewrite'] = [
|
|
'slug' => $this->tax_slug,
|
|
'with_front' => false,
|
|
'hierarchical' => isset( $args['allow_hierarchy'] ) ? $args['allow_hierarchy'] : $this->defaults['allow_hierarchy'],
|
|
];
|
|
}
|
|
|
|
# Merge our args with the defaults:
|
|
$this->args = array_merge( $this->defaults, $args );
|
|
|
|
# This allows the 'labels' arg to contain some, none or all labels:
|
|
if ( isset( $args['labels'] ) ) {
|
|
$this->args['labels'] = array_merge( $this->defaults['labels'], $args['labels'] );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Initialise the taxonomy by adding the necessary actions and filters.
|
|
*/
|
|
public function init(): void {
|
|
# Rewrite testing:
|
|
if ( $this->args['rewrite'] ) {
|
|
add_filter( 'rewrite_testing_tests', [ $this, 'rewrite_testing_tests' ], 1 );
|
|
}
|
|
|
|
# Register taxonomy:
|
|
$this->register_taxonomy();
|
|
|
|
/**
|
|
* Fired when the extended taxonomy instance is set up.
|
|
*
|
|
* @since 4.0.0
|
|
*
|
|
* @param \ExtCPTs\Taxonomy $instance The extended taxonomy instance.
|
|
*/
|
|
do_action( "ext-taxos/{$this->taxonomy}/instance", $this );
|
|
}
|
|
|
|
/**
|
|
* Add our rewrite tests to the Rewrite Rule Testing tests array.
|
|
*
|
|
* @codeCoverageIgnore
|
|
*
|
|
* @param array<string,array<string,string>> $tests The existing rewrite rule tests.
|
|
* @return array<string,array<string,string>> Updated rewrite rule tests.
|
|
*/
|
|
public function rewrite_testing_tests( array $tests ): array {
|
|
require_once __DIR__ . '/ExtendedRewriteTesting.php';
|
|
require_once __DIR__ . '/TaxonomyRewriteTesting.php';
|
|
|
|
$extended = new TaxonomyRewriteTesting( $this );
|
|
|
|
return array_merge( $tests, $extended->get_tests() );
|
|
}
|
|
|
|
/**
|
|
* Registers our taxonomy.
|
|
*/
|
|
public function register_taxonomy(): void {
|
|
if ( true === $this->args['query_var'] ) {
|
|
$query_var = $this->taxonomy;
|
|
} else {
|
|
$query_var = $this->args['query_var'];
|
|
}
|
|
|
|
$post_types = get_post_types(
|
|
[
|
|
'query_var' => $query_var,
|
|
]
|
|
);
|
|
|
|
if ( $query_var && count( $post_types ) ) {
|
|
trigger_error(
|
|
esc_html(
|
|
sprintf(
|
|
/* translators: %s: Taxonomy query variable name */
|
|
__( 'Taxonomy query var "%s" clashes with a post type query var of the same name', 'extended-cpts' ),
|
|
$query_var
|
|
)
|
|
),
|
|
E_USER_ERROR
|
|
);
|
|
} elseif ( in_array( $query_var, [ 'type', 'tab' ], true ) ) {
|
|
trigger_error(
|
|
esc_html(
|
|
sprintf(
|
|
/* translators: %s: Taxonomy query variable name */
|
|
__( 'Taxonomy query var "%s" is not allowed', 'extended-cpts' ),
|
|
$query_var
|
|
)
|
|
),
|
|
E_USER_ERROR
|
|
);
|
|
} else {
|
|
register_taxonomy( $this->taxonomy, $this->object_type, $this->args );
|
|
}
|
|
}
|
|
|
|
}
|