diff --git a/amp.php b/amp.php index 8090d1e422d..e4aa3a69529 100644 --- a/amp.php +++ b/amp.php @@ -296,7 +296,6 @@ function amp_correct_query_when_is_front_page( WP_Query $query ) { * 'template_dir' => 'my-amp-templates', * ) ); * - * @todo Why do we even need this function? * @see \AMP_Theme_Support::is_paired_available() * * @return boolean Whether this is in AMP 'canonical' mode, that is whether it is native and there is not separate AMP URL current URL. @@ -319,18 +318,9 @@ function amp_is_canonical() { if ( ! empty( $args['template_dir'] ) ) { return false; } -// -// // Otherwise, the available_callback dictates whether AMP is available. -// if ( isset( $args['available_callback'] ) && is_callable( $args['available_callback'] ) ) { -// return call_user_func( $args['available_callback'] ); -// } } return true; } -// -//function amp_is_available() { -// -//} /** * Load classes. diff --git a/includes/admin/class-amp-post-meta-box.php b/includes/admin/class-amp-post-meta-box.php index 55842b335ba..71fe1bc39aa 100644 --- a/includes/admin/class-amp-post-meta-box.php +++ b/includes/admin/class-amp-post-meta-box.php @@ -170,8 +170,6 @@ public function render_status( $post ) { is_post_type_viewable( $post->post_type ) && current_user_can( 'edit_post', $post->ID ) - && - ! amp_is_canonical() ); if ( true !== $verify ) { diff --git a/includes/amp-helper-functions.php b/includes/amp-helper-functions.php index f4a4491647e..04d250d2a37 100644 --- a/includes/amp-helper-functions.php +++ b/includes/amp-helper-functions.php @@ -317,60 +317,23 @@ function is_amp_endpoint() { return false; } - // Otherwise, it is an AMP endpoint if AMP is available. - return amp_get_availability(); -} - -/** - * Determine availability of AMP for the given query. - * - * @since 1.0 - * @global WP_Query $wp_the_query - * - * @param WP_Query|null $query Query. If null then the global query will be used. - * @return bool Whether AMP is available. - */ -function amp_get_availability( $query = null ) { - global $wp_the_query; - if ( ! $query ) { - $query = $wp_the_query; - } - - if ( ! ( $query instanceof WP_Query ) ) { - _doing_it_wrong( __FUNCTION__, esc_html__( 'No WP_Query available.', 'amp' ), '1.0' ); - return false; - } - - $available = null; - if ( current_theme_supports( 'amp' ) ) { - $args = get_theme_support( 'amp' ); - if ( isset( $args[0]['available_callback'] ) && is_callable( $args[0]['available_callback'] ) ) { - $callback = $args[0]['available_callback']; - - // If the available_callback is a method on the query, then call the method on the query itself. - if ( is_string( $callback ) && 'is_' === substr( $callback, 0, 3 ) && method_exists( $query, $callback ) ) { - $available = call_user_func( array( $query, $callback ) ); - } else { - $available = call_user_func( $callback ); - } - } - } - - // Availability has been is programmatically determined via the available_callback. - if ( is_bool( $available ) ) { - return $available; - } - - if ( $query->is_singular() ) { + // Check if the queried object supports AMP. + if ( is_singular() ) { /** * Post. * * @var WP_Post $queried_object */ - $queried_object = $query->get_queried_object(); - return post_supports_amp( $queried_object ); // @todo FAIL: This is calling get_support_errors(), and get_support_errors() is calling amp_get_availability(). + $queried_object = get_queried_object(); + if ( ! post_supports_amp( $queried_object ) ) { + return false; + } + } + + if ( current_theme_supports( 'amp' ) ) { + return true === AMP_Theme_Support::get_template_availability(); } else { - return (bool) AMP_Options_Manager::get_option( 'non_singular_supported' ); // @todo Consider other kinds of queries. + return false; // Legacy templates only support posts via AMP_Post_Template. } } diff --git a/includes/class-amp-post-type-support.php b/includes/class-amp-post-type-support.php index cc74157d379..22a1bef580b 100644 --- a/includes/class-amp-post-type-support.php +++ b/includes/class-amp-post-type-support.php @@ -94,23 +94,6 @@ public static function get_support_errors( $post ) { $errors[] = 'skip-post'; } - $query = new WP_Query(); - - $query->queried_object = $post; - $query->queried_object_id = $post->ID; - if ( 'page' === $post->post_type ) { - $query->set( 'post_id', $post->ID ); - } else { - $query->set( 'p', $post->ID ); - } - $query->parse_query(); - - $availability = amp_get_availability( $query ); - if ( ! $availability ) { - $errors[] = ''; - } - - return $errors; } } diff --git a/includes/class-amp-theme-support.php b/includes/class-amp-theme-support.php index 36cec33def1..57644ce47a8 100644 --- a/includes/class-amp-theme-support.php +++ b/includes/class-amp-theme-support.php @@ -337,7 +337,116 @@ public static function add_amp_template_filters() { foreach ( self::$template_types as $template_type ) { add_filter( "{$template_type}_template_hierarchy", array( __CLASS__, 'filter_amp_template_hierarchy' ) ); } - add_filter( 'template_include', array( __CLASS__, 'filter_amp_template_include' ), 100 ); + } + + /** + * Locate the template for a given query. + * + * @param WP_Query $query Query. + * @return string The template filename if one is located. + */ + public static function get_query_template( $query ) { + foreach ( self::$template_types as $template_type ) { + add_filter( "{$template_type}_template_hierarchy", array( __CLASS__, 'filter_amp_template_hierarchy' ) ); + } + + // phpcs:disable -- This is copied from wp-includes/template-loader.php + if ( $query->is_embed() && $template = get_embed_template() ) : + elseif ( $query->is_404() && $template = get_404_template() ) : + elseif ( $query->is_search() && $template = get_search_template() ) : + elseif ( $query->is_front_page() && $template = get_front_page_template() ) : + elseif ( $query->is_home() && $template = get_home_template() ) : + elseif ( $query->is_post_type_archive() && $template = get_post_type_archive_template() ) : + elseif ( $query->is_tax() && $template = get_taxonomy_template() ) : + elseif ( $query->is_attachment() && $template = get_attachment_template() ) : + elseif ( $query->is_single() && $template = get_single_template() ) : + elseif ( $query->is_page() && $template = get_page_template() ) : + elseif ( $query->is_singular() && $template = get_singular_template() ) : + elseif ( $query->is_category() && $template = get_category_template() ) : + elseif ( $query->is_tag() && $template = get_tag_template() ) : + elseif ( $query->is_author() && $template = get_author_template() ) : + elseif ( $query->is_date() && $template = get_date_template() ) : + elseif ( $query->is_archive() && $template = get_archive_template() ) : + else : + $template = get_index_template(); + endif; + // phpcs:enable + + /** This filter is documented in wp-includes/template-loader.php */ + $template = apply_filters( 'template_include', $template ); + + foreach ( self::$template_types as $template_type ) { + remove_filter( "{$template_type}_template_hierarchy", array( __CLASS__, 'filter_amp_template_hierarchy' ) ); + } + + return $template; + } + + /** + * Determine template availability of AMP for the given query. + * + * This is not intended to return whether AMP is available for a _specific_ post. For that, use `post_supports_amp()`. + * + * @since 1.0 + * @global WP_Query $wp_query + * @see post_supports_amp() + * + * @param WP_Query|WP_Post|null $query Query or queried post. If null then the global query will be used. + * @return true|WP_Error True if template is available, WP_Error if otherwise. + */ + public static function get_template_availability( $query = null ) { + global $wp_query; + + if ( $query instanceof WP_Post ) { + $post = $query; + $query = new WP_Query(); + + $query->queried_object = $post; + $query->queried_object_id = $post->ID; + if ( 'page' === $post->post_type ) { + $query->set( 'post_id', $post->ID ); + } else { + $query->set( 'p', $post->ID ); + } + $query->parse_query(); + } elseif ( ! $query ) { + $query = $wp_query; + } + + if ( ! ( $query instanceof WP_Query ) ) { + _doing_it_wrong( __FUNCTION__, esc_html__( 'No WP_Query available.', 'amp' ), '1.0' ); + return new WP_Error( 'no_query_available' ); + } + + if ( ! current_theme_supports( 'amp' ) ) { + return new WP_Error( 'no_theme_support' ); + } + + $args = get_theme_support( 'amp' ); + if ( isset( $args[0]['available_callback'] ) && is_callable( $args[0]['available_callback'] ) ) { + $callback = $args[0]['available_callback']; + + // If the available_callback is a method on the query, then call the method on the query itself. + if ( is_string( $callback ) && 'is_' === substr( $callback, 0, 3 ) && method_exists( $query, $callback ) ) { + $available = call_user_func( array( $query, $callback ) ); + } else { + $available = call_user_func( $callback ); + } + if ( false === $available ) { + return new WP_Error( 'unavailable_by_callback' ); + } + } + + // Make sure there is a template available for the query in the template_dir if it is defined.. + if ( ! empty( $args[0]['template_dir'] ) ) { + $template = self::get_query_template( $query ); + if ( empty( $template ) || ! file_exists( $template ) ) { + return new WP_Error( 'no_existing_template' ); + } + } + + // If all checks have passed, then the template is available. + return true; } /** @@ -768,23 +877,6 @@ public static function filter_amp_template_hierarchy( $templates ) { return $templates; } - /** - * Redirect to the non-canonical URL when the template to include is empty. - * - * This is a failsafe in case an index.php is not located in the AMP template_dir, - * and the available_callback fails to omit a given request from being available in AMP. - * - * @param string $template Template to include. - * @return string Template to include. - */ - public static function filter_amp_template_include( $template ) { - if ( empty( $template ) ) { - wp_safe_redirect( self::get_current_canonical_url(), 302 ); // Temporary redirect because support may come later. - exit; - } - return $template; - } - /** * Get canonical URL for current request. * diff --git a/includes/options/class-amp-options-menu.php b/includes/options/class-amp-options-menu.php index a953786bd78..a0c5e20a1cb 100644 --- a/includes/options/class-amp-options-menu.php +++ b/includes/options/class-amp-options-menu.php @@ -292,7 +292,7 @@ public function render_supported_templates() {

- +

@@ -302,7 +302,7 @@ public function render_supported_templates() { $element_name = AMP_Options_Manager::OPTION_NAME . '[supported_post_types][]'; ?> -

+

@@ -333,19 +333,38 @@ public function render_supported_templates() { array( - 'front' => array(), - 'posts' => array(), - 'date' => array(), - ), - 'author' => array( + 'author' => array( '' => __( 'All author pages', 'amp' ), ), - 'category' => array( - '' => __( 'All category pages', 'amp' ), - ) + 'category' => array_merge( + array( + '' => __( 'All category pages', 'amp' ), + ) + ), + 'tag' => array_merge( + array( + '' => __( 'All tag pages', 'amp' ), + ) + ), + 'date' => array( + '' => __( 'All date archives', 'amp' ), + 'day' => __( 'Daily archives', 'amp' ), + 'month' => __( 'Monthly archives', 'amp' ), + 'year' => __( 'Yearly archives', 'amp' ), + ), + 'page' => array( + 'front' => __( 'Front page', 'amp' ), + 'posts' => __( 'Posts page', 'amp' ), + 'archive' => __( 'Archive page', 'amp' ), + '404' => __( '404 error page', 'amp' ), + 'search' => __( 'Search results', 'amp' ), + ), + // @todo Post type archives. + // @todo Custom taxonomies. ); + ?>