PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 16.3
Jetpack – WP Security, Backup, Speed, & Growth v16.3
16.3 16.3-beta 16.3-a.5 16.3-a.7 16.3-a.3 16.3-a.1 16.2 16.2-beta 12.0.3 12.1.3 12.2.3 12.3.2 12.4.2 12.5.2 12.6.4 12.7.3 12.8.3 12.9.5 13.0.2 13.1.5 13.2.4 13.3.3 13.4.5 13.5.2 13.6.2 All 508 releases
← All changes | modules/sitemaps/sitemaps.php +613 -0 16.2-beta → 16.3 View file →
@@ -1,0 +1,613 @@
1 +<?php // phpcs:ignore WordPress.Files.FileName.InvalidClassFileName
2 +/**
3 + * Generate sitemap files in base XML as well as some namespace extensions.
4 + *
5 + * This module generates two different base sitemaps.
6 + *
7 + * 1. sitemap.xml
8 + * The basic sitemap is updated regularly by wp-cron. It is stored in the
9 + * database and retrieved when requested. This sitemap aims to include canonical
10 + * URLs for all published content and abide by the sitemap spec. This is the root
11 + * of a tree of sitemap and sitemap index xml files, depending on the number of URLs.
12 + *
13 + * By default the sitemap contains published posts of type 'post' and 'page', as
14 + * well as the home url. To include other post types use the 'jetpack_sitemap_post_types'
15 + * filter.
16 + *
17 + * @link https://www.sitemaps.org/protocol.html Base sitemaps protocol.
18 + * @link https://support.google.com/webmasters/answer/178636 Image sitemap extension.
19 + * @link https://developers.google.com/webmasters/videosearch/sitemaps Video sitemap extension.
20 + *
21 + * 2. news-sitemap.xml
22 + * The news sitemap is generated on the fly when requested. It does not aim for
23 + * completeness, instead including at most 1000 of the most recent published posts
24 + * from the previous 2 days, per the news-sitemap spec.
25 + *
26 + * @link https://support.google.com/webmasters/answer/74288 News sitemap extension.
27 + *
28 + * @package automattic/jetpack
29 + * @since 3.9.0
30 + * @since 4.8.0 Remove 1000 post limit.
31 + * @author Automattic
32 + */
33 +
34 +if ( ! defined( 'ABSPATH' ) ) {
35 + exit( 0 );
36 +}
37 +
38 +/* Include all of the sitemap subclasses. */
39 +require_once __DIR__ . '/sitemap-constants.php';
40 +require_once __DIR__ . '/sitemap-buffer.php';
41 +require_once __DIR__ . '/sitemap-buffer-fallback.php';
42 +require_once __DIR__ . '/sitemap-buffer-xmlwriter.php';
43 +require_once __DIR__ . '/sitemap-buffer-page-xmlwriter.php';
44 +require_once __DIR__ . '/sitemap-buffer-image-xmlwriter.php';
45 +require_once __DIR__ . '/sitemap-buffer-video-xmlwriter.php';
46 +require_once __DIR__ . '/sitemap-buffer-news-xmlwriter.php';
47 +require_once __DIR__ . '/sitemap-buffer-master-xmlwriter.php';
48 +require_once __DIR__ . '/sitemap-buffer-factory.php';
49 +require_once __DIR__ . '/sitemap-stylist.php';
50 +require_once __DIR__ . '/sitemap-librarian.php';
51 +require_once __DIR__ . '/sitemap-finder.php';
52 +require_once __DIR__ . '/sitemap-builder.php';
53 +
54 +if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
55 + require_once __DIR__ . '/sitemap-logger.php';
56 +}
57 +
58 +// phpcs:disable Universal.Files.SeparateFunctionsFromOO.Mixed -- TODO: Move classes to appropriately-named class files.
59 +
60 +/**
61 + * Governs the generation, storage, and serving of sitemaps.
62 + *
63 + * @since 4.8.0
64 + *
65 + * @phan-constructor-used-for-side-effects
66 + */
67 +class Jetpack_Sitemap_Manager {
68 +
69 + /**
70 + * Librarian object for storing and retrieving sitemap data.
71 + *
72 + * @see Jetpack_Sitemap_Librarian
73 + * @since 4.8.0
74 + * @var Jetpack_Sitemap_Librarian $librarian Librarian object for storing and retrieving sitemap data.
75 + */
76 + private $librarian;
77 +
78 + /**
79 + * Logger object for reporting debug messages.
80 + *
81 + * @see Jetpack_Sitemap_Logger
82 + * @since 4.8.0
83 + * @var Jetpack_Sitemap_Logger $logger Logger object for reporting debug messages.
84 + */
85 + private $logger;
86 +
87 + /**
88 + * Finder object for handling sitemap URIs.
89 + *
90 + * @see Jetpack_Sitemap_Finder
91 + * @since 4.8.0
92 + * @var Jetpack_Sitemap_Finder $finder Finder object for handling with sitemap URIs.
93 + */
94 + private $finder;
95 +
96 + /**
97 + * Construct a new Jetpack_Sitemap_Manager.
98 + *
99 + * @access public
100 + * @since 4.8.0
101 + */
102 + public function __construct() {
103 + $this->librarian = new Jetpack_Sitemap_Librarian();
104 + $this->finder = new Jetpack_Sitemap_Finder();
105 +
106 + if ( defined( 'WP_DEBUG' ) && ( true === WP_DEBUG ) ) {
107 + $this->logger = new Jetpack_Sitemap_Logger();
108 + }
109 +
110 + // Add callback for sitemap URL handler.
111 + add_action(
112 + 'wp_loaded',
113 + array( $this, 'callback_action_catch_sitemap_urls' ),
114 + defined( 'IS_WPCOM' ) && IS_WPCOM ? 100 : 10
115 + );
116 +
117 + // Add generator to wp_cron task list.
118 + $this->schedule_sitemap_generation();
119 +
120 + // Add sitemap to robots.txt.
121 + add_action(
122 + 'do_robotstxt',
123 + array( $this, 'callback_action_do_robotstxt' ),
124 + 20
125 + );
126 +
127 + // The news sitemap is cached; here we add a callback to
128 + // flush the cached news sitemap when a post is published.
129 + add_action(
130 + 'publish_post',
131 + array( $this, 'callback_action_flush_news_sitemap_cache' ),
132 + 10
133 + );
134 +
135 + // In case we need to purge all sitemaps, we do this.
136 + add_action(
137 + 'jetpack_sitemaps_purge_data',
138 + array( $this, 'callback_action_purge_data' )
139 + );
140 +
141 + /*
142 + * Module parameters are stored as options in the database.
143 + * This allows us to avoid having to process all of init
144 + * before serving the sitemap data. The following actions
145 + * process and store these filters.
146 + */
147 +
148 + // Process filters and store location string for sitemap.
149 + add_action(
150 + 'init',
151 + array( $this, 'callback_action_filter_sitemap_location' ),
152 + 999
153 + );
154 + }
155 +
156 + /**
157 + * Echo a raw string of given content-type.
158 + *
159 + * @access private
160 + * @since 4.8.0
161 + *
162 + * @param string $the_content_type The content type to be served.
163 + * @param string $the_content The string to be echoed.
164 + * @return never
165 + */
166 + private function serve_raw_and_die( $the_content_type, $the_content ) {
167 + header( 'Content-Type: ' . $the_content_type . '; charset=UTF-8' );
168 +
169 + global $wp_query;
170 + $wp_query->is_feed = true;
171 + set_query_var( 'feed', 'sitemap' );
172 +
173 + if ( '' === $the_content ) {
174 + $error = __( 'No sitemap found. Please try again later.', 'jetpack' );
175 + if ( current_user_can( 'manage_options' ) ) {
176 + $next = human_time_diff( wp_next_scheduled( 'jp_sitemap_cron_hook' ) );
177 + /* translators: %s is a human_time_diff until next sitemap generation. */
178 + $error = sprintf( __( 'No sitemap found. The system will try to build it again in %s.', 'jetpack' ), $next );
179 + }
180 +
181 + wp_die(
182 + esc_html( $error ),
183 + esc_html__( 'Sitemaps', 'jetpack' ),
184 + array(
185 + 'response' => 404,
186 + )
187 + );
188 + }
189 +
190 + echo $the_content; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- All content created by Jetpack.
191 +
192 + die( 0 );
193 + }
194 +
195 + /**
196 + * Callback to intercept sitemap url requests and serve sitemap files.
197 + *
198 + * @access public
199 + * @since 4.8.0
200 + */
201 + public function callback_action_catch_sitemap_urls() {
202 + // Regular expressions for sitemap URL routing.
203 + $regex = array(
204 + 'sitemap' => '/^sitemap-[1-9][0-9]*\.xml$/',
205 + 'index' => '/^sitemap-index-[1-9][0-9]*\.xml$/',
206 + 'image' => '/^image-sitemap-[1-9][0-9]*\.xml$/',
207 + 'image-index' => '/^image-sitemap-index-[1-9][0-9]*\.xml$/',
208 + 'video' => '/^video-sitemap-[1-9][0-9]*\.xml$/',
209 + 'video-index' => '/^video-sitemap-index-[1-9][0-9]*\.xml$/',
210 + );
211 +
212 + // The raw path(+query) of the requested URI.
213 + if ( isset( $_SERVER['REQUEST_URI'] ) ) { // WPCS: Input var okay.
214 + $raw_uri = sanitize_text_field(
215 + wp_unslash( $_SERVER['REQUEST_URI'] ) // WPCS: Input var okay.
216 + );
217 + } else {
218 + $raw_uri = '';
219 + }
220 +
221 + $request = $this->finder->recognize_sitemap_uri( $raw_uri );
222 +
223 + if ( isset( $request['sitemap_name'] ) ) {
224 +
225 + /**
226 + * Filter the content type used to serve the sitemap XML files.
227 + *
228 + * @module sitemaps
229 + *
230 + * @since 3.9.0
231 + *
232 + * @param string $xml_content_type By default, it's 'text/xml'.
233 + */
234 + $xml_content_type = apply_filters( 'jetpack_sitemap_content_type', 'text/xml' );
235 +
236 + // Catch master sitemap xml.
237 + if ( 'sitemap.xml' === $request['sitemap_name'] ) {
238 + $sitemap_content = $this->librarian->get_sitemap_text(
239 + jp_sitemap_filename( JP_MASTER_SITEMAP_TYPE, 0 ),
240 + JP_MASTER_SITEMAP_TYPE
241 + );
242 +
243 + // if there is no master sitemap yet, let's just return an empty sitemap with a short TTL instead of a 404.
244 + if ( empty( $sitemap_content ) ) {
245 + $builder = new Jetpack_Sitemap_Builder();
246 + $sitemap_content = $builder->empty_sitemap_xml();
247 + }
248 +
249 + $this->serve_raw_and_die(
250 + $xml_content_type,
251 + $sitemap_content
252 + );
253 + }
254 +
255 + // Catch sitemap xsl.
256 + if ( 'sitemap.xsl' === $request['sitemap_name'] ) {
257 + $this->serve_raw_and_die(
258 + 'application/xml',
259 + Jetpack_Sitemap_Stylist::sitemap_xsl()
260 + );
261 + }
262 +
263 + // Catch sitemap index xsl.
264 + if ( 'sitemap-index.xsl' === $request['sitemap_name'] ) {
265 + $this->serve_raw_and_die(
266 + 'application/xml',
267 + Jetpack_Sitemap_Stylist::sitemap_index_xsl()
268 + );
269 + }
270 +
271 + // Catch image sitemap xsl.
272 + if ( 'image-sitemap.xsl' === $request['sitemap_name'] ) {
273 + $this->serve_raw_and_die(
274 + 'application/xml',
275 + Jetpack_Sitemap_Stylist::image_sitemap_xsl()
276 + );
277 + }
278 +
279 + // Catch video sitemap xsl.
280 + if ( 'video-sitemap.xsl' === $request['sitemap_name'] ) {
281 + $this->serve_raw_and_die(
282 + 'application/xml',
283 + Jetpack_Sitemap_Stylist::video_sitemap_xsl()
284 + );
285 + }
286 +
287 + // Catch news sitemap xml.
288 + if ( 'news-sitemap.xml' === $request['sitemap_name'] ) {
289 + $sitemap_builder = new Jetpack_Sitemap_Builder();
290 + $this->serve_raw_and_die(
291 + $xml_content_type,
292 + $sitemap_builder->news_sitemap_xml()
293 + );
294 + }
295 +
296 + // Catch news sitemap xsl.
297 + if ( 'news-sitemap.xsl' === $request['sitemap_name'] ) {
298 + $this->serve_raw_and_die(
299 + 'application/xml',
300 + Jetpack_Sitemap_Stylist::news_sitemap_xsl()
301 + );
302 + }
303 +
304 + // Catch sitemap xml.
305 + if ( preg_match( $regex['sitemap'], $request['sitemap_name'] ) ) {
306 + $this->serve_raw_and_die(
307 + $xml_content_type,
308 + $this->librarian->get_sitemap_text(
309 + $request['sitemap_name'],
310 + JP_PAGE_SITEMAP_TYPE
311 + )
312 + );
313 + }
314 +
315 + // Catch sitemap index xml.
316 + if ( preg_match( $regex['index'], $request['sitemap_name'] ) ) {
317 + $this->serve_raw_and_die(
318 + $xml_content_type,
319 + $this->librarian->get_sitemap_text(
320 + $request['sitemap_name'],
321 + JP_PAGE_SITEMAP_INDEX_TYPE
322 + )
323 + );
324 + }
325 +
326 + // Catch image sitemap xml.
327 + if ( preg_match( $regex['image'], $request['sitemap_name'] ) ) {
328 + $this->serve_raw_and_die(
329 + $xml_content_type,
330 + $this->librarian->get_sitemap_text(
331 + $request['sitemap_name'],
332 + JP_IMAGE_SITEMAP_TYPE
333 + )
334 + );
335 + }
336 +
337 + // Catch image sitemap index xml.
338 + if ( preg_match( $regex['image-index'], $request['sitemap_name'] ) ) {
339 + $this->serve_raw_and_die(
340 + $xml_content_type,
341 + $this->librarian->get_sitemap_text(
342 + $request['sitemap_name'],
343 + JP_IMAGE_SITEMAP_INDEX_TYPE
344 + )
345 + );
346 + }
347 +
348 + // Catch video sitemap xml.
349 + if ( preg_match( $regex['video'], $request['sitemap_name'] ) ) {
350 + $this->serve_raw_and_die(
351 + $xml_content_type,
352 + $this->librarian->get_sitemap_text(
353 + $request['sitemap_name'],
354 + JP_VIDEO_SITEMAP_TYPE
355 + )
356 + );
357 + }
358 +
359 + // Catch video sitemap index xml.
360 + if ( preg_match( $regex['video-index'], $request['sitemap_name'] ) ) {
361 + $this->serve_raw_and_die(
362 + $xml_content_type,
363 + $this->librarian->get_sitemap_text(
364 + $request['sitemap_name'],
365 + JP_VIDEO_SITEMAP_INDEX_TYPE
366 + )
367 + );
368 + }
369 + }
370 + }
371 +
372 + /**
373 + * Callback for adding sitemap-interval to the list of schedules.
374 + *
375 + * @access public
376 + * @since 4.8.0
377 + *
378 + * @param array $schedules The array of WP_Cron schedules.
379 + *
380 + * @return array The updated array of WP_Cron schedules.
381 + */
382 + public function callback_add_sitemap_schedule( $schedules ) {
383 + $schedules['sitemap-interval'] = array(
384 + 'interval' => JP_SITEMAP_INTERVAL,
385 + 'display' => __( 'Sitemap Interval', 'jetpack' ),
386 + );
387 + return $schedules;
388 + }
389 +
390 + /**
391 + * Callback handler for sitemap cron hook
392 + *
393 + * @access public
394 + */
395 + public function callback_sitemap_cron_hook() {
396 + $sitemap_builder = new Jetpack_Sitemap_Builder();
397 + $sitemap_builder->update_sitemap();
398 + }
399 +
400 + /**
401 + * Add actions to schedule sitemap generation.
402 + * Should only be called once, in the constructor.
403 + *
404 + * @access private
405 + * @since 4.8.0
406 + */
407 + private function schedule_sitemap_generation() {
408 + // Add cron schedule.
409 + add_filter( 'cron_schedules', array( $this, 'callback_add_sitemap_schedule' ) ); // phpcs:ignore WordPress.WP.CronInterval.ChangeDetected
410 +
411 + add_action(
412 + 'jp_sitemap_cron_hook',
413 + array( $this, 'callback_sitemap_cron_hook' )
414 + );
415 +
416 + if ( ! wp_next_scheduled( 'jp_sitemap_cron_hook' ) ) {
417 + /**
418 + * Filter the delay in seconds until sitemap generation cron job is started.
419 + *
420 + * This filter allows a site operator or hosting provider to potentialy spread out sitemap generation for a
421 + * lot of sites over time. By default, it will be randomly done over 15 minutes.
422 + *
423 + * @module sitemaps
424 + * @since 6.6.1
425 + *
426 + * @param int $delay Time to delay in seconds.
427 + */
428 + $delay = apply_filters( 'jetpack_sitemap_generation_delay', MINUTE_IN_SECONDS * wp_rand( 1, 15 ) ); // Randomly space it out to start within next fifteen minutes.
429 + wp_schedule_event(
430 + time() + $delay,
431 + 'sitemap-interval',
432 + 'jp_sitemap_cron_hook'
433 + );
434 + }
435 + }
436 +
437 + /**
438 + * Callback to add sitemap to robots.txt.
439 + *
440 + * @access public
441 + * @since 4.8.0
442 + */
443 + public function callback_action_do_robotstxt() {
444 +
445 + /**
446 + * Filter whether to make the default sitemap discoverable to robots or not. Default true.
447 + *
448 + * @module sitemaps
449 + * @since 3.9.0
450 + * @deprecated 7.4.0
451 + *
452 + * @param bool $discover_sitemap Make default sitemap discoverable to robots.
453 + */
454 + $discover_sitemap = apply_filters_deprecated( 'jetpack_sitemap_generate', array( true ), 'jetpack-7.4.0', 'jetpack_sitemap_include_in_robotstxt' );
455 +
456 + /**
457 + * Filter whether to make the default sitemap discoverable to robots or not. Default true.
458 + *
459 + * @module sitemaps
460 + * @since 7.4.0
461 + *
462 + * @param bool $discover_sitemap Make default sitemap discoverable to robots.
463 + */
464 + $discover_sitemap = apply_filters( 'jetpack_sitemap_include_in_robotstxt', $discover_sitemap );
465 +
466 + if ( true === $discover_sitemap ) {
467 + $sitemap_url = $this->finder->construct_sitemap_url( 'sitemap.xml' );
468 + echo 'Sitemap: ' . esc_url( $sitemap_url ) . "\n";
469 + }
470 +
471 + /**
472 + * Filter whether to make the news sitemap discoverable to robots or not. Default true.
473 + *
474 + * @module sitemaps
475 + * @since 3.9.0
476 + * @deprecated 7.4.0
477 + *
478 + * @param bool $discover_news_sitemap Make default news sitemap discoverable to robots.
479 + */
480 + $discover_news_sitemap = apply_filters_deprecated( 'jetpack_news_sitemap_generate', array( true ), 'jetpack-7.4.0', 'jetpack_news_sitemap_include_in_robotstxt' );
481 +
482 + /**
483 + * Filter whether to make the news sitemap discoverable to robots or not. Default true.
484 + *
485 + * @module sitemaps
486 + * @since 7.4.0
487 + *
488 + * @param bool $discover_news_sitemap Make default news sitemap discoverable to robots.
489 + */
490 + $discover_news_sitemap = apply_filters( 'jetpack_news_sitemap_include_in_robotstxt', $discover_news_sitemap );
491 +
492 + if ( true === $discover_news_sitemap ) {
493 + $news_sitemap_url = $this->finder->construct_sitemap_url( 'news-sitemap.xml' );
494 + echo 'Sitemap: ' . esc_url( $news_sitemap_url ) . "\n";
495 + }
496 + }
497 +
498 + /**
499 + * Callback to delete the news sitemap cache.
500 + *
501 + * @access public
502 + * @since 4.8.0
503 + */
504 + public function callback_action_flush_news_sitemap_cache() {
505 + delete_transient( 'jetpack_news_sitemap_xml' );
506 + }
507 +
508 + /**
509 + * Callback for resetting stored sitemap data.
510 + *
511 + * @access public
512 + * @since 5.3.0
513 + * @since 6.7.0 Schedules a regeneration.
514 + */
515 + public function callback_action_purge_data() {
516 + $this->callback_action_flush_news_sitemap_cache();
517 + $this->librarian->delete_all_stored_sitemap_data();
518 + /** This filter is documented in modules/sitemaps/sitemaps.php */
519 + $delay = apply_filters( 'jetpack_sitemap_generation_delay', MINUTE_IN_SECONDS * wp_rand( 1, 15 ) ); // Randomly space it out to start within next fifteen minutes.
520 + wp_schedule_single_event( time() + $delay, 'jp_sitemap_cron_hook' );
521 + }
522 +
523 + /**
524 + * Callback to set the sitemap location.
525 + *
526 + * @access public
527 + * @since 4.8.0
528 + */
529 + public function callback_action_filter_sitemap_location() {
530 + update_option(
531 + 'jetpack_sitemap_location',
532 + /**
533 + * Additional path for sitemap URIs. Default value is empty.
534 + *
535 + * This string is any additional path fragment you want included between
536 + * the home URL and the sitemap filenames. Exactly how this fragment is
537 + * interpreted depends on your permalink settings. For example:
538 + *
539 + * Pretty permalinks:
540 + * home_url() . jetpack_sitemap_location . '/sitemap.xml'
541 + *
542 + * Plain ("ugly") permalinks:
543 + * home_url() . jetpack_sitemap_location . '/?jetpack-sitemap=sitemap.xml'
544 + *
545 + * PATHINFO permalinks:
546 + * home_url() . '/index.php' . jetpack_sitemap_location . '/sitemap.xml'
547 + *
548 + * where 'sitemap.xml' is the name of a specific sitemap file.
549 + * The value of this filter must be a valid path fragment per RFC 3986;
550 + * in particular it must either be empty or begin with a '/'.
551 + * Also take care that any restrictions on sitemap location imposed by
552 + * the sitemap protocol are satisfied.
553 + *
554 + * The result of this filter is stored in an option, 'jetpack_sitemap_location';
555 + * that option is what gets read when the sitemap location is needed.
556 + * This way we don't have to wait for init to finish before building sitemaps.
557 + *
558 + * @link https://tools.ietf.org/html/rfc3986#section-3.3 RFC 3986
559 + * @link https://www.sitemaps.org/ The sitemap protocol
560 + *
561 + * @since 4.8.0
562 + */
563 + apply_filters(
564 + 'jetpack_sitemap_location',
565 + ''
566 + )
567 + );
568 + }
569 +} // End Jetpack_Sitemap_Manager class.
570 +
571 +new Jetpack_Sitemap_Manager();
572 +
573 +/**
574 + * Absolute URL of the current blog's sitemap.
575 + *
576 + * @module sitemaps
577 + *
578 + * @since 3.9.0
579 + * @since 4.8.1 Code uses method found in Jetpack_Sitemap_Finder::construct_sitemap_url in 4.8.0.
580 + * It has been moved here to avoid fatal errors with other plugins that were expecting to find this function.
581 + *
582 + * @param string $filename Sitemap file name. Defaults to 'sitemap.xml', the initial sitemaps page.
583 + *
584 + * @return string Sitemap URL.
585 + */
586 +function jetpack_sitemap_uri( $filename = 'sitemap.xml' ) {
587 + global $wp_rewrite;
588 +
589 + $location = Jetpack_Options::get_option_and_ensure_autoload( 'jetpack_sitemap_location', '' );
590 +
591 + if ( $wp_rewrite->using_index_permalinks() ) {
592 + $sitemap_url = home_url( '/index.php' . $location . '/' . $filename );
593 + } elseif ( $wp_rewrite->using_permalinks() ) {
594 + $sitemap_url = home_url( $location . '/' . $filename );
595 + } else {
596 + $sitemap_url = home_url( $location . '/?jetpack-sitemap=' . $filename );
597 + }
598 +
599 + /**
600 + * Filter sitemap URL relative to home URL.
601 + *
602 + * @module sitemaps
603 + *
604 + * @since 3.9.0
605 + *
606 + * @param string $sitemap_url Sitemap URL.
607 + */
608 + return apply_filters( 'jetpack_sitemap_location', $sitemap_url );
609 +}
610 +
611 +// Register Jetpack Sitemaps abilities (WordPress Abilities API, WP 6.9+).
612 +require_once __DIR__ . '/abilities/class-sitemaps-abilities.php';
613 +\Automattic\Jetpack\Plugin\Abilities\Sitemaps_Abilities::init();