Skip to content

Commit

Permalink
Make it so Products by Category and Products by Tag aren't listed in …
Browse files Browse the repository at this point in the history
…the Site Editor templates list by default (II)
  • Loading branch information
Aljullu committed Feb 19, 2024
1 parent a624ea4 commit ef336c7
Show file tree
Hide file tree
Showing 2 changed files with 141 additions and 105 deletions.
133 changes: 41 additions & 92 deletions plugins/woocommerce/src/Blocks/BlockTemplatesController.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ public function __construct() {
* Initialization method.
*/
protected function init() {
add_filter( 'pre_get_block_template', array( $this, 'get_block_template_fallback' ), 10, 3 );
add_filter( 'pre_get_block_file_template', array( $this, 'get_block_file_template' ), 10, 3 );
add_filter( 'get_block_template', array( $this, 'add_block_template_details' ), 10, 3 );
add_filter( 'get_block_templates', array( $this, 'add_block_templates' ), 10, 3 );
Expand Down Expand Up @@ -124,76 +123,6 @@ public function render_woocommerce_template_part( $attributes ) {
return function_exists( '\gutenberg_render_block_core_template_part' ) ? \gutenberg_render_block_core_template_part( $attributes ) : \render_block_core_template_part( $attributes );
}

/**
* This function is used on the `pre_get_block_template` hook to return the fallback template from the db in case
* the template is eligible for it.
*
* @param \WP_Block_Template|null $template Block template object to short-circuit the default query,
* or null to allow WP to run its normal queries.
* @param string $id Template unique identifier (example: theme_slug//template_slug).
* @param string $template_type wp_template or wp_template_part.
*
* @return object|null
*/
public function get_block_template_fallback( $template, $id, $template_type ) {
// Add protection against invalid ids.
if ( ! is_string( $id ) || ! strstr( $id, '//' ) ) {
return null;
}
// Add protection against invalid template types.
if (
'wp_template' !== $template_type &&
'wp_template_part' !== $template_type
) {
return null;
}
$template_name_parts = explode( '//', $id );
$theme = $template_name_parts[0] ?? '';
$slug = $template_name_parts[1] ?? '';

if ( empty( $theme ) || empty( $slug ) || ! BlockTemplateUtils::template_is_eligible_for_product_archive_fallback( $slug ) ) {
return null;
}

$wp_query_args = array(
'post_name__in' => array( 'archive-product', $slug ),
'post_type' => $template_type,
'post_status' => array( 'auto-draft', 'draft', 'publish', 'trash' ),
'no_found_rows' => true,
'tax_query' => array( // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_tax_query
array(
'taxonomy' => 'wp_theme',
'field' => 'name',
'terms' => $theme,
),
),
);
$template_query = new \WP_Query( $wp_query_args );
$posts = $template_query->posts;

// If we have more than one result from the query, it means that the current template is present in the db (has
// been customized by the user) and we should not return the `archive-product` template.
if ( count( $posts ) > 1 ) {
return null;
}

if ( count( $posts ) > 0 && 'archive-product' === $posts[0]->post_name ) {
$template = _build_block_template_result_from_post( $posts[0] );

if ( ! is_wp_error( $template ) ) {
$template->id = $theme . '//' . $slug;
$template->slug = $slug;
$template->title = BlockTemplateUtils::get_block_template_title( $slug );
$template->description = BlockTemplateUtils::get_block_template_description( $slug );
unset( $template->source );

return $template;
}
}

return $template;
}

/**
* Adds the `archive-product` template to the `taxonomy-product_cat`, `taxonomy-product_tag`, `taxonomy-attribute`
* templates to be able to fall back to it.
Expand Down Expand Up @@ -330,6 +259,28 @@ public function add_block_templates( $query_result, $query, $template_type ) {
return $query_result;
}

// We need to remove theme (i.e. filesystem) templates that have the same slug as a customised one.
// This only affects saved templates that were saved BEFORE a theme template with the same slug was added.
$query_result = BlockTemplateUtils::remove_theme_templates_with_custom_alternative( $query_result );

// There is the chance that the user customized the default template, installed a theme with a custom template
// and customized that one as well. When that happens, duplicates might appear in the list.
// See: https://github.com/woocommerce/woocommerce/issues/42220.
$theme_slug = wp_get_theme()->get_stylesheet();
$query_result = BlockTemplateUtils::remove_duplicate_customized_templates( $query_result, $theme_slug );

/**
* WC templates from theme aren't included in `$this->get_block_templates()` but are handled by Gutenberg.
* We need to do additional search through all templates file to update title and description for WC
* templates that aren't listed in theme.json.
*/
$query_result = array_map(
function( $template ) use ( $template_type ) {
return BlockTemplateUtils::update_template_data( $template, $template_type );
},
$query_result
);

$post_type = isset( $query['post_type'] ) ? $query['post_type'] : '';
$slugs = isset( $query['slug__in'] ) ? $query['slug__in'] : array();
$template_files = $this->get_block_templates( $slugs, $template_type );
Expand Down Expand Up @@ -361,28 +312,26 @@ public function add_block_templates( $query_result, $query, $template_type ) {
$query_result[] = $template_file;
continue;
}
}

// We need to remove theme (i.e. filesystem) templates that have the same slug as a customised one.
// This only affects saved templates that were saved BEFORE a theme template with the same slug was added.
$query_result = BlockTemplateUtils::remove_theme_templates_with_custom_alternative( $query_result );

// There is the chance that the user customized the default template, installed a theme with a custom template
// and customized that one as well. When that happens, duplicates might appear in the list.
// See: https://github.com/woocommerce/woocommerce/issues/42220.
$query_result = BlockTemplateUtils::remove_duplicate_customized_templates( $query_result, $theme_slug );

/**
* WC templates from theme aren't included in `$this->get_block_templates()` but are handled by Gutenberg.
* We need to do additional search through all templates file to update title and description for WC
* templates that aren't listed in theme.json.
*/
$query_result = array_map(
function( $template ) use ( $template_type ) {
return BlockTemplateUtils::update_template_data( $template, $template_type );
},
$query_result
);
$template_data = BlockTemplatesRegistry::get_template( $template_file->slug );
if ( isset( $template_data->fallback_template ) ) {
continue;
}
$is_not_custom = false === array_search(
$theme_slug . '//' . $template_file->slug,
array_column( $query_result, 'id' ),
true
);
$fits_slug_query =
! isset( $query['slug__in'] ) || in_array( $template_file->slug, $query['slug__in'], true );
$fits_area_query =
! isset( $query['area'] ) || ( property_exists( $template_file, 'area' ) && $template_file->area === $query['area'] );
$should_include = $is_not_custom && $fits_slug_query && $fits_area_query;
if ( $should_include ) {
$template = BlockTemplateUtils::build_template_result_from_file( $template_file, $template_type );
$query_result[] = $template;
}
}

