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 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;
}