Add upstream
This commit is contained in:
@@ -0,0 +1,146 @@
|
||||
<?php
|
||||
/**
|
||||
* The fallback buffer for users with no XML support.
|
||||
*
|
||||
* @since 5.3.0
|
||||
* @package Jetpack
|
||||
*/
|
||||
|
||||
/**
|
||||
* A buffer for constructing master sitemap xml files.
|
||||
*
|
||||
* @since 5.1.0
|
||||
*/
|
||||
abstract class Jetpack_Sitemap_Buffer_Fallback extends Jetpack_Sitemap_Buffer {
|
||||
|
||||
/**
|
||||
* The buffer contents.
|
||||
*
|
||||
* @access protected
|
||||
* @since 5.3.0
|
||||
* @var string The buffer contents.
|
||||
*/
|
||||
protected $buffer;
|
||||
|
||||
public function __construct( $item_limit, $byte_limit, $time = '1970-01-01 00:00:00' ) {
|
||||
$this->is_full_flag = false;
|
||||
$this->is_empty_flag = true;
|
||||
$this->timestamp = $time;
|
||||
|
||||
$this->finder = new Jetpack_Sitemap_Finder();
|
||||
|
||||
$this->item_capacity = max( 1, intval( $item_limit ) );
|
||||
$this->byte_capacity = max( 1, intval( $byte_limit ) ) - strlen( $this->contents() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Append an item to the buffer, if there is room for it,
|
||||
* and set is_empty_flag to false. If there is no room,
|
||||
* we set is_full_flag to true. If $item is null,
|
||||
* don't do anything and report success.
|
||||
*
|
||||
* @since 5.3.0
|
||||
*
|
||||
* @param array $array The item to be added.
|
||||
*
|
||||
* @return bool True if the append succeeded, False if not.
|
||||
*/
|
||||
public function append( $array ) {
|
||||
if ( is_null( $array ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( $this->is_full_flag ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( 0 >= $this->item_capacity || 0 >= $this->byte_capacity ) {
|
||||
$this->is_full_flag = true;
|
||||
return false;
|
||||
} else {
|
||||
$this->item_capacity -= 1;
|
||||
$added_string = $this->array_to_xml_string( $array );
|
||||
$this->buffer .= $added_string;
|
||||
$this->is_empty_flag = false;
|
||||
|
||||
mbstring_binary_safe_encoding(); // So we can safely use strlen().
|
||||
$this->byte_capacity -= strlen( $added_string );
|
||||
reset_mbstring_encoding();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect whether the buffer is empty.
|
||||
*
|
||||
* @since 5.3.0
|
||||
*
|
||||
* @return bool True if the buffer is empty, false otherwise.
|
||||
*/
|
||||
public function is_empty() {
|
||||
return $this->is_empty_flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the contents of the buffer.
|
||||
*
|
||||
* @since 5.3.0
|
||||
*
|
||||
* @return string The contents of the buffer (with the footer included).
|
||||
*/
|
||||
public function contents() {
|
||||
$root = $this->get_root_element();
|
||||
|
||||
return '<?xml version="1.0" encoding="UTF-8"?>' . PHP_EOL . $root[0] . $this->buffer . $root[1] . PHP_EOL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Legacy implementation of array to XML conversion without using DOMDocument.
|
||||
*
|
||||
* @param Array $array
|
||||
* @return String $result
|
||||
*/
|
||||
public function array_to_xml_string( $array, $parent = null, $root = null ) {
|
||||
$string = '';
|
||||
|
||||
foreach ( $array as $key => $value ) {
|
||||
// Only allow a-z, A-Z, colon, underscore, and hyphen.
|
||||
$tag = preg_replace( '/[^a-zA-Z:_-]/', '_', $key );
|
||||
|
||||
if ( is_array( $value ) ) {
|
||||
$string .= "<$tag>";
|
||||
$string .= $this->array_to_xml_string( $value );
|
||||
$string .= "</$tag>";
|
||||
} elseif ( is_null( $value ) ) {
|
||||
$string .= "<$tag />";
|
||||
} else {
|
||||
$string .= "<$tag>" . htmlspecialchars( $value ) . "</$tag>";
|
||||
}
|
||||
}
|
||||
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render an associative array of XML attribute key/value pairs.
|
||||
*
|
||||
* @access public
|
||||
* @since 5.3.0
|
||||
*
|
||||
* @param array $array Key/value array of attributes.
|
||||
*
|
||||
* @return string The rendered attribute string.
|
||||
*/
|
||||
public static function array_to_xml_attr_string( $array ) {
|
||||
$string = '';
|
||||
|
||||
foreach ( $array as $key => $value ) {
|
||||
$key = preg_replace( '/[^a-zA-Z:_-]/', '_', $key );
|
||||
$string .= ' ' . $key . '="' . esc_attr( $value ) . '"';
|
||||
}
|
||||
|
||||
return $string;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
/**
|
||||
* Sitemaps (per the protocol) are essentially lists of XML fragments;
|
||||
* lists which are subject to size constraints. The Jetpack_Sitemap_Buffer_Image
|
||||
* extends the Jetpack_Sitemap_Buffer class to represent the single image sitemap
|
||||
* buffer.
|
||||
*
|
||||
* @since 5.3.0
|
||||
* @package Jetpack
|
||||
*/
|
||||
|
||||
/**
|
||||
* A buffer for constructing sitemap image xml files for users that have no libxml support.
|
||||
*
|
||||
* @since 5.3.0
|
||||
*/
|
||||
class Jetpack_Sitemap_Buffer_Image extends Jetpack_Sitemap_Buffer_Fallback {
|
||||
|
||||
protected function get_root_element() {
|
||||
if ( ! isset( $this->root ) ) {
|
||||
|
||||
/**
|
||||
* Filter the XML namespaces included in image sitemaps.
|
||||
*
|
||||
* @module sitemaps
|
||||
*
|
||||
* @since 4.8.0
|
||||
*
|
||||
* @param array $namespaces Associative array with namespaces and namespace URIs.
|
||||
*/
|
||||
$namespaces = apply_filters(
|
||||
'jetpack_sitemap_image_ns',
|
||||
array(
|
||||
'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
|
||||
'xsi:schemaLocation' => 'http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd',
|
||||
'xmlns' => 'http://www.sitemaps.org/schemas/sitemap/0.9',
|
||||
'xmlns:image' => 'http://www.google.com/schemas/sitemap-image/1.1',
|
||||
)
|
||||
);
|
||||
|
||||
$sitemap_xsl_url = $this->finder->construct_sitemap_url( 'sitemap.xsl' );
|
||||
$jetpack_version = JETPACK__VERSION;
|
||||
|
||||
$this->root = array(
|
||||
"<!-- generator='jetpack-{$jetpack_version}' -->" . PHP_EOL
|
||||
. "<?xml-stylesheet type='text/xsl' href='{$sitemap_xsl_url}'?>" . PHP_EOL
|
||||
. '<urlset ' . $this->array_to_xml_attr_string( $namespaces ) . '>' . PHP_EOL,
|
||||
'</urlset>',
|
||||
);
|
||||
|
||||
$this->byte_capacity -= strlen( join( '', $this->root ) );
|
||||
}
|
||||
|
||||
return $this->root;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
/**
|
||||
* Sitemaps (per the protocol) are essentially lists of XML fragments;
|
||||
* lists which are subject to size constraints. The Jetpack_Sitemap_Buffer_Image
|
||||
* extends the Jetpack_Sitemap_Buffer class to represent the single image sitemap
|
||||
* buffer.
|
||||
*
|
||||
* @since 5.3.0
|
||||
* @package Jetpack
|
||||
*/
|
||||
|
||||
/**
|
||||
* A buffer for constructing sitemap image xml files.
|
||||
*
|
||||
* @since 5.3.0
|
||||
*/
|
||||
class Jetpack_Sitemap_Buffer_Image extends Jetpack_Sitemap_Buffer {
|
||||
|
||||
public function __construct( $item_limit, $byte_limit, $time = '1970-01-01 00:00:00' ) {
|
||||
parent::__construct( $item_limit, $byte_limit, $time );
|
||||
|
||||
$this->doc->appendChild(
|
||||
$this->doc->createComment( "generator='jetpack-" . JETPACK__VERSION . "'" )
|
||||
);
|
||||
|
||||
$this->doc->appendChild(
|
||||
$this->doc->createProcessingInstruction(
|
||||
'xml-stylesheet',
|
||||
'type="text/xsl" href="' . $this->finder->construct_sitemap_url( 'image-sitemap.xsl' ) . '"'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
protected function get_root_element() {
|
||||
if ( ! isset( $this->root ) ) {
|
||||
|
||||
/**
|
||||
* Filter the XML namespaces included in image sitemaps.
|
||||
*
|
||||
* @module sitemaps
|
||||
*
|
||||
* @since 4.8.0
|
||||
*
|
||||
* @param array $namespaces Associative array with namespaces and namespace URIs.
|
||||
*/
|
||||
$namespaces = apply_filters(
|
||||
'jetpack_sitemap_image_ns',
|
||||
array(
|
||||
'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
|
||||
'xsi:schemaLocation' => 'http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd',
|
||||
'xmlns' => 'http://www.sitemaps.org/schemas/sitemap/0.9',
|
||||
'xmlns:image' => 'http://www.google.com/schemas/sitemap-image/1.1',
|
||||
)
|
||||
);
|
||||
|
||||
$this->root = $this->doc->createElement( 'urlset' );
|
||||
|
||||
foreach ( $namespaces as $name => $value ) {
|
||||
$this->root->setAttribute( $name, $value );
|
||||
}
|
||||
|
||||
$this->doc->appendChild( $this->root );
|
||||
$this->byte_capacity -= strlen( $this->doc->saveXML( $this->root ) );
|
||||
}
|
||||
|
||||
return $this->root;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
/**
|
||||
* Sitemaps (per the protocol) are essentially lists of XML fragments;
|
||||
* lists which are subject to size constraints. The Jetpack_Sitemap_Buffer_Master
|
||||
* extends the Jetpack_Sitemap_Buffer class to represent the master sitemap
|
||||
* buffer.
|
||||
*
|
||||
* @since 5.3.0
|
||||
* @package Jetpack
|
||||
*/
|
||||
|
||||
/**
|
||||
* A buffer for constructing master sitemap xml files for users without libxml support.
|
||||
*
|
||||
* @since 5.3.0
|
||||
*/
|
||||
class Jetpack_Sitemap_Buffer_Master extends Jetpack_Sitemap_Buffer_Fallback {
|
||||
|
||||
protected function get_root_element() {
|
||||
|
||||
if ( ! isset( $this->root ) ) {
|
||||
|
||||
$sitemap_index_xsl_url = $this->finder->construct_sitemap_url( 'sitemap-index.xsl' );
|
||||
$jetpack_version = JETPACK__VERSION;
|
||||
|
||||
$this->root = array(
|
||||
"<!-- generator='jetpack-{$jetpack_version}' -->" . PHP_EOL
|
||||
. "<?xml-stylesheet type='text/xsl' href='{$sitemap_index_xsl_url}'?>" . PHP_EOL
|
||||
. "<sitemapindex xmlns='http://www.sitemaps.org/schemas/sitemap/0.9'>" . PHP_EOL,
|
||||
'</sitemapindex>',
|
||||
);
|
||||
|
||||
$this->byte_capacity -= strlen( join( '', $this->root ) );
|
||||
}
|
||||
|
||||
return $this->root;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
/**
|
||||
* Sitemaps (per the protocol) are essentially lists of XML fragments;
|
||||
* lists which are subject to size constraints. The Jetpack_Sitemap_Buffer_Master
|
||||
* extends the Jetpack_Sitemap_Buffer class to represent the master sitemap
|
||||
* buffer.
|
||||
*
|
||||
* @since 5.3.0
|
||||
* @package Jetpack
|
||||
*/
|
||||
|
||||
/**
|
||||
* A buffer for constructing master sitemap xml files.
|
||||
*
|
||||
* @since 5.3.0
|
||||
*/
|
||||
class Jetpack_Sitemap_Buffer_Master extends Jetpack_Sitemap_Buffer {
|
||||
|
||||
public function __construct( $item_limit, $byte_limit, $time = '1970-01-01 00:00:00' ) {
|
||||
parent::__construct( $item_limit, $byte_limit, $time );
|
||||
|
||||
$this->doc->appendChild(
|
||||
$this->doc->createComment( "generator='jetpack-" . JETPACK__VERSION . "'" )
|
||||
);
|
||||
|
||||
$this->doc->appendChild(
|
||||
$this->doc->createProcessingInstruction(
|
||||
'xml-stylesheet',
|
||||
'type="text/xsl" href="' . $this->finder->construct_sitemap_url( 'sitemap-index.xsl' ) . '"'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
protected function get_root_element() {
|
||||
if ( ! isset( $this->root ) ) {
|
||||
$this->root = $this->doc->createElement( 'sitemapindex' );
|
||||
$this->root->setAttribute( 'xmlns', 'http://www.sitemaps.org/schemas/sitemap/0.9' );
|
||||
$this->doc->appendChild( $this->root );
|
||||
$this->byte_capacity -= strlen( $this->doc->saveXML( $this->root ) );
|
||||
}
|
||||
|
||||
return $this->root;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
/**
|
||||
* Sitemaps (per the protocol) are essentially lists of XML fragments;
|
||||
* lists which are subject to size constraints. The Jetpack_Sitemap_Buffer_News
|
||||
* extends the Jetpack_Sitemap_Buffer class to represent the single news sitemap
|
||||
* buffer.
|
||||
*
|
||||
* @since 5.3.0
|
||||
* @package Jetpack
|
||||
*/
|
||||
|
||||
/**
|
||||
* A buffer for constructing sitemap image xml files for users without libxml support.
|
||||
*
|
||||
* @since 5.3.0
|
||||
*/
|
||||
class Jetpack_Sitemap_Buffer_News extends Jetpack_Sitemap_Buffer_Fallback {
|
||||
|
||||
protected function get_root_element() {
|
||||
if ( ! isset( $this->root ) ) {
|
||||
|
||||
/**
|
||||
* Filter the attribute value pairs used for namespace and namespace URI mappings.
|
||||
*
|
||||
* @module sitemaps
|
||||
*
|
||||
* @since 4.8.0
|
||||
*
|
||||
* @param array $namespaces Associative array with namespaces and namespace URIs.
|
||||
*/
|
||||
$namespaces = apply_filters(
|
||||
'jetpack_sitemap_news_ns',
|
||||
array(
|
||||
'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
|
||||
'xsi:schemaLocation' => 'http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd',
|
||||
'xmlns' => 'http://www.sitemaps.org/schemas/sitemap/0.9',
|
||||
'xmlns:news' => 'http://www.google.com/schemas/sitemap-news/0.9',
|
||||
)
|
||||
);
|
||||
|
||||
$jetpack_version = JETPACK__VERSION;
|
||||
$news_sitemap_xsl_url = $this->finder->construct_sitemap_url( 'news-sitemap.xsl' );
|
||||
|
||||
$this->root = array(
|
||||
"<!-- generator='jetpack-{$jetpack_version}' -->" . PHP_EOL
|
||||
. "<?xml-stylesheet type='text/xsl' href='{$news_sitemap_xsl_url}'?>" . PHP_EOL
|
||||
. '<urlset ' . $this->array_to_xml_attr_string( $namespaces ) . '>',
|
||||
'</urlset>',
|
||||
);
|
||||
|
||||
$this->byte_capacity -= strlen( join( '', $this->root ) );
|
||||
}
|
||||
|
||||
return $this->root;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
/**
|
||||
* Sitemaps (per the protocol) are essentially lists of XML fragments;
|
||||
* lists which are subject to size constraints. The Jetpack_Sitemap_Buffer_News
|
||||
* extends the Jetpack_Sitemap_Buffer class to represent the single news sitemap
|
||||
* buffer.
|
||||
*
|
||||
* @since 5.3.0
|
||||
* @package Jetpack
|
||||
*/
|
||||
|
||||
/**
|
||||
* A buffer for constructing sitemap image xml files.
|
||||
*
|
||||
* @since 5.3.0
|
||||
*/
|
||||
class Jetpack_Sitemap_Buffer_News extends Jetpack_Sitemap_Buffer {
|
||||
|
||||
public function __construct( $item_limit, $byte_limit, $time = '1970-01-01 00:00:00' ) {
|
||||
parent::__construct( $item_limit, $byte_limit, $time );
|
||||
|
||||
$this->doc->appendChild(
|
||||
$this->doc->createComment( "generator='jetpack-" . JETPACK__VERSION . "'" )
|
||||
);
|
||||
|
||||
$this->doc->appendChild(
|
||||
$this->doc->createProcessingInstruction(
|
||||
'xml-stylesheet',
|
||||
'type="text/xsl" href="' . $this->finder->construct_sitemap_url( 'news-sitemap.xsl' ) . '"'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
protected function get_root_element() {
|
||||
if ( ! isset( $this->root ) ) {
|
||||
|
||||
/**
|
||||
* Filter the attribute value pairs used for namespace and namespace URI mappings.
|
||||
*
|
||||
* @module sitemaps
|
||||
*
|
||||
* @since 4.8.0
|
||||
*
|
||||
* @param array $namespaces Associative array with namespaces and namespace URIs.
|
||||
*/
|
||||
$namespaces = apply_filters(
|
||||
'jetpack_sitemap_news_ns',
|
||||
array(
|
||||
'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
|
||||
'xsi:schemaLocation' => 'http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd',
|
||||
'xmlns' => 'http://www.sitemaps.org/schemas/sitemap/0.9',
|
||||
'xmlns:news' => 'http://www.google.com/schemas/sitemap-news/0.9',
|
||||
)
|
||||
);
|
||||
|
||||
$this->root = $this->doc->createElement( 'urlset' );
|
||||
|
||||
foreach ( $namespaces as $name => $value ) {
|
||||
$this->root->setAttribute( $name, $value );
|
||||
}
|
||||
|
||||
$this->doc->appendChild( $this->root );
|
||||
$this->byte_capacity -= strlen( $this->doc->saveXML( $this->root ) );
|
||||
}
|
||||
|
||||
return $this->root;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
/**
|
||||
* Sitemaps (per the protocol) are essentially lists of XML fragments;
|
||||
* lists which are subject to size constraints. The Jetpack_Sitemap_Buffer_Page
|
||||
* extends the Jetpack_Sitemap_Buffer class to represent the single page sitemap
|
||||
* buffer.
|
||||
*
|
||||
* @since 5.3.0
|
||||
* @package Jetpack
|
||||
*/
|
||||
|
||||
/**
|
||||
* A buffer for constructing sitemap page xml files for users with no libxml support.
|
||||
*
|
||||
* @since 5.3.0
|
||||
*/
|
||||
class Jetpack_Sitemap_Buffer_Page extends Jetpack_Sitemap_Buffer_Fallback {
|
||||
|
||||
protected function get_root_element() {
|
||||
if ( ! isset( $this->root ) ) {
|
||||
|
||||
/**
|
||||
* Filter the attribute value pairs used for namespace and namespace URI mappings.
|
||||
*
|
||||
* @module sitemaps
|
||||
*
|
||||
* @since 3.9.0
|
||||
*
|
||||
* @param array $namespaces Associative array with namespaces and namespace URIs.
|
||||
*/
|
||||
$namespaces = apply_filters(
|
||||
'jetpack_sitemap_ns',
|
||||
array(
|
||||
'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
|
||||
'xsi:schemaLocation' => 'http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd',
|
||||
'xmlns' => 'http://www.sitemaps.org/schemas/sitemap/0.9',
|
||||
)
|
||||
);
|
||||
|
||||
$jetpack_version = JETPACK__VERSION;
|
||||
$sitemap_xsl_url = $this->finder->construct_sitemap_url( 'sitemap.xsl' );
|
||||
|
||||
$this->root = array(
|
||||
"<!-- generator='jetpack-{$jetpack_version}' -->" . PHP_EOL
|
||||
. "<?xml-stylesheet type='text/xsl' href='{$sitemap_xsl_url}'?>" . PHP_EOL
|
||||
. '<urlset ' . $this->array_to_xml_attr_string( $namespaces ) . '>',
|
||||
'</urlset>',
|
||||
);
|
||||
|
||||
$this->byte_capacity -= strlen( join( '', $this->root ) );
|
||||
}
|
||||
|
||||
return $this->root;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
/**
|
||||
* Sitemaps (per the protocol) are essentially lists of XML fragments;
|
||||
* lists which are subject to size constraints. The Jetpack_Sitemap_Buffer_Page
|
||||
* extends the Jetpack_Sitemap_Buffer class to represent the single page sitemap
|
||||
* buffer.
|
||||
*
|
||||
* @since 5.3.0
|
||||
* @package Jetpack
|
||||
*/
|
||||
|
||||
/**
|
||||
* A buffer for constructing sitemap page xml files.
|
||||
*
|
||||
* @since 5.3.0
|
||||
*/
|
||||
class Jetpack_Sitemap_Buffer_Page extends Jetpack_Sitemap_Buffer {
|
||||
|
||||
public function __construct( $item_limit, $byte_limit, $time = '1970-01-01 00:00:00' ) {
|
||||
parent::__construct( $item_limit, $byte_limit, $time );
|
||||
|
||||
$this->doc->appendChild(
|
||||
$this->doc->createComment( "generator='jetpack-" . JETPACK__VERSION . "'" )
|
||||
);
|
||||
|
||||
$this->doc->appendChild(
|
||||
$this->doc->createProcessingInstruction(
|
||||
'xml-stylesheet',
|
||||
'type="text/xsl" href="' . $this->finder->construct_sitemap_url( 'sitemap.xsl' ) . '"'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
protected function get_root_element() {
|
||||
if ( ! isset( $this->root ) ) {
|
||||
|
||||
/**
|
||||
* Filter the attribute value pairs used for namespace and namespace URI mappings.
|
||||
*
|
||||
* @module sitemaps
|
||||
*
|
||||
* @since 3.9.0
|
||||
*
|
||||
* @param array $namespaces Associative array with namespaces and namespace URIs.
|
||||
*/
|
||||
$namespaces = apply_filters(
|
||||
'jetpack_sitemap_ns',
|
||||
array(
|
||||
'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
|
||||
'xsi:schemaLocation' => 'http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd',
|
||||
'xmlns' => 'http://www.sitemaps.org/schemas/sitemap/0.9',
|
||||
)
|
||||
);
|
||||
|
||||
$this->root = $this->doc->createElement( 'urlset' );
|
||||
|
||||
foreach ( $namespaces as $name => $value ) {
|
||||
$this->root->setAttribute( $name, $value );
|
||||
}
|
||||
|
||||
$this->doc->appendChild( $this->root );
|
||||
$this->byte_capacity -= strlen( $this->doc->saveXML( $this->root ) );
|
||||
}
|
||||
|
||||
return $this->root;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
/**
|
||||
* Sitemaps (per the protocol) are essentially lists of XML fragments;
|
||||
* lists which are subject to size constraints. The Jetpack_Sitemap_Buffer_Video
|
||||
* extends the Jetpack_Sitemap_Buffer class to represent the single video sitemap
|
||||
* buffer.
|
||||
*
|
||||
* @since 5.3.0
|
||||
* @package Jetpack
|
||||
*/
|
||||
|
||||
/**
|
||||
* A buffer for constructing sitemap video xml files for users without libxml support.
|
||||
*
|
||||
* @since 5.3.0
|
||||
*/
|
||||
class Jetpack_Sitemap_Buffer_Video extends Jetpack_Sitemap_Buffer_Fallback {
|
||||
|
||||
protected function get_root_element() {
|
||||
if ( ! isset( $this->root ) ) {
|
||||
|
||||
/**
|
||||
* Filter the XML namespaces included in video sitemaps.
|
||||
*
|
||||
* @module sitemaps
|
||||
*
|
||||
* @since 4.8.0
|
||||
*
|
||||
* @param array $namespaces Associative array with namespaces and namespace URIs.
|
||||
*/
|
||||
$namespaces = apply_filters(
|
||||
'jetpack_sitemap_video_ns',
|
||||
array(
|
||||
'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
|
||||
'xsi:schemaLocation' => 'http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd',
|
||||
'xmlns' => 'http://www.sitemaps.org/schemas/sitemap/0.9',
|
||||
'xmlns:video' => 'http://www.google.com/schemas/sitemap-video/1.1',
|
||||
)
|
||||
);
|
||||
|
||||
$video_sitemap_xsl_url = $this->finder->construct_sitemap_url( 'video-sitemap.xsl' );
|
||||
$jetpack_version = JETPACK__VERSION;
|
||||
|
||||
$this->root = array(
|
||||
"<!-- generator='jetpack-{$jetpack_version}' -->" . PHP_EOL
|
||||
. "<?xml-stylesheet type='text/xsl' href='{$video_sitemap_xsl_url}'?>" . PHP_EOL
|
||||
. '<urlset ' . $this->array_to_xml_attr_string( $namespaces ) . '>',
|
||||
'</urlset>',
|
||||
);
|
||||
|
||||
$this->byte_capacity -= strlen( join( '', $this->root ) );
|
||||
}
|
||||
|
||||
return $this->root;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
/**
|
||||
* Sitemaps (per the protocol) are essentially lists of XML fragments;
|
||||
* lists which are subject to size constraints. The Jetpack_Sitemap_Buffer_Video
|
||||
* extends the Jetpack_Sitemap_Buffer class to represent the single video sitemap
|
||||
* buffer.
|
||||
*
|
||||
* @since 5.3.0
|
||||
* @package Jetpack
|
||||
*/
|
||||
|
||||
/**
|
||||
* A buffer for constructing sitemap video xml files.
|
||||
*
|
||||
* @since 5.3.0
|
||||
*/
|
||||
class Jetpack_Sitemap_Buffer_Video extends Jetpack_Sitemap_Buffer {
|
||||
|
||||
public function __construct( $item_limit, $byte_limit, $time = '1970-01-01 00:00:00' ) {
|
||||
parent::__construct( $item_limit, $byte_limit, $time );
|
||||
|
||||
$this->doc->appendChild(
|
||||
$this->doc->createComment( "generator='jetpack-" . JETPACK__VERSION . "'" )
|
||||
);
|
||||
|
||||
$this->doc->appendChild(
|
||||
$this->doc->createProcessingInstruction(
|
||||
'xml-stylesheet',
|
||||
'type="text/xsl" href="' . $this->finder->construct_sitemap_url( 'video-sitemap.xsl' ) . '"'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
protected function get_root_element() {
|
||||
if ( ! isset( $this->root ) ) {
|
||||
|
||||
/**
|
||||
* Filter the XML namespaces included in video sitemaps.
|
||||
*
|
||||
* @module sitemaps
|
||||
*
|
||||
* @since 4.8.0
|
||||
*
|
||||
* @param array $namespaces Associative array with namespaces and namespace URIs.
|
||||
*/
|
||||
$namespaces = apply_filters(
|
||||
'jetpack_sitemap_video_ns',
|
||||
array(
|
||||
'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
|
||||
'xsi:schemaLocation' => 'http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd',
|
||||
'xmlns' => 'http://www.sitemaps.org/schemas/sitemap/0.9',
|
||||
'xmlns:video' => 'http://www.google.com/schemas/sitemap-video/1.1',
|
||||
)
|
||||
);
|
||||
|
||||
$this->root = $this->doc->createElement( 'urlset' );
|
||||
|
||||
foreach ( $namespaces as $name => $value ) {
|
||||
$this->root->setAttribute( $name, $value );
|
||||
}
|
||||
|
||||
$this->doc->appendChild( $this->root );
|
||||
$this->byte_capacity -= strlen( $this->doc->saveXML( $this->root ) );
|
||||
}
|
||||
|
||||
return $this->root;
|
||||
}
|
||||
}
|
||||
325
wp-content/plugins/jetpack/modules/sitemaps/sitemap-buffer.php
Normal file
325
wp-content/plugins/jetpack/modules/sitemaps/sitemap-buffer.php
Normal file
@@ -0,0 +1,325 @@
|
||||
<?php
|
||||
/**
|
||||
* Sitemaps (per the protocol) are essentially lists of XML fragments;
|
||||
* lists which are subject to size constraints. The Jetpack_Sitemap_Buffer
|
||||
* class abstracts the details of constructing these lists while
|
||||
* maintaining the constraints.
|
||||
*
|
||||
* @since 4.8.0
|
||||
* @package Jetpack
|
||||
*/
|
||||
|
||||
/**
|
||||
* A buffer for constructing sitemap xml files.
|
||||
*
|
||||
* Models a list of strings such that
|
||||
*
|
||||
* 1. the list must have a bounded number of entries,
|
||||
* 2. the concatenation of the strings must have bounded
|
||||
* length (including some header and footer strings), and
|
||||
* 3. each item has a timestamp, and we need to keep track
|
||||
* of the most recent timestamp of the items in the list.
|
||||
*
|
||||
* @since 4.8.0
|
||||
*/
|
||||
abstract class Jetpack_Sitemap_Buffer {
|
||||
|
||||
/**
|
||||
* Largest number of items the buffer can hold.
|
||||
*
|
||||
* @access protected
|
||||
* @since 4.8.0
|
||||
* @var int $item_capacity The item capacity.
|
||||
*/
|
||||
protected $item_capacity;
|
||||
|
||||
/**
|
||||
* Largest number of bytes the buffer can hold.
|
||||
*
|
||||
* @access protected
|
||||
* @since 4.8.0
|
||||
* @var int $byte_capacity The byte capacity.
|
||||
*/
|
||||
protected $byte_capacity;
|
||||
|
||||
/**
|
||||
* Flag which detects when the buffer is full.
|
||||
*
|
||||
* @access protected
|
||||
* @since 4.8.0
|
||||
* @var bool $is_full_flag The flag value. This flag is set to false on construction and only flipped to true if we've tried to add something and failed.
|
||||
*/
|
||||
protected $is_full_flag;
|
||||
|
||||
/**
|
||||
* Flag which detects when the buffer is empty.
|
||||
*
|
||||
* @access protected
|
||||
* @since 4.8.0
|
||||
* @var bool $is_empty_flag The flag value. This flag is set to true on construction and only flipped to false if we've tried to add something and succeeded.
|
||||
*/
|
||||
protected $is_empty_flag;
|
||||
|
||||
/**
|
||||
* The most recent timestamp seen by the buffer.
|
||||
*
|
||||
* @access protected
|
||||
* @since 4.8.0
|
||||
* @var string $timestamp Must be in 'YYYY-MM-DD hh:mm:ss' format.
|
||||
*/
|
||||
protected $timestamp;
|
||||
|
||||
/**
|
||||
* The DOM document object that is currently being used to construct the XML doc.
|
||||
*
|
||||
* @access protected
|
||||
* @since 5.3.0
|
||||
* @var DOMDocument $doc
|
||||
*/
|
||||
protected $doc = null;
|
||||
|
||||
/**
|
||||
* The root DOM element object that holds everything inside. Do not use directly, call
|
||||
* the get_root_element getter method instead.
|
||||
*
|
||||
* @access protected
|
||||
* @since 5.3.0
|
||||
* @var DOMElement $doc
|
||||
*/
|
||||
protected $root = null;
|
||||
|
||||
/**
|
||||
* Helper class to construct sitemap paths.
|
||||
*
|
||||
* @since 5.3.0
|
||||
* @protected
|
||||
* @var Jetpack_Sitemap_Finder
|
||||
*/
|
||||
protected $finder;
|
||||
|
||||
/**
|
||||
* Construct a new Jetpack_Sitemap_Buffer.
|
||||
*
|
||||
* @since 4.8.0
|
||||
*
|
||||
* @param int $item_limit The maximum size of the buffer in items.
|
||||
* @param int $byte_limit The maximum size of the buffer in bytes.
|
||||
* @param string $time The initial datetime of the buffer. Must be in 'YYYY-MM-DD hh:mm:ss' format.
|
||||
*/
|
||||
public function __construct( $item_limit, $byte_limit, $time ) {
|
||||
$this->is_full_flag = false;
|
||||
$this->timestamp = $time;
|
||||
|
||||
$this->finder = new Jetpack_Sitemap_Finder();
|
||||
$this->doc = new DOMDocument( '1.0', 'UTF-8' );
|
||||
|
||||
$this->item_capacity = max( 1, intval( $item_limit ) );
|
||||
$this->byte_capacity = max( 1, intval( $byte_limit ) ) - strlen( $this->doc->saveXML() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a DOM element that contains all sitemap elements.
|
||||
*
|
||||
* @access protected
|
||||
* @since 5.3.0
|
||||
* @return DOMElement $root
|
||||
*/
|
||||
abstract protected function get_root_element();
|
||||
|
||||
/**
|
||||
* Append an item to the buffer, if there is room for it,
|
||||
* and set is_empty_flag to false. If there is no room,
|
||||
* we set is_full_flag to true. If $item is null,
|
||||
* don't do anything and report success.
|
||||
*
|
||||
* @since 4.8.0
|
||||
* @deprecated 5.3.0 Use Jetpack_Sitemap_Buffer::append.
|
||||
*
|
||||
* @param string $item The item to be added.
|
||||
*/
|
||||
public function try_to_add_item( $item ) {
|
||||
_deprecated_function(
|
||||
'Jetpack_Sitemap_Buffer::try_to_add_item',
|
||||
'5.3.0',
|
||||
'Jetpack_Sitemap_Buffer::append'
|
||||
);
|
||||
$this->append( $item );
|
||||
}
|
||||
|
||||
/**
|
||||
* Append an item to the buffer, if there is room for it,
|
||||
* and set is_empty_flag to false. If there is no room,
|
||||
* we set is_full_flag to true. If $item is null,
|
||||
* don't do anything and report success.
|
||||
*
|
||||
* @since 5.3.0
|
||||
*
|
||||
* @param array $array The item to be added.
|
||||
*
|
||||
* @return bool True if the append succeeded, False if not.
|
||||
*/
|
||||
public function append( $array ) {
|
||||
if ( is_null( $array ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( $this->is_full_flag ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( 0 >= $this->item_capacity || 0 >= $this->byte_capacity ) {
|
||||
$this->is_full_flag = true;
|
||||
return false;
|
||||
} else {
|
||||
$this->item_capacity -= 1;
|
||||
$added_element = $this->array_to_xml_string( $array, $this->get_root_element(), $this->doc );
|
||||
|
||||
$this->byte_capacity -= strlen( $this->doc->saveXML( $added_element ) );
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the contents of the buffer.
|
||||
*
|
||||
* @since 4.8.0
|
||||
*
|
||||
* @return string The contents of the buffer (with the footer included).
|
||||
*/
|
||||
public function contents() {
|
||||
if ( $this->is_empty() ) {
|
||||
// The sitemap should have at least the root element added to the DOM.
|
||||
$this->get_root_element();
|
||||
}
|
||||
return $this->doc->saveXML();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the document object.
|
||||
*
|
||||
* @since 5.3.0
|
||||
* @return DOMDocument $doc
|
||||
*/
|
||||
public function get_document() {
|
||||
return $this->doc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect whether the buffer is full.
|
||||
*
|
||||
* @since 4.8.0
|
||||
*
|
||||
* @return bool True if the buffer is full, false otherwise.
|
||||
*/
|
||||
public function is_full() {
|
||||
return $this->is_full_flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect whether the buffer is empty.
|
||||
*
|
||||
* @since 4.8.0
|
||||
*
|
||||
* @return bool True if the buffer is empty, false otherwise.
|
||||
*/
|
||||
public function is_empty() {
|
||||
return (
|
||||
! isset( $this->root )
|
||||
|| ! $this->root->hasChildNodes()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the timestamp of the buffer.
|
||||
*
|
||||
* @since 4.8.0
|
||||
*
|
||||
* @param string $new_time A datetime string in 'YYYY-MM-DD hh:mm:ss' format.
|
||||
*/
|
||||
public function view_time( $new_time ) {
|
||||
$this->timestamp = max( $this->timestamp, $new_time );
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the timestamp of the buffer.
|
||||
*
|
||||
* @since 4.8.0
|
||||
*
|
||||
* @return string A datetime string in 'YYYY-MM-DD hh:mm:ss' format.
|
||||
*/
|
||||
public function last_modified() {
|
||||
return $this->timestamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render an associative array as an XML string. This is needed because
|
||||
* SimpleXMLElement only handles valid XML, but we sometimes want to
|
||||
* pass around (possibly invalid) fragments. Note that 'null' values make
|
||||
* a tag self-closing; this is only sometimes correct (depending on the
|
||||
* version of HTML/XML); see the list of 'void tags'.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* array(
|
||||
* 'html' => array( |<html xmlns="foo">
|
||||
* 'head' => array( | <head>
|
||||
* 'title' => 'Woo!', | <title>Woo!</title>
|
||||
* ), | </head>
|
||||
* 'body' => array( ==> | <body>
|
||||
* 'h2' => 'Some thing', | <h2>Some thing</h2>
|
||||
* 'p' => 'it's all up ons', | <p>it's all up ons</p>
|
||||
* 'br' => null, | <br />
|
||||
* ), | </body>
|
||||
* ), |</html>
|
||||
* )
|
||||
*
|
||||
* @access protected
|
||||
* @since 3.9.0
|
||||
* @since 4.8.0 Rename, add $depth parameter, and change return type.
|
||||
* @since 5.3.0 Refactor, remove $depth parameter, add $parent and $root, make access protected.
|
||||
*
|
||||
* @param array $array A recursive associative array of tag/child relationships.
|
||||
* @param DOMElement $parent (optional) an element to which new children should be added.
|
||||
* @param DOMDocument $root (optional) the parent document.
|
||||
*
|
||||
* @return string|DOMDocument The rendered XML string or an object if root element is specified.
|
||||
*/
|
||||
protected function array_to_xml_string( $array, $parent = null, $root = null ) {
|
||||
$return_string = false;
|
||||
|
||||
if ( null === $parent ) {
|
||||
$return_string = true;
|
||||
$parent = $root = new DOMDocument();
|
||||
}
|
||||
|
||||
if ( is_array( $array ) ) {
|
||||
|
||||
foreach ( $array as $key => $value ) {
|
||||
$element = $root->createElement( $key );
|
||||
$parent->appendChild( $element );
|
||||
|
||||
if ( is_array( $value ) ) {
|
||||
foreach ( $value as $child_key => $child_value ) {
|
||||
$child = $root->createElement( $child_key );
|
||||
$element->appendChild( $child );
|
||||
$child->appendChild( self::array_to_xml_string( $child_value, $child, $root ) );
|
||||
}
|
||||
} else {
|
||||
$element->appendChild(
|
||||
$root->createTextNode( $value )
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$element = $root->createTextNode( $array );
|
||||
$parent->appendChild( $element );
|
||||
}
|
||||
|
||||
if ( $return_string ) {
|
||||
return $root->saveHTML();
|
||||
} else {
|
||||
return $element;
|
||||
}
|
||||
}
|
||||
}
|
||||
1468
wp-content/plugins/jetpack/modules/sitemaps/sitemap-builder.php
Normal file
1468
wp-content/plugins/jetpack/modules/sitemaps/sitemap-builder.php
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,216 @@
|
||||
<?php
|
||||
/**
|
||||
* Sitemap-related constants.
|
||||
*
|
||||
* @package Jetpack
|
||||
* @since 4.8.0
|
||||
* @author Automattic
|
||||
*/
|
||||
|
||||
/**
|
||||
* Maximum size (in bytes) of a sitemap xml file.
|
||||
* Max is 716800 = 700kb to avoid potential failures for default memcached limits (1MB)
|
||||
*
|
||||
* @link http://www.sitemaps.org/
|
||||
* @since 4.8.0
|
||||
*/
|
||||
if ( ! defined( 'JP_SITEMAP_MAX_BYTES' ) ) {
|
||||
define( 'JP_SITEMAP_MAX_BYTES', 716800 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Maximum size (in url nodes) of a sitemap xml file.
|
||||
* Per the spec, max value is 50000.
|
||||
*
|
||||
* @link http://www.sitemaps.org/
|
||||
* @since 4.8.0
|
||||
*/
|
||||
if ( ! defined( 'JP_SITEMAP_MAX_ITEMS' ) ) {
|
||||
define( 'JP_SITEMAP_MAX_ITEMS', 2000 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Maximum size (in url nodes) of a news sitemap xml file.
|
||||
* Per the spec, max value is 1000.
|
||||
*
|
||||
* @link https://support.google.com/news/publisher/answer/74288?hl=en
|
||||
* @since 4.8.0
|
||||
*/
|
||||
if ( ! defined( 'JP_NEWS_SITEMAP_MAX_ITEMS' ) ) {
|
||||
define( 'JP_NEWS_SITEMAP_MAX_ITEMS', 1000 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Batch size for database queries.
|
||||
*
|
||||
* @since 4.8.0
|
||||
*/
|
||||
if ( ! defined( 'JP_SITEMAP_BATCH_SIZE' ) ) {
|
||||
define( 'JP_SITEMAP_BATCH_SIZE', 50 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Number of sitemap files to update on each run.
|
||||
*
|
||||
* @since 4.8.0
|
||||
*/
|
||||
if ( ! defined( 'JP_SITEMAP_UPDATE_SIZE' ) ) {
|
||||
define( 'JP_SITEMAP_UPDATE_SIZE', 100 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Number of seconds between sitemap updates.
|
||||
*
|
||||
* @since 4.8.0
|
||||
*/
|
||||
if ( ! defined( 'JP_SITEMAP_INTERVAL' ) ) {
|
||||
define( 'JP_SITEMAP_INTERVAL', 12 * HOUR_IN_SECONDS );
|
||||
}
|
||||
|
||||
/**
|
||||
* Number of seconds to lock the sitemap state.
|
||||
*
|
||||
* @since 4.8.0
|
||||
*/
|
||||
if ( ! defined( 'JP_SITEMAP_LOCK_INTERVAL' ) ) {
|
||||
define( 'JP_SITEMAP_LOCK_INTERVAL', 15 * MINUTE_IN_SECONDS );
|
||||
}
|
||||
|
||||
/**
|
||||
* Cache lifetime of news sitemap (in seconds).
|
||||
*
|
||||
* @since 4.8.0
|
||||
*/
|
||||
if ( ! defined( 'JP_NEWS_SITEMAP_INTERVAL' ) ) {
|
||||
define( 'JP_NEWS_SITEMAP_INTERVAL', 12 * HOUR_IN_SECONDS );
|
||||
}
|
||||
|
||||
/*
|
||||
* These constants represent the types of various kinds of sitemaps.
|
||||
* Note: these strings are used as 'post_types' in the database, and
|
||||
* so must be at most 20 characters long.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'JP_MASTER_SITEMAP_TYPE' ) ) {
|
||||
define( 'JP_MASTER_SITEMAP_TYPE', 'jp_sitemap_master' );
|
||||
}
|
||||
|
||||
if ( ! defined( 'JP_PAGE_SITEMAP_TYPE' ) ) {
|
||||
define( 'JP_PAGE_SITEMAP_TYPE', 'jp_sitemap' );
|
||||
}
|
||||
|
||||
if ( ! defined( 'JP_PAGE_SITEMAP_INDEX_TYPE' ) ) {
|
||||
define( 'JP_PAGE_SITEMAP_INDEX_TYPE', 'jp_sitemap_index' );
|
||||
}
|
||||
|
||||
if ( ! defined( 'JP_IMAGE_SITEMAP_TYPE' ) ) {
|
||||
define( 'JP_IMAGE_SITEMAP_TYPE', 'jp_img_sitemap' );
|
||||
}
|
||||
|
||||
if ( ! defined( 'JP_IMAGE_SITEMAP_INDEX_TYPE' ) ) {
|
||||
define( 'JP_IMAGE_SITEMAP_INDEX_TYPE', 'jp_img_sitemap_index' );
|
||||
}
|
||||
|
||||
if ( ! defined( 'JP_VIDEO_SITEMAP_TYPE' ) ) {
|
||||
define( 'JP_VIDEO_SITEMAP_TYPE', 'jp_vid_sitemap' );
|
||||
}
|
||||
|
||||
if ( ! defined( 'JP_VIDEO_SITEMAP_INDEX_TYPE' ) ) {
|
||||
define( 'JP_VIDEO_SITEMAP_INDEX_TYPE', 'jp_vid_sitemap_index' );
|
||||
}
|
||||
|
||||
/**
|
||||
* The name (with extension) of a sitemap file of the given
|
||||
* type and number.
|
||||
*
|
||||
* @since 4.8.0
|
||||
*
|
||||
* @param string $type The sitemap type.
|
||||
* @param string $number The sitemap number.
|
||||
*
|
||||
* @return string The filename.
|
||||
*/
|
||||
function jp_sitemap_filename( $type, $number = null ) {
|
||||
if ( is_null( $number ) ) {
|
||||
return "error-not-int-$type-$number.xml";
|
||||
} elseif ( JP_MASTER_SITEMAP_TYPE === $type ) {
|
||||
return 'sitemap.xml';
|
||||
} elseif ( JP_PAGE_SITEMAP_TYPE === $type ) {
|
||||
return "sitemap-$number.xml";
|
||||
} elseif ( JP_PAGE_SITEMAP_INDEX_TYPE === $type ) {
|
||||
return "sitemap-index-$number.xml";
|
||||
} elseif ( JP_IMAGE_SITEMAP_TYPE === $type ) {
|
||||
return "image-sitemap-$number.xml";
|
||||
} elseif ( JP_IMAGE_SITEMAP_INDEX_TYPE === $type ) {
|
||||
return "image-sitemap-index-$number.xml";
|
||||
} elseif ( JP_VIDEO_SITEMAP_TYPE === $type ) {
|
||||
return "video-sitemap-$number.xml";
|
||||
} elseif ( JP_VIDEO_SITEMAP_INDEX_TYPE === $type ) {
|
||||
return "video-sitemap-index-$number.xml";
|
||||
} else {
|
||||
return "error-bad-type-$type-$number.xml";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The index type corresponding to a sitemap type.
|
||||
*
|
||||
* @since 4.8.0
|
||||
*
|
||||
* @param string $type The sitemap type.
|
||||
*
|
||||
* @return string The index type.
|
||||
*/
|
||||
function jp_sitemap_index_type_of( $type ) {
|
||||
if ( JP_PAGE_SITEMAP_TYPE === $type ) {
|
||||
return JP_PAGE_SITEMAP_INDEX_TYPE;
|
||||
} elseif ( JP_IMAGE_SITEMAP_TYPE === $type ) {
|
||||
return JP_IMAGE_SITEMAP_INDEX_TYPE;
|
||||
} elseif ( JP_VIDEO_SITEMAP_TYPE === $type ) {
|
||||
return JP_VIDEO_SITEMAP_INDEX_TYPE;
|
||||
} else {
|
||||
return "error-bad-type-$type";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The sitemap type corresponding to an index type.
|
||||
*
|
||||
* @since 4.8.0
|
||||
*
|
||||
* @param string $type The index type.
|
||||
*
|
||||
* @return string The sitemap type.
|
||||
*/
|
||||
function jp_sitemap_child_type_of( $type ) {
|
||||
if ( JP_PAGE_SITEMAP_INDEX_TYPE === $type ) {
|
||||
return JP_PAGE_SITEMAP_TYPE;
|
||||
} elseif ( JP_IMAGE_SITEMAP_INDEX_TYPE === $type ) {
|
||||
return JP_IMAGE_SITEMAP_TYPE;
|
||||
} elseif ( JP_VIDEO_SITEMAP_INDEX_TYPE === $type ) {
|
||||
return JP_VIDEO_SITEMAP_TYPE;
|
||||
} else {
|
||||
return "error-bad-type-$type";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert '0000-00-00 00:00:00' to '0000-00-00T00:00:00Z'.
|
||||
* Note that the input is assumed to be in UTC (a.k.a. GMT).
|
||||
*
|
||||
* @link https://www.w3.org/TR/NOTE-datetime
|
||||
* @since 4.8.0
|
||||
*
|
||||
* @param string $datetime The timestamp to convert.
|
||||
*
|
||||
* @return string The converted timestamp.
|
||||
*/
|
||||
function jp_sitemap_datetime( $datetime ) {
|
||||
$regex = '/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/';
|
||||
|
||||
if ( preg_match( $regex, $datetime ) ) {
|
||||
return str_replace( ' ', 'T', $datetime ) . 'Z';
|
||||
} else {
|
||||
return $datetime;
|
||||
}
|
||||
}
|
||||
116
wp-content/plugins/jetpack/modules/sitemaps/sitemap-finder.php
Normal file
116
wp-content/plugins/jetpack/modules/sitemaps/sitemap-finder.php
Normal file
@@ -0,0 +1,116 @@
|
||||
<?php
|
||||
/**
|
||||
* The functions in this class provide an API for handling
|
||||
* sitemap related URIs.
|
||||
*
|
||||
* @package Jetpack
|
||||
* @since 4.8.0
|
||||
* @author Automattic
|
||||
*/
|
||||
|
||||
/**
|
||||
* The Jetpack_Sitemap_Finder object deals with constructing
|
||||
* sitemap URIs.
|
||||
*
|
||||
* @since 4.8.0
|
||||
*/
|
||||
class Jetpack_Sitemap_Finder {
|
||||
|
||||
/**
|
||||
* Construct the complete URL of a sitemap file. Depends on
|
||||
* permalink settings.
|
||||
*
|
||||
* @access public
|
||||
* @since 4.8.0
|
||||
* @since 4.8.1 Call jetpack_sitemap_uri()
|
||||
*
|
||||
* @param string $filename The filename of the sitemap.
|
||||
*
|
||||
* @return string Complete URI of the given sitemap file.
|
||||
*/
|
||||
public function construct_sitemap_url( $filename ) {
|
||||
$url = jetpack_sitemap_uri( $filename );
|
||||
|
||||
if ( pathinfo( $filename, PATHINFO_EXTENSION ) === 'xsl' ) {
|
||||
// strip scheme for sites where sitemap could be access via http or https
|
||||
$url = preg_replace( '/^https?:/', '', $url );
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Path and query prefix of sitemap files. Depends on permalink
|
||||
* settings.
|
||||
*
|
||||
* @access public
|
||||
* @since 4.8.0
|
||||
*
|
||||
* @return string The path+query prefix.
|
||||
*/
|
||||
public function the_jetpack_sitemap_path_and_query_prefix() {
|
||||
global $wp_rewrite;
|
||||
|
||||
// Get path fragment from home_url().
|
||||
$home = wp_parse_url( home_url() );
|
||||
if ( isset( $home['path'] ) ) {
|
||||
$home_path = $home['path'];
|
||||
} else {
|
||||
$home_path = '';
|
||||
}
|
||||
|
||||
// Get additional path fragment from filter.
|
||||
$location = Jetpack_Options::get_option_and_ensure_autoload(
|
||||
'jetpack_sitemap_location',
|
||||
''
|
||||
);
|
||||
|
||||
if ( $wp_rewrite->using_index_permalinks() ) {
|
||||
return $home_path . '/index.php' . $location . '/';
|
||||
} elseif ( $wp_rewrite->using_permalinks() ) {
|
||||
return $home_path . $location . '/';
|
||||
} else {
|
||||
return $home_path . $location . '/?jetpack-sitemap=';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Examine a path+query URI fragment looking for a sitemap request.
|
||||
*
|
||||
* @access public
|
||||
* @since 4.8.0
|
||||
*
|
||||
* @param string $raw_uri A URI (path+query only) to test for sitemap-ness.
|
||||
*
|
||||
* @return array @args {
|
||||
* @type string $sitemap_name The recognized sitemap name (or null).
|
||||
* }
|
||||
*/
|
||||
public function recognize_sitemap_uri( $raw_uri ) {
|
||||
// The path+query where sitemaps are served.
|
||||
$sitemap_path = $this->the_jetpack_sitemap_path_and_query_prefix();
|
||||
|
||||
// A regex which detects $sitemap_path at the beginning of a string.
|
||||
$path_regex = '/^' . preg_quote( $sitemap_path, '/' ) . '/';
|
||||
|
||||
// Check that the request URI begins with the sitemap path.
|
||||
if ( preg_match( $path_regex, $raw_uri ) ) {
|
||||
// Strip off the $sitemap_path and any trailing slash.
|
||||
$stripped_uri = preg_replace( $path_regex, '', rtrim( $raw_uri, '/' ) );
|
||||
} else {
|
||||
$stripped_uri = '';
|
||||
}
|
||||
|
||||
// Check that the stripped uri begins with one of the sitemap prefixes.
|
||||
if ( preg_match( '/^sitemap|^image-s|^news-s|^video-s/', $stripped_uri ) ) {
|
||||
$filename = $stripped_uri;
|
||||
} else {
|
||||
$filename = null;
|
||||
}
|
||||
|
||||
return array(
|
||||
'sitemap_name' => $filename,
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,431 @@
|
||||
<?php
|
||||
/**
|
||||
* Sitemaps are stored in the database using a custom table. This class
|
||||
* provides a small API for storing and retrieving sitemap data so we can
|
||||
* avoid lots of explicit SQL juggling while building sitemaps. This file
|
||||
* also includes the SQL used to retrieve posts and images to be included
|
||||
* in the sitemaps.
|
||||
*
|
||||
* @since 4.8.0
|
||||
* @package Jetpack
|
||||
*/
|
||||
|
||||
/* Ensure sitemap constants are available. */
|
||||
require_once dirname( __FILE__ ) . '/sitemap-constants.php';
|
||||
|
||||
/**
|
||||
* This object handles any database interaction required
|
||||
* for sitemap generation.
|
||||
*
|
||||
* @since 4.8.0
|
||||
*/
|
||||
class Jetpack_Sitemap_Librarian {
|
||||
|
||||
/**
|
||||
* Retrieve a single sitemap with given name and type.
|
||||
* Returns null if no such sitemap exists.
|
||||
*
|
||||
* @access public
|
||||
* @since 4.8.0
|
||||
*
|
||||
* @param string $name Name of the sitemap to be retrieved.
|
||||
* @param string $type Type of the sitemap to be retrieved.
|
||||
*
|
||||
* @return array $args {
|
||||
* @type int $id ID number of the sitemap in the database.
|
||||
* @type string $timestamp Most recent timestamp of the resources pointed to.
|
||||
* @type string $name Name of the sitemap in the database.
|
||||
* @type string $type Type of the sitemap in the database.
|
||||
* @type string $text The content of the sitemap.
|
||||
* }
|
||||
*/
|
||||
public function read_sitemap_data( $name, $type ) {
|
||||
$post_array = get_posts(
|
||||
array(
|
||||
'numberposts' => 1,
|
||||
'title' => $name,
|
||||
'post_type' => $type,
|
||||
'post_status' => 'draft',
|
||||
)
|
||||
);
|
||||
|
||||
$the_post = array_shift( $post_array );
|
||||
|
||||
if ( null === $the_post ) {
|
||||
return null;
|
||||
} else {
|
||||
return array(
|
||||
'id' => $the_post->ID,
|
||||
'timestamp' => $the_post->post_date,
|
||||
'name' => $the_post->post_title,
|
||||
'type' => $the_post->post_type,
|
||||
'text' => base64_decode( $the_post->post_content ),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a sitemap of given type and index in the database.
|
||||
* Note that the timestamp is reencoded as 'Y-m-d H:i:s'.
|
||||
*
|
||||
* If a sitemap with that type and name does not exist, create it.
|
||||
* If a sitemap with that type and name does exist, update it.
|
||||
*
|
||||
* @access public
|
||||
* @since 4.8.0
|
||||
*
|
||||
* @param string $index Index of the sitemap to be stored.
|
||||
* @param string $type Type of the sitemap to be stored.
|
||||
* @param string $contents Contents of the sitemap to be stored.
|
||||
* @param string $timestamp Timestamp of the sitemap to be stored, in 'YYYY-MM-DD hh:mm:ss' format.
|
||||
*/
|
||||
public function store_sitemap_data( $index, $type, $contents, $timestamp ) {
|
||||
$name = jp_sitemap_filename( $type, $index );
|
||||
|
||||
$the_post = $this->read_sitemap_data( $name, $type );
|
||||
|
||||
if ( null === $the_post ) {
|
||||
// Post does not exist.
|
||||
wp_insert_post(
|
||||
array(
|
||||
'post_title' => $name,
|
||||
'post_content' => base64_encode( $contents ),
|
||||
'post_type' => $type,
|
||||
'post_date' => date( 'Y-m-d H:i:s', strtotime( $timestamp ) ),
|
||||
)
|
||||
);
|
||||
} else {
|
||||
// Post does exist.
|
||||
wp_insert_post(
|
||||
array(
|
||||
'ID' => $the_post['id'],
|
||||
'post_title' => $name,
|
||||
'post_content' => base64_encode( $contents ),
|
||||
'post_type' => $type,
|
||||
'post_date' => date( 'Y-m-d H:i:s', strtotime( $timestamp ) ),
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a sitemap by name and type.
|
||||
*
|
||||
* @access public
|
||||
* @since 4.8.0
|
||||
*
|
||||
* @param string $name Row name.
|
||||
* @param string $type Row type.
|
||||
*
|
||||
* @return bool 'true' if a row was deleted, 'false' otherwise.
|
||||
*/
|
||||
public function delete_sitemap_data( $name, $type ) {
|
||||
$the_post = $this->read_sitemap_data( $name, $type );
|
||||
|
||||
if ( null === $the_post ) {
|
||||
return false;
|
||||
} else {
|
||||
wp_delete_post( $the_post['id'] );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the contents of a sitemap with given name and type.
|
||||
* If no such sitemap exists, return the empty string. Note that the
|
||||
* returned string is run through wp_specialchars_decode.
|
||||
*
|
||||
* @access public
|
||||
* @since 4.8.0
|
||||
*
|
||||
* @param string $name Row name.
|
||||
* @param string $type Row type.
|
||||
*
|
||||
* @return string Text of the specified sitemap, or the empty string.
|
||||
*/
|
||||
public function get_sitemap_text( $name, $type ) {
|
||||
$row = $this->read_sitemap_data( $name, $type );
|
||||
|
||||
if ( null === $row ) {
|
||||
return '';
|
||||
} else {
|
||||
return $row['text'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete numbered sitemaps named prefix-(p+1), prefix-(p+2), ...
|
||||
* until the first nonexistent sitemap is found.
|
||||
*
|
||||
* @access public
|
||||
* @since 4.8.0
|
||||
*
|
||||
* @param int $position Number before the first sitemap to be deleted.
|
||||
* @param string $type Sitemap type.
|
||||
*/
|
||||
public function delete_numbered_sitemap_rows_after( $position, $type ) {
|
||||
$any_left = true;
|
||||
|
||||
while ( true === $any_left ) {
|
||||
$position++;
|
||||
$name = jp_sitemap_filename( $type, $position );
|
||||
$any_left = $this->delete_sitemap_data( $name, $type );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes all stored sitemap data.
|
||||
*
|
||||
* @access public
|
||||
* @since 4.8.0
|
||||
*/
|
||||
public function delete_all_stored_sitemap_data() {
|
||||
$this->delete_sitemap_type_data( JP_MASTER_SITEMAP_TYPE );
|
||||
$this->delete_sitemap_type_data( JP_PAGE_SITEMAP_TYPE );
|
||||
$this->delete_sitemap_type_data( JP_PAGE_SITEMAP_INDEX_TYPE );
|
||||
$this->delete_sitemap_type_data( JP_IMAGE_SITEMAP_TYPE );
|
||||
$this->delete_sitemap_type_data( JP_IMAGE_SITEMAP_INDEX_TYPE );
|
||||
$this->delete_sitemap_type_data( JP_VIDEO_SITEMAP_TYPE );
|
||||
$this->delete_sitemap_type_data( JP_VIDEO_SITEMAP_INDEX_TYPE );
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes all sitemap data of specific type
|
||||
*
|
||||
* @access protected
|
||||
* @since 5.3.0
|
||||
*
|
||||
* @param String $type Type of sitemap.
|
||||
*/
|
||||
protected function delete_sitemap_type_data( $type ) {
|
||||
$ids = get_posts(
|
||||
array(
|
||||
'post_type' => $type,
|
||||
'post_status' => 'draft',
|
||||
'fields' => 'ids',
|
||||
)
|
||||
);
|
||||
|
||||
foreach ( $ids as $id ) {
|
||||
wp_trash_post( $id );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve an array of sitemap rows (of a given type) sorted by ID.
|
||||
*
|
||||
* Returns the smallest $num_posts sitemap rows (measured by ID)
|
||||
* of the given type which are larger than $from_id.
|
||||
*
|
||||
* @access public
|
||||
* @since 4.8.0
|
||||
*
|
||||
* @param string $type Type of the sitemap rows to retrieve.
|
||||
* @param int $from_id Greatest lower bound of retrieved sitemap post IDs.
|
||||
* @param int $num_posts Largest number of sitemap posts to retrieve.
|
||||
*
|
||||
* @return array The sitemaps, as an array of associative arrays.
|
||||
*/
|
||||
public function query_sitemaps_after_id( $type, $from_id, $num_posts ) {
|
||||
global $wpdb;
|
||||
|
||||
return $wpdb->get_results(
|
||||
$wpdb->prepare(
|
||||
"SELECT *
|
||||
FROM $wpdb->posts
|
||||
WHERE post_type=%s
|
||||
AND post_status=%s
|
||||
AND ID>%d
|
||||
ORDER BY ID ASC
|
||||
LIMIT %d;",
|
||||
$type,
|
||||
'draft',
|
||||
$from_id,
|
||||
$num_posts
|
||||
),
|
||||
ARRAY_A
|
||||
); // WPCS: db call ok; no-cache ok.
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve an array of posts sorted by ID.
|
||||
*
|
||||
* More precisely, returns the smallest $num_posts posts
|
||||
* (measured by ID) which are larger than $from_id.
|
||||
*
|
||||
* @access public
|
||||
* @since 4.8.0
|
||||
*
|
||||
* @param int $from_id Greatest lower bound of retrieved post IDs.
|
||||
* @param int $num_posts Largest number of posts to retrieve.
|
||||
*
|
||||
* @return array The posts.
|
||||
*/
|
||||
public function query_posts_after_id( $from_id, $num_posts ) {
|
||||
global $wpdb;
|
||||
|
||||
// Get the list of post types to include and prepare for query.
|
||||
$post_types = Jetpack_Options::get_option_and_ensure_autoload(
|
||||
'jetpack_sitemap_post_types',
|
||||
array( 'page', 'post' )
|
||||
);
|
||||
foreach ( (array) $post_types as $i => $post_type ) {
|
||||
$post_types[ $i ] = $wpdb->prepare( '%s', $post_type );
|
||||
}
|
||||
$post_types_list = join( ',', $post_types );
|
||||
|
||||
return $wpdb->get_results(
|
||||
$wpdb->prepare(
|
||||
"SELECT *
|
||||
FROM $wpdb->posts
|
||||
WHERE post_status='publish'
|
||||
AND post_type IN ($post_types_list)
|
||||
AND ID>%d
|
||||
ORDER BY ID ASC
|
||||
LIMIT %d;",
|
||||
$from_id,
|
||||
$num_posts
|
||||
)
|
||||
); // WPCS: db call ok; no-cache ok.
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the most recent timestamp among approved comments for the given post_id.
|
||||
*
|
||||
* @access public
|
||||
* @since 4.8.0
|
||||
*
|
||||
* @param int $post_id Post identifier.
|
||||
*
|
||||
* @return int Timestamp in 'Y-m-d h:i:s' format (UTC) of the most recent comment on the given post, or null if no such comments exist.
|
||||
*/
|
||||
public function query_latest_approved_comment_time_on_post( $post_id ) {
|
||||
global $wpdb;
|
||||
|
||||
return $wpdb->get_var(
|
||||
$wpdb->prepare(
|
||||
"SELECT MAX(comment_date_gmt)
|
||||
FROM $wpdb->comments
|
||||
WHERE comment_post_ID = %d AND comment_approved = '1' AND comment_type=''",
|
||||
$post_id
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve an array of image posts sorted by ID.
|
||||
*
|
||||
* More precisely, returns the smallest $num_posts image posts
|
||||
* (measured by ID) which are larger than $from_id.
|
||||
*
|
||||
* @access public
|
||||
* @since 4.8.0
|
||||
*
|
||||
* @param int $from_id Greatest lower bound of retrieved image post IDs.
|
||||
* @param int $num_posts Largest number of image posts to retrieve.
|
||||
*
|
||||
* @return array The posts.
|
||||
*/
|
||||
public function query_images_after_id( $from_id, $num_posts ) {
|
||||
global $wpdb;
|
||||
|
||||
return $wpdb->get_results(
|
||||
$wpdb->prepare(
|
||||
"SELECT *
|
||||
FROM $wpdb->posts
|
||||
WHERE post_type='attachment'
|
||||
AND post_mime_type LIKE %s
|
||||
AND ID>%d
|
||||
ORDER BY ID ASC
|
||||
LIMIT %d;",
|
||||
'image/%',
|
||||
$from_id,
|
||||
$num_posts
|
||||
)
|
||||
); // WPCS: db call ok; no-cache ok.
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve an array of video posts sorted by ID.
|
||||
*
|
||||
* More precisely, returns the smallest $num_posts video posts
|
||||
* (measured by ID) which are larger than $from_id.
|
||||
*
|
||||
* @access public
|
||||
* @since 4.8.0
|
||||
*
|
||||
* @param int $from_id Greatest lower bound of retrieved video post IDs.
|
||||
* @param int $num_posts Largest number of video posts to retrieve.
|
||||
*
|
||||
* @return array The posts.
|
||||
*/
|
||||
public function query_videos_after_id( $from_id, $num_posts ) {
|
||||
global $wpdb;
|
||||
|
||||
return $wpdb->get_results(
|
||||
$wpdb->prepare(
|
||||
"SELECT *
|
||||
FROM $wpdb->posts
|
||||
WHERE post_type='attachment'
|
||||
AND post_mime_type LIKE %s
|
||||
AND ID>%d
|
||||
ORDER BY ID ASC
|
||||
LIMIT %d;",
|
||||
'video/%',
|
||||
$from_id,
|
||||
$num_posts
|
||||
)
|
||||
); // WPCS: db call ok; no-cache ok.
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve an array of published posts from the last 2 days.
|
||||
*
|
||||
* @access public
|
||||
* @since 4.8.0
|
||||
*
|
||||
* @param int $num_posts Largest number of posts to retrieve.
|
||||
*
|
||||
* @return array The posts.
|
||||
*/
|
||||
public function query_most_recent_posts( $num_posts ) {
|
||||
global $wpdb;
|
||||
|
||||
$two_days_ago = date( 'Y-m-d', strtotime( '-2 days' ) );
|
||||
|
||||
/**
|
||||
* Filter post types to be included in news sitemap.
|
||||
*
|
||||
* @module sitemaps
|
||||
*
|
||||
* @since 3.9.0
|
||||
*
|
||||
* @param array $post_types Array with post types to include in news sitemap.
|
||||
*/
|
||||
$post_types = apply_filters(
|
||||
'jetpack_sitemap_news_sitemap_post_types',
|
||||
array( 'page', 'post' )
|
||||
);
|
||||
|
||||
foreach ( (array) $post_types as $i => $post_type ) {
|
||||
$post_types[ $i ] = $wpdb->prepare( '%s', $post_type );
|
||||
}
|
||||
|
||||
$post_types_list = join( ',', $post_types );
|
||||
|
||||
return $wpdb->get_results(
|
||||
$wpdb->prepare(
|
||||
"SELECT *
|
||||
FROM $wpdb->posts
|
||||
WHERE post_status='publish'
|
||||
AND post_date >= '%s'
|
||||
AND post_type IN ($post_types_list)
|
||||
ORDER BY post_date DESC
|
||||
LIMIT %d;",
|
||||
$two_days_ago,
|
||||
$num_posts
|
||||
)
|
||||
); // WPCS: db call ok; no-cache ok.
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
/**
|
||||
* A message logger for the Jetpack Sitemap module.
|
||||
*
|
||||
* @package Jetpack
|
||||
* @since 4.8.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Handles logging errors and debug messages for sitemap generator.
|
||||
*
|
||||
* A Jetpack_Sitemap_Logger object keeps track of its birth time as well
|
||||
* as a "unique" ID string. Calling the report() method writes a message
|
||||
* to the PHP error log as well as the ID string for easier grepping.
|
||||
*
|
||||
* @since 4.8.0
|
||||
*/
|
||||
class Jetpack_Sitemap_Logger {
|
||||
/**
|
||||
* A unique-ish string for each logger, enabling us to grep
|
||||
* for the messages written by an individual generation phase.
|
||||
*
|
||||
* @access private
|
||||
* @since 4.8.0
|
||||
* @var string $key The key string.
|
||||
*/
|
||||
private $key;
|
||||
|
||||
/**
|
||||
* The birth time of this object in microseconds.
|
||||
*
|
||||
* @access private
|
||||
* @since 4.8.0
|
||||
* @var int $starttime The birth time.
|
||||
*/
|
||||
private $starttime;
|
||||
|
||||
/**
|
||||
* Initializes a new logger object.
|
||||
*
|
||||
* @access public
|
||||
* @since 4.8.0
|
||||
*
|
||||
* @param string $message An optional message string to be written to the debug log on initialization.
|
||||
*/
|
||||
public function __construct( $message = null ) {
|
||||
$this->key = wp_generate_password( 5, false );
|
||||
$this->starttime = microtime( true );
|
||||
if ( ! is_null( $message ) ) {
|
||||
$this->report( $message );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a string to the debug log, including the logger's ID string.
|
||||
*
|
||||
* @access public
|
||||
* @since 4.8.0
|
||||
*
|
||||
* @param string $message The string to be written to the log.
|
||||
* @param boolean $is_error If true, $message will be logged even if JETPACK_DEV_DEBUG is not enabled.
|
||||
*/
|
||||
public function report( $message, $is_error = false ) {
|
||||
$message = 'jp-sitemap-' . $this->key . ': ' . $message;
|
||||
if ( ! ( defined( 'WP_DEBUG' ) && WP_DEBUG ) ) {
|
||||
return;
|
||||
}
|
||||
if ( ! $is_error && ! ( defined( 'JETPACK_DEV_DEBUG' ) && JETPACK_DEV_DEBUG ) ) {
|
||||
return;
|
||||
}
|
||||
error_log( $message ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the elapsed lifetime of the logger to the debug log, with an optional message.
|
||||
*
|
||||
* @access public
|
||||
* @since 4.8.0
|
||||
*
|
||||
* @param string $message The optional message string. Default is the empty string.
|
||||
*/
|
||||
public function time( $message = '' ) {
|
||||
$time = round( microtime( true ) - $this->starttime, 3 );
|
||||
$this->report( $message . ' ' . $time . ' seconds elapsed.' );
|
||||
}
|
||||
}
|
||||
144
wp-content/plugins/jetpack/modules/sitemaps/sitemap-state.php
Normal file
144
wp-content/plugins/jetpack/modules/sitemaps/sitemap-state.php
Normal file
@@ -0,0 +1,144 @@
|
||||
<?php
|
||||
/**
|
||||
* Abstract sitemap generation state class.
|
||||
*
|
||||
* @package Jetpack
|
||||
* @since 4.8.0
|
||||
* @author Automattic
|
||||
*/
|
||||
|
||||
/* Include standard constants and librarian. */
|
||||
require_once dirname( __FILE__ ) . '/sitemap-constants.php';
|
||||
require_once dirname( __FILE__ ) . '/sitemap-librarian.php';
|
||||
|
||||
if ( defined( 'WP_DEBUG' ) && ( true === WP_DEBUG ) ) {
|
||||
require_once dirname( __FILE__ ) . '/sitemap-logger.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* This class provides an interface for storing and retrieving
|
||||
* the state of a sitemap generation phase. Whenever the builder
|
||||
* wants to build a new sitemap page, it uses this class to see
|
||||
* what the current state of the sitemap is. The lock is stored
|
||||
* as a transient with max lifetime of 15 minutes; this way if our
|
||||
* builder times out before unlocking the state, the lock will expire
|
||||
* before the builder tries again.
|
||||
*
|
||||
* @since 4.8.0
|
||||
*/
|
||||
class Jetpack_Sitemap_State {
|
||||
|
||||
/**
|
||||
* Initial state for the sitemap generator.
|
||||
*
|
||||
* @access public
|
||||
* @since 4.8.0
|
||||
*
|
||||
* @param string $type The initial sitemap type.
|
||||
*
|
||||
* @return array $args {
|
||||
* @type string sitemap-type The type of sitemap to be generated.
|
||||
* @type int last-added The largest index to be added to a generated sitemap page.
|
||||
* @type int number The index of the last sitemap to be generated.
|
||||
* @type string last-modified The latest timestamp seen.
|
||||
* @type array max The latest index of each sitemap type seen.
|
||||
* }
|
||||
*/
|
||||
private static function initial( $type = JP_PAGE_SITEMAP_TYPE ) {
|
||||
return array(
|
||||
'sitemap-type' => $type,
|
||||
'last-added' => 0,
|
||||
'number' => 0,
|
||||
'last-modified' => '1970-01-01 00:00:00',
|
||||
'max' => array(),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the sitemap state.
|
||||
*
|
||||
* @param string $type The initial sitemap type.
|
||||
*
|
||||
* @access public
|
||||
* @since 4.8.0
|
||||
*/
|
||||
public static function reset( $type ) {
|
||||
delete_transient( 'jetpack-sitemap-state-lock' );
|
||||
update_option(
|
||||
'jetpack-sitemap-state',
|
||||
self::initial( $type )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a sitemap state, and unlock it.
|
||||
*
|
||||
* @access public
|
||||
* @since 4.8.0
|
||||
*
|
||||
* @param array $state Array of the Sitemap state details.
|
||||
* @type string sitemap-type The type of sitemap to be generated.
|
||||
* @type int last-added The largest index to be added to a generated sitemap page.
|
||||
* @type int number The index of the last sitemap to be generated.
|
||||
* @type string last-modified The latest timestamp seen.
|
||||
*/
|
||||
public static function check_in( $state ) {
|
||||
// Get the old max value.
|
||||
$sitemap_old = get_option( 'jetpack-sitemap-state', self::initial() );
|
||||
$state['max'] = $sitemap_old['max'];
|
||||
|
||||
// Update the max value of the current type.
|
||||
$state['max'][ $state['sitemap-type'] ]['number'] = $state['number'];
|
||||
$state['max'][ $state['sitemap-type'] ]['lastmod'] = $state['last-modified'];
|
||||
|
||||
update_option( 'jetpack-sitemap-state', $state );
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlock the sitemap state.
|
||||
*
|
||||
* @access public
|
||||
* @since 4.8.0
|
||||
*/
|
||||
public static function unlock() {
|
||||
delete_transient( 'jetpack-sitemap-state-lock' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the stored sitemap state. Returns false if the state is locked.
|
||||
*
|
||||
* @access public
|
||||
* @since 4.8.0
|
||||
*
|
||||
* @return bool|array $args {
|
||||
* @type string sitemap-type The type of sitemap to be generated.
|
||||
* @type int last-added The largest index to be added to a generated sitemap page.
|
||||
* @type int number The index of the last sitemap to be generated.
|
||||
* @type string last-modified The latest timestamp seen.
|
||||
* @type array max The latest index of each sitemap type seen.
|
||||
* }
|
||||
*/
|
||||
public static function check_out() {
|
||||
// See if the state is locked.
|
||||
if ( true === get_transient( 'jetpack-sitemap-state-lock' ) ) {
|
||||
// If it is, return false.
|
||||
return false;
|
||||
} else {
|
||||
// Otherwise, lock the state for 15 minutes and then return it.
|
||||
set_transient( 'jetpack-sitemap-state-lock', true, JP_SITEMAP_LOCK_INTERVAL );
|
||||
return get_option( 'jetpack-sitemap-state', self::initial() );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the stored state and lock.
|
||||
*
|
||||
* @access public
|
||||
* @since 4.8.0
|
||||
*/
|
||||
public static function delete() {
|
||||
delete_transient( 'jetpack-sitemap-state-lock' );
|
||||
delete_option( 'jetpack-sitemap-state' );
|
||||
}
|
||||
|
||||
}
|
||||
783
wp-content/plugins/jetpack/modules/sitemaps/sitemap-stylist.php
Normal file
783
wp-content/plugins/jetpack/modules/sitemaps/sitemap-stylist.php
Normal file
@@ -0,0 +1,783 @@
|
||||
<?php
|
||||
/**
|
||||
* The XSL used to style sitemaps is essentially a bunch of
|
||||
* static strings. This class handles the construction of
|
||||
* those strings.
|
||||
*
|
||||
* @package Jetpack
|
||||
* @since 4.8.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Builds the XSL files required by Jetpack_Sitemap_Manager.
|
||||
*
|
||||
* @since 4.8.0
|
||||
*/
|
||||
class Jetpack_Sitemap_Stylist {
|
||||
|
||||
/**
|
||||
* Convert named entities, strip all HTML except anchor tags,
|
||||
* and interpolate with vsprintf. This is a helper function
|
||||
* for all the internationalized UI strings in this class
|
||||
* which have to include URLs.
|
||||
*
|
||||
* Note that $url_array should be indexed by integers like so:
|
||||
*
|
||||
* array(
|
||||
* 1 => 'example.com',
|
||||
* 2 => 'example.org',
|
||||
* );
|
||||
*
|
||||
* Then '%1$s' in the format string will substitute 'example.com'
|
||||
* and '%2$s' will substitute 'example.org'.
|
||||
*
|
||||
* @access private
|
||||
* @since 4.8.0
|
||||
* @link http://php.net/manual/en/function.vsprintf.php Format string documentation.
|
||||
*
|
||||
* @param string $format A vsprintf-style format string to be sanitized.
|
||||
* @param array $url_array The string substitution array to be passed to vsprintf.
|
||||
*
|
||||
* @return string The sanitized string.
|
||||
*/
|
||||
private static function sanitize_with_links( $format, $url_array ) {
|
||||
return vsprintf(
|
||||
wp_kses(
|
||||
ent2ncr( $format ),
|
||||
array(
|
||||
'a' => array(
|
||||
'href' => true,
|
||||
'title' => true,
|
||||
),
|
||||
)
|
||||
),
|
||||
$url_array
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the xsl of a sitemap xml file as a string.
|
||||
*
|
||||
* @access public
|
||||
* @since 4.8.0
|
||||
*
|
||||
* @return string The contents of the xsl file.
|
||||
*/
|
||||
public static function sitemap_xsl() {
|
||||
$title = esc_html( ent2ncr( __( 'XML Sitemap', 'jetpack' ) ) );
|
||||
$header_url = esc_html( ent2ncr( __( 'URL', 'jetpack' ) ) );
|
||||
$header_lastmod = esc_html( ent2ncr( __( 'Last Modified', 'jetpack' ) ) );
|
||||
|
||||
$description = self::sanitize_with_links(
|
||||
__(
|
||||
'This is an XML Sitemap generated by <a href="%1$s" rel="noopener noreferrer" target="_blank">Jetpack</a>, meant to be consumed by search engines like <a href="%2$s" rel="noopener noreferrer" target="_blank">Google</a> or <a href="%3$s" rel="noopener noreferrer" target="_blank">Bing</a>.',
|
||||
'jetpack'
|
||||
),
|
||||
array(
|
||||
1 => 'http://jetpack.com/',
|
||||
2 => 'https://www.google.com/',
|
||||
3 => 'https://www.bing.com/',
|
||||
)
|
||||
);
|
||||
|
||||
$more_info = self::sanitize_with_links(
|
||||
__(
|
||||
'You can find more information on XML sitemaps at <a href="%1$s" rel="noopener noreferrer" target="_blank">sitemaps.org</a>',
|
||||
'jetpack'
|
||||
),
|
||||
array(
|
||||
1 => 'http://sitemaps.org',
|
||||
)
|
||||
);
|
||||
|
||||
$generated_by = self::sanitize_with_links(
|
||||
__(
|
||||
'Generated by <a href="%s" rel="noopener noreferrer" target="_blank">Jetpack for WordPress</a>',
|
||||
'jetpack'
|
||||
),
|
||||
array(
|
||||
1 => 'https://jetpack.com',
|
||||
)
|
||||
);
|
||||
|
||||
$css = self::sitemap_xsl_css();
|
||||
|
||||
return <<<XSL
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<xsl:stylesheet version='2.0'
|
||||
xmlns:html='http://www.w3.org/TR/REC-html40'
|
||||
xmlns:sitemap='http://www.sitemaps.org/schemas/sitemap/0.9'
|
||||
xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
|
||||
<xsl:output method='html' version='1.0' encoding='UTF-8' indent='yes'/>
|
||||
<xsl:template match="/">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>$title</title>
|
||||
<meta http-equiv='Content-Type' content='text/html; charset=utf-8'/>
|
||||
<style type='text/css'>
|
||||
$css
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id='description'>
|
||||
<h1>$title</h1>
|
||||
<p>$description</p>
|
||||
<p>$more_info</p>
|
||||
</div>
|
||||
<div id='content'>
|
||||
<!-- <xsl:value-of select="count(sitemap:urlset/sitemap:url)"/> -->
|
||||
<table>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>$header_url</th>
|
||||
<th>$header_lastmod</th>
|
||||
</tr>
|
||||
<xsl:for-each select="sitemap:urlset/sitemap:url">
|
||||
<tr>
|
||||
<xsl:choose>
|
||||
<xsl:when test='position() mod 2 != 1'>
|
||||
<xsl:attribute name="class">odd</xsl:attribute>
|
||||
</xsl:when>
|
||||
</xsl:choose>
|
||||
<td>
|
||||
<xsl:value-of select = "position()" />
|
||||
</td>
|
||||
<td>
|
||||
<xsl:variable name='itemURL'>
|
||||
<xsl:value-of select='sitemap:loc'/>
|
||||
</xsl:variable>
|
||||
<a href='{\$itemURL}'>
|
||||
<xsl:value-of select='sitemap:loc'/>
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
<xsl:value-of select='sitemap:lastmod'/>
|
||||
</td>
|
||||
</tr>
|
||||
</xsl:for-each>
|
||||
</table>
|
||||
</div>
|
||||
<div id='footer'>
|
||||
<p>$generated_by</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>\n
|
||||
XSL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the xsl of a sitemap index xml file as a string.
|
||||
*
|
||||
* @access public
|
||||
* @since 4.8.0
|
||||
*
|
||||
* @return string The contents of the xsl file.
|
||||
*/
|
||||
public static function sitemap_index_xsl() {
|
||||
$title = esc_html( ent2ncr( __( 'XML Sitemap Index', 'jetpack' ) ) );
|
||||
$header_url = esc_html( ent2ncr( __( 'Sitemap URL', 'jetpack' ) ) );
|
||||
$header_lastmod = esc_html( ent2ncr( __( 'Last Modified', 'jetpack' ) ) );
|
||||
|
||||
$description = self::sanitize_with_links(
|
||||
__(
|
||||
'This is an XML Sitemap Index generated by <a href="%1$s" rel="noopener noreferrer" target="_blank">Jetpack</a>, meant to be consumed by search engines like <a href="%2$s" rel="noopener noreferrer" target="_blank">Google</a> or <a href="%3$s" rel="noopener noreferrer" target="_blank">Bing</a>.',
|
||||
'jetpack'
|
||||
),
|
||||
array(
|
||||
1 => 'http://jetpack.com/',
|
||||
2 => 'https://www.google.com/',
|
||||
3 => 'https://www.bing.com/',
|
||||
)
|
||||
);
|
||||
|
||||
if ( current_user_can( 'manage_options' ) ) {
|
||||
$next = human_time_diff( wp_next_scheduled( 'jp_sitemap_cron_hook' ) );
|
||||
/* translators: %s is a human_time_diff until next sitemap generation. */
|
||||
$no_nodes_warning = sprintf( __( 'No sitemap found. The system will try to build it again in %s.', 'jetpack' ), $next );
|
||||
} else {
|
||||
$no_nodes_warning = '';
|
||||
}
|
||||
|
||||
$more_info = self::sanitize_with_links(
|
||||
__(
|
||||
'You can find more information on XML sitemaps at <a href="%1$s" rel="noopener noreferrer" target="_blank">sitemaps.org</a>',
|
||||
'jetpack'
|
||||
),
|
||||
array(
|
||||
1 => 'http://sitemaps.org',
|
||||
)
|
||||
);
|
||||
|
||||
$generated_by = self::sanitize_with_links(
|
||||
__(
|
||||
'Generated by <a href="%s" rel="noopener noreferrer" target="_blank">Jetpack for WordPress</a>',
|
||||
'jetpack'
|
||||
),
|
||||
array(
|
||||
1 => 'https://jetpack.com',
|
||||
)
|
||||
);
|
||||
|
||||
$css = self::sitemap_xsl_css();
|
||||
|
||||
return <<<XSL
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<xsl:stylesheet version='2.0'
|
||||
xmlns:html='http://www.w3.org/TR/REC-html40'
|
||||
xmlns:sitemap='http://www.sitemaps.org/schemas/sitemap/0.9'
|
||||
xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
|
||||
<xsl:output method='html' version='1.0' encoding='UTF-8' indent='yes'/>
|
||||
<xsl:template match="/">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>$title</title>
|
||||
<meta http-equiv='Content-Type' content='text/html; charset=utf-8'/>
|
||||
<style type='text/css'>
|
||||
$css
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id='description'>
|
||||
<h1>$title</h1>
|
||||
<xsl:choose>
|
||||
<xsl:when test='not(sitemap:sitemapindex/sitemap:sitemap)'>
|
||||
<p><strong>$no_nodes_warning</strong></p>
|
||||
</xsl:when>
|
||||
</xsl:choose>
|
||||
<p>$description</p>
|
||||
<p>$more_info</p>
|
||||
</div>
|
||||
<div id='content'>
|
||||
<table>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>$header_url</th>
|
||||
<th>$header_lastmod</th>
|
||||
</tr>
|
||||
<xsl:for-each select='sitemap:sitemapindex/sitemap:sitemap'>
|
||||
<tr>
|
||||
<xsl:choose>
|
||||
<xsl:when test='position() mod 2 != 1'>
|
||||
<xsl:attribute name="class">odd</xsl:attribute>
|
||||
</xsl:when>
|
||||
</xsl:choose>
|
||||
<td>
|
||||
<xsl:value-of select = "position()" />
|
||||
</td>
|
||||
<td>
|
||||
<xsl:variable name='itemURL'>
|
||||
<xsl:value-of select='sitemap:loc'/>
|
||||
</xsl:variable>
|
||||
<a href='{\$itemURL}'>
|
||||
<xsl:value-of select='sitemap:loc'/>
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
<xsl:value-of select='sitemap:lastmod'/>
|
||||
</td>
|
||||
</tr>
|
||||
</xsl:for-each>
|
||||
</table>
|
||||
</div>
|
||||
<div id='footer'>
|
||||
<p>$generated_by</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>\n
|
||||
XSL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the xsl of an image sitemap xml file as a string.
|
||||
*
|
||||
* @access public
|
||||
* @since 4.8.0
|
||||
*
|
||||
* @return string The contents of the xsl file.
|
||||
*/
|
||||
public static function image_sitemap_xsl() {
|
||||
$title = esc_html( ent2ncr( __( 'XML Image Sitemap', 'jetpack' ) ) );
|
||||
$header_url = esc_html( ent2ncr( __( 'Page URL', 'jetpack' ) ) );
|
||||
$header_image_url = esc_html( ent2ncr( __( 'Image URL', 'jetpack' ) ) );
|
||||
$header_thumbnail = esc_html( ent2ncr( __( 'Thumbnail', 'jetpack' ) ) );
|
||||
$header_title = esc_html( ent2ncr( __( 'Title', 'jetpack' ) ) );
|
||||
$header_lastmod = esc_html( ent2ncr( __( 'Last Modified', 'jetpack' ) ) );
|
||||
$header_caption = esc_html( ent2ncr( __( 'Caption', 'jetpack' ) ) );
|
||||
|
||||
$description = self::sanitize_with_links(
|
||||
__(
|
||||
'This is an XML Image Sitemap generated by <a href="%1$s" rel="noopener noreferrer" target="_blank">Jetpack</a>, meant to be consumed by search engines like <a href="%2$s" rel="noopener noreferrer" target="_blank">Google</a> or <a href="%3$s" rel="noopener noreferrer" target="_blank">Bing</a>.',
|
||||
'jetpack'
|
||||
),
|
||||
array(
|
||||
1 => 'http://jetpack.com/',
|
||||
2 => 'https://www.google.com/',
|
||||
3 => 'https://www.bing.com/',
|
||||
)
|
||||
);
|
||||
|
||||
$more_info = self::sanitize_with_links(
|
||||
__(
|
||||
'You can find more information on XML sitemaps at <a href="%1$s" rel="noopener noreferrer" target="_blank">sitemaps.org</a>',
|
||||
'jetpack'
|
||||
),
|
||||
array(
|
||||
1 => 'http://sitemaps.org',
|
||||
)
|
||||
);
|
||||
|
||||
$generated_by = self::sanitize_with_links(
|
||||
__(
|
||||
'Generated by <a href="%s" rel="noopener noreferrer" target="_blank">Jetpack for WordPress</a>',
|
||||
'jetpack'
|
||||
),
|
||||
array(
|
||||
1 => 'https://jetpack.com',
|
||||
)
|
||||
);
|
||||
|
||||
$css = self::sitemap_xsl_css();
|
||||
|
||||
return <<<XSL
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<xsl:stylesheet version='2.0'
|
||||
xmlns:html='http://www.w3.org/TR/REC-html40'
|
||||
xmlns:sitemap='http://www.sitemaps.org/schemas/sitemap/0.9'
|
||||
xmlns:image='http://www.google.com/schemas/sitemap-image/1.1'
|
||||
xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
|
||||
<xsl:output method='html' version='1.0' encoding='UTF-8' indent='yes'/>
|
||||
<xsl:template match="/">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>$title</title>
|
||||
<meta http-equiv='Content-Type' content='text/html; charset=utf-8'/>
|
||||
<style type='text/css'>
|
||||
$css
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id='description'>
|
||||
<h1>$title</h1>
|
||||
<p>$description</p>
|
||||
<p>$more_info</p>
|
||||
</div>
|
||||
<div id='content'>
|
||||
<!-- <xsl:value-of select="count(sitemap:urlset/sitemap:url)"/> -->
|
||||
<table>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>$header_url</th>
|
||||
<th>$header_image_url</th>
|
||||
<th>$header_title</th>
|
||||
<th>$header_caption</th>
|
||||
<th>$header_lastmod</th>
|
||||
<th>$header_thumbnail</th>
|
||||
</tr>
|
||||
<xsl:for-each select="sitemap:urlset/sitemap:url">
|
||||
<tr>
|
||||
<xsl:choose>
|
||||
<xsl:when test='position() mod 2 != 1'>
|
||||
<xsl:attribute name="class">odd</xsl:attribute>
|
||||
</xsl:when>
|
||||
</xsl:choose>
|
||||
<td>
|
||||
<xsl:value-of select = "position()" />
|
||||
</td>
|
||||
<td>
|
||||
<xsl:variable name='pageURL'>
|
||||
<xsl:value-of select='sitemap:loc'/>
|
||||
</xsl:variable>
|
||||
<a href='{\$pageURL}'>
|
||||
<xsl:value-of select='sitemap:loc'/>
|
||||
</a>
|
||||
</td>
|
||||
<xsl:variable name='itemURL'>
|
||||
<xsl:value-of select='image:image/image:loc'/>
|
||||
</xsl:variable>
|
||||
<td>
|
||||
<a href='{\$itemURL}'>
|
||||
<xsl:value-of select='image:image/image:loc'/>
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
<xsl:value-of select='image:image/image:title'/>
|
||||
</td>
|
||||
<td>
|
||||
<xsl:value-of select='image:image/image:caption'/>
|
||||
</td>
|
||||
<td>
|
||||
<xsl:value-of select='sitemap:lastmod'/>
|
||||
</td>
|
||||
<td>
|
||||
<a href='{\$itemURL}'>
|
||||
<img class='thumbnail' src='{\$itemURL}'/>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</xsl:for-each>
|
||||
</table>
|
||||
</div>
|
||||
<div id='footer'>
|
||||
<p>$generated_by</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>\n
|
||||
XSL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the xsl of a video sitemap xml file as a string.
|
||||
*
|
||||
* @access public
|
||||
* @since 4.8.0
|
||||
*
|
||||
* @return string The contents of the xsl file.
|
||||
*/
|
||||
public static function video_sitemap_xsl() {
|
||||
$title = esc_html( ent2ncr( __( 'XML Video Sitemap', 'jetpack' ) ) );
|
||||
$header_url = esc_html( ent2ncr( __( 'Page URL', 'jetpack' ) ) );
|
||||
$header_image_url = esc_html( ent2ncr( __( 'Video URL', 'jetpack' ) ) );
|
||||
$header_thumbnail = esc_html( ent2ncr( __( 'Thumbnail', 'jetpack' ) ) );
|
||||
$header_title = esc_html( ent2ncr( __( 'Title', 'jetpack' ) ) );
|
||||
$header_lastmod = esc_html( ent2ncr( __( 'Last Modified', 'jetpack' ) ) );
|
||||
$header_description = esc_html( ent2ncr( __( 'Description', 'jetpack' ) ) );
|
||||
|
||||
$description = self::sanitize_with_links(
|
||||
__(
|
||||
'This is an XML Video Sitemap generated by <a href="%1$s" rel="noopener noreferrer" target="_blank">Jetpack</a>, meant to be consumed by search engines like <a href="%2$s" rel="noopener noreferrer" target="_blank">Google</a> or <a href="%3$s" rel="noopener noreferrer" target="_blank">Bing</a>.',
|
||||
'jetpack'
|
||||
),
|
||||
array(
|
||||
1 => 'http://jetpack.com/',
|
||||
2 => 'https://www.google.com/',
|
||||
3 => 'https://www.bing.com/',
|
||||
)
|
||||
);
|
||||
|
||||
$more_info = self::sanitize_with_links(
|
||||
__(
|
||||
'You can find more information on XML sitemaps at <a href="%1$s" rel="noopener noreferrer" target="_blank">sitemaps.org</a>',
|
||||
'jetpack'
|
||||
),
|
||||
array(
|
||||
1 => 'http://sitemaps.org',
|
||||
)
|
||||
);
|
||||
|
||||
$generated_by = self::sanitize_with_links(
|
||||
__(
|
||||
'Generated by <a href="%s" rel="noopener noreferrer" target="_blank">Jetpack for WordPress</a>',
|
||||
'jetpack'
|
||||
),
|
||||
array(
|
||||
1 => 'https://jetpack.com',
|
||||
)
|
||||
);
|
||||
|
||||
$css = self::sitemap_xsl_css();
|
||||
|
||||
return <<<XSL
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<xsl:stylesheet version='2.0'
|
||||
xmlns:html='http://www.w3.org/TR/REC-html40'
|
||||
xmlns:sitemap='http://www.sitemaps.org/schemas/sitemap/0.9'
|
||||
xmlns:video='http://www.google.com/schemas/sitemap-video/1.1'
|
||||
xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
|
||||
<xsl:output method='html' version='1.0' encoding='UTF-8' indent='yes'/>
|
||||
<xsl:template match="/">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>$title</title>
|
||||
<meta http-equiv='Content-Type' content='text/html; charset=utf-8'/>
|
||||
<style type='text/css'>
|
||||
$css
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id='description'>
|
||||
<h1>$title</h1>
|
||||
<p>$description</p>
|
||||
<p>$more_info</p>
|
||||
</div>
|
||||
<div id='content'>
|
||||
<!-- <xsl:value-of select="count(sitemap:urlset/sitemap:url)"/> -->
|
||||
<table>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>$header_url</th>
|
||||
<th>$header_image_url</th>
|
||||
<th>$header_title</th>
|
||||
<th>$header_description</th>
|
||||
<th>$header_lastmod</th>
|
||||
<th>$header_thumbnail</th>
|
||||
</tr>
|
||||
<xsl:for-each select="sitemap:urlset/sitemap:url">
|
||||
<tr>
|
||||
<xsl:choose>
|
||||
<xsl:when test='position() mod 2 != 1'>
|
||||
<xsl:attribute name="class">odd</xsl:attribute>
|
||||
</xsl:when>
|
||||
</xsl:choose>
|
||||
<td>
|
||||
<xsl:value-of select = "position()" />
|
||||
</td>
|
||||
<td>
|
||||
<xsl:variable name='pageURL'>
|
||||
<xsl:value-of select='sitemap:loc'/>
|
||||
</xsl:variable>
|
||||
<a href='{\$pageURL}'>
|
||||
<xsl:value-of select='sitemap:loc'/>
|
||||
</a>
|
||||
</td>
|
||||
<xsl:variable name='itemURL'>
|
||||
<xsl:value-of select='video:video/video:content_loc'/>
|
||||
</xsl:variable>
|
||||
<td>
|
||||
<a href='{\$itemURL}'>
|
||||
<xsl:value-of select='video:video/video:content_loc'/>
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
<xsl:value-of select='video:video/video:title'/>
|
||||
</td>
|
||||
<td>
|
||||
<xsl:value-of select='video:video/video:description'/>
|
||||
</td>
|
||||
<td>
|
||||
<xsl:value-of select='sitemap:lastmod'/>
|
||||
</td>
|
||||
<td>
|
||||
<xsl:variable name='thumbURL'>
|
||||
<xsl:value-of select='video:video/video:thumbnail_loc'/>
|
||||
</xsl:variable>
|
||||
<a href='{\$thumbURL}'>
|
||||
<img class='thumbnail' src='{\$thumbURL}'/>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</xsl:for-each>
|
||||
</table>
|
||||
</div>
|
||||
<div id='footer'>
|
||||
<p>$generated_by</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>\n
|
||||
XSL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the xsl of a news sitemap xml file as a string.
|
||||
*
|
||||
* @access public
|
||||
* @since 4.8.0
|
||||
*
|
||||
* @return string The contents of the xsl file.
|
||||
*/
|
||||
public static function news_sitemap_xsl() {
|
||||
$title = esc_html( ent2ncr( __( 'XML News Sitemap', 'jetpack' ) ) );
|
||||
$header_url = esc_html( ent2ncr( __( 'Page URL', 'jetpack' ) ) );
|
||||
$header_title = esc_html( ent2ncr( __( 'Title', 'jetpack' ) ) );
|
||||
$header_pubdate = esc_html( ent2ncr( __( 'Publication Date', 'jetpack' ) ) );
|
||||
|
||||
$description = self::sanitize_with_links(
|
||||
__(
|
||||
'This is an XML News Sitemap generated by <a href="%1$s" rel="noopener noreferrer" target="_blank">Jetpack</a>, meant to be consumed by search engines like <a href="%2$s" rel="noopener noreferrer" target="_blank">Google</a> or <a href="%3$s" rel="noopener noreferrer" target="_blank">Bing</a>.',
|
||||
'jetpack'
|
||||
),
|
||||
array(
|
||||
1 => 'http://jetpack.com/',
|
||||
2 => 'https://www.google.com/',
|
||||
3 => 'https://www.bing.com/',
|
||||
)
|
||||
);
|
||||
|
||||
$more_info = self::sanitize_with_links(
|
||||
__(
|
||||
'You can find more information on XML sitemaps at <a href="%1$s" rel="noopener noreferrer" target="_blank">sitemaps.org</a>',
|
||||
'jetpack'
|
||||
),
|
||||
array(
|
||||
1 => 'http://sitemaps.org',
|
||||
)
|
||||
);
|
||||
|
||||
$generated_by = self::sanitize_with_links(
|
||||
__(
|
||||
'Generated by <a href="%s" rel="noopener noreferrer" target="_blank">Jetpack for WordPress</a>',
|
||||
'jetpack'
|
||||
),
|
||||
array(
|
||||
1 => 'https://jetpack.com',
|
||||
)
|
||||
);
|
||||
|
||||
$css = self::sitemap_xsl_css();
|
||||
|
||||
return <<<XSL
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<xsl:stylesheet version='2.0'
|
||||
xmlns:html='http://www.w3.org/TR/REC-html40'
|
||||
xmlns:sitemap='http://www.sitemaps.org/schemas/sitemap/0.9'
|
||||
xmlns:news='http://www.google.com/schemas/sitemap-news/0.9'
|
||||
xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
|
||||
<xsl:output method='html' version='1.0' encoding='UTF-8' indent='yes'/>
|
||||
<xsl:template match="/">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>$title</title>
|
||||
<meta http-equiv='Content-Type' content='text/html; charset=utf-8'/>
|
||||
<style type='text/css'>
|
||||
$css
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id='description'>
|
||||
<h1>$title</h1>
|
||||
<p>$description</p>
|
||||
<p>$more_info</p>
|
||||
</div>
|
||||
<div id='content'>
|
||||
<!-- <xsl:value-of select="count(sitemap:urlset/sitemap:url)"/> -->
|
||||
<table>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>$header_url</th>
|
||||
<th>$header_title</th>
|
||||
<th>$header_pubdate</th>
|
||||
</tr>
|
||||
<xsl:for-each select="sitemap:urlset/sitemap:url">
|
||||
<tr>
|
||||
<xsl:choose>
|
||||
<xsl:when test='position() mod 2 != 1'>
|
||||
<xsl:attribute name="class">odd</xsl:attribute>
|
||||
</xsl:when>
|
||||
</xsl:choose>
|
||||
<td>
|
||||
<xsl:value-of select = "position()" />
|
||||
</td>
|
||||
<xsl:variable name='pageURL'>
|
||||
<xsl:value-of select='sitemap:loc'/>
|
||||
</xsl:variable>
|
||||
<td>
|
||||
<a href='{\$pageURL}'>
|
||||
<xsl:value-of select='sitemap:loc'/>
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
<a href='{\$pageURL}'>
|
||||
<xsl:value-of select='news:news/news:title'/>
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
<xsl:value-of select='news:news/news:publication_date'/>
|
||||
</td>
|
||||
</tr>
|
||||
</xsl:for-each>
|
||||
</table>
|
||||
</div>
|
||||
<div id='footer'>
|
||||
<p>$generated_by</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>\n
|
||||
XSL;
|
||||
}
|
||||
|
||||
/**
|
||||
* The CSS to be included in sitemap xsl stylesheets;
|
||||
* factored out for uniformity.
|
||||
*
|
||||
* @access public
|
||||
* @since 4.8.0
|
||||
*
|
||||
* @return string The CSS.
|
||||
*/
|
||||
public static function sitemap_xsl_css() {
|
||||
return <<<CSS
|
||||
body {
|
||||
font: 14px 'Open Sans', Helvetica, Arial, sans-serif;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #3498db;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#description {
|
||||
background-color: #81a844;
|
||||
color: #FFF;
|
||||
padding: 30px 30px 20px;
|
||||
}
|
||||
|
||||
#description a {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
#content {
|
||||
padding: 10px 30px 30px;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
border-bottom: 1px solid;
|
||||
}
|
||||
|
||||
th, td {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
th {
|
||||
text-align: left;
|
||||
border-bottom: 1px solid #ccc;
|
||||
}
|
||||
|
||||
th, td {
|
||||
padding: 10px 15px;
|
||||
}
|
||||
|
||||
.odd {
|
||||
background-color: #E7F1D4;
|
||||
}
|
||||
|
||||
#footer {
|
||||
margin: 20px 30px;
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
#footer a {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
#description a, #footer a {
|
||||
border-bottom: 1px solid;
|
||||
}
|
||||
|
||||
#description a:hover, #footer a:hover {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
img.thumbnail {
|
||||
max-height: 100px;
|
||||
max-width: 100px;
|
||||
}
|
||||
CSS;
|
||||
}
|
||||
|
||||
}
|
||||
600
wp-content/plugins/jetpack/modules/sitemaps/sitemaps.php
Normal file
600
wp-content/plugins/jetpack/modules/sitemaps/sitemaps.php
Normal file
@@ -0,0 +1,600 @@
|
||||
<?php // phpcs:ignore WordPress.Files.FileName.InvalidClassFileName
|
||||
/**
|
||||
* Generate sitemap files in base XML as well as some namespace extensions.
|
||||
*
|
||||
* This module generates two different base sitemaps.
|
||||
*
|
||||
* 1. sitemap.xml
|
||||
* The basic sitemap is updated regularly by wp-cron. It is stored in the
|
||||
* database and retrieved when requested. This sitemap aims to include canonical
|
||||
* URLs for all published content and abide by the sitemap spec. This is the root
|
||||
* of a tree of sitemap and sitemap index xml files, depending on the number of URLs.
|
||||
*
|
||||
* By default the sitemap contains published posts of type 'post' and 'page', as
|
||||
* well as the home url. To include other post types use the 'jetpack_sitemap_post_types'
|
||||
* filter.
|
||||
*
|
||||
* @link http://sitemaps.org/protocol.php Base sitemaps protocol.
|
||||
* @link https://support.google.com/webmasters/answer/178636 Image sitemap extension.
|
||||
* @link https://developers.google.com/webmasters/videosearch/sitemaps Video sitemap extension.
|
||||
*
|
||||
* 2. news-sitemap.xml
|
||||
* The news sitemap is generated on the fly when requested. It does not aim for
|
||||
* completeness, instead including at most 1000 of the most recent published posts
|
||||
* from the previous 2 days, per the news-sitemap spec.
|
||||
*
|
||||
* @link http://www.google.com/support/webmasters/bin/answer.py?answer=74288 News sitemap extension.
|
||||
*
|
||||
* @package Jetpack
|
||||
* @since 3.9.0
|
||||
* @since 4.8.0 Remove 1000 post limit.
|
||||
* @author Automattic
|
||||
*/
|
||||
|
||||
/* Include all of the sitemap subclasses. */
|
||||
require_once dirname( __FILE__ ) . '/sitemap-constants.php';
|
||||
require_once dirname( __FILE__ ) . '/sitemap-buffer.php';
|
||||
require_once dirname( __FILE__ ) . '/sitemap-stylist.php';
|
||||
require_once dirname( __FILE__ ) . '/sitemap-librarian.php';
|
||||
require_once dirname( __FILE__ ) . '/sitemap-finder.php';
|
||||
require_once dirname( __FILE__ ) . '/sitemap-builder.php';
|
||||
|
||||
if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
|
||||
require_once dirname( __FILE__ ) . '/sitemap-logger.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* Governs the generation, storage, and serving of sitemaps.
|
||||
*
|
||||
* @since 4.8.0
|
||||
*/
|
||||
class Jetpack_Sitemap_Manager {
|
||||
|
||||
/**
|
||||
* Librarian object for storing and retrieving sitemap data.
|
||||
*
|
||||
* @see Jetpack_Sitemap_Librarian
|
||||
* @since 4.8.0
|
||||
* @var Jetpack_Sitemap_Librarian $librarian Librarian object for storing and retrieving sitemap data.
|
||||
*/
|
||||
private $librarian;
|
||||
|
||||
/**
|
||||
* Logger object for reporting debug messages.
|
||||
*
|
||||
* @see Jetpack_Sitemap_Logger
|
||||
* @since 4.8.0
|
||||
* @var Jetpack_Sitemap_Logger $logger Logger object for reporting debug messages.
|
||||
*/
|
||||
private $logger;
|
||||
|
||||
/**
|
||||
* Finder object for handling sitemap URIs.
|
||||
*
|
||||
* @see Jetpack_Sitemap_Finder
|
||||
* @since 4.8.0
|
||||
* @var Jetpack_Sitemap_Finder $finder Finder object for handling with sitemap URIs.
|
||||
*/
|
||||
private $finder;
|
||||
|
||||
/**
|
||||
* Construct a new Jetpack_Sitemap_Manager.
|
||||
*
|
||||
* @access public
|
||||
* @since 4.8.0
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->librarian = new Jetpack_Sitemap_Librarian();
|
||||
$this->finder = new Jetpack_Sitemap_Finder();
|
||||
|
||||
if ( defined( 'WP_DEBUG' ) && ( true === WP_DEBUG ) ) {
|
||||
$this->logger = new Jetpack_Sitemap_Logger();
|
||||
}
|
||||
|
||||
// Add callback for sitemap URL handler.
|
||||
add_action(
|
||||
'init',
|
||||
array( $this, 'callback_action_catch_sitemap_urls' ),
|
||||
defined( 'IS_WPCOM' ) && IS_WPCOM ? 100 : 10
|
||||
);
|
||||
|
||||
// Add generator to wp_cron task list.
|
||||
$this->schedule_sitemap_generation();
|
||||
|
||||
// Add sitemap to robots.txt.
|
||||
add_action(
|
||||
'do_robotstxt',
|
||||
array( $this, 'callback_action_do_robotstxt' ),
|
||||
20
|
||||
);
|
||||
|
||||
// The news sitemap is cached; here we add a callback to
|
||||
// flush the cached news sitemap when a post is published.
|
||||
add_action(
|
||||
'publish_post',
|
||||
array( $this, 'callback_action_flush_news_sitemap_cache' ),
|
||||
10
|
||||
);
|
||||
|
||||
// In case we need to purge all sitemaps, we do this.
|
||||
add_action(
|
||||
'jetpack_sitemaps_purge_data',
|
||||
array( $this, 'callback_action_purge_data' )
|
||||
);
|
||||
|
||||
/*
|
||||
* Module parameters are stored as options in the database.
|
||||
* This allows us to avoid having to process all of init
|
||||
* before serving the sitemap data. The following actions
|
||||
* process and store these filters.
|
||||
*/
|
||||
|
||||
// Process filters and store location string for sitemap.
|
||||
add_action(
|
||||
'init',
|
||||
array( $this, 'callback_action_filter_sitemap_location' ),
|
||||
999
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Echo a raw string of given content-type.
|
||||
*
|
||||
* @access private
|
||||
* @since 4.8.0
|
||||
*
|
||||
* @param string $the_content_type The content type to be served.
|
||||
* @param string $the_content The string to be echoed.
|
||||
*/
|
||||
private function serve_raw_and_die( $the_content_type, $the_content ) {
|
||||
header( 'Content-Type: ' . $the_content_type . '; charset=UTF-8' );
|
||||
|
||||
global $wp_query;
|
||||
$wp_query->is_feed = true;
|
||||
set_query_var( 'feed', 'sitemap' );
|
||||
|
||||
if ( '' === $the_content ) {
|
||||
$error = __( 'No sitemap found. Please try again later.', 'jetpack' );
|
||||
if ( current_user_can( 'manage_options' ) ) {
|
||||
$next = human_time_diff( wp_next_scheduled( 'jp_sitemap_cron_hook' ) );
|
||||
/* translators: %s is a human_time_diff until next sitemap generation. */
|
||||
$error = sprintf( __( 'No sitemap found. The system will try to build it again in %s.', 'jetpack' ), $next );
|
||||
}
|
||||
|
||||
wp_die(
|
||||
esc_html( $error ),
|
||||
esc_html__( 'Sitemaps', 'jetpack' ),
|
||||
array(
|
||||
'response' => 404,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
echo $the_content; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- All content created by Jetpack.
|
||||
|
||||
die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback to intercept sitemap url requests and serve sitemap files.
|
||||
*
|
||||
* @access public
|
||||
* @since 4.8.0
|
||||
*/
|
||||
public function callback_action_catch_sitemap_urls() {
|
||||
// Regular expressions for sitemap URL routing.
|
||||
$regex = array(
|
||||
'master' => '/^sitemap\.xml$/',
|
||||
'sitemap' => '/^sitemap-[1-9][0-9]*\.xml$/',
|
||||
'index' => '/^sitemap-index-[1-9][0-9]*\.xml$/',
|
||||
'sitemap-style' => '/^sitemap\.xsl$/',
|
||||
'index-style' => '/^sitemap-index\.xsl$/',
|
||||
'image' => '/^image-sitemap-[1-9][0-9]*\.xml$/',
|
||||
'image-index' => '/^image-sitemap-index-[1-9][0-9]*\.xml$/',
|
||||
'image-style' => '/^image-sitemap\.xsl$/',
|
||||
'video' => '/^video-sitemap-[1-9][0-9]*\.xml$/',
|
||||
'video-index' => '/^video-sitemap-index-[1-9][0-9]*\.xml$/',
|
||||
'video-style' => '/^video-sitemap\.xsl$/',
|
||||
'news' => '/^news-sitemap\.xml$/',
|
||||
'news-style' => '/^news-sitemap\.xsl$/',
|
||||
);
|
||||
|
||||
// The raw path(+query) of the requested URI.
|
||||
if ( isset( $_SERVER['REQUEST_URI'] ) ) { // WPCS: Input var okay.
|
||||
$raw_uri = sanitize_text_field(
|
||||
wp_unslash( $_SERVER['REQUEST_URI'] ) // WPCS: Input var okay.
|
||||
);
|
||||
} else {
|
||||
$raw_uri = '';
|
||||
}
|
||||
|
||||
$request = $this->finder->recognize_sitemap_uri( $raw_uri );
|
||||
|
||||
if ( isset( $request['sitemap_name'] ) ) {
|
||||
|
||||
/**
|
||||
* Filter the content type used to serve the sitemap XML files.
|
||||
*
|
||||
* @module sitemaps
|
||||
*
|
||||
* @since 3.9.0
|
||||
*
|
||||
* @param string $xml_content_type By default, it's 'text/xml'.
|
||||
*/
|
||||
$xml_content_type = apply_filters( 'jetpack_sitemap_content_type', 'text/xml' );
|
||||
|
||||
// Catch master sitemap xml.
|
||||
if ( preg_match( $regex['master'], $request['sitemap_name'] ) ) {
|
||||
$sitemap_content = $this->librarian->get_sitemap_text(
|
||||
jp_sitemap_filename( JP_MASTER_SITEMAP_TYPE, 0 ),
|
||||
JP_MASTER_SITEMAP_TYPE
|
||||
);
|
||||
|
||||
// if there is no master sitemap yet, let's just return an empty sitemap with a short TTL instead of a 404.
|
||||
if ( empty( $sitemap_content ) ) {
|
||||
$builder = new Jetpack_Sitemap_Builder();
|
||||
$sitemap_content = $builder->empty_sitemap_xml();
|
||||
}
|
||||
|
||||
$this->serve_raw_and_die(
|
||||
$xml_content_type,
|
||||
$sitemap_content
|
||||
);
|
||||
}
|
||||
|
||||
// Catch sitemap xml.
|
||||
if ( preg_match( $regex['sitemap'], $request['sitemap_name'] ) ) {
|
||||
$this->serve_raw_and_die(
|
||||
$xml_content_type,
|
||||
$this->librarian->get_sitemap_text(
|
||||
$request['sitemap_name'],
|
||||
JP_PAGE_SITEMAP_TYPE
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Catch sitemap index xml.
|
||||
if ( preg_match( $regex['index'], $request['sitemap_name'] ) ) {
|
||||
$this->serve_raw_and_die(
|
||||
$xml_content_type,
|
||||
$this->librarian->get_sitemap_text(
|
||||
$request['sitemap_name'],
|
||||
JP_PAGE_SITEMAP_INDEX_TYPE
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Catch sitemap xsl.
|
||||
if ( preg_match( $regex['sitemap-style'], $request['sitemap_name'] ) ) {
|
||||
$this->serve_raw_and_die(
|
||||
'application/xml',
|
||||
Jetpack_Sitemap_Stylist::sitemap_xsl()
|
||||
);
|
||||
}
|
||||
|
||||
// Catch sitemap index xsl.
|
||||
if ( preg_match( $regex['index-style'], $request['sitemap_name'] ) ) {
|
||||
$this->serve_raw_and_die(
|
||||
'application/xml',
|
||||
Jetpack_Sitemap_Stylist::sitemap_index_xsl()
|
||||
);
|
||||
}
|
||||
|
||||
// Catch image sitemap xml.
|
||||
if ( preg_match( $regex['image'], $request['sitemap_name'] ) ) {
|
||||
$this->serve_raw_and_die(
|
||||
$xml_content_type,
|
||||
$this->librarian->get_sitemap_text(
|
||||
$request['sitemap_name'],
|
||||
JP_IMAGE_SITEMAP_TYPE
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Catch image sitemap index xml.
|
||||
if ( preg_match( $regex['image-index'], $request['sitemap_name'] ) ) {
|
||||
$this->serve_raw_and_die(
|
||||
$xml_content_type,
|
||||
$this->librarian->get_sitemap_text(
|
||||
$request['sitemap_name'],
|
||||
JP_IMAGE_SITEMAP_INDEX_TYPE
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Catch image sitemap xsl.
|
||||
if ( preg_match( $regex['image-style'], $request['sitemap_name'] ) ) {
|
||||
$this->serve_raw_and_die(
|
||||
'application/xml',
|
||||
Jetpack_Sitemap_Stylist::image_sitemap_xsl()
|
||||
);
|
||||
}
|
||||
|
||||
// Catch video sitemap xml.
|
||||
if ( preg_match( $regex['video'], $request['sitemap_name'] ) ) {
|
||||
$this->serve_raw_and_die(
|
||||
$xml_content_type,
|
||||
$this->librarian->get_sitemap_text(
|
||||
$request['sitemap_name'],
|
||||
JP_VIDEO_SITEMAP_TYPE
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Catch video sitemap index xml.
|
||||
if ( preg_match( $regex['video-index'], $request['sitemap_name'] ) ) {
|
||||
$this->serve_raw_and_die(
|
||||
$xml_content_type,
|
||||
$this->librarian->get_sitemap_text(
|
||||
$request['sitemap_name'],
|
||||
JP_VIDEO_SITEMAP_INDEX_TYPE
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Catch video sitemap xsl.
|
||||
if ( preg_match( $regex['video-style'], $request['sitemap_name'] ) ) {
|
||||
$this->serve_raw_and_die(
|
||||
'application/xml',
|
||||
Jetpack_Sitemap_Stylist::video_sitemap_xsl()
|
||||
);
|
||||
}
|
||||
|
||||
// Catch news sitemap xml.
|
||||
if ( preg_match( $regex['news'], $request['sitemap_name'] ) ) {
|
||||
$sitemap_builder = new Jetpack_Sitemap_Builder();
|
||||
$this->serve_raw_and_die(
|
||||
$xml_content_type,
|
||||
$sitemap_builder->news_sitemap_xml()
|
||||
);
|
||||
}
|
||||
|
||||
// Catch news sitemap xsl.
|
||||
if ( preg_match( $regex['news-style'], $request['sitemap_name'] ) ) {
|
||||
$this->serve_raw_and_die(
|
||||
'application/xml',
|
||||
Jetpack_Sitemap_Stylist::news_sitemap_xsl()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for adding sitemap-interval to the list of schedules.
|
||||
*
|
||||
* @access public
|
||||
* @since 4.8.0
|
||||
*
|
||||
* @param array $schedules The array of WP_Cron schedules.
|
||||
*
|
||||
* @return array The updated array of WP_Cron schedules.
|
||||
*/
|
||||
public function callback_add_sitemap_schedule( $schedules ) {
|
||||
$schedules['sitemap-interval'] = array(
|
||||
'interval' => JP_SITEMAP_INTERVAL,
|
||||
'display' => __( 'Sitemap Interval', 'jetpack' ),
|
||||
);
|
||||
return $schedules;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback handler for sitemap cron hook
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function callback_sitemap_cron_hook() {
|
||||
$sitemap_builder = new Jetpack_Sitemap_Builder();
|
||||
$sitemap_builder->update_sitemap();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add actions to schedule sitemap generation.
|
||||
* Should only be called once, in the constructor.
|
||||
*
|
||||
* @access private
|
||||
* @since 4.8.0
|
||||
*/
|
||||
private function schedule_sitemap_generation() {
|
||||
// Add cron schedule.
|
||||
add_filter( 'cron_schedules', array( $this, 'callback_add_sitemap_schedule' ) ); // phpcs:ignore WordPress.WP.CronInterval.ChangeDetected
|
||||
|
||||
add_action(
|
||||
'jp_sitemap_cron_hook',
|
||||
array( $this, 'callback_sitemap_cron_hook' )
|
||||
);
|
||||
|
||||
if ( ! wp_next_scheduled( 'jp_sitemap_cron_hook' ) ) {
|
||||
/**
|
||||
* Filter the delay in seconds until sitemap generation cron job is started.
|
||||
*
|
||||
* This filter allows a site operator or hosting provider to potentialy spread out sitemap generation for a
|
||||
* lot of sites over time. By default, it will be randomly done over 15 minutes.
|
||||
*
|
||||
* @module sitemaps
|
||||
* @since 6.6.1
|
||||
*
|
||||
* @param int $delay Time to delay in seconds.
|
||||
*/
|
||||
$delay = apply_filters( 'jetpack_sitemap_generation_delay', MINUTE_IN_SECONDS * wp_rand( 1, 15 ) ); // Randomly space it out to start within next fifteen minutes.
|
||||
wp_schedule_event(
|
||||
time() + $delay,
|
||||
'sitemap-interval',
|
||||
'jp_sitemap_cron_hook'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback to add sitemap to robots.txt.
|
||||
*
|
||||
* @access public
|
||||
* @since 4.8.0
|
||||
*/
|
||||
public function callback_action_do_robotstxt() {
|
||||
|
||||
/**
|
||||
* Filter whether to make the default sitemap discoverable to robots or not. Default true.
|
||||
*
|
||||
* @module sitemaps
|
||||
* @since 3.9.0
|
||||
* @deprecated 7.4.0
|
||||
*
|
||||
* @param bool $discover_sitemap Make default sitemap discoverable to robots.
|
||||
*/
|
||||
$discover_sitemap = apply_filters_deprecated( 'jetpack_sitemap_generate', array( true ), 'jetpack-7.4.0', 'jetpack_sitemap_include_in_robotstxt' );
|
||||
|
||||
/**
|
||||
* Filter whether to make the default sitemap discoverable to robots or not. Default true.
|
||||
*
|
||||
* @module sitemaps
|
||||
* @since 7.4.0
|
||||
*
|
||||
* @param bool $discover_sitemap Make default sitemap discoverable to robots.
|
||||
*/
|
||||
$discover_sitemap = apply_filters( 'jetpack_sitemap_include_in_robotstxt', $discover_sitemap );
|
||||
|
||||
if ( true === $discover_sitemap ) {
|
||||
$sitemap_url = $this->finder->construct_sitemap_url( 'sitemap.xml' );
|
||||
echo 'Sitemap: ' . esc_url( $sitemap_url ) . "\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter whether to make the news sitemap discoverable to robots or not. Default true.
|
||||
*
|
||||
* @module sitemaps
|
||||
* @since 3.9.0
|
||||
* @deprecated 7.4.0
|
||||
*
|
||||
* @param bool $discover_news_sitemap Make default news sitemap discoverable to robots.
|
||||
*/
|
||||
$discover_news_sitemap = apply_filters_deprecated( 'jetpack_news_sitemap_generate', array( true ), 'jetpack-7.4.0', 'jetpack_news_sitemap_include_in_robotstxt' );
|
||||
|
||||
/**
|
||||
* Filter whether to make the news sitemap discoverable to robots or not. Default true.
|
||||
*
|
||||
* @module sitemaps
|
||||
* @since 7.4.0
|
||||
*
|
||||
* @param bool $discover_news_sitemap Make default news sitemap discoverable to robots.
|
||||
*/
|
||||
$discover_news_sitemap = apply_filters( 'jetpack_news_sitemap_include_in_robotstxt', $discover_news_sitemap );
|
||||
|
||||
if ( true === $discover_news_sitemap ) {
|
||||
$news_sitemap_url = $this->finder->construct_sitemap_url( 'news-sitemap.xml' );
|
||||
echo 'Sitemap: ' . esc_url( $news_sitemap_url ) . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback to delete the news sitemap cache.
|
||||
*
|
||||
* @access public
|
||||
* @since 4.8.0
|
||||
*/
|
||||
public function callback_action_flush_news_sitemap_cache() {
|
||||
delete_transient( 'jetpack_news_sitemap_xml' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for resetting stored sitemap data.
|
||||
*
|
||||
* @access public
|
||||
* @since 5.3.0
|
||||
* @since 6.7.0 Schedules a regeneration.
|
||||
*/
|
||||
public function callback_action_purge_data() {
|
||||
$this->callback_action_flush_news_sitemap_cache();
|
||||
$this->librarian->delete_all_stored_sitemap_data();
|
||||
/** This filter is documented in modules/sitemaps/sitemaps.php */
|
||||
$delay = apply_filters( 'jetpack_sitemap_generation_delay', MINUTE_IN_SECONDS * wp_rand( 1, 15 ) ); // Randomly space it out to start within next fifteen minutes.
|
||||
wp_schedule_single_event( time() + $delay, 'jp_sitemap_cron_hook' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback to set the sitemap location.
|
||||
*
|
||||
* @access public
|
||||
* @since 4.8.0
|
||||
*/
|
||||
public function callback_action_filter_sitemap_location() {
|
||||
update_option(
|
||||
'jetpack_sitemap_location',
|
||||
/**
|
||||
* Additional path for sitemap URIs. Default value is empty.
|
||||
*
|
||||
* This string is any additional path fragment you want included between
|
||||
* the home URL and the sitemap filenames. Exactly how this fragment is
|
||||
* interpreted depends on your permalink settings. For example:
|
||||
*
|
||||
* Pretty permalinks:
|
||||
* home_url() . jetpack_sitemap_location . '/sitemap.xml'
|
||||
*
|
||||
* Plain ("ugly") permalinks:
|
||||
* home_url() . jetpack_sitemap_location . '/?jetpack-sitemap=sitemap.xml'
|
||||
*
|
||||
* PATHINFO permalinks:
|
||||
* home_url() . '/index.php' . jetpack_sitemap_location . '/sitemap.xml'
|
||||
*
|
||||
* where 'sitemap.xml' is the name of a specific sitemap file.
|
||||
* The value of this filter must be a valid path fragment per RFC 3986;
|
||||
* in particular it must either be empty or begin with a '/'.
|
||||
* Also take care that any restrictions on sitemap location imposed by
|
||||
* the sitemap protocol are satisfied.
|
||||
*
|
||||
* The result of this filter is stored in an option, 'jetpack_sitemap_location';
|
||||
* that option is what gets read when the sitemap location is needed.
|
||||
* This way we don't have to wait for init to finish before building sitemaps.
|
||||
*
|
||||
* @link https://tools.ietf.org/html/rfc3986#section-3.3 RFC 3986
|
||||
* @link http://www.sitemaps.org/ The sitemap protocol
|
||||
*
|
||||
* @since 4.8.0
|
||||
*/
|
||||
apply_filters(
|
||||
'jetpack_sitemap_location',
|
||||
''
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
} // End Jetpack_Sitemap_Manager class.
|
||||
|
||||
new Jetpack_Sitemap_Manager();
|
||||
|
||||
/**
|
||||
* Absolute URL of the current blog's sitemap.
|
||||
*
|
||||
* @module sitemaps
|
||||
*
|
||||
* @since 3.9.0
|
||||
* @since 4.8.1 Code uses method found in Jetpack_Sitemap_Finder::construct_sitemap_url in 4.8.0.
|
||||
* It has been moved here to avoid fatal errors with other plugins that were expecting to find this function.
|
||||
*
|
||||
* @param string $filename Sitemap file name. Defaults to 'sitemap.xml', the initial sitemaps page.
|
||||
*
|
||||
* @return string Sitemap URL.
|
||||
*/
|
||||
function jetpack_sitemap_uri( $filename = 'sitemap.xml' ) {
|
||||
global $wp_rewrite;
|
||||
|
||||
$location = Jetpack_Options::get_option_and_ensure_autoload( 'jetpack_sitemap_location', '' );
|
||||
|
||||
if ( $wp_rewrite->using_index_permalinks() ) {
|
||||
$sitemap_url = home_url( '/index.php' . $location . '/' . $filename );
|
||||
} elseif ( $wp_rewrite->using_permalinks() ) {
|
||||
$sitemap_url = home_url( $location . '/' . $filename );
|
||||
} else {
|
||||
$sitemap_url = home_url( $location . '/?jetpack-sitemap=' . $filename );
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter sitemap URL relative to home URL.
|
||||
*
|
||||
* @module sitemaps
|
||||
*
|
||||
* @since 3.9.0
|
||||
*
|
||||
* @param string $sitemap_url Sitemap URL.
|
||||
*/
|
||||
return apply_filters( 'jetpack_sitemap_location', $sitemap_url );
|
||||
}
|
||||
Reference in New Issue
Block a user