wc_product_post_type_link() │ WC 1.0
Filter to allow product_cat in the permalinks for products.
Хуки из функции
Возвращает
Строку.
Использование
wc_product_post_type_link( $permalink, $post );
- $permalink(строка) (обязательный)
- The existing permalink URL.
- $post(WP_Post) (обязательный)
- WP_Post object.
Код wc_product_post_type_link() wc product post type link WC 10.7.0
function wc_product_post_type_link( $permalink, $post ) {
// Abort if post is not a product.
if ( 'product' !== $post->post_type ) {
return $permalink;
}
// Abort early if the placeholder rewrite tag isn't in the generated URL.
if ( false === strpos( $permalink, '%' ) ) {
return $permalink;
}
// Only process category if the permalink structure uses category placeholders.
$needs_category = strpos( $permalink, '%category%' ) !== false || strpos( $permalink, '%product_cat%' ) !== false;
$product_cat = '';
if ( $needs_category ) {
// Get the custom taxonomy terms in use by this post.
$terms = get_the_terms( $post->ID, 'product_cat' );
if ( ! empty( $terms ) && ! is_wp_error( $terms ) && is_array( $terms ) ) {
// Re-index array to ensure sequential keys starting from 0 since filters may remove some keys.
$terms = array_values( $terms );
// Find the deepest category (most ancestors) for the permalink.
$deepest_term = $terms[0];
$deepest_ancestors = $deepest_term->parent ? get_ancestors( $deepest_term->term_id, 'product_cat' ) : array();
foreach ( $terms as $term ) {
if ( $term->term_id === $deepest_term->term_id ) {
continue;
}
// Skip root categories - they can't be deeper than current.
if ( ! $term->parent ) {
continue;
}
$ancestors = get_ancestors( $term->term_id, 'product_cat' );
if ( count( $ancestors ) > count( $deepest_ancestors ) ) {
$deepest_ancestors = $ancestors;
$deepest_term = $term;
}
}
/**
* Filter the product category used for the product permalink.
*
* By default, the deepest category (most ancestors) is selected. Prior to 9.9.0,
* categories were sorted by parent term ID descending, then term ID ascending.
* This filter allows customization of which category is used in the product permalink.
*
* @since 2.4.0
* @since 9.9.0 Selection algorithm changed to use deepest category instead of sort order.
*
* @param WP_Term $deepest_term The selected category term object (deepest category since 9.9.0).
* @param WP_Term[] $terms All category terms assigned to the product.
* @param WP_Post $post The product post object.
*/
$category_object = apply_filters( 'wc_product_post_type_link_product_cat', $deepest_term, $terms, $post );
$category_object = ! $category_object instanceof WP_Term ? $deepest_term : $category_object;
$product_cat = $category_object->slug;
if ( $category_object->parent ) {
// Reuse cached ancestors if the filter didn't change the category, otherwise fetch them.
$ancestors = ( $category_object->term_id === $deepest_term->term_id )
? $deepest_ancestors
: get_ancestors( $category_object->term_id, 'product_cat' );
foreach ( $ancestors as $ancestor ) {
$ancestor_object = get_term( $ancestor, 'product_cat' );
/**
* Filter whether to use only the top-level parent category in the product permalink.
*
* When true, only the top-level ancestor category slug is used instead of
* the full category hierarchy path (e.g., 'parent' instead of 'parent/child/grandchild').
*
* @since 2.6.5
*
* @param bool $use_parent_only Whether to use only the top-level parent category. Default false.
*/
if ( apply_filters( 'woocommerce_product_post_type_link_parent_category_only', false ) ) {
$product_cat = $ancestor_object->slug;
} else {
$product_cat = $ancestor_object->slug . '/' . $product_cat;
}
}
}
} else {
// If no terms are assigned to this post, use a string instead (can't leave the placeholder there).
$product_cat = _x( 'uncategorized', 'slug', 'woocommerce' );
}
}
$find = array(
'%year%',
'%monthnum%',
'%day%',
'%hour%',
'%minute%',
'%second%',
'%post_id%',
'%category%',
'%product_cat%',
);
$replace = array(
date_i18n( 'Y', strtotime( $post->post_date ) ),
date_i18n( 'm', strtotime( $post->post_date ) ),
date_i18n( 'd', strtotime( $post->post_date ) ),
date_i18n( 'H', strtotime( $post->post_date ) ),
date_i18n( 'i', strtotime( $post->post_date ) ),
date_i18n( 's', strtotime( $post->post_date ) ),
(string) $post->ID,
$product_cat,
$product_cat,
);
$permalink = str_replace( $find, $replace, $permalink );
return $permalink;
}