return $query_result;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,100 @@ public function __construct() {
* Initialization method.
*/
public function init() {
// Make it searching for a template returns the default WooCommerce template.
add_filter( 'pre_get_block_template', array( $this, 'get_block_template_fallback' ), 10, 3 );
add_filter( 'taxonomy_template_hierarchy', array( $this, 'template_hierarchy' ), 1 );
}

/**
* This function is used on the `pre_get_block_template` hook to return the fallback template from the db in case
* the template is eligible for it.
*
* @param \WP_Block_Template|null $template Block template object to short-circuit the default query,
* or null to allow WP to run its normal queries.
* @param string $id Template unique identifier (example: theme_slug//template_slug).
* @param string $template_type wp_template or wp_template_part.
*
* @return object|null
*/
public function get_block_template_fallback( $template, $id, $template_type ) {
// Add protection against invalid ids.
if ( ! is_string( $id ) || ! strstr( $id, '//' ) ) {
return null;
}
// Add protection against invalid template types.
if (
'wp_template' !== $template_type &&
'wp_template_part' !== $template_type
) {
return null;
}
$template_name_parts = explode( '//', $id );
$theme = $template_name_parts[0] ?? '';
$slug = $template_name_parts[1] ?? '';

if ( empty( $theme ) || empty( $slug ) || ! BlockTemplateUtils::template_is_eligible_for_product_archive_fallback( $slug ) ) {
return null;
}
if ( BlockTemplateUtils::theme_has_template( $this->slug ) ) {
return null;
}

$wp_query_args = array(
'post_name__in' => array( 'archive-product', $slug ),
'post_type' => $template_type,
'post_status' => array( 'auto-draft', 'draft', 'publish', 'trash' ),
'no_found_rows' => true,
'tax_query' => array( // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_tax_query
array(
'taxonomy' => 'wp_theme',
'field' => 'name',
'terms' => $theme,
),
),
);
$template_query = new \WP_Query( $wp_query_args );
$posts = $template_query->posts;

// If we have more than one result from the query, it means that the current template is present in the db (has
// been customized by the user) and we should not return the `archive-product` template.
if ( count( $posts ) > 1 ) {
return null;
}

if ( count( $posts ) > 0 && 'archive-product' === $posts[0]->post_name ) {
$template = _build_block_template_result_from_post( $posts[0] );

if ( ! is_wp_error( $template ) ) {
$template->id = $theme . '//' . $slug;
$template->slug = $slug;
$template->title = BlockTemplateUtils::get_block_template_title( $slug );
$template->description = BlockTemplateUtils::get_block_template_description( $slug );
unset( $template->source );

return $template;
}
}

if ( count( $posts ) > 0 ) {
$template = _build_block_template_result_from_post( $posts[0] );
$directory = BlockTemplateUtils::get_templates_directory( 'wp_template' );
$template_file_path = $directory . '/' . $this->fallback_template . '.html';
$theme_slug = wp_get_theme()->get_stylesheet();

// Add fallback content when creating the page.
if ( $template->id === $theme_slug . '//' . $this->slug && ( ! isset( $template->content ) || '' === $template->content ) ) {
$fallback_template_content = file_get_contents( $template_file_path );
$template->content = BlockTemplateUtils::inject_theme_attribute_in_content( $fallback_template_content );
// Remove the term description block from the archive-product template
// as the Product Catalog/Shop page doesn't have a description.
$template->content = str_replace( '<!-- wp:term-description {"align":"wide"} /-->', '', $template->content );
}
}

return $template;
}

/**
* When the page should be displaying the template, add it to the hierarchy.
*
Expand Down Expand Up @@ -65,10 +156,6 @@ public function template_hierarchy( $templates ) {
* @return array
*/
public function add_block_templates( $query_result, $query, $template_type ) {
// Is it's not the same area, do nothing.
if ( isset( $query['area'] ) && 'wp_template' !== $query['area'] ) {
return $query_result;
}
// Is it's not the same slug, do nothing.
if ( isset( $query['slug__in'] ) && ! in_array( $this->slug, $query['slug__in'], true ) ) {
return $query_result;
Expand All @@ -77,20 +164,20 @@ public function add_block_templates( $query_result, $query, $template_type ) {
if ( 'wp_template' !== $template_type ) {
return $query_result;
}
// If template is in DB, do nothing.
if ( count( $query_result ) > 0 ) {
// If the theme has the template, do nothing.
if ( BlockTemplateUtils::theme_has_template( $this->slug ) ) {
return $query_result;
}
// If template is in theme, do nothing.
if ( BlockTemplateUtils::theme_has_template( $this->slug ) ) {
$directory = BlockTemplateUtils::get_templates_directory( 'wp_template' );
$template_file_path = $directory . '/' . $this->fallback_template . '.html';
// If template is in DB, do nothing.
if ( count( $query_result ) > 0 ) {
return $query_result;
}

$directory = BlockTemplateUtils::get_templates_directory( 'wp_template' );
$template_file_path = $directory . '/' . $this->slug . '.html';
$template_object = BlockTemplateUtils::create_new_block_template_object( $template_file_path, 'wp_template', $this->slug, true );
$template = BlockTemplateUtils::build_template_result_from_file( $template_object, 'wp_template' );
$query_result[] = $template;
$template_object = BlockTemplateUtils::create_new_block_template_object( $template_file_path, 'wp_template', $this->slug, true );
$template = BlockTemplateUtils::build_template_result_from_file( $template_object, 'wp_template' );
$query_result[] = $template;

return $query_result;
}
Expand Down

0 comments on commit ef336c7

Please sign in to comment.