|
Server : LiteSpeed System : Linux srv104790275 5.15.0-161-generic #171-Ubuntu SMP Sat Oct 11 08:17:01 UTC 2025 x86_64 User : dewac4139 ( 1077) PHP Version : 8.0.30 Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare, Directory : /home/mentaribetslot.com/public_html/wp-content/plugins/amp/src/Validation/ |
Upload File : |
<?php
/**
* Provides URLs to scan.
*
* @package AMP
* @since 2.1
*/
namespace AmpProject\AmpWP\Validation;
use AmpProject\AmpWP\Infrastructure\Service;
use AMP_Theme_Support;
use WP_Query;
use AMP_Options_Manager;
use AmpProject\AmpWP\Option;
use AmpProject\AmpWP\Admin\ReaderThemes;
/**
* ScannableURLProvider class.
*
* @since 2.1
* @internal
*/
final class ScannableURLProvider implements Service {
/**
* Template conditionals to restrict results to.
*
* @var string[]
*/
private $include_conditionals = [];
/**
* Limit for the number of URLs to obtain for each template type.
*
* @var int
*/
private $limit_per_type;
/**
* Construct.
*
* @param string[] $include_conditionals Template conditionals to restrict results to.
* @param int $limit_per_type Limit of URLs to obtain per type.
*/
public function __construct( $include_conditionals = [], $limit_per_type = 1 ) {
$this->include_conditionals = $include_conditionals;
$this->limit_per_type = $limit_per_type;
}
/**
* Get supportable templates.
*
* If the current options are for legacy Reader mode, then the templates not supported by it are disabled.
*
* @see AMP_Theme_Support::get_supportable_templates()
*
* @return array Supportable templates.
*/
public function get_supportable_templates() {
$options = AMP_Options_Manager::get_options();
$supportable_templates = AMP_Theme_Support::get_supportable_templates( $options );
if (
AMP_Theme_Support::READER_MODE_SLUG === $options[ Option::THEME_SUPPORT ]
&&
ReaderThemes::DEFAULT_READER_THEME === $options[ Option::READER_THEME ]
) {
$allowed_templates = [
'is_singular',
];
if ( 'page' === get_option( 'show_on_front' ) ) {
$page_for_posts = get_option( 'page_for_posts' );
if ( $page_for_posts && amp_is_post_supported( $page_for_posts ) ) {
$allowed_templates[] = 'is_home';
}
$page_on_front = get_option( 'page_on_front' );
if ( $page_on_front && amp_is_post_supported( $page_on_front ) ) {
$allowed_templates[] = 'is_front_page';
}
}
foreach ( array_diff( array_keys( $supportable_templates ), $allowed_templates ) as $template ) {
$supportable_templates[ $template ]['supported'] = false;
}
}
return $supportable_templates;
}
/**
* Set include conditionals.
*
* @param string[] $include_conditionals Include conditionals.
*/
public function set_include_conditionals( $include_conditionals ) {
$this->include_conditionals = $include_conditionals;
}
/**
* Set limit per type.
*
* @param int $limit_per_type Limit per type.
*/
public function set_limit_per_type( $limit_per_type ) {
$this->limit_per_type = $limit_per_type;
}
/**
* Get the array of URLs to check.
*
* @return array Array of URLs and types.
*/
public function get_urls() {
$urls = [];
/*
* If 'Your homepage displays' is set to 'Your latest posts', include the homepage.
*/
if ( 'posts' === get_option( 'show_on_front' ) ) {
if ( $this->is_template_supported( 'is_home' ) ) {
$urls[] = [
'url' => home_url( '/' ),
'type' => 'is_home',
'label' => __( 'Homepage', 'amp' ),
];
}
} elseif ( 'page' === get_option( 'show_on_front' ) ) {
if (
$this->is_template_supported( 'is_front_page' )
&&
get_option( 'page_on_front' )
&&
amp_is_post_supported( get_option( 'page_on_front' ) )
) {
$urls[] = [
'url' => get_permalink( get_option( 'page_on_front' ) ),
'type' => 'is_front_page',
'label' => __( 'Homepage', 'amp' ),
];
}
if (
$this->is_template_supported( 'is_home' )
&&
get_option( 'page_for_posts' )
&&
amp_is_post_supported( get_option( 'page_for_posts' ) )
) {
$urls[] = [
'url' => get_permalink( get_option( 'page_for_posts' ) ),
'type' => 'is_home',
'label' => __( 'Blog', 'amp' ),
];
}
}
$amp_enabled_taxonomies = array_filter(
get_taxonomies( [ 'public' => true ] ),
function ( $taxonomy ) {
return $this->does_taxonomy_support_amp( $taxonomy );
}
);
$public_post_types = get_post_types( [ 'public' => true ] );
// Include one URL of each template/content type, then another URL of each type on the next iteration.
for ( $i = 0; $i < $this->limit_per_type; $i++ ) {
if ( $this->is_template_supported( 'is_singular' ) ) {
foreach ( $public_post_types as $post_type ) {
$post_ids = $this->get_posts_by_type( $post_type, $i );
$post_id = reset( $post_ids );
if ( $post_id ) {
$post_type_object = get_post_type_object( $post_type );
$urls[] = [
'url' => get_permalink( $post_id ),
'type' => sprintf( 'is_singular[%s]', $post_type ),
'label' => $post_type_object->labels->singular_name ?: $post_type,
];
}
}
}
foreach ( $amp_enabled_taxonomies as $taxonomy ) {
$taxonomy_links = $this->get_taxonomy_links( $taxonomy, $i, 1 );
$link = reset( $taxonomy_links );
if ( $link ) {
$taxonomy_object = get_taxonomy( $taxonomy );
$urls[] = [
'url' => $link,
'type' => sprintf( 'is_tax[%s]', $taxonomy ),
'label' => $taxonomy_object->labels->singular_name ?: $taxonomy,
];
}
}
$author_page_urls = $this->get_author_page_urls( $i, 1 );
$author_page_url = reset( $author_page_urls );
if ( $author_page_url ) {
$urls[] = [
'url' => $author_page_url,
'type' => 'is_author',
'label' => __( 'Author Archive', 'amp' ),
];
}
}
// Only validate 1 date and 1 search page.
$url = $this->get_date_page();
if ( $url ) {
$urls[] = [
'url' => $url,
'type' => 'is_date',
'label' => __( 'Date Archive', 'amp' ),
];
}
$url = $this->get_search_page();
if ( $url ) {
$urls[] = [
'url' => $url,
'type' => 'is_search',
'label' => __( 'Search Results', 'amp' ),
];
}
return $urls;
}
/**
* Gets whether the template is supported.
*
* @param string $template The template to check.
* @return bool Whether the template is supported.
*/
private function is_template_supported( $template ) {
// If we received an allowlist of conditionals, this template conditional must be present in it.
if (
count( $this->include_conditionals ) > 0
&&
! in_array( $template, $this->include_conditionals, true )
) {
return false;
}
$supportable_templates = $this->get_supportable_templates();
// Check whether this taxonomy's template is supported, including in the 'AMP Settings' > 'Supported Templates' UI.
return ! empty( $supportable_templates[ $template ]['supported'] );
}
/**
* Gets the post IDs that support AMP.
*
* By default, this only gets the post IDs if they support AMP.
* This means that 'Posts' isn't deselected in 'AMP Settings' > 'Supported Templates'
* and 'Enable AMP' isn't unchecked in the post's editor.
*
* @param int[] $ids The post IDs to check for AMP support.
* @return array The post IDs that support AMP, or an empty array.
*/
private function get_posts_that_support_amp( $ids ) {
return array_values(
array_filter(
$ids,
static function ( $id ) {
return amp_is_post_supported( $id );
}
)
);
}
/**
* Gets the IDs of published posts that support AMP.
*
* @see \amp_admin_get_preview_permalink()
*
* @param string $post_type The post type.
* @param int|null $offset The offset of the query (optional).
* @return int[] $post_ids The post IDs in an array.
*/
private function get_posts_by_type( $post_type, $offset = null ) {
// Note that we get 100 posts because it may be that some of them have AMP disabled. It is more
// efficient to do it this way than to try to do a meta query that looks for posts that have the
// amp_status meta equal to 'enabled' or else for posts that lack the meta key altogether. In the latter
// case, the absence of the meta may not mean AMP is enabled since the default-enabled state can be
// overridden with the `amp_post_status_default_enabled` filter. So in this case, we grab 100 post IDs
// and then just use the first one.
$args = [
'post_type' => $post_type,
'posts_per_page' => 100,
'post_status' => 'publish',
'orderby' => 'ID',
'order' => 'DESC',
'fields' => 'ids',
];
$posts_to_exclude = [];
if ( 'page' === get_option( 'show_on_front' ) ) {
$posts_to_exclude[] = (int) get_option( 'page_for_posts' );
$posts_to_exclude[] = (int) get_option( 'page_on_front' );
}
if ( is_int( $offset ) ) {
$args['offset'] = $offset;
}
// Attachment posts usually have the post_status of 'inherit,' so they can use the status of the post they're attached to.
if ( 'attachment' === $post_type ) {
$args['post_status'] = 'inherit';
}
$query = new WP_Query( $args );
return $this->get_posts_that_support_amp( array_diff( $query->posts, $posts_to_exclude ) );
}
/**
* Gets the author page URLs, like https://example.com/author/admin/.
*
* Accepts an $offset parameter, for the query of authors.
* 0 is the first author in the query, and 1 is the second.
*
* @param int $offset The offset for the URL to query for, should be an int if passing an argument.
* @param int $number The total number to query for, should be an int if passing an argument.
* @return string[] The author page URLs, or an empty array.
*/
private function get_author_page_urls( $offset, $number ) {
$author_page_urls = [];
if ( ! $this->is_template_supported( 'is_author' ) ) {
return $author_page_urls;
}
foreach ( get_users( compact( 'offset', 'number' ) ) as $author ) {
$authored_post_query = new WP_Query(
[
'post_type' => 'post',
'post_status' => 'publish',
'author' => $author->ID,
'posts_per_page' => 1,
]
);
if ( count( $authored_post_query->posts ) > 0 ) {
$author_page_urls[] = get_author_posts_url( $author->ID, $author->user_nicename );
}
}
return $author_page_urls;
}
/**
* Gets a single search page URL, like https://example.com/?s=example.
*
* @return string|null An example search page, or null.
*/
private function get_search_page() {
if ( ! $this->is_template_supported( 'is_search' ) ) {
return null;
}
return add_query_arg( 's', 'example', home_url( '/' ) );
}
/**
* Gets a single date page URL, like https://example.com/2018/.
*
* @return string|null An example year archive URL, or null.
*/
private function get_date_page() {
if ( ! $this->is_template_supported( 'is_date' ) ) {
return null;
}
$query = new WP_Query(
[
'post_type' => 'post',
'post_status' => 'publish',
'posts_per_page' => 1,
'orderby' => 'date',
'order' => 'DESC',
]
);
$posts = $query->posts;
$latest_post = array_shift( $posts );
if ( ! $latest_post ) {
return null;
}
$year = (int) get_the_date( 'Y', $latest_post );
if ( $year <= 0 ) {
return null;
}
return get_year_link( $year );
}
/**
* Gets whether the taxonomy supports AMP.
*
* @param string $taxonomy The taxonomy.
* @return boolean Whether the taxonomy supports AMP.
*/
private function does_taxonomy_support_amp( $taxonomy ) {
if ( 'post_tag' === $taxonomy ) {
$taxonomy = 'tag';
}
$taxonomy_key = 'is_' . $taxonomy;
$custom_taxonomy_key = sprintf( 'is_tax[%s]', $taxonomy );
return $this->is_template_supported( $taxonomy_key ) || $this->is_template_supported( $custom_taxonomy_key );
}
/**
* Gets the front-end links for taxonomy terms.
* For example, https://example.org/?cat=2
*
* @param string $taxonomy The name of the taxonomy, like 'category' or 'post_tag'.
* @param int $offset The number at which to offset the query (optional).
* @param int $number The maximum amount of links to get (optional).
* @return string[] The term links, as an array of strings.
*/
private function get_taxonomy_links( $taxonomy, $offset, $number ) {
return array_map(
static function ( $term ) {
return get_term_link( $term );
},
get_terms(
array_merge(
compact( 'taxonomy', 'offset', 'number' ),
[
'orderby' => 'id',
]
)
)
);
}
}