File size: 6,687 Bytes
51345ad |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 |
<?php
/**
* Sitemaps: WP_Sitemaps_Renderer class
*
* Responsible for rendering Sitemaps data to XML in accordance with sitemap protocol.
*
* @package WordPress
* @subpackage Sitemaps
* @since 5.5.0
*/
/**
* Class WP_Sitemaps_Renderer
*
* @since 5.5.0
*/
#[AllowDynamicProperties]
class WP_Sitemaps_Renderer {
/**
* XSL stylesheet for styling a sitemap for web browsers.
*
* @since 5.5.0
*
* @var string
*/
protected $stylesheet = '';
/**
* XSL stylesheet for styling a sitemap for web browsers.
*
* @since 5.5.0
*
* @var string
*/
protected $stylesheet_index = '';
/**
* WP_Sitemaps_Renderer constructor.
*
* @since 5.5.0
*/
public function __construct() {
$stylesheet_url = $this->get_sitemap_stylesheet_url();
if ( $stylesheet_url ) {
$this->stylesheet = '<?xml-stylesheet type="text/xsl" href="' . esc_url( $stylesheet_url ) . '" ?>';
}
$stylesheet_index_url = $this->get_sitemap_index_stylesheet_url();
if ( $stylesheet_index_url ) {
$this->stylesheet_index = '<?xml-stylesheet type="text/xsl" href="' . esc_url( $stylesheet_index_url ) . '" ?>';
}
}
/**
* Gets the URL for the sitemap stylesheet.
*
* @since 5.5.0
*
* @global WP_Rewrite $wp_rewrite WordPress rewrite component.
*
* @return string The sitemap stylesheet URL.
*/
public function get_sitemap_stylesheet_url() {
global $wp_rewrite;
$sitemap_url = home_url( '/wp-sitemap.xsl' );
if ( ! $wp_rewrite->using_permalinks() ) {
$sitemap_url = home_url( '/?sitemap-stylesheet=sitemap' );
}
/**
* Filters the URL for the sitemap stylesheet.
*
* If a falsey value is returned, no stylesheet will be used and
* the "raw" XML of the sitemap will be displayed.
*
* @since 5.5.0
*
* @param string $sitemap_url Full URL for the sitemaps XSL file.
*/
return apply_filters( 'wp_sitemaps_stylesheet_url', $sitemap_url );
}
/**
* Gets the URL for the sitemap index stylesheet.
*
* @since 5.5.0
*
* @global WP_Rewrite $wp_rewrite WordPress rewrite component.
*
* @return string The sitemap index stylesheet URL.
*/
public function get_sitemap_index_stylesheet_url() {
global $wp_rewrite;
$sitemap_url = home_url( '/wp-sitemap-index.xsl' );
if ( ! $wp_rewrite->using_permalinks() ) {
$sitemap_url = home_url( '/?sitemap-stylesheet=index' );
}
/**
* Filters the URL for the sitemap index stylesheet.
*
* If a falsey value is returned, no stylesheet will be used and
* the "raw" XML of the sitemap index will be displayed.
*
* @since 5.5.0
*
* @param string $sitemap_url Full URL for the sitemaps index XSL file.
*/
return apply_filters( 'wp_sitemaps_stylesheet_index_url', $sitemap_url );
}
/**
* Renders a sitemap index.
*
* @since 5.5.0
*
* @param array $sitemaps Array of sitemap URLs.
*/
public function render_index( $sitemaps ) {
header( 'Content-Type: application/xml; charset=UTF-8' );
$this->check_for_simple_xml_availability();
$index_xml = $this->get_sitemap_index_xml( $sitemaps );
if ( ! empty( $index_xml ) ) {
// All output is escaped within get_sitemap_index_xml().
echo $index_xml;
}
}
/**
* Gets XML for a sitemap index.
*
* @since 5.5.0
*
* @param array $sitemaps Array of sitemap URLs.
* @return string|false A well-formed XML string for a sitemap index. False on error.
*/
public function get_sitemap_index_xml( $sitemaps ) {
$sitemap_index = new SimpleXMLElement(
sprintf(
'%1$s%2$s%3$s',
'<?xml version="1.0" encoding="UTF-8" ?>',
$this->stylesheet_index,
'<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" />'
)
);
foreach ( $sitemaps as $entry ) {
$sitemap = $sitemap_index->addChild( 'sitemap' );
// Add each element as a child node to the <sitemap> entry.
foreach ( $entry as $name => $value ) {
if ( 'loc' === $name ) {
$sitemap->addChild( $name, esc_url( $value ) );
} elseif ( 'lastmod' === $name ) {
$sitemap->addChild( $name, esc_xml( $value ) );
} else {
_doing_it_wrong(
__METHOD__,
sprintf(
/* translators: %s: List of element names. */
__( 'Fields other than %s are not currently supported for the sitemap index.' ),
implode( ',', array( 'loc', 'lastmod' ) )
),
'5.5.0'
);
}
}
}
return $sitemap_index->asXML();
}
/**
* Renders a sitemap.
*
* @since 5.5.0
*
* @param array $url_list Array of URLs for a sitemap.
*/
public function render_sitemap( $url_list ) {
header( 'Content-Type: application/xml; charset=UTF-8' );
$this->check_for_simple_xml_availability();
$sitemap_xml = $this->get_sitemap_xml( $url_list );
if ( ! empty( $sitemap_xml ) ) {
// All output is escaped within get_sitemap_xml().
echo $sitemap_xml;
}
}
/**
* Gets XML for a sitemap.
*
* @since 5.5.0
*
* @param array $url_list Array of URLs for a sitemap.
* @return string|false A well-formed XML string for a sitemap index. False on error.
*/
public function get_sitemap_xml( $url_list ) {
$urlset = new SimpleXMLElement(
sprintf(
'%1$s%2$s%3$s',
'<?xml version="1.0" encoding="UTF-8" ?>',
$this->stylesheet,
'<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" />'
)
);
foreach ( $url_list as $url_item ) {
$url = $urlset->addChild( 'url' );
// Add each element as a child node to the <url> entry.
foreach ( $url_item as $name => $value ) {
if ( 'loc' === $name ) {
$url->addChild( $name, esc_url( $value ) );
} elseif ( in_array( $name, array( 'lastmod', 'changefreq', 'priority' ), true ) ) {
$url->addChild( $name, esc_xml( $value ) );
} else {
_doing_it_wrong(
__METHOD__,
sprintf(
/* translators: %s: List of element names. */
__( 'Fields other than %s are not currently supported for sitemaps.' ),
implode( ',', array( 'loc', 'lastmod', 'changefreq', 'priority' ) )
),
'5.5.0'
);
}
}
}
return $urlset->asXML();
}
/**
* Checks for the availability of the SimpleXML extension and errors if missing.
*
* @since 5.5.0
*/
private function check_for_simple_xml_availability() {
if ( ! class_exists( 'SimpleXMLElement' ) ) {
add_filter(
'wp_die_handler',
static function () {
return '_xml_wp_die_handler';
}
);
wp_die(
sprintf(
/* translators: %s: SimpleXML */
esc_xml( __( 'Could not generate XML sitemap due to missing %s extension' ) ),
'SimpleXML'
),
esc_xml( __( 'WordPress › Error' ) ),
array(
'response' => 501, // "Not implemented".
)
);
}
}
}
|