tags->addContext( $this->getContexts() ); aioseo()->tags->addTags( $this->getTags() ); } /** * Replace the tags in the string provided. * * @since 4.1.1 * * @param string $string The string with tags. * @param array $item The breadcrumb item. * @param boolean $stripPunctuation Whether we should strip punctuation after the tags have been converted. * @return string The string with tags replaced. */ public function replaceTags( $string, $item, $stripPunctuation = false ) { if ( ! $string || ! preg_match( '/#/', (string) $string ) ) { return $string; } // Replace separator tag so we don't strip it as punctuation. $separatorTag = aioseo()->tags->denotationChar . 'separator_sa'; $string = preg_replace( "/$separatorTag(?![a-zA-Z0-9_])/im", '>thisisjustarandomplaceholder<', (string) $string ); // Replace custom breadcrumb tags. foreach ( $this->getTags() as $tag ) { $tagId = aioseo()->tags->denotationChar . $tag['id']; $pattern = "/$tagId(?![a-zA-Z0-9_])/im"; if ( preg_match( $pattern, (string) $string ) ) { $tagValue = str_replace( '$', '\$', (string) $this->getTagValue( $tag, $item ) ); $string = preg_replace( $pattern, $tagValue, (string) $string ); } } if ( $stripPunctuation ) { $string = aioseo()->helpers->stripPunctuation( $string ); } // Remove any remaining tags from the title attribute. $string = preg_replace_callback( '/title="([^"]*)"/i', function ( $matches ) { $sanitizedTitle = wp_strip_all_tags( aioseo()->helpers->decodeHtmlEntities( $matches[1] ) ); return 'title="' . esc_attr( $sanitizedTitle ) . '"'; }, aioseo()->helpers->decodeHtmlEntities( $string ) ); return preg_replace( '/>thisisjustarandomplaceholder<(?![a-zA-Z0-9_])/im', aioseo()->helpers->decodeHtmlEntities( aioseo()->options->searchAppearance->global->separator ), (string) $string ); } /** * Get the value of the tag to replace. * * @since 4.1.1 * @version 5.0.3 Return an empty value when the crumb isn't of the tag's kind. * * @param string $tag The tag to look for. * @param int $item The crumb array. * @return string The value of the tag. */ public function getTagValue( $tag, $item ) { $product = false; if ( 0 === stripos( $tag['id'], 'breadcrumb_wc_product_' ) ) { $product = wc_get_product( $item['reference'] ); if ( ! $product ) { return; } } switch ( $tag['id'] ) { case 'breadcrumb_link': return $item['link']; case 'breadcrumb_separator': return aioseo()->breadcrumbs->frontend->getSeparator(); case 'breadcrumb_wc_product_price': return $product ? wc_price( $product->get_price() ) : ''; case 'breadcrumb_wc_product_sku': return $product ? $product->get_sku() : ''; case 'breadcrumb_wc_product_brand': return $product ? aioseo()->helpers->getWooCommerceBrand( $product->get_id() ) : ''; // A template can use any tag on any crumb, so each one only applies to crumbs of its own kind. case 'breadcrumb_author_first_name': return is_a( $item['reference'], 'WP_User' ) ? $item['reference']->first_name : ''; case 'breadcrumb_author_last_name': return is_a( $item['reference'], 'WP_User' ) ? $item['reference']->last_name : ''; case 'breadcrumb_archive_post_type_name': return is_a( $item['reference'], 'WP_Post_Type' ) ? $item['reference']->label : ''; case 'breadcrumb_search_string': return is_scalar( $item['reference'] ) ? (string) $item['reference'] : ''; case 'breadcrumb_format_page_number': return is_array( $item['reference'] ) && isset( $item['reference']['paged'] ) ? $item['reference']['paged'] : ''; default: return $item['label']; } } /** * Gets our breadcrumb custom tags. * * @since 4.1.1 * * @return array An array of tags. */ public function getTags() { $tags = [ [ 'id' => 'breadcrumb_link', 'name' => __( 'Permalink', 'all-in-one-seo-pack' ), 'description' => __( 'The permalink.', 'all-in-one-seo-pack' ) ], [ 'id' => 'breadcrumb_label', 'name' => __( 'Label', 'all-in-one-seo-pack' ), 'description' => __( 'The label.', 'all-in-one-seo-pack' ) ], [ 'id' => 'breadcrumb_post_title', // Translators: 1 - The type of page (Post, Page, Category, Tag, etc.). 'name' => sprintf( _x( '%1$s Title', 'SEO template tag', 'all-in-one-seo-pack' ), 'Post' ), 'description' => __( 'The original title of the current post.', 'all-in-one-seo-pack' ) ], [ 'id' => 'breadcrumb_taxonomy_title', // Translators: 1 - The type of page (Post, Page, Category, Tag, etc.). 'name' => sprintf( _x( '%1$s Title', 'SEO template tag', 'all-in-one-seo-pack' ), 'Category' ), // Translators: 1 - The name of a taxonomy. 'description' => sprintf( __( 'The %1$s title.', 'all-in-one-seo-pack' ), 'Category' ) ], [ 'id' => 'breadcrumb_separator', 'name' => __( 'Separator', 'all-in-one-seo-pack' ), 'description' => __( 'The crumb separator.', 'all-in-one-seo-pack' ) ], [ 'id' => 'breadcrumb_blog_page_title', 'name' => __( 'Blog Page Title', 'all-in-one-seo-pack' ), 'description' => __( 'The blog page title.', 'all-in-one-seo-pack' ) ], [ 'id' => 'breadcrumb_author_display_name', 'name' => __( 'Author Display Name', 'all-in-one-seo-pack' ), 'description' => __( 'The author\'s display name.', 'all-in-one-seo-pack' ) ], [ 'id' => 'breadcrumb_author_first_name', 'name' => __( 'Author First Name', 'all-in-one-seo-pack' ), 'description' => __( 'The author\'s first name.', 'all-in-one-seo-pack' ) ], [ 'id' => 'breadcrumb_author_last_name', 'name' => __( 'Author Last Name', 'all-in-one-seo-pack' ), 'description' => __( 'The author\'s last name.', 'all-in-one-seo-pack' ) ], [ 'id' => 'breadcrumb_search_result_format', 'name' => __( 'Search result format', 'all-in-one-seo-pack' ), 'description' => __( 'The search result format.', 'all-in-one-seo-pack' ) ], [ 'id' => 'breadcrumb_404_error_format', 'name' => __( '404 Error Format', 'all-in-one-seo-pack' ), 'description' => __( 'The 404 error format.', 'all-in-one-seo-pack' ) ], [ 'id' => 'breadcrumb_date_archive_year', 'name' => __( 'Year', 'all-in-one-seo-pack' ), 'description' => __( 'The year.', 'all-in-one-seo-pack' ) ], [ 'id' => 'breadcrumb_date_archive_month', 'name' => __( 'Month', 'all-in-one-seo-pack' ), 'description' => __( 'The month.', 'all-in-one-seo-pack' ) ], [ 'id' => 'breadcrumb_date_archive_day', 'name' => __( 'Day', 'all-in-one-seo-pack' ), 'description' => __( 'The day.', 'all-in-one-seo-pack' ) ], [ 'id' => 'breadcrumb_search_string', 'name' => __( 'Search String', 'all-in-one-seo-pack' ), 'description' => __( 'The search string.', 'all-in-one-seo-pack' ) ], [ 'id' => 'breadcrumb_format_page_number', 'name' => __( 'Page Number', 'all-in-one-seo-pack' ), 'description' => __( 'The page number.', 'all-in-one-seo-pack' ) ], [ 'id' => 'breadcrumb_archive_post_type_format', 'name' => __( 'Archive format', 'all-in-one-seo-pack' ), 'description' => __( 'The archive format.', 'all-in-one-seo-pack' ) ], [ 'id' => 'breadcrumb_archive_post_type_name', 'name' => __( 'Post Type Name', 'all-in-one-seo-pack' ), 'description' => __( 'The archive post type name.', 'all-in-one-seo-pack' ) ] ]; $postTypes = aioseo()->helpers->getPublicPostTypes(); foreach ( $postTypes as $postType ) { if ( 'product' === $postType['name'] && aioseo()->helpers->isWoocommerceActive() ) { $tags[] = [ 'id' => 'breadcrumb_wc_product_price', // Translators: 1 - The name of a post type. 'name' => sprintf( __( '%1$s Price', 'all-in-one-seo-pack' ), $postType['singular'] ), // Translators: 1 - The name of a post type. 'description' => sprintf( __( 'The %1$s price.', 'all-in-one-seo-pack' ), $postType['singular'] ) ]; $tags[] = [ 'id' => 'breadcrumb_wc_product_sku', // Translators: 1 - The name of a post type. 'name' => sprintf( __( '%1$s SKU', 'all-in-one-seo-pack' ), $postType['singular'] ), // Translators: 1 - The name of a post type. 'description' => sprintf( __( 'The %1$s SKU.', 'all-in-one-seo-pack' ), $postType['singular'] ) ]; $tags[] = [ 'id' => 'breadcrumb_wc_product_brand', // Translators: 1 - The name of a post type. 'name' => sprintf( __( '%1$s Brand', 'all-in-one-seo-pack' ), $postType['singular'] ), // Translators: 1 - The name of a post type. 'description' => sprintf( __( 'The %1$s brand.', 'all-in-one-seo-pack' ), $postType['singular'] ) ]; } } return $tags; } /** * Gets our breadcrumb contexts. * * @since 4.1.1 * * @return array An array of contexts. */ public function getContexts() { $contexts = []; $baseTags = [ 'breadcrumb_link', 'breadcrumb_separator' ]; $postTypes = aioseo()->helpers->getPublicPostTypes(); foreach ( $postTypes as $postType ) { $contexts[ 'breadcrumbs-post-type-' . $postType['name'] ] = array_merge( $baseTags, [ 'breadcrumb_post_title' ] ); if ( 'product' === $postType['name'] && aioseo()->helpers->isWoocommerceActive() ) { $contexts[ 'breadcrumbs-post-type-' . $postType['name'] ] = array_merge( $contexts[ 'breadcrumbs-post-type-' . $postType['name'] ], [ 'breadcrumb_wc_product_price', 'breadcrumb_wc_product_sku', 'breadcrumb_wc_product_brand' ] ); } } $taxonomies = aioseo()->helpers->getPublicTaxonomies(); foreach ( $taxonomies as $taxonomy ) { $contexts[ 'breadcrumbs-taxonomy-' . $taxonomy['name'] ] = array_merge( $baseTags, [ 'breadcrumb_taxonomy_title' ] ); } $archives = aioseo()->helpers->getPublicPostTypes( false, true, true ); foreach ( $archives as $archive ) { $contexts[ 'breadcrumbs-post-type-archive-' . $archive['name'] ] = array_merge( $baseTags, [ 'breadcrumb_archive_post_type_format', 'breadcrumb_archive_post_type_name' ] ); } $contexts['breadcrumbs-blog-archive'] = array_merge( $baseTags, [ 'breadcrumb_blog_page_title' ] ); $contexts['breadcrumbs-author'] = array_merge( $baseTags, [ 'breadcrumb_author_display_name', 'breadcrumb_author_first_name', 'breadcrumb_author_last_name' ] ); $contexts['breadcrumbs-search'] = array_merge( $baseTags, [ 'breadcrumb_search_result_format', 'breadcrumb_search_string' ] ); $contexts['breadcrumbs-notFound'] = array_merge( $baseTags, [ 'breadcrumb_404_error_format' ] ); $contexts['breadcrumbs-date-archive-year'] = array_merge( $baseTags, [ 'breadcrumb_date_archive_year' ] ); $contexts['breadcrumbs-date-archive-month'] = array_merge( $baseTags, [ 'breadcrumb_date_archive_month' ] ); $contexts['breadcrumbs-date-archive-day'] = array_merge( $baseTags, [ 'breadcrumb_date_archive_day' ] ); $contexts['breadcrumbs-format-archive'] = [ 'breadcrumb_archive_post_type_name' ]; $contexts['breadcrumbs-format-search'] = [ 'breadcrumb_search_string' ]; $contexts['breadcrumbs-format-paged'] = [ 'breadcrumb_format_page_number' ]; return $contexts; } }