/docroot/wp-content/plugins/google-news-sitemap-generator/google-news-sitemap.php

https://bitbucket.org/greg_gallant/cd-blog · PHP · 377 lines · 224 code · 56 blank · 97 comment · 29 complexity · 317323893170a93490fa15f43f15d220 MD5 · raw file

  1. <?
  2. /*
  3. Plugin Name: Google News Sitemap
  4. Plugin URI: http://www.southcoastwebsites.co.uk/wordpress/
  5. Version: v1.5
  6. Author: <a href="http://www.southcoastwebsites.co.uk/wordpress/">Chris Jinks</a>
  7. Description: Basic XML sitemap generator for submission to Google News
  8. Installation:
  9. ==============================================================================
  10. 1. Upload `google-news-sitemap-generator` directory to the `/wp-content/plugins/` directory
  11. 2. Activate the plugin through the 'Plugins' menu in WordPress
  12. 3. Move the file "google-news-sitemap.xml" into your blog root directory and CHMOD to 777 so it is writable
  13. 4. Save/publish/delete a post to generate the sitemap
  14. Release History:
  15. ==============================================================================
  16. 2008-08-04 v1.00 First release
  17. 2008-08-17 v1.1 Compatible with new Wordpress database taxonomy (>2.3)
  18. 2008-10-11 v1.2 Improved installation instructions, admin panel, general bug fixing
  19. 2009-07-27 v1.3 Exclude category options, scheduled posts now supported, UI improved.
  20. 2009-08-30 v1.3.1 Addition of XML version/encoding tag to beginning of sitemap
  21. 2009-11-11 v1.4 Update to new Google News Sitemap format
  22. 2010-03-13 v1.5 Update to new Google News Sitemap format
  23. */
  24. /* Copyright 2008 Chris Jinks / David Stansbury
  25. Original concept: David Stansbury - http://www.kb3kai.com/david_stansbury/
  26. This program is free software; you can redistribute it and/or modify
  27. it under the terms of the GNU General Public License as published by
  28. the Free Software Foundation; either version 2 of the License, or
  29. (at your option) any later version.
  30. This program is distributed in the hope that it will be useful,
  31. but WITHOUT ANY WARRANTY; without even the implied warranty of
  32. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  33. GNU General Public License for more details.
  34. You should have received a copy of the GNU General Public License
  35. along with this program; if not, write to the Free Software
  36. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  37. */
  38. function get_category_keywords($newsID)
  39. {
  40. global $wpdb;
  41. //Check for new >2.3 Wordpress taxonomy
  42. if (function_exists("get_taxonomy") && function_exists("get_terms"))
  43. {
  44. /* // CDIM-1072: Use only four tags
  45. //Get categoy names
  46. $categories = $wpdb->get_results("
  47. SELECT $wpdb->terms.name FROM $wpdb->term_relationships, $wpdb->term_taxonomy, $wpdb->terms
  48. WHERE $wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id
  49. AND $wpdb->term_taxonomy.term_id = $wpdb->terms.term_id
  50. AND $wpdb->term_relationships.object_id = $newsID
  51. AND $wpdb->term_taxonomy.taxonomy = 'category'");
  52. $i = 0;
  53. $categoryKeywords = "";
  54. foreach ($categories as $category)
  55. {
  56. if ($i>0){$categoryKeywords.= ", ";} //Comma seperator
  57. $categoryKeywords.= $category->name; //ammed string
  58. $i++;
  59. }
  60. */
  61. $categoryKeywords = '';
  62. //Get tags
  63. $tags = $wpdb->get_results("
  64. SELECT $wpdb->terms.name FROM $wpdb->term_relationships, $wpdb->term_taxonomy, $wpdb->terms
  65. WHERE $wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id
  66. AND $wpdb->term_taxonomy.term_id = $wpdb->terms.term_id
  67. AND $wpdb->term_relationships.object_id = $newsID
  68. AND $wpdb->term_taxonomy.taxonomy = 'post_tag'");
  69. $i = 0;
  70. $tagKeywords = "";
  71. foreach ($tags as $tag)
  72. {
  73. if ($i < 4) { // CDIM-1072: Use only four tags
  74. if ($i>0){$tagKeywords.= ", ";} //Comma seperator
  75. $tagKeywords.= $tag->name; //ammed string
  76. $i++;
  77. }
  78. }
  79. }
  80. //Old Wordpress database <2.3
  81. else
  82. {
  83. $categories = $wpdb->get_results("SELECT category_id FROM $wpdb->post2cat WHERE post_id=$newsID");
  84. $i = 0;
  85. $categoryKeywords = "";
  86. foreach ($categories as $category)
  87. {
  88. if ($i>0){$categoryKeywords.= ", ";} //Comma seperator
  89. $categoryKeywords.= get_catname($category->category_id); //ammed string
  90. $i++;
  91. }
  92. }
  93. if (get_option('googlenewssitemap_tagkeywords') == 'on')
  94. {
  95. if($tagKeywords!=NULL)
  96. {
  97. // CDIM-1072: Use only four tags
  98. //$categoryKeywords = $categoryKeywords.', '.$tagKeywords; //IF tags are included
  99. $categoryKeywords = $tagKeywords; //IF tags are included
  100. }
  101. }
  102. return $categoryKeywords; //Return post category names as keywords
  103. }
  104. function write_google_news_sitemap()
  105. {
  106. global $wpdb;
  107. // Fetch options from database
  108. $permalink_structure = $wpdb->get_var("SELECT option_value FROM $wpdb->options
  109. WHERE option_name='permalink_structure'");
  110. $siteurl = $wpdb->get_var("SELECT option_value FROM $wpdb->options
  111. WHERE option_name='siteurl'");
  112. // Output XML header
  113. // Begin urlset
  114. $xmlOutput = '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:news="http://www.google.com/schemas/sitemap-news/0.9">';
  115. //Credit
  116. $xmlOutput.= "\n<!-- Generated by Google News Sitemap Generator Wordpress Plugin -->\n";
  117. $xmlOutput.= "<!-- Created by Chris Jinks | http://www.southcoastwebsites.co.uk -->\n";
  118. $xmlOutput.= "<!-- http://wordpress.org/extend/plugins/google-news-sitemap-generator/ -->\n";
  119. //Show either Posts or Pages or Both
  120. if (get_option('googlenewssitemap_includePages') == 'on' && get_option('googlenewssitemap_includePosts') == 'on')
  121. $includeMe = 'AND (post_type="page" OR post_type = "post")';
  122. elseif (get_option('googlenewssitemap_includePages') == 'on')
  123. $includeMe = 'AND post_type="page"';
  124. elseif (get_option('googlenewssitemap_includePosts') == 'on')
  125. $includeMe = 'AND post_type="post"';
  126. //Exclude categories
  127. if (get_option('googlenewssitemap_excludeCat')<>NULL)
  128. {
  129. $exPosts = get_objects_in_term(get_option('googlenewssitemap_excludeCat'),"category");
  130. $includeMe.= ' AND ID NOT IN ('.implode(",",$exPosts).')';
  131. }
  132. // CDIM-1072: Exclude wp_postmeta._pprredirect_url if http://www.caranddriver.com
  133. $exPosts = $wpdb->get_col("SELECT post_id FROM wp_postmeta where meta_key = '_pprredirect_url';");
  134. $includeMe.= ' AND ID NOT IN ('.implode(",",$exPosts).')';
  135. //Limit to last 2 days, 50,000 items
  136. $rows = $wpdb->get_results("SELECT ID, post_date_gmt, post_title
  137. FROM $wpdb->posts
  138. WHERE post_status='publish'
  139. AND (DATEDIFF(CURDATE(), post_date_gmt)<=2)
  140. $includeMe
  141. ORDER BY post_date_gmt DESC
  142. LIMIT 0, 50000");
  143. // Output sitemap data
  144. foreach($rows as $row){
  145. $xmlOutput.= "\t<url>\n";
  146. $xmlOutput.= "\t\t<loc>";
  147. $xmlOutput.= get_permalink($row->ID);
  148. $xmlOutput.= "</loc>\n";
  149. $xmlOutput.= "\t\t<news:news>\n";
  150. $xmlOutput.= "\t\t\t<news:publication>\n";
  151. $xmlOutput.= "\t\t\t\t<news:name>";
  152. // CDIM-1072: Force site name
  153. // CDIM-1256 remove (blog)
  154. $xmlOutput.= 'Car and Driver';
  155. //$xmlOutput.= htmlspecialchars(get_option('blogname'));
  156. $xmlOutput.= "</news:name>\n";
  157. $xmlOutput.= "\t\t\t\t<news:language>";
  158. $xmlOutput.= get_option('rss_language');
  159. $xmlOutput.= "</news:language>\n";
  160. $xmlOutput.= "\t\t\t</news:publication>\n";
  161. $xmlOutput.= "\t\t\t<news:publication_date>";
  162. $thedate = substr($row->post_date_gmt, 0, 10);
  163. $xmlOutput.= $thedate;
  164. $xmlOutput.= "</news:publication_date>\n";
  165. $xmlOutput.= "\t\t\t<news:title>";
  166. $xmlOutput.= htmlspecialchars($row->post_title);
  167. $xmlOutput.= "</news:title>\n";
  168. $xmlOutput.= "\t\t\t<news:keywords>";
  169. //Use the categories for keywords
  170. $xmlOutput.= get_category_keywords($row->ID);
  171. $xmlOutput.= "</news:keywords>\n";
  172. $xmlOutput.= "\t\t</news:news>\n";
  173. $xmlOutput.= "\t</url>\n";
  174. }
  175. // End urlset
  176. $xmlOutput.= "</urlset>\n";
  177. $xmlOutput.= "<!-- Last build time: ".date("F j, Y, g:i a")."-->";
  178. $xmlFile = "../google-news-sitemap.xml";
  179. $fp = fopen($xmlFile, "w+"); // open the cache file "google-news-sitemap.xml" for writing
  180. fwrite($fp, $xmlOutput); // save the contents of output buffer to the file
  181. fclose($fp); // close the file
  182. }
  183. if(function_exists('add_action')) //Stop error when directly accessing the PHP file
  184. {
  185. add_action('publish_post', 'write_google_news_sitemap');
  186. add_action('save_post', 'write_google_news_sitemap');
  187. add_action('delete_post', 'write_google_news_sitemap');
  188. add_action('transition_post_status', 'write_google_news_sitemap',10, 3); //Future scheduled post action fix
  189. //Any changes to the settings are executed on change
  190. add_action('update_option_googlenewssitemap_includePosts', 'write_google_news_sitemap', 10, 2);
  191. add_action('update_option_googlenewssitemap_includePages', 'write_google_news_sitemap', 10, 2);
  192. add_action('update_option_googlenewssitemap_tagkeywords', 'write_google_news_sitemap', 10, 2);
  193. add_action('update_option_googlenewssitemap_excludeCat', 'write_google_news_sitemap', 10, 2);
  194. }
  195. else //Friendly error message :)
  196. {
  197. ?>
  198. <p style="color:#FF0000"><em>Accessing this file directly will not generate the sitemap.</em></p>
  199. <p>The sitemap will be generated automatically when you save/pubish/delete a post from the standard Wordpress interface.</p>
  200. <p><strong>Instructions</strong></p>
  201. <p>1. Upload `google-news-sitemap-generator` directory to the `/wp-content/plugins/` directory<br />
  202. 2. Activate the plugin through the 'Plugins' menu in WordPress<br />
  203. 3. Move the file "google-news-sitemap.xml" into your blog root directory and CHMOD to 777 so it is writable<br />
  204. 4. Save/publish/delete a post to generate the sitemap</p>
  205. <?
  206. }
  207. //
  208. // Admin panel options.... //
  209. //
  210. add_action('admin_menu', 'show_googlenewssitemap_options');
  211. function show_googlenewssitemap_options() {
  212. // Add a new submenu under Options:
  213. add_options_page('Google News Sitemap Generator Plugin Options', 'Google News Sitemap', 'edit_pages', 'googlenewssitemap', 'googlenewssitemap_options');
  214. //Add options for plugin
  215. add_option('googlenewssitemap_includePosts', 'on');
  216. add_option('googlenewssitemap_includePages', 'off');
  217. add_option('googlenewssitemap_tagkeywords', 'off');
  218. add_option('googlenewssitemap_excludeCat', '');
  219. }
  220. //
  221. // Admin page HTML //
  222. //
  223. function googlenewssitemap_options() { ?>
  224. <style type="text/css">
  225. div.headerWrap { background-color:#e4f2fds; width:200px}
  226. #options h3 { padding:7px; padding-top:10px; margin:0px; cursor:auto }
  227. #options label { width: 300px; float: left; margin-left: 10px; }
  228. #options input { float: left; margin-left:10px}
  229. #options p { clear: both; padding-bottom:10px; }
  230. #options .postbox { margin:0px 0px 10px 0px; padding:0px; }
  231. </style>
  232. <div class="wrap">
  233. <form method="post" action="options.php" id="options">
  234. <?php wp_nonce_field('update-options') ?>
  235. <h2>Google News Sitemap Options</h2>
  236. <div class="postbox">
  237. <h3 class="hndle">Information</h3>
  238. <div style="text-decoration:none; padding:10px">
  239. <div style="width:180px; text-align:center; float:right; font-size:10px; font-weight:bold">
  240. <a href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=396299">
  241. <img src="https://www.paypal.com/en_GB/i/btn/btn_donateCC_LG.gif" border="0" style="padding-bottom:10px" /></a><br />
  242. Please donate to keep this plugin alive and for future updates! Thanks! :)
  243. </div>
  244. <a href="http://wordpress.org/extend/plugins/google-news-sitemap-generator/" style="text-decoration:none" target="_blank">Google News Sitemap Generator homepage</a> <small>- Report a bug or suggest a feature</small><br /><br />
  245. <a href="http://www.google.com/webmasters/tools/" style="text-decoration:none" target="_blank">Google Webmaster Tools</a> <small>- Submit Google News sitemap</small> <br /><br />
  246. <a href="http://www.google.com/support/news_pub/bin/answer.py?answer=74288&topic=11666" style="text-decoration:none" target="_blank">Google News Sitemap Guidelines</a> <small>- Detailed outline of sitemaps specification</small><br />
  247. <br />
  248. <a href="http://www.southcoastwebsites.co.uk/wordpress/" style="text-decoration:none" target="_blank">Plugin developer page</a> <small>- More information about the developer of this plugin</small><br />
  249. </div>
  250. </div>
  251. <div class="postbox">
  252. <h3 class="hndle">Sitemap contents</h3>
  253. <p>
  254. <?php
  255. if (get_option('googlenewssitemap_includePosts') == 'on') {echo '<input type="checkbox" name="googlenewssitemap_includePosts" checked="yes" />';}
  256. else {echo '<input type="checkbox" name="googlenewssitemap_includePosts" />';}
  257. ?>
  258. <label>Include posts in Google News sitemap <small>(Default)</small></label>
  259. </p>
  260. <p>
  261. <?php
  262. if (get_option('googlenewssitemap_includePages') == 'on') {echo '<input type="checkbox" name="googlenewssitemap_includePages" checked="yes" />';}
  263. else {echo '<input type="checkbox" name="googlenewssitemap_includePages" />';}
  264. ?>
  265. <label>Include pages in Google News sitemap</label>
  266. </p>
  267. <br style="clear:both"/>
  268. </div>
  269. <div class="postbox">
  270. <h3 class="hndle">Sitemap keywords</h3>
  271. <p>
  272. <?php
  273. if (get_option('googlenewssitemap_tagkeywords') == 'on') {echo '<input type="checkbox" name="googlenewssitemap_tagkeywords" checked="yes" />';}
  274. else {echo '<input type="checkbox" name="googlenewssitemap_tagkeywords" />';}
  275. ?>
  276. <label>Use post tags as sitemap keywords <small><a href="http://www.google.com/support/news_pub/bin/answer.py?answer=74288&topic=11666" style="text-decoration:none" target="_blank">More Info</a></small></label>
  277. </p>
  278. <br style="clear:both"/>
  279. </div>
  280. <div class="postbox">
  281. <h3 class="hndle">Exclude categories</h3>
  282. <div style="padding:10px">Select the categories you would like to <em><strong>exclude</strong></em> from the Google News Sitemap:</div>
  283. <div style="padding:10px">
  284. <?php
  285. //Categories to exclude from sitemap
  286. $excludedCats = get_option('googlenewssitemap_excludeCat');
  287. if (!is_array($excludedCats))
  288. $excludedCats= array();
  289. $categories = get_categories('hide_empty=1');
  290. foreach ($categories as $cat) {
  291. if (in_array($cat->cat_ID,$excludedCats))
  292. {
  293. echo '<label class="selectit"><input type="checkbox" name="googlenewssitemap_excludeCat[\''.$cat->cat_ID.'\']" value="'.$cat->cat_ID.'" checked="yes" /><span style="padding-left:5px">'.$cat->cat_name.'</span></label>';
  294. }
  295. else
  296. {
  297. echo '<label class="selectit"><input type="checkbox" name="googlenewssitemap_excludeCat[\''.$cat->cat_ID.'\']" value="'.$cat->cat_ID.'" /><span style="padding-left:5px">'.$cat->cat_name.'</span></label>';
  298. }
  299. }
  300. ?>
  301. <br style="clear:both"/>
  302. </div>
  303. </div>
  304. <input type="hidden" name="action" value="update" />
  305. <input type="hidden" name="page_options" value="googlenewssitemap_includePosts,googlenewssitemap_includePages,googlenewssitemap_tagkeywords,googlenewssitemap_excludeCat" />
  306. <div style="clear:both;padding-top:0px;"></div>
  307. <p class="submit"><input type="submit" name="Submit" value="<?php _e('Update Options') ?>" /></p>
  308. <div style="clear:both;padding-top:20px;"></div>
  309. </form>
  310. </div>
  311. <?php } ?>