[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

title

Body

[close]

/wp-includes/sitemaps/ -> class-wp-sitemaps.php (source)

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


Generated : Fri Apr 19 08:20:01 2024 Cross-referenced by PHPXref