ru-se.com

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

class-wp-sitemaps.php (6290B)


      1 <?php
      2 /**
      3  * Sitemaps: WP_Sitemaps class
      4  *
      5  * This is the main class integrating all other classes.
      6  *
      7  * @package WordPress
      8  * @subpackage Sitemaps
      9  * @since 5.5.0
     10  */
     11 
     12 /**
     13  * Class WP_Sitemaps.
     14  *
     15  * @since 5.5.0
     16  */
     17 class WP_Sitemaps {
     18 	/**
     19 	 * The main index of supported sitemaps.
     20 	 *
     21 	 * @since 5.5.0
     22 	 *
     23 	 * @var WP_Sitemaps_Index
     24 	 */
     25 	public $index;
     26 
     27 	/**
     28 	 * The main registry of supported sitemaps.
     29 	 *
     30 	 * @since 5.5.0
     31 	 *
     32 	 * @var WP_Sitemaps_Registry
     33 	 */
     34 	public $registry;
     35 
     36 	/**
     37 	 * An instance of the renderer class.
     38 	 *
     39 	 * @since 5.5.0
     40 	 *
     41 	 * @var WP_Sitemaps_Renderer
     42 	 */
     43 	public $renderer;
     44 
     45 	/**
     46 	 * WP_Sitemaps constructor.
     47 	 *
     48 	 * @since 5.5.0
     49 	 */
     50 	public function __construct() {
     51 		$this->registry = new WP_Sitemaps_Registry();
     52 		$this->renderer = new WP_Sitemaps_Renderer();
     53 		$this->index    = new WP_Sitemaps_Index( $this->registry );
     54 	}
     55 
     56 	/**
     57 	 * Initiates all sitemap functionality.
     58 	 *
     59 	 * If sitemaps are disabled, only the rewrite rules will be registered
     60 	 * by this method, in order to properly send 404s.
     61 	 *
     62 	 * @since 5.5.0
     63 	 */
     64 	public function init() {
     65 		// These will all fire on the init hook.
     66 		$this->register_rewrites();
     67 
     68 		add_action( 'template_redirect', array( $this, 'render_sitemaps' ) );
     69 
     70 		if ( ! $this->sitemaps_enabled() ) {
     71 			return;
     72 		}
     73 
     74 		$this->register_sitemaps();
     75 
     76 		// Add additional action callbacks.
     77 		add_filter( 'pre_handle_404', array( $this, 'redirect_sitemapxml' ), 10, 2 );
     78 		add_filter( 'robots_txt', array( $this, 'add_robots' ), 0, 2 );
     79 	}
     80 
     81 	/**
     82 	 * Determines whether sitemaps are enabled or not.
     83 	 *
     84 	 * @since 5.5.0
     85 	 *
     86 	 * @return bool Whether sitemaps are enabled.
     87 	 */
     88 	public function sitemaps_enabled() {
     89 		$is_enabled = (bool) get_option( 'blog_public' );
     90 
     91 		/**
     92 		 * Filters whether XML Sitemaps are enabled or not.
     93 		 *
     94 		 * When XML Sitemaps are disabled via this filter, rewrite rules are still
     95 		 * in place to ensure a 404 is returned.
     96 		 *
     97 		 * @see WP_Sitemaps::register_rewrites()
     98 		 *
     99 		 * @since 5.5.0
    100 		 *
    101 		 * @param bool $is_enabled Whether XML Sitemaps are enabled or not. Defaults
    102 		 * to true for public sites.
    103 		 */
    104 		return (bool) apply_filters( 'wp_sitemaps_enabled', $is_enabled );
    105 	}
    106 
    107 	/**
    108 	 * Registers and sets up the functionality for all supported sitemaps.
    109 	 *
    110 	 * @since 5.5.0
    111 	 */
    112 	public function register_sitemaps() {
    113 		$providers = array(
    114 			'posts'      => new WP_Sitemaps_Posts(),
    115 			'taxonomies' => new WP_Sitemaps_Taxonomies(),
    116 			'users'      => new WP_Sitemaps_Users(),
    117 		);
    118 
    119 		/* @var WP_Sitemaps_Provider $provider */
    120 		foreach ( $providers as $name => $provider ) {
    121 			$this->registry->add_provider( $name, $provider );
    122 		}
    123 	}
    124 
    125 	/**
    126 	 * Registers sitemap rewrite tags and routing rules.
    127 	 *
    128 	 * @since 5.5.0
    129 	 */
    130 	public function register_rewrites() {
    131 		// Add rewrite tags.
    132 		add_rewrite_tag( '%sitemap%', '([^?]+)' );
    133 		add_rewrite_tag( '%sitemap-subtype%', '([^?]+)' );
    134 
    135 		// Register index route.
    136 		add_rewrite_rule( '^wp-sitemap\.xml$', 'index.php?sitemap=index', 'top' );
    137 
    138 		// Register rewrites for the XSL stylesheet.
    139 		add_rewrite_tag( '%sitemap-stylesheet%', '([^?]+)' );
    140 		add_rewrite_rule( '^wp-sitemap\.xsl$', 'index.php?sitemap-stylesheet=sitemap', 'top' );
    141 		add_rewrite_rule( '^wp-sitemap-index\.xsl$', 'index.php?sitemap-stylesheet=index', 'top' );
    142 
    143 		// Register routes for providers.
    144 		add_rewrite_rule(
    145 			'^wp-sitemap-([a-z]+?)-([a-z\d_-]+?)-(\d+?)\.xml$',
    146 			'index.php?sitemap=$matches[1]&sitemap-subtype=$matches[2]&paged=$matches[3]',
    147 			'top'
    148 		);
    149 		add_rewrite_rule(
    150 			'^wp-sitemap-([a-z]+?)-(\d+?)\.xml$',
    151 			'index.php?sitemap=$matches[1]&paged=$matches[2]',
    152 			'top'
    153 		);
    154 	}
    155 
    156 	/**
    157 	 * Renders sitemap templates based on rewrite rules.
    158 	 *
    159 	 * @since 5.5.0
    160 	 *
    161 	 * @global WP_Query $wp_query WordPress Query object.
    162 	 */
    163 	public function render_sitemaps() {
    164 		global $wp_query;
    165 
    166 		$sitemap         = sanitize_text_field( get_query_var( 'sitemap' ) );
    167 		$object_subtype  = sanitize_text_field( get_query_var( 'sitemap-subtype' ) );
    168 		$stylesheet_type = sanitize_text_field( get_query_var( 'sitemap-stylesheet' ) );
    169 		$paged           = absint( get_query_var( 'paged' ) );
    170 
    171 		// Bail early if this isn't a sitemap or stylesheet route.
    172 		if ( ! ( $sitemap || $stylesheet_type ) ) {
    173 			return;
    174 		}
    175 
    176 		if ( ! $this->sitemaps_enabled() ) {
    177 			$wp_query->set_404();
    178 			status_header( 404 );
    179 			return;
    180 		}
    181 
    182 		// Render stylesheet if this is stylesheet route.
    183 		if ( $stylesheet_type ) {
    184 			$stylesheet = new WP_Sitemaps_Stylesheet();
    185 
    186 			$stylesheet->render_stylesheet( $stylesheet_type );
    187 			exit;
    188 		}
    189 
    190 		// Render the index.
    191 		if ( 'index' === $sitemap ) {
    192 			$sitemap_list = $this->index->get_sitemap_list();
    193 
    194 			$this->renderer->render_index( $sitemap_list );
    195 			exit;
    196 		}
    197 
    198 		$provider = $this->registry->get_provider( $sitemap );
    199 
    200 		if ( ! $provider ) {
    201 			return;
    202 		}
    203 
    204 		if ( empty( $paged ) ) {
    205 			$paged = 1;
    206 		}
    207 
    208 		$url_list = $provider->get_url_list( $paged, $object_subtype );
    209 
    210 		// Force a 404 and bail early if no URLs are present.
    211 		if ( empty( $url_list ) ) {
    212 			$wp_query->set_404();
    213 			status_header( 404 );
    214 			return;
    215 		}
    216 
    217 		$this->renderer->render_sitemap( $url_list );
    218 		exit;
    219 	}
    220 
    221 	/**
    222 	 * Redirects a URL to the wp-sitemap.xml
    223 	 *
    224 	 * @since 5.5.0
    225 	 *
    226 	 * @param bool     $bypass Pass-through of the pre_handle_404 filter value.
    227 	 * @param WP_Query $query  The WP_Query object.
    228 	 * @return bool Bypass value.
    229 	 */
    230 	public function redirect_sitemapxml( $bypass, $query ) {
    231 		// If a plugin has already utilized the pre_handle_404 function, return without action to avoid conflicts.
    232 		if ( $bypass ) {
    233 			return $bypass;
    234 		}
    235 
    236 		// 'pagename' is for most permalink types, name is for when the %postname% is used as a top-level field.
    237 		if ( 'sitemap-xml' === $query->get( 'pagename' )
    238 			|| 'sitemap-xml' === $query->get( 'name' )
    239 		) {
    240 			wp_safe_redirect( $this->index->get_index_url() );
    241 			exit();
    242 		}
    243 
    244 		return $bypass;
    245 	}
    246 
    247 	/**
    248 	 * Adds the sitemap index to robots.txt.
    249 	 *
    250 	 * @since 5.5.0
    251 	 *
    252 	 * @param string $output robots.txt output.
    253 	 * @param bool   $public Whether the site is public.
    254 	 * @return string The robots.txt output.
    255 	 */
    256 	public function add_robots( $output, $public ) {
    257 		if ( $public ) {
    258 			$output .= "\nSitemap: " . esc_url( $this->index->get_index_url() ) . "\n";
    259 		}
    260 
    261 		return $output;
    262 	}
    263 }