-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTerm.php
149 lines (130 loc) · 5.89 KB
/
Term.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
<?php //phpcs:disable SlevomatCodingStandard.Operators.SpreadOperatorSpacing.IncorrectSpacesAfterOperator
namespace XWP\Helper\Functions;
use Closure;
use WP_Error;
use WP_Term;
/**
* Taxonomy and term helper functions.
*/
final class Term {
/**
* Formats a term name with its ancestors.
*
* @param WP_Term|int|string|null|array|\WP_Error $term WP_Term object, Term ID, Term slug, or Term name.
* @param array<string, mixed> $args Formatting arguments. Default empty array.
* - formatter (callable) Custom formatter for the displayed term name. Default null.
* - count (bool) Whether to include the term count in the formatted name. Default false.
* - link_format (string|callable|array|bool) URL Link format for the term link. Default false.
* - link_items (bool) Whether to link the term items. Default false.
* - link_final (bool) Whether to link the final term. Default true.
* - separator (string) Separator between terms. Default ' > '.
* - taxonomy (string) Taxonomy name. Default null. Mandatory if $term is a string. Optional otherwise.
* @return string Formatted term name with ancestors.
*/
public static function format_hierarhical_name( WP_Term|int|string|null|array|\WP_Error $term, array $args = array() ): string {
$args = self::parse_format_args( $args );
$term = self::get_term_object( $term, $args['taxonomy'] ?? null );
if ( ! $term ) {
return '';
}
$formatter = self::get_name_formatter( $args );
$formatted = \array_map( 'get_term', \get_ancestors( $term->term_id, $term->taxonomy ) );
$formatted = \array_map( $formatter, \array_reverse( $formatted ) );
$formatted[] = $args['link_final'] ? $formatter( $term ) : $term->name;
$formatted = \implode( $args['separator'], $formatted );
return $args['show_count'] ? \sprintf( '%s (%d)', $formatted, $term->count ) : $formatted;
}
/**
* Parse the arguments for the term name formatter.
*
* @param array $args The arguments for the term name formatter.
* @return array
*/
private static function parse_format_args( array $args ): array {
$defs = array(
'formatter' => null,
'link_final' => true,
'link_format' => true,
'link_items' => true,
'separator' => ' > ',
'show_count' => false,
'taxonomy' => null,
);
if ( ! $args['link_format'] ) {
$args['link_items'] = false;
$args['link_final'] = false;
}
return \wp_parse_args( $args, $defs );
}
/**
* Get the formatter for the term name.
*
* @param array $args The arguments for the term name formatter.
* @return Closure
*/
private static function get_name_formatter( array $args ): Closure {
if ( \is_callable( $args['formatter'] ?? null ) ) {
return static fn( $t ) => $args['formatter']( $t );
}
$formatter ??= $args['link_items'] && $args['link_format']
? self::get_link_formatter( $args['link_format'] )
: null;
if ( ! $formatter ) {
return static fn( WP_Term $term ) => \esc_html( $term->name );
}
return static fn( WP_Term $term ) => \sprintf(
'<a href="%s">%s</a>',
\esc_url( $formatter( $term ) ),
\esc_html( $term->name ),
);
}
/**
* Get the link formatter for the term name.
*
* @param string|callable|array|bool $fmt The link format for the term name.
* @return Closure|null
*/
private static function get_link_formatter( string|callable|array|bool $fmt ): ?Closure {
return match ( true ) {
\is_bool( $fmt ) && $fmt => static fn( $t ) => \get_term_link( $t ),
\is_array( $fmt ) => static fn( $t ) => \call_user_func( $fmt, $t ),
\is_string( $fmt ) => static fn( $t ) => \add_query_arg( $t->taxonomy, $t->slug, $fmt ),
\is_callable( $fmt ) => static fn( $t ) => $fmt( $t ),
default => null,
};
}
/**
* Get a term object from a variety of inputs.
*
* @param WP_Term|\WP_Error|int|string|null|array $from The term object, term ID, term slug, term name, or term array.
* @param string|null $tax The taxonomy name.
*/
public static function get_term_object( WP_Term|\WP_Error|int|string|null|array $from, ?string $tax = null ): ?WP_Term {
$term = match ( true ) {
$from instanceof WP_Term => $from,
\is_numeric( $from ) => \get_term( \absint( $from ) ),
\is_string( $from ) && $tax => \get_term_by( 'slug', $from, $tax ),
\is_array( $from ) => self::get_term_object_from_array( $from, $tax ),
\is_wp_error( $from ) => null,
default => null,
};
return $term instanceof WP_Term ? $term : null;
}
/**
* Get a term object from an array.
*
* @param array $arr The term array.
* @param string|null $taxonomy The taxonomy name.
* @return WP_Term|\WP_Error|null|bool The term object or error.
*/
private static function get_term_object_from_array( array $arr, ?string $taxonomy = null ): WP_Term|\WP_Error|null|bool {
$tax = $taxonomy ?? $arr['taxonomy'] ?? $arr['tax'] ?? null;
$id = $arr['term_id'] ?? $arr['id'] ?? $arr['ID'] ?? false;
return match ( true ) {
false !== $id && 0 > $id => \get_term_by( 'id', $id, $tax ),
isset( $arr['slug'], $tax ) => \get_term_by( 'slug', $arr['slug'], $tax ),
isset( $arr['name'], $tax ) => \get_term_by( 'name', $arr['name'], $tax ),
default => null,
};
}
}