Skip to content

Commit

Permalink
feat(Functions): Added term utils
Browse files Browse the repository at this point in the history
  • Loading branch information
seebeen committed Aug 29, 2024
1 parent 72da061 commit 70444a5
Show file tree
Hide file tree
Showing 3 changed files with 171 additions and 1 deletion.
149 changes: 149 additions & 0 deletions Term.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,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 $args['formatter']( ... );
}

$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 => \get_term_link( ... ),
\is_callable( $fmt ) => $fmt( ... ),
\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 ),
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,
};
}
}
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"prefer-stable": true,
"autoload": {
"psr-4": {
"XWP\\Helper\\Functions\\": ""
"XWP\\Helper\\Functions\\": "."
},
"files": [
"xwp-helper-fns.php"
Expand Down
21 changes: 21 additions & 0 deletions xwp-helper-fns.php
Original file line number Diff line number Diff line change
Expand Up @@ -223,3 +223,24 @@ function xwp_fetch_req_var( $key, $def = null ) {
return f\Request::fetch_req_var( $key, $def );
}
endif;


if ( ! function_exists( 'xwp_format_term_name' ) ) :
/**
* Format a term name with term parents.
*
* @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.
*/
function xwp_format_term_name( WP_Term|int|string|null|array|\WP_Error $term, array $args = array() ): string {
return f\Term::format_hierarhical_name( $term, $args );
}
endif;

0 comments on commit 70444a5

Please sign in to comment.