XML Sitemap & Google News feeds - Version 4.4

Version Description

Google News Sitemap: limit posts to certain categories. Some (query) optimizations and bugfixes.

=

Download this release

Release Info

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

Code changes from version 4.3.2 to 4.4

hacks.php CHANGED
@@ -3,144 +3,6 @@
3
* MISSING WORDPRESS FUNCTIONS
4
* ------------------------------------- */
5
6
- /**
7
- * Retrieve the date that the last page was published.
8
- *
9
- * The server timezone is the default and is the difference between GMT and
10
- * server time. The 'blog' value is the date when the last post was posted. The
11
- * 'gmt' is when the last post was posted in GMT formatted date.
12
- *
13
- * Variation of get_lastpostdate defined in wp-includes/post.php since 0.71
14
- *
15
- * @uses apply_filters() Calls 'get_lastpagedate' filter
16
- *
17
- * @param string $timezone The location to get the time. Can be 'gmt', 'blog', or 'server'.
18
- * @return string The date of the last post.
19
-
20
- if( !function_exists('get_lastpagedate') ) {
21
- function get_lastpagedate($timezone = 'server') {
22
- return apply_filters( 'get_lastpagedate', _get_time( $timezone, 'date', 'page' ), $timezone );
23
- }
24
- } */
25
-
26
- /**
27
- * Retrieve last page modified date depending on timezone.
28
- *
29
- * The server timezone is the default and is the difference between GMT and
30
- * server time. The 'blog' value is just when the last post was modified. The
31
- * 'gmt' is when the last post was modified in GMT time.
32
- *
33
- * Variation of get_lastpostmodified defined in wp-includes/post.php since 1.2.0
34
- *
35
- * @uses apply_filters() Calls 'get_lastpagemodified' filter
36
- *
37
- * @param string $timezone The location to get the time. Can be 'gmt', 'blog', or 'server'.
38
- * @return string The date the post was last modified.
39
-
40
- if( !function_exists('get_lastpagemodified') ) {
41
- function get_lastpagemodified($timezone = 'server') {
42
- $lastpagemodified = _get_time( $timezone, 'modified', 'page' );
43
-
44
- $lastpagedate = get_lastpagedate($timezone);
45
- if ( $lastpagedate > $lastpagemodified )
46
- $lastpagemodified = $lastpagedate;
47
-
48
- return apply_filters( 'get_lastpagemodified', $lastpagemodified, $timezone );
49
- }
50
- } */
51
-
52
- /**
53
- * Retrieve the date that the first post was published.
54
- *
55
- * The server timezone is the default and is the difference between GMT and
56
- * server time. The 'blog' value is the date when the last post was posted. The
57
- * 'gmt' is when the last post was posted in GMT formatted date.
58
- *
59
- * Reverse of get_lastpostdate defined in wp-includes/post.php since 0.71
60
- *
61
- * @uses apply_filters() Calls 'get_firstpostdate' filter
62
- *
63
- * @param string $timezone The location to get the time. Can be 'gmt', 'blog', or 'server'.
64
- * @return string The date of the last post.
65
-
66
- if( !function_exists('get_firstpostdate') ) {
67
- function get_firstpostdate($timezone = 'server') {
68
- return apply_filters( 'get_firstpostdate', _get_time( $timezone, 'date', 'post', 'first' ), $timezone );
69
- }
70
- } */
71
-
72
- /**
73
- * Retrieve the date that the first page was published.
74
- *
75
- * The server timezone is the default and is the difference between GMT and
76
- * server time. The 'blog' value is the date when the last post was posted. The
77
- * 'gmt' is when the last post was posted in GMT formatted date.
78
- *
79
- * Adaptation of get_firstpostdate defined in this file
80
- *
81
- * @uses apply_filters() Calls 'get_firstpagedate' filter
82
- *
83
- * @param string $timezone The location to get the time. Can be 'gmt', 'blog', or 'server'.
84
- * @return string The date of the last post.
85
-
86
- if( !function_exists('get_firstpagedate') ) {
87
- function get_firstpagedate($timezone = 'server') {
88
- return apply_filters( 'get_firstpagedate', _get_time( $timezone, 'date', 'page', 'first' ), $timezone );
89
- }
90
- } */
91
-
92
- /**
93
- * Retrieve first post modified date depending on timezone.
94
- *
95
- * The server timezone is the default and is the difference between GMT and
96
- * server time. The 'blog' value is the date when the last post was posted. The
97
- * 'gmt' is when the last post was posted in GMT formatted date.
98
- *
99
- * Reverse of get_lastpostmodified defined in wp-includes/post.php since WP 1.2.0
100
- *
101
- * @uses apply_filters() Calls 'get_firstpostmodified' filter
102
- *
103
- * @param string $timezone The location to get the time. Can be 'gmt', 'blog', or 'server'.
104
- * @return string The date of the oldest modified post.
105
-
106
- if( !function_exists('get_firstpostmodified') ) {
107
- function get_firstpostmodified($timezone = 'server') {
108
- $firstpostmodified = _get_time( $timezone, 'modified', 'post', 'first' );
109
-
110
- $firstpostdate = get_firstpostdate($timezone);
111
- if ( $firstpostdate > $firstpostmodified )
112
- $firstpostmodified = $firstpostdate;
113
-
114
- return apply_filters( 'get_firstpostmodified', $firstpostmodified, $timezone );
115
- }
116
- } */
117
-
118
- /**
119
- * Retrieve first page modified date depending on timezone.
120
- *
121
- * The server timezone is the default and is the difference between GMT and
122
- * server time. The 'blog' value is the date when the last post was posted. The
123
- * 'gmt' is when the last post was posted in GMT formatted date.
124
- *
125
- * Variation of get_firstpostmodified defined in this file
126
- *
127
- * @uses apply_filters() Calls 'get_firstpagemodified' filter
128
- *
129
- * @param string $timezone The location to get the time. Can be 'gmt', 'blog', or 'server'.
130
- * @return string The date of the oldest modified page.
131
-
132
- if( !function_exists('get_firstpagemodified') ) {
133
- function get_firstpagemodified($timezone = 'server') {
134
- $firstpagemodified = _get_time( $timezone, 'modified', 'page', 'first' );
135
-
136
- $firstpagedate = get_firstpagedate($timezone);
137
- if ( $firstpagedate > $firstpagemodified )
138
- $firstpagemodified = $firstpagedate;
139
-
140
- return apply_filters( 'get_firstpagemodified', $firstpagemodified, $timezone );
141
- }
142
- } */
143
-
144
/**
145
* Retrieve the date that the first post/page was published.
146
*
@@ -160,30 +22,6 @@ if( !function_exists('get_firstdate') ) {
160
}
161
}
162
163
- /**
164
- * Retrieve first post/page modified date depending on timezone.
165
- *
166
- * The server timezone is the default and is the difference between GMT and
167
- * server time. The 'blog' value is the date when the last post was posted. The
168
- * 'gmt' is when the last post was posted in GMT formatted date.
169
- *
170
- * @uses apply_filters() Calls 'get_firstmodified' filter
171
- *
172
- * @param string $timezone The location to get the time. Can be 'gmt', 'blog', or 'server'.
173
- * @return string The date of the oldest modified post or page.
174
-
175
- if( !function_exists('get_firstmodified') ) {
176
- function get_firstmodified($timezone = 'server') {
177
- $firstmodified = _get_time( $timezone, 'modified', 'any', 'first' );
178
-
179
- $firstdate = get_firstdate($timezone);
180
- if ( $firstdate > $firstmodified )
181
- $firstmodified = $firstdate;
182
-
183
- return apply_filters( 'get_firstmodified', $firstmodified, $timezone );
184
- }
185
- } */
186
-
187
/**
188
* Retrieve the date that the last post/page was published.
189
*
@@ -208,8 +46,8 @@ if( !function_exists('get_lastdate') ) {
208
$lastmodified[] = _get_time( $timezone, 'date', $post_type, 'last', $m );
209
210
sort($lastmodified);
211
-
212
- return apply_filters( 'get_lastdate', array_shift(array_filter($lastmodified)), $timezone );
213
}
214
}
215
@@ -227,12 +65,6 @@ if( !function_exists('get_lastdate') ) {
227
*/
228
if( !function_exists('get_lastmodified') ) {
229
function get_lastmodified($timezone = 'server', $post_type = 'any', $m = false) {
230
- //$lastmodified = _get_time( $timezone, 'modified', $post_type, 'last', $m );
231
-
232
- //$lastdate = get_lastdate($timezone, $post_type, $m);
233
- //if ( $lastdate > $lastmodified )
234
- // $lastmodified = $lastdate;
235
-
236
return apply_filters( 'get_lastmodified', _get_time( $timezone, 'modified', $post_type, 'last', $m ), $timezone );
237
}
238
}
@@ -241,8 +73,6 @@ if( !function_exists('get_lastmodified') ) {
241
* Retrieve first or last post type date data based on timezone.
242
* Variation of function _get_last_post_time
243
*
244
- * @access private
245
- *
246
* @param string $timezone The location to get the time. Can be 'gmt', 'blog', or 'server'.
247
* @param string $field Field to check. Can be 'date' or 'modified'.
248
* @param string $post_type Post type to check. Defaults to 'any'.
@@ -313,35 +143,3 @@ if( !function_exists('_get_time') ) {
313
return $date;
314
}
315
}
316
-
317
- /* By gunter [dot] sammet [at] gmail [dot] com http://www.php.net/manual/en/function.htmlentities.php#88169 */
318
- $entity_custom_from = false;
319
- $entity_custom_to = false;
320
- function html_entity_decode_encode_rss($data) {
321
- global $entity_custom_from, $entity_custom_to;
322
-
323
- if(!is_array($entity_custom_from) || !is_array($entity_custom_to)) {
324
- $array_position = 0;
325
- foreach (get_html_translation_table(HTML_ENTITIES) as $key => $value) {
326
- switch ($value) {
327
- case ' ':
328
- break;
329
- case '>':
330
- case '<':
331
- case '"':
332
- case ''':
333
- case '&':
334
- $entity_custom_from[$array_position] = $key;
335
- $entity_custom_to[$array_position] = $value;
336
- $array_position++;
337
- break;
338
- default:
339
- $entity_custom_from[$array_position] = $value;
340
- $entity_custom_to[$array_position] = $key;
341
- $array_position++;
342
- }
343
- }
344
- }
345
- return str_replace($entity_custom_from, $entity_custom_to, $data);
346
- }
347
-
3
* MISSING WORDPRESS FUNCTIONS
4
* ------------------------------------- */
5
6
/**
7
* Retrieve the date that the first post/page was published.
8
*
22
}
23
}
24
25
/**
26
* Retrieve the date that the last post/page was published.
27
*
46
$lastmodified[] = _get_time( $timezone, 'date', $post_type, 'last', $m );
47
48
sort($lastmodified);
49
+ $lastmodified = array_filter($lastmodified);
50
+ return apply_filters( 'get_lastdate', reset($lastmodified), $timezone );
51
}
52
}
53
65
*/
66
if( !function_exists('get_lastmodified') ) {
67
function get_lastmodified($timezone = 'server', $post_type = 'any', $m = false) {
68
return apply_filters( 'get_lastmodified', _get_time( $timezone, 'modified', $post_type, 'last', $m ), $timezone );
69
}
70
}
73
* Retrieve first or last post type date data based on timezone.
74
* Variation of function _get_last_post_time
75
*
76
* @param string $timezone The location to get the time. Can be 'gmt', 'blog', or 'server'.
77
* @param string $field Field to check. Can be 'date' or 'modified'.
78
* @param string $post_type Post type to check. Defaults to 'any'.
143
return $date;
144
}
145
}
includes/admin.php CHANGED
@@ -25,8 +25,7 @@
25
<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>';
26
if (isset($options['sitemap-news']))
27
echo '<span class="description"> &nbsp;&ndash;&nbsp; <a href="#xmlnf" id="xmlnf_link">'.translate('Settings').'</a> &nbsp;&ndash;&nbsp; <a href="'.trailingslashit(get_bloginfo('url')). ( ('' == get_option('permalink_structure')) ? '?feed=sitemap-news' : $options['sitemap-news'] ) .'" target="_blank">'.translate('View').'</a></span>';
28
- else
29
- // echo '<span class="description"> '.__('Only set when your site has been or will soon be accepted by Google News.','xml-sitemap-feed').'</span>';
30
echo '
31
</fieldset>';
32
echo '
@@ -58,11 +57,12 @@
58
</script>';
59
}
60
61
public function ping_settings_field() {
62
$options = parent::get_ping();
63
$defaults = parent::defaults('ping');
64
$update_services = get_option('ping_sites');
65
- $pinged = parent::get_pong();
66
$prefix = parent::prefix();
67
$names = array(
68
'google' => array (
@@ -86,18 +86,14 @@
86
$defaults[$key] += $values;
87
}
88
echo '
89
- <fieldset id="xmlsf_ping"><legend class="screen-reader-text">'.__('Ping on Publish','xml-sitemap-feed').'</legend>
90
';
91
foreach ( $defaults as $key => $values ) {
92
93
- echo '
94
- <input type="hidden" name="'.$prefix.'ping['.
95
- $key.'][uri]" value="'.
96
- $values['uri'].'" />';
97
if ( isset($values['type']) && $values['type'] == 'RPC' ) {
98
$active = ( strpos($update_services,untrailingslashit($values['uri'])) === false ) ? false : true;
99
} else {
100
- $active = !empty($options[$key]["active"]) ? true : false;
101
}
102
echo '
103
<label><input type="checkbox" name="'.$prefix.'ping['.
@@ -107,10 +103,40 @@
107
echo isset($names[$key]) && !empty($names[$key]['name']) ? $names[$key]['name'] : $key ;
108
echo '</label>';
109
110
echo ' <span class="description">';
111
- if (isset($pinged[$key]))
112
- foreach ((array)$pinged[$key] as $pretty => $time)
113
- echo sprintf(__('Successfully pinged for %1$s on %2$s GMT.','xml-sitemap-feed'),$pretty, $time).' ';
114
echo '</span><br />';
115
}
116
@@ -118,19 +144,70 @@
118
</fieldset>';
119
}
120
121
public function robots_settings_field() {
122
- $prefix = parent::prefix();
123
- echo '<label>'.sprintf(__('Rules to append to the %s generated by WordPress.','xml-sitemap-feed'),'<a href="'.trailingslashit(get_bloginfo('url')).'robots.txt" target="_blank">robots.txt</a>').'<br /><textarea name="'.$prefix.'robots" id="xmlsf_robots" class="large-text" cols="50" rows="6" />'.esc_attr( parent::get_robots() ).'</textarea></label>
124
- <p class="description"><span style="color: red" class="error">'.__('Only add rules here when you know what you are doing, otherwise you might break search engine access to your site.','xml-sitemap-feed').'</span><br />'.__('These rules will not have effect when you are using a static robots.txt file.','xml-sitemap-feed').'</p>';
125
}
126
127
public function reset_settings_field() {
128
- $prefix = parent::prefix();
129
echo '
130
- <label><input type="checkbox" name="'.$prefix.'sitemaps[reset]" value="1" /> '.
131
- __('Clear all XML Sitemap Feed options from the database and start fresh with the default settings.','xml-sitemap-feed').'</label>';
132
echo '
133
- <p class="description">'.sprintf(__('Disabling and reenabling the %s plugin will have the same effect.','xml-sitemap-feed'),__('XML Sitemap & Google News Feeds','xml-sitemap-feed')).'</p>';
134
}
135
136
/**
@@ -138,7 +215,11 @@
138
*/
139
140
public function xml_sitemap_settings() {
141
- echo '<p><a href="https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=ravanhagen%40gmail%2ecom&item_name=XML%20Sitemap%20Feeds&item_number='.XMLSF_VERSION.'&no_shipping=0&tax=0&charset=UTF%2d8" title="'.sprintf(__('Donate to keep the free %s plugin development & support going!','xml-sitemap-feed'),__('XML Sitemap & Google News Feeds','xml-sitemap-feed')).'"><img src="https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif" style="border:none;float:right;margin:4px 0 0 10px" alt="'.sprintf(__('Donate to keep the free %s plugin development & support going!','xml-sitemap-feed'),__('XML Sitemap & Google News Feeds','xml-sitemap-feed')).'" width="92" height="26" /></a>'.sprintf(__('These settings control the XML Sitemaps generated by the %s plugin.','xml-sitemap-feed'),__('XML Sitemap & Google News Feeds','xml-sitemap-feed')).'</p>';
142
}
143
144
public function post_types_settings_field() {
@@ -147,9 +228,13 @@
147
$prefix = parent::prefix();
148
$do_note = false;
149
150
echo '<fieldset id="xmlsf_post_types"><legend class="screen-reader-text">'.__('XML Sitemaps for post types','xml-sitemap-feed').'</legend>
151
';
152
- foreach ( get_post_types(array('public'=>true),'objects') as $post_type ) {
153
// skip unallowed post types
154
if (in_array($post_type->name,parent::disabled_post_types()))
155
continue;
@@ -240,7 +325,8 @@
240
}
241
242
echo '
243
- <p class="description">* '.__('Priority settings do not affect ranking in search results in any way. They are only meant to suggest search engines which URLs to index first. Once a URL has been indexed, its Priority becomes meaningless until its Lastmod is updated.','xml-sitemap-feed').' <a href="#xmlsf_post_types_note_1_more" id="xmlsf_post_types_note_1_link">'.translate('[more]').'</a> <span id="xmlsf_post_types_note_1_more">'.__('Maximum Priority (1.0) is reserved for the front page, individual posts and, when allowed, posts with high comment count.','xml-sitemap-feed').' '.__('Priority values are taken as relative values. Setting all to the same (high) value is pointless.','xml-sitemap-feed').'</span></p>
244
<script type="text/javascript">
245
jQuery( document ).ready( function() {
246
jQuery("#xmlsf_post_types_note_1_more").hide();
@@ -258,7 +344,6 @@ jQuery( document ).ready( function() {
258
public function taxonomies_settings_field() {
259
$options = parent::get_taxonomies();
260
$active = parent::get_option('post_types');
261
- $prefix = parent::prefix();
262
$output = '';
263
264
foreach ( get_taxonomies(array('public'=>true),'objects') as $taxonomy ) {
@@ -274,7 +359,7 @@ jQuery( document ).ready( function() {
274
275
$count = wp_count_terms( $taxonomy->name );
276
$output .= '
277
- <label><input type="checkbox" name="'.$prefix.'taxonomies['.
278
$taxonomy->name.']" id="xmlsf_taxonomies_'.
279
$taxonomy->name.'" value="'.
280
$taxonomy->name.'"'.
@@ -297,7 +382,9 @@ jQuery( document ).ready( function() {
297
echo $output;
298
299
echo '
300
- <p class="description">'.__('It is generally not recommended to include taxonomy pages, unless their content brings added value.','xml-sitemap-feed').' <a href="#xmlsf_taxonomies_note_1_more" id="xmlsf_taxonomies_note_1_link">'.translate('[more]').'</a> <span id="xmlsf_taxonomies_note_1_more">'.__('For example, when you use category descriptions with information that is not present elsewhere on your site or if taxonomy pages list posts with an excerpt that is different from, but complementary to the post content. In these cases you might consider including certain taxonomies. Otherwise, if you fear <a href="http://moz.com/learn/seo/duplicate-content">negative affects of duplicate content</a> or PageRank spread, you might even consider disallowing indexation of taxonomies.','xml-sitemap-feed').' '.sprintf(__('You can do this by adding specific robots.txt rules in the %s field above.','xml-sitemap-feed'),'<strong>'.__('Additional robots.txt rules','xml-sitemap-feed').'</strong>');
301
echo '</span></p>
302
<script type="text/javascript">
303
jQuery( document ).ready( function() {
@@ -312,13 +399,24 @@ jQuery( document ).ready( function() {
312
</fieldset>';
313
} else {
314
echo '
315
- <p style="color: red" class="error">'.__('No taxonomies available for the currently included post types.','xml-sitemap-feed').'</p>';
316
}
317
}
318
319
public function urls_settings_field() {
320
$urls = parent::get_urls();
321
- $prefix = parent::prefix();
322
$lines = array();
323
324
if(!empty($urls)) {
@@ -328,18 +426,24 @@ jQuery( document ).ready( function() {
328
}
329
}
330
331
- echo '<label>'.__('Additional URLs to append to the XML Sitemap.','xml-sitemap-feed').'<br /><textarea name="'.$prefix.'urls" id="xmlsf_urls" class="large-text" cols="50" rows="4" />'. implode("\n",$lines) .'</textarea></label>
332
- <p class="description">'.__('Add the full URL, including protocol (http/https) and domain, of any static page or WordPress page that you want to append to the ones already included by the settings above. Optionally add a priority value between 0 and 1, separated with a space, after the URL. Start each URL on a new line.','xml-sitemap-feed').'</p>';
333
334
}
335
336
public function domains_settings_field() {
337
$default = parent::domain();
338
$domains = (array) parent::get_option('domains');
339
- $prefix = parent::prefix();
340
341
- echo '<label>'.__('Additional domains to allow in the XML Sitemap.','xml-sitemap-feed').'<br /><textarea name="'.$prefix.'domains" id="xmlsf_domains" class="large-text" cols="50" rows="4" />'. implode("\n",$domains) .'</textarea></label>
342
- <p class="description">'.sprintf(__('By default, only the domain %s as used in your WordPress site address is allowed. This means that all URLs that use another domain (custom URLs or using a plugin like Page Links To) are filtered from the XML Sitemap. However, if you are the verified owner of other domains in your Google/Bing Webmaster Tools account, you can include these in the same sitemap. Add these domains, without protocol (http/https) each on a new line. Note that if you enter a domain with www, all URLs without it or with other subdomains will be filtered.','xml-sitemap-feed'),'<strong>'.$default.'</strong>').'</p>';
343
344
}
345
@@ -349,35 +453,130 @@ jQuery( document ).ready( function() {
349
*/
350
351
public function news_sitemap_settings() {
352
- echo '<p><a href="https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=ravanhagen%40gmail%2ecom&item_name=XML%20Sitemap%20Feeds&item_number='.XMLSF_VERSION.'&no_shipping=0&tax=0&charset=UTF%2d8" title="'.sprintf(__('Donate to keep the free %s plugin development & support going!','xml-sitemap-feed'),__('XML Sitemap & Google News Feeds','xml-sitemap-feed')).'"><img src="https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif" style="border:none;float:right;margin:4px 0 0 10px" alt="'.sprintf(__('Donate to keep the free %s plugin development & support going!','xml-sitemap-feed'),__('XML Sitemap & Google News Feeds','xml-sitemap-feed')).'" width="92" height="26" /></a>'.sprintf(__('These settings control the Google News Sitemap generated by the %s plugin.','xml-sitemap-feed'),__('XML Sitemap & Google News Feeds','xml-sitemap-feed')).' '.__('When you are done configuring and preparing your news content and you are convinced your site adheres to the <a href="https://support.google.com/news/publisher/answer/40787?ref_topic=2484652" target="_blank">Google News guidelines</a>, go ahead and <a href="https://support.google.com/news/publisher/troubleshooter/3179220?#ts=3179198" target="_blank">submit your site for inclusion</a>!','xml-sitemap-feed').'</p>';
353
}
354
355
//TODO: publication name allow tag %category% ... post_types (+ exclusion per post or none + allow inclusion per post), limit to category ...
356
public function news_name_field() {
357
$options = parent::get_option('news_tags');
358
- $prefix = parent::prefix();
359
360
$name = !empty($options['name']) ? $options['name'] : '';
361
echo '
362
- <input type="text" name="'.$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>';
363
}
364
365
- public function news_image_field() {
366
$options = parent::get_option('news_tags');
367
$prefix = parent::prefix();
368
369
$image = !empty($options['image']) ? $options['image'] : '';
370
echo '
371
- <label>'.__('Add image tags for','xml-sitemap-feed').' <select name="'.$prefix.'news_tags[image]">
372
- <option value="">'.translate('None').'</option>
373
- <option value="featured" '.
374
- selected( $image == "featured", true, false).
375
- '>'.translate('Featured Image').'</option>
376
- <option value="attached" '.
377
- selected( $image == "attached", true, false).
378
- '>'.__('Attached images','xml-sitemap-feed').'</option>
379
- ';
380
- echo '</select></label>';
381
}
382
383
public function news_access_field() {
@@ -386,7 +585,6 @@ jQuery( document ).ready( function() {
386
387
$access = !empty($options['access']) ? $options['access'] : '';
388
$access_default = !empty($access['default']) ? $access['default'] : '';
389
- // $access_private = !empty($access['private']) ? $access['private'] : '';
390
$access_password = !empty($access['password']) ? $access['password'] : '';
391
echo '
392
<fieldset id="xmlsf_news_access"><legend class="screen-reader-text">'.__('Access (&lt;access&gt; tag)','xml-sitemap-feed').'</legend>
@@ -400,13 +598,6 @@ jQuery( document ).ready( function() {
400
<option value="Registration" '.selected( "Registration" == $access_default, true, false).'>'.__('Registration','xml-sitemap-feed').'</option>
401
<option value="Subscription" '.selected( "Subscription" == $access_default, true, false).'>'.__('Subscription','xml-sitemap-feed').'</option>
402
</select></label></li>';
403
- /* TODO consider allowing private posts into the news sitemap; find a way to change 404 response into user configurable redirect/excerpt with login form/...
404
- echo '
405
-
406
- <li><label>'.sprintf(__('Tag %s posts as','xml-sitemap-feed'),translate('Private')).' <select name="'.$prefix.'news_tags[access][private]" id="xmlsf_news_tags_access_private">
407
- <option value="Registration" '.selected( "Registration" == $access_private, true, false).'>'.__('Registration','xml-sitemap-feed').'</option>
408
- <option value="Subscription" '.selected( "Subscription" == $access_private, true, false).'>'.__('Subscription','xml-sitemap-feed').'</option>
409
- </select></label></li>';*/
410
echo '
411
412
<li><label>'.sprintf(__('Tag %s posts as','xml-sitemap-feed'),translate('Password Protected')).' <select name="'.$prefix.'news_tags[access][password]" id="xmlsf_news_tags_access_password">
@@ -514,6 +705,7 @@ jQuery( document ).ready( function() {
514
//sanitize callback functions
515
516
public function sanitize_robots_settings($new) {
517
return trim(strip_tags($new));
518
}
519
@@ -523,7 +715,7 @@ jQuery( document ).ready( function() {
523
if (isset($new['reset']) && $new['reset'] == '1') // if reset is checked, set transient to clear all settings
524
set_transient('xmlsf_clear_settings','');
525
526
- // if( '1' == get_option('blog_public') ) {
527
if ($old != $new && !isset($new['reset'])) // when sitemaps are added or removed, set transient to flush rewrite rules
528
set_transient('xmlsf_flush_rewrite_rules','');
529
@@ -531,46 +723,13 @@ jQuery( document ).ready( function() {
531
set_transient('xmlsf_create_genres','');
532
533
$sanitized = $new;
534
- // } else {
535
- // $sanitized = $old;
536
- // }
537
-
538
- return $sanitized;
539
- }
540
-
541
- public function sanitize_ping_settings($new) {
542
-
543
- if( '1' == get_option('blog_public') ) {
544
- $defaults = parent::defaults('ping');
545
- $sanitized = array();
546
- $update_services = get_option('ping_sites');
547
- $update_services_new = $update_services;
548
-
549
- foreach ($defaults as $key => $values) {
550
- if(!isset($new[$key]))
551
- continue;
552
-
553
- if (isset($values['type']) && $values['type'] == 'RPC') {
554
- if ( isset($values['uri']) ) {
555
- if ( !empty($new[$key]['active']) && strpos($update_services,untrailingslashit($values['uri'])) === false )
556
- $update_services_new .= "\n" . $values['uri'];
557
- elseif ( empty($new[$key]['active']) && strpos($update_services,untrailingslashit($values['uri'])) !== false )
558
- $update_services_new = str_replace(array(trailingslashit($values['uri']),untrailingslashit($values['uri'])),'',$update_services_new);
559
- }
560
- } elseif (is_array($new[$key])) {
561
- $sanitized += array( $key => $new[$key] );
562
- }
563
- }
564
-
565
- if($update_services_new != $update_services)
566
- update_option('ping_sites',$update_services_new);
567
} else {
568
- $sanitized = parent::get_option('ping');
569
}
570
571
return $sanitized;
572
}
573
-
574
public function sanitize_post_types_settings( $new = array() ) {
575
$old = parent::get_post_types();
576
$defaults = parent::defaults('post_types');
@@ -585,10 +744,6 @@ jQuery( document ).ready( function() {
585
586
if ( isset($settings['priority']) && is_numeric($settings['priority']) ) {
587
$sanitized[$post_type]['priority'] = $this->sanitize_priority($settings['priority'],0.1,0.9);
588
- /* if ($settings['priority'] <= 0)
589
- $sanitized[$post_type]['priority'] = '0.1';
590
- elseif ($settings['priority'] >= 1)
591
- $sanitized[$post_type]['priority'] = '0.9';*/
592
} else {
593
$sanitized[$post_type]['priority'] = $defaults[$post_type]['priority'];
594
}
@@ -600,14 +755,14 @@ jQuery( document ).ready( function() {
600
return $sanitized;
601
}
602
603
- private function sanitize_priority($priority, $min = 0, $max = 1) {
604
- $priority = (float)$priority;
605
- if ($priority < $min || $priority === 0 )
606
- return (string)$min;
607
- elseif ($priority >= $max)
608
- return (string)$max;
609
else
610
- return (string)$priority;
611
}
612
613
public function sanitize_taxonomies_settings($new) {
@@ -619,13 +774,30 @@ jQuery( document ).ready( function() {
619
return $new;
620
}
621
622
public function sanitize_urls_settings($new) {
623
$old = parent::get_urls();
624
- $input = explode("\n",trim(strip_tags($new)));
625
$sanitized = array();
626
$callback = create_function('$a','return filter_var($a,FILTER_VALIDATE_URL) || is_numeric($a);');
627
628
- foreach ($input as $line) {
629
if(empty($line))
630
continue;
631
@@ -653,13 +825,20 @@ jQuery( document ).ready( function() {
653
654
public function sanitize_domains_settings($new) {
655
$default = parent::domain();
656
$input = explode("\n",trim(strip_tags($new)));
657
$sanitized = array();
658
659
foreach ($input as $line) {
660
$line = trim($line);
661
- if(!empty($line) && $line != $default && strpos($line,".".$default) === false)
662
- $sanitized[] = $line;
663
}
664
665
return (!empty($sanitized)) ? $sanitized : '';
@@ -744,12 +923,6 @@ jQuery( document ).ready( function() {
744
// _xmlsf_priority
745
if ( isset($_POST['xmlsf_priority']) && is_numeric($_POST['xmlsf_priority']) ) {
746
update_post_meta($post_id, '_xmlsf_priority', $this->sanitize_priority($_POST['xmlsf_priority']) );
747
- /* if ($_POST['xmlsf_priority'] < 0 || $_POST['xmlsf_priority'] === 0 )
748
- update_post_meta($post_id, '_xmlsf_priority', '0');
749
- elseif ($_POST['xmlsf_priority'] >= 1)
750
- update_post_meta($post_id, '_xmlsf_priority', '1');
751
- else
752
- update_post_meta($post_id, '_xmlsf_priority', $_POST['xmlsf_priority']);*/
753
} else {
754
delete_post_meta($post_id, '_xmlsf_priority');
755
}
@@ -770,67 +943,66 @@ jQuery( document ).ready( function() {
770
function __construct() {
771
$sitemaps = parent::get_sitemaps();
772
$prefix = parent::prefix();
773
- $blog_public = get_option('blog_public');
774
775
// sitemaps
776
register_setting('reading', $prefix.'sitemaps', array($this,'sanitize_sitemaps_settings') );
777
add_settings_field($prefix.'sitemaps', __('Enable XML sitemaps','xml-sitemap-feed'), array($this,'sitemaps_settings_field'), 'reading');
778
779
- if ( '1' == $blog_public && ( isset($sitemaps['sitemap']) || isset($sitemaps['sitemap-news']) ) ) {
780
- // pings
781
- register_setting('reading', $prefix.'ping', array($this,'sanitize_ping_settings') );
782
- add_settings_field($prefix.'ping', __('Ping on Publish','xml-sitemap-feed'), array($this,'ping_settings_field'), 'reading');
783
-
784
- if ( is_multisite() ) {
785
- register_setting('writing', $prefix.'ping', array($this,'sanitize_ping_settings') );
786
- add_settings_field($prefix.'ping', translate('Update Services'), array($this,'ping_settings_field'), 'writing');
787
- }
788
- }
789
-
790
- //robots only when permalinks are set
791
- if(''!=get_option('permalink_structure')) {
792
register_setting('reading', $prefix.'robots', array($this,'sanitize_robots_settings') );
793
add_settings_field($prefix.'robots', __('Additional robots.txt rules','xml-sitemap-feed'), array($this,'robots_settings_field'), 'reading');
794
}
795
796
- // TODO put this back in but only for multi-site when activated site-wide...
797
- if ( is_multisite() && is_plugin_active_for_network(XMLSF_PLUGIN_BASENAME) )
798
- add_settings_field($prefix.'reset', __('Reset XML sitemaps','xml-sitemap-feed'), array($this,'reset_settings_field'), 'reading');
799
800
- if ( '1' == $blog_public && isset($sitemaps['sitemap']) ) {
801
- // XML SITEMAP SETTINGS
802
- add_settings_section('xml_sitemap_section', '<a name="xmlsf"></a>'.__('XML Sitemap','xml-sitemap-feed'), array($this,'xml_sitemap_settings'), 'reading');
803
- // post_types
804
- register_setting('reading', $prefix.'post_types', array($this,'sanitize_post_types_settings') );
805
- add_settings_field($prefix.'post_types', __('Include post types','xml-sitemap-feed'), array($this,'post_types_settings_field'), 'reading', 'xml_sitemap_section');
806
- // taxonomies
807
- register_setting('reading', $prefix.'taxonomies', array($this,'sanitize_taxonomies_settings') );
808
- add_settings_field($prefix.'taxonomies', __('Include taxonomies','xml-sitemap-feed'), array($this,'taxonomies_settings_field'), 'reading', 'xml_sitemap_section');
809
- // custom urls
810
- register_setting('reading', $prefix.'urls', array($this,'sanitize_urls_settings') );
811
- add_settings_field($prefix.'urls', __('Include custom URLs','xml-sitemap-feed'), array($this,'urls_settings_field'), 'reading', 'xml_sitemap_section');
812
-
813
- // custom domains
814
- register_setting('reading', $prefix.'domains', array($this,'sanitize_domains_settings') );
815
- add_settings_field($prefix.'domains', __('Additional allowed domains','xml-sitemap-feed'), array($this,'domains_settings_field'), 'reading', 'xml_sitemap_section');
816
-
817
- // POST META BOX
818
- add_action( 'add_meta_boxes', array($this,'add_meta_box') );
819
- add_action( 'save_post', array($this,'save_metadata') );
820
- }
821
822
- if ( '1' == $blog_public && isset($sitemaps['sitemap-news']) ) {
823
- // XML SITEMAP SETTINGS
824
- add_settings_section('news_sitemap_section', '<a name="xmlnf"></a>'.__('Google News Sitemap','xml-sitemap-feed'), array($this,'news_sitemap_settings'), 'reading');
825
-
826
- // tags
827
- register_setting('reading', $prefix.'news_tags', array($this,'sanitize_news_tags_settings') );
828
- add_settings_field($prefix.'news_name', '<label for="xmlsf_news_name">'.__('Publication name','xml-sitemap-feed').'</label>', array($this,'news_name_field'), 'reading', 'news_sitemap_section');
829
- add_settings_field($prefix.'news_image', translate('Images'), array($this,'news_image_field'), 'reading', 'news_sitemap_section');
830
- add_settings_field($prefix.'news_access', __('Access (&lt;access&gt; tag)','xml-sitemap-feed'), array($this,'news_access_field'), 'reading', 'news_sitemap_section');
831
- add_settings_field($prefix.'news_genres', __('Genres (&lt;genres&gt; tag)','xml-sitemap-feed'), array($this,'news_genres_field'), 'reading', 'news_sitemap_section');
832
- add_settings_field($prefix.'news_keywords', __('Topics (&lt;keywords&gt; tag)','xml-sitemap-feed'), array($this,'news_keywords_field'), 'reading', 'news_sitemap_section');
833
- add_settings_field($prefix.'news_locations', __('Locations (&lt;geo_locations&gt; tag)','xml-sitemap-feed'), array($this,'news_locations_field'), 'reading', 'news_sitemap_section');
834
}
835
836
// ACTION LINK
@@ -845,4 +1017,3 @@ jQuery( document ).ready( function() {
845
846
if ( class_exists('XMLSitemapFeed') )
847
$xmlsf_admin = new XMLSF_Admin();
848
-
25
<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>';
26
if (isset($options['sitemap-news']))
27
echo '<span class="description"> &nbsp;&ndash;&nbsp; <a href="#xmlnf" id="xmlnf_link">'.translate('Settings').'</a> &nbsp;&ndash;&nbsp; <a href="'.trailingslashit(get_bloginfo('url')). ( ('' == get_option('permalink_structure')) ? '?feed=sitemap-news' : $options['sitemap-news'] ) .'" target="_blank">'.translate('View').'</a></span>';
28
+
29
echo '
30
</fieldset>';
31
echo '
57
</script>';
58
}
59
60
+ /* PINGS */
61
+
62
public function ping_settings_field() {
63
$options = parent::get_ping();
64
$defaults = parent::defaults('ping');
65
$update_services = get_option('ping_sites');
66
$prefix = parent::prefix();
67
$names = array(
68
'google' => array (
86
$defaults[$key] += $values;
87
}
88
echo '
89
+ <fieldset id="xmlsf_ping"><legend class="screen-reader-text">'.translate('Update Services').'</legend>
90
';
91
foreach ( $defaults as $key => $values ) {
92
93
if ( isset($values['type']) && $values['type'] == 'RPC' ) {
94
$active = ( strpos($update_services,untrailingslashit($values['uri'])) === false ) ? false : true;
95
} else {
96
+ $active = !empty($options[$key]['active']) ? true : false;
97
}
98
echo '
99
<label><input type="checkbox" name="'.$prefix.'ping['.
103
echo isset($names[$key]) && !empty($names[$key]['name']) ? $names[$key]['name'] : $key ;
104
echo '</label>';
105
106
+ echo '
107
+ <input type="hidden" name="'.$prefix.'ping['.
108
+ $key.'][uri]" value="'.
109
+ $values['uri'].'" />';
110
+ echo '
111
+ <input type="hidden" name="'.$prefix.'ping['.
112
+ $key.'][type]" value="'.
113
+ $values['type'].'" />';
114
+ if (isset($values['news']))
115
+ echo '
116
+ <input type="hidden" name="'.$prefix.'ping['.
117
+ $key.'][news]" value="'.
118
+ $values['news'].'" />';
119
+
120
echo ' <span class="description">';
121
+ if (!empty($options[$key]['pong'])) {
122
+ if ( $tzstring = get_option('timezone_string') ) {
123
+ // use same timezoneformat as translatable examples in options-general.php
124
+ $timezone_format = _x('Y-m-d G:i:s', 'timezone date format');
125
+ date_default_timezone_set($tzstring);
126
+ } else {
127
+ $timezone_format = 'Y-m-d G:i:s T';
128
+ }
129
+
130
+ foreach ((array)$options[$key]['pong'] as $pretty => $time) {
131
+ echo '
132
+ <input type="hidden" name="'.$prefix.'ping['.
133
+ $key.'][pong]['.$pretty.']" value="'.
134
+ $time.'" />';
135
+ if ( !empty($time) )
136
+ echo sprintf(__('Successfully sent %1$s on %2$s.','xml-sitemap-feed'),$pretty, date($timezone_format,$time)).' ';
137
+ }
138
+ date_default_timezone_set('UTC');
139
+ }
140
echo '</span><br />';
141
}
142
144
</fieldset>';
145
}
146
147
+ public function sanitize_ping_settings($new) {
148
+ $defaults = parent::defaults('ping');
149
+ $old = parent::get_option('ping');
150
+ $sanitized = array();
151
+ $update_services = get_option('ping_sites');
152
+ $update_services_new = $update_services;
153
+
154
+ foreach ($defaults as $key => $values) {
155
+ if(!isset($new[$key]))
156
+ continue;
157
+
158
+ if ( isset($values['type']) && $values['type']=='RPC' && isset($values['uri']) ) {
159
+ // did we toggle the option?
160
+ $changed = true;
161
+ if ( isset($old[$key]) ) {
162
+ $old_active = isset($old[$key]['active']) ? $old[$key]['active'] : '';
163
+ $new_active = isset($new[$key]['active']) ? $new[$key]['active'] : '';
164
+ if ( $old_active == $new_active )
165
+ $changed = false;
166
+ }
167
+
168
+ if ( $changed ) {
169
+ // then change the ping_sites list according to option
170
+ if ( !empty($new[$key]['active']) && strpos($update_services,untrailingslashit($values['uri'])) === false )
171
+ $update_services_new .= "\n" . $values['uri'];
172
+ elseif ( empty($new[$key]['active']) && strpos($update_services,untrailingslashit($values['uri'])) !== false )
173
+ $update_services_new = str_replace(array(trailingslashit($values['uri']),untrailingslashit($values['uri'])),'',$update_services_new);
174
+ } else {
175
+ // or change the option according to ping_sites
176
+ if ( strpos($update_services,untrailingslashit($values['uri'])) !== false )
177
+ $new[$key]['active'] = '1';
178
+ else
179
+ unset($new[$key]['active']);
180
+ }
181
+ }
182
+ if ( is_array($new[$key]) ) {
183
+ $sanitized += array( $key => $new[$key] );
184
+ }
185
+ }
186
+
187
+ if($update_services_new != $update_services)
188
+ update_option('ping_sites',$update_services_new);
189
+
190
+ return $sanitized;
191
+ }
192
+
193
+ /* ROBOTS */
194
+
195
public function robots_settings_field() {
196
+ echo '
197
+ <fieldset><legend class="screen-reader-text">'.__('Additional robots.txt rules','xml-sitemap-feed').'</legend>
198
+ <label>'.sprintf(__('Rules that will be appended to the %s generated by WordPress:','xml-sitemap-feed'),'<a href="'.trailingslashit(get_bloginfo('url')).'robots.txt" target="_blank">robots.txt</a>').'<br /><textarea name="'.parent::prefix().'robots" id="xmlsf_robots" class="large-text" cols="50" rows="6" />'.esc_attr( parent::get_robots() ).'</textarea></label>
199
+ <p class="description">'.__('These rules will not have effect when you are using a static robots.txt file.','xml-sitemap-feed').'<br /><span style="color: red" class="warning">'.__('Only add rules here when you know what you are doing, otherwise you might break search engine access to your site.','xml-sitemap-feed').'</span></p>
200
+ </fieldset>';
201
}
202
203
public function reset_settings_field() {
204
echo '
205
+ <fieldset><legend class="screen-reader-text">'.__('Reset XML sitemaps','xml-sitemap-feed').'</legend>
206
+ <label><input type="checkbox" name="'.parent::prefix().'sitemaps[reset]" value="1" /> '.
207
+ __('Clear all XML Sitemap Feed settings from the database.','xml-sitemap-feed').'</label>
208
+ </fieldset>';
209
echo '
210
+ <p class="description">'.__('You can use this to start fresh with the default settings or to remove all XML Sitemap and Google News settings and taxonomy terms before uninstalling.','xml-sitemap-feed').'</p>';
211
}
212
213
/**
215
*/
216
217
public function xml_sitemap_settings() {
218
+ echo '<p><a target="_blank" href="https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=ravanhagen%40gmail%2ecom&item_name=XML%20Sitemap%20Feeds&item_number='.XMLSF_VERSION.'&no_shipping=0&tax=0&charset=UTF%2d8" title="'.
219
+ sprintf(__('Donate to keep the free %s plugin development & support going!','xml-sitemap-feed'),__('XML Sitemap & Google News Feeds','xml-sitemap-feed')).'"><img src="https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif" style="border:none;float:right;margin:4px 0 0 10px" alt="'.
220
+ sprintf(__('Donate to keep the free %s plugin development & support going!','xml-sitemap-feed'),__('XML Sitemap & Google News Feeds','xml-sitemap-feed')).'" width="92" height="26" /></a>'.
221
+ sprintf(__('These settings control the XML Sitemaps generated by the %s plugin.','xml-sitemap-feed'),__('XML Sitemap & Google News Feeds','xml-sitemap-feed')).' '.
222
+ sprintf(__('For ping options, go to %s.','xml-sitemap-feed'),'<a href="options-writing.php">'.translate('Writing Settings').'</a>').'</p>';
223
}
224
225
public function post_types_settings_field() {
228
$prefix = parent::prefix();
229
$do_note = false;
230
231
+ $post_types = get_post_types(array('public'=>true),'objects');
232
+ if ( !is_array($post_types) || is_wp_error($post_types) )
233
+ return;
234
+
235
echo '<fieldset id="xmlsf_post_types"><legend class="screen-reader-text">'.__('XML Sitemaps for post types','xml-sitemap-feed').'</legend>
236
';
237
+ foreach ( $post_types as $post_type ) {
238
// skip unallowed post types
239
if (in_array($post_type->name,parent::disabled_post_types()))
240
continue;
325
}
326
327
echo '
328
+ <p class="description">* '.__('Priority settings do not affect ranking in search results in any way. They are only meant to suggest search engines which URLs to index first. Once a URL has been indexed, its Priority becomes meaningless until its Lastmod is updated.','xml-sitemap-feed').' <a href="#xmlsf_post_types_note_1_more" id="xmlsf_post_types_note_1_link">'.translate('[more]').'</a>
329
+ <span id="xmlsf_post_types_note_1_more">'.__('Maximum Priority (1.0) is reserved for the front page, individual posts and, when allowed, posts with high comment count.','xml-sitemap-feed').' '.__('Priority values are taken as relative values. Setting all to the same (high) value is pointless.','xml-sitemap-feed').'</span></p>
330
<script type="text/javascript">
331
jQuery( document ).ready( function() {
332
jQuery("#xmlsf_post_types_note_1_more").hide();
344
public function taxonomies_settings_field() {
345
$options = parent::get_taxonomies();
346
$active = parent::get_option('post_types');
347
$output = '';
348
349
foreach ( get_taxonomies(array('public'=>true),'objects') as $taxonomy ) {
359
360
$count = wp_count_terms( $taxonomy->name );
361
$output .= '
362
+ <label><input type="checkbox" name="'.parent::prefix().'taxonomies['.
363
$taxonomy->name.']" id="xmlsf_taxonomies_'.
364
$taxonomy->name.'" value="'.
365
$taxonomy->name.'"'.
382
echo $output;
383
384
echo '
385
+ <p class="description">'.__('It is generally not recommended to include taxonomy pages, unless their content brings added value.','xml-sitemap-feed').' <a href="#xmlsf_taxonomies_note_1_more" id="xmlsf_taxonomies_note_1_link">'.translate('[more]').'</a>
386
+ <span id="xmlsf_taxonomies_note_1_more">'.__('For example, when you use category descriptions with information that is not present elsewhere on your site or if taxonomy pages list posts with an excerpt that is different from, but complementary to the post content. In these cases you might consider including certain taxonomies. Otherwise, if you fear <a href="http://moz.com/learn/seo/duplicate-content">negative affects of duplicate content</a> or PageRank spread, you might even consider disallowing indexation of taxonomies.','xml-sitemap-feed').' '.
387
+ sprintf(__('You can do this by adding specific robots.txt rules in the %s field above.','xml-sitemap-feed'),'<strong>'.__('Additional robots.txt rules','xml-sitemap-feed').'</strong>');
388
echo '</span></p>
389
<script type="text/javascript">
390
jQuery( document ).ready( function() {
399
</fieldset>';
400
} else {
401
echo '
402
+ <p style="color: red" class="warning">'.__('No taxonomies available for the currently included post types.','xml-sitemap-feed').'</p>';
403
}
404
}
405
406
+ public function custom_sitemaps_settings_field() {
407
+ $lines = parent::get_custom_sitemaps();
408
+
409
+ echo '
410
+ <fieldset><legend class="screen-reader-text">'.__('Include custom XML Sitemaps','xml-sitemap-feed').'</legend>
411
+ <label>'.__('Additional XML Sitemaps to append to the main XML Sitemap Index:','xml-sitemap-feed').'<br />
412
+ <textarea name="'.parent::prefix().'custom_sitemaps" id="xmlsf_custom_sitemaps" class="large-text" cols="50" rows="4" />'. implode("\n",$lines) .'</textarea></label>
413
+ <p class="description">'.__('Add the full URL, including protocol (http/https) and domain, of any XML Sitemap that you want to append to the Sitemap Index. Start each URL on a new line.','xml-sitemap-feed').'<br /><span style="color: red" class="warning">'.__('Only valid sitemaps are allowed in the Sitemap Index. Use your Google/Bing Webmaster Tools to verify!','xml-sitemap-feed').'</span></p>
414
+ </fieldset>';
415
+
416
+ }
417
+
418
public function urls_settings_field() {
419
$urls = parent::get_urls();
420
$lines = array();
421
422
if(!empty($urls)) {
426
}
427
}
428
429
+ echo '
430
+ <fieldset><legend class="screen-reader-text">'.__('Include custom URLs','xml-sitemap-feed').'</legend>
431
+ <label>'.__('Additional URLs to append in an extra XML Sitemap:','xml-sitemap-feed').'<br />
432
+ <textarea name="'.parent::prefix().'urls" id="xmlsf_urls" class="large-text" cols="50" rows="4" />'. implode("\n",$lines) .'</textarea></label>
433
+ <p class="description">'.__('Add the full URL, including protocol (http/https) and domain, of any (static) page that you want to append to the ones already included by WordPress. Optionally add a priority value between 0 and 1, separated with a space after the URL. Start each URL on a new line.','xml-sitemap-feed').'</p>
434
+ </fieldset>';
435
436
}
437
438
public function domains_settings_field() {
439
$default = parent::domain();
440
$domains = (array) parent::get_option('domains');
441
442
+ echo '
443
+ <fieldset><legend class="screen-reader-text">'.__('Allowed domains','xml-sitemap-feed').'</legend>
444
+ <label>'.__('Additional domains to allow in the XML Sitemaps:','xml-sitemap-feed').'<br /><textarea name="'.parent::prefix().'domains" id="xmlsf_domains" class="large-text" cols="50" rows="4" />'. implode("\n",$domains) .'</textarea></label>
445
+ <p class="description">'.sprintf(__('By default, only the domain %s as used in your WordPress site address is allowed. This means that all URLs that use another domain (custom URLs or using a plugin like Page Links To) are filtered from the XML Sitemap. However, if you are the verified owner of other domains in your Google/Bing Webmaster Tools account, you can include these in the same sitemap. Add these domains, without protocol (http/https) each on a new line. Note that if you enter a domain with www, all URLs without it or with other subdomains will be filtered.','xml-sitemap-feed'),'<strong>'.$default.'</strong>').'</p>
446
+ </fieldset>';
447
448
}
449
453
*/
454
455
public function news_sitemap_settings() {
456
+ echo '<p><a target="_blank" href="https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=ravanhagen%40gmail%2ecom&item_name=XML%20Sitemap%20Feeds&item_number='.XMLSF_VERSION.'&no_shipping=0&tax=0&charset=UTF%2d8" title="'.
457
+ sprintf(__('Donate to keep the free %s plugin development & support going!','xml-sitemap-feed'),__('XML Sitemap & Google News Feeds','xml-sitemap-feed')).'"><img src="https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif" style="border:none;float:right;margin:4px 0 0 10px" alt="'.
458
+ sprintf(__('Donate to keep the free %s plugin development & support going!','xml-sitemap-feed'),__('XML Sitemap & Google News Feeds','xml-sitemap-feed')).'" width="92" height="26" /></a>'.
459
+ sprintf(__('These settings control the Google News Sitemap generated by the %s plugin.','xml-sitemap-feed'),__('XML Sitemap & Google News Feeds','xml-sitemap-feed')).' '.__('When you are done configuring and preparing your news content and you are convinced your site adheres to the <a href="https://support.google.com/news/publisher/answer/40787?ref_topic=2484652" target="_blank">Google News guidelines</a>, go ahead and <a href="https://support.google.com/news/publisher/troubleshooter/3179220?#ts=3179198" target="_blank">submit your site for inclusion</a>!','xml-sitemap-feed').' '.
460
+ sprintf(__('For ping options, go to %s.','xml-sitemap-feed'),'<a href="options-writing.php">'.translate('Writing Settings').'</a>').'</p>';
461
+
462
}
463
464
//TODO: publication name allow tag %category% ... post_types (+ exclusion per post or none + allow inclusion per post), limit to category ...
465
public function news_name_field() {
466
$options = parent::get_option('news_tags');
467
468
$name = !empty($options['name']) ? $options['name'] : '';
469
echo '
470
+ <fieldset><legend class="screen-reader-text">'.__('Publication name','xml-sitemap-feed').'</legend>
471
+ <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>
472
+ </fieldset>';
473
}
474
475
+ public function news_post_type_field() {
476
+ $defaults = parent::defaults('news_tags');
477
$options = parent::get_option('news_tags');
478
$prefix = parent::prefix();
479
480
+ $news_post_type = !empty($options['post_type']) ? $options['post_type'] : $defaults['post_type'];
481
+
482
+ $post_types = get_post_types(array('publicly_queryable' =>true),'objects');
483
+
484
+
485
+ // check for valid post types
486
+ if ( !is_array($post_types) || empty($post_types) || is_wp_error($post_types) ) {
487
+ echo '
488
+ <p style="color: red" class="error">'.__('Error: There where no valid post types found. Without at least one public post type, a Google News Sitemap cannot be created by this plugin. Please deselect the option Google News Sitemap at <a href="#xmlsf_sitemaps">Enable XML sitemaps</a> and choose another method.','xml-sitemap-feed').'</p>';
489
+ } else {
490
+ echo '
491
+ <fieldset><legend class="screen-reader-text">'.__('Include post types','xml-sitemap-feed').'</legend>';
492
+
493
+ foreach ( $post_types as $post_type ) {
494
+ // skip unallowed post types
495
+ if ( !is_object($post_type) || in_array($post_type->name,parent::disabled_post_types()) )
496
+ continue;
497
+
498
+ $checked = in_array($post_type->name,$news_post_type) || $news_post_type == 'any' ? true : false;
499
+ $disabled = false;
500
+ if ( isset($options['categories']) && is_array($options['categories']) ) {
501
+ // need to disable all post types that do not have the category taxonomy
502
+ $taxonomies = get_object_taxonomies($post_type->name,'names');
503
+ if ( !in_array('category',(array)$taxonomies) ) {
504
+ $disabled = true;
505
+ $checked = false;
506
+ }
507
+ }
508
+
509
+ echo '
510
+ <label><input type="checkbox" name="'.$prefix.'news_tags[post_type][]" id="xmlsf_post_type_'.
511
+ $post_type->name.'" value="'.$post_type->name.'" '.
512
+ checked( $checked, true, false).' '.
513
+ disabled( $disabled, true, false).' /> '.
514
+ $post_type->label.'</label><br />';
515
+ }
516
+ echo '
517
+ <p class="description">'.sprintf(__('At least one post type must be selected. By default, the post type %s will be used.','xml-sitemap-feed'),translate('Posts')).'</p>
518
+ </fieldset>';
519
+ }
520
+
521
+ }
522
+
523
+ public function news_categories_field() {
524
+ $options = parent::get_option('news_tags');
525
+
526
+ $all_categories = get_terms( 'category', array('hide_empty' => 0,'hierachical' => true) );
527
+ $selected_categories = isset($options['categories']) && is_array($options['categories']) ? $options['categories'] : array();
528
+ $count = count($all_categories);
529
+
530
+ if ($count==0) {
531
+ echo '
532
+ <p class="description">' . translate('No categories') . '</p>';
533
+ return;
534
+ } else {
535
+ echo '
536
+ <fieldset><legend class="screen-reader-text">'.translate('Categories').'</legend>';
537
+
538
+ $size = $count < 15 ? $count : 15;
539
+ echo '
540
+ <label>'.__('Limit to posts in these post categories:','xml-sitemap-feed').'<br />
541
+ <select multiple name="'.parent::prefix().'news_tags[categories][]" size="'.$size.'">';
542
+
543
+ foreach($all_categories as $category) {
544
+ $depth = count( explode( '%#%', get_category_parents($category, false, '%#%') ) ) - 2;
545
+ $pad = str_repeat('&nbsp;', $depth * 3);
546
+
547
+ $cat_name = apply_filters('list_cats', $category->name, $category);
548
+ echo '
549
+ <option class="depth-'.$depth.'" value="'.$category->term_id.'" '.
550
+ selected( in_array($category->term_id,$selected_categories), true, false ).
551
+ '>'.$pad.$cat_name.'</option>';
552
+ }
553
+ echo '
554
+ </select>
555
+ </label>
556
+ <p class="description">'.__('If you wish to limit posts that will feature in your News Sitemap to certain categories, select them here. Use the Ctrl/Cmd key plus click to select more than one or to deselect. If no categories are selected, posts of all categories will be included in your News Sitemap.','xml-sitemap-feed').'<br /><span style="color: red" class="warning">'.__('Please be aware that limiting by post category will rule out all custom post types that do not use post categories, even if you selected them to be included (above).','xml-sitemap-feed').'</span></p>';
557
+ echo '
558
+ </fieldset>';
559
+ }
560
+ }
561
+
562
+ public function news_image_field() {
563
+ $options = parent::get_option('news_tags');
564
+
565
$image = !empty($options['image']) ? $options['image'] : '';
566
echo '
567
+ <fieldset><legend class="screen-reader-text">'.translate('Images').'</legend>
568
+ <label>'.__('Add image tags for','xml-sitemap-feed').' <select name="'.parent::prefix().'news_tags[image]">
569
+ <option value="">'.translate('None').'</option>
570
+ <option value="featured" '.
571
+ selected( $image == "featured", true, false).
572
+ '>'.translate('Featured Image').'</option>
573
+ <option value="attached" '.
574
+ selected( $image == "attached", true, false).
575
+ '>'.__('Attached images','xml-sitemap-feed').'</option>
576
+ ';
577
+ echo '</select></label>
578
+ <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/185541" target="_blank">'.translate('More information...').'</a></p>
579
+ </fieldset>';
580
}
581
582
public function news_access_field() {
585
586
$access = !empty($options['access']) ? $options['access'] : '';
587
$access_default = !empty($access['default']) ? $access['default'] : '';
588
$access_password = !empty($access['password']) ? $access['password'] : '';
589
echo '
590
<fieldset id="xmlsf_news_access"><legend class="screen-reader-text">'.__('Access (&lt;access&gt; tag)','xml-sitemap-feed').'</legend>
598
<option value="Registration" '.selected( "Registration" == $access_default, true, false).'>'.__('Registration','xml-sitemap-feed').'</option>
599
<option value="Subscription" '.selected( "Subscription" == $access_default, true, false).'>'.__('Subscription','xml-sitemap-feed').'</option>
600
</select></label></li>';
601
echo '
602
603
<li><label>'.sprintf(__('Tag %s posts as','xml-sitemap-feed'),translate('Password Protected')).' <select name="'.$prefix.'news_tags[access][password]" id="xmlsf_news_tags_access_password">
705
//sanitize callback functions
706
707
public function sanitize_robots_settings($new) {
708
+ if(is_array($new)) $new = array_shift(array_filter($new));
709
return trim(strip_tags($new));
710
}
711
715
if (isset($new['reset']) && $new['reset'] == '1') // if reset is checked, set transient to clear all settings
716
set_transient('xmlsf_clear_settings','');
717
718
+ if( '1' == get_option('blog_public') ) {
719
if ($old != $new && !isset($new['reset'])) // when sitemaps are added or removed, set transient to flush rewrite rules
720
set_transient('xmlsf_flush_rewrite_rules','');
721
723
set_transient('xmlsf_create_genres','');
724
725
$sanitized = $new;
726
} else {
727
+ $sanitized = $old;
728
}
729
730
return $sanitized;
731
}
732
+
733
public function sanitize_post_types_settings( $new = array() ) {
734
$old = parent::get_post_types();
735
$defaults = parent::defaults('post_types');
744
745
if ( isset($settings['priority']) && is_numeric($settings['priority']) ) {
746
$sanitized[$post_type]['priority'] = $this->sanitize_priority($settings['priority'],0.1,0.9);
747
} else {
748
$sanitized[$post_type]['priority'] = $defaults[$post_type]['priority'];
749
}
755
return $sanitized;
756
}
757
758
+ private function sanitize_priority($priority, $min = 0.0, $max = 1.0) {
759
+ $priority = floatval(str_replace(",",".",$priority));
760
+ if ($priority <= (float)$min)
761
+ return number_format($min,1);
762
+ elseif ($priority >= (float)$max)
763
+ return number_format($max,1);
764
else
765
+ return number_format($priority,1);
766
}
767
768
public function sanitize_taxonomies_settings($new) {
774
return $new;
775
}
776
777
+ public function sanitize_custom_sitemaps_settings($new) {
778
+ $old = parent::get_custom_sitemaps();
779
+ $callback = create_function('$a','return filter_var($a,FILTER_VALIDATE_URL);');
780
+ if(is_array($new)) $new = array_shift(array_filter($new));
781
+ $input_arr = explode("\n",trim(strip_tags($new)));
782
+ $sanitized = array();
783
+
784
+ foreach ($input_arr as $line) {
785
+ $line = filter_var(esc_url(trim($line)),FILTER_VALIDATE_URL,FILTER_FLAG_PATH_REQUIRED);
786
+ if(!empty($line))
787
+ $sanitized[] = $line;
788
+ }
789
+
790
+ return $sanitized;
791
+ }
792
+
793
public function sanitize_urls_settings($new) {
794
$old = parent::get_urls();
795
+ if(is_array($new)) $new = array_shift(array_filter($new));
796
+ $input_arr = explode("\n",trim(strip_tags($new)));
797
$sanitized = array();
798
$callback = create_function('$a','return filter_var($a,FILTER_VALIDATE_URL) || is_numeric($a);');
799
800
+ foreach ($input_arr as $line) {
801
if(empty($line))
802
continue;
803
825
826
public function sanitize_domains_settings($new) {
827
$default = parent::domain();
828
+ if(is_array($new)) $new = array_shift(array_filter($new));
829
$input = explode("\n",trim(strip_tags($new)));
830
$sanitized = array();
831
832
foreach ($input as $line) {
833
$line = trim($line);
834
+ $parsed_url = parse_url(trim(filter_var($line,FILTER_SANITIZE_URL)));
835
+ // Before PHP version 5.4.7, parse_url will return the domain as path when scheme is omitted so we do:
836
+ $domain_arr = explode('/', $parsed_url['path']);
837
+ $domain = trim(!empty($parsed_url['host']) ? $parsed_url['host'] : array_shift(array_filter($domain_arr)));
838
+
839
+ // filter out empties and default domain
840
+ if(!empty($domain) && $domain !== $default && strpos($domain,".".$default) === false)
841
+ $sanitized[] = $domain;
842
}
843
844
return (!empty($sanitized)) ? $sanitized : '';
923
// _xmlsf_priority
924
if ( isset($_POST['xmlsf_priority']) && is_numeric($_POST['xmlsf_priority']) ) {
925
update_post_meta($post_id, '_xmlsf_priority', $this->sanitize_priority($_POST['xmlsf_priority']) );
926
} else {
927
delete_post_meta($post_id, '_xmlsf_priority');
928
}
943
function __construct() {
944
$sitemaps = parent::get_sitemaps();
945
$prefix = parent::prefix();
946
947
// sitemaps
948
register_setting('reading', $prefix.'sitemaps', array($this,'sanitize_sitemaps_settings') );
949
add_settings_field($prefix.'sitemaps', __('Enable XML sitemaps','xml-sitemap-feed'), array($this,'sitemaps_settings_field'), 'reading');
950
951
+ // robots rules only when permalinks are set
952
+ $rules = get_option( 'rewrite_rules' );
953
+ if( get_option('permalink_structure') && isset( $rules['robots\.txt#x27;] ) ) {
954
register_setting('reading', $prefix.'robots', array($this,'sanitize_robots_settings') );
955
add_settings_field($prefix.'robots', __('Additional robots.txt rules','xml-sitemap-feed'), array($this,'robots_settings_field'), 'reading');
956
}
957
958
+ if ( get_option('blog_public') ) {
959
+ if ( is_multisite() && is_plugin_active_for_network(XMLSF_PLUGIN_BASENAME) )
960
+ add_settings_field($prefix.'reset', __('Reset XML sitemaps','xml-sitemap-feed'), array($this,'reset_settings_field'), 'reading');
961
962
+ if ( isset($sitemaps['sitemap']) ) {
963
+ // XML SITEMAP SETTINGS
964
+ add_settings_section('xml_sitemap_section', '<a name="xmlsf"></a>'.__('XML Sitemap','xml-sitemap-feed'), array($this,'xml_sitemap_settings'), 'reading');
965
+ // post_types
966
+ register_setting('reading', $prefix.'post_types', array($this,'sanitize_post_types_settings') );
967
+ add_settings_field($prefix.'post_types', __('Include post types','xml-sitemap-feed'), array($this,'post_types_settings_field'), 'reading', 'xml_sitemap_section');
968
+ // taxonomies
969
+ register_setting('reading', $prefix.'taxonomies', array($this,'sanitize_taxonomies_settings') );
970
+ add_settings_field($prefix.'taxonomies', __('Include taxonomies','xml-sitemap-feed'), array($this,'taxonomies_settings_field'), 'reading', 'xml_sitemap_section');
971
+ // custom domains
972
+ register_setting('reading', $prefix.'domains', array($this,'sanitize_domains_settings') );
973
+ add_settings_field($prefix.'domains', __('Allowed domains','xml-sitemap-feed'), array($this,'domains_settings_field'), 'reading', 'xml_sitemap_section');
974
+ // custom urls
975
+ register_setting('reading', $prefix.'urls', array($this,'sanitize_urls_settings') );
976
+ add_settings_field($prefix.'urls', __('Include custom URLs','xml-sitemap-feed'), array($this,'urls_settings_field'), 'reading', 'xml_sitemap_section');
977
+ // custom sitemaps
978
+ register_setting('reading', $prefix.'custom_sitemaps', array($this,'sanitize_custom_sitemaps_settings') );
979
+ add_settings_field($prefix.'custom_sitemaps', __('Include custom XML Sitemaps','xml-sitemap-feed'), array($this,'custom_sitemaps_settings_field'), 'reading', 'xml_sitemap_section');
980
+
981
+ // POST META BOX
982
+ add_action( 'add_meta_boxes', array($this,'add_meta_box') );
983
+ add_action( 'save_post', array($this,'save_metadata') );
984
+ }
985
986
+ if ( isset($sitemaps['sitemap-news']) ) {
987
+ // XML SITEMAP SETTINGS
988
+ add_settings_section('news_sitemap_section', '<a name="xmlnf"></a>'.__('Google News Sitemap','xml-sitemap-feed'), array($this,'news_sitemap_settings'), 'reading');
989
+
990
+ // tags
991
+ register_setting('reading', $prefix.'news_tags', array($this,'sanitize_news_tags_settings') );
992
+ add_settings_field($prefix.'news_name', '<label for="xmlsf_news_name">'.__('Publication name','xml-sitemap-feed').'</label>', array($this,'news_name_field'), 'reading', 'news_sitemap_section');
993
+ add_settings_field($prefix.'news_post_type', __('Include post types','xml-sitemap-feed'), array($this,'news_post_type_field'), 'reading', 'news_sitemap_section');
994
+ add_settings_field($prefix.'news_categories', translate('Categories'), array($this,'news_categories_field'), 'reading', 'news_sitemap_section');
995
+ add_settings_field($prefix.'news_image', translate('Images'), array($this,'news_image_field'), 'reading', 'news_sitemap_section');
996
+ add_settings_field($prefix.'news_access', __('Access (&lt;access&gt; tag)','xml-sitemap-feed'), array($this,'news_access_field'), 'reading', 'news_sitemap_section');
997
+ add_settings_field($prefix.'news_genres', __('Genres (&lt;genres&gt; tag)','xml-sitemap-feed'), array($this,'news_genres_field'), 'reading', 'news_sitemap_section');
998
+ add_settings_field($prefix.'news_keywords', __('Topics (&lt;keywords&gt; tag)','xml-sitemap-feed'), array($this,'news_keywords_field'), 'reading', 'news_sitemap_section');
999
+ add_settings_field($prefix.'news_locations', __('Locations (&lt;geo_locations&gt; tag)','xml-sitemap-feed'), array($this,'news_locations_field'), 'reading', 'news_sitemap_section');
1000
+ }
1001
+
1002
+ if ( isset($sitemaps['sitemap']) || isset($sitemaps['sitemap-news']) ) {
1003
+ register_setting('writing', $prefix.'ping', array($this,'sanitize_ping_settings') );
1004
+ add_settings_field($prefix.'ping', translate('Update Services'), array($this,'ping_settings_field'), 'writing');
1005
+ }
1006
}
1007
1008
// ACTION LINK
1017
1018
if ( class_exists('XMLSitemapFeed') )
1019
$xmlsf_admin = new XMLSF_Admin();
includes/core.php CHANGED
@@ -36,7 +36,7 @@ class XMLSitemapFeed {
36
// Global values used for priority and changefreq calculation
37
private $domain;
38
private $firstdate;
39
- private $lastmodified;
40
private $postmodified = array();
41
private $termmodified = array();
42
private $blogpage;
@@ -66,7 +66,7 @@ class XMLSitemapFeed {
66
}
67
68
// default options
69
- private function build_defaults()
70
{
71
// sitemaps
72
if ( '1' == get_option('blog_public') )
@@ -120,49 +120,57 @@ class XMLSitemapFeed {
120
// news sitemap settings
121
$this->defaults['news_sitemap'] = array();
122
123
- // ping search engines
124
$this->defaults['ping'] = array(
125
'google' => array (
126
'active' => '1',
127
'uri' => 'http://www.google.com/webmasters/tools/ping?sitemap=',
128
- 'type' => 'GET'
129
),
130
'bing' => array (
131
'active' => '1',
132
'uri' => 'http://www.bing.com/ping?sitemap=',
133
- 'type' => 'GET'
134
),
135
'yandex' => array (
136
'active' => '',
137
'uri' => 'http://ping.blogs.yandex.ru/RPC2',
138
- 'type' => 'RPC'
139
),
140
'baidu' => array (
141
'active' => '',
142
'uri' => 'http://ping.baidu.com/ping/RPC2',
143
- 'type' => 'RPC'
144
),
145
'others' => array (
146
'active' => '1',
147
'uri' => 'http://rpc.pingomatic.com/',
148
- 'type' => 'RPC'
149
),
150
);
151
152
- $this->defaults['pong'] = array(); // for storing last ping timestamps and status
153
-
154
// robots
155
- $this->defaults['robots'] = "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
157
// additional urls
158
$this->defaults['urls'] = array();
159
160
// additional allowed domains
161
$this->defaults['domains'] = array();
162
163
// news sitemap tags settings
164
$this->defaults['news_tags'] = array(
165
- 'name' => '',
166
'image' => 'featured',
167
'access' => array(
168
'default' => '',
@@ -182,8 +190,6 @@ class XMLSitemapFeed {
182
'default' => ''
183
)
184
);
185
-
186
-
187
}
188
189
/**
@@ -193,7 +199,7 @@ class XMLSitemapFeed {
193
public function defaults($key = false)
194
{
195
if (empty($this->defaults))
196
- $this->build_defaults();
197
198
if ($key) {
199
$return = ( isset($this->defaults[$key]) ) ? $this->defaults[$key] : '';
@@ -224,15 +230,7 @@ class XMLSitemapFeed {
224
// make sure it's an array we are returning
225
return (!empty($return)) ? (array)$return : array();
226
}
227
-
228
- public function get_pong()
229
- {
230
- $return = $this->get_option('pong');
231
232
- // make sure it's an array we are returning
233
- return (!empty($return)) ? (array)$return : array();
234
- }
235
-
236
public function disabled_post_types()
237
{
238
return $this->disabled_post_types;
@@ -255,10 +253,9 @@ class XMLSitemapFeed {
255
256
public function have_post_types()
257
{
258
- $post_types = $this->get_option('post_types');
259
$return = array();
260
261
- foreach ( $post_types as $type => $values ) {
262
if(!empty($values['active'])) {
263
$count = wp_count_posts( $values['name'] );
264
if ($count->publish > 0) {
@@ -280,6 +277,21 @@ class XMLSitemapFeed {
280
return (!empty($return)) ? (array)$return : array();
281
}
282
283
public function get_urls()
284
{
285
$return = $this->get_option('urls');
@@ -297,10 +309,11 @@ class XMLSitemapFeed {
297
298
public function get_domains()
299
{
300
- $return = array_merge( array( $this->domain() ), (array)$this->get_option('domains') );
301
-
302
- // make sure it's an array we are returning
303
- return (!empty($return)) ? (array)$return : array();
304
}
305
306
public function get_archives($post_type = 'post', $type = '')
@@ -320,7 +333,7 @@ class XMLSitemapFeed {
320
}
321
if ( $arcresults ) {
322
foreach ( (array) $arcresults as $arcresult ) {
323
- $return[$arcresult->year.$arcresult->month] = $this->get_index_url( 'posttype', $post_type, $arcresult->year . $arcresult->month );
324
}
325
}
326
} elseif ('yearly' == $type) {
@@ -336,11 +349,11 @@ class XMLSitemapFeed {
336
}
337
if ($arcresults) {
338
foreach ( (array) $arcresults as $arcresult) {
339
- $return[$arcresult->year] = $this->get_index_url( 'posttype', $post_type, $arcresult->year );
340
}
341
}
342
} else {
343
- $return[0] = $this->get_index_url('posttype', $post_type); // $sitemap = 'home', $type = false, $param = false
344
}
345
return $return;
346
}
@@ -351,15 +364,19 @@ class XMLSitemapFeed {
351
}
352
353
public function do_tags( $type = 'post' )
354
- {
355
- $return = $this->get_option('post_types');
356
357
// make sure it's an array we are returning
358
- return ( isset($return[$type]) && !empty($return[$type]['tags']) ) ? (array)$return[$type]['tags'] : array();
359
}
360
361
- public function is_home($id) {
362
-
363
if ( empty($this->blogpage) ) {
364
$blogpage = get_option('page_for_posts');
365
@@ -375,7 +392,6 @@ class XMLSitemapFeed {
375
}
376
377
return in_array($id,$this->blogpage);
378
-
379
}
380
381
/**
@@ -394,7 +410,7 @@ class XMLSitemapFeed {
394
395
if ( empty($this->postmodified[$post->ID]) ) {
396
$postmodified = get_post_modified_time( 'Y-m-d H:i:s', true, $post->ID );
397
- $options = $this->get_option('post_types');
398
399
if( !empty($options[$post->post_type]['update_lastmod_on_comments']) )
400
$lastcomment = get_comments( array(
@@ -404,9 +420,13 @@ class XMLSitemapFeed {
404
) );
405
406
if ( isset($lastcomment[0]->comment_date_gmt) )
407
- if ( mysql2date( 'U', $lastcomment[0]->comment_date_gmt ) > mysql2date( 'U', $postmodified ) )
408
$postmodified = $lastcomment[0]->comment_date_gmt;
409
410
$this->postmodified[$post->ID] = $postmodified;
411
}
412
@@ -425,14 +445,14 @@ class XMLSitemapFeed {
425
'update_post_term_cache' => false,
426
'update_cache' => false,
427
'tax_query' => array(
428
- array(
429
- 'taxonomy' => $term->taxonomy,
430
- 'field' => 'slug',
431
- 'terms' => $term->slug
432
)
433
)
434
- )
435
- );
436
$this->termmodified[$term->term_id] = isset($posts[0]->post_date_gmt) ? $posts[0]->post_date_gmt : '';
437
}
438
return $this->termmodified[$term->term_id];
@@ -441,13 +461,14 @@ class XMLSitemapFeed {
441
return get_lastdate( 'gmt', $obj->object_type );
442
// uses get_lastdate() function defined in xml-sitemap/hacks.php !
443
// which is a shortcut: returns last post date, not last modified date...
444
- // TODO find the long way around (take tax type, get all terms,
445
- // do tax_query with all terms for one post and get its lastmod date)
446
}
447
448
else :
449
450
- return '0000-00-00 00:00:00';
451
452
endif;
453
}
@@ -460,7 +481,7 @@ class XMLSitemapFeed {
460
$options = $this->get_option('news_tags');
461
$which = isset($options['image']) ? $options['image'] : '';
462
} else {
463
- $options = $this->get_option('post_types');
464
$which = isset($options[$post->post_type]['tags']['image']) ? $options[$post->post_type]['tags']['image'] : '';
465
}
466
if('attached' == $which) {
@@ -494,7 +515,7 @@ class XMLSitemapFeed {
494
public function get_lastmod($sitemap = 'post_type', $term = '')
495
{
496
$return = trim(mysql2date('Y-m-d\TH:i:s+00:00', $this->modified($sitemap,$term), false));
497
- return !empty($return) ? '<lastmod>'.$return.'</lastmod>' : '';
498
}
499
500
public function get_changefreq($sitemap = 'post_type', $term = '')
@@ -504,7 +525,7 @@ class XMLSitemapFeed {
504
if (empty($modified))
505
return 'weekly';
506
507
- $lastactivityage = ( gmdate('U') - mysql2date( 'U', $modified ) ); // post age
508
509
if ( ($lastactivityage/86400) < 1 ) { // last activity less than 1 day old
510
$changefreq = 'hourly';
@@ -525,31 +546,31 @@ class XMLSitemapFeed {
525
{
526
if ( 'post_type' == $sitemap ) :
527
global $post;
528
- $options = $this->get_option('post_types');
529
$defaults = $this->defaults('post_types');
530
$priority_meta = get_metadata('post', $post->ID, '_xmlsf_priority' , true);
531
532
if ( !empty($priority_meta) || $priority_meta == '0' ) {
533
534
- $priority = $priority_meta;
535
536
} elseif ( !empty($options[$post->post_type]['dynamic_priority']) ) {
537
538
- $post_modified = mysql2date('U',$post->post_modified_gmt);
539
540
if ( empty($this->lastmodified) )
541
- $this->lastmodified = mysql2date('U',get_lastmodified('GMT',$post->post_type));
542
// last posts or page modified date in Unix seconds
543
// uses get_lastmodified() function defined in xml-sitemap/hacks.php !
544
545
if ( empty($this->firstdate) )
546
- $this->firstdate = mysql2date('U',get_firstdate('GMT',$post->post_type));
547
// uses get_firstdate() function defined in xml-sitemap/hacks.php !
548
549
if ( isset($options[$post->post_type]['priority']) )
550
- $priority_value = $options[$post->post_type]['priority'];
551
else
552
- $priority_value = $defaults[$post->post_type]['priority'];
553
554
// reduce by age
555
// NOTE : home/blog page gets same treatment as sticky post
@@ -561,10 +582,6 @@ class XMLSitemapFeed {
561
if ( $post->comment_count > 0 )
562
$priority = $priority + 0.1 + ( 0.9 - $priority ) * $post->comment_count / wp_count_comments($post->post_type)->approved;
563
564
- // and a final trim for cases where we end up above 1 (sticky posts with many comments)
565
- if ($priority > 1)
566
- $priority = 1;
567
-
568
} else {
569
570
$priority = ( isset($options[$post->post_type]['priority']) && is_numeric($options[$post->post_type]['priority']) ) ? $options[$post->post_type]['priority'] : $defaults[$post->post_type]['priority'];
@@ -592,6 +609,14 @@ class XMLSitemapFeed {
592
593
endif;
594
595
return number_format($priority,1);
596
}
597
@@ -639,7 +664,7 @@ class XMLSitemapFeed {
639
}
640
}
641
}
642
-
643
return apply_filters( 'xmlsf_allowed_domain', $return );
644
}
645
@@ -687,7 +712,7 @@ class XMLSitemapFeed {
687
// add robots.txt rules
688
public function robots_txt($output)
689
{
690
- return $output . $this->get_option('robots') ;
691
}
692
693
/**
@@ -772,27 +797,44 @@ class XMLSitemapFeed {
772
}
773
774
if ( $request['feed'] == 'sitemap-news' ) {
775
// disable caching
776
- define( 'DONOTCACHEPAGE', 1 ); // wp super cache -- or does super cache always clear feeds after new posts??
777
- // TODO w3tc
778
779
- // setup actions and filters
780
add_action('do_feed_sitemap-news', array($this, 'load_template_news'), 10, 1);
781
- add_filter('post_limits', array($this, 'filter_news_limits') );
782
- add_filter('posts_where', array($this, 'filter_news_where'), 10, 1);
783
784
- // modify request parameters
785
- $types_arr = explode(',',XMLSF_NEWS_POST_TYPE);
786
- $request['post_type'] = (in_array('any',$types_arr)) ? 'any' : $types_arr;
787
788
- // include post status private at some point?
789
- // $request['post_status'] = array( 'publish', 'private' );
790
- // for now only publish:
791
- $request['post_status'] = 'publish';
792
793
$request['no_found_rows'] = true;
794
- $request['update_post_meta_cache'] = false;
795
- //$request['update_post_term_cache'] = false; // << TODO test: can we disable or do we need this for terms?
796
797
return $request;
798
}
@@ -819,10 +861,6 @@ class XMLSitemapFeed {
819
$request['no_found_rows'] = true;
820
$request['update_post_meta_cache'] = false;
821
$request['update_post_term_cache'] = false;
822
- /*if ('attachment' == $post_type['name']) {
823
- $request['post_status'] = 'inherit';
824
- $request['post_mime_type'] = 'image,audio'; // ,video,audio
825
- }*/
826
827
return $request;
828
}
@@ -839,8 +877,9 @@ class XMLSitemapFeed {
839
$request['taxonomy'] = $taxonomy;
840
$request['lang'] = '';
841
$request['no_found_rows'] = true;
842
- $request['update_post_meta_cache'] = false;
843
$request['update_post_term_cache'] = false;
844
$request['post_status'] = 'publish';
845
846
return $request;
@@ -921,13 +960,22 @@ class XMLSitemapFeed {
921
{
922
return 'LIMIT 0, 1000';
923
}
924
925
// Create a new filtering function that will add a where clause to the query,
926
// used for the Google News Sitemap
927
public function filter_news_where( $where = '' )
928
{
929
- // only posts from the last 2 days
930
- return $where . " AND post_date > '" . date('Y-m-d H:i:s', strtotime('-49 hours')) . "'";
931
}
932
933
@@ -952,38 +1000,66 @@ class XMLSitemapFeed {
952
953
public function do_pings($new_status, $old_status, $post)
954
{
955
- // first check if we've got a post type that is included in our sitemap
956
- foreach($this->get_option('post_types') as $post_type)
957
- if( $post->post_type == $post_type['name'] ) {
958
- $active = true; // got a live one, green light is on.
959
- break;
960
- }
961
- if ( !isset($active) )
962
- return;
963
-
964
- if ( $old_status != 'publish' && $new_status == 'publish' ) {
965
- // Post is published from any other status
966
- $sitemaps = $this->get_sitemaps();
967
- foreach ($this->get_ping() as $se => $data)
968
- if( !empty($data['active']) && '1' == $data['active'])
969
- foreach ( $sitemaps as $pretty )
970
- if ( $this->ping( $data['uri'].urlencode(trailingslashit(get_bloginfo('url')) . $pretty) ) ) {
971
- $pong = $this->get_pong();
972
- $pong[$se][$pretty] = mysql2date('Y-m-d H:i:s', 'now', false);
973
- update_option($this->prefix.'pong',$pong);
974
}
975
}
976
- /*
977
- if ( $old_status == 'publish' && $new_status == 'publish' ) {
978
- // Post is updated
979
- // TODO make pinging in this case optional ... later, maybe
980
}
981
- */
982
- // see more on http://codex.wordpress.org/Post_Status_Transitions
983
}
984
985
/**
986
- * DE-ACTIVATION
987
*/
988
989
public function clear_settings()
@@ -1002,54 +1078,89 @@ class XMLSitemapFeed {
1002
}
1003
$terms = get_terms('gn-location-1',array('hide_empty' => false));
1004
foreach ( $terms as $term ) {
1005
- wp_delete_term( $term->term_id, 'gn-genre' );
1006
}
1007
$terms = get_terms('gn-location-2',array('hide_empty' => false));
1008
foreach ( $terms as $term ) {
1009
- wp_delete_term( $term->term_id, 'gn-genre' );
1010
}
1011
$terms = get_terms('gn-location-3',array('hide_empty' => false));
1012
foreach ( $terms as $term ) {
1013
- wp_delete_term( $term->term_id, 'gn-genre' );
1014
}
1015
1016
- remove_action('generate_rewrite_rules', array($this, 'rewrite_rules') );
1017
- global $wp_rewrite;
1018
- $wp_rewrite->flush_rules();
1019
}
1020
1021
/**
1022
* INITIALISATION
1023
*/
1024
1025
- public function plugins_loaded()
1026
{
1027
- // TEXT DOMAIN
1028
- if ( is_admin() ) // text domain needed on admin only
1029
- load_plugin_textdomain('xml-sitemap-feed', false, dirname(dirname(plugin_basename( __FILE__ ))) . '/languages' );
1030
-
1031
- // UPGRADE
1032
- if (get_option('xmlsf_version') != XMLSF_VERSION) {
1033
// rewrite rules not available on plugins_loaded
1034
// and don't flush rules from init as Polylang chokes on that
1035
- // just remove the rules and let WP renew them when ready...
1036
delete_option('rewrite_rules');
1037
1038
- // upgrade from ping to pong
1039
- $pings = get_option($this->prefix.'pings');
1040
- if (!empty($pings))
1041
- update_option($this->prefix.'pong',$pings);
1042
-
1043
- $this->yes_mother = true; // did you flush and wash your hands?
1044
1045
- update_option('xmlsf_version', XMLSF_VERSION);
1046
}
1047
1048
}
1049
1050
private function flush_rules($hard = false)
1051
{
1052
- if ($this->yes_mother) // did you flush?
1053
return; // yes, mother!
1054
1055
global $wp_rewrite;
@@ -1057,85 +1168,93 @@ class XMLSitemapFeed {
1057
$wp_rewrite->flush_rules($hard);
1058
1059
$this->yes_mother = true;
1060
}
1061
1062
public function register_gn_taxonomies()
1063
{
1064
- register_taxonomy( 'gn-genre', 'post', array(
1065
- 'hierarchical' => true,
1066
- 'labels' => array(
1067
- 'name' => __('Google News Genres','xml-sitemap-feed'),
1068
- 'singular_name' => __('Google News Genre','xml-sitemap-feed'),
1069
- //'menu_name' => __('GN Genres','xml-sitemap-feed'),
1070
- ),
1071
- 'public' => false,
1072
- 'show_ui' => true,
1073
- 'show_tagcloud' => false,
1074
- 'query_var' => false,
1075
- 'capabilities' => array( // prevent creation / deletion
1076
- 'manage_terms' => 'nobody',
1077
- 'edit_terms' => 'nobody',
1078
- 'delete_terms' => 'nobody',
1079
- 'assign_terms' => 'edit_posts'
1080
- )
1081
- ));
1082
-
1083
- register_taxonomy( 'gn-location-3', 'post', array(
1084
- 'hierarchical' => false,
1085
- 'labels' => array(
1086
- 'name' => __('Google News Country','xml-sitemap-feed'),
1087
- //'menu_name' => __('GN Genres','xml-sitemap-feed'),
1088
- 'separate_items_with_commas' => __('Only one allowed. Must be consistent with other Google News location entities (if set).','xml-sitemap-feed'),
1089
- ),
1090
- 'public' => false,
1091
- 'show_ui' => true,
1092
- 'show_tagcloud' => false,
1093
- 'query_var' => false,
1094
- 'capabilities' => array( // prevent creation / deletion
1095
- 'manage_terms' => 'nobody',
1096
- 'edit_terms' => 'nobody',
1097
- 'delete_terms' => 'nobody',
1098
- 'assign_terms' => 'edit_posts'
1099
- )
1100
- ));
1101
-
1102
- register_taxonomy( 'gn-location-2', 'post', array(
1103
- 'hierarchical' => false,
1104
- 'labels' => array(
1105
- 'name' => __('Google News State/Province','xml-sitemap-feed'),
1106
- //'menu_name' => __('GN Genres','xml-sitemap-feed'),
1107
- 'separate_items_with_commas' => __('Only one allowed. Must be consistent with other Google News location entities (if set).','xml-sitemap-feed'),
1108
- ),
1109
- 'public' => false,
1110
- 'show_ui' => true,
1111
- 'show_tagcloud' => false,
1112
- 'query_var' => false,
1113
- 'capabilities' => array( // prevent creation / deletion
1114
- 'manage_terms' => 'nobody',
1115
- 'edit_terms' => 'nobody',
1116
- 'delete_terms' => 'nobody',
1117
- 'assign_terms' => 'edit_posts'
1118
- )
1119
- ));
1120
-
1121
- register_taxonomy( 'gn-location-1', 'post', array(
1122
- 'hierarchical' => false,
1123
- 'labels' => array(
1124
- 'name' => __('Google News City','xml-sitemap-feed'),
1125
- //'menu_name' => __('GN Genres','xml-sitemap-feed'),
1126
- 'separate_items_with_commas' => __('Only one allowed. Must be consistent with other Google News location entities (if set).','xml-sitemap-feed'),
1127
- ),
1128
- 'public' => false,
1129
- 'show_ui' => true,
1130
- 'show_tagcloud' => false,
1131
- 'query_var' => false,
1132
- 'capabilities' => array( // prevent creation / deletion
1133
- 'manage_terms' => 'nobody',
1134
- 'edit_terms' => 'nobody',
1135
- 'delete_terms' => 'nobody',
1136
- 'assign_terms' => 'edit_posts'
1137
- )
1138
- ));
1139
1140
}
1141
@@ -1203,7 +1322,7 @@ class XMLSitemapFeed {
1203
// REQUEST main filtering function
1204
add_filter('request', array($this, 'filter_request'), 1 );
1205
1206
- // TEXT DOMAIN, LANGUAGE PLUGIN FILTERS ...
1207
add_action('plugins_loaded', array($this,'plugins_loaded'), 11 );
1208
1209
// REWRITES
@@ -1213,7 +1332,7 @@ class XMLSitemapFeed {
1213
// TAXONOMY
1214
add_action('init', array($this,'register_news_taxonomy'), 0 );
1215
1216
- // REGISTER SETTINGS, SETTINGS FIELDS, UPGRADE checks...
1217
add_action('admin_init', array($this,'admin_init'));
1218
1219
// ROBOTSTXT
@@ -1223,8 +1342,15 @@ class XMLSitemapFeed {
1223
// PINGING
1224
add_action('transition_post_status', array($this, 'do_pings'), 10, 3);
1225
1226
// DE-ACTIVATION
1227
- register_deactivation_hook( XMLSF_PLUGIN_DIR . '/xml-sitemap.php', array($this, 'clear_settings') );
1228
}
1229
-
1230
}
36
// Global values used for priority and changefreq calculation
37
private $domain;
38
private $firstdate;
39
+ private $lastmodified; // unused at the moment
40
private $postmodified = array();
41
private $termmodified = array();
42
private $blogpage;
66
}
67
68
// default options
69
+ private function set_defaults()
70
{
71
// sitemaps
72
if ( '1' == get_option('blog_public') )
120
// news sitemap settings
121
$this->defaults['news_sitemap'] = array();
122
123
+ // search engines to ping
124
$this->defaults['ping'] = array(
125
'google' => array (
126
'active' => '1',
127
'uri' => 'http://www.google.com/webmasters/tools/ping?sitemap=',
128
+ 'type' => 'GET',
129
+ 'news' => '1'
130
),
131
'bing' => array (
132
'active' => '1',
133
'uri' => 'http://www.bing.com/ping?sitemap=',
134
+ 'type' => 'GET',
135
+ 'news' => '1'
136
),
137
'yandex' => array (
138
'active' => '',
139
'uri' => 'http://ping.blogs.yandex.ru/RPC2',
140
+ 'type' => 'RPC',
141
),
142
'baidu' => array (
143
'active' => '',
144
'uri' => 'http://ping.baidu.com/ping/RPC2',
145
+ 'type' => 'RPC',
146
),
147
'others' => array (
148
'active' => '1',
149
'uri' => 'http://rpc.pingomatic.com/',
150
+ 'type' => 'RPC',
151
),
152
);
153
154
// robots
155
+ $this->defaults['robots'] = "";
156
+ // 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";
157
+ // Better is to set <meta name="robots" content="noindex, follow"> or send X-Robots-Tag header. TODO !!
158
159
// additional urls
160
$this->defaults['urls'] = array();
161
162
+ // additional custom_sitemaps
163
+ $this->defaults['custom_sitemaps'] = array();
164
+
165
// additional allowed domains
166
$this->defaults['domains'] = array();
167
168
// news sitemap tags settings
169
+ $news_post_types = defined('XMLSF_NEWS_POST_TYPE') ? explode(',',XMLSF_NEWS_POST_TYPE) : array('post');
170
$this->defaults['news_tags'] = array(
171
+ 'name' => '',
172
+ 'post_type' => (in_array('any',$news_post_types)) ? 'any' : $news_post_types,
173
+ 'categories' => '',
174
'image' => 'featured',
175
'access' => array(
176
'default' => '',
190
'default' => ''
191
)
192
);
193
}
194
195
/**
199
public function defaults($key = false)
200
{
201
if (empty($this->defaults))
202
+ $this->set_defaults();
203
204
if ($key) {
205
$return = ( isset($this->defaults[$key]) ) ? $this->defaults[$key] : '';
230
// make sure it's an array we are returning
231
return (!empty($return)) ? (array)$return : array();
232
}
233
234
public function disabled_post_types()
235
{
236
return $this->disabled_post_types;
253
254
public function have_post_types()
255
{
256
$return = array();
257
258
+ foreach ( $this->get_post_types() as $type => $values ) {
259
if(!empty($values['active'])) {
260
$count = wp_count_posts( $values['name'] );
261
if ($count->publish > 0) {
277
return (!empty($return)) ? (array)$return : array();
278
}
279
280
+ public function get_custom_sitemaps()
281
+ {
282
+ $return = $this->get_option('custom_sitemaps');
283
+
284
+ // make sure it's an array we are returning
285
+ if(!empty($return)) {
286
+ if(is_array($return))
287
+ return $return;
288
+ else
289
+ return explode("\n",$return);
290
+ } else {
291
+ return array();
292
+ }
293
+ }
294
+
295
public function get_urls()
296
{
297
$return = $this->get_option('urls');
309
310
public function get_domains()
311
{
312
+ $domains = $this->get_option('domains');
313
+ if (!empty($domains) && is_array($domains))
314
+ return array_merge( array( $this->domain() ), $domains );
315
+ else
316
+ return array( $this->domain() );
317
}
318
319
public function get_archives($post_type = 'post', $type = '')
333
}
334
if ( $arcresults ) {
335
foreach ( (array) $arcresults as $arcresult ) {
336
+ $return[$arcresult->year.$arcresult->month] = esc_html( $this->get_index_url( 'posttype', $post_type, $arcresult->year . $arcresult->month ) );
337
}
338
}
339
} elseif ('yearly' == $type) {
349
}
350
if ($arcresults) {
351
foreach ( (array) $arcresults as $arcresult) {
352
+ $return[$arcresult->year] = esc_html($this->get_index_url( 'posttype', $post_type, $arcresult->year ) );
353
}
354
}
355
} else {
356
+ $return[0] = esc_html($this->get_index_url('posttype', $post_type) ); // $sitemap = 'home', $type = false, $param = false
357
}
358
return $return;
359
}
364
}
365
366
public function do_tags( $type = 'post' )
367
+ {
368
+ $return = $this->get_post_types();
369
370
// make sure it's an array we are returning
371
+ return (
372
+ is_string($type) &&
373
+ isset($return[$type]) &&
374
+ !empty($return[$type]['tags'])
375
+ ) ? (array)$return[$type]['tags'] : array();
376
}
377
378
+ public function is_home($id)
379
+ {
380
if ( empty($this->blogpage) ) {
381
$blogpage = get_option('page_for_posts');
382
392
}
393
394
return in_array($id,$this->blogpage);
395
}
396
397
/**
410
411
if ( empty($this->postmodified[$post->ID]) ) {
412
$postmodified = get_post_modified_time( 'Y-m-d H:i:s', true, $post->ID );
413
+ $options = $this->get_post_types();
414
415
if( !empty($options[$post->post_type]['update_lastmod_on_comments']) )
416
$lastcomment = get_comments( array(
420
) );
421
422
if ( isset($lastcomment[0]->comment_date_gmt) )
423
+ if ( mysql2date( 'U', $lastcomment[0]->comment_date_gmt, false ) > mysql2date( 'U', $postmodified, false ) )
424
$postmodified = $lastcomment[0]->comment_date_gmt;
425
426
+ // make sure lastmod is not older than publication date (happens on scheduled posts)
427
+ if ( isset($post->post_date_gmt) && strtotime($post->post_date_gmt) > strtotime($postmodified) )
428
+ $postmodified = $post->post_date_gmt;
429
+
430
$this->postmodified[$post->ID] = $postmodified;
431
}
432
445
'update_post_term_cache' => false,
446
'update_cache' => false,
447
'tax_query' => array(
448
+ array(
449
+ 'taxonomy' => $term->taxonomy,
450
+ 'field' => 'slug',
451
+ 'terms' => $term->slug
452
+ )
453
)
454
)
455
+ );
456
$this->termmodified[$term->term_id] = isset($posts[0]->post_date_gmt) ? $posts[0]->post_date_gmt : '';
457
}
458
return $this->termmodified[$term->term_id];
461
return get_lastdate( 'gmt', $obj->object_type );
462
// uses get_lastdate() function defined in xml-sitemap/hacks.php !
463
// which is a shortcut: returns last post date, not last modified date...
464
+ // TODO find the long way home: take tax type, get all terms,
465
+ // do tax_query with all terms for one post and get its lastmod date
466
+ // ... or can 'terms' in tax_query be empty?
467
}
468
469
else :
470
471
+ return '';
472
473
endif;
474
}
481
$options = $this->get_option('news_tags');
482
$which = isset($options['image']) ? $options['image'] : '';
483
} else {
484
+ $options = $this->get_post_types();
485
$which = isset($options[$post->post_type]['tags']['image']) ? $options[$post->post_type]['tags']['image'] : '';
486
}
487
if('attached' == $which) {
515
public function get_lastmod($sitemap = 'post_type', $term = '')
516
{
517
$return = trim(mysql2date('Y-m-d\TH:i:s+00:00', $this->modified($sitemap,$term), false));
518
+ return !empty($return) ? "\t<lastmod>".$return."</lastmod>\r\n\t" : '';
519
}
520
521
public function get_changefreq($sitemap = 'post_type', $term = '')
525
if (empty($modified))
526
return 'weekly';
527
528
+ $lastactivityage = ( gmdate('U') - mysql2date( 'U', $modified, false ) ); // post age
529
530
if ( ($lastactivityage/86400) < 1 ) { // last activity less than 1 day old
531
$changefreq = 'hourly';
546
{
547
if ( 'post_type' == $sitemap ) :
548
global $post;
549
+ $options = $this->get_post_types();
550
$defaults = $this->defaults('post_types');
551
$priority_meta = get_metadata('post', $post->ID, '_xmlsf_priority' , true);
552
553
if ( !empty($priority_meta) || $priority_meta == '0' ) {
554
555
+ $priority = floatval(str_replace(",",".",$priority_meta));
556
557
} elseif ( !empty($options[$post->post_type]['dynamic_priority']) ) {
558
559
+ $post_modified = mysql2date('U',$post->post_modified_gmt, false);
560
561
if ( empty($this->lastmodified) )
562
+ $this->lastmodified = mysql2date('U',get_lastmodified('GMT',$post->post_type),false);
563
// last posts or page modified date in Unix seconds
564
// uses get_lastmodified() function defined in xml-sitemap/hacks.php !
565
566
if ( empty($this->firstdate) )
567
+ $this->firstdate = mysql2date('U',get_firstdate('GMT',$post->post_type),false);
568
// uses get_firstdate() function defined in xml-sitemap/hacks.php !
569
570
if ( isset($options[$post->post_type]['priority']) )
571
+ $priority_value = floatval(str_replace(",",".",$options[$post->post_type]['priority']));
572
else
573
+ $priority_value = floatval($defaults[$post->post_type]['priority']);
574
575
// reduce by age
576
// NOTE : home/blog page gets same treatment as sticky post
582
if ( $post->comment_count > 0 )
583
$priority = $priority + 0.1 + ( 0.9 - $priority ) * $post->comment_count / wp_count_comments($post->post_type)->approved;
584
585
} else {
586
587
$priority = ( isset($options[$post->post_type]['priority']) && is_numeric($options[$post->post_type]['priority']) ) ? $options[$post->post_type]['priority'] : $defaults[$post->post_type]['priority'];
609
610
endif;
611
612
+ // make sure we're not below zero
613
+ if ($priority < 0)
614
+ $priority = 0;
615
+
616
+ // and a final trim for cases where we ended up above 1 (sticky posts with many comments)
617
+ if ($priority > 1)
618
+ $priority = 1;
619
+
620
return number_format($priority,1);
621
}
622
664
}
665
}
666
}
667
+
668
return apply_filters( 'xmlsf_allowed_domain', $return );
669
}
670
712
// add robots.txt rules
713
public function robots_txt($output)
714
{
715
+ return $output . $this->get_option('robots') . "\n\n";
716
}
717
718
/**
797
}
798
799
if ( $request['feed'] == 'sitemap-news' ) {
800
+ $defaults = $this->defaults('news_tags');
801
+ $options = $this->get_option('news_tags');
802
+ $news_post_type = isset($options['post_type']) && !empty($options['post_type']) ? $options['post_type'] : $defaults['post_type'];
803
+ if (empty($news_post_type)) $news_post_type = 'post';
804
+
805
// disable caching
806
+ define('DONOTCACHEPAGE', true);
807
+ define('DONOTCACHEDB', true);
808
809
+ // setup template
810
add_action('do_feed_sitemap-news', array($this, 'load_template_news'), 10, 1);
811
812
+ // set up query filters
813
+ // TODO: test 'gmt' against 'blog' against 'server'
814
815
+ if ( function_exists('date_default_timezone_set') ) {
816
+ date_default_timezone_set ( 'UTC' );
817
+ $zone = 'gmt';
818
+ } else {
819
+ $zone = 'blog';
820
+ }
821
+ if ( get_lastdate($zone, $news_post_type) > date('Y-m-d H:i:s', strtotime('-48 hours')) ) {
822
+ add_filter('post_limits', array($this, 'filter_news_limits'));
823
+ add_filter('posts_where', array($this, 'filter_news_where'), 10, 1);
824
+ } else {
825
+ add_filter('post_limits', array($this, 'filter_no_news_limits'));
826
+ }
827
+
828
+ /* modify request parameters */
829
+ // post type
830
+ $request['post_type'] = $news_post_type;
831
+
832
+ // categories
833
+ if ( isset($options['categories']) && is_array($options['categories']) )
834
+ $request['cat'] = implode(',',$options['categories']);
835
836
+ $request['post_status'] = 'publish';
837
$request['no_found_rows'] = true;
838
839
return $request;
840
}
861
$request['no_found_rows'] = true;
862
$request['update_post_meta_cache'] = false;
863
$request['update_post_term_cache'] = false;
864
865
return $request;
866
}
877
$request['taxonomy'] = $taxonomy;
878
$request['lang'] = '';
879
$request['no_found_rows'] = true;
880
+ $request['cache_results'] = false;
881
$request['update_post_term_cache'] = false;
882
+ $request['update_post_meta_cache'] = false;
883
$request['post_status'] = 'publish';
884
885
return $request;
960
{
961
return 'LIMIT 0, 1000';
962
}
963
+ public function filter_no_news_limits( $limits )
964
+ {
965
+ return 'LIMIT 0, 1';
966
+ }
967
968
// Create a new filtering function that will add a where clause to the query,
969
// used for the Google News Sitemap
970
public function filter_news_where( $where = '' )
971
{
972
+ // only posts from the last 48 hours
973
+ if ( function_exists('date_default_timezone_set') ) {
974
+ date_default_timezone_set ( 'UTC' );
975
+ return $where . " AND post_date_gmt > '" . date('Y-m-d H:i:s', strtotime('-48 hours')) . "'";
976
+ } else {
977
+ return $where . " AND post_date > '" . date('Y-m-d H:i:s', strtotime('-48 hours')) . "'";
978
+ }
979
}
980
981
1000
1001
public function do_pings($new_status, $old_status, $post)
1002
{
1003
+ $sitemaps = $this->get_sitemaps();
1004
+ $to_ping = $this->get_ping();
1005
+ $update = false;
1006
+
1007
+ // first check if news sitemap is set
1008
+ if ( !empty($sitemaps['sitemap-news']) ) {
1009
+ // then check if we've got a post type that is included in our news sitemap
1010
+ $news_tags = $this->get_option('news_tags');
1011
+ if ( !empty($news_tags['post_type']) && is_array($news_tags['post_type']) && in_array($post->post_type,$news_tags['post_type']) ) {
1012
+ // are we publishing?
1013
+ if ( $old_status != 'publish' && $new_status == 'publish' ) {
1014
+ // loop through ping targets
1015
+ foreach ($to_ping as $se => $data) {
1016
+ // check active switch
1017
+ if( empty($data['active']) || empty($data['news']) )
1018
+ continue;
1019
+ // and if we did not ping already within the last 5 minutes
1020
+ if( !empty($data['pong']) && is_array($data['pong']) && !empty($data['pong'][$sitemaps['sitemap-news']]) && (int)$data['pong'][$sitemaps['sitemap-news']] + 300 > time() )
1021
+ continue;
1022
+ // ping !
1023
+ if ( $this->ping( $data['uri'].urlencode(trailingslashit(get_bloginfo('url')) . $sitemaps['sitemap-news']) ) ) {
1024
+ $to_ping[$se]['pong'][$sitemaps['sitemap-news']] = time();
1025
+ $update = true;
1026
}
1027
+
1028
+ }
1029
+ }
1030
+ }
1031
}
1032
+
1033
+ // first check if regular sitemap is set
1034
+ if ( !empty($sitemaps['sitemap']) ) {
1035
+ // then check if we've got a post type that is included in our sitemap
1036
+ foreach($this->get_post_types() as $post_type) {
1037
+ if ( !empty($post_type) && is_array($post_type) && in_array($post->post_type,$post_type) ) {
1038
+ // are we publishing?
1039
+ if ( $old_status != 'publish' && $new_status == 'publish' ) {
1040
+ foreach ($to_ping as $se => $data) {
1041
+ // check active switch
1042
+ if( empty($data['active']) || empty($data['type']) || $data['type']!='GET' )
1043
+ continue;
1044
+ // and if we did not ping already within the last hour
1045
+ if( !empty($data['pong']) && is_array($data['pong']) && !empty($data['pong'][$sitemaps['sitemap']]) && (int)$data['pong'][$sitemaps['sitemap']] + 3600 > time() )
1046
+ continue;
1047
+ // ping !
1048
+ if ( $this->ping( $data['uri'].urlencode(trailingslashit(get_bloginfo('url')) . $sitemaps['sitemap']) ) ) {
1049
+ $to_ping[$se]['pong'][$sitemaps['sitemap']] = time();
1050
+ $update = true;
1051
+ }
1052
+ }
1053
+ }
1054
+ }
1055
+ }
1056
}
1057
+
1058
+ if ( $update ) update_option($this->prefix.'ping',$to_ping);
1059
}
1060
1061
/**
1062
+ * CLEAR ALL SETTINGS
1063
*/
1064
1065
public function clear_settings()
1078
}
1079
$terms = get_terms('gn-location-1',array('hide_empty' => false));
1080
foreach ( $terms as $term ) {
1081
+ wp_delete_term( $term->term_id, 'gn-location-1' );
1082
}
1083
$terms = get_terms('gn-location-2',array('hide_empty' => false));
1084
foreach ( $terms as $term ) {
1085
+ wp_delete_term( $term->term_id, 'gn-location-2' );
1086
}
1087
$terms = get_terms('gn-location-3',array('hide_empty' => false));
1088
foreach ( $terms as $term ) {
1089
+ wp_delete_term( $term->term_id, 'gn-location-3' );
1090
}
1091
1092
+ error_log('XML Sitemap Feeds settings cleared');
1093
+ }
1094
+
1095
+ function cache_flush()
1096
+ {
1097
+ // make this optional?
1098
+ wp_cache_flush();
1099
}
1100
1101
/**
1102
* INITIALISATION
1103
*/
1104
1105
+ public function upgrade($version)
1106
{
1107
+ if ( version_compare(XMLSF_VERSION, $version, '>') ) {
1108
// rewrite rules not available on plugins_loaded
1109
// and don't flush rules from init as Polylang chokes on that
1110
+ // just remove the db option and let WP regenerate them when ready...
1111
delete_option('rewrite_rules');
1112
+ // ... but make sure rules are regenerated when admin is visited.
1113
+ set_transient('xmlsf_flush_rewrite_rules','');
1114
+
1115
+ // remove robots.txt rule blocking stylesheets, but only one time!
1116
+ if ( version_compare('4.4', $version, '>') && $robot_rules = get_option($this->prefix.'robots')) {
1117
+ $robot_rules = str_replace(array("Disallow: */wp-content/","Allow: */wp-content/uploads/"),"",$robot_rules);
1118
+ delete_option($this->prefix.'robots');
1119
+ add_option($this->prefix.'robots', $robot_rules, '', 'no');
1120
+ }
1121
+
1122
+ // upgrade pings
1123
+ if ( $pong = get_option( $this->prefix.'pong' ) && is_array($pong) ) {
1124
+ $ping = $this->get_ping();
1125
+ foreach ( $pong as $se => $arr) {
1126
+ if ( is_array( $arr ) ) {
1127
+ // convert formatted time to unix time
1128
+ foreach ( $arr as $pretty => $date ) {
1129
+ $time = strtotime($date);
1130
+ $arr[$pretty] = (int)$time < time() ? $time : '';
1131
+ }
1132
+ // and set array
1133
+ $ping[$se]['pong'] = $arr;
1134
+ }
1135
+ }
1136
+ delete_option( $this->prefix.'pong' );
1137
+ delete_option( $this->prefix.'ping' );
1138
+ add_option( $this->prefix.'ping', array_merge( $this->defaults('ping'), $ping ), '', 'no' );
1139
+ }
1140
1141
+ delete_option('xmlsf_version');
1142
+ add_option($this->prefix.'version', XMLSF_VERSION, '', 'no');
1143
1144
+ error_log('XML Sitemap Feeds upgraded from '.$version.' to '.XMLSF_VERSION);
1145
}
1146
+
1147
+ }
1148
+
1149
+ public function plugins_loaded()
1150
+ {
1151
+ // TEXT DOMAIN
1152
+ if ( is_admin() ) // text domain needed on admin only
1153
+ load_plugin_textdomain('xml-sitemap-feed', false, dirname(dirname(plugin_basename( __FILE__ ))) . '/languages' );
1154
+
1155
+ // UPGRADE
1156
+ $this->upgrade( get_option('xmlsf_version', 0) );
1157
1158
}
1159
1160
private function flush_rules($hard = false)
1161
{
1162
+ // did you flush already?
1163
+ if ($this->yes_mother)
1164
return; // yes, mother!
1165
1166
global $wp_rewrite;
1168
$wp_rewrite->flush_rules($hard);
1169
1170
$this->yes_mother = true;
1171
+ error_log('XML Sitemap Feeds rewrite rules flushed');
1172
}
1173
1174
public function register_gn_taxonomies()
1175
{
1176
+ $defaults = $this->defaults('news_tags');
1177
+ $options = $this->get_option('news_tags');
1178
+
1179
+ $post_types = !empty($options['post_type']) ? $options['post_type'] : $defaults['post_type'];
1180
+ if ($post_types=='any')
1181
+ $post_types = get_post_types(array('public'=>true));
1182
+
1183
+ register_taxonomy( 'gn-genre', $post_types, array(
1184
+ 'hierarchical' => true,
1185
+ 'labels' => array(
1186
+ 'name' => __('Google News Genres','xml-sitemap-feed'),
1187
+ 'singular_name' => __('Google News Genre','xml-sitemap-feed'),
1188
+ //'menu_name' => __('GN Genres','xml-sitemap-feed'),
1189
+ ),
1190
+ 'public' => false,
1191
+ 'show_ui' => true,
1192
+ 'show_tagcloud' => false,
1193
+ 'query_var' => false,
1194
+ 'capabilities' => array( // prevent creation / deletion
1195
+ 'manage_terms' => 'nobody',
1196
+ 'edit_terms' => 'nobody',
1197
+ 'delete_terms' => 'nobody',
1198
+ 'assign_terms' => 'edit_posts'
1199
+ )
1200
+ ));
1201
+
1202
+ register_taxonomy( 'gn-location-3', $post_types, array(
1203
+ 'hierarchical' => false,
1204
+ 'labels' => array(
1205
+ 'name' => __('Google News Country','xml-sitemap-feed'),
1206
+ //'menu_name' => __('GN Genres','xml-sitemap-feed'),
1207
+ 'separate_items_with_commas' => __('Only one allowed. Must be consistent with other Google News location entities (if set).','xml-sitemap-feed'),
1208
+ ),
1209
+ 'public' => false,
1210
+ 'show_ui' => true,
1211
+ 'show_tagcloud' => false,
1212
+ 'query_var' => false,
1213
+ 'capabilities' => array( // prevent creation / deletion
1214
+ 'manage_terms' => 'nobody',
1215
+ 'edit_terms' => 'nobody',
1216
+ 'delete_terms' => 'nobody',
1217
+ 'assign_terms' => 'edit_posts'
1218
+ )
1219
+ ));
1220
+
1221
+ register_taxonomy( 'gn-location-2', $post_types, array(
1222
+ 'hierarchical' => false,
1223
+ 'labels' => array(
1224
+ 'name' => __('Google News State/Province','xml-sitemap-feed'),
1225
+ //'menu_name' => __('GN Genres','xml-sitemap-feed'),
1226
+ 'separate_items_with_commas' => __('Only one allowed. Must be consistent with other Google News location entities (if set).','xml-sitemap-feed'),
1227
+ ),
1228
+ 'public' => false,
1229
+ 'show_ui' => true,
1230
+ 'show_tagcloud' => false,
1231
+ 'query_var' => false,
1232
+ 'capabilities' => array( // prevent creation / deletion
1233
+ 'manage_terms' => 'nobody',
1234
+ 'edit_terms' => 'nobody',
1235
+ 'delete_terms' => 'nobody',
1236
+ 'assign_terms' => 'edit_posts'
1237
+ )
1238
+ ));
1239
+
1240
+ register_taxonomy( 'gn-location-1', $post_types, array(
1241
+ 'hierarchical' => false,
1242
+ 'labels' => array(
1243
+ 'name' => __('Google News City','xml-sitemap-feed'),
1244
+ //'menu_name' => __('GN Genres','xml-sitemap-feed'),
1245
+ 'separate_items_with_commas' => __('Only one allowed. Must be consistent with other Google News location entities (if set).','xml-sitemap-feed'),
1246
+ ),
1247
+ 'public' => false,
1248
+ 'show_ui' => true,
1249
+ 'show_tagcloud' => false,
1250
+ 'query_var' => false,
1251
+ 'capabilities' => array( // prevent creation / deletion
1252
+ 'manage_terms' => 'nobody',
1253
+ 'edit_terms' => 'nobody',
1254
+ 'delete_terms' => 'nobody',
1255
+ 'assign_terms' => 'edit_posts'
1256
+ )
1257
+ ));
1258
1259
}
1260
1322
// REQUEST main filtering function
1323
add_filter('request', array($this, 'filter_request'), 1 );
1324
1325
+ // TEXT DOMAIN, UPGRADE PROCESS ...
1326
add_action('plugins_loaded', array($this,'plugins_loaded'), 11 );
1327
1328
// REWRITES
1332
// TAXONOMY
1333
add_action('init', array($this,'register_news_taxonomy'), 0 );
1334
1335
+ // REGISTER SETTINGS, SETTINGS FIELDS...
1336
add_action('admin_init', array($this,'admin_init'));
1337
1338
// ROBOTSTXT
1342
// PINGING
1343
add_action('transition_post_status', array($this, 'do_pings'), 10, 3);
1344
1345
+ // CLEAR OBJECT CACHE
1346
+ add_action('transition_post_status', array($this, 'cache_flush'), 99);
1347
+
1348
+ // ACTIVATION
1349
+ // activation currently same as upgrade routine based on db version check
1350
+ //register_activation_hook( XMLSF_PLUGIN_BASENAME, array($this, 'activate') );
1351
+
1352
// DE-ACTIVATION
1353
+ register_deactivation_hook( XMLSF_PLUGIN_BASENAME, array($this, 'flush_rules') );
1354
+
1355
}
1356
}
includes/feed-sitemap-custom.php CHANGED
@@ -7,9 +7,10 @@
7
8
status_header('200'); // force header('HTTP/1.1 200 OK') even for sites without posts
9
header('Content-Type: text/xml; charset=' . get_bloginfo('charset'), true);
10
11
echo '<?xml version="1.0" encoding="' . get_bloginfo('charset') . '"?>
12
- <?xml-stylesheet type="text/xsl" href="' . plugins_url('xsl/sitemap.xsl.php',__FILE__) . '?ver=' . XMLSF_VERSION . '"?>
13
<!-- generated-on="' . date('Y-m-d\TH:i:s+00:00') . '" -->
14
<!-- generator="XML & Google News Sitemap Feed plugin for WordPress" -->
15
<!-- generator-url="http://status301.net/wordpress-plugins/xml-sitemap-feed/" -->
@@ -25,9 +26,7 @@ global $xmlsf;
25
$urls = $xmlsf->get_urls();
26
27
// and loop away!
28
- if ( !empty($urls) ) :
29
- foreach ( $urls as $url ) {
30
-
31
if (empty($url[0]))
32
continue;
33
@@ -43,8 +42,6 @@ if ( !empty($urls) ) :
43
<!-- URL <?php echo esc_url( $url[0] ); ?> skipped: Not within allowed domains. -->
44
<?php
45
}
46
-
47