lesystem) templates that have the same slug as a customised one. We don't need to check // for `woocommerce` in $template->source here because woocommerce templates won't have been added to $templates // if a saved version was found in the db. This only affects saved templates that were saved BEFORE a theme // template with the same slug was added. return array_values( array_filter( $templates, function ( $template ) use ( $customised_template_slugs ) { // This template has been customised and saved as a post, so return it. return ! ( 'theme' === $template->source && in_array( $template->slug, $customised_template_slugs, true ) ); } ) ); } /** * Removes customized templates that shouldn't be available. That means customized templates based on the * WooCommerce default template when there is a customized template based on the theme template. * * @param \WP_Block_Template[]|\stdClass[] $templates List of templates to run the filter on. * @param string $theme_slug Slug of the theme currently active. * * @return array Filtered list of templates with only relevant templates available. */ public static function remove_duplicate_customized_templates( $templates, $theme_slug ) { $filtered_templates = array_filter( $templates, function ( $template ) use ( $templates, $theme_slug ) { if ( $template->theme === $theme_slug ) { // This is a customized template based on the theme template, so it should be returned. return true; } // This is a template customized from the WooCommerce default template. // Only return it if there isn't a customized version of the theme template. $is_there_a_customized_theme_template = array_filter( $templates, function ( $theme_template ) use ( $template, $theme_slug ) { return $theme_template->slug === $template->slug && $theme_template->theme === $theme_slug; } ); if ( $is_there_a_customized_theme_template ) { return false; } return true; }, ); return $filtered_templates; } /** * Returns whether the blockified templates should be used or not. * If the option is not stored on the db, we need to check if the current theme is a block one or not. * * @return boolean */ public static function should_use_blockified_product_grid_templates() { $use_blockified_templates = get_option( Options::WC_BLOCK_USE_BLOCKIFIED_PRODUCT_GRID_BLOCK_AS_TEMPLATE ); if ( false === $use_blockified_templates ) { return wc_current_theme_is_fse_theme(); } return wc_string_to_bool( $use_blockified_templates ); } /** * Returns whether the passed `$template` has the legacy template block. * * @param object $template The template object. * @return boolean */ public static function template_has_legacy_template_block( $template ) { return has_block( 'woocommerce/legacy-template', $template->content ); } /** * Updates the title, description and area of a template to the correct values and to make them more user-friendly. * For example, instead of: * - Title: `Tag (product_tag)` * - Description: `Displays taxonomy: Tag.` * we display: * - Title: `Products by Tag` * - Description: `Displays products filtered by a tag.`. * * @param WP_Block_Template $template The template object. * @param string $template_type wp_template or wp_template_part. * * @return WP_Block_Template */ public static function update_template_data( $template, $template_type ) { if ( ! $template ) { return $template; } if ( empty( $template->title ) || $template->title === $template->slug ) { $template->title = self::get_block_template_title( $template->slug ); } if ( empty( $template->description ) ) { $template->description = self::get_block_template_description( $template->slug ); } if ( empty( $template->area ) || 'uncategorized' === $template->area ) { $template->area = self::get_block_template_area( $template->slug, $template_type ); } return $template; } /** * Gets the templates saved in the database. * * @param array $slugs An array of slugs to retrieve templates for. * @param string $template_type wp_template or wp_template_part. * * @return int[]|\WP_Post[] An array of found templates. */ public static function get_block_templates_from_db( $slugs = array(), $template_type = 'wp_template' ) { $check_query_args = array( 'post_type' => $template_type, 'posts_per_page' => -1, 'no_found_rows' => true, 'tax_query' => array( // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_tax_query array( 'taxonomy' => 'wp_theme', 'field' => 'name', 'terms' => array( self::DEPRECATED_PLUGIN_SLUG, self::PLUGIN_SLUG, get_stylesheet() ), ), ), ); if ( is_array( $slugs ) && count( $slugs ) > 0 ) { $check_query_args['post_name__in'] = $slugs; } $check_query = new \WP_Query( $check_query_args ); $saved_woo_templates = $check_query->posts; return array_map( function ( $saved_woo_template ) { return self::build_template_result_from_post( $saved_woo_template ); }, $saved_woo_templates ); } /** * Gets the template part by slug * * @param string $slug The template part slug. * * @return string The template part content. */ public static function get_template_part( $slug ) { $templates_from_db = self::get_block_templates_from_db( array( $slug ), 'wp_template_part' ); if ( count( $templates_from_db ) > 0 ) { $template_slug_to_load = $templates_from_db[0]->theme; } else { $theme_has_template = self::theme_has_template_part( $slug ); $template_slug_to_load = $theme_has_template ? get_stylesheet() : self::PLUGIN_SLUG; } $template_part = get_block_template( $template_slug_to_load . '//' . $slug, 'wp_template_part' ); if ( $template_part && ! empty( $template_part->content ) ) { return $template_part->content; } // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents return file_get_contents( self::get_templates_directory( 'wp_template_part' ) . DIRECTORY_SEPARATOR . $slug . '.html' ); } }