balmet.com

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

class-wp-sitemaps-renderer.php (6797B)


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