/monthly-xml-sitemap.php

  1. <?php 
  2.  
  3. /** 
  4. Plugin Name: Google Monthly XML Sitemap 
  5. Plugin URI: http://andreapernici.com/wordpress/google-monthly-xml-sitemap/ 
  6. Description: Automatically generate sitemap divided by month to scale for large website and to reduce the load of each post generation excluding old posts and page from this operation. Go to <a href="options-general.php?page=monthly-xml-sitemap.php">Settings -> Google Monthly XML Sitemap</a> for setup. 
  7. Version: 1.0.6 
  8. Author: Andrea Pernici 
  9. Author URI: http://www.andreapernici.com/ 
  10.  
  11. Copyright 2009 Andrea Pernici (andreapernici@gmail.com) 
  12.  
  13. This program is free software; you can redistribute it and/or modify 
  14. it under the terms of the GNU General Public License as published by 
  15. the Free Software Foundation; either version 2 of the License, or 
  16. (at your option) any later version. 
  17.  
  18. This program is distributed in the hope that it will be useful,  
  19. but WITHOUT ANY WARRANTY; without even the implied warranty of 
  20. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
  21. GNU General Public License for more details. 
  22.  
  23. You should have received a copy of the GNU General Public License 
  24. along with this program; if not, write to the Free Software 
  25. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 
  26.   
  27. */ 
  28.  
  29. $apgmxs_sitemap_version = "1.0.0"; 
  30. $apgmxs_upload_dir = wp_upload_dir();  
  31. $apgmxs_xml_upload_dir = $apgmxs_upload_dir['basedir'].'/ap-sitemap'; 
  32. $apgmxs_xml_upload_urls = $apgmxs_upload_dir['baseurl'].'/ap-sitemap'; 
  33. if ( !is_dir($apgmxs_xml_upload_dir) ) mkdir($apgmxs_xml_upload_dir) or die("Could not create directory " . $apgmxs_xml_upload_dir); 
  34. // Aggiungiamo le opzioni di default 
  35. add_option('apgmxs_news_active', true); 
  36. add_option('apgmxs_tags', true); 
  37. add_option('apgmxs_path', $apgmxs_xml_upload_dir); 
  38. add_option('apgmxs_urls', $apgmxs_xml_upload_urls); 
  39. add_option('apgmxs_last_ping', 0); 
  40. add_option('apgmxs_excludecatlist', ''); 
  41. add_option('apgmxs_excludepostlist', ''); 
  42. //Controllo eliminazione, pubblicazione pagine post per rebuild 
  43. add_action('future_to_publish', apgmxs_autobuild , 9999, 1); // should be  
  44. add_action('delete_post', apgmxs_autobuild , 9999, 1);  
  45. add_action('publish_post', apgmxs_autobuild , 9999, 1);  
  46. add_action('publish_page', apgmxs_autobuild , 9999, 1); 
  47.  
  48. // Carichiamo le opzioni 
  49. $apgmxs_news_active = get_option('apgmxs_news_active'); 
  50. $apgmxs_path = get_option('apgmxs_path'); 
  51.  
  52. // Aggiungiamo la pagina delle opzioni 
  53. add_action('admin_menu', 'apgmxs_add_pages'); 
  54.  
  55. //Aggiungo la pagina della configurazione 
  56. function apgmxs_add_pages() { 
  57. add_options_page("AP Monthly XML Sitemap", "Monthly XML Sitemap", 8, basename(__FILE__), "apgmxs_admin_page"); 
  58.  
  59.  
  60. function apgmxs_escapexml($string) { 
  61. return str_replace ( array ( '&', '"', "'", '<', '>'), array ( '&' , '"', ''' , '<' , '>'), $string); 
  62.  
  63. function apgmxs_permissions() { 
  64.  
  65. $apgmxs_news_active = get_option('apgmxs_news_active'); 
  66.  
  67. $apgmxs_path = get_option('apgmxs_path'); 
  68. if ( !is_dir($apgmxs_path) ) mkdir($apgmxs_path) or die("Could not create directory " . $apgmxs_path); 
  69. $apgmxs_news_file_path = $apgmxs_path . "/sitemap-ap-monthly-index.xml"; 
  70.  
  71. if ($apgmxs_news_active && is_file($apgmxs_news_file_path) && is_writable($apgmxs_news_file_path)) $apgmxs_permission += 0; 
  72. elseif ($apgmxs_news_active && !is_file($apgmxs_news_file_path) && is_writable($apgmxs_path)) { 
  73. $fp = fopen($apgmxs_news_file_path, 'w'); 
  74. fwrite($fp, "<?xml version=\"1.0\" encoding=\"UTF-8\"?><urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\" />"); 
  75. fclose($fp); 
  76. if (is_file($apgmxs_news_file_path) && is_writable($apgmxs_news_file_path)) $apgmxs_permission += 0; 
  77. else $apgmxs_permission += 2; 
  78. elseif ($apgmxs_news_active) $apgmxs_permission += 2; 
  79. else $apgmxs_permission += 0; 
  80.  
  81. return $apgmxs_permission; 
  82.  
  83. function apgmxs_getDirectoryList($directory) { 
  84. // create an array to hold directory list 
  85. $results = array(); 
  86. // create a handler for the directory 
  87. $handler = opendir($directory); 
  88. // open directory and walk through the filenames 
  89. while ($file = readdir($handler)) { 
  90. // if file isn't this directory or its parent, add it to the results 
  91. if ($file != "." && $file != "..") { 
  92. $results[] = $file; 
  93. // tidy up: close the handler 
  94. closedir($handler); 
  95. // done! 
  96. return $results; 
  97.  
  98. /** 
  99. Auto Build sitemap 
  100. */ 
  101. function apgmxs_autobuild($postID) { 
  102. global $wp_version; 
  103. $isScheduled = false; 
  104. $lastPostID = 0; 
  105. //Ricostruisce la sitemap una volta per post se non fa import 
  106. if($lastPostID != $postID && (!defined('WP_IMPORTING') || WP_IMPORTING != true)) { 
  107.  
  108. //Costruisce la sitemap direttamente oppure fa un cron 
  109. if(floatval($wp_version) >= 2.1) { 
  110. if(!$isScheduled) { 
  111. //Ogni 15 secondi. 
  112. //Pulisce tutti gli hooks. 
  113. wp_clear_scheduled_hook(apgmxs_generate_sitemap()); 
  114. wp_schedule_single_event(time()+15, apgmxs_generate_sitemap()); 
  115. $isScheduled = true; 
  116. } else { 
  117. //Costruisce la sitemap una volta sola e mai in bulk mode 
  118. if(!$lastPostID && (!isset($_GET["delete"]) || count((array) $_GET['delete'])<=0)) { 
  119. apgmxs_generate_sitemap(); 
  120. $lastPostID = $postID; 
  121.  
  122.  
  123. function apgmxs_generate_sitemap() { 
  124. global $apgmxs_sitemap_version, $table_prefix; 
  125. global $wpdb; 
  126.  
  127. $t = $table_prefix; 
  128.  
  129. $apgmxs_news_active = get_option('apgmxs_news_active'); 
  130. $apgmxs_path = get_option('apgmxs_path'); 
  131. $apgmxs_urls = get_option('apgmxs_urls'); 
  132. $apgmxs_excludecatlist = get_option('apgmxs_excludecatlist'); 
  133. $apgmxs_excludepostlist = get_option('apgmxs_excludepostlist'); 
  134.  
  135. $includeMe = ''; 
  136. $includeNoCat = ''; 
  137. $includeNoPost = ''; 
  138. if ( apgmxs_excludecatlist <> NULL ) { 
  139. $exPosts = get_objects_in_term($apgmxs_excludecatlist, "category"); 
  140. $includeNoCat = ' AND `ID` NOT IN ('.implode(", ", $exPosts).')'; 
  141. $ceck = implode(", ", $exPosts); 
  142. if ($ceck == '' || $ceck == ' ') $includeNoCat = ''; 
  143. if ($apgmxs_excludepostlist != '') { 
  144. $includeNoPost = ' AND `ID` NOT IN ('.$apgmxs_excludepostlist.')'; 
  145. $ceck = implode(", ", $exPosts); 
  146. if ($apgmxs_excludepostlist == '' || $apgmxs_excludepostlist == ' ') $includeNoPost = ''; 
  147.  
  148. $apgmxs_permission = apgmxs_permissions(); 
  149. if ($apgmxs_permission > 2 || (!$apgmxs_active && !$apgmxs_news_active)) return; 
  150.  
  151. $home = get_option('home') . "/"; 
  152.  
  153. $xml_sitemap_google_monthly = '<?xml version="1.0" encoding="UTF-8"?>'; 
  154. $xml_sitemap_google_monthly .= ' 
  155. <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> 
  156. <!-- Generated by Google Monthly XML Sitemap '.$apgmxs_sitemap_version.' --> 
  157. <!-- plugin by Andrea Pernici --> 
  158. <!-- http://andreapernici.com/wordpress/google-monthly-xml-sitemap/ --> 
  159. <!-- Created '.date("F d, Y, H:i").' -->'; 
  160.  
  161. $posts = $wpdb->get_results("SELECT * FROM ".$wpdb->posts." WHERE `post_status`='publish'  
  162. AND (`post_type`='page' OR `post_type`='post') ". $includeNoCat . ' ' . $includeNoPost." GROUP BY `ID` ORDER BY `post_date` DESC");  
  163.  
  164. $now = date("Y-m-d"); 
  165.  
  166. $actualmonth = date("m"); 
  167. $actualyear = date("Y"); 
  168. $toprependurl = ''; 
  169. // To generate only the last month sitemap 
  170. $apgmxs_flag=0; 
  171. // This loop assumes that the posts are ordered 
  172. foreach ($posts as $post) { 
  173. if ($apgmxs_news_active && $apgmxs_permission != 2) { 
  174. $postDate = strtotime($post->post_date); 
  175. $postmonth = mysql2date('m', $post->post_date); 
  176. $postyear = mysql2date('Y', $post->post_date); 
  177. //echo 'postlmonth'.$postmonth.'<br/>'; 
  178. //echo 'actualmonth'.$actualmonth.'<br/>'; 
  179. if ($postmonth == $actualmonth && $actualyear == $postyear ) { 
  180. $xml_sitemap_urls .= $toprependurl." 
  181. <url> 
  182. <loc>".apgmxs_escapexml(get_permalink($post->ID))."</loc> 
  183. <lastmod>".mysql2date('Y-m-d', $post->post_date)."</lastmod> 
  184. </url>"; 
  185. $toprependurl = ''; 
  186. } else { 
  187. $toprependurl = " 
  188. <url> 
  189. <loc>".apgmxs_escapexml(get_permalink($post->ID))."</loc> 
  190. <lastmod>".mysql2date('Y-m-d', $post->post_date)."</lastmod> 
  191. </url>"; 
  192. $filename = $apgmxs_path . "/sitemap-ap-".$actualyear."-".$actualmonth.".xml"; 
  193. if (!file_exists($filename) || ( $apgmxs_flag==0 )) { 
  194. $fp = fopen($filename, 'w'); 
  195. $steppedsitemap = $xml_sitemap_google_monthly . $xml_sitemap_urls . " 
  196. </urlset>"; 
  197. fwrite($fp, $steppedsitemap); 
  198. fclose($fp); 
  199. } else {echo 'Execution Stopped at this point: '.$filename.'<br />You Have probably some issue with your post_date that is set to 0000-00-00 - Please Check'; break;} 
  200. $actualmonth = $postmonth; 
  201. $actualyear = $postyear; 
  202. $xml_sitemap_urls = ''; 
  203. $steppedsitemap = ''; 
  204. $apgmxs_flag=1;  
  205.  
  206.  
  207. // Get all the generated monthly Sitemaps and generate the sitemap Index. 
  208. $apgmxs_file_list = apgmxs_getDirectoryList($apgmxs_path); 
  209. $apgmxs_j=0; 
  210. while ($apgmxs_file_list[$apgmxs_j]) {  
  211. if ($apgmxs_file_list[$apgmxs_j] == 'sitemap-ap-monthly-index.xml') {  
  212. $apgmxs_j++; 
  213. } else { 
  214. $apgmxs_sitemap_index_content .= '<sitemap> 
  215. <loc>'.$apgmxs_urls.'/'.$apgmxs_file_list[$apgmxs_j].'</loc> 
  216. <lastmod>'.$now.'</lastmod> 
  217. </sitemap>'; 
  218. $apgmxs_j++; 
  219.  
  220.  
  221. $apgmxs_sitemap_index_start = '<?xml version="1.0" encoding="UTF-8"?> 
  222. <sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">'; 
  223. $apgmxs_sitemap_index_end = ' 
  224. </sitemapindex>'; 
  225.  
  226. if ($apgmxs_news_active && $apgmxs_permission != 2) { 
  227. $fp = fopen($apgmxs_path . "/sitemap-ap-monthly-index.xml", 'w'); 
  228. fwrite($fp, $apgmxs_sitemap_index_start.$apgmxs_sitemap_index_content.$apgmxs_sitemap_index_end); 
  229. fclose($fp); 
  230.  
  231. // Ping the sitemap index to search engine 
  232. $apgmxs_last_ping = get_option('apgmxs_last_ping'); 
  233. if ((time() - $apgmxs_last_ping) > 60 * 60) { 
  234. //get_headers("http://www.google.com/webmasters/tools/ping?sitemap=" . urlencode($home . $apgmxs_path . "sitemap.xml")); //PHP5+ 
  235. $fp = @fopen("http://www.google.com/webmasters/tools/ping?sitemap=" . urlencode($apgmxs_urls. "/sitemap-ap-monthly-index.xml"), 80); 
  236. @fclose($fp); 
  237. $fp = @fopen("http://www.bing.com/webmaster/ping.aspx?siteMap=". urlencode($apgmxs_urls. "/sitemap-ap-monthly-index.xml"), 80); 
  238. @fclose($fp); 
  239. update_option('apgmxs_last_ping', time()); 
  240.  
  241.  
  242.  
  243. //Config page 
  244. function apgmxs_admin_page() { 
  245. $msg = ""; 
  246.  
  247. // Check form submission and update options 
  248. if ('apgmxs_submit' == $_POST['apgmxs_submit']) { 
  249. update_option('apgmxs_news_active', $_POST['apgmxs_news_active']); 
  250. update_option('apgmxs_excludecat', $_POST['apgmxs_excludecat']); 
  251. update_option('apgmxs_excludepostlist', $_POST['apgmxs_excludepostlist']); 
  252.  
  253. // Excluded category 
  254. $exCats = array(); 
  255. if(isset($_POST["post_category"])) { 
  256. foreach((array) $_POST["post_category"] AS $vv) if(!empty($vv) && is_numeric($vv)) $exCats[] = intval($vv); 
  257. update_option('apgmxs_excludecatlist', $exCats);  
  258.  
  259. // Sitemap generation 
  260. apgmxs_generate_sitemap(); 
  261.  
  262. $apgmxs_news_active = get_option('apgmxs_news_active'); 
  263. $apgmxs_path = get_option('apgmxs_path'); 
  264. $apgmxs_urls = get_option('apgmxs_urls'); 
  265. $apgmxs_excludepostlist = get_option('apgmxs_excludepostlist'); 
  266.  
  267. $apgmxs_permission = apgmxs_permissions(); 
  268. $apgmxs_file_list = apgmxs_getDirectoryList($apgmxs_path); 
  269. if ($apgmxs_permission == 1) $msg = "Error: there is a problem with <em>sitemap-ap-monthly-index.xml</em>. It doesn't exist or is not writable. <a href=\"http://www.andreapernici.com/wordpress/google-news-sitemap/\" target=\"_blank\" >For help see the plugin's homepage</a>."; 
  270. elseif ($apgmxs_permission == 2) $msg = "Error: there is a problem with <em>sitemap-ap-monthly-index.xml</em>. It doesn't exist or is not writable. <a href=\"http://www.andreapernici.com/wordpress/google-news-sitemap/\" target=\"_blank\" >For help see the plugin's homepage</a>."; 
  271. elseif ($apgmxs_permission == 3) $msg = "Error: there is a problem with <em>sitemap-ap-monthly-index</em>. It doesn't exist or is not writable. <a href=\"http://www.andreapernici.com/wordpress/google-news-sitemap/\" target=\"_blank\" >For help see the plugin's homepage</a>."; 
  272. ?> 
  273.  
  274. <style type="text/css"> 
  275. a.sm_button { 
  276. padding:4px; 
  277. display:block; 
  278. padding-left:25px; 
  279. background-repeat:no-repeat; 
  280. background-position:5px 50%; 
  281. text-decoration:none; 
  282. border:none; 
  283.  
  284. .sm-padded .inside { 
  285. margin:12px!important; 
  286. .sm-padded .inside ul { 
  287. margin:6px 0 12px 0; 
  288.  
  289. .sm-padded .inside input { 
  290. padding:1px; 
  291. margin:0; 
  292. </style>  
  293.  
  294.  
  295.  
  296. <div class="wrap" id="sm_div"> 
  297. <h2>Google Monthly XML Sitemap</h2>  
  298. by <strong>Andrea Pernici</strong> 
  299. <p> 
  300.  <a target="_blank" title="Google Monthly XML Sitemap Plugin Release History" href="http://andreapernici.com/wordpress/google-monthly-xml-sitemap/">Changelog</a>  
  301. | <a target="_blank" title="Google Monthly XML Sitemap Support" href="http://andreapernici.com/wordpress/google-monthly-xml-sitemap/">Support</a> 
  302. </p> 
  303. <?php if ($msg) { ?> 
  304. <div id="message" class="error"><p><strong><?php echo $msg; ?></strong></p></div> 
  305. <?php } ?> 
  306.  
  307. <div style="width:824px;">  
  308. <div style="float:left;background-color:white;padding: 10px 10px 10px 10px;margin-right:15px;border: 1px solid #ddd;">  
  309. <div style="width:350px;height:130px;">  
  310. <h3>Donate</h3>  
  311. <em>If you like this plugin and find it useful, help keep this plugin free and actively developed by going to the <a href="http://andreapernici.com/donazioni" target="_blank"><strong>donate</strong></a> page on my website.</em>  
  312. <p><em>Also, don't forget to follow me on <a href="http://twitter.com/andreapernici/" target="_blank"><strong>Twitter</strong></a>.</em></p>  
  313. </div>  
  314. </div>  
  315.  
  316. <div style="float:left;background-color:white;padding: 10px 10px 10px 10px;border: 1px solid #ddd;">  
  317. <div style="width:415px;height:130px;">  
  318. <h3>Google Guidelines and Credits</h3>  
  319. <p><em>For any doubt refer to the plugin page <a href="http://www.andreapernici.com/wordpress/google-monthly-xml-sitemap/">here</a>.</em></p> 
  320. <p><em>Plugin by <a href="http://www.andreapernici.com">Andrea Pernici</a> to save lots of system resources.</em> </p> 
  321. </div>  
  322. </div>  
  323. </div> 
  324. <div style="clear:both";></div>  
  325. </div> 
  326.  
  327.  
  328.  
  329. <div id="wpbody-content">  
  330.  
  331. <div class="wrap" id="sm_div"> 
  332.  
  333. <div id="poststuff" class="metabox-holder has-right-sidebar">  
  334. <div class="inner-sidebar">  
  335. <div id="side-sortables" class="meta-box-sortabless ui-sortable" style="position:relative;">  
  336. <div id="sm_pnres" class="postbox">  
  337. <h3 class="hndle"><span>Info plugin:</span></h3>  
  338. <div class="inside">  
  339. <a class="sm_button sm_pluginHome" href="http://www.andreapernici.com/wordpress/google-monthly-xml-sitemap/">Plugin Homepage</a>  
  340. <a class="sm_button sm_pluginSupport" href="http://wordpress.org/extend/plugins/google-monthly-xml-sitemap/">Forum</a> 
  341. <a class="sm_button sm_donatePayPal" href="http://andreapernici.com/donazioni">Donations</a> 
  342. </div>  
  343. </div> 
  344. <div id="sm_elencositemap" class="postbox"> 
  345. <h3 class="hndle"><span>Generated Sitemap</span></h3>  
  346. <div class="inside"> 
  347. <?php $apgmxs_i=0; 
  348. while ($apgmxs_file_list[$apgmxs_i]) {  
  349. echo '<a target="_blank" href="'.$apgmxs_urls.'/'.$apgmxs_file_list[$apgmxs_i].'">'.$apgmxs_file_list[$apgmxs_i].'</a><br />'; 
  350. $apgmxs_i++; 
  351. } ?> 
  352. </div> 
  353. </div> 
  354. </div> 
  355. </div> 
  356.  
  357.  
  358.  
  359.  
  360. <div class="has-sidebar sm-padded" >  
  361.  
  362. <div id="post-body-content" class="has-sidebar-content">  
  363.  
  364. <div class="meta-box-sortabless">  
  365.  
  366. <div id="sm_rebuild" class="postbox">  
  367. <h3 class="hndle"><span>Google Monthly XML Sitemap settings</span></h3> 
  368. <div class="inside">  
  369.  
  370. <form name="form1" method="post" action="<?php echo $_SERVER["REQUEST_URI"]; ?>&updated=true"> 
  371. <input type="hidden" name="apgmxs_submit" value="apgmxs_submit" /> 
  372. <ul> 
  373. <li> 
  374. <label for="apgmxs_news_active"> 
  375. <input name="apgmxs_news_active" type="checkbox" id="apgmxs_news_active" value="1" <?php echo $apgmxs_news_active?'checked="checked"':''; ?> /> 
  376. Create Monthly Sitemap. 
  377. </label> 
  378. </li> 
  379. </ul> 
  380. <b>Sitemap will be generated in <?php echo $apgmxs_urls;?>/sitemap-ap-monthly-index.xml</b><br /> 
  381. <b>Il percorso della sitemap sul server saraà il seguente <?php echo $apgmxs_path;?></b> 
  382. </div> 
  383. </div> 
  384. <!-- Excluded Items -->  
  385.  
  386. <div id="sm_excludes" class="postbox">  
  387. <h3 class="hndle"><span>Escludi elementi</span></h3>  
  388.  
  389. <div class="inside">  
  390.  
  391. <b>Exclude Category:</b>  
  392.  
  393. <?php  
  394. $excludedCats = get_option('apgmxs_excludecatlist'); 
  395. if (!is_array($excludedCats)) $excludedCats = array(); 
  396. ?> 
  397. <div style="border-color:#CEE1EF; border-style:solid; border-width:2px; height:10em; margin:5px 0px 5px 40px; overflow:auto; padding:0.5em 0.5em;">  
  398. <ul>  
  399. <?php wp_category_checklist(0, 0, $excludedCats, false); ?>  
  400.  
  401. </ul>  
  402.  
  403. </div>  
  404.  
  405. <b>Exlclude Articles:</b>  
  406. <div style="margin:5px 0 13px 40px;">  
  407. <label for="apgmxs_excludepost">Exclude the following articles or pages: <small>put comma separated ID (ex. 1, 2, 3)</small><br />  
  408. <input name="apgmxs_excludepostlist" id="apgmxs_excludepostlist" type="text" style="width:400px;" value="<?php echo $apgmxs_excludepostlist;?>" /></label><br />  
  409. </div>  
  410.  
  411. </div>  
  412. </div>  
  413. <!-- Excluded --> 
  414. <p class="submit"> <input type="submit" value="Save & Rebuild" /></p> 
  415. </form> 
  416.  
  417.  
  418. </div> 
  419. </div> 
  420. </div> 
  421. </div> 
  422. </div>  
  423. </div> 
  424. <?php 
  425. ?> 
.