XML Sitemap & Google News feeds - Version 4.6

Version Description

New action hook xmlsf_news_tags_after, attempt to remove conflicting static sitemap files on activation

=

Download this release

Release Info

Developer RavanH
Plugin Icon 128x128 XML Sitemap & Google News feeds
Version 4.6
Comparing to
See all releases

Code changes from version 4.5.1 to 4.6

Files changed (4) hide show
  1. includes/core.php +233 -216
  2. includes/feed-sitemap-news.php +3 -0
  3. readme.txt +8 -4
  4. xml-sitemap.php +27 -24
includes/core.php CHANGED
@@ -10,31 +10,31 @@ class XMLSitemapFeed {
10
  /**
11
  * Plugin variables
12
  */
13
-
14
  // Pretty permalinks base name
15
  public $base_name = 'sitemap';
16
 
17
  // Pretty permalinks extension
18
  public $extension = 'xml';
19
-
20
  // Database options prefix
21
  private $prefix = 'xmlsf_';
22
-
23
  // Flushed flag
24
  private $yes_mother = false;
25
 
26
  private $defaults = array();
27
  private $disabled_post_types = array('attachment'); /* attachment post type is disabled... images are included via tags in the post and page sitemaps */
28
  private $disabled_taxonomies = array('post_format'); /* post format taxonomy is brute force disabled for now; might come back... */
29
- private $gn_genres = array(
30
- 'PressRelease',
31
- 'Satire',
32
- 'Blog',
33
- 'OpEd',
34
- 'Opinion',
35
- 'UserGenerated'
36
  );
37
-
38
  // Global values used for priority and changefreq calculation
39
  private $domain;
40
  private $firstdate;
@@ -43,32 +43,32 @@ class XMLSitemapFeed {
43
  private $termmodified = array();
44
  private $blogpage;
45
  private $images = array();
46
-
47
  // make some private parts public ;)
48
-
49
- public function prefix()
50
  {
51
  return $this->prefix;
52
  }
53
 
54
- public function gn_genres()
55
  {
56
  return $this->gn_genres;
57
  }
58
 
59
- public function domain()
60
  {
61
  // allowed domain
62
  if (empty($this->domain)) {
63
- $url_parsed = parse_url(home_url()); // second parameter PHP_URL_HOST for only PHP5 + ...
64
  $this->domain = str_replace("www.","",$url_parsed['host']);
65
  }
66
-
67
  return $this->domain;
68
  }
69
 
70
  // default options
71
- private function set_defaults()
72
  {
73
  // sitemaps
74
  if ( '1' == get_option('blog_public') )
@@ -93,14 +93,14 @@ class XMLSitemapFeed {
93
  'dynamic_priority' => '',
94
  'tags' => array('image' => 'attached'/*,'video' => ''*/)
95
  );
96
- }
97
 
98
  $active_arr = array('post','page');
99
-
100
  foreach ( $active_arr as $name )
101
  if ( isset($this->defaults['post_types'][$name]) )
102
  $this->defaults['post_types'][$name]['active'] = '1';
103
-
104
  if ( isset($this->defaults['post_types']['post']) ) {
105
  if (wp_count_posts('post')->publish > 500)
106
  $this->defaults['post_types']['post']['archive'] = 'yearly';
@@ -115,7 +115,7 @@ class XMLSitemapFeed {
115
 
116
  // taxonomies
117
  $this->defaults['taxonomies'] = array(); // by default do not include any taxonomies
118
-
119
  // news sitemap settings
120
  $this->defaults['news_sitemap'] = array();
121
 
@@ -154,7 +154,7 @@ class XMLSitemapFeed {
154
  $this->defaults['robots'] = "";
155
  // Old rules "Disallow: */xmlrpc.php\nDisallow: */wp-*.php\nDisallow: */trackback/\nDisallow: *?wptheme=\nDisallow: *?comments=\nDisallow: *?replytocom\nDisallow: */comment-page-\nDisallow: *?s=\nDisallow: */wp-content/\nAllow: */wp-content/uploads/\n";
156
  // Better is to set <meta name="robots" content="noindex, follow"> or send X-Robots-Tag header. TODO !!
157
-
158
  // additional urls
159
  $this->defaults['urls'] = array();
160
 
@@ -163,25 +163,25 @@ class XMLSitemapFeed {
163
 
164
  // additional allowed domains
165
  $this->defaults['domains'] = array();
166
-
167
  // news sitemap tags settings
168
- $this->defaults['news_tags'] = array(
169
  'name' => '',
170
  'post_type' => array('post'),
171
  'categories' => '',
172
  'image' => 'featured',
173
- 'access' => array(
174
- 'default' => '',
175
  //'private' => 'Registration', // private posts do not show up in feeds when not logged in. no point in setting access level then...
176
- 'password' => 'Subscription'
177
- ),
178
- 'genres' => array(
179
- 'active' => '1',
180
- 'default' => array('Blog')
181
  ),
182
- 'keywords' => array(
183
- 'from' => 'category',
184
- 'default' => ''
 
 
 
 
185
  )
186
  );
187
  }
@@ -189,8 +189,8 @@ class XMLSitemapFeed {
189
  /**
190
  * QUERY FUNCTIONS
191
  */
192
-
193
- public function defaults($key = false)
194
  {
195
  if (empty($this->defaults))
196
  $this->set_defaults();
@@ -203,50 +203,50 @@ class XMLSitemapFeed {
203
 
204
  return apply_filters( 'xmlsf_defaults', $return, $key );
205
  }
206
-
207
- public function get_option($option)
208
  {
209
  return get_option($this->prefix.$option, $this->defaults($option));
210
  }
211
-
212
- public function get_sitemaps()
213
  {
214
  $return = $this->get_option('sitemaps');
215
-
216
  // make sure it's an array we are returning
217
  return (!empty($return)) ? (array)$return : array();
218
  }
219
-
220
- public function get_ping()
221
- {
222
  $return = $this->get_option('ping');
223
-
224
  // make sure it's an array we are returning
225
  return (!empty($return)) ? (array)$return : array();
226
  }
227
-
228
- public function disabled_post_types()
229
- {
230
  return $this->disabled_post_types;
231
 
232
  }
233
-
234
- public function disabled_taxonomies()
235
- {
236
  return $this->disabled_taxonomies;
237
 
238
  }
239
-
240
- public function get_post_types()
241
- {
242
  $return = $this->get_option('post_types');
243
 
244
  // make sure it's an array we are returning
245
  return (!empty($return)) ? (array)$return : array();
246
  }
247
 
248
- public function have_post_types()
249
- {
250
  $return = array();
251
 
252
  foreach ( $this->get_post_types() as $type => $values ) {
@@ -262,16 +262,16 @@ class XMLSitemapFeed {
262
  // make sure it's an array we are returning
263
  return (!empty($return)) ? (array)$return : array();
264
  }
265
-
266
- public function get_taxonomies()
267
  {
268
  $return = $this->get_option('taxonomies');
269
 
270
  // make sure it's an array we are returning
271
  return (!empty($return)) ? (array)$return : array();
272
  }
273
-
274
- public function get_custom_sitemaps()
275
  {
276
  $return = $this->get_option('custom_sitemaps');
277
 
@@ -283,10 +283,10 @@ class XMLSitemapFeed {
283
  return explode("\n",$return);
284
  } else {
285
  return array();
286
- }
287
  }
288
 
289
- public function get_urls()
290
  {
291
  $return = $this->get_option('urls');
292
 
@@ -298,24 +298,24 @@ class XMLSitemapFeed {
298
  return explode("\n",$return);
299
  } else {
300
  return array();
301
- }
302
  }
303
 
304
- public function get_domains()
305
  {
306
  $domains = $this->get_option('domains');
307
  if (!empty($domains) && is_array($domains))
308
  return array_merge( array( $this->domain() ), $domains );
309
- else
310
  return array( $this->domain() );
311
  }
312
 
313
- public function get_archives($post_type = 'post', $type = '')
314
  {
315
  global $wpdb;
316
  $return = array();
317
  if ( 'monthly' == $type ) {
318
- $query = "SELECT YEAR(post_date) AS `year`, LPAD(MONTH(post_date),2,'0') AS `month`, count(ID) as posts FROM $wpdb->posts WHERE post_type = '$post_type' AND post_status = 'publish' GROUP BY YEAR(post_date), MONTH(post_date) ORDER BY post_date DESC";
319
  $key = md5($query);
320
  $cache = wp_cache_get( 'xmlsf_get_archives' , 'general');
321
  if ( !isset( $cache[ $key ] ) ) {
@@ -352,28 +352,28 @@ class XMLSitemapFeed {
352
  return $return;
353
  }
354
 
355
- public function get_robots()
356
  {
357
  return ( $robots = $this->get_option('robots') ) ? $robots : '';
358
  }
359
 
360
- public function do_tags( $type = 'post' )
361
- {
362
  $return = $this->get_post_types();
363
 
364
  // make sure it's an array we are returning
365
- return (
366
- is_string($type) &&
367
- isset($return[$type]) &&
368
- !empty($return[$type]['tags'])
369
  ) ? (array)$return[$type]['tags'] : array();
370
  }
371
-
372
- public function is_home($id)
373
  {
374
  if ( empty($this->blogpage) ) {
375
  $blogpage = get_option('page_for_posts');
376
-
377
  if ( !empty($blogpage) ) {
378
  global $polylang;
379
  if ( isset($polylang) )
@@ -387,12 +387,12 @@ class XMLSitemapFeed {
387
 
388
  return in_array($id,$this->blogpage);
389
  }
390
-
391
  /**
392
  * TEMPLATE FUNCTIONS
393
  */
394
-
395
- public function modified($sitemap = 'post_type', $term = '')
396
  {
397
  if ('post_type' == $sitemap) :
398
 
@@ -416,27 +416,27 @@ class XMLSitemapFeed {
416
  if ( isset($lastcomment[0]->comment_date_gmt) )
417
  if ( mysql2date( 'U', $lastcomment[0]->comment_date_gmt, false ) > mysql2date( 'U', $postmodified, false ) )
418
  $postmodified = $lastcomment[0]->comment_date_gmt;
419
-
420
  // make sure lastmod is not older than publication date (happens on scheduled posts)
421
  if ( isset($post->post_date_gmt) && strtotime($post->post_date_gmt) > strtotime($postmodified) )
422
  $postmodified = $post->post_date_gmt;
423
 
424
  $this->postmodified[$post->ID] = $postmodified;
425
  }
426
-
427
  return $this->postmodified[$post->ID];
428
 
429
  elseif ( !empty($term) ) :
430
 
431
- if ( is_object($term) ) {
432
  if ( !isset($this->termmodified[$term->term_id]) ) {
433
  // get the latest post in this taxonomy item, to use its post_date as lastmod
434
  $posts = get_posts ( array(
435
  'post_type' => 'any',
436
- 'numberposts' => 1,
437
- 'no_found_rows' => true,
438
- 'update_post_meta_cache' => false,
439
- 'update_post_term_cache' => false,
440
  'update_cache' => false,
441
  'tax_query' => array(
442
  array(
@@ -454,9 +454,9 @@ class XMLSitemapFeed {
454
  $obj = get_taxonomy($term);
455
  return get_lastdate( 'gmt', $obj->object_type );
456
  // uses get_lastdate() function defined in xml-sitemap/hacks.php !
457
- // which is a shortcut: returns last post date, not last modified date...
458
- // TODO find the long way home: take tax type, get all terms,
459
- // do tax_query with all terms for one post and get its lastmod date
460
  // ... or can 'terms' in tax_query be empty?
461
  }
462
 
@@ -467,7 +467,7 @@ class XMLSitemapFeed {
467
  endif;
468
  }
469
 
470
- public function get_images($sitemap = '')
471
  {
472
  global $post;
473
  if ( empty($this->images[$post->ID]) ) {
@@ -484,7 +484,7 @@ class XMLSitemapFeed {
484
  if ($attachments) {
485
  foreach ( $attachments as $attachment ) {
486
  $url = wp_get_attachment_image_src( $attachment->ID, 'full' );
487
- $this->images[$post->ID][] = array(
488
  'loc' => esc_attr( esc_url_raw( $url[0] ) ), // use esc_attr() to entity escape & here ?? esc_url() creates &#038; which is not what we want...
489
  'title' => apply_filters( 'the_title_xmlsitemap', $attachment->post_title ),
490
  'caption' => apply_filters( 'the_title_xmlsitemap', $attachment->post_excerpt )
@@ -495,7 +495,7 @@ class XMLSitemapFeed {
495
  if (has_post_thumbnail( $post->ID ) ) {
496
  $attachment = get_post(get_post_thumbnail_id( $post->ID ));
497
  $url = wp_get_attachment_image_src( $attachment->ID, 'full' );
498
- $this->images[$post->ID][] = array(
499
  'loc' => esc_attr( esc_url_raw( $url[0] ) ),
500
  'title' => apply_filters( 'the_title_xmlsitemap', $attachment->post_title ),
501
  'caption' => apply_filters( 'the_title_xmlsitemap', $attachment->post_excerpt )
@@ -505,67 +505,67 @@ class XMLSitemapFeed {
505
  }
506
  return ( isset($this->images[$post->ID]) ) ? $this->images[$post->ID] : false;
507
  }
508
-
509
- public function get_lastmod($sitemap = 'post_type', $term = '')
510
  {
511
  $return = trim(mysql2date('Y-m-d\TH:i:s+00:00', $this->modified($sitemap,$term), false));
512
  return !empty($return) ? "\t<lastmod>".$return."</lastmod>\r\n\t" : '';
513
  }
514
 
515
- public function get_changefreq($sitemap = 'post_type', $term = '')
516
  {
517
  $modified = trim($this->modified($sitemap,$term));
518
 
519
  if (empty($modified))
520
  return 'weekly';
521
-
522
  $lastactivityage = ( gmdate('U') - mysql2date( 'U', $modified, false ) ); // post age
523
-
524
- if ( ($lastactivityage/86400) < 1 ) { // last activity less than 1 day old
525
  $changefreq = 'hourly';
526
- } else if ( ($lastactivityage/86400) < 7 ) { // last activity less than 1 week old
527
  $changefreq = 'daily';
528
- } else if ( ($lastactivityage/86400) < 30 ) { // last activity less than one month old
529
  $changefreq = 'weekly';
530
- } else if ( ($lastactivityage/86400) < 365 ) { // last activity less than 1 year old
531
  $changefreq = 'monthly';
532
  } else {
533
  $changefreq = 'yearly'; // over a year old...
534
- }
535
 
536
  return $changefreq;
537
  }
538
 
539
- public function get_priority($sitemap = 'post_type', $term = '')
540
  {
541
  if ( 'post_type' == $sitemap ) :
542
  global $post;
543
  $options = $this->get_post_types();
544
  $defaults = $this->defaults('post_types');
545
  $priority_meta = get_metadata('post', $post->ID, '_xmlsf_priority' , true);
546
-
547
  if ( !empty($priority_meta) || $priority_meta == '0' ) {
548
-
549
  $priority = floatval(str_replace(",",".",$priority_meta));
550
-
551
  } elseif ( !empty($options[$post->post_type]['dynamic_priority']) ) {
552
 
553
  $post_modified = mysql2date('U',$post->post_modified_gmt, false);
554
-
555
  if ( empty($this->lastmodified) )
556
- $this->lastmodified = mysql2date('U',get_lastmodified('GMT',$post->post_type),false);
557
- // last posts or page modified date in Unix seconds
558
  // uses get_lastmodified() function defined in xml-sitemap/hacks.php !
559
-
560
  if ( empty($this->firstdate) )
561
- $this->firstdate = mysql2date('U',get_firstdate('GMT',$post->post_type),false);
562
  // uses get_firstdate() function defined in xml-sitemap/hacks.php !
563
-
564
  if ( isset($options[$post->post_type]['priority']) )
565
  $priority_value = floatval(str_replace(",",".",$options[$post->post_type]['priority']));
566
  else
567
  $priority_value = floatval($defaults[$post->post_type]['priority']);
568
-
569
  // reduce by age
570
  // NOTE : home/blog page gets same treatment as sticky post
571
  if ( is_sticky($post->ID) || $this->is_home($post->ID) )
@@ -579,7 +579,7 @@ class XMLSitemapFeed {
579
  } else {
580
 
581
  $priority = ( isset($options[$post->post_type]['priority']) && is_numeric($options[$post->post_type]['priority']) ) ? $options[$post->post_type]['priority'] : $defaults[$post->post_type]['priority'];
582
-
583
  }
584
 
585
  elseif ( ! empty($term) ) :
@@ -602,7 +602,7 @@ class XMLSitemapFeed {
602
  $priority = 0.5;
603
 
604
  endif;
605
-
606
  // make sure we're not below zero
607
  if ($priority < 0)
608
  $priority = 0;
@@ -614,43 +614,43 @@ class XMLSitemapFeed {
614
  return number_format($priority,1);
615
  }
616
 
617
- public function get_home_urls()
618
  {
619
  $urls = array();
620
-
621
  global $polylang,$q_config;
622
 
623
- if ( isset($polylang) )
624
  foreach ($polylang->get_languages_list() as $term)
625
  $urls[] = $polylang->get_home_url($term);
626
  else
627
  $urls[] = home_url();
628
-
629
  return $urls;
630
  }
631
 
632
- public function get_excluded($post_type)
633
  {
634
  $exclude = array();
635
-
636
  if ( $post_type == 'page' && $id = get_option('page_on_front') ) {
637
  global $polylang;
638
  if ( isset($polylang) )
639
  $exclude += $polylang->get_translations('post', $id);
640
- else
641
  $exclude[] = $id;
642
  }
643
-
644
  return $exclude;
645
  }
646
 
647
- public function is_allowed_domain($url)
648
  {
649
  $domains = $this->get_domains();
650
  $return = false;
651
  $parsed_url = parse_url($url);
652
 
653
- if (isset($parsed_url['host'])) {
654
  foreach( $domains as $domain ) {
655
  if( $parsed_url['host'] == $domain || strpos($parsed_url['host'],".".$domain) !== false ) {
656
  $return = true;
@@ -662,13 +662,13 @@ class XMLSitemapFeed {
662
  return apply_filters( 'xmlsf_allowed_domain', $return );
663
  }
664
 
665
- public function get_index_url( $sitemap = 'home', $type = false, $param = false )
666
  {
667
- $root = esc_url( trailingslashit(home_url()) );
668
  $name = $this->base_name.'-'.$sitemap;
669
-
670
  if ( $type )
671
- $name .= '-'.$type;
672
 
673
  if ( '' == get_option('permalink_structure') || '1' != get_option('blog_public')) {
674
  $name = '?feed='.$name;
@@ -677,24 +677,24 @@ class XMLSitemapFeed {
677
  $name .= $param ? '.'.$param : '';
678
  $name .= '.'.$this->extension;
679
  }
680
-
681
  return $root . $name;
682
  }
683
-
684
 
685
  /**
686
- * ROBOTSTXT
687
  */
688
 
689
  // add sitemap location in robots.txt generated by WP
690
- public function robots($output)
691
- {
692
  echo "\n# XML Sitemap & Google News Feeds version ".XMLSF_VERSION." - http://status301.net/wordpress-plugins/xml-sitemap-feed/";
693
 
694
  if ( '1' != get_option('blog_public') ) {
695
  echo "\n# XML Sitemaps are disabled. Please see Site Visibility on Settings > Reading.";
696
  } else {
697
- foreach ( $this->get_sitemaps() as $pretty )
698
  echo "\nSitemap: " . trailingslashit(get_bloginfo('url')) . $pretty;
699
 
700
  if ( empty($pretty) )
@@ -702,13 +702,13 @@ class XMLSitemapFeed {
702
  }
703
  echo "\n\n";
704
  }
705
-
706
  // add robots.txt rules
707
- public function robots_txt($output)
708
  {
709
  return $output . $this->get_option('robots') . "\n\n";
710
  }
711
-
712
  /**
713
  * REWRITES
714
  */
@@ -719,8 +719,7 @@ class XMLSitemapFeed {
719
  *
720
  * @param string $request
721
  */
722
-
723
- public function trailingslash($request)
724
  {
725
  if (pathinfo($request, PATHINFO_EXTENSION)) {
726
  return untrailingslashit($request);
@@ -733,8 +732,7 @@ class XMLSitemapFeed {
733
  *
734
  * @param string $wp_rewrite
735
  */
736
-
737
- public function rewrite_rules($wp_rewrite)
738
  {
739
  $xmlsf_rules = array();
740
  $sitemaps = $this->get_sitemaps();
@@ -745,7 +743,7 @@ class XMLSitemapFeed {
745
  if (!empty($sitemaps['sitemap'])) {
746
  // home urls
747
  $xmlsf_rules[ $this->base_name . '-home\.' . $this->extension . '$' ] = $wp_rewrite->index . '?feed=sitemap-home';
748
-
749
  // add rules for post types (can be split by month or year)
750
  foreach ( $this->get_post_types() as $post_type ) {
751
  if ( isset($post_type['active']) && '1' == $post_type['active'] )
@@ -762,10 +760,10 @@ class XMLSitemapFeed {
762
  $xmlsf_rules[ $this->base_name . '-custom\.' . $this->extension . '$' ] = $wp_rewrite->index . '?feed=sitemap-custom';
763
 
764
  }
765
-
766
  $wp_rewrite->rules = $xmlsf_rules + $wp_rewrite->rules;
767
  }
768
-
769
  /**
770
  * REQUEST FILTER
771
  */
@@ -778,12 +776,12 @@ class XMLSitemapFeed {
778
  return $theme;
779
  }
780
 
781
- public function filter_request( $request )
782
  {
783
  if ( isset($request['feed']) && strpos($request['feed'],'sitemap') == 0 ) {
784
 
785
  if ( $request['feed'] == 'sitemap' ) {
786
-
787
  // setup actions and filters
788
  add_action('do_feed_sitemap', array($this, 'load_template_index'), 10, 1);
789
 
@@ -794,18 +792,18 @@ class XMLSitemapFeed {
794
  $defaults = $this->defaults('news_tags');
795
  $options = $this->get_option('news_tags');
796
  $news_post_type = isset($options['post_type']) && !empty($options['post_type']) ? $options['post_type'] : $defaults['post_type'];
797
- if (empty($news_post_type)) $news_post_type = 'post';
798
-
799
  // disable caching
800
  define('DONOTCACHEPAGE', true);
801
- define('DONOTCACHEDB', true);
802
-
803
  // setup template
804
  add_action('do_feed_sitemap-news', array($this, 'load_template_news'), 10, 1);
805
 
806
  // set up query filters
807
  // TODO: test 'gmt' against 'blog' against 'server'
808
-
809
  if ( function_exists('date_default_timezone_set') ) {
810
  date_default_timezone_set ( 'UTC' );
811
  $zone = 'gmt';
@@ -814,7 +812,7 @@ class XMLSitemapFeed {
814
  }
815
  if ( get_lastdate($zone, $news_post_type) > date('Y-m-d H:i:s', strtotime('-48 hours')) ) {
816
  add_filter('post_limits', array($this, 'filter_news_limits'));
817
- add_filter('posts_where', array($this, 'filter_news_where'), 10, 1);
818
  } else {
819
  add_filter('post_limits', array($this, 'filter_no_news_limits'));
820
  }
@@ -825,9 +823,9 @@ class XMLSitemapFeed {
825
 
826
  // categories
827
  if ( isset($options['categories']) && is_array($options['categories']) )
828
- $request['cat'] = implode(',',$options['categories']);
829
-
830
- $request['post_status'] = 'publish';
831
  $request['no_found_rows'] = true;
832
 
833
  return $request;
@@ -898,37 +896,37 @@ class XMLSitemapFeed {
898
  */
899
 
900
  // set up the sitemap index template
901
- public function load_template_index()
902
  {
903
  load_template( dirname( __FILE__ ) . '/feed-sitemap.php' );
904
  }
905
 
906
  // set up the sitemap home page(s) template
907
- public function load_template_base()
908
  {
909
  load_template( dirname( __FILE__ ) . '/feed-sitemap-home.php' );
910
  }
911
 
912
  // set up the post types sitemap template
913
- public function load_template()
914
  {
915
  load_template( dirname( __FILE__ ) . '/feed-sitemap-post_type.php' );
916
  }
917
 
918
  // set up the taxonomy sitemap template
919
- public function load_template_taxonomy()
920
  {
921
  load_template( dirname( __FILE__ ) . '/feed-sitemap-taxonomy.php' );
922
  }
923
 
924
  // set up the news sitemap template
925
- public function load_template_news()
926
  {
927
  load_template( dirname( __FILE__ ) . '/feed-sitemap-news.php' );
928
  }
929
 
930
  // set up the news sitemap template
931
- public function load_template_custom()
932
  {
933
  load_template( dirname( __FILE__ ) . '/feed-sitemap-custom.php' );
934
  }
@@ -938,19 +936,19 @@ class XMLSitemapFeed {
938
  */
939
 
940
  // override default feed limit
941
- public function filter_limits( $limits )
942
  {
943
  return 'LIMIT 0, 50000';
944
  }
945
 
946
  // override default feed limit for taxonomy sitemaps
947
- public function filter_limits_taxonomy( $limits )
948
  {
949
  return 'LIMIT 0, 1';
950
  }
951
 
952
  // only posts from the last 48 hours
953
- public function filter_news_where( $where = '' )
954
  {
955
  if ( function_exists('date_default_timezone_set') ) {
956
  date_default_timezone_set ( 'UTC' );
@@ -959,15 +957,15 @@ class XMLSitemapFeed {
959
  return $where . " AND post_date > '" . date('Y-m-d H:i:s', strtotime('-48 hours')) . "'";
960
  }
961
  }
962
-
963
  // override default feed limit for GN
964
- public function filter_news_limits( $limits )
965
  {
966
  return 'LIMIT 0, 1000';
967
  }
968
 
969
  // in case there is no news, just take the latest post
970
- public function filter_no_news_limits( $limits )
971
  {
972
  return 'LIMIT 0, 1';
973
  }
@@ -976,7 +974,7 @@ class XMLSitemapFeed {
976
  * PINGING
977
  */
978
 
979
- public function ping($uri, $timeout = 3)
980
  {
981
  $options = array();
982
  $options['timeout'] = $timeout;
@@ -986,12 +984,12 @@ class XMLSitemapFeed {
986
  if ( '200' == wp_remote_retrieve_response_code($response) )
987
  $succes = true;
988
  else
989
- $succes = false;
990
 
991
  return $succes;
992
  }
993
 
994
- public function do_pings($new_status, $old_status, $post)
995
  {
996
  $sitemaps = $this->get_sitemaps();
997
  $to_ping = $this->get_ping();
@@ -1004,7 +1002,7 @@ class XMLSitemapFeed {
1004
  if ( !empty($news_tags['post_type']) && is_array($news_tags['post_type']) && in_array($post->post_type,$news_tags['post_type']) ) {
1005
 
1006
  // TODO: check if we're posting to an included category!
1007
-
1008
  // are we publishing?
1009
  if ( $old_status != 'publish' && $new_status == 'publish' ) {
1010
  // loop through ping targets
@@ -1058,17 +1056,17 @@ class XMLSitemapFeed {
1058
  * CLEARING & PURGING
1059
  */
1060
 
1061
- public function clear_settings()
1062
  {
1063
  delete_option('xmlsf_version');
1064
  foreach ( $this->defaults() as $option => $settings ) {
1065
  delete_option('xmlsf_'.$option);
1066
  }
1067
-
1068
  if ( defined('WP_DEBUG') && WP_DEBUG )
1069
  error_log('XML Sitemap Feeds settings cleared');
1070
  }
1071
-
1072
  function cache_flush($new_status, $old_status)
1073
  {
1074
  // are we moving the post in or out of published status?
@@ -1078,7 +1076,7 @@ class XMLSitemapFeed {
1078
  }
1079
  }
1080
 
1081
- public function nginx_helper_purge_urls( $urls = array(), $redis = false )
1082
  {
1083
  // are permalinks set, blog public and $urls an array?
1084
  if ( '' == get_option('permalink_structure') || '1' != get_option('blog_public') || ! is_array( $urls ) )
@@ -1095,13 +1093,13 @@ class XMLSitemapFeed {
1095
  foreach ( $this->get_sitemaps() as $pretty ) {
1096
 
1097
  if ( 'sitemap.xml' == $pretty ) {
1098
-
1099
  // add home sitemap
1100
  $urls[] = parse_url( $this->get_index_url('home'), PHP_URL_PATH);
1101
 
1102
  // add public post types sitemaps
1103
  foreach ( $this->have_post_types() as $post_type ) {
1104
- $archive = !empty($post_type['archive']) ? $post_type['archive'] : '';
1105
  foreach ( $this->get_archives($post_type['name'],$archive) as $url )
1106
  $urls[] = parse_url( $url, PHP_URL_PATH);
1107
  }
@@ -1136,9 +1134,9 @@ class XMLSitemapFeed {
1136
  * INITIALISATION
1137
  */
1138
 
1139
- public function upgrade($old_version)
1140
  {
1141
- // rewrite rules not available on plugins_loaded
1142
  // and don't flush rules from init as Polylang chokes on that
1143
  // just remove the db option and let WP regenerate them when ready...
1144
  delete_option('rewrite_rules');
@@ -1151,7 +1149,7 @@ class XMLSitemapFeed {
1151
  delete_option($this->prefix.'robots');
1152
  add_option($this->prefix.'robots', $robot_rules, '', 'no');
1153
  }
1154
-
1155
  if ( version_compare('4.4.1', $old_version, '>') ) {
1156
  // register location taxonomies then delete all terms
1157
  register_taxonomy( 'gn-location-3', null );
@@ -1189,7 +1187,7 @@ class XMLSitemapFeed {
1189
  $time = strtotime($date);
1190
  $arr[$pretty] = (int)$time < time() ? $time : '';
1191
  }
1192
- // and set array
1193
  $ping[$se]['pong'] = $arr;
1194
  }
1195
  }
@@ -1203,18 +1201,38 @@ class XMLSitemapFeed {
1203
 
1204
  if ( defined('WP_DEBUG') && WP_DEBUG )
1205
  error_log('XML Sitemap Feeds upgraded from '.$old_version.' to '.XMLSF_VERSION);
1206
-
1207
  }
1208
 
1209
- public function plugins_loaded()
1210
  {
1211
  // TEXT DOMAIN
1212
  if ( is_admin() ) // text domain needed on admin only
1213
  load_plugin_textdomain('xml-sitemap-feed', false, dirname(dirname(plugin_basename( __FILE__ ))) . '/languages' );
1214
-
1215
  }
1216
 
1217
- public function init()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1218
  {
1219
  // UPGRADE
1220
  $version = get_option('xmlsf_version', 0);
@@ -1224,7 +1242,7 @@ class XMLSitemapFeed {
1224
 
1225
  // TAXONOMIES
1226
  $sitemaps = $this->get_sitemaps();
1227
-
1228
  if (isset($sitemaps['sitemap-news'])) {
1229
  // register the taxonomies
1230
  $this->register_gn_taxonomies();
@@ -1238,38 +1256,38 @@ class XMLSitemapFeed {
1238
  }
1239
  }
1240
 
1241
- public function admin_init()
1242
  {
1243
  // CATCH TRANSIENT for reset
1244
  if (delete_transient('xmlsf_clear_settings'))
1245
  $this->clear_settings();
1246
-
1247
  // CATCH TRANSIENT for flushing rewrite rules after the sitemaps setting has changed
1248
  if (delete_transient('xmlsf_flush_rewrite_rules'))
1249
  $this->flush_rules();
1250
-
1251
  // Include the admin class file
1252
  include_once( dirname(__FILE__) . '/admin.php' );
1253
 
1254
  }
1255
 
1256
- public function flush_rules($hard = false)
1257
- {
1258
  // did you flush already?
1259
  if ($this->yes_mother)
1260
  return; // yes, mother!
1261
 
1262
  global $wp_rewrite;
1263
  // don't need hard flush by default
1264
- $wp_rewrite->flush_rules($hard);
1265
 
1266
  if ( defined('WP_DEBUG') && WP_DEBUG )
1267
  error_log('XML Sitemap Feeds rewrite rules flushed');
1268
 
1269
  $this->yes_mother = true;
1270
  }
1271
-
1272
- public function register_gn_taxonomies()
1273
  {
1274
  $defaults = $this->defaults('news_tags');
1275
  $options = $this->get_option('news_tags');
@@ -1295,9 +1313,9 @@ class XMLSitemapFeed {
1295
  )
1296
  ));
1297
  }
1298
-
1299
  // for debugging
1300
- public function _e_usage()
1301
  {
1302
  if (defined('WP_DEBUG') && WP_DEBUG == true) {
1303
  echo '<!-- Queries executed '.get_num_queries();
@@ -1311,53 +1329,52 @@ class XMLSitemapFeed {
1311
  * CONSTRUCTOR
1312
  */
1313
 
1314
- function __construct()
1315
  {
1316
  // sitemap element filters
1317
  add_filter('the_title_xmlsitemap', 'strip_tags');
1318
  add_filter('the_title_xmlsitemap', 'ent2ncr', 8);
1319
  add_filter('the_title_xmlsitemap', 'esc_html');
1320
  add_filter('bloginfo_xmlsitemap', 'ent2ncr', 8);
1321
-
1322
  // TEMPLATE
1323
  add_filter('template', array($this, 'template'), 0);
1324
-
1325
  // REQUEST main filtering function
1326
  add_filter('request', array($this, 'filter_request'), 1 );
1327
-
1328
  // TEXT DOMAIN, UPGRADE PROCESS ...
1329
  add_action('plugins_loaded', array($this,'plugins_loaded'), 11 );
1330
 
1331
  // REWRITES
1332
  add_action('generate_rewrite_rules', array($this, 'rewrite_rules') );
1333
  add_filter('user_trailingslashit', array($this, 'trailingslash') );
1334
-
1335
  // TAXONOMY
1336
  add_action('init', array($this,'init'), 0 );
1337
-
1338
  // REGISTER SETTINGS, SETTINGS FIELDS...
1339
  add_action('admin_init', array($this,'admin_init'), 0);
1340
-
1341
  // ROBOTSTXT
1342
  add_action('do_robotstxt', array($this, 'robots'), 0 );
1343
  add_filter('robots_txt', array($this, 'robots_txt'), 0 );
1344
-
1345
  // PINGING
1346
- add_action('transition_post_status', array($this, 'do_pings'), 10, 3);
1347
 
1348
  // CLEAR OBJECT CACHE
1349
- add_action('transition_post_status', array($this, 'cache_flush'), 99, 2);
1350
-
1351
  // NGINX HELPER PURGE URLS
1352
  add_filter('rt_nginx_helper_purge_urls', array($this, 'nginx_helper_purge_urls'), 10, 2);
1353
-
1354
  // ACTIVATION
1355
- // activation currently same as upgrade routine based on db version check
1356
- //register_activation_hook( XMLSF_PLUGIN_BASENAME, array($this, 'activate') );
1357
-
1358
  // DE-ACTIVATION
1359
  register_deactivation_hook( XMLSF_PLUGIN_BASENAME, array($this, 'flush_rules') );
1360
-
1361
  }
1362
  }
1363
 
10
  /**
11
  * Plugin variables
12
  */
13
+
14
  // Pretty permalinks base name
15
  public $base_name = 'sitemap';
16
 
17
  // Pretty permalinks extension
18
  public $extension = 'xml';
19
+
20
  // Database options prefix
21
  private $prefix = 'xmlsf_';
22
+
23
  // Flushed flag
24
  private $yes_mother = false;
25
 
26
  private $defaults = array();
27
  private $disabled_post_types = array('attachment'); /* attachment post type is disabled... images are included via tags in the post and page sitemaps */
28
  private $disabled_taxonomies = array('post_format'); /* post format taxonomy is brute force disabled for now; might come back... */
29
+ private $gn_genres = array(
30
+ 'PressRelease',
31
+ 'Satire',
32
+ 'Blog',
33
+ 'OpEd',
34
+ 'Opinion',
35
+ 'UserGenerated'
36
  );
37
+
38
  // Global values used for priority and changefreq calculation
39
  private $domain;
40
  private $firstdate;
43
  private $termmodified = array();
44
  private $blogpage;
45
  private $images = array();
46
+
47
  // make some private parts public ;)
48
+
49
+ public function prefix()
50
  {
51
  return $this->prefix;
52
  }
53
 
54
+ public function gn_genres()
55
  {
56
  return $this->gn_genres;
57
  }
58
 
59
+ public function domain()
60
  {
61
  // allowed domain
62
  if (empty($this->domain)) {
63
+ $url_parsed = parse_url(home_url()); // second parameter PHP_URL_HOST for only PHP5 + ...
64
  $this->domain = str_replace("www.","",$url_parsed['host']);
65
  }
66
+
67
  return $this->domain;
68
  }
69
 
70
  // default options
71
+ private function set_defaults()
72
  {
73
  // sitemaps
74
  if ( '1' == get_option('blog_public') )
93
  'dynamic_priority' => '',
94
  'tags' => array('image' => 'attached'/*,'video' => ''*/)
95
  );
96
+ }
97
 
98
  $active_arr = array('post','page');
99
+
100
  foreach ( $active_arr as $name )
101
  if ( isset($this->defaults['post_types'][$name]) )
102
  $this->defaults['post_types'][$name]['active'] = '1';
103
+
104
  if ( isset($this->defaults['post_types']['post']) ) {
105
  if (wp_count_posts('post')->publish > 500)
106
  $this->defaults['post_types']['post']['archive'] = 'yearly';
115
 
116
  // taxonomies
117
  $this->defaults['taxonomies'] = array(); // by default do not include any taxonomies
118
+
119
  // news sitemap settings
120
  $this->defaults['news_sitemap'] = array();
121
 
154
  $this->defaults['robots'] = "";
155
  // Old rules "Disallow: */xmlrpc.php\nDisallow: */wp-*.php\nDisallow: */trackback/\nDisallow: *?wptheme=\nDisallow: *?comments=\nDisallow: *?replytocom\nDisallow: */comment-page-\nDisallow: *?s=\nDisallow: */wp-content/\nAllow: */wp-content/uploads/\n";
156
  // Better is to set <meta name="robots" content="noindex, follow"> or send X-Robots-Tag header. TODO !!
157
+
158
  // additional urls
159
  $this->defaults['urls'] = array();
160
 
163
 
164
  // additional allowed domains
165
  $this->defaults['domains'] = array();
166
+
167
  // news sitemap tags settings
168
+ $this->defaults['news_tags'] = array(
169
  'name' => '',
170
  'post_type' => array('post'),
171
  'categories' => '',
172
  'image' => 'featured',
173
+ 'access' => array(
174
+ 'default' => '',
175
  //'private' => 'Registration', // private posts do not show up in feeds when not logged in. no point in setting access level then...
176
+ 'password' => 'Subscription'
 
 
 
 
177
  ),
178
+ 'genres' => array(
179
+ 'active' => '1',
180
+ 'default' => array('Blog')
181
+ ),
182
+ 'keywords' => array(
183
+ 'from' => 'category',
184
+ 'default' => ''
185
  )
186
  );
187
  }
189
  /**
190
  * QUERY FUNCTIONS
191
  */
192
+
193
+ public function defaults($key = false)
194
  {
195
  if (empty($this->defaults))
196
  $this->set_defaults();
203
 
204
  return apply_filters( 'xmlsf_defaults', $return, $key );
205
  }
206
+
207
+ public function get_option($option)
208
  {
209
  return get_option($this->prefix.$option, $this->defaults($option));
210
  }
211
+
212
+ public function get_sitemaps()
213
  {
214
  $return = $this->get_option('sitemaps');
215
+
216
  // make sure it's an array we are returning
217
  return (!empty($return)) ? (array)$return : array();
218
  }
219
+
220
+ public function get_ping()
221
+ {
222
  $return = $this->get_option('ping');
223
+
224
  // make sure it's an array we are returning
225
  return (!empty($return)) ? (array)$return : array();
226
  }
227
+
228
+ public function disabled_post_types()
229
+ {
230
  return $this->disabled_post_types;
231
 
232
  }
233
+
234
+ public function disabled_taxonomies()
235
+ {
236
  return $this->disabled_taxonomies;
237
 
238
  }
239
+
240
+ public function get_post_types()
241
+ {
242
  $return = $this->get_option('post_types');
243
 
244
  // make sure it's an array we are returning
245
  return (!empty($return)) ? (array)$return : array();
246
  }
247
 
248
+ public function have_post_types()
249
+ {
250
  $return = array();
251
 
252
  foreach ( $this->get_post_types() as $type => $values ) {
262
  // make sure it's an array we are returning
263
  return (!empty($return)) ? (array)$return : array();
264
  }
265
+
266
+ public function get_taxonomies()
267
  {
268
  $return = $this->get_option('taxonomies');
269
 
270
  // make sure it's an array we are returning
271
  return (!empty($return)) ? (array)$return : array();
272
  }
273
+
274
+ public function get_custom_sitemaps()
275
  {
276
  $return = $this->get_option('custom_sitemaps');
277
 
283
  return explode("\n",$return);
284
  } else {
285
  return array();
286
+ }
287
  }
288
 
289
+ public function get_urls()
290
  {
291
  $return = $this->get_option('urls');
292
 
298
  return explode("\n",$return);
299
  } else {
300
  return array();
301
+ }
302
  }
303
 
304
+ public function get_domains()
305
  {
306
  $domains = $this->get_option('domains');
307
  if (!empty($domains) && is_array($domains))
308
  return array_merge( array( $this->domain() ), $domains );
309
+ else
310
  return array( $this->domain() );
311
  }
312
 
313
+ public function get_archives($post_type = 'post', $type = '')
314
  {
315
  global $wpdb;
316
  $return = array();
317
  if ( 'monthly' == $type ) {
318
+ $query = "SELECT YEAR(post_date) AS `year`, LPAD(MONTH(post_date),2,'0') AS `month`, count(ID) as posts FROM $wpdb->posts WHERE post_type = '$post_type' AND post_status = 'publish' GROUP BY YEAR(post_date), MONTH(post_date) ORDER BY post_date DESC";
319
  $key = md5($query);
320
  $cache = wp_cache_get( 'xmlsf_get_archives' , 'general');
321
  if ( !isset( $cache[ $key ] ) ) {
352
  return $return;
353
  }
354
 
355
+ public function get_robots()
356
  {
357
  return ( $robots = $this->get_option('robots') ) ? $robots : '';
358
  }
359
 
360
+ public function do_tags( $type = 'post' )
361
+ {
362
  $return = $this->get_post_types();
363
 
364
  // make sure it's an array we are returning
365
+ return (
366
+ is_string($type) &&
367
+ isset($return[$type]) &&
368
+ !empty($return[$type]['tags'])
369
  ) ? (array)$return[$type]['tags'] : array();
370
  }
371
+
372
+ public function is_home($id)
373
  {
374
  if ( empty($this->blogpage) ) {
375
  $blogpage = get_option('page_for_posts');
376
+
377
  if ( !empty($blogpage) ) {
378
  global $polylang;
379
  if ( isset($polylang) )
387
 
388
  return in_array($id,$this->blogpage);
389
  }
390
+
391
  /**
392
  * TEMPLATE FUNCTIONS
393
  */
394
+
395
+ public function modified($sitemap = 'post_type', $term = '')
396
  {
397
  if ('post_type' == $sitemap) :
398
 
416
  if ( isset($lastcomment[0]->comment_date_gmt) )
417
  if ( mysql2date( 'U', $lastcomment[0]->comment_date_gmt, false ) > mysql2date( 'U', $postmodified, false ) )
418
  $postmodified = $lastcomment[0]->comment_date_gmt;
419
+
420
  // make sure lastmod is not older than publication date (happens on scheduled posts)
421
  if ( isset($post->post_date_gmt) && strtotime($post->post_date_gmt) > strtotime($postmodified) )
422
  $postmodified = $post->post_date_gmt;
423
 
424
  $this->postmodified[$post->ID] = $postmodified;
425
  }
426
+
427
  return $this->postmodified[$post->ID];
428
 
429
  elseif ( !empty($term) ) :
430
 
431
+ if ( is_object($term) ) {
432
  if ( !isset($this->termmodified[$term->term_id]) ) {
433
  // get the latest post in this taxonomy item, to use its post_date as lastmod
434
  $posts = get_posts ( array(
435
  'post_type' => 'any',
436
+ 'numberposts' => 1,
437
+ 'no_found_rows' => true,
438
+ 'update_post_meta_cache' => false,
439
+ 'update_post_term_cache' => false,
440
  'update_cache' => false,
441
  'tax_query' => array(
442
  array(
454
  $obj = get_taxonomy($term);
455
  return get_lastdate( 'gmt', $obj->object_type );
456
  // uses get_lastdate() function defined in xml-sitemap/hacks.php !
457
+ // which is a shortcut: returns last post date, not last modified date...
458
+ // TODO find the long way home: take tax type, get all terms,
459
+ // do tax_query with all terms for one post and get its lastmod date
460
  // ... or can 'terms' in tax_query be empty?
461
  }
462
 
467
  endif;
468
  }
469
 
470
+ public function get_images($sitemap = '')
471
  {
472
  global $post;
473
  if ( empty($this->images[$post->ID]) ) {
484
  if ($attachments) {
485
  foreach ( $attachments as $attachment ) {
486
  $url = wp_get_attachment_image_src( $attachment->ID, 'full' );
487
+ $this->images[$post->ID][] = array(
488
  'loc' => esc_attr( esc_url_raw( $url[0] ) ), // use esc_attr() to entity escape & here ?? esc_url() creates &#038; which is not what we want...
489
  'title' => apply_filters( 'the_title_xmlsitemap', $attachment->post_title ),
490
  'caption' => apply_filters( 'the_title_xmlsitemap', $attachment->post_excerpt )
495
  if (has_post_thumbnail( $post->ID ) ) {
496
  $attachment = get_post(get_post_thumbnail_id( $post->ID ));
497
  $url = wp_get_attachment_image_src( $attachment->ID, 'full' );
498
+ $this->images[$post->ID][] = array(
499
  'loc' => esc_attr( esc_url_raw( $url[0] ) ),
500
  'title' => apply_filters( 'the_title_xmlsitemap', $attachment->post_title ),
501
  'caption' => apply_filters( 'the_title_xmlsitemap', $attachment->post_excerpt )
505
  }
506
  return ( isset($this->images[$post->ID]) ) ? $this->images[$post->ID] : false;
507
  }
508
+
509
+ public function get_lastmod($sitemap = 'post_type', $term = '')
510
  {
511
  $return = trim(mysql2date('Y-m-d\TH:i:s+00:00', $this->modified($sitemap,$term), false));
512
  return !empty($return) ? "\t<lastmod>".$return."</lastmod>\r\n\t" : '';
513
  }
514
 
515
+ public function get_changefreq($sitemap = 'post_type', $term = '')
516
  {
517
  $modified = trim($this->modified($sitemap,$term));
518
 
519
  if (empty($modified))
520
  return 'weekly';
521
+
522
  $lastactivityage = ( gmdate('U') - mysql2date( 'U', $modified, false ) ); // post age
523
+
524
+ if ( ($lastactivityage/86400) < 1 ) { // last activity less than 1 day old
525
  $changefreq = 'hourly';
526
+ } else if ( ($lastactivityage/86400) < 7 ) { // last activity less than 1 week old
527
  $changefreq = 'daily';
528
+ } else if ( ($lastactivityage/86400) < 30 ) { // last activity less than one month old
529
  $changefreq = 'weekly';
530
+ } else if ( ($lastactivityage/86400) < 365 ) { // last activity less than 1 year old
531
  $changefreq = 'monthly';
532
  } else {
533
  $changefreq = 'yearly'; // over a year old...
534
+ }
535
 
536
  return $changefreq;
537
  }
538
 
539
+ public function get_priority($sitemap = 'post_type', $term = '')
540
  {
541
  if ( 'post_type' == $sitemap ) :
542
  global $post;
543
  $options = $this->get_post_types();
544
  $defaults = $this->defaults('post_types');
545
  $priority_meta = get_metadata('post', $post->ID, '_xmlsf_priority' , true);
546
+
547
  if ( !empty($priority_meta) || $priority_meta == '0' ) {
548
+
549
  $priority = floatval(str_replace(",",".",$priority_meta));
550
+
551
  } elseif ( !empty($options[$post->post_type]['dynamic_priority']) ) {
552
 
553
  $post_modified = mysql2date('U',$post->post_modified_gmt, false);
554
+
555
  if ( empty($this->lastmodified) )
556
+ $this->lastmodified = mysql2date('U',get_lastmodified('GMT',$post->post_type),false);
557
+ // last posts or page modified date in Unix seconds
558
  // uses get_lastmodified() function defined in xml-sitemap/hacks.php !
559
+
560
  if ( empty($this->firstdate) )
561
+ $this->firstdate = mysql2date('U',get_firstdate('GMT',$post->post_type),false);
562
  // uses get_firstdate() function defined in xml-sitemap/hacks.php !
563
+
564
  if ( isset($options[$post->post_type]['priority']) )
565
  $priority_value = floatval(str_replace(",",".",$options[$post->post_type]['priority']));
566
  else
567
  $priority_value = floatval($defaults[$post->post_type]['priority']);
568
+
569
  // reduce by age
570
  // NOTE : home/blog page gets same treatment as sticky post
571
  if ( is_sticky($post->ID) || $this->is_home($post->ID) )
579
  } else {
580
 
581
  $priority = ( isset($options[$post->post_type]['priority']) && is_numeric($options[$post->post_type]['priority']) ) ? $options[$post->post_type]['priority'] : $defaults[$post->post_type]['priority'];
582
+
583
  }
584
 
585
  elseif ( ! empty($term) ) :
602
  $priority = 0.5;
603
 
604
  endif;
605
+
606
  // make sure we're not below zero
607
  if ($priority < 0)
608
  $priority = 0;
614
  return number_format($priority,1);
615
  }
616
 
617
+ public function get_home_urls()
618
  {
619
  $urls = array();
620
+
621
  global $polylang,$q_config;
622
 
623
+ if ( isset($polylang) )
624
  foreach ($polylang->get_languages_list() as $term)
625
  $urls[] = $polylang->get_home_url($term);
626
  else
627
  $urls[] = home_url();
628
+
629
  return $urls;
630
  }
631
 
632
+ public function get_excluded($post_type)
633
  {
634
  $exclude = array();
635
+
636
  if ( $post_type == 'page' && $id = get_option('page_on_front') ) {
637
  global $polylang;
638
  if ( isset($polylang) )
639
  $exclude += $polylang->get_translations('post', $id);
640
+ else
641
  $exclude[] = $id;
642
  }
643
+
644
  return $exclude;
645
  }
646
 
647
+ public function is_allowed_domain($url)
648
  {
649
  $domains = $this->get_domains();
650
  $return = false;
651
  $parsed_url = parse_url($url);
652
 
653
+ if (isset($parsed_url['host'])) {
654
  foreach( $domains as $domain ) {
655
  if( $parsed_url['host'] == $domain || strpos($parsed_url['host'],".".$domain) !== false ) {
656
  $return = true;
662
  return apply_filters( 'xmlsf_allowed_domain', $return );
663
  }
664
 
665
+ public function get_index_url( $sitemap = 'home', $type = false, $param = false )
666
  {
667
+ $root = esc_url( trailingslashit(home_url()) );
668
  $name = $this->base_name.'-'.$sitemap;
669
+
670
  if ( $type )
671
+ $name .= '-'.$type;
672
 
673
  if ( '' == get_option('permalink_structure') || '1' != get_option('blog_public')) {
674
  $name = '?feed='.$name;
677
  $name .= $param ? '.'.$param : '';
678
  $name .= '.'.$this->extension;
679
  }
680
+
681
  return $root . $name;
682
  }
683
+
684
 
685
  /**
686
+ * ROBOTSTXT
687
  */
688
 
689
  // add sitemap location in robots.txt generated by WP
690
+ public function robots($output)
691
+ {
692
  echo "\n# XML Sitemap & Google News Feeds version ".XMLSF_VERSION." - http://status301.net/wordpress-plugins/xml-sitemap-feed/";
693
 
694
  if ( '1' != get_option('blog_public') ) {
695
  echo "\n# XML Sitemaps are disabled. Please see Site Visibility on Settings > Reading.";
696
  } else {
697
+ foreach ( $this->get_sitemaps() as $pretty )
698
  echo "\nSitemap: " . trailingslashit(get_bloginfo('url')) . $pretty;
699
 
700
  if ( empty($pretty) )
702
  }
703
  echo "\n\n";
704
  }
705
+
706
  // add robots.txt rules
707
+ public function robots_txt($output)
708
  {
709
  return $output . $this->get_option('robots') . "\n\n";
710
  }
711
+
712
  /**
713
  * REWRITES
714
  */
719
  *
720
  * @param string $request
721
  */
722
+ public function trailingslash($request)
 
723
  {
724
  if (pathinfo($request, PATHINFO_EXTENSION)) {
725
  return untrailingslashit($request);
732
  *
733
  * @param string $wp_rewrite
734
  */
735
+ public function rewrite_rules($wp_rewrite)
 
736
  {
737
  $xmlsf_rules = array();
738
  $sitemaps = $this->get_sitemaps();
743
  if (!empty($sitemaps['sitemap'])) {
744
  // home urls
745
  $xmlsf_rules[ $this->base_name . '-home\.' . $this->extension . '$' ] = $wp_rewrite->index . '?feed=sitemap-home';
746
+
747
  // add rules for post types (can be split by month or year)
748
  foreach ( $this->get_post_types() as $post_type ) {
749
  if ( isset($post_type['active']) && '1' == $post_type['active'] )
760
  $xmlsf_rules[ $this->base_name . '-custom\.' . $this->extension . '$' ] = $wp_rewrite->index . '?feed=sitemap-custom';
761
 
762
  }
763
+
764
  $wp_rewrite->rules = $xmlsf_rules + $wp_rewrite->rules;
765
  }
766
+
767
  /**
768
  * REQUEST FILTER
769
  */
776
  return $theme;
777
  }
778
 
779
+ public function filter_request( $request )
780
  {
781
  if ( isset($request['feed']) && strpos($request['feed'],'sitemap') == 0 ) {
782
 
783
  if ( $request['feed'] == 'sitemap' ) {
784
+
785
  // setup actions and filters
786
  add_action('do_feed_sitemap', array($this, 'load_template_index'), 10, 1);
787
 
792
  $defaults = $this->defaults('news_tags');
793
  $options = $this->get_option('news_tags');
794
  $news_post_type = isset($options['post_type']) && !empty($options['post_type']) ? $options['post_type'] : $defaults['post_type'];
795
+ if (empty($news_post_type)) $news_post_type = 'post';
796
+
797
  // disable caching
798
  define('DONOTCACHEPAGE', true);
799
+ define('DONOTCACHEDB', true);
800
+
801
  // setup template
802
  add_action('do_feed_sitemap-news', array($this, 'load_template_news'), 10, 1);
803
 
804
  // set up query filters
805
  // TODO: test 'gmt' against 'blog' against 'server'
806
+
807
  if ( function_exists('date_default_timezone_set') ) {
808
  date_default_timezone_set ( 'UTC' );
809
  $zone = 'gmt';
812
  }
813
  if ( get_lastdate($zone, $news_post_type) > date('Y-m-d H:i:s', strtotime('-48 hours')) ) {
814
  add_filter('post_limits', array($this, 'filter_news_limits'));
815
+ add_filter('posts_where', array($this, 'filter_news_where'), 10, 1);
816
  } else {
817
  add_filter('post_limits', array($this, 'filter_no_news_limits'));
818
  }
823
 
824
  // categories
825
  if ( isset($options['categories']) && is_array($options['categories']) )
826
+ $request['cat'] = implode(',',$options['categories']);
827
+
828
+ $request['post_status'] = 'publish';
829
  $request['no_found_rows'] = true;
830
 
831
  return $request;
896
  */
897
 
898
  // set up the sitemap index template
899
+ public function load_template_index()
900
  {
901
  load_template( dirname( __FILE__ ) . '/feed-sitemap.php' );
902
  }
903
 
904
  // set up the sitemap home page(s) template
905
+ public function load_template_base()
906
  {
907
  load_template( dirname( __FILE__ ) . '/feed-sitemap-home.php' );
908
  }
909
 
910
  // set up the post types sitemap template
911
+ public function load_template()
912
  {
913
  load_template( dirname( __FILE__ ) . '/feed-sitemap-post_type.php' );
914
  }
915
 
916
  // set up the taxonomy sitemap template
917
+ public function load_template_taxonomy()
918
  {
919
  load_template( dirname( __FILE__ ) . '/feed-sitemap-taxonomy.php' );
920
  }
921
 
922
  // set up the news sitemap template
923
+ public function load_template_news()
924
  {
925
  load_template( dirname( __FILE__ ) . '/feed-sitemap-news.php' );
926
  }
927
 
928
  // set up the news sitemap template
929
+ public function load_template_custom()
930
  {
931
  load_template( dirname( __FILE__ ) . '/feed-sitemap-custom.php' );
932
  }
936
  */
937
 
938
  // override default feed limit
939
+ public function filter_limits( $limits )
940
  {
941
  return 'LIMIT 0, 50000';
942
  }
943
 
944
  // override default feed limit for taxonomy sitemaps
945
+ public function filter_limits_taxonomy( $limits )
946
  {
947
  return 'LIMIT 0, 1';
948
  }
949
 
950
  // only posts from the last 48 hours
951
+ public function filter_news_where( $where = '' )
952
  {
953
  if ( function_exists('date_default_timezone_set') ) {
954
  date_default_timezone_set ( 'UTC' );
957
  return $where . " AND post_date > '" . date('Y-m-d H:i:s', strtotime('-48 hours')) . "'";
958
  }
959
  }
960
+
961
  // override default feed limit for GN
962
+ public function filter_news_limits( $limits )
963
  {
964
  return 'LIMIT 0, 1000';
965
  }
966
 
967
  // in case there is no news, just take the latest post
968
+ public function filter_no_news_limits( $limits )
969
  {
970
  return 'LIMIT 0, 1';
971
  }
974
  * PINGING
975
  */
976
 
977
+ public function ping($uri, $timeout = 3)
978
  {
979
  $options = array();
980
  $options['timeout'] = $timeout;
984
  if ( '200' == wp_remote_retrieve_response_code($response) )
985
  $succes = true;
986
  else
987
+ $succes = false;
988
 
989
  return $succes;
990
  }
991
 
992
+ public function do_pings($new_status, $old_status, $post)
993
  {
994
  $sitemaps = $this->get_sitemaps();
995
  $to_ping = $this->get_ping();
1002
  if ( !empty($news_tags['post_type']) && is_array($news_tags['post_type']) && in_array($post->post_type,$news_tags['post_type']) ) {
1003
 
1004
  // TODO: check if we're posting to an included category!
1005
+
1006
  // are we publishing?
1007
  if ( $old_status != 'publish' && $new_status == 'publish' ) {
1008
  // loop through ping targets
1056
  * CLEARING & PURGING
1057
  */
1058
 
1059
+ public function clear_settings()
1060
  {
1061
  delete_option('xmlsf_version');
1062
  foreach ( $this->defaults() as $option => $settings ) {
1063
  delete_option('xmlsf_'.$option);
1064
  }
1065
+
1066
  if ( defined('WP_DEBUG') && WP_DEBUG )
1067
  error_log('XML Sitemap Feeds settings cleared');
1068
  }
1069
+
1070
  function cache_flush($new_status, $old_status)
1071
  {
1072
  // are we moving the post in or out of published status?
1076
  }
1077
  }
1078
 
1079
+ public function nginx_helper_purge_urls( $urls = array(), $redis = false )
1080
  {
1081
  // are permalinks set, blog public and $urls an array?
1082
  if ( '' == get_option('permalink_structure') || '1' != get_option('blog_public') || ! is_array( $urls ) )
1093
  foreach ( $this->get_sitemaps() as $pretty ) {
1094
 
1095
  if ( 'sitemap.xml' == $pretty ) {
1096
+
1097
  // add home sitemap
1098
  $urls[] = parse_url( $this->get_index_url('home'), PHP_URL_PATH);
1099
 
1100
  // add public post types sitemaps
1101
  foreach ( $this->have_post_types() as $post_type ) {
1102
+ $archive = !empty($post_type['archive']) ? $post_type['archive'] : '';
1103
  foreach ( $this->get_archives($post_type['name'],$archive) as $url )
1104
  $urls[] = parse_url( $url, PHP_URL_PATH);
1105
  }
1134
  * INITIALISATION
1135
  */
1136
 
1137
+ public function upgrade($old_version)
1138
  {
1139
+ // rewrite rules not available on plugins_loaded
1140
  // and don't flush rules from init as Polylang chokes on that
1141
  // just remove the db option and let WP regenerate them when ready...
1142
  delete_option('rewrite_rules');
1149
  delete_option($this->prefix.'robots');
1150
  add_option($this->prefix.'robots', $robot_rules, '', 'no');
1151
  }
1152
+
1153
  if ( version_compare('4.4.1', $old_version, '>') ) {
1154
  // register location taxonomies then delete all terms
1155
  register_taxonomy( 'gn-location-3', null );
1187
  $time = strtotime($date);
1188
  $arr[$pretty] = (int)$time < time() ? $time : '';
1189
  }
1190
+ // and set array
1191
  $ping[$se]['pong'] = $arr;
1192
  }
1193
  }
1201
 
1202
  if ( defined('WP_DEBUG') && WP_DEBUG )
1203
  error_log('XML Sitemap Feeds upgraded from '.$old_version.' to '.XMLSF_VERSION);
1204
+
1205
  }
1206
 
1207
+ public function plugins_loaded()
1208
  {
1209
  // TEXT DOMAIN
1210
  if ( is_admin() ) // text domain needed on admin only
1211
  load_plugin_textdomain('xml-sitemap-feed', false, dirname(dirname(plugin_basename( __FILE__ ))) . '/languages' );
1212
+
1213
  }
1214
 
1215
+ public function activate()
1216
+ {
1217
+ // return if this is a multisite and we're not network activating
1218
+ if ( is_multisite() ) {
1219
+ if ( !is_network_admin() ) return;
1220
+ }
1221
+
1222
+ // is file.php included on plugin activation? if not, get_home_path()
1223
+ // is not available and we need to do:
1224
+ //require_once(ABSPATH . 'wp-admin/includes/file.php');
1225
+ $home_path = trailingslashit( get_home_path() );
1226
+
1227
+ // CHECK FOR STATIC SITEMAP FILES, DELETE IF EXIST
1228
+ $sitemaps = $this->get_sitemaps();
1229
+ foreach ( $sitemaps as $name => $pretty ) {
1230
+ if ( file_exists( $home_path . $pretty ) )
1231
+ unlink( $home_path . $pretty );
1232
+ }
1233
+ }
1234
+
1235
+ public function init()
1236
  {
1237
  // UPGRADE
1238
  $version = get_option('xmlsf_version', 0);
1242
 
1243
  // TAXONOMIES
1244
  $sitemaps = $this->get_sitemaps();
1245
+
1246
  if (isset($sitemaps['sitemap-news'])) {
1247
  // register the taxonomies
1248
  $this->register_gn_taxonomies();
1256
  }
1257
  }
1258
 
1259
+ public function admin_init()
1260
  {
1261
  // CATCH TRANSIENT for reset
1262
  if (delete_transient('xmlsf_clear_settings'))
1263
  $this->clear_settings();
1264
+
1265
  // CATCH TRANSIENT for flushing rewrite rules after the sitemaps setting has changed
1266
  if (delete_transient('xmlsf_flush_rewrite_rules'))
1267
  $this->flush_rules();
1268
+
1269
  // Include the admin class file
1270
  include_once( dirname(__FILE__) . '/admin.php' );
1271
 
1272
  }
1273
 
1274
+ public function flush_rules($hard = false)
1275
+ {
1276
  // did you flush already?
1277
  if ($this->yes_mother)
1278
  return; // yes, mother!
1279
 
1280
  global $wp_rewrite;
1281
  // don't need hard flush by default
1282
+ $wp_rewrite->flush_rules($hard);
1283
 
1284
  if ( defined('WP_DEBUG') && WP_DEBUG )
1285
  error_log('XML Sitemap Feeds rewrite rules flushed');
1286
 
1287
  $this->yes_mother = true;
1288
  }
1289
+
1290
+ public function register_gn_taxonomies()
1291
  {
1292
  $defaults = $this->defaults('news_tags');
1293
  $options = $this->get_option('news_tags');
1313
  )
1314
  ));
1315
  }
1316
+
1317
  // for debugging
1318
+ public function _e_usage()
1319
  {
1320
  if (defined('WP_DEBUG') && WP_DEBUG == true) {
1321
  echo '<!-- Queries executed '.get_num_queries();
1329
  * CONSTRUCTOR
1330
  */
1331
 
1332
+ function __construct()
1333
  {
1334
  // sitemap element filters
1335
  add_filter('the_title_xmlsitemap', 'strip_tags');
1336
  add_filter('the_title_xmlsitemap', 'ent2ncr', 8);
1337
  add_filter('the_title_xmlsitemap', 'esc_html');
1338
  add_filter('bloginfo_xmlsitemap', 'ent2ncr', 8);
1339
+
1340
  // TEMPLATE
1341
  add_filter('template', array($this, 'template'), 0);
1342
+
1343
  // REQUEST main filtering function
1344
  add_filter('request', array($this, 'filter_request'), 1 );
1345
+
1346
  // TEXT DOMAIN, UPGRADE PROCESS ...
1347
  add_action('plugins_loaded', array($this,'plugins_loaded'), 11 );
1348
 
1349
  // REWRITES
1350
  add_action('generate_rewrite_rules', array($this, 'rewrite_rules') );
1351
  add_filter('user_trailingslashit', array($this, 'trailingslash') );
1352
+
1353
  // TAXONOMY
1354
  add_action('init', array($this,'init'), 0 );
1355
+
1356
  // REGISTER SETTINGS, SETTINGS FIELDS...
1357
  add_action('admin_init', array($this,'admin_init'), 0);
1358
+
1359
  // ROBOTSTXT
1360
  add_action('do_robotstxt', array($this, 'robots'), 0 );
1361
  add_filter('robots_txt', array($this, 'robots_txt'), 0 );
1362
+
1363
  // PINGING
1364
+ add_action('transition_post_status', array($this, 'do_pings'), 10, 3);
1365
 
1366
  // CLEAR OBJECT CACHE
1367
+ add_action('transition_post_status', array($this, 'cache_flush'), 99, 2);
1368
+
1369
  // NGINX HELPER PURGE URLS
1370
  add_filter('rt_nginx_helper_purge_urls', array($this, 'nginx_helper_purge_urls'), 10, 2);
1371
+
1372
  // ACTIVATION
1373
+ register_activation_hook( XMLSF_PLUGIN_BASENAME, array($this, 'activate') );
1374
+
 
1375
  // DE-ACTIVATION
1376
  register_deactivation_hook( XMLSF_PLUGIN_BASENAME, array($this, 'flush_rules') );
1377
+
1378
  }
1379
  }
1380
 
includes/feed-sitemap-news.php CHANGED
@@ -157,6 +157,9 @@ if ( have_posts() ) :
157
  <news:keywords><?php echo $keywords; ?></news:keywords>
158
  <?php
159
  }
 
 
 
160
  ?>
161
  </news:news>
162
  <?php
157
  <news:keywords><?php echo $keywords; ?></news:keywords>
158
  <?php
159
  }
160
+
161
+ /* xmlsf_news_tags_after action hook */
162
+ do_action( 'xmlsf_news_tags_after' );
163
  ?>
164
  </news:news>
165
  <?php
readme.txt CHANGED
@@ -4,7 +4,7 @@ Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=ravan
4
  Tags: sitemap, xml sitemap, news sitemap, sitemap.xml, robots.txt, Google, Google News, Yahoo, Bing, , Yandex, Baidu, seo, feed, polylang, image sitemap
5
  Requires at least: 3.2
6
  Tested up to: 4.5
7
- Stable tag: 4.5.1
8
 
9
  XML and Google News Sitemaps to feed the hungry spiders. Multisite, WP Super Cache and Polylang compatible.
10
 
@@ -287,17 +287,21 @@ Thanks for sharing your translation :)
287
 
288
  == Screenshots ==
289
 
290
- 1. XML Sitemap feed viewed in a normal browser. For human eyes only ;)
291
  2. XML Sitemap source as read by search engines.
292
 
293
 
294
  == Upgrade Notice ==
295
 
296
- = 4.5.1 =
297
- Fix Persistent/Stored XSS vulnerability on admin page, thanks to Sneha Rajguru @Sneharajguru
298
 
299
  == Changelog ==
300
 
 
 
 
 
301
  = 4.5.1 =
302
  * fix Persistent/Stored XSS vulnerability on admin page, thanks to Sneha Rajguru @Sneharajguru
303
 
4
  Tags: sitemap, xml sitemap, news sitemap, sitemap.xml, robots.txt, Google, Google News, Yahoo, Bing, , Yandex, Baidu, seo, feed, polylang, image sitemap
5
  Requires at least: 3.2
6
  Tested up to: 4.5
7
+ Stable tag: 4.6
8
 
9
  XML and Google News Sitemaps to feed the hungry spiders. Multisite, WP Super Cache and Polylang compatible.
10
 
287
 
288
  == Screenshots ==
289
 
290
+ 1. XML Sitemap feed viewed in a normal browser. For your eyes only ;)
291
  2. XML Sitemap source as read by search engines.
292
 
293
 
294
  == Upgrade Notice ==
295
 
296
+ = 4.6 =
297
+ New action hook xmlsf_news_tags_after, attempt to remove conflicting static sitemap files on activation
298
 
299
  == Changelog ==
300
 
301
+ = 4.6 =
302
+ * NEW: xmlsf_news_tags_after action hook
303
+ * Attempt to remove static sitemap files left over by other sitemap plugins
304
+
305
  = 4.5.1 =
306
  * fix Persistent/Stored XSS vulnerability on admin page, thanks to Sneha Rajguru @Sneharajguru
307
 
xml-sitemap.php CHANGED
@@ -4,13 +4,13 @@ Plugin Name: XML Sitemap & Google News feeds
4
  Plugin URI: http://status301.net/wordpress-plugins/xml-sitemap-feed/
5
  Description: Feed the hungry spiders in compliance with the XML Sitemap and Google News protocols. Happy with the results? Please leave me a <strong><a href="https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=ravanhagen%40gmail%2ecom&item_name=XML%20Sitemap%20Feed&item_number=4%2e0&no_shipping=0&tax=0&bn=PP%2dDonationsBF&charset=UTF%2d8&lc=us">tip</a></strong> for continued development and support. Thanks :)
6
  Text Domain: xml-sitemap-feed
7
- Version: 4.5.1
8
  Author: RavanH
9
  Author URI: http://status301.net/
10
  */
11
 
12
- /* Copyright 2015 RavanH
13
- http://status301.net/
14
  mailto: ravanhagen@gmail.com
15
 
16
  This program is free software; you can redistribute it and/or modify
@@ -29,14 +29,17 @@ Author URI: http://status301.net/
29
  *
30
  * FILTERS
31
  * xmlsf_defaults -> Filters the default array values for different option groups.
32
- * xmlsf_allowed_domain -> Filters the response when checking the url against allowed domains.
33
  * Can be true or false.
34
- * the_title_xmlsitemap -> Filters the Google News publication name, title and keywords
35
  and Image title and caption tags
36
-
37
  * ACTIONS
38
- * none at this point, but feel free to request, suggest or submit one :)
39
- *
 
 
 
40
  */
41
 
42
  if(!empty($_SERVER['SCRIPT_FILENAME']) && 'xml-sitemap.php' == basename($_SERVER['SCRIPT_FILENAME']))
@@ -47,41 +50,41 @@ if(!empty($_SERVER['SCRIPT_FILENAME']) && 'xml-sitemap.php' == basename($_SERVER
47
  * CONSTANTS
48
  * -------------------- */
49
 
50
- define('XMLSF_VERSION', '4.5.1');
51
 
52
  define('XMLSF_PLUGIN_BASENAME', plugin_basename(__FILE__));
53
 
54
- /*
55
- * The following constants can be used to change plugin defaults
56
  * by defining them in wp-config.php
57
  */
58
 
59
- /*
60
- * XMLSF_NAME
61
- *
62
  * Pretty permalink name for the main sitemap (index)
63
  */
64
-
65
  if ( !defined('XMLSF_NAME') )
66
 
67
  define('XMLSF_NAME', 'sitemap.xml');
68
 
69
- /*
70
- * XMLSF_NEWS_NAME
71
- *
72
  * Pretty permalink name for the news sitemap
73
  */
74
-
75
  if ( !defined('XMLSF_NEWS_NAME') )
76
 
77
  define('XMLSF_NEWS_NAME', 'sitemap-news.xml');
78
 
79
- /*
80
- * XMLSF_MULTISITE_UNINSTALL
81
- *
82
  * Set this constant in wp-config.php if you want to allow looping over each site
83
  * in the network to run XMLSitemapFeed_Uninstall->uninstall() defined in uninstall.php
84
- *
85
  * Be careful: There is NO batch-processing so it does not scale on large networks!
86
  *
87
  * example:
@@ -92,7 +95,7 @@ if ( !defined('XMLSF_NEWS_NAME') )
92
  /* -------------------------------------
93
  * INCLUDE HACKS & CLASS
94
  * ------------------------------------- */
95
-
96
  $xmlsf_dir = dirname(__FILE__);
97
 
98
  if ( file_exists ( $xmlsf_dir.'/xml-sitemap-feed' ) )
4
  Plugin URI: http://status301.net/wordpress-plugins/xml-sitemap-feed/
5
  Description: Feed the hungry spiders in compliance with the XML Sitemap and Google News protocols. Happy with the results? Please leave me a <strong><a href="https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=ravanhagen%40gmail%2ecom&item_name=XML%20Sitemap%20Feed&item_number=4%2e0&no_shipping=0&tax=0&bn=PP%2dDonationsBF&charset=UTF%2d8&lc=us">tip</a></strong> for continued development and support. Thanks :)
6
  Text Domain: xml-sitemap-feed
7
+ Version: 4.6
8
  Author: RavanH
9
  Author URI: http://status301.net/
10
  */
11
 
12
+ /* Copyright 2015 RavanH
13
+ http://status301.net/
14
  mailto: ravanhagen@gmail.com
15
 
16
  This program is free software; you can redistribute it and/or modify
29
  *
30
  * FILTERS
31
  * xmlsf_defaults -> Filters the default array values for different option groups.
32
+ * xmlsf_allowed_domain -> Filters the response when checking the url against allowed domains.
33
  * Can be true or false.
34
+ * the_title_xmlsitemap -> Filters the Google News publication name, title and keywords
35
  and Image title and caption tags
36
+
37
  * ACTIONS
38
+ * xmlsf_news_tags_after -> Fired inside the Google News Sitemap loop at the end of the news
39
+ * tags, just before each closing </news:news> is generated. Can be used to
40
+ * echo custom tags or trigger another action in the background.
41
+ *
42
+ * feel free to request, suggest or submit more :)
43
  */
44
 
45
  if(!empty($_SERVER['SCRIPT_FILENAME']) && 'xml-sitemap.php' == basename($_SERVER['SCRIPT_FILENAME']))
50
  * CONSTANTS
51
  * -------------------- */
52
 
53
+ define('XMLSF_VERSION', '4.6');
54
 
55
  define('XMLSF_PLUGIN_BASENAME', plugin_basename(__FILE__));
56
 
57
+ /*
58
+ * The following constants can be used to change plugin defaults
59
  * by defining them in wp-config.php
60
  */
61
 
62
+ /*
63
+ * XMLSF_NAME
64
+ *
65
  * Pretty permalink name for the main sitemap (index)
66
  */
67
+
68
  if ( !defined('XMLSF_NAME') )
69
 
70
  define('XMLSF_NAME', 'sitemap.xml');
71
 
72
+ /*
73
+ * XMLSF_NEWS_NAME
74
+ *
75
  * Pretty permalink name for the news sitemap
76
  */
77
+
78
  if ( !defined('XMLSF_NEWS_NAME') )
79
 
80
  define('XMLSF_NEWS_NAME', 'sitemap-news.xml');
81
 
82
+ /*
83
+ * XMLSF_MULTISITE_UNINSTALL
84
+ *
85
  * Set this constant in wp-config.php if you want to allow looping over each site
86
  * in the network to run XMLSitemapFeed_Uninstall->uninstall() defined in uninstall.php
87
+ *
88
  * Be careful: There is NO batch-processing so it does not scale on large networks!
89
  *
90
  * example:
95
  /* -------------------------------------
96
  * INCLUDE HACKS & CLASS
97
  * ------------------------------------- */
98
+
99
  $xmlsf_dir = dirname(__FILE__);
100
 
101
  if ( file_exists ( $xmlsf_dir.'/xml-sitemap-feed' ) )