From 7594dc16459dad75b8b880a8d3f46d94da18d257 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Fri, 5 May 2023 16:58:12 +0100 Subject: [PATCH 1/6] Checkout endpoint work --- src/Templates/CheckoutTemplate.php | 120 ++++++++++++++++++++++++++++- 1 file changed, 118 insertions(+), 2 deletions(-) diff --git a/src/Templates/CheckoutTemplate.php b/src/Templates/CheckoutTemplate.php index 8a32e3e79bf..038578fd658 100644 --- a/src/Templates/CheckoutTemplate.php +++ b/src/Templates/CheckoutTemplate.php @@ -13,10 +13,9 @@ class CheckoutTemplate { /** * Constructor. * - * Templates require FSE theme support, so this will only init if a FSE theme is active. + * Templates require block themes support, so this will only init if a block theme is active. */ public function __construct() { - // Templates require FSE theme support. if ( ! wc_current_theme_is_fse_theme() ) { return; } @@ -27,11 +26,128 @@ public function __construct() { * Initialization method. */ protected function init() { + add_action( 'init', array( $this, 'add_endpoint' ) ); + add_filter( 'pre_get_document_title', array( $this, 'endpoint_title' ) ); + add_filter( 'woocommerce_is_checkout', array( $this, 'is_checkout' ) ); + add_filter( 'woocommerce_settings_pages', array( $this, 'update_settings_page' ) ); + add_action( 'woocommerce_admin_field_endpoint', array( $this, 'input_field' ) ); + + // Todo flushes for the rewrite endpoint. Need to happen when settings change and when the theme changes. + add_action( 'after_switch_theme', 'flush_rewrite_rules' ); + add_action( 'update_option_woocommerce_checkout_pay_endpoint', 'flush_rewrite_rules' ); + add_filter( 'page_template_hierarchy', array( $this, 'update_page_template_hierarchy' ), 1 ); + add_filter( 'frontpage_template_hierarchy', array( $this, 'update_page_template_hierarchy' ), 1 ); add_action( 'current_screen', array( $this, 'template_editor_redirect' ) ); add_filter( 'woocommerce_blocks_template_content', array( $this, 'default_template_content' ), 10, 3 ); } + /** + * Add a query var for the checkout. This will allow to to detect when the user is viewing the checkout. + * + * @todo setting to control `checkout` + */ + public function add_endpoint() { + if ( wc_get_page_id( 'checkout' ) ) { + $default_endpoint = get_post( wc_get_page_id( 'checkout' ) )->post_name ?: __( 'checkout', 'woo-gutenberg-products-block' ); + } else { + $default_endpoint = __( 'checkout', 'woo-gutenberg-products-block' ); + } + $endpoint = get_option( 'woocommerce_checkout_page_endpoint', $default_endpoint ); + $query_vars = WC()->query->get_query_vars(); + + add_rewrite_endpoint( $endpoint . '/' . $query_vars['order-received'], \EP_ROOT, $query_vars['order-received'] ); + add_rewrite_endpoint( $endpoint . '/' . $query_vars['order-pay'], \EP_ROOT, $query_vars['order-pay'] ); + add_rewrite_endpoint( $endpoint, \EP_ROOT, 'checkout' ); + } + + /** + * Returns true when the endpoint is showing. + * + * @return boolean + */ + protected function is_endpoint() { + global $wp; + return isset( $wp->query_vars['checkout'] ); + } + + /** + * Filters the page title when the endpoint is active. + * + * @param string $title Page title. + * @return string + */ + public function endpoint_title( $title ) { + if ( $this->is_endpoint() ) { + return __( 'Checkout', 'woo-gutenberg-products-block' ); + } + return $title; + } + + /** + * Filters the `is_checkout` function so we can return true when the endpoint is active. + * + * @param boolean $return True when on the checkout page. + * @return boolean + */ + public function is_checkout( $return ) { + if ( $this->is_endpoint() ) { + return true; + } + return $return; + } + + public function update_settings_page( $settings ) { + foreach ( $settings as $key => $setting ) { + if ( 'woocommerce_checkout_page_id' === $setting['id'] ) { + if ( wc_get_page_id( 'checkout' ) ) { + $default = get_post( wc_get_page_id( 'checkout' ) )->post_name ?: __( 'checkout', 'woo-gutenberg-products-block' ); + } else { + $default = __( 'checkout', 'woo-gutenberg-products-block' ); + } + $settings[ $key ] = [ + 'title' => __( 'Checkout page', 'woo-gutenberg-products-block' ), + 'desc' => __( 'Endpoint for the checkout page.', 'woo-gutenberg-products-block' ), + 'id' => 'woocommerce_checkout_page_endpoint', + 'type' => 'endpoint', + 'default' => $default, + 'desc_tip' => true, + 'autoload' => false, + ]; + } + } + return $settings; + } + + public function input_field( $value ) { + $field_description = \WC_Admin_Settings::get_field_description( $value ); + $description = $field_description['description']; + $tooltip_html = $field_description['tooltip_html']; + ?> + + + + + + + + + + + + + + Date: Tue, 9 May 2023 11:54:09 +0100 Subject: [PATCH 2/6] Move setting field to util --- src/Templates/CheckoutTemplate.php | 109 +++++++++++++---------------- src/Utils/SettingsUtils.php | 45 ++++++++++++ 2 files changed, 94 insertions(+), 60 deletions(-) create mode 100644 src/Utils/SettingsUtils.php diff --git a/src/Templates/CheckoutTemplate.php b/src/Templates/CheckoutTemplate.php index 038578fd658..15803a45094 100644 --- a/src/Templates/CheckoutTemplate.php +++ b/src/Templates/CheckoutTemplate.php @@ -1,6 +1,8 @@ post_name ?: $default; + } + + return $default; } /** @@ -48,12 +66,7 @@ protected function init() { * @todo setting to control `checkout` */ public function add_endpoint() { - if ( wc_get_page_id( 'checkout' ) ) { - $default_endpoint = get_post( wc_get_page_id( 'checkout' ) )->post_name ?: __( 'checkout', 'woo-gutenberg-products-block' ); - } else { - $default_endpoint = __( 'checkout', 'woo-gutenberg-products-block' ); - } - $endpoint = get_option( 'woocommerce_checkout_page_endpoint', $default_endpoint ); + $endpoint = get_option( 'woocommerce_checkout_page_endpoint', $this->get_default_endpoint() ); $query_vars = WC()->query->get_query_vars(); add_rewrite_endpoint( $endpoint . '/' . $query_vars['order-received'], \EP_ROOT, $query_vars['order-received'] ); @@ -72,12 +85,25 @@ protected function is_endpoint() { } /** - * Filters the page title when the endpoint is active. + * Filters the `is_checkout` function so we can return true when the endpoint is active. + * + * @param boolean $return True when on the checkout page. + * @return boolean + */ + public function is_checkout( $return ) { + if ( $this->is_endpoint() ) { + return true; + } + return $return; + } + + /** + * Filter the page title when the endpoint is active. * * @param string $title Page title. * @return string */ - public function endpoint_title( $title ) { + public function endpoint_page_title( $title ) { if ( $this->is_endpoint() ) { return __( 'Checkout', 'woo-gutenberg-products-block' ); } @@ -85,69 +111,32 @@ public function endpoint_title( $title ) { } /** - * Filters the `is_checkout` function so we can return true when the endpoint is active. + * Update Woo Settings page to include the checkout endpoint instead of the checkout page dropdown. * - * @param boolean $return True when on the checkout page. - * @return boolean + * @param array $settings Settings pages. + * @return array */ - public function is_checkout( $return ) { - if ( $this->is_endpoint() ) { - return true; - } - return $return; - } + public function add_endpoint_field_to_settings_page( $settings ) { + $default_endpoint = $this->get_default_endpoint(); - public function update_settings_page( $settings ) { foreach ( $settings as $key => $setting ) { if ( 'woocommerce_checkout_page_id' === $setting['id'] ) { - if ( wc_get_page_id( 'checkout' ) ) { - $default = get_post( wc_get_page_id( 'checkout' ) )->post_name ?: __( 'checkout', 'woo-gutenberg-products-block' ); - } else { - $default = __( 'checkout', 'woo-gutenberg-products-block' ); - } $settings[ $key ] = [ 'title' => __( 'Checkout page', 'woo-gutenberg-products-block' ), - 'desc' => __( 'Endpoint for the checkout page.', 'woo-gutenberg-products-block' ), + 'desc' => __( 'This is the URL for the checkout page template.', 'woo-gutenberg-products-block' ), 'id' => 'woocommerce_checkout_page_endpoint', - 'type' => 'endpoint', - 'default' => $default, + 'type' => 'permalink', + 'default' => $default_endpoint, 'desc_tip' => true, 'autoload' => false, ]; + + add_action( 'woocommerce_admin_field_permalink', array( SettingsUtils::class, 'permalink_input_field' ) ); } } return $settings; } - public function input_field( $value ) { - $field_description = \WC_Admin_Settings::get_field_description( $value ); - $description = $field_description['description']; - $tooltip_html = $field_description['tooltip_html']; - ?> - - - - - - - - - - - - - - + + + + + + + + + + + + + + Date: Tue, 9 May 2023 12:15:27 +0100 Subject: [PATCH 3/6] Include link to edit the template --- src/Templates/CheckoutTemplate.php | 20 +++++++++++++++++--- src/Utils/SettingsUtils.php | 7 ++++--- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/Templates/CheckoutTemplate.php b/src/Templates/CheckoutTemplate.php index 15803a45094..0616807c456 100644 --- a/src/Templates/CheckoutTemplate.php +++ b/src/Templates/CheckoutTemplate.php @@ -60,6 +60,15 @@ protected function get_default_endpoint() { return $default; } + /** + * URL to edit the template. + * + * @return string + */ + protected function get_edit_template_url() { + return admin_url( 'site-editor.php?postType=wp_template&postId=woocommerce%2Fwoocommerce%2F%2Fcheckout' ); + } + /** * Add a query var for the checkout. This will allow to to detect when the user is viewing the checkout. * @@ -123,11 +132,16 @@ public function add_endpoint_field_to_settings_page( $settings ) { if ( 'woocommerce_checkout_page_id' === $setting['id'] ) { $settings[ $key ] = [ 'title' => __( 'Checkout page', 'woo-gutenberg-products-block' ), - 'desc' => __( 'This is the URL for the checkout page template.', 'woo-gutenberg-products-block' ), + 'desc' => sprintf( + // translators: %1$s: opening anchor tag, %2$s: closing anchor tag. + __( 'The checkout page template can be %1$s edited here%2$s.', 'woo-gutenberg-products-block' ), + '', + '' + ), + 'desc_tip' => __( 'This is the URL to the checkout page.', 'woo-gutenberg-products-block' ), 'id' => 'woocommerce_checkout_page_endpoint', 'type' => 'permalink', 'default' => $default_endpoint, - 'desc_tip' => true, 'autoload' => false, ]; @@ -163,7 +177,7 @@ public function template_editor_redirect( \WP_Screen $current_screen ) { $edit_page_id = 'page' === $current_screen->id && ! empty( $_GET['post'] ) ? absint( $_GET['post'] ) : 0; // phpcs:ignore WordPress.Security.NonceVerification.Recommended if ( $edit_page_id === $page_id ) { - wp_safe_redirect( admin_url( 'site-editor.php?postType=wp_template&postId=woocommerce%2Fwoocommerce%2F%2Fcheckout' ) ); + wp_safe_redirect( $this->get_edit_template_url() ); exit; } } diff --git a/src/Utils/SettingsUtils.php b/src/Utils/SettingsUtils.php index c11f1526817..892af1c1c2f 100644 --- a/src/Utils/SettingsUtils.php +++ b/src/Utils/SettingsUtils.php @@ -23,7 +23,7 @@ public static function permalink_input_field( $value ) { - + @@ -36,8 +36,9 @@ public static function permalink_input_field( $value ) { value="" class="" placeholder="" - /> - + /> + + Date: Tue, 9 May 2023 12:25:34 +0100 Subject: [PATCH 4/6] Remove todo --- src/Templates/CheckoutTemplate.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Templates/CheckoutTemplate.php b/src/Templates/CheckoutTemplate.php index 0616807c456..64d8fcdd356 100644 --- a/src/Templates/CheckoutTemplate.php +++ b/src/Templates/CheckoutTemplate.php @@ -71,8 +71,6 @@ protected function get_edit_template_url() { /** * Add a query var for the checkout. This will allow to to detect when the user is viewing the checkout. - * - * @todo setting to control `checkout` */ public function add_endpoint() { $endpoint = get_option( 'woocommerce_checkout_page_endpoint', $this->get_default_endpoint() ); From 58cb700e085d794ee1aac1fef7b22b2e1770e81e Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Wed, 10 May 2023 16:12:15 +0100 Subject: [PATCH 5/6] Refactor checkout templates to share logic (#9411) --- src/BlockTemplatesController.php | 136 +++++++++++++++++- src/BlockTypes/ClassicTemplate.php | 2 +- src/Templates/AbstractPageTemplate.php | 138 ++++++++++++++++++ src/Templates/CartTemplate.php | 68 +++------ src/Templates/CheckoutTemplate.php | 177 +++--------------------- src/Templates/OrderReceivedTemplate.php | 47 +++---- src/Utils/BlockTemplateUtils.php | 6 +- 7 files changed, 333 insertions(+), 241 deletions(-) create mode 100644 src/Templates/AbstractPageTemplate.php diff --git a/src/BlockTemplatesController.php b/src/BlockTemplatesController.php index a8be46b5798..c009b953d6c 100644 --- a/src/BlockTemplatesController.php +++ b/src/BlockTemplatesController.php @@ -1,7 +1,6 @@ package->is_experimental_build() ) { add_action( 'after_switch_theme', array( $this, 'check_should_use_blockified_product_grid_templates' ), 10, 2 ); } @@ -566,18 +579,18 @@ public function render_block_template() { } } elseif ( is_cart() && - ! BlockTemplateUtils::theme_has_template( CartTemplate::SLUG ) && $this->block_template_is_available( CartTemplate::SLUG ) + ! BlockTemplateUtils::theme_has_template( CartTemplate::get_slug() ) && $this->block_template_is_available( CartTemplate::get_slug() ) ) { add_filter( 'woocommerce_has_block_template', '__return_true', 10, 0 ); } elseif ( is_checkout() && - ! BlockTemplateUtils::theme_has_template( CheckoutTemplate::SLUG ) && $this->block_template_is_available( CheckoutTemplate::SLUG ) + ! BlockTemplateUtils::theme_has_template( CheckoutTemplate::get_slug() ) && $this->block_template_is_available( CheckoutTemplate::get_slug() ) ) { add_filter( 'woocommerce_has_block_template', '__return_true', 10, 0 ); } elseif ( is_wc_endpoint_url( 'order-received' ) - && ! BlockTemplateUtils::theme_has_template( OrderReceivedTemplate::SLUG ) - && $this->block_template_is_available( OrderReceivedTemplate::SLUG ) + && ! BlockTemplateUtils::theme_has_template( OrderReceivedTemplate::get_slug() ) + && $this->block_template_is_available( OrderReceivedTemplate::get_slug() ) ) { add_filter( 'woocommerce_has_block_template', '__return_true', 10, 0 ); } else { @@ -646,4 +659,117 @@ function_exists( 'is_shop' ) && return $post_type_name; } + + /** + * Registers rewrite endpoints for templates during init. + */ + public function register_template_endpoints() { + $query_vars = WC()->query->get_query_vars(); + $cart_page = CartTemplate::get_legacy_page(); + $cart_endpoint = get_option( 'woocommerce_cart_page_endpoint', $cart_page ? $cart_page->post_name : CartTemplate::get_slug() ); + $checkout_page = CheckoutTemplate::get_legacy_page(); + $checkout_endpoint = get_option( 'woocommerce_checkout_page_endpoint', $checkout_page ? $checkout_page->post_name : CheckoutTemplate::get_slug() ); + + add_rewrite_endpoint( $checkout_endpoint . '/' . $query_vars['order-received'], \EP_ROOT, $query_vars['order-received'] ); + add_rewrite_endpoint( $checkout_endpoint . '/' . $query_vars['order-pay'], \EP_ROOT, $query_vars['order-pay'] ); + add_rewrite_endpoint( $checkout_endpoint, \EP_ROOT, CheckoutTemplate::get_slug() ); + add_rewrite_endpoint( $cart_endpoint, \EP_ROOT, CartTemplate::get_slug() ); + } + + /** + * Filters the `is_checkout` function so we can return true when the endpoint is active, or if one of its other endpoints are in use (e.g. order received). + * + * @param boolean $return True when on the checkout page. + * @return boolean + */ + public function is_checkout_endpoint( $return ) { + global $wp; + + if ( isset( $wp->query_vars[ CheckoutTemplate::get_slug() ] ) || isset( $wp->query_vars[ OrderReceivedTemplate::get_slug() ] ) ) { + return true; + } + + return $return; + } + + /** + * Filters the `is_cart` function so we can return true when the endpoint is active. + * + * @param boolean $return True when on the checkout page. + * @return boolean + */ + public function is_cart_endpoint( $return ) { + global $wp; + + if ( isset( $wp->query_vars[ CartTemplate::get_slug() ] ) ) { + return true; + } + + return $return; + } + + /** + * Replace the cart PAGE URL with the template endpoint URL. + * + * @return string + */ + public function get_cart_url() { + return site_url( '/' . CartTemplate::get_slug() ); + } + + /** + * Replace the checkout PAGE URL with the template endpoint URL. + * + * @return string + */ + public function get_checkout_url() { + return site_url( '/' . CheckoutTemplate::get_slug() ); + } + + /** + * Replaces page settings in WooCommerce with text based permalinks which point to a template. + * + * @param array $settings Settings pages. + * @return array + */ + public function template_permalink_settings( $settings ) { + foreach ( $settings as $key => $setting ) { + if ( 'woocommerce_checkout_page_id' === $setting['id'] ) { + $checkout_page = CheckoutTemplate::get_legacy_page(); + $settings[ $key ] = [ + 'title' => __( 'Checkout page', 'woo-gutenberg-products-block' ), + 'desc' => sprintf( + // translators: %1$s: opening anchor tag, %2$s: closing anchor tag. + __( 'The checkout page template can be %1$s edited here%2$s.', 'woo-gutenberg-products-block' ), + '', + '' + ), + 'desc_tip' => __( 'This is the URL to the checkout page.', 'woo-gutenberg-products-block' ), + 'id' => 'woocommerce_checkout_page_endpoint', + 'type' => 'permalink', + 'default' => $checkout_page ? $checkout_page->post_name : CheckoutTemplate::get_slug(), + 'autoload' => false, + ]; + } + if ( 'woocommerce_cart_page_id' === $setting['id'] ) { + $cart_page = CartTemplate::get_legacy_page(); + $settings[ $key ] = [ + 'title' => __( 'Cart page', 'woo-gutenberg-products-block' ), + 'desc' => sprintf( + // translators: %1$s: opening anchor tag, %2$s: closing anchor tag. + __( 'The cart page template can be %1$s edited here%2$s.', 'woo-gutenberg-products-block' ), + '', + '' + ), + 'desc_tip' => __( 'This is the URL to the cart page.', 'woo-gutenberg-products-block' ), + 'id' => 'woocommerce_cart_page_endpoint', + 'type' => 'permalink', + 'default' => $cart_page ? $cart_page->post_name : CartTemplate::get_slug(), + 'autoload' => false, + ]; + } + } + + return $settings; + } } diff --git a/src/BlockTypes/ClassicTemplate.php b/src/BlockTypes/ClassicTemplate.php index 5720eb51cf7..090f15b8e8d 100644 --- a/src/BlockTypes/ClassicTemplate.php +++ b/src/BlockTypes/ClassicTemplate.php @@ -63,7 +63,7 @@ protected function render( $attributes, $content, $block ) { $frontend_scripts::load_scripts(); } - if ( OrderReceivedTemplate::SLUG === $attributes['template'] ) { + if ( OrderReceivedTemplate::get_slug() === $attributes['template'] ) { return $this->render_order_received(); } diff --git a/src/Templates/AbstractPageTemplate.php b/src/Templates/AbstractPageTemplate.php new file mode 100644 index 00000000000..51968c5c49d --- /dev/null +++ b/src/Templates/AbstractPageTemplate.php @@ -0,0 +1,138 @@ +init(); + } + } + + /** + * Initialization method. + */ + protected function init() { + add_filter( 'page_template_hierarchy', array( $this, 'page_template_hierarchy' ), 1 ); + add_filter( 'frontpage_template_hierarchy', array( $this, 'page_template_hierarchy' ), 1 ); + add_filter( 'woocommerce_blocks_template_content', array( $this, 'page_template_content' ), 10, 2 ); + add_action( 'current_screen', array( $this, 'page_template_editor_redirect' ) ); + add_filter( 'pre_get_document_title', array( $this, 'page_template_title' ) ); + } + + /** + * Returns the template slug. + * + * @return string + */ + abstract public static function get_slug(); + + /** + * Returns the page object assigned to this template/page used for legacy purposes. Pages are no longer required. + * + * @return \WP_Post|null Post object or null. + */ + abstract public static function get_legacy_page(); + + /** + * Should return true on pages/endpoints/routes where the template should be shown. + * + * @return boolean + */ + abstract protected function is_active_template(); + + /** + * Should return the title of the page. + * + * @return string + */ + abstract protected function get_template_title(); + + /** + * Returns the URL to edit the template. + * + * @return string + */ + protected function get_edit_template_url() { + return admin_url( 'site-editor.php?postType=wp_template&postId=woocommerce%2Fwoocommerce%2F%2F' . $this->get_slug() ); + } + + /** + * Get the default content for a template. + * + * Overridden by child class to include their own logic. + * + * @param string $template_content The original content of the template. + * @return string + */ + protected function get_default_template_content( $template_content ) { + return $template_content; + } + + /** + * When the page should be displaying the template, add it to the hierarchy. + * + * This places the template name e.g. `cart`, at the beginning of the template hierarchy array. The hook priority + * is 1 to ensure it runs first; other consumers e.g. extensions, could therefore inject their own template instead + * of this one when using the default priority of 10. + * + * @param array $templates Templates that match the pages_template_hierarchy. + */ + public function page_template_hierarchy( $templates ) { + if ( $this->is_active_template() ) { + array_unshift( $templates, $this->get_slug() ); + } + return $templates; + } + + /** + * Returns the default template content. + * + * @param string $template_content The content of the template. + * @param object $template_file The template file object. + * @return string + */ + public function page_template_content( $template_content, $template_file ) { + if ( $this->get_slug() !== $template_file->slug ) { + return $template_content; + } + return $this->get_default_template_content( $template_content ); + } + + /** + * Redirect the edit page screen to the template editor. + * + * @param \WP_Screen $current_screen Current screen information. + */ + public function page_template_editor_redirect( \WP_Screen $current_screen ) { + $page = $this->get_legacy_page(); + $edit_page_id = 'page' === $current_screen->id && ! empty( $_GET['post'] ) ? absint( $_GET['post'] ) : 0; // phpcs:ignore WordPress.Security.NonceVerification.Recommended + + if ( $page && $edit_page_id === $page->id ) { + wp_safe_redirect( $this->get_edit_template_url() ); + exit; + } + } + + /** + * Filter the page title when the template is active. + * + * @param string $title Page title. + * @return string + */ + public function page_template_title( $title ) { + if ( $this->is_active_template() ) { + return $this->get_template_title(); + } + return $title; + } +} diff --git a/src/Templates/CartTemplate.php b/src/Templates/CartTemplate.php index 4064b53aa9b..5de42b8cf73 100644 --- a/src/Templates/CartTemplate.php +++ b/src/Templates/CartTemplate.php @@ -6,78 +6,52 @@ * * @internal */ -class CartTemplate { - - const SLUG = 'cart'; - +class CartTemplate extends AbstractPageTemplate { /** - * Constructor. + * Template slug. * - * Templates require FSE theme support, so this will only init if a FSE theme is active. + * @return string */ - public function __construct() { - // Templates require FSE theme support. - if ( ! wc_current_theme_is_fse_theme() ) { - return; - } - $this->init(); + public static function get_slug() { + return 'cart'; } /** - * Initialization method. + * Returns the page object assigned to this template/page used for legacy purposes. Pages are no longer required. + * + * @return \WP_Post|null Post object or null. */ - protected function init() { - add_filter( 'page_template_hierarchy', array( $this, 'update_page_template_hierarchy' ), 1 ); - add_action( 'current_screen', array( $this, 'template_editor_redirect' ) ); - add_filter( 'woocommerce_blocks_template_content', array( $this, 'default_template_content' ), 10, 3 ); + public static function get_legacy_page() { + $page_id = wc_get_page_id( 'cart' ); + return $page_id ? get_post( $page_id ) : null; } /** - * When the page is displaying the cart and a block theme is active, render the Cart Template. - * - * This places the template name e.g. `cart`, at the beginning of the template hierarchy array. The hook priority - * is 1 to ensure it runs first; other consumers e.g. extensions, could therefore inject their own template instead - * of this one when using the default priority of 10. + * True when viewing the cart page or cart endpoint. * - * @param array $templates Templates that match the pages_template_hierarchy. + * @return boolean */ - public function update_page_template_hierarchy( $templates ) { - if ( is_cart() ) { - array_unshift( $templates, self::SLUG ); - } - return $templates; + protected function is_active_template() { + return is_cart(); } /** - * Redirect a page to the template editor if it's the checkout page and a block theme is active. + * Should return the title of the page. * - * @param \WP_Screen $current_screen Current screen information. + * @return string */ - public function template_editor_redirect( \WP_Screen $current_screen ) { - $page_id = wc_get_page_id( 'cart' ) ?: false; - $edit_page_id = 'page' === $current_screen->id && ! empty( $_GET['post'] ) ? absint( $_GET['post'] ) : 0; // phpcs:ignore WordPress.Security.NonceVerification.Recommended - - if ( $edit_page_id === $page_id ) { - wp_safe_redirect( admin_url( 'site-editor.php?postType=wp_template&postId=woocommerce%2Fwoocommerce%2F%2Fcart' ) ); - exit; - } + protected function get_template_title() { + return __( 'Cart', 'woo-gutenberg-products-block' ); } /** * Migrates an existing page using blocks to the block templates. * * @param string $template_content The content of the template. - * @param object $template_file The template file object. - * @param string $template_type The type of template. * @return string */ - public function default_template_content( $template_content, $template_file, $template_type ) { - if ( self::SLUG !== $template_file->slug ) { - return $template_content; - } - - $page_id = wc_get_page_id( 'cart' ); - $page = $page_id ? get_post( $page_id ) : false; + public function get_default_template_content( $template_content ) { + $page = $this->get_legacy_page(); if ( $page && ! empty( $page->post_content ) ) { $template_content = ' diff --git a/src/Templates/CheckoutTemplate.php b/src/Templates/CheckoutTemplate.php index 64d8fcdd356..316a7c3c389 100644 --- a/src/Templates/CheckoutTemplate.php +++ b/src/Templates/CheckoutTemplate.php @@ -1,200 +1,57 @@ init(); - } - - /** - * Initialization method. - */ - protected function init() { - // Register the endpoint in the rewrite rules. - add_action( 'init', array( $this, 'add_endpoint' ) ); - add_filter( 'woocommerce_is_checkout', array( $this, 'is_checkout' ) ); - add_filter( 'pre_get_document_title', array( $this, 'endpoint_page_title' ) ); - - // Handle settings for endpoints. - add_filter( 'woocommerce_settings_pages', array( $this, 'add_endpoint_field_to_settings_page' ) ); - add_action( 'after_switch_theme', 'flush_rewrite_rules' ); - add_action( 'update_option_woocommerce_checkout_pay_endpoint', 'flush_rewrite_rules' ); - - add_filter( 'page_template_hierarchy', array( $this, 'update_page_template_hierarchy' ), 1 ); - add_filter( 'frontpage_template_hierarchy', array( $this, 'update_page_template_hierarchy' ), 1 ); - add_filter( 'woocommerce_blocks_template_content', array( $this, 'default_template_content' ), 10, 3 ); - add_action( 'current_screen', array( $this, 'template_editor_redirect' ) ); - } - +class CheckoutTemplate extends AbstractPageTemplate { /** - * Get the default endpoint for the template. This defaults to checkout unless a page already exists. + * Template slug. * * @return string */ - protected function get_default_endpoint() { - $default = __( 'checkout', 'woo-gutenberg-products-block' ); - - if ( wc_get_page_id( 'checkout' ) ) { - $page_data = get_post( wc_get_page_id( 'checkout' ) ); - return $page_data->post_name ?: $default; - } - - return $default; - } - - /** - * URL to edit the template. - * - * @return string - */ - protected function get_edit_template_url() { - return admin_url( 'site-editor.php?postType=wp_template&postId=woocommerce%2Fwoocommerce%2F%2Fcheckout' ); - } - - /** - * Add a query var for the checkout. This will allow to to detect when the user is viewing the checkout. - */ - public function add_endpoint() { - $endpoint = get_option( 'woocommerce_checkout_page_endpoint', $this->get_default_endpoint() ); - $query_vars = WC()->query->get_query_vars(); - - add_rewrite_endpoint( $endpoint . '/' . $query_vars['order-received'], \EP_ROOT, $query_vars['order-received'] ); - add_rewrite_endpoint( $endpoint . '/' . $query_vars['order-pay'], \EP_ROOT, $query_vars['order-pay'] ); - add_rewrite_endpoint( $endpoint, \EP_ROOT, 'checkout' ); + public static function get_slug() { + return 'checkout'; } /** - * Returns true when the endpoint is showing. + * Returns the page object assigned to this template/page used for legacy purposes. Pages are no longer required. * - * @return boolean + * @return \WP_Post|null Post object or null. */ - protected function is_endpoint() { - global $wp; - return isset( $wp->query_vars['checkout'] ); + public static function get_legacy_page() { + $page_id = wc_get_page_id( 'checkout' ); + return $page_id ? get_post( $page_id ) : null; } /** - * Filters the `is_checkout` function so we can return true when the endpoint is active. + * True when viewing the cart page or cart endpoint. * - * @param boolean $return True when on the checkout page. * @return boolean */ - public function is_checkout( $return ) { - if ( $this->is_endpoint() ) { - return true; - } - return $return; + public function is_active_template() { + return is_checkout(); } /** - * Filter the page title when the endpoint is active. + * Should return the title of the page. * - * @param string $title Page title. * @return string */ - public function endpoint_page_title( $title ) { - if ( $this->is_endpoint() ) { - return __( 'Checkout', 'woo-gutenberg-products-block' ); - } - return $title; - } - - /** - * Update Woo Settings page to include the checkout endpoint instead of the checkout page dropdown. - * - * @param array $settings Settings pages. - * @return array - */ - public function add_endpoint_field_to_settings_page( $settings ) { - $default_endpoint = $this->get_default_endpoint(); - - foreach ( $settings as $key => $setting ) { - if ( 'woocommerce_checkout_page_id' === $setting['id'] ) { - $settings[ $key ] = [ - 'title' => __( 'Checkout page', 'woo-gutenberg-products-block' ), - 'desc' => sprintf( - // translators: %1$s: opening anchor tag, %2$s: closing anchor tag. - __( 'The checkout page template can be %1$s edited here%2$s.', 'woo-gutenberg-products-block' ), - '', - '' - ), - 'desc_tip' => __( 'This is the URL to the checkout page.', 'woo-gutenberg-products-block' ), - 'id' => 'woocommerce_checkout_page_endpoint', - 'type' => 'permalink', - 'default' => $default_endpoint, - 'autoload' => false, - ]; - - add_action( 'woocommerce_admin_field_permalink', array( SettingsUtils::class, 'permalink_input_field' ) ); - } - } - return $settings; - } - - /** - * When the page is displaying the checkout and a block theme is active, render the Checkout Template. - * - * This places the template name e.g. `checkout`, at the beginning of the template hierarchy array. The hook priority - * is 1 to ensure it runs first; other consumers e.g. extensions, could therefore inject their own template instead - * of this one when using the default priority of 10. - * - * @param array $templates Templates that match the pages_template_hierarchy. - */ - public function update_page_template_hierarchy( $templates ) { - if ( is_checkout() ) { - array_unshift( $templates, self::SLUG ); - } - return $templates; - } - - /** - * Redirect a page to the template editor if it's the checkout page and a block theme is active. - * - * @param \WP_Screen $current_screen Current screen information. - */ - public function template_editor_redirect( \WP_Screen $current_screen ) { - $page_id = wc_get_page_id( 'checkout' ); - $edit_page_id = 'page' === $current_screen->id && ! empty( $_GET['post'] ) ? absint( $_GET['post'] ) : 0; // phpcs:ignore WordPress.Security.NonceVerification.Recommended - - if ( $edit_page_id === $page_id ) { - wp_safe_redirect( $this->get_edit_template_url() ); - exit; - } + protected function get_template_title() { + return __( 'Checkout', 'woo-gutenberg-products-block' ); } /** * Migrates an existing page using blocks to the block templates. * * @param string $template_content The content of the template. - * @param object $template_file The template file object. - * @param string $template_type The type of template. * @return string */ - public function default_template_content( $template_content, $template_file, $template_type ) { - if ( self::SLUG !== $template_file->slug ) { - return $template_content; - } - - $page_id = wc_get_page_id( 'checkout' ); - $page = $page_id ? get_post( $page_id ) : false; + public function get_default_template_content( $template_content ) { + $page = $this->get_legacy_page(); if ( $page && ! empty( $page->post_content ) ) { $template_content = ' diff --git a/src/Templates/OrderReceivedTemplate.php b/src/Templates/OrderReceivedTemplate.php index e6707f06b3a..d2845b85010 100644 --- a/src/Templates/OrderReceivedTemplate.php +++ b/src/Templates/OrderReceivedTemplate.php @@ -6,43 +6,40 @@ * * @internal */ -class OrderReceivedTemplate { - - const SLUG = 'order-received'; - +class OrderReceivedTemplate extends AbstractPageTemplate { /** - * Constructor. + * Template slug. * - * Templates require FSE theme support, so this will only init if a FSE theme is active. + * @return string */ - public function __construct() { - // Templates require FSE theme support. - if ( ! wc_current_theme_is_fse_theme() ) { - return; - } - $this->init(); + public static function get_slug() { + return 'order-received'; } /** - * Initialization method. + * Returns the page object assigned to this template/page used for legacy purposes. Pages are no longer required. + * + * @return \WP_Post|null Post object or null. */ - protected function init() { - add_filter( 'page_template_hierarchy', array( $this, 'update_page_template_hierarchy' ), 1 ); + public static function get_legacy_page() { + return null; } /** - * When it's the Order Received page and a block theme is active, render the Order Received Template. + * True when viewing the cart page or cart endpoint. * - * This places the template name e.g. `order-received`, at the beginning of the template hierarchy array. The hook priority - * is 1 to ensure it runs first; other consumers e.g. extensions, could therefore inject their own template instead - * of this one when using the default priority of 10. + * @return boolean + */ + protected function is_active_template() { + return is_wc_endpoint_url( 'order-received' ); + } + + /** + * Should return the title of the page. * - * @param array $templates Templates that match the pages_template_hierarchy. + * @return string */ - public function update_page_template_hierarchy( $templates ) { - if ( is_wc_endpoint_url( 'order-received' ) ) { - array_unshift( $templates, self::SLUG ); - } - return $templates; + protected function get_template_title() { + return __( 'Order Received', 'woo-gutenberg-products-block' ); } } diff --git a/src/Utils/BlockTemplateUtils.php b/src/Utils/BlockTemplateUtils.php index b1ab42daf73..0c7aa8f0348 100644 --- a/src/Utils/BlockTemplateUtils.php +++ b/src/Utils/BlockTemplateUtils.php @@ -350,15 +350,15 @@ public static function get_plugin_block_template_types() { 'title' => _x( 'Mini Cart', 'Template name', 'woo-gutenberg-products-block' ), 'description' => __( 'Template used to display the Mini Cart drawer.', 'woo-gutenberg-products-block' ), ), - CartTemplate::SLUG => array( + CartTemplate::get_slug() => array( 'title' => _x( 'Cart', 'Template name', 'woo-gutenberg-products-block' ), 'description' => __( 'Template used to display the Cart.', 'woo-gutenberg-products-block' ), ), - CheckoutTemplate::SLUG => array( + CheckoutTemplate::get_slug() => array( 'title' => _x( 'Checkout', 'Template name', 'woo-gutenberg-products-block' ), 'description' => __( 'Template used to display the Checkout.', 'woo-gutenberg-products-block' ), ), - OrderReceivedTemplate::SLUG => array( + OrderReceivedTemplate::get_slug() => array( 'title' => _x( 'Order Received', 'Template name', 'woo-gutenberg-products-block' ), 'description' => __( 'Displays the order confirmation page.', 'woo-gutenberg-products-block' ), ), From 268646b5c8babf9bb26167ce65a6571810675f7b Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Mon, 15 May 2023 16:27:31 +0100 Subject: [PATCH 6/6] Sync endpoints with pages (#9426) * Switch to page syncing * Update settings descriptions --- src/BlockTemplatesController.php | 135 ++++++++++-------------- src/Templates/AbstractPageTemplate.php | 18 ++-- src/Templates/CartTemplate.php | 8 +- src/Templates/CheckoutTemplate.php | 22 ++-- src/Templates/OrderReceivedTemplate.php | 6 +- 5 files changed, 84 insertions(+), 105 deletions(-) diff --git a/src/BlockTemplatesController.php b/src/BlockTemplatesController.php index c009b953d6c..a3119a2da30 100644 --- a/src/BlockTemplatesController.php +++ b/src/BlockTemplatesController.php @@ -9,6 +9,7 @@ use Automattic\WooCommerce\Blocks\Utils\BlockTemplateUtils; use Automattic\WooCommerce\Blocks\Templates\OrderReceivedTemplate; use Automattic\WooCommerce\Blocks\Utils\SettingsUtils; +use \WP_Post; /** * BlockTypesController class. @@ -75,16 +76,9 @@ protected function init() { add_filter( 'post_type_archive_title', array( $this, 'update_product_archive_title' ), 10, 2 ); if ( wc_current_theme_is_fse_theme() ) { - add_action( 'init', array( $this, 'register_template_endpoints' ) ); - add_filter( 'woocommerce_is_checkout', array( $this, 'is_checkout_endpoint' ) ); - add_filter( 'woocommerce_is_cart', array( $this, 'is_cart_endpoint' ) ); - add_filter( 'woocommerce_get_cart_url', array( $this, 'get_cart_url' ) ); - add_filter( 'woocommerce_get_checkout_url', array( $this, 'get_checkout_url' ) ); add_filter( 'woocommerce_settings_pages', array( $this, 'template_permalink_settings' ) ); + add_filter( 'pre_update_option', array( $this, 'update_template_permalink' ), 10, 2 ); add_action( 'woocommerce_admin_field_permalink', array( SettingsUtils::class, 'permalink_input_field' ) ); - add_action( 'after_switch_theme', 'flush_rewrite_rules' ); - add_action( 'update_option_woocommerce_checkout_page_endpoint', 'flush_rewrite_rules' ); - add_action( 'update_option_woocommerce_cart_page_endpoint', 'flush_rewrite_rules' ); } if ( $this->package->is_experimental_build() ) { @@ -660,72 +654,6 @@ function_exists( 'is_shop' ) && return $post_type_name; } - /** - * Registers rewrite endpoints for templates during init. - */ - public function register_template_endpoints() { - $query_vars = WC()->query->get_query_vars(); - $cart_page = CartTemplate::get_legacy_page(); - $cart_endpoint = get_option( 'woocommerce_cart_page_endpoint', $cart_page ? $cart_page->post_name : CartTemplate::get_slug() ); - $checkout_page = CheckoutTemplate::get_legacy_page(); - $checkout_endpoint = get_option( 'woocommerce_checkout_page_endpoint', $checkout_page ? $checkout_page->post_name : CheckoutTemplate::get_slug() ); - - add_rewrite_endpoint( $checkout_endpoint . '/' . $query_vars['order-received'], \EP_ROOT, $query_vars['order-received'] ); - add_rewrite_endpoint( $checkout_endpoint . '/' . $query_vars['order-pay'], \EP_ROOT, $query_vars['order-pay'] ); - add_rewrite_endpoint( $checkout_endpoint, \EP_ROOT, CheckoutTemplate::get_slug() ); - add_rewrite_endpoint( $cart_endpoint, \EP_ROOT, CartTemplate::get_slug() ); - } - - /** - * Filters the `is_checkout` function so we can return true when the endpoint is active, or if one of its other endpoints are in use (e.g. order received). - * - * @param boolean $return True when on the checkout page. - * @return boolean - */ - public function is_checkout_endpoint( $return ) { - global $wp; - - if ( isset( $wp->query_vars[ CheckoutTemplate::get_slug() ] ) || isset( $wp->query_vars[ OrderReceivedTemplate::get_slug() ] ) ) { - return true; - } - - return $return; - } - - /** - * Filters the `is_cart` function so we can return true when the endpoint is active. - * - * @param boolean $return True when on the checkout page. - * @return boolean - */ - public function is_cart_endpoint( $return ) { - global $wp; - - if ( isset( $wp->query_vars[ CartTemplate::get_slug() ] ) ) { - return true; - } - - return $return; - } - - /** - * Replace the cart PAGE URL with the template endpoint URL. - * - * @return string - */ - public function get_cart_url() { - return site_url( '/' . CartTemplate::get_slug() ); - } - - /** - * Replace the checkout PAGE URL with the template endpoint URL. - * - * @return string - */ - public function get_checkout_url() { - return site_url( '/' . CheckoutTemplate::get_slug() ); - } - /** * Replaces page settings in WooCommerce with text based permalinks which point to a template. * @@ -735,12 +663,12 @@ public function get_checkout_url() { public function template_permalink_settings( $settings ) { foreach ( $settings as $key => $setting ) { if ( 'woocommerce_checkout_page_id' === $setting['id'] ) { - $checkout_page = CheckoutTemplate::get_legacy_page(); + $checkout_page = CheckoutTemplate::get_placeholder_page(); $settings[ $key ] = [ 'title' => __( 'Checkout page', 'woo-gutenberg-products-block' ), 'desc' => sprintf( // translators: %1$s: opening anchor tag, %2$s: closing anchor tag. - __( 'The checkout page template can be %1$s edited here%2$s.', 'woo-gutenberg-products-block' ), + __( 'The checkout template can be %1$s edited here%2$s.', 'woo-gutenberg-products-block' ), '', '' ), @@ -752,12 +680,12 @@ public function template_permalink_settings( $settings ) { ]; } if ( 'woocommerce_cart_page_id' === $setting['id'] ) { - $cart_page = CartTemplate::get_legacy_page(); + $cart_page = CartTemplate::get_placeholder_page(); $settings[ $key ] = [ 'title' => __( 'Cart page', 'woo-gutenberg-products-block' ), 'desc' => sprintf( // translators: %1$s: opening anchor tag, %2$s: closing anchor tag. - __( 'The cart page template can be %1$s edited here%2$s.', 'woo-gutenberg-products-block' ), + __( 'The cart template can be %1$s edited here%2$s.', 'woo-gutenberg-products-block' ), '', '' ), @@ -772,4 +700,55 @@ public function template_permalink_settings( $settings ) { return $settings; } + + /** + * Syncs entered permalink with the pages and returns the correct value. + * + * @param string $value Value of the option. + * @param string $option Name of the option. + * @return string + */ + public function update_template_permalink( $value, $option ) { + if ( 'woocommerce_checkout_page_endpoint' === $option ) { + return $this->sync_endpoint_with_page( CheckoutTemplate::get_placeholder_page(), 'checkout', $value ); + } + if ( 'woocommerce_cart_page_endpoint' === $option ) { + return $this->sync_endpoint_with_page( CartTemplate::get_placeholder_page(), 'cart', $value ); + } + return $value; + } + + /** + * Syncs the provided permalink with the actual WP page. + * + * @param WP_Post|null $page The page object, or null if it does not exist. + * @param string $page_slug The identifier for the page e.g. cart, checkout. + * @param string $permalink The new permalink to use. + * @return string THe actual permalink assigned to the page. May differ from $permalink if it was already taken. + */ + protected function sync_endpoint_with_page( $page, $page_slug, $permalink ) { + if ( ! $page ) { + $updated_page_id = wc_create_page( + esc_sql( $permalink ), + 'woocommerce_' . $page_slug . '_page_id', + $page_slug, + '', + '', + 'publish' + ); + } else { + $updated_page_id = wp_update_post( + [ + 'ID' => $page->ID, + 'post_name' => esc_sql( $permalink ), + ] + ); + } + + // Get post again in case slug was updated with a suffix. + if ( $updated_page_id && ! is_wp_error( $updated_page_id ) ) { + return get_post( $updated_page_id )->post_name; + } + return $permalink; + } } diff --git a/src/Templates/AbstractPageTemplate.php b/src/Templates/AbstractPageTemplate.php index 51968c5c49d..df267c9525d 100644 --- a/src/Templates/AbstractPageTemplate.php +++ b/src/Templates/AbstractPageTemplate.php @@ -37,25 +37,25 @@ protected function init() { abstract public static function get_slug(); /** - * Returns the page object assigned to this template/page used for legacy purposes. Pages are no longer required. + * Returns the page object assigned to this template/page. * * @return \WP_Post|null Post object or null. */ - abstract public static function get_legacy_page(); + abstract public static function get_placeholder_page(); /** - * Should return true on pages/endpoints/routes where the template should be shown. + * Should return the title of the page. * - * @return boolean + * @return string */ - abstract protected function is_active_template(); + abstract public static function get_template_title(); /** - * Should return the title of the page. + * Should return true on pages/endpoints/routes where the template should be shown. * - * @return string + * @return boolean */ - abstract protected function get_template_title(); + abstract protected function is_active_template(); /** * Returns the URL to edit the template. @@ -114,7 +114,7 @@ public function page_template_content( $template_content, $template_file ) { * @param \WP_Screen $current_screen Current screen information. */ public function page_template_editor_redirect( \WP_Screen $current_screen ) { - $page = $this->get_legacy_page(); + $page = $this->get_placeholder_page(); $edit_page_id = 'page' === $current_screen->id && ! empty( $_GET['post'] ) ? absint( $_GET['post'] ) : 0; // phpcs:ignore WordPress.Security.NonceVerification.Recommended if ( $page && $edit_page_id === $page->id ) { diff --git a/src/Templates/CartTemplate.php b/src/Templates/CartTemplate.php index 5de42b8cf73..f5c916cd3ff 100644 --- a/src/Templates/CartTemplate.php +++ b/src/Templates/CartTemplate.php @@ -17,11 +17,11 @@ public static function get_slug() { } /** - * Returns the page object assigned to this template/page used for legacy purposes. Pages are no longer required. + * Returns the page object assigned to this template/page. * * @return \WP_Post|null Post object or null. */ - public static function get_legacy_page() { + public static function get_placeholder_page() { $page_id = wc_get_page_id( 'cart' ); return $page_id ? get_post( $page_id ) : null; } @@ -40,7 +40,7 @@ protected function is_active_template() { * * @return string */ - protected function get_template_title() { + public static function get_template_title() { return __( 'Cart', 'woo-gutenberg-products-block' ); } @@ -51,7 +51,7 @@ protected function get_template_title() { * @return string */ public function get_default_template_content( $template_content ) { - $page = $this->get_legacy_page(); + $page = $this->get_placeholder_page(); if ( $page && ! empty( $page->post_content ) ) { $template_content = ' diff --git a/src/Templates/CheckoutTemplate.php b/src/Templates/CheckoutTemplate.php index 316a7c3c389..6c991922b81 100644 --- a/src/Templates/CheckoutTemplate.php +++ b/src/Templates/CheckoutTemplate.php @@ -17,31 +17,31 @@ public static function get_slug() { } /** - * Returns the page object assigned to this template/page used for legacy purposes. Pages are no longer required. + * Returns the page object assigned to this template/page. * * @return \WP_Post|null Post object or null. */ - public static function get_legacy_page() { + public static function get_placeholder_page() { $page_id = wc_get_page_id( 'checkout' ); return $page_id ? get_post( $page_id ) : null; } /** - * True when viewing the cart page or cart endpoint. + * Should return the title of the page. * - * @return boolean + * @return string */ - public function is_active_template() { - return is_checkout(); + public static function get_template_title() { + return __( 'Checkout', 'woo-gutenberg-products-block' ); } /** - * Should return the title of the page. + * True when viewing the cart page or cart endpoint. * - * @return string + * @return boolean */ - protected function get_template_title() { - return __( 'Checkout', 'woo-gutenberg-products-block' ); + public function is_active_template() { + return is_checkout(); } /** @@ -51,7 +51,7 @@ protected function get_template_title() { * @return string */ public function get_default_template_content( $template_content ) { - $page = $this->get_legacy_page(); + $page = $this->get_placeholder_page(); if ( $page && ! empty( $page->post_content ) ) { $template_content = ' diff --git a/src/Templates/OrderReceivedTemplate.php b/src/Templates/OrderReceivedTemplate.php index d2845b85010..3fd14e9d22d 100644 --- a/src/Templates/OrderReceivedTemplate.php +++ b/src/Templates/OrderReceivedTemplate.php @@ -17,11 +17,11 @@ public static function get_slug() { } /** - * Returns the page object assigned to this template/page used for legacy purposes. Pages are no longer required. + * Returns the page object assigned to this template/page. * * @return \WP_Post|null Post object or null. */ - public static function get_legacy_page() { + public static function get_placeholder_page() { return null; } @@ -39,7 +39,7 @@ protected function is_active_template() { * * @return string */ - protected function get_template_title() { + public static function get_template_title() { return __( 'Order Received', 'woo-gutenberg-products-block' ); } }