You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

212 lines
4.9 KiB
PHP

<?php
/**
* Render XML output for sitemaps.
*
* @since 0.9.0
* @package RankMath
* @subpackage RankMath\Sitemap
* @author Rank Math <support@rankmath.com>
*
* @copyright Copyright (C) 2008-2019, Yoast BV
* The following code is a derivative work of the code from the Yoast(https://github.com/Yoast/wordpress-seo/), which is licensed under GPL v3.
*/
namespace RankMath\Sitemap;
use RankMath\Helper;
use RankMath\Traits\Hooker;
defined( 'ABSPATH' ) || exit;
/**
* Sitemap XML class.
*/
class Sitemap_XML extends XML {
use Hooker;
/**
* Hold sitemap type.
*
* @var string
*/
public $type;
/**
* Sitemap cache.
*
* @var Cache
*/
public $cache;
/**
* Hold the current page.
*
* @var int
*/
private $current_page = 1;
/**
* Content of the sitemap to output.
*
* @var string
*/
protected $sitemap = '';
/**
* Whether or not the XML sitemap was served from cache or not.
*
* @var boolean
*/
private $transient = false;
/**
* Holds the stats for the sitemap generation.
*
* @var array
*/
private $stats = [];
/**
* The Constructor.
*
* @param string $type Sitemap type.
*/
public function __construct( $type ) {
remove_all_actions( 'widgets_init' );
$this->filter( 'user_has_cap', 'filter_user_has_cap' );
$this->type = $type;
$this->cache = new Cache();
$this->set_n( get_query_var( 'sitemap_n' ) );
$this->output();
}
/**
* Generate sitemap now.
*/
private function output() {
global $wp_query;
$this->init_stats();
if ( ! $this->has_sitemap_in_cache() ) {
$this->build_sitemap();
}
if ( empty( $this->sitemap ) ) {
$wp_query->set_404();
status_header( 404 );
return;
}
$this->send_headers();
echo $this->sitemap; // phpcs:ignore
$this->output_credits();
remove_all_actions( 'wp_footer' );
die;
}
/**
* Output XML credits.
*/
private function output_credits() {
if ( ! $this->do_filter( 'sitemap/remove_credit', false ) ) {
echo "\n<!-- XML Sitemap generated by Rank Math SEO Plugin (c) Rank Math - rankmath.com -->";
}
if ( ! WP_DEBUG_DISPLAY || ! WP_DEBUG ) {
return;
}
$time = timer_stop( 0, 3 );
$sql = get_num_queries() - $this->stats['query'];
$memory = size_format( memory_get_usage() - $this->stats['memory'], 2 );
$template = $this->transient ? 'Served from cache in %s second(s) (Memory usage: %s)' : 'This sitemap was originally generated in %s second(s). (Memory usage: %s) - %s queries';
$template = sprintf( $template, $time, $memory, $sql );
echo "\n<!-- {$template} -->"; // phpcs:ignore
if ( defined( 'SAVEQUERIES' ) && SAVEQUERIES ) {
$queries = print_r( $GLOBALS['wpdb']->queries, true ); // phpcs:ignore
echo "\n<!-- {$queries} -->"; // phpcs:ignore
}
}
/**
* Try to get the sitemap from cache.
*
* @return boolean If the sitemap has been retrieved from cache.
*/
private function has_sitemap_in_cache() {
$this->transient = false;
if ( true !== Sitemap::is_cache_enabled() ) {
return false;
}
$this->sitemap = $this->cache->get_sitemap( $this->type, $this->current_page );
if ( ! empty( $this->sitemap ) ) {
$this->transient = true;
return true;
}
// No cache was found, refresh it because cache is enabled.
$this->build_sitemap();
if ( ! empty( $this->sitemap ) ) {
return $this->cache->store_sitemap( $this->type, $this->current_page, $this->sitemap );
}
return false;
}
/**
* Attempts to build the requested sitemap.
*/
public function build_sitemap() {
$generator = new Generator();
$this->sitemap = $generator->get_output( $this->type, $this->current_page );
}
/**
* Set the sitemap current page to allow creating partial sitemaps with wp-cli
* in a one-off process.
*
* @param integer $current_page The part that should be generated.
*/
public function set_n( $current_page ) {
if ( ! empty( $current_page ) && is_scalar( $current_page ) ) {
$this->maybe_redirect( $current_page );
$this->current_page = max( intval( $current_page ), 1 );
}
}
/**
* Inits building some sitemap generation stats.
*/
private function init_stats() {
timer_start();
$this->stats['query'] = get_num_queries();
$this->stats['memory'] = memory_get_usage();
}
/**
* Redirect page if $current_page has leading zeros.
*
* @param mixed $current_page The page number.
* @return void
*/
private function maybe_redirect( $current_page ) {
// Redirect when there are only zeros.
if ( '' !== $current_page && intval( $current_page ) < 1 ) {
Helper::redirect( preg_replace( '/0+\.xml$/', '.xml', Helper::get_current_page_url() ) );
die();
}
// Redirect when there are leading zeros.
$zeros_stripped = ltrim( $current_page, '0' );
if ( (string) $zeros_stripped !== (string) $current_page ) {
Helper::redirect( preg_replace( '/' . preg_quote( $current_page ) . '\.xml$/', $zeros_stripped . '.xml', Helper::get_current_page_url() ) );
die();
}
}
}