Version Description
Set access or exclude individual posts from Google News sitemap. Improved cache handling and Nginx Helper compatibility.
=
Download this release
Release Info
Developer | RavanH |
Plugin | XML Sitemap & Google News feeds |
Version | 4.5 |
Comparing to | |
See all releases |
Code changes from version 4.4.1 to 4.5
- includes/admin.php +95 -36
- includes/core.php +1364 -1305
- includes/feed-sitemap-news.php +23 -12
- includes/feed-sitemap.php +11 -14
- includes/xsl/sitemap-news.xsl +4 -1
- readme.txt +12 -6
- xml-sitemap.php +2 -2
includes/admin.php
CHANGED
@@ -19,12 +19,12 @@ class XMLSF_Admin extends XMLSitemapFeed {
|
|
19 |
$prefix = parent::prefix();
|
20 |
|
21 |
echo '<fieldset id="xmlsf_sitemaps"><legend class="screen-reader-text">'.__('XML Sitemaps','xml-sitemap-feed').'</legend>
|
22 |
-
<label><input type="checkbox" name="'.$prefix.'sitemaps[sitemap]" id="xmlsf_sitemaps_index" value="'.XMLSF_NAME.'" '.checked(isset($options['sitemap']), true, false).' '.disabled($disabled, true, false).' /> '.__('XML Sitemap Index','xml-sitemap-feed').'</label>';//xmlsf
|
23 |
if (isset($options['sitemap']))
|
24 |
echo '<span class="description"> – <a href="#xmlsf" id="xmlsf_link">'.translate('Settings').'</a> – <a href="'.trailingslashit(get_bloginfo('url')). ( ('' == get_option('permalink_structure')) ? '?feed=sitemap' : $options['sitemap'] ) .'" target="_blank">'.translate('View').'</a></span>';
|
25 |
|
26 |
echo '<br>
|
27 |
-
<label><input type="checkbox" name="'.$prefix.'sitemaps[sitemap-news]" id="xmlsf_sitemaps_news" value="'.XMLSF_NEWS_NAME.'" '.checked(isset($options['sitemap-news']), true, false).' '.disabled($disabled, true, false).' /> '.__('Google News Sitemap','xml-sitemap-feed').'</label>';
|
28 |
if (isset($options['sitemap-news']))
|
29 |
echo '<span class="description"> – <a href="#xmlnf" id="xmlnf_link">'.translate('Settings').'</a> – <a href="'.trailingslashit(get_bloginfo('url')). ( ('' == get_option('permalink_structure')) ? '?feed=sitemap-news' : $options['sitemap-news'] ) .'" target="_blank">'.translate('View').'</a></span>';
|
30 |
|
@@ -472,8 +472,8 @@ jQuery( document ).ready( function() {
|
|
472 |
$name = !empty($options['name']) ? $options['name'] : '';
|
473 |
echo '
|
474 |
<fieldset><legend class="screen-reader-text">'.__('Publication name','xml-sitemap-feed').'</legend>
|
475 |
-
<input type="text" name="'.parent::prefix().'news_tags[name]" id="xmlsf_news_name" value="'.$name.'" class="regular-text"> <span class="description">'.sprintf(__('By default, the general %s setting will be used.','xml-sitemap-feed'),'<a href="options-general.php">'.translate('Site Title').'</a>').'</span>
|
476 |
-
__('The publication name should match the name submitted on the Google News Publisher Center. If you wish to change it, please read <a href="https://support.google.com/news/publisher/answer/40402" target="_blank">Updated publication name</a>.') . '
|
477 |
</fieldset>';
|
478 |
}
|
479 |
|
@@ -586,14 +586,14 @@ jQuery( document ).ready( function() {
|
|
586 |
'>'.__('Attached images','xml-sitemap-feed').'</option>
|
587 |
';
|
588 |
echo '</select></label>
|
589 |
-
<p class="description">'.__('Note: Google News prefers at most one image per article in the News Sitemap. If multiple valid images are specified, the crawler will have to pick one arbitrarily. Images in News Sitemaps should be in jpeg or png format.','xml-sitemap-feed').' <a href="https://support.google.com/news/publisher/answer/
|
590 |
</fieldset>';
|
591 |
}
|
592 |
|
593 |
public function news_labels_field() {
|
594 |
echo '
|
595 |
<fieldset id="xmlsf_news_labels"><legend class="screen-reader-text">'.__('Source labels','xml-sitemap-feed').'</legend>' .
|
596 |
-
__('You can use the
|
597 |
<br><br>';
|
598 |
|
599 |
$options = parent::get_option('news_tags');
|
@@ -604,21 +604,21 @@ jQuery( document ).ready( function() {
|
|
604 |
$access_default = !empty($access['default']) ? $access['default'] : '';
|
605 |
$access_password = !empty($access['password']) ? $access['password'] : '';
|
606 |
echo '
|
607 |
-
<fieldset id="
|
608 |
-
'.sprintf(__('The
|
609 |
-
|
610 |
<ul>';
|
611 |
|
612 |
echo '
|
613 |
<li><label>'.__('Tag normal posts as','xml-sitemap-feed').' <select name="'.$prefix.'news_tags[access][default]" id="xmlsf_news_tags_access_default">
|
614 |
<option value="">'.translate('Public').'</option>
|
615 |
-
<option value="Registration" '.selected( "Registration" == $access_default, true, false).'>'.__('
|
616 |
-
<option value="Subscription" '.selected( "Subscription" == $access_default, true, false).'>'.__('
|
617 |
</select></label></li>';
|
618 |
echo '
|
619 |
<li><label>'.__('Tag Password Protected posts as','xml-sitemap-feed').' <select name="'.$prefix.'news_tags[access][password]" id="xmlsf_news_tags_access_password">
|
620 |
-
<option value="Registration" '.selected( "Registration" == $access_password, true, false).'>'.__('
|
621 |
-
<option value="Subscription" '.selected( "Subscription" == $access_password, true, false).'>'.__('
|
622 |
</select></label></li>';
|
623 |
echo '
|
624 |
</ul>
|
@@ -629,11 +629,9 @@ jQuery( document ).ready( function() {
|
|
629 |
$genres = !empty($options['genres']) ? $options['genres'] : array();
|
630 |
$genres_default = !empty($genres['default']) ? (array)$genres['default'] : array();
|
631 |
|
632 |
-
$count = count($gn_genres);
|
633 |
-
|
634 |
echo '
|
635 |
-
<fieldset id="
|
636 |
-
'.__('The
|
637 |
echo '<input type="hidden" name="'.$prefix.'news_tags[genres][active]" value="';
|
638 |
echo !empty($genres['active']) ? $genres['active'] : '';
|
639 |
echo '" />';
|
@@ -644,8 +642,8 @@ jQuery( document ).ready( function() {
|
|
644 |
*/
|
645 |
echo '
|
646 |
<ul>
|
647 |
-
<li><label>'.__('Default genre:','xml-sitemap-feed').'<br><select multiple name="'.$prefix.'news_tags[genres][default][]" id="xmlsf_news_tags_genres_default" size="'
|
648 |
-
foreach ( $gn_genres as $
|
649 |
echo '
|
650 |
<option value="'.$name.'" '.selected( in_array($name,$genres_default), true, false ).'>'.$name.'</option>';
|
651 |
echo '
|
@@ -655,17 +653,17 @@ jQuery( document ).ready( function() {
|
|
655 |
<p class="description">'.__('Use the Ctrl/Cmd key plus click to select more than one or to deselect.','xml-sitemap-feed').' '.sprintf(__('Read more about source labels on %s','xml-sitemap-feed'),'<a href="https://support.google.com/news/publisher/answer/4582731" target="_blank">'.__('What does each source label mean?','xml-sitemap-feed').'</a>').'</p>
|
656 |
</fieldset>';
|
657 |
|
658 |
-
}
|
659 |
|
660 |
public function news_keywords_field() {
|
661 |
$options = parent::get_option('news_tags');
|
662 |
-
$prefix = parent::prefix()
|
663 |
|
664 |
$keywords = !empty($options['keywords']) ? $options['keywords'] : array();
|
665 |
$keywords_from = !empty($keywords['from']) ? $keywords['from'] : '';
|
666 |
echo '
|
667 |
-
<fieldset id="xmlsf_news_keywords"><legend class="screen-reader-text"
|
668 |
-
'.__('The
|
669 |
<ul>
|
670 |
<li><label>'.sprintf(__('Use %s for topics.','xml-sitemap-feed'),' <select name="'.$prefix.'news_tags[keywords][from]" id="xmlsf_news_tags_keywords_from">
|
671 |
<option value="">'.translate('None').'</option>
|
@@ -815,9 +813,15 @@ jQuery( document ).ready( function() {
|
|
815 |
$line = trim($line);
|
816 |
$parsed_url = parse_url(trim(filter_var($line,FILTER_SANITIZE_URL)));
|
817 |
// Before PHP version 5.4.7, parse_url will return the domain as path when scheme is omitted so we do:
|
818 |
-
|
819 |
-
|
820 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
821 |
// filter out empties and default domain
|
822 |
if(!empty($domain) && $domain !== $default && strpos($domain,".".$default) === false)
|
823 |
$sanitized[] = $domain;
|
@@ -844,10 +848,11 @@ jQuery( document ).ready( function() {
|
|
844 |
*/
|
845 |
|
846 |
/* Adds a box to the side column */
|
847 |
-
public function
|
848 |
{
|
849 |
-
//
|
850 |
foreach (parent::get_post_types() as $post_type) {
|
|
|
851 |
if (isset($post_type["active"]))
|
852 |
add_meta_box(
|
853 |
'xmlsf_section',
|
@@ -857,6 +862,18 @@ jQuery( document ).ready( function() {
|
|
857 |
'side'
|
858 |
);
|
859 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
860 |
}
|
861 |
|
862 |
public function meta_box($post)
|
@@ -866,14 +883,14 @@ jQuery( document ).ready( function() {
|
|
866 |
|
867 |
// The actual fields for data entry
|
868 |
// Use get_post_meta to retrieve an existing value from the database and use the value for the form
|
869 |
-
$
|
870 |
$priority = get_post_meta( $post->ID, '_xmlsf_priority', true );
|
871 |
$disabled = '';
|
872 |
|
873 |
// disable options and (visibly) set excluded to true for private posts
|
874 |
if ( 'private' == $post->post_status ) {
|
875 |
$disabled = ' disabled="disabled"';
|
876 |
-
$
|
877 |
}
|
878 |
|
879 |
// disable options and (visibly) set priority to 1 for front page
|
@@ -882,16 +899,46 @@ jQuery( document ).ready( function() {
|
|
882 |
$priority = '1'; // force excluded to true for private posts
|
883 |
}
|
884 |
|
885 |
-
echo '<p><label><input type="checkbox" name="xmlsf_exclude" id="xmlsf_exclude" value="1"'.checked(!empty($
|
886 |
_e('Exclude from XML Sitemap','xml-sitemap-feed');
|
887 |
echo '</label></p>';
|
888 |
|
889 |
echo '<p><label>';
|
890 |
_e('Priority','xml-sitemap-feed');
|
891 |
echo ' <input type="number" step="0.1" min="0" max="1" name="xmlsf_priority" id="xmlsf_priority" value="'.$priority.'" class="small-text"'.$disabled.'></label> <span class="description">';
|
892 |
-
printf(__('Leave empty for automatic Priority as configured on %1$s > %2$s.','xml-sitemap-feed'),translate('Settings'),translate('Reading'));
|
893 |
echo '</span></p>';
|
894 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
895 |
|
896 |
/* When the post is saved, save our meta data */
|
897 |
function save_metadata( $post_id )
|
@@ -916,6 +963,19 @@ jQuery( document ).ready( function() {
|
|
916 |
delete_post_meta($post_id, '_xmlsf_exclude');
|
917 |
}
|
918 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
919 |
}
|
920 |
|
921 |
/**
|
@@ -961,7 +1021,7 @@ jQuery( document ).ready( function() {
|
|
961 |
add_settings_field($prefix.'custom_sitemaps', __('Include custom XML Sitemaps','xml-sitemap-feed'), array($this,'custom_sitemaps_settings_field'), 'reading', 'xml_sitemap_section');
|
962 |
|
963 |
// POST META BOX
|
964 |
-
add_action( 'add_meta_boxes', array($this,'
|
965 |
add_action( 'save_post', array($this,'save_metadata') );
|
966 |
}
|
967 |
|
@@ -975,9 +1035,8 @@ jQuery( document ).ready( function() {
|
|
975 |
add_settings_field($prefix.'news_post_type', __('Include post types','xml-sitemap-feed'), array($this,'news_post_type_field'), 'reading', 'news_sitemap_section');
|
976 |
add_settings_field($prefix.'news_categories', translate('Categories'), array($this,'news_categories_field'), 'reading', 'news_sitemap_section');
|
977 |
add_settings_field($prefix.'news_image', translate('Images'), array($this,'news_image_field'), 'reading', 'news_sitemap_section');
|
978 |
-
add_settings_field($prefix.'
|
979 |
-
|
980 |
-
add_settings_field($prefix.'news_keywords', __('Topics','xml-sitemap-feed'), array($this,'news_keywords_field'), 'reading', 'news_sitemap_section');
|
981 |
|
982 |
}
|
983 |
|
19 |
$prefix = parent::prefix();
|
20 |
|
21 |
echo '<fieldset id="xmlsf_sitemaps"><legend class="screen-reader-text">'.__('XML Sitemaps','xml-sitemap-feed').'</legend>
|
22 |
+
<label><input type="checkbox" name="'.$prefix.'sitemaps[sitemap]" id="xmlsf_sitemaps_index" value="'.htmlspecialchars(XMLSF_NAME).'" '.checked(isset($options['sitemap']), true, false).' '.disabled($disabled, true, false).' /> '.__('XML Sitemap Index','xml-sitemap-feed').'</label>';//xmlsf
|
23 |
if (isset($options['sitemap']))
|
24 |
echo '<span class="description"> – <a href="#xmlsf" id="xmlsf_link">'.translate('Settings').'</a> – <a href="'.trailingslashit(get_bloginfo('url')). ( ('' == get_option('permalink_structure')) ? '?feed=sitemap' : $options['sitemap'] ) .'" target="_blank">'.translate('View').'</a></span>';
|
25 |
|
26 |
echo '<br>
|
27 |
+
<label><input type="checkbox" name="'.$prefix.'sitemaps[sitemap-news]" id="xmlsf_sitemaps_news" value="'.htmlspecialchars(XMLSF_NEWS_NAME).'" '.checked(isset($options['sitemap-news']), true, false).' '.disabled($disabled, true, false).' /> '.__('Google News Sitemap','xml-sitemap-feed').'</label>';
|
28 |
if (isset($options['sitemap-news']))
|
29 |
echo '<span class="description"> – <a href="#xmlnf" id="xmlnf_link">'.translate('Settings').'</a> – <a href="'.trailingslashit(get_bloginfo('url')). ( ('' == get_option('permalink_structure')) ? '?feed=sitemap-news' : $options['sitemap-news'] ) .'" target="_blank">'.translate('View').'</a></span>';
|
30 |
|
472 |
$name = !empty($options['name']) ? $options['name'] : '';
|
473 |
echo '
|
474 |
<fieldset><legend class="screen-reader-text">'.__('Publication name','xml-sitemap-feed').'</legend>
|
475 |
+
<input type="text" name="'.parent::prefix().'news_tags[name]" id="xmlsf_news_name" value="'.$name.'" class="regular-text"> <span class="description">'.sprintf(__('By default, the general %s setting will be used.','xml-sitemap-feed'),'<a href="options-general.php">'.translate('Site Title').'</a>').'</span><p class="description">' .
|
476 |
+
__('The publication name should match the name submitted on the Google News Publisher Center. If you wish to change it, please read <a href="https://support.google.com/news/publisher/answer/40402" target="_blank">Updated publication name</a>.') . '</p>
|
477 |
</fieldset>';
|
478 |
}
|
479 |
|
586 |
'>'.__('Attached images','xml-sitemap-feed').'</option>
|
587 |
';
|
588 |
echo '</select></label>
|
589 |
+
<p class="description">'.__('Note: Google News prefers at most one image per article in the News Sitemap. If multiple valid images are specified, the crawler will have to pick one arbitrarily. Images in News Sitemaps should be in jpeg or png format.','xml-sitemap-feed').' <a href="https://support.google.com/news/publisher/answer/13369" target="_blank">'.__('More information…','xml-sitemap-feed').'</a></p>
|
590 |
</fieldset>';
|
591 |
}
|
592 |
|
593 |
public function news_labels_field() {
|
594 |
echo '
|
595 |
<fieldset id="xmlsf_news_labels"><legend class="screen-reader-text">'.__('Source labels','xml-sitemap-feed').'</legend>' .
|
596 |
+
sprintf(__('You can use the %1$s and %2$s tags to provide Google more information about the content of your articles.','xml-sitemap-feed'),'<access>','<genres>') . ' <a href="https://support.google.com/news/publisher/answer/93992" target="_blank">'.__('More information…','xml-sitemap-feed').'</a>
|
597 |
<br><br>';
|
598 |
|
599 |
$options = parent::get_option('news_tags');
|
604 |
$access_default = !empty($access['default']) ? $access['default'] : '';
|
605 |
$access_password = !empty($access['password']) ? $access['password'] : '';
|
606 |
echo '
|
607 |
+
<fieldset id="xmlsf_news_labels_access"><legend class="screen-reader-text"><access></legend>
|
608 |
+
'.sprintf(__('The %4$s tag specifies whether an article is available to all readers (%1$s), or only to those with a free (%2$s) or paid membership (%3$s) to your site.','xml-sitemap-feed'),translate('Public'),__('Registration','xml-sitemap-feed'),__('Subscription','xml-sitemap-feed'),'<strong><access></strong>').'
|
609 |
+
'.__('You can assign a different access level when writing a post.','xml-sitemap-feed') . '
|
610 |
<ul>';
|
611 |
|
612 |
echo '
|
613 |
<li><label>'.__('Tag normal posts as','xml-sitemap-feed').' <select name="'.$prefix.'news_tags[access][default]" id="xmlsf_news_tags_access_default">
|
614 |
<option value="">'.translate('Public').'</option>
|
615 |
+
<option value="Registration" '.selected( "Registration" == $access_default, true, false).'>'.__('Free registration','xml-sitemap-feed').'</option>
|
616 |
+
<option value="Subscription" '.selected( "Subscription" == $access_default, true, false).'>'.__('Paid subscription','xml-sitemap-feed').'</option>
|
617 |
</select></label></li>';
|
618 |
echo '
|
619 |
<li><label>'.__('Tag Password Protected posts as','xml-sitemap-feed').' <select name="'.$prefix.'news_tags[access][password]" id="xmlsf_news_tags_access_password">
|
620 |
+
<option value="Registration" '.selected( "Registration" == $access_password, true, false).'>'.__('Free registration','xml-sitemap-feed').'</option>
|
621 |
+
<option value="Subscription" '.selected( "Subscription" == $access_password, true, false).'>'.__('Paid subscription','xml-sitemap-feed').'</option>
|
622 |
</select></label></li>';
|
623 |
echo '
|
624 |
</ul>
|
629 |
$genres = !empty($options['genres']) ? $options['genres'] : array();
|
630 |
$genres_default = !empty($genres['default']) ? (array)$genres['default'] : array();
|
631 |
|
|
|
|
|
632 |
echo '
|
633 |
+
<fieldset id="xmlsf_news_labels_genres"><legend class="screen-reader-text"><genres></legend>
|
634 |
+
'.sprintf(__('The %s tag specifies one or more properties for an article, namely, whether it is a press release, a blog post, an opinion, an op-ed piece, user-generated content, or satire.','xml-sitemap-feed'),'<strong><genres></strong>').' '.__('You can assign different genres when writing a post.','xml-sitemap-feed');
|
635 |
echo '<input type="hidden" name="'.$prefix.'news_tags[genres][active]" value="';
|
636 |
echo !empty($genres['active']) ? $genres['active'] : '';
|
637 |
echo '" />';
|
642 |
*/
|
643 |
echo '
|
644 |
<ul>
|
645 |
+
<li><label>'.__('Default genre:','xml-sitemap-feed').'<br><select multiple name="'.$prefix.'news_tags[genres][default][]" id="xmlsf_news_tags_genres_default" size="'.count($gn_genres).'">';
|
646 |
+
foreach ( $gn_genres as $name)
|
647 |
echo '
|
648 |
<option value="'.$name.'" '.selected( in_array($name,$genres_default), true, false ).'>'.$name.'</option>';
|
649 |
echo '
|
653 |
<p class="description">'.__('Use the Ctrl/Cmd key plus click to select more than one or to deselect.','xml-sitemap-feed').' '.sprintf(__('Read more about source labels on %s','xml-sitemap-feed'),'<a href="https://support.google.com/news/publisher/answer/4582731" target="_blank">'.__('What does each source label mean?','xml-sitemap-feed').'</a>').'</p>
|
654 |
</fieldset>';
|
655 |
|
656 |
+
/* }
|
657 |
|
658 |
public function news_keywords_field() {
|
659 |
$options = parent::get_option('news_tags');
|
660 |
+
$prefix = parent::prefix();*/
|
661 |
|
662 |
$keywords = !empty($options['keywords']) ? $options['keywords'] : array();
|
663 |
$keywords_from = !empty($keywords['from']) ? $keywords['from'] : '';
|
664 |
echo '
|
665 |
+
<fieldset id="xmlsf_news_keywords"><legend class="screen-reader-text"><keywords></legend>
|
666 |
+
'.sprintf(__('The %s tag is used to help classify the articles you submit to Google News by <strong>topic</strong>.','xml-sitemap-feed'),'<strong><keywords></strong>').'
|
667 |
<ul>
|
668 |
<li><label>'.sprintf(__('Use %s for topics.','xml-sitemap-feed'),' <select name="'.$prefix.'news_tags[keywords][from]" id="xmlsf_news_tags_keywords_from">
|
669 |
<option value="">'.translate('None').'</option>
|
813 |
$line = trim($line);
|
814 |
$parsed_url = parse_url(trim(filter_var($line,FILTER_SANITIZE_URL)));
|
815 |
// Before PHP version 5.4.7, parse_url will return the domain as path when scheme is omitted so we do:
|
816 |
+
if ( !empty($parsed_url['host']) ) {
|
817 |
+
$domain = trim( $parsed_url['host'] );
|
818 |
+
} else {
|
819 |
+
$domain_arr = explode('/', $parsed_url['path']);
|
820 |
+
$domain_arr = array_filter($domain_arr);
|
821 |
+
$domain = array_shift( $domain_arr );
|
822 |
+
$domain = trim( $domain );
|
823 |
+
}
|
824 |
+
|
825 |
// filter out empties and default domain
|
826 |
if(!empty($domain) && $domain !== $default && strpos($domain,".".$default) === false)
|
827 |
$sanitized[] = $domain;
|
848 |
*/
|
849 |
|
850 |
/* Adds a box to the side column */
|
851 |
+
public function add_meta_boxes()
|
852 |
{
|
853 |
+
// XML Sitemap
|
854 |
foreach (parent::get_post_types() as $post_type) {
|
855 |
+
// Only include metaboxes on post types that are included
|
856 |
if (isset($post_type["active"]))
|
857 |
add_meta_box(
|
858 |
'xmlsf_section',
|
862 |
'side'
|
863 |
);
|
864 |
}
|
865 |
+
// Google News Sitemap
|
866 |
+
// Only include metaboxes on post types that are included
|
867 |
+
$news_tags = parent::get_option('news_tags');
|
868 |
+
foreach ( (array)$news_tags['post_type'] as $post_type ) {
|
869 |
+
add_meta_box(
|
870 |
+
'xmlsf_news_section',
|
871 |
+
__( 'Google News Sitemap', 'xml-sitemap-feed' ),
|
872 |
+
array($this,'meta_box_news'),
|
873 |
+
$post_type,
|
874 |
+
'side'
|
875 |
+
);
|
876 |
+
}
|
877 |
}
|
878 |
|
879 |
public function meta_box($post)
|
883 |
|
884 |
// The actual fields for data entry
|
885 |
// Use get_post_meta to retrieve an existing value from the database and use the value for the form
|
886 |
+
$exclude = get_post_meta( $post->ID, '_xmlsf_exclude', true );
|
887 |
$priority = get_post_meta( $post->ID, '_xmlsf_priority', true );
|
888 |
$disabled = '';
|
889 |
|
890 |
// disable options and (visibly) set excluded to true for private posts
|
891 |
if ( 'private' == $post->post_status ) {
|
892 |
$disabled = ' disabled="disabled"';
|
893 |
+
$exclude = true;
|
894 |
}
|
895 |
|
896 |
// disable options and (visibly) set priority to 1 for front page
|
899 |
$priority = '1'; // force excluded to true for private posts
|
900 |
}
|
901 |
|
902 |
+
echo '<p><label><input type="checkbox" name="xmlsf_exclude" id="xmlsf_exclude" value="1"'.checked(!empty($exclude), true, false).$disabled.' > ';
|
903 |
_e('Exclude from XML Sitemap','xml-sitemap-feed');
|
904 |
echo '</label></p>';
|
905 |
|
906 |
echo '<p><label>';
|
907 |
_e('Priority','xml-sitemap-feed');
|
908 |
echo ' <input type="number" step="0.1" min="0" max="1" name="xmlsf_priority" id="xmlsf_priority" value="'.$priority.'" class="small-text"'.$disabled.'></label> <span class="description">';
|
909 |
+
printf(__('Leave empty for automatic Priority as configured on %1$s > %2$s.','xml-sitemap-feed'),translate('Settings'),'<a href="' . admin_url('options-reading.php') . '#xmlsf">' . translate('Reading') . '</a>');
|
910 |
echo '</span></p>';
|
911 |
}
|
912 |
+
|
913 |
+
public function meta_box_news($post)
|
914 |
+
{
|
915 |
+
// Use nonce for verification
|
916 |
+
wp_nonce_field( plugin_basename( __FILE__ ), 'xmlsf_sitemap_nonce' );
|
917 |
+
|
918 |
+
// The actual fields for data entry
|
919 |
+
// Use get_post_meta to retrieve an existing value from the database and use the value for the form
|
920 |
+
$exclude = get_post_meta( $post->ID, '_xmlsf_news_exclude', true );
|
921 |
+
$access = get_post_meta( $post->ID, '_xmlsf_news_access', true );
|
922 |
+
$disabled = '';
|
923 |
+
|
924 |
+
// disable options and (visibly) set excluded to true for private posts
|
925 |
+
if ( 'private' == $post->post_status ) {
|
926 |
+
$disabled = ' disabled="disabled"';
|
927 |
+
$exclude = true;
|
928 |
+
}
|
929 |
+
|
930 |
+
echo '<p><label>'.__('Access','xml-sitemap-feed').'
|
931 |
+
<select name="xmlsf_news_access" id="xmlsf_news_access">
|
932 |
+
<option value="">'.translate('Default').'</option>
|
933 |
+
<option value="Public" '.selected( "Public" == $access, true, false).'>'.translate('Public').'</option>
|
934 |
+
<option value="Registration" '.selected( "Registration" == $access, true, false).'>'.__('Registration','xml-sitemap-feed').'</option>
|
935 |
+
<option value="Subscription" '.selected( "Subscription" == $access, true, false).'>'.__('Subscription','xml-sitemap-feed').'</option>
|
936 |
+
</select></label></p>';
|
937 |
+
|
938 |
+
echo '<p><label><input type="checkbox" name="xmlsf_news_exclude" id="xmlsf_news_exclude" value="1"'.checked(!empty($exclude), true, false).$disabled.' > ';
|
939 |
+
_e('Exclude from Google News Sitemap','xml-sitemap-feed');
|
940 |
+
echo '</label></p>';
|
941 |
+
}
|
942 |
|
943 |
/* When the post is saved, save our meta data */
|
944 |
function save_metadata( $post_id )
|
963 |
delete_post_meta($post_id, '_xmlsf_exclude');
|
964 |
}
|
965 |
|
966 |
+
// _xmlsf_news_exclude
|
967 |
+
if ( isset($_POST['xmlsf_news_exclude']) && $_POST['xmlsf_news_exclude'] != '' ) {
|
968 |
+
update_post_meta($post_id, '_xmlsf_news_exclude', $_POST['xmlsf_news_exclude']);
|
969 |
+
} else {
|
970 |
+
delete_post_meta($post_id, '_xmlsf_news_exclude');
|
971 |
+
}
|
972 |
+
|
973 |
+
// _xmlsf_news_access
|
974 |
+
if ( isset($_POST['xmlsf_news_access']) && $_POST['xmlsf_news_access'] != '' ) {
|
975 |
+
update_post_meta($post_id, '_xmlsf_news_access', $_POST['xmlsf_news_access']);
|
976 |
+
} else {
|
977 |
+
delete_post_meta($post_id, '_xmlsf_news_access');
|
978 |
+
}
|
979 |
}
|
980 |
|
981 |
/**
|
1021 |
add_settings_field($prefix.'custom_sitemaps', __('Include custom XML Sitemaps','xml-sitemap-feed'), array($this,'custom_sitemaps_settings_field'), 'reading', 'xml_sitemap_section');
|
1022 |
|
1023 |
// POST META BOX
|
1024 |
+
add_action( 'add_meta_boxes', array($this,'add_meta_boxes') );
|
1025 |
add_action( 'save_post', array($this,'save_metadata') );
|
1026 |
}
|
1027 |
|
1035 |
add_settings_field($prefix.'news_post_type', __('Include post types','xml-sitemap-feed'), array($this,'news_post_type_field'), 'reading', 'news_sitemap_section');
|
1036 |
add_settings_field($prefix.'news_categories', translate('Categories'), array($this,'news_categories_field'), 'reading', 'news_sitemap_section');
|
1037 |
add_settings_field($prefix.'news_image', translate('Images'), array($this,'news_image_field'), 'reading', 'news_sitemap_section');
|
1038 |
+
add_settings_field($prefix.'news_labels', __('Source labels','xml-sitemap-feed'), array($this,'news_labels_field'), 'reading', 'news_sitemap_section');
|
1039 |
+
// add_settings_field($prefix.'news_keywords', __('Topics','xml-sitemap-feed'), array($this,'news_keywords_field'), 'reading', 'news_sitemap_section');
|
|
|
1040 |
|
1041 |
}
|
1042 |
|
includes/core.php
CHANGED
@@ -1,1305 +1,1364 @@
|
|
1 |
-
<?php
|
2 |
-
/* ------------------------------
|
3 |
-
* XMLSitemapFeed CLASS
|
4 |
-
* ------------------------------ */
|
5 |
-
|
6 |
-
if ( !class_exists('XMLSitemapFeed') ) :
|
7 |
-
|
8 |
-
class XMLSitemapFeed {
|
9 |
-
|
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 |
-
'
|
31 |
-
'
|
32 |
-
'
|
33 |
-
'
|
34 |
-
'
|
35 |
-
'
|
36 |
-
);
|
37 |
-
|
38 |
-
// Global values used for priority and changefreq calculation
|
39 |
-
private $domain;
|
40 |
-
private $firstdate;
|
41 |
-
private $lastmodified; // unused at the moment
|
42 |
-
private $postmodified = array();
|
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') )
|
75 |
-
$this->defaults['sitemaps'] = array(
|
76 |
-
'sitemap' => XMLSF_NAME
|
77 |
-
);
|
78 |
-
else
|
79 |
-
$this->defaults['sitemaps'] = array();
|
80 |
-
|
81 |
-
// post_types
|
82 |
-
$this->defaults['post_types'] = array();
|
83 |
-
foreach ( get_post_types(array('public'=>true),'names') as $name ) { // want 'publicly_queryable' but that excludes pages for some weird reason
|
84 |
-
// skip unallowed post types
|
85 |
-
if (in_array($name,$this->disabled_post_types))
|
86 |
-
continue;
|
87 |
-
|
88 |
-
$this->defaults['post_types'][$name] = array(
|
89 |
-
'name' => $name,
|
90 |
-
'active' => '',
|
91 |
-
'archive' => '',
|
92 |
-
'priority' => '0.5',
|
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';
|
107 |
-
$this->defaults['post_types']['post']['priority'] = '0.7';
|
108 |
-
$this->defaults['post_types']['post']['dynamic_priority'] = '1';
|
109 |
-
}
|
110 |
-
|
111 |
-
if ( isset($this->defaults['post_types']['page']) ) {
|
112 |
-
unset($this->defaults['post_types']['page']['archive']);
|
113 |
-
$this->defaults['post_types']['page']['priority'] = '0.3';
|
114 |
-
}
|
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 |
-
|
122 |
-
// search engines to ping
|
123 |
-
$this->defaults['ping'] = array(
|
124 |
-
'google' => array (
|
125 |
-
'active' => '1',
|
126 |
-
'uri' => 'http://www.google.com/webmasters/tools/ping?sitemap=',
|
127 |
-
'type' => 'GET',
|
128 |
-
'news' => '1'
|
129 |
-
),
|
130 |
-
'bing' => array (
|
131 |
-
'active' => '1',
|
132 |
-
'uri' => 'http://www.bing.com/ping?sitemap=',
|
133 |
-
'type' => 'GET',
|
134 |
-
'news' => '1'
|
135 |
-
),
|
136 |
-
'yandex' => array (
|
137 |
-
'active' => '',
|
138 |
-
'uri' => 'http://ping.blogs.yandex.ru/RPC2',
|
139 |
-
'type' => 'RPC',
|
140 |
-
),
|
141 |
-
'baidu' => array (
|
142 |
-
'active' => '',
|
143 |
-
'uri' => 'http://ping.baidu.com/ping/RPC2',
|
144 |
-
'type' => 'RPC',
|
145 |
-
),
|
146 |
-
'others' => array (
|
147 |
-
'active' => '1',
|
148 |
-
'uri' => 'http://rpc.pingomatic.com/',
|
149 |
-
'type' => 'RPC',
|
150 |
-
),
|
151 |
-
);
|
152 |
-
|
153 |
-
// robots
|
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 |
-
|
161 |
-
// additional custom_sitemaps
|
162 |
-
$this->defaults['custom_sitemaps'] = array();
|
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()
|
181 |
-
),
|
182 |
-
'keywords' => array(
|
183 |
-
'from' => 'category',
|
184 |
-
'default' => ''
|
185 |
-
)
|
186 |
-
);
|
187 |
-
}
|
188 |
-
|
189 |
-
/**
|
190 |
-
* QUERY FUNCTIONS
|
191 |
-
*/
|
192 |
-
|
193 |
-
public function defaults($key = false)
|
194 |
-
{
|
195 |
-
if (empty($this->defaults))
|
196 |
-
$this->set_defaults();
|
197 |
-
|
198 |
-
if ($key) {
|
199 |
-
$return = ( isset($this->defaults[$key]) ) ? $this->defaults[$key] : '';
|
200 |
-
} else {
|
201 |
-
$return = $this->defaults;
|
202 |
-
}
|
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 ) {
|
253 |
-
if(!empty($values['active'])) {
|
254 |
-
$count = wp_count_posts( $values['name'] );
|
255 |
-
if ($count->publish > 0) {
|
256 |
-
$values['count'] = $count->publish;
|
257 |
-
$return[$type] = $values;
|
258 |
-
}
|
259 |
-
}
|
260 |
-
}
|
261 |
-
|
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 |
-
|
278 |
-
// make sure it's an array we are returning
|
279 |
-
if(!empty($return)) {
|
280 |
-
if(is_array($return))
|
281 |
-
return $return;
|
282 |
-
else
|
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 |
-
|
293 |
-
// make sure it's an array we are returning
|
294 |
-
if(!empty($return)) {
|
295 |
-
if(is_array($return))
|
296 |
-
return $return;
|
297 |
-
else
|
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 ] ) ) {
|
322 |
-
$arcresults = $wpdb->get_results($query);
|
323 |
-
$cache[ $key ] = $arcresults;
|
324 |
-
wp_cache_set( 'xmlsf_get_archives', $cache, 'general' );
|
325 |
-
} else {
|
326 |
-
$arcresults = $cache[ $key ];
|
327 |
-
}
|
328 |
-
if ( $arcresults ) {
|
329 |
-
foreach ( (array) $arcresults as $arcresult ) {
|
330 |
-
$return[$arcresult->year.$arcresult->month] = esc_html( $this->get_index_url( 'posttype', $post_type, $arcresult->year . $arcresult->month ) );
|
331 |
-
}
|
332 |
-
}
|
333 |
-
} elseif ('yearly' == $type) {
|
334 |
-
$query = "SELECT YEAR(post_date) AS `year`, count(ID) as posts FROM $wpdb->posts WHERE post_type = '$post_type' AND post_status = 'publish' GROUP BY YEAR(post_date) ORDER BY post_date DESC";
|
335 |
-
$key = md5($query);
|
336 |
-
$cache = wp_cache_get( 'xmlsf_get_archives' , 'general');
|
337 |
-
if ( !isset( $cache[ $key ] ) ) {
|
338 |
-
$arcresults = $wpdb->get_results($query);
|
339 |
-
$cache[ $key ] = $arcresults;
|
340 |
-
wp_cache_set( 'xmlsf_get_archives', $cache, 'general' );
|
341 |
-
} else {
|
342 |
-
$arcresults = $cache[ $key ];
|
343 |
-
}
|
344 |
-
if ($arcresults) {
|
345 |
-
foreach ( (array) $arcresults as $arcresult) {
|
346 |
-
$return[$arcresult->year] = esc_html($this->get_index_url( 'posttype', $post_type, $arcresult->year ) );
|
347 |
-
}
|
348 |
-
}
|
349 |
-
} else {
|
350 |
-
$return[0] = esc_html($this->get_index_url('posttype', $post_type) ); // $sitemap = 'home', $type = false, $param = false
|
351 |
-
}
|
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) )
|
380 |
-
$this->blogpage = $polylang->get_translations('post', $blogpage);
|
381 |
-
else
|
382 |
-
$this->blogpage = array($blogpage);
|
383 |
-
} else {
|
384 |
-
$this->blogpage = array('-1');
|
385 |
-
}
|
386 |
-
}
|
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 |
-
|
399 |
-
global $post;
|
400 |
-
|
401 |
-
// if blog page look for last post date
|
402 |
-
if ( $post->post_type == 'page' && $this->is_home($post->ID) )
|
403 |
-
return get_lastmodified('GMT','post');
|
404 |
-
|
405 |
-
if ( empty($this->postmodified[$post->ID]) ) {
|
406 |
-
$postmodified = get_post_modified_time( 'Y-m-d H:i:s', true, $post->ID );
|
407 |
-
$options = $this->get_post_types();
|
408 |
-
|
409 |
-
if( !empty($options[$post->post_type]['update_lastmod_on_comments']) )
|
410 |
-
$lastcomment = get_comments( array(
|
411 |
-
'status' => 'approve',
|
412 |
-
'number' => 1,
|
413 |
-
'post_id' => $post->ID,
|
414 |
-
) );
|
415 |
-
|
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(
|
443 |
-
'taxonomy' => $term->taxonomy,
|
444 |
-
'field' => 'slug',
|
445 |
-
'terms' => $term->slug
|
446 |
-
)
|
447 |
-
)
|
448 |
-
)
|
449 |
-
);
|
450 |
-
$this->termmodified[$term->term_id] = isset($posts[0]->post_date_gmt) ? $posts[0]->post_date_gmt : '';
|
451 |
-
}
|
452 |
-
return $this->termmodified[$term->term_id];
|
453 |
-
} else {
|
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 |
-
|
463 |
-
else :
|
464 |
-
|
465 |
-
return '';
|
466 |
-
|
467 |
-
endif;
|
468 |
-
}
|
469 |
-
|
470 |
-
public function get_images($sitemap = '')
|
471 |
-
{
|
472 |
-
global $post;
|
473 |
-
if ( empty($this->images[$post->ID]) ) {
|
474 |
-
if ('news' == $sitemap) {
|
475 |
-
$options = $this->get_option('news_tags');
|
476 |
-
$which = isset($options['image']) ? $options['image'] : '';
|
477 |
-
} else {
|
478 |
-
$options = $this->get_post_types();
|
479 |
-
$which = isset($options[$post->post_type]['tags']['image']) ? $options[$post->post_type]['tags']['image'] : '';
|
480 |
-
}
|
481 |
-
if('attached' == $which) {
|
482 |
-
$args = array( 'post_type' => 'attachment', 'post_mime_type' => 'image', 'numberposts' => -1, 'post_status' =>'inherit', 'post_parent' => $post->ID );
|
483 |
-
$attachments = get_posts($args);
|
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' =>
|
489 |
-
'title' => apply_filters( 'the_title_xmlsitemap', $attachment->post_title ),
|
490 |
-
'caption' => apply_filters( 'the_title_xmlsitemap', $attachment->post_excerpt )
|
491 |
-
);
|
492 |
-
}
|
493 |
-
}
|
494 |
-
} elseif ('featured' == $which) {
|
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' =>
|
500 |
-
'title' => apply_filters( 'the_title_xmlsitemap', $attachment->post_title ),
|
501 |
-
'caption' => apply_filters( 'the_title_xmlsitemap', $attachment->post_excerpt )
|
502 |
-
);
|
503 |
-
}
|
504 |
-
}
|
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) )
|
572 |
-
$priority = $priority_value;
|
573 |
-
else
|
574 |
-
$priority = ( $this->lastmodified > $this->firstdate ) ? $priority_value - $priority_value * ( $this->lastmodified - $post_modified ) / ( $this->lastmodified - $this->firstdate ) : $priority_value;
|
575 |
-
|
576 |
-
if ( $post->comment_count > 0 )
|
577 |
-
$priority = $priority + 0.1 + ( 0.9 - $priority ) * $post->comment_count / wp_count_comments($post->post_type)->approved;
|
578 |
-
|
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) ) :
|
586 |
-
|
587 |
-
$max_priority = 0.4;
|
588 |
-
$min_priority = 0.0;
|
589 |
-
// TODO make these values optional
|
590 |
-
|
591 |
-
$tax_obj = get_taxonomy($term->taxonomy);
|
592 |
-
$postcount = 0;
|
593 |
-
foreach ($tax_obj->object_type as $post_type) {
|
594 |
-
$_post_count = wp_count_posts($post_type);
|
595 |
-
$postcount += $_post_count->publish;
|
596 |
-
}
|
597 |
-
|
598 |
-
$priority = ( $postcount > 0 ) ? $min_priority + ( $max_priority * $term->count / $postcount ) : $min_priority;
|
599 |
-
|
600 |
-
else :
|
601 |
-
|
602 |
-
$priority = 0.5;
|
603 |
-
|
604 |
-
endif;
|
605 |
-
|
606 |
-
// make sure we're not below zero
|
607 |
-
if ($priority < 0)
|
608 |
-
$priority = 0;
|
609 |
-
|
610 |
-
// and a final trim for cases where we ended up above 1 (sticky posts with many comments)
|
611 |
-
if ($priority > 1)
|
612 |
-
$priority = 1;
|
613 |
-
|
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;
|
657 |
-
break;
|
658 |
-
}
|
659 |
-
}
|
660 |
-
}
|
661 |
-
|
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;
|
675 |
-
$name .= $param ? '&m='.$param : '';
|
676 |
-
} else {
|
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) )
|
701 |
-
echo "\n# No XML Sitemaps are enabled. Please see XML Sitemaps on Settings > Reading.";
|
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 |
-
*/
|
715 |
-
|
716 |
-
/**
|
717 |
-
* Remove the trailing slash from permalinks that have an extension,
|
718 |
-
* such as /sitemap.xml (thanks to Permalink Editor plugin for WordPress)
|
719 |
-
*
|
720 |
-
* @param string $request
|
721 |
-
*/
|
722 |
-
|
723 |
-
public function trailingslash($request)
|
724 |
-
{
|
725 |
-
if (pathinfo($request, PATHINFO_EXTENSION)) {
|
726 |
-
return untrailingslashit($request);
|
727 |
-
}
|
728 |
-
return $request; // trailingslashit($request);
|
729 |
-
}
|
730 |
-
|
731 |
-
/**
|
732 |
-
* Add sitemap rewrite rules
|
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();
|
741 |
-
|
742 |
-
foreach ( $sitemaps as $name => $pretty )
|
743 |
-
$xmlsf_rules[ preg_quote($pretty) . '$' ] = $wp_rewrite->index . '?feed=' . $name;
|
744 |
-
|
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'] )
|
752 |
-
$xmlsf_rules[ $this->base_name . '-posttype-' . $post_type['name'] . '\.([0-9]+)?\.?' . $this->extension . '$' ] = $wp_rewrite->index . '?feed=sitemap-posttype-' . $post_type['name'] . '&m=$matches[1]';
|
753 |
-
}
|
754 |
-
|
755 |
-
// add rules for taxonomies
|
756 |
-
foreach ( $this->get_taxonomies() as $taxonomy ) {
|
757 |
-
$xmlsf_rules[ $this->base_name . '-taxonomy-' . $taxonomy . '\.' . $this->extension . '$' ] = $wp_rewrite->index . '?feed=sitemap-taxonomy-' . $taxonomy;
|
758 |
-
}
|
759 |
-
|
760 |
-
$urls = $this->get_urls();
|
761 |
-
if(!empty($urls))
|
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 |
-
*/
|
772 |
-
public function template( $theme ) {
|
773 |
-
|
774 |
-
if ( isset($request['feed']) && strpos($request['feed'],'sitemap') == 0 )
|
775 |
-
// clear get_template response to prevent themes functions.php (another source of blank line problems) from loading
|
776 |
-
return '';
|
777 |
-
else
|
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 |
-
|
790 |
-
return $request;
|
791 |
-
}
|
792 |
-
|
793 |
-
if ( $request['feed'] == 'sitemap-news' ) {
|
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';
|
812 |
-
} else {
|
813 |
-
$zone = 'blog';
|
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 |
-
}
|
821 |
-
|
822 |
-
/* modify request parameters */
|
823 |
-
// post type
|
824 |
-
$request['post_type'] = $news_post_type;
|
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;
|
834 |
-
}
|
835 |
-
|
836 |
-
if ( $request['feed'] == 'sitemap-home' ) {
|
837 |
-
// setup actions and filters
|
838 |
-
add_action('do_feed_sitemap-home', array($this, 'load_template_base'), 10, 1);
|
839 |
-
|
840 |
-
return $request;
|
841 |
-
}
|
842 |
-
|
843 |
-
if ( strpos($request['feed'],'sitemap-posttype') == 0 ) {
|
844 |
-
foreach ( $this->get_post_types() as $post_type ) {
|
845 |
-
if ( $request['feed'] == 'sitemap-posttype-'.$post_type['name'] ) {
|
846 |
-
// setup actions and filters
|
847 |
-
add_action('do_feed_sitemap-posttype-'.$post_type['name'], array($this, 'load_template'), 10, 1);
|
848 |
-
add_filter( 'post_limits', array($this, 'filter_limits') );
|
849 |
-
|
850 |
-
// modify request parameters
|
851 |
-
$request['post_type'] = $post_type['name'];
|
852 |
-
$request['post_status'] = 'publish';
|
853 |
-
$request['orderby'] = 'modified';
|
854 |
-
$request['lang'] = '';
|
855 |
-
$request['no_found_rows'] = true;
|
856 |
-
$request['update_post_meta_cache'] = false;
|
857 |
-
$request['update_post_term_cache'] = false;
|
858 |
-
|
859 |
-
return $request;
|
860 |
-
}
|
861 |
-
}
|
862 |
-
}
|
863 |
-
|
864 |
-
if ( strpos($request['feed'],'sitemap-taxonomy') == 0 ) {
|
865 |
-
foreach ( $this->get_taxonomies() as $taxonomy ) {
|
866 |
-
if ( $request['feed'] == 'sitemap-taxonomy-'.$taxonomy ) {
|
867 |
-
// setup actions and filters
|
868 |
-
add_action('do_feed_sitemap-taxonomy-'.$taxonomy, array($this, 'load_template_taxonomy'), 10, 1);
|
869 |
-
|
870 |
-
// modify request parameters
|
871 |
-
$request['taxonomy'] = $taxonomy;
|
872 |
-
$request['lang'] = '';
|
873 |
-
$request['no_found_rows'] = true;
|
874 |
-
$request['cache_results'] = false;
|
875 |
-
$request['update_post_term_cache'] = false;
|
876 |
-
$request['update_post_meta_cache'] = false;
|
877 |
-
$request['post_status'] = 'publish';
|
878 |
-
|
879 |
-
return $request;
|
880 |
-
}
|
881 |
-
}
|
882 |
-
}
|
883 |
-
|
884 |
-
if ( strpos($request['feed'],'sitemap-custom') == 0 ) {
|
885 |
-
// setup actions and filters
|
886 |
-
add_action('do_feed_sitemap-custom', array($this, 'load_template_custom'), 10, 1);
|
887 |
-
|
888 |
-
return $request;
|
889 |
-
}
|
890 |
-
|
891 |
-
}
|
892 |
-
|
893 |
-
return $request;
|
894 |
-
}
|
895 |
-
|
896 |
-
/**
|
897 |
-
* FEED TEMPLATES
|
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 |
-
}
|
935 |
-
|
936 |
-
/**
|
937 |
-
* LIMITS
|
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 |
-
//
|
953 |
-
public function
|
954 |
-
{
|
955 |
-
|
956 |
-
|
957 |
-
|
958 |
-
|
959 |
-
|
960 |
-
|
961 |
-
|
962 |
-
|
963 |
-
//
|
964 |
-
public function
|
965 |
-
{
|
966 |
-
|
967 |
-
|
968 |
-
|
969 |
-
|
970 |
-
|
971 |
-
|
972 |
-
|
973 |
-
}
|
974 |
-
|
975 |
-
|
976 |
-
|
977 |
-
|
978 |
-
|
979 |
-
|
980 |
-
|
981 |
-
|
982 |
-
$options =
|
983 |
-
|
984 |
-
|
985 |
-
|
986 |
-
|
987 |
-
|
988 |
-
|
989 |
-
|
990 |
-
|
991 |
-
|
992 |
-
|
993 |
-
|
994 |
-
|
995 |
-
|
996 |
-
|
997 |
-
$
|
998 |
-
$
|
999 |
-
|
1000 |
-
|
1001 |
-
|
1002 |
-
|
1003 |
-
|
1004 |
-
$news_tags
|
1005 |
-
|
1006 |
-
//
|
1007 |
-
|
1008 |
-
|
1009 |
-
|
1010 |
-
|
1011 |
-
|
1012 |
-
|
1013 |
-
|
1014 |
-
|
1015 |
-
|
1016 |
-
|
1017 |
-
|
1018 |
-
|
1019 |
-
|
1020 |
-
|
1021 |
-
|
1022 |
-
|
1023 |
-
|
1024 |
-
|
1025 |
-
|
1026 |
-
|
1027 |
-
|
1028 |
-
|
1029 |
-
|
1030 |
-
|
1031 |
-
|
1032 |
-
|
1033 |
-
|
1034 |
-
|
1035 |
-
|
1036 |
-
|
1037 |
-
|
1038 |
-
|
1039 |
-
|
1040 |
-
|
1041 |
-
|
1042 |
-
|
1043 |
-
|
1044 |
-
|
1045 |
-
|
1046 |
-
|
1047 |
-
|
1048 |
-
|
1049 |
-
|
1050 |
-
|
1051 |
-
|
1052 |
-
|
1053 |
-
|
1054 |
-
|
1055 |
-
|
1056 |
-
|
1057 |
-
|
1058 |
-
|
1059 |
-
|
1060 |
-
|
1061 |
-
|
1062 |
-
|
1063 |
-
|
1064 |
-
|
1065 |
-
|
1066 |
-
|
1067 |
-
|
1068 |
-
|
1069 |
-
|
1070 |
-
|
1071 |
-
|
1072 |
-
|
1073 |
-
|
1074 |
-
|
1075 |
-
|
1076 |
-
|
1077 |
-
|
1078 |
-
|
1079 |
-
|
1080 |
-
|
1081 |
-
|
1082 |
-
|
1083 |
-
//
|
1084 |
-
|
1085 |
-
|
1086 |
-
|
1087 |
-
|
1088 |
-
|
1089 |
-
|
1090 |
-
|
1091 |
-
|
1092 |
-
|
1093 |
-
|
1094 |
-
|
1095 |
-
|
1096 |
-
|
1097 |
-
|
1098 |
-
|
1099 |
-
|
1100 |
-
|
1101 |
-
|
1102 |
-
|
1103 |
-
|
1104 |
-
|
1105 |
-
|
1106 |
-
|
1107 |
-
|
1108 |
-
|
1109 |
-
|
1110 |
-
|
1111 |
-
|
1112 |
-
|
1113 |
-
|
1114 |
-
|
1115 |
-
|
1116 |
-
|
1117 |
-
|
1118 |
-
|
1119 |
-
|
1120 |
-
|
1121 |
-
|
1122 |
-
|
1123 |
-
|
1124 |
-
|
1125 |
-
|
1126 |
-
|
1127 |
-
|
1128 |
-
|
1129 |
-
|
1130 |
-
|
1131 |
-
|
1132 |
-
|
1133 |
-
|
1134 |
-
|
1135 |
-
|
1136 |
-
|
1137 |
-
|
1138 |
-
|
1139 |
-
|
1140 |
-
|
1141 |
-
|
1142 |
-
|
1143 |
-
|
1144 |
-
|
1145 |
-
|
1146 |
-
|
1147 |
-
|
1148 |
-
|
1149 |
-
|
1150 |
-
|
1151 |
-
|
1152 |
-
|
1153 |
-
|
1154 |
-
|
1155 |
-
|
1156 |
-
|
1157 |
-
|
1158 |
-
|
1159 |
-
|
1160 |
-
|
1161 |
-
|
1162 |
-
|
1163 |
-
$
|
1164 |
-
|
1165 |
-
|
1166 |
-
|
1167 |
-
|
1168 |
-
|
1169 |
-
|
1170 |
-
|
1171 |
-
|
1172 |
-
|
1173 |
-
|
1174 |
-
|
1175 |
-
|
1176 |
-
|
1177 |
-
|
1178 |
-
|
1179 |
-
|
1180 |
-
}
|
1181 |
-
|
1182 |
-
|
1183 |
-
|
1184 |
-
|
1185 |
-
|
1186 |
-
|
1187 |
-
|
1188 |
-
|
1189 |
-
|
1190 |
-
|
1191 |
-
|
1192 |
-
|
1193 |
-
|
1194 |
-
|
1195 |
-
|
1196 |
-
|
1197 |
-
|
1198 |
-
|
1199 |
-
|
1200 |
-
|
1201 |
-
|
1202 |
-
|
1203 |
-
|
1204 |
-
|
1205 |
-
|
1206 |
-
|
1207 |
-
|
1208 |
-
|
1209 |
-
|
1210 |
-
|
1211 |
-
|
1212 |
-
|
1213 |
-
|
1214 |
-
|
1215 |
-
|
1216 |
-
|
1217 |
-
|
1218 |
-
|
1219 |
-
|
1220 |
-
$
|
1221 |
-
|
1222 |
-
|
1223 |
-
|
1224 |
-
|
1225 |
-
|
1226 |
-
|
1227 |
-
|
1228 |
-
|
1229 |
-
|
1230 |
-
|
1231 |
-
|
1232 |
-
|
1233 |
-
|
1234 |
-
|
1235 |
-
|
1236 |
-
|
1237 |
-
|
1238 |
-
|
1239 |
-
|
1240 |
-
|
1241 |
-
|
1242 |
-
|
1243 |
-
|
1244 |
-
|
1245 |
-
|
1246 |
-
|
1247 |
-
|
1248 |
-
|
1249 |
-
|
1250 |
-
|
1251 |
-
|
1252 |
-
|
1253 |
-
|
1254 |
-
|
1255 |
-
|
1256 |
-
|
1257 |
-
|
1258 |
-
|
1259 |
-
|
1260 |
-
|
1261 |
-
|
1262 |
-
|
1263 |
-
|
1264 |
-
|
1265 |
-
|
1266 |
-
|
1267 |
-
|
1268 |
-
|
1269 |
-
|
1270 |
-
|
1271 |
-
|
1272 |
-
|
1273 |
-
|
1274 |
-
|
1275 |
-
|
1276 |
-
|
1277 |
-
|
1278 |
-
|
1279 |
-
|
1280 |
-
|
1281 |
-
|
1282 |
-
|
1283 |
-
|
1284 |
-
|
1285 |
-
|
1286 |
-
|
1287 |
-
|
1288 |
-
|
1289 |
-
|
1290 |
-
|
1291 |
-
|
1292 |
-
|
1293 |
-
|
1294 |
-
|
1295 |
-
|
1296 |
-
|
1297 |
-
|
1298 |
-
|
1299 |
-
|
1300 |
-
|
1301 |
-
|
1302 |
-
|
1303 |
-
|
1304 |
-
|
1305 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/* ------------------------------
|
3 |
+
* XMLSitemapFeed CLASS
|
4 |
+
* ------------------------------ */
|
5 |
+
|
6 |
+
if ( !class_exists('XMLSitemapFeed') ) :
|
7 |
+
|
8 |
+
class XMLSitemapFeed {
|
9 |
+
|
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;
|
41 |
+
private $lastmodified; // unused at the moment
|
42 |
+
private $postmodified = array();
|
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') )
|
75 |
+
$this->defaults['sitemaps'] = array(
|
76 |
+
'sitemap' => XMLSF_NAME
|
77 |
+
);
|
78 |
+
else
|
79 |
+
$this->defaults['sitemaps'] = array();
|
80 |
+
|
81 |
+
// post_types
|
82 |
+
$this->defaults['post_types'] = array();
|
83 |
+
foreach ( get_post_types(array('public'=>true),'names') as $name ) { // want 'publicly_queryable' but that excludes pages for some weird reason
|
84 |
+
// skip unallowed post types
|
85 |
+
if (in_array($name,$this->disabled_post_types))
|
86 |
+
continue;
|
87 |
+
|
88 |
+
$this->defaults['post_types'][$name] = array(
|
89 |
+
'name' => $name,
|
90 |
+
'active' => '',
|
91 |
+
'archive' => '',
|
92 |
+
'priority' => '0.5',
|
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';
|
107 |
+
$this->defaults['post_types']['post']['priority'] = '0.7';
|
108 |
+
$this->defaults['post_types']['post']['dynamic_priority'] = '1';
|
109 |
+
}
|
110 |
+
|
111 |
+
if ( isset($this->defaults['post_types']['page']) ) {
|
112 |
+
unset($this->defaults['post_types']['page']['archive']);
|
113 |
+
$this->defaults['post_types']['page']['priority'] = '0.3';
|
114 |
+
}
|
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 |
+
|
122 |
+
// search engines to ping
|
123 |
+
$this->defaults['ping'] = array(
|
124 |
+
'google' => array (
|
125 |
+
'active' => '1',
|
126 |
+
'uri' => 'http://www.google.com/webmasters/tools/ping?sitemap=',
|
127 |
+
'type' => 'GET',
|
128 |
+
'news' => '1'
|
129 |
+
),
|
130 |
+
'bing' => array (
|
131 |
+
'active' => '1',
|
132 |
+
'uri' => 'http://www.bing.com/ping?sitemap=',
|
133 |
+
'type' => 'GET',
|
134 |
+
'news' => '1'
|
135 |
+
),
|
136 |
+
'yandex' => array (
|
137 |
+
'active' => '',
|
138 |
+
'uri' => 'http://ping.blogs.yandex.ru/RPC2',
|
139 |
+
'type' => 'RPC',
|
140 |
+
),
|
141 |
+
'baidu' => array (
|
142 |
+
'active' => '',
|
143 |
+
'uri' => 'http://ping.baidu.com/ping/RPC2',
|
144 |
+
'type' => 'RPC',
|
145 |
+
),
|
146 |
+
'others' => array (
|
147 |
+
'active' => '1',
|
148 |
+
'uri' => 'http://rpc.pingomatic.com/',
|
149 |
+
'type' => 'RPC',
|
150 |
+
),
|
151 |
+
);
|
152 |
+
|
153 |
+
// robots
|
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 |
+
|
161 |
+
// additional custom_sitemaps
|
162 |
+
$this->defaults['custom_sitemaps'] = array();
|
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 |
+
}
|
188 |
+
|
189 |
+
/**
|
190 |
+
* QUERY FUNCTIONS
|
191 |
+
*/
|
192 |
+
|
193 |
+
public function defaults($key = false)
|
194 |
+
{
|
195 |
+
if (empty($this->defaults))
|
196 |
+
$this->set_defaults();
|
197 |
+
|
198 |
+
if ($key) {
|
199 |
+
$return = ( isset($this->defaults[$key]) ) ? $this->defaults[$key] : '';
|
200 |
+
} else {
|
201 |
+
$return = $this->defaults;
|
202 |
+
}
|
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 ) {
|
253 |
+
if(!empty($values['active'])) {
|
254 |
+
$count = wp_count_posts( $values['name'] );
|
255 |
+
if ($count->publish > 0) {
|
256 |
+
$values['count'] = $count->publish;
|
257 |
+
$return[$type] = $values;
|
258 |
+
}
|
259 |
+
}
|
260 |
+
}
|
261 |
+
|
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 |
+
|
278 |
+
// make sure it's an array we are returning
|
279 |
+
if(!empty($return)) {
|
280 |
+
if(is_array($return))
|
281 |
+
return $return;
|
282 |
+
else
|
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 |
+
|
293 |
+
// make sure it's an array we are returning
|
294 |
+
if(!empty($return)) {
|
295 |
+
if(is_array($return))
|
296 |
+
return $return;
|
297 |
+
else
|
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 ] ) ) {
|
322 |
+
$arcresults = $wpdb->get_results($query);
|
323 |
+
$cache[ $key ] = $arcresults;
|
324 |
+
wp_cache_set( 'xmlsf_get_archives', $cache, 'general' );
|
325 |
+
} else {
|
326 |
+
$arcresults = $cache[ $key ];
|
327 |
+
}
|
328 |
+
if ( $arcresults ) {
|
329 |
+
foreach ( (array) $arcresults as $arcresult ) {
|
330 |
+
$return[$arcresult->year.$arcresult->month] = esc_html( $this->get_index_url( 'posttype', $post_type, $arcresult->year . $arcresult->month ) );
|
331 |
+
}
|
332 |
+
}
|
333 |
+
} elseif ('yearly' == $type) {
|
334 |
+
$query = "SELECT YEAR(post_date) AS `year`, count(ID) as posts FROM $wpdb->posts WHERE post_type = '$post_type' AND post_status = 'publish' GROUP BY YEAR(post_date) ORDER BY post_date DESC";
|
335 |
+
$key = md5($query);
|
336 |
+
$cache = wp_cache_get( 'xmlsf_get_archives' , 'general');
|
337 |
+
if ( !isset( $cache[ $key ] ) ) {
|
338 |
+
$arcresults = $wpdb->get_results($query);
|
339 |
+
$cache[ $key ] = $arcresults;
|
340 |
+
wp_cache_set( 'xmlsf_get_archives', $cache, 'general' );
|
341 |
+
} else {
|
342 |
+
$arcresults = $cache[ $key ];
|
343 |
+
}
|
344 |
+
if ($arcresults) {
|
345 |
+
foreach ( (array) $arcresults as $arcresult) {
|
346 |
+
$return[$arcresult->year] = esc_html($this->get_index_url( 'posttype', $post_type, $arcresult->year ) );
|
347 |
+
}
|
348 |
+
}
|
349 |
+
} else {
|
350 |
+
$return[0] = esc_html($this->get_index_url('posttype', $post_type) ); // $sitemap = 'home', $type = false, $param = false
|
351 |
+
}
|
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) )
|
380 |
+
$this->blogpage = $polylang->get_translations('post', $blogpage);
|
381 |
+
else
|
382 |
+
$this->blogpage = array($blogpage);
|
383 |
+
} else {
|
384 |
+
$this->blogpage = array('-1');
|
385 |
+
}
|
386 |
+
}
|
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 |
+
|
399 |
+
global $post;
|
400 |
+
|
401 |
+
// if blog page look for last post date
|
402 |
+
if ( $post->post_type == 'page' && $this->is_home($post->ID) )
|
403 |
+
return get_lastmodified('GMT','post');
|
404 |
+
|
405 |
+
if ( empty($this->postmodified[$post->ID]) ) {
|
406 |
+
$postmodified = get_post_modified_time( 'Y-m-d H:i:s', true, $post->ID );
|
407 |
+
$options = $this->get_post_types();
|
408 |
+
|
409 |
+
if( !empty($options[$post->post_type]['update_lastmod_on_comments']) )
|
410 |
+
$lastcomment = get_comments( array(
|
411 |
+
'status' => 'approve',
|
412 |
+
'number' => 1,
|
413 |
+
'post_id' => $post->ID,
|
414 |
+
) );
|
415 |
+
|
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(
|
443 |
+
'taxonomy' => $term->taxonomy,
|
444 |
+
'field' => 'slug',
|
445 |
+
'terms' => $term->slug
|
446 |
+
)
|
447 |
+
)
|
448 |
+
)
|
449 |
+
);
|
450 |
+
$this->termmodified[$term->term_id] = isset($posts[0]->post_date_gmt) ? $posts[0]->post_date_gmt : '';
|
451 |
+
}
|
452 |
+
return $this->termmodified[$term->term_id];
|
453 |
+
} else {
|
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 |
+
|
463 |
+
else :
|
464 |
+
|
465 |
+
return '';
|
466 |
+
|
467 |
+
endif;
|
468 |
+
}
|
469 |
+
|
470 |
+
public function get_images($sitemap = '')
|
471 |
+
{
|
472 |
+
global $post;
|
473 |
+
if ( empty($this->images[$post->ID]) ) {
|
474 |
+
if ('news' == $sitemap) {
|
475 |
+
$options = $this->get_option('news_tags');
|
476 |
+
$which = isset($options['image']) ? $options['image'] : '';
|
477 |
+
} else {
|
478 |
+
$options = $this->get_post_types();
|
479 |
+
$which = isset($options[$post->post_type]['tags']['image']) ? $options[$post->post_type]['tags']['image'] : '';
|
480 |
+
}
|
481 |
+
if('attached' == $which) {
|
482 |
+
$args = array( 'post_type' => 'attachment', 'post_mime_type' => 'image', 'numberposts' => -1, 'post_status' =>'inherit', 'post_parent' => $post->ID );
|
483 |
+
$attachments = get_posts($args);
|
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 & 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 )
|
491 |
+
);
|
492 |
+
}
|
493 |
+
}
|
494 |
+
} elseif ('featured' == $which) {
|
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 )
|
502 |
+
);
|
503 |
+
}
|
504 |
+
}
|
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) )
|
572 |
+
$priority = $priority_value;
|
573 |
+
else
|
574 |
+
$priority = ( $this->lastmodified > $this->firstdate ) ? $priority_value - $priority_value * ( $this->lastmodified - $post_modified ) / ( $this->lastmodified - $this->firstdate ) : $priority_value;
|
575 |
+
|
576 |
+
if ( $post->comment_count > 0 )
|
577 |
+
$priority = $priority + 0.1 + ( 0.9 - $priority ) * $post->comment_count / wp_count_comments($post->post_type)->approved;
|
578 |
+
|
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) ) :
|
586 |
+
|
587 |
+
$max_priority = 0.4;
|
588 |
+
$min_priority = 0.0;
|
589 |
+
// TODO make these values optional
|
590 |
+
|
591 |
+
$tax_obj = get_taxonomy($term->taxonomy);
|
592 |
+
$postcount = 0;
|
593 |
+
foreach ($tax_obj->object_type as $post_type) {
|
594 |
+
$_post_count = wp_count_posts($post_type);
|
595 |
+
$postcount += $_post_count->publish;
|
596 |
+
}
|
597 |
+
|
598 |
+
$priority = ( $postcount > 0 ) ? $min_priority + ( $max_priority * $term->count / $postcount ) : $min_priority;
|
599 |
+
|
600 |
+
else :
|
601 |
+
|
602 |
+
$priority = 0.5;
|
603 |
+
|
604 |
+
endif;
|
605 |
+
|
606 |
+
// make sure we're not below zero
|
607 |
+
if ($priority < 0)
|
608 |
+
$priority = 0;
|
609 |
+
|
610 |
+
// and a final trim for cases where we ended up above 1 (sticky posts with many comments)
|
611 |
+
if ($priority > 1)
|
612 |
+
$priority = 1;
|
613 |
+
|
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;
|
657 |
+
break;
|
658 |
+
}
|
659 |
+
}
|
660 |
+
}
|
661 |
+
|
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;
|
675 |
+
$name .= $param ? '&m='.$param : '';
|
676 |
+
} else {
|
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) )
|
701 |
+
echo "\n# No XML Sitemaps are enabled. Please see XML Sitemaps on Settings > Reading.";
|
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 |
+
*/
|
715 |
+
|
716 |
+
/**
|
717 |
+
* Remove the trailing slash from permalinks that have an extension,
|
718 |
+
* such as /sitemap.xml (thanks to Permalink Editor plugin for WordPress)
|
719 |
+
*
|
720 |
+
* @param string $request
|
721 |
+
*/
|
722 |
+
|
723 |
+
public function trailingslash($request)
|
724 |
+
{
|
725 |
+
if (pathinfo($request, PATHINFO_EXTENSION)) {
|
726 |
+
return untrailingslashit($request);
|
727 |
+
}
|
728 |
+
return $request; // trailingslashit($request);
|
729 |
+
}
|
730 |
+
|
731 |
+
/**
|
732 |
+
* Add sitemap rewrite rules
|
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();
|
741 |
+
|
742 |
+
foreach ( $sitemaps as $name => $pretty )
|
743 |
+
$xmlsf_rules[ preg_quote($pretty) . '$' ] = $wp_rewrite->index . '?feed=' . $name;
|
744 |
+
|
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'] )
|
752 |
+
$xmlsf_rules[ $this->base_name . '-posttype-' . $post_type['name'] . '\.([0-9]+)?\.?' . $this->extension . '$' ] = $wp_rewrite->index . '?feed=sitemap-posttype-' . $post_type['name'] . '&m=$matches[1]';
|
753 |
+
}
|
754 |
+
|
755 |
+
// add rules for taxonomies
|
756 |
+
foreach ( $this->get_taxonomies() as $taxonomy ) {
|
757 |
+
$xmlsf_rules[ $this->base_name . '-taxonomy-' . $taxonomy . '\.' . $this->extension . '$' ] = $wp_rewrite->index . '?feed=sitemap-taxonomy-' . $taxonomy;
|
758 |
+
}
|
759 |
+
|
760 |
+
$urls = $this->get_urls();
|
761 |
+
if(!empty($urls))
|
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 |
+
*/
|
772 |
+
public function template( $theme ) {
|
773 |
+
|
774 |
+
if ( isset($request['feed']) && strpos($request['feed'],'sitemap') == 0 )
|
775 |
+
// clear get_template response to prevent themes functions.php (another source of blank line problems) from loading
|
776 |
+
return '';
|
777 |
+
else
|
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 |
+
|
790 |
+
return $request;
|
791 |
+
}
|
792 |
+
|
793 |
+
if ( $request['feed'] == 'sitemap-news' ) {
|
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';
|
812 |
+
} else {
|
813 |
+
$zone = 'blog';
|
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 |
+
}
|
821 |
+
|
822 |
+
/* modify request parameters */
|
823 |
+
// post type
|
824 |
+
$request['post_type'] = $news_post_type;
|
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;
|
834 |
+
}
|
835 |
+
|
836 |
+
if ( $request['feed'] == 'sitemap-home' ) {
|
837 |
+
// setup actions and filters
|
838 |
+
add_action('do_feed_sitemap-home', array($this, 'load_template_base'), 10, 1);
|
839 |
+
|
840 |
+
return $request;
|
841 |
+
}
|
842 |
+
|
843 |
+
if ( strpos($request['feed'],'sitemap-posttype') == 0 ) {
|
844 |
+
foreach ( $this->get_post_types() as $post_type ) {
|
845 |
+
if ( $request['feed'] == 'sitemap-posttype-'.$post_type['name'] ) {
|
846 |
+
// setup actions and filters
|
847 |
+
add_action('do_feed_sitemap-posttype-'.$post_type['name'], array($this, 'load_template'), 10, 1);
|
848 |
+
add_filter( 'post_limits', array($this, 'filter_limits') );
|
849 |
+
|
850 |
+
// modify request parameters
|
851 |
+
$request['post_type'] = $post_type['name'];
|
852 |
+
$request['post_status'] = 'publish';
|
853 |
+
$request['orderby'] = 'modified';
|
854 |
+
$request['lang'] = '';
|
855 |
+
$request['no_found_rows'] = true;
|
856 |
+
$request['update_post_meta_cache'] = false;
|
857 |
+
$request['update_post_term_cache'] = false;
|
858 |
+
|
859 |
+
return $request;
|
860 |
+
}
|
861 |
+
}
|
862 |
+
}
|
863 |
+
|
864 |
+
if ( strpos($request['feed'],'sitemap-taxonomy') == 0 ) {
|
865 |
+
foreach ( $this->get_taxonomies() as $taxonomy ) {
|
866 |
+
if ( $request['feed'] == 'sitemap-taxonomy-'.$taxonomy ) {
|
867 |
+
// setup actions and filters
|
868 |
+
add_action('do_feed_sitemap-taxonomy-'.$taxonomy, array($this, 'load_template_taxonomy'), 10, 1);
|
869 |
+
|
870 |
+
// modify request parameters
|
871 |
+
$request['taxonomy'] = $taxonomy;
|
872 |
+
$request['lang'] = '';
|
873 |
+
$request['no_found_rows'] = true;
|
874 |
+
$request['cache_results'] = false;
|
875 |
+
$request['update_post_term_cache'] = false;
|
876 |
+
$request['update_post_meta_cache'] = false;
|
877 |
+
$request['post_status'] = 'publish';
|
878 |
+
|
879 |
+
return $request;
|
880 |
+
}
|
881 |
+
}
|
882 |
+
}
|
883 |
+
|
884 |
+
if ( strpos($request['feed'],'sitemap-custom') == 0 ) {
|
885 |
+
// setup actions and filters
|
886 |
+
add_action('do_feed_sitemap-custom', array($this, 'load_template_custom'), 10, 1);
|
887 |
+
|
888 |
+
return $request;
|
889 |
+
}
|
890 |
+
|
891 |
+
}
|
892 |
+
|
893 |
+
return $request;
|
894 |
+
}
|
895 |
+
|
896 |
+
/**
|
897 |
+
* FEED TEMPLATES
|
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 |
+
}
|
935 |
+
|
936 |
+
/**
|
937 |
+
* LIMITS
|
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' );
|
957 |
+
return $where . " AND post_date_gmt > '" . date('Y-m-d H:i:s', strtotime('-48 hours')) . "'";
|
958 |
+
} else {
|
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 |
+
}
|
974 |
+
|
975 |
+
/**
|
976 |
+
* PINGING
|
977 |
+
*/
|
978 |
+
|
979 |
+
public function ping($uri, $timeout = 3)
|
980 |
+
{
|
981 |
+
$options = array();
|
982 |
+
$options['timeout'] = $timeout;
|
983 |
+
|
984 |
+
$response = wp_remote_request( $uri, $options );
|
985 |
+
|
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();
|
998 |
+
$update = false;
|
999 |
+
|
1000 |
+
// first check if news sitemap is set
|
1001 |
+
if ( !empty($sitemaps['sitemap-news']) ) {
|
1002 |
+
// then check if we've got a post type that is included in our news sitemap
|
1003 |
+
$news_tags = $this->get_option('news_tags');
|
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
|
1011 |
+
foreach ($to_ping as $se => $data) {
|
1012 |
+
// check active switch
|
1013 |
+
if( empty($data['active']) || empty($data['news']) )
|
1014 |
+
continue;
|
1015 |
+
// and if we did not ping already within the last 5 minutes
|
1016 |
+
if( !empty($data['pong']) && is_array($data['pong']) && !empty($data['pong'][$sitemaps['sitemap-news']]) && (int)$data['pong'][$sitemaps['sitemap-news']] + 300 > time() )
|
1017 |
+
continue;
|
1018 |
+
// ping !
|
1019 |
+
if ( $this->ping( $data['uri'].urlencode(trailingslashit(get_bloginfo('url')) . $sitemaps['sitemap-news']) ) ) {
|
1020 |
+
$to_ping[$se]['pong'][$sitemaps['sitemap-news']] = time();
|
1021 |
+
$update = true;
|
1022 |
+
}
|
1023 |
+
|
1024 |
+
}
|
1025 |
+
}
|
1026 |
+
}
|
1027 |
+
}
|
1028 |
+
|
1029 |
+
// first check if regular sitemap is set
|
1030 |
+
if ( !empty($sitemaps['sitemap']) ) {
|
1031 |
+
// then check if we've got a post type that is included in our sitemap
|
1032 |
+
foreach($this->get_post_types() as $post_type) {
|
1033 |
+
if ( !empty($post_type) && is_array($post_type) && in_array($post->post_type,$post_type) ) {
|
1034 |
+
// are we publishing?
|
1035 |
+
if ( $old_status != 'publish' && $new_status == 'publish' ) {
|
1036 |
+
foreach ($to_ping as $se => $data) {
|
1037 |
+
// check active switch
|
1038 |
+
if( empty($data['active']) || empty($data['type']) || $data['type']!='GET' )
|
1039 |
+
continue;
|
1040 |
+
// and if we did not ping already within the last hour
|
1041 |
+
if( !empty($data['pong']) && is_array($data['pong']) && !empty($data['pong'][$sitemaps['sitemap']]) && (int)$data['pong'][$sitemaps['sitemap']] + 3600 > time() )
|
1042 |
+
continue;
|
1043 |
+
// ping !
|
1044 |
+
if ( $this->ping( $data['uri'].urlencode(trailingslashit(get_bloginfo('url')) . $sitemaps['sitemap']) ) ) {
|
1045 |
+
$to_ping[$se]['pong'][$sitemaps['sitemap']] = time();
|
1046 |
+
$update = true;
|
1047 |
+
}
|
1048 |
+
}
|
1049 |
+
}
|
1050 |
+
}
|
1051 |
+
}
|
1052 |
+
}
|
1053 |
+
|
1054 |
+
if ( $update ) update_option($this->prefix.'ping',$to_ping);
|
1055 |
+
}
|
1056 |
+
|
1057 |
+
/**
|
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?
|
1075 |
+
if ( $new_status == 'publish' || $old_status == 'publish' ) {
|
1076 |
+
// Use cache_delete to remove single key instead of complete cache_flush. Thanks Jeremy Clarke!
|
1077 |
+
wp_cache_delete('xmlsf_get_archives', 'general');
|
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 ) )
|
1085 |
+
return $urls;
|
1086 |
+
|
1087 |
+
if ( $redis ) {
|
1088 |
+
|
1089 |
+
// wildcard allowed, this makes everything simple
|
1090 |
+
$urls[] = '/sitemap*.xml';
|
1091 |
+
|
1092 |
+
} else {
|
1093 |
+
|
1094 |
+
// no wildcard, go through the motions
|
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 |
+
}
|
1108 |
+
|
1109 |
+
// add public post taxonomies sitemaps
|
1110 |
+
foreach ( $this->get_taxonomies() as $taxonomy ) {
|
1111 |
+
$urls[] = parse_url( $this->get_index_url('taxonomy',$taxonomy), PHP_URL_PATH);
|
1112 |
+
}
|
1113 |
+
|
1114 |
+
// add custom URLs sitemap
|
1115 |
+
$custom_urls = $this->get_urls();
|
1116 |
+
if ( !empty( $custom_urls ) ) {
|
1117 |
+
$urls[] = parse_url( $this->get_index_url('custom'), PHP_URL_PATH);
|
1118 |
+
}
|
1119 |
+
|
1120 |
+
// custom sitemaps
|
1121 |
+
foreach ($this->get_custom_sitemaps() as $url) {
|
1122 |
+
if ( !empty($url) && $this->is_allowed_domain($url) )
|
1123 |
+
$urls[] = parse_url( esc_url($url), PHP_URL_PATH);
|
1124 |
+
}
|
1125 |
+
}
|
1126 |
+
}
|
1127 |
+
|
1128 |
+
$urls[] = '/' . $pretty;
|
1129 |
+
|
1130 |
+
}
|
1131 |
+
|
1132 |
+
return $urls;
|
1133 |
+
}
|
1134 |
+
|
1135 |
+
/**
|
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');
|
1145 |
+
// ... but make sure rules are regenerated when admin is visited.
|
1146 |
+
set_transient('xmlsf_flush_rewrite_rules','');
|
1147 |
+
|
1148 |
+
// remove robots.txt rule blocking stylesheets, but only one time!
|
1149 |
+
if ( version_compare('4.4', $old_version, '>') && $robot_rules = get_option($this->prefix.'robots')) {
|
1150 |
+
$robot_rules = str_replace(array("Disallow: */wp-content/","Allow: */wp-content/uploads/"),"",$robot_rules);
|
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 );
|
1158 |
+
$terms = get_terms('gn-location-3',array('hide_empty' => false));
|
1159 |
+
foreach ( $terms as $term )
|
1160 |
+
wp_delete_term( $term->term_id, 'gn-location-3' );
|
1161 |
+
|
1162 |
+
register_taxonomy( 'gn-location-2', null );
|
1163 |
+
$terms = get_terms('gn-location-2',array('hide_empty' => false));
|
1164 |
+
foreach ( $terms as $term )
|
1165 |
+
wp_delete_term( $term->term_id, 'gn-location-2' );
|
1166 |
+
|
1167 |
+
register_taxonomy( 'gn-location-1', null );
|
1168 |
+
$terms = get_terms('gn-location-1',array('hide_empty' => false));
|
1169 |
+
foreach ( $terms as $term )
|
1170 |
+
wp_delete_term( $term->term_id, 'gn-location-1' );
|
1171 |
+
}
|
1172 |
+
|
1173 |
+
if ( version_compare('4.5', $old_version, '>') ) {
|
1174 |
+
// purge genres taxonomy terms
|
1175 |
+
$this->register_gn_taxonomies();
|
1176 |
+
$terms = get_terms('gn-genre',array('hide_empty' => false));
|
1177 |
+
foreach ( $terms as $term )
|
1178 |
+
wp_delete_term( $term->term_id, 'gn-genre' );
|
1179 |
+
set_transient('xmlsf_create_genres','', 10); // flag recreation
|
1180 |
+
}
|
1181 |
+
|
1182 |
+
// upgrade pings
|
1183 |
+
if ( $pong = get_option( $this->prefix.'pong' ) && is_array($pong) ) {
|
1184 |
+
$ping = $this->get_ping();
|
1185 |
+
foreach ( $pong as $se => $arr) {
|
1186 |
+
if ( is_array( $arr ) ) {
|
1187 |
+
// convert formatted time to unix time
|
1188 |
+
foreach ( $arr as $pretty => $date ) {
|
1189 |
+
$time = strtotime($date);
|
1190 |
+
$arr[$pretty] = (int)$time < time() ? $time : '';
|
1191 |
+
}
|
1192 |
+
// and set array
|
1193 |
+
$ping[$se]['pong'] = $arr;
|
1194 |
+
}
|
1195 |
+
}
|
1196 |
+
delete_option( $this->prefix.'pong' );
|
1197 |
+
delete_option( $this->prefix.'ping' );
|
1198 |
+
add_option( $this->prefix.'ping', array_merge( $this->defaults('ping'), $ping ), '', 'no' );
|
1199 |
+
}
|
1200 |
+
|
1201 |
+
delete_option('xmlsf_version');
|
1202 |
+
add_option($this->prefix.'version', XMLSF_VERSION, '', 'no');
|
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);
|
1221 |
+
|
1222 |
+
if ( version_compare(XMLSF_VERSION, $version, '>') )
|
1223 |
+
$this->upgrade($version);
|
1224 |
+
|
1225 |
+
// TAXONOMIES
|
1226 |
+
$sitemaps = $this->get_sitemaps();
|
1227 |
+
|
1228 |
+
if (isset($sitemaps['sitemap-news'])) {
|
1229 |
+
// register the taxonomies
|
1230 |
+
$this->register_gn_taxonomies();
|
1231 |
+
|
1232 |
+
// create terms
|
1233 |
+
if ( delete_transient('xmlsf_create_genres') ) {
|
1234 |
+
foreach ($this->gn_genres as $name) {
|
1235 |
+
wp_insert_term( $name, 'gn-genre' );
|
1236 |
+
}
|
1237 |
+
}
|
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');
|
1276 |
+
|
1277 |
+
$post_types = !empty($options['post_type']) ? $options['post_type'] : $defaults['post_type'];
|
1278 |
+
|
1279 |
+
register_taxonomy( 'gn-genre', $post_types, array(
|
1280 |
+
'hierarchical' => true,
|
1281 |
+
'labels' => array(
|
1282 |
+
'name' => __('Google News Genres','xml-sitemap-feed'),
|
1283 |
+
'singular_name' => __('Google News Genre','xml-sitemap-feed'),
|
1284 |
+
//'menu_name' => __('GN Genres','xml-sitemap-feed'),
|
1285 |
+
),
|
1286 |
+
'public' => false,
|
1287 |
+
'show_ui' => true,
|
1288 |
+
'show_tagcloud' => false,
|
1289 |
+
'query_var' => false,
|
1290 |
+
'capabilities' => array( // prevent creation / deletion
|
1291 |
+
'manage_terms' => 'nobody',
|
1292 |
+
'edit_terms' => 'nobody',
|
1293 |
+
'delete_terms' => 'nobody',
|
1294 |
+
'assign_terms' => 'edit_posts'
|
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();
|
1304 |
+
if(function_exists('memory_get_peak_usage'))
|
1305 |
+
echo ' | Peak memory usage '.round(memory_get_peak_usage()/1024/1024,2).'M';
|
1306 |
+
echo ' -->';
|
1307 |
+
}
|
1308 |
+
}
|
1309 |
+
|
1310 |
+
/**
|
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 |
+
|
1364 |
+
endif;
|
includes/feed-sitemap-news.php
CHANGED
@@ -42,6 +42,9 @@ echo '">
|
|
42 |
$language = explode('-', convert_chars(strip_tags(get_bloginfo('language'))));
|
43 |
$language = empty($language) ? 'en' : reset($language);
|
44 |
|
|
|
|
|
|
|
45 |
// loop away!
|
46 |
if ( have_posts() ) :
|
47 |
while ( have_posts() ) :
|
@@ -49,10 +52,11 @@ if ( have_posts() ) :
|
|
49 |
|
50 |
// check if we are not dealing with an external URL :: Thanks to Francois Deschenes :)
|
51 |
// or if post meta says "exclude me please"
|
52 |
-
$exclude = get_post_meta( $post->ID, '
|
53 |
if ( !empty($exclude) || !$xmlsf->is_allowed_domain(get_permalink()) )
|
54 |
continue;
|
55 |
|
|
|
56 |
?>
|
57 |
<url>
|
58 |
<loc><?php echo esc_url( get_permalink() ); ?></loc>
|
@@ -66,10 +70,12 @@ if ( have_posts() ) :
|
|
66 |
else
|
67 |
echo apply_filters( 'the_title_xmlsitemap', get_bloginfo('name') ); ?></news:name>
|
68 |
<news:language><?php
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
|
|
|
|
73 |
} else {
|
74 |
echo $language;
|
75 |
} ?></news:language>
|
@@ -79,16 +85,19 @@ if ( have_posts() ) :
|
|
79 |
<news:title><?php echo apply_filters( 'the_title_xmlsitemap', get_the_title() ); ?></news:title>
|
80 |
<?php
|
81 |
// access tag
|
82 |
-
$access = '';
|
83 |
-
|
|
|
|
|
84 |
if ( post_password_required() ) {
|
85 |
if (!empty($options['access']['password'])) $access = $options['access']['password'];
|
86 |
} else {
|
87 |
if (!empty($options['access']['default'])) $access = $options['access']['default'];
|
88 |
}
|
89 |
-
|
90 |
-
|
91 |
-
|
|
|
92 |
?>
|
93 |
<news:access><?php echo $access; ?></news:access>
|
94 |
<?php
|
@@ -178,8 +187,10 @@ if ( have_posts() ) :
|
|
178 |
</url>
|
179 |
<?php
|
180 |
endwhile;
|
181 |
-
|
182 |
-
|
|
|
|
|
183 |
|
184 |
$lastmodified_gmt = get_lastmodified('GMT'); // last posts or page modified date
|
185 |
?>
|
42 |
$language = explode('-', convert_chars(strip_tags(get_bloginfo('language'))));
|
43 |
$language = empty($language) ? 'en' : reset($language);
|
44 |
|
45 |
+
// set empty news sitemap flag
|
46 |
+
$have_posts = false;
|
47 |
+
|
48 |
// loop away!
|
49 |
if ( have_posts() ) :
|
50 |
while ( have_posts() ) :
|
52 |
|
53 |
// check if we are not dealing with an external URL :: Thanks to Francois Deschenes :)
|
54 |
// or if post meta says "exclude me please"
|
55 |
+
$exclude = get_post_meta( $post->ID, '_xmlsf_news_exclude', true );
|
56 |
if ( !empty($exclude) || !$xmlsf->is_allowed_domain(get_permalink()) )
|
57 |
continue;
|
58 |
|
59 |
+
$have_posts = true;
|
60 |
?>
|
61 |
<url>
|
62 |
<loc><?php echo esc_url( get_permalink() ); ?></loc>
|
70 |
else
|
71 |
echo apply_filters( 'the_title_xmlsitemap', get_bloginfo('name') ); ?></news:name>
|
72 |
<news:language><?php
|
73 |
+
if ( taxonomy_exists('language') ) {
|
74 |
+
$lang = get_the_terms($post->ID,'language');
|
75 |
+
if ( is_array($lang) ) {
|
76 |
+
$lang = reset($lang);
|
77 |
+
echo is_object($lang) ? $lang->slug : $language;
|
78 |
+
}
|
79 |
} else {
|
80 |
echo $language;
|
81 |
} ?></news:language>
|
85 |
<news:title><?php echo apply_filters( 'the_title_xmlsitemap', get_the_title() ); ?></news:title>
|
86 |
<?php
|
87 |
// access tag
|
88 |
+
$access = get_post_meta( $post->ID, '_xmlsf_news_access', true );
|
89 |
+
|
90 |
+
if (empty($access)) : // if not set per meta, let's get global settings
|
91 |
+
if (!empty($options['access'])) {
|
92 |
if ( post_password_required() ) {
|
93 |
if (!empty($options['access']['password'])) $access = $options['access']['password'];
|
94 |
} else {
|
95 |
if (!empty($options['access']['default'])) $access = $options['access']['default'];
|
96 |
}
|
97 |
+
}
|
98 |
+
endif;
|
99 |
+
|
100 |
+
if (!empty($access) && $access != 'Public' ) {
|
101 |
?>
|
102 |
<news:access><?php echo $access; ?></news:access>
|
103 |
<?php
|
187 |
</url>
|
188 |
<?php
|
189 |
endwhile;
|
190 |
+
endif;
|
191 |
+
|
192 |
+
if ( !$have_posts ) :
|
193 |
+
// No posts done? Then do at least the homepage to prevent error message in WMT.
|
194 |
|
195 |
$lastmodified_gmt = get_lastmodified('GMT'); // last posts or page modified date
|
196 |
?>
|
includes/feed-sitemap.php
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
<?php
|
2 |
/**
|
3 |
-
*
|
4 |
*
|
5 |
* @package XML Sitemap Feed plugin for WordPress
|
6 |
*/
|
@@ -28,13 +28,10 @@ global $xmlsf;
|
|
28 |
<lastmod><?php echo mysql2date('Y-m-d\TH:i:s+00:00', get_lastdate( 'gmt' ), false); ?></lastmod>
|
29 |
</sitemap>
|
30 |
<?php
|
31 |
-
// add rules for
|
32 |
-
foreach ( $xmlsf->have_post_types() as $post_type )
|
|
|
33 |
|
34 |
-
if (!empty($post_type['archive']))
|
35 |
-
$archive = $post_type['archive'];
|
36 |
-
else
|
37 |
-
$archive = '';
|
38 |
foreach ( $xmlsf->get_archives($post_type['name'],$archive) as $m => $url ) {
|
39 |
?>
|
40 |
<sitemap>
|
@@ -43,11 +40,10 @@ foreach ( $xmlsf->have_post_types() as $post_type ) :
|
|
43 |
</sitemap>
|
44 |
<?php
|
45 |
}
|
46 |
-
|
47 |
-
|
48 |
-
// add rules for custom public post taxonomies
|
49 |
-
foreach ( $xmlsf->get_taxonomies() as $taxonomy ) :
|
50 |
|
|
|
|
|
51 |
if ( wp_count_terms( $taxonomy, array('hide_empty'=>true) ) > 0 ) {
|
52 |
?>
|
53 |
<sitemap>
|
@@ -55,17 +51,17 @@ foreach ( $xmlsf->get_taxonomies() as $taxonomy ) :
|
|
55 |
<?php echo $xmlsf->get_lastmod('taxonomy',$taxonomy); ?></sitemap>
|
56 |
<?php
|
57 |
}
|
58 |
-
|
59 |
|
60 |
// custom URLs sitemap
|
61 |
$urls = $xmlsf->get_urls();
|
62 |
-
if ( !empty($urls) )
|
63 |
?>
|
64 |
<sitemap>
|
65 |
<loc><?php echo $xmlsf->get_index_url('custom'); ?></loc>
|
66 |
</sitemap>
|
67 |
<?php
|
68 |
-
|
69 |
|
70 |
// custom sitemaps
|
71 |
$custom_sitemaps = $xmlsf->get_custom_sitemaps();
|
@@ -78,5 +74,6 @@ foreach ($custom_sitemaps as $url) {
|
|
78 |
</sitemap>
|
79 |
<?php
|
80 |
}
|
|
|
81 |
?></sitemapindex>
|
82 |
<?php $xmlsf->_e_usage();
|
1 |
<?php
|
2 |
/**
|
3 |
+
* XML Sitemap Index Feed Template
|
4 |
*
|
5 |
* @package XML Sitemap Feed plugin for WordPress
|
6 |
*/
|
28 |
<lastmod><?php echo mysql2date('Y-m-d\TH:i:s+00:00', get_lastdate( 'gmt' ), false); ?></lastmod>
|
29 |
</sitemap>
|
30 |
<?php
|
31 |
+
// add rules for public post types
|
32 |
+
foreach ( $xmlsf->have_post_types() as $post_type ) {
|
33 |
+
$archive = isset($post_type['archive']) ? $post_type['archive'] : '';
|
34 |
|
|
|
|
|
|
|
|
|
35 |
foreach ( $xmlsf->get_archives($post_type['name'],$archive) as $m => $url ) {
|
36 |
?>
|
37 |
<sitemap>
|
40 |
</sitemap>
|
41 |
<?php
|
42 |
}
|
43 |
+
}
|
|
|
|
|
|
|
44 |
|
45 |
+
// add rules for public taxonomies
|
46 |
+
foreach ( $xmlsf->get_taxonomies() as $taxonomy ) {
|
47 |
if ( wp_count_terms( $taxonomy, array('hide_empty'=>true) ) > 0 ) {
|
48 |
?>
|
49 |
<sitemap>
|
51 |
<?php echo $xmlsf->get_lastmod('taxonomy',$taxonomy); ?></sitemap>
|
52 |
<?php
|
53 |
}
|
54 |
+
}
|
55 |
|
56 |
// custom URLs sitemap
|
57 |
$urls = $xmlsf->get_urls();
|
58 |
+
if ( !empty($urls) ) {
|
59 |
?>
|
60 |
<sitemap>
|
61 |
<loc><?php echo $xmlsf->get_index_url('custom'); ?></loc>
|
62 |
</sitemap>
|
63 |
<?php
|
64 |
+
}
|
65 |
|
66 |
// custom sitemaps
|
67 |
$custom_sitemaps = $xmlsf->get_custom_sitemaps();
|
74 |
</sitemap>
|
75 |
<?php
|
76 |
}
|
77 |
+
|
78 |
?></sitemapindex>
|
79 |
<?php $xmlsf->_e_usage();
|
includes/xsl/sitemap-news.xsl
CHANGED
@@ -16,7 +16,8 @@
|
|
16 |
<body>
|
17 |
<h1>Google News Sitemap Feed</h1>
|
18 |
<div id="header">
|
19 |
-
<p>This is a Google News Sitemap to aid <a href="http://news.google.com">Google News</a> finding news on your website. Please note that <strong><em>only posts from the last 48 hours</em></strong> will be processed by Google News
|
|
|
20 |
</div>
|
21 |
<div id="content">
|
22 |
<table cellpadding="5">
|
@@ -24,6 +25,7 @@
|
|
24 |
<th>#</th>
|
25 |
<th>Title</th>
|
26 |
<th>Language</th>
|
|
|
27 |
<th>Genre(s)</th>
|
28 |
<th>Keyword(s)</th>
|
29 |
<th>Image(s)</th>
|
@@ -38,6 +40,7 @@
|
|
38 |
<a href="{$itemURL}"><xsl:value-of select="news:news/news:title"/></a>
|
39 |
</td>
|
40 |
<td><xsl:value-of select="news:news/news:publication/news:language"/></td>
|
|
|
41 |
<td><xsl:value-of select="news:news/news:genres"/></td>
|
42 |
<td><xsl:value-of select="news:news/news:keywords"/></td>
|
43 |
<td><xsl:value-of select="count(image:image)"/></td>
|
16 |
<body>
|
17 |
<h1>Google News Sitemap Feed</h1>
|
18 |
<div id="header">
|
19 |
+
<p>This is a <a href="https://support.google.com/news/publisher/answer/75717" target="_blank">Google News Sitemap</a> to aid <a href="http://news.google.com" target="_blank">Google News</a> finding news on your website. Please note that <strong><em>only posts from the last 48 hours</em></strong> will be processed by Google News.</p>
|
20 |
+
<p>Follow the guidelines on <a href="https://support.google.com/news/publisher/answer/40787" target="_blank">Getting into Google News</a> and when you're ready, apply for inclusion within the <a href="https://partnerdash.google.com/partnerdash/d/news#p:id=pfehome">Google News Publisher Center</a>. For general questions about Google News, please see the <a href="https://groups.google.com/a/googleproductforums.com/forum/#!categories/news/google-news-publishers" target="_blank">Publisher Help Forum</a>.</p>
|
21 |
</div>
|
22 |
<div id="content">
|
23 |
<table cellpadding="5">
|
25 |
<th>#</th>
|
26 |
<th>Title</th>
|
27 |
<th>Language</th>
|
28 |
+
<th>Access</th>
|
29 |
<th>Genre(s)</th>
|
30 |
<th>Keyword(s)</th>
|
31 |
<th>Image(s)</th>
|
40 |
<a href="{$itemURL}"><xsl:value-of select="news:news/news:title"/></a>
|
41 |
</td>
|
42 |
<td><xsl:value-of select="news:news/news:publication/news:language"/></td>
|
43 |
+
<td><xsl:value-of select="news:news/news:access"/></td>
|
44 |
<td><xsl:value-of select="news:news/news:genres"/></td>
|
45 |
<td><xsl:value-of select="news:news/news:keywords"/></td>
|
46 |
<td><xsl:value-of select="count(image:image)"/></td>
|
readme.txt
CHANGED
@@ -3,8 +3,8 @@ Contributors: RavanH
|
|
3 |
Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=ravanhagen%40gmail%2ecom&item_name=XML%20Sitemap%20Feed&item_number=3%2e8&no_shipping=0&tax=0&bn=PP%2dDonationsBF&charset=UTF%2d8&lc=us
|
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.
|
7 |
-
Stable tag: 4.
|
8 |
|
9 |
XML and Google News Sitemaps to feed the hungry spiders. Multisite, WP Super Cache and Polylang compatible.
|
10 |
|
@@ -16,7 +16,7 @@ The main advantage of this plugin over other XML Sitemap plugins is **simplicity
|
|
16 |
|
17 |
You, or site owners on your Multisite network, will not be bothered with overly complicated settings like most other XML Sitemap plugins. The default settings will suffice in most cases and XML sitemap values like ChangeFreq and URL Priority are auto-calculated based on post age and comment activity.
|
18 |
|
19 |
-
|
20 |
|
21 |
Please read the FAQ's for info on how to get your articles listed on Google News.
|
22 |
|
@@ -293,12 +293,18 @@ Thanks for sharing your translation :)
|
|
293 |
|
294 |
== Upgrade Notice ==
|
295 |
|
296 |
-
= 4.
|
297 |
-
|
298 |
-
|
299 |
|
300 |
== Changelog ==
|
301 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
302 |
= 4.4.1 =
|
303 |
* BUGFIX contribution by alejandra.aranibar: multiple news post types makes get_lastdate return oldest instead of newest date
|
304 |
* BUGFIX plugins_url filter not working, reported by Michael
|
3 |
Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=ravanhagen%40gmail%2ecom&item_name=XML%20Sitemap%20Feed&item_number=3%2e8&no_shipping=0&tax=0&bn=PP%2dDonationsBF&charset=UTF%2d8&lc=us
|
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.4
|
7 |
+
Stable tag: 4.5
|
8 |
|
9 |
XML and Google News Sitemaps to feed the hungry spiders. Multisite, WP Super Cache and Polylang compatible.
|
10 |
|
16 |
|
17 |
You, or site owners on your Multisite network, will not be bothered with overly complicated settings like most other XML Sitemap plugins. The default settings will suffice in most cases and XML sitemap values like ChangeFreq and URL Priority are auto-calculated based on post age and comment activity.
|
18 |
|
19 |
+
An XML Sitemap Index becomes instantly available on **yourblog.url/sitemap.xml** (or yourblog.url/?feed=sitemap if you're not using a 'fancy' permalink structure) containing references to posts and pages by default, ready for indexing by search engines like Google, Bing, Yahoo, AOL and Ask. When the Google News Sitemap is activated, it will become available on **yourblog.url/sitemap-news.xml** (or yourblog.url/?feed=sitemap-news), ready for indexing by Google News. Both are automatically referenced in the dynamically created **robots.txt** on **yourblog.url/robots.txt** to tell search engines where to find your XML Sitemaps. Google and Bing can be pinged on each new publication.
|
20 |
|
21 |
Please read the FAQ's for info on how to get your articles listed on Google News.
|
22 |
|
293 |
|
294 |
== Upgrade Notice ==
|
295 |
|
296 |
+
= 4.5 =
|
297 |
+
Set access or exclude individual posts from Google News sitemap. Improved cache handling and Nginx Helper compatibility.
|
|
|
298 |
|
299 |
== Changelog ==
|
300 |
|
301 |
+
= 4.5 =
|
302 |
+
* Set Google News access tag per post
|
303 |
+
* Exclude posts from Google News sitemap
|
304 |
+
* News Sitemap stylesheet text/links update
|
305 |
+
* FIX: delete cached key as suggested by Jeremy Clarke https://wordpress.org/support/topic/please-stop-running-wp_cache_flush-whenever-posts-are-edited
|
306 |
+
* NEW: Nginx Helper compatibility to purge cache sitemap URLs from FastCGI Cache or Redis
|
307 |
+
|
308 |
= 4.4.1 =
|
309 |
* BUGFIX contribution by alejandra.aranibar: multiple news post types makes get_lastdate return oldest instead of newest date
|
310 |
* BUGFIX plugins_url filter not working, reported by Michael
|
xml-sitemap.php
CHANGED
@@ -4,7 +4,7 @@ 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.
|
8 |
Author: RavanH
|
9 |
Author URI: http://status301.net/
|
10 |
*/
|
@@ -47,7 +47,7 @@ if(!empty($_SERVER['SCRIPT_FILENAME']) && 'xml-sitemap.php' == basename($_SERVER
|
|
47 |
* CONSTANTS
|
48 |
* -------------------- */
|
49 |
|
50 |
-
define('XMLSF_VERSION', '4.
|
51 |
|
52 |
define('XMLSF_PLUGIN_BASENAME', plugin_basename(__FILE__));
|
53 |
|
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
|
8 |
Author: RavanH
|
9 |
Author URI: http://status301.net/
|
10 |
*/
|
47 |
* CONSTANTS
|
48 |
* -------------------- */
|
49 |
|
50 |
+
define('XMLSF_VERSION', '4.5');
|
51 |
|
52 |
define('XMLSF_PLUGIN_BASENAME', plugin_basename(__FILE__));
|
53 |
|