/application/libraries/Sitemaps.php

https://github.com/chamnan/ionize · PHP · 247 lines · 159 code · 40 blank · 48 comment · 21 complexity · 694318399e7a5c3c2730b6d97a17c459 MD5 · raw file

  1. <?php if (!defined('BASEPATH')) exit('No direct script access allowed');
  2. /**
  3. * A class for generating XML sitemaps
  4. *
  5. * @author Philipp Dörner <pd@signalkraft.com>
  6. * @version 0.7
  7. * @access public
  8. * @package sitemaps
  9. *
  10. */
  11. class Sitemaps
  12. {
  13. var $items = array();
  14. function __construct()
  15. {
  16. $CI =& get_instance();
  17. $CI->config->load('sitemaps');
  18. }
  19. /**
  20. * Adds a new item to the urlset
  21. *
  22. * @param array $new_item
  23. * @access public
  24. */
  25. function add_item($new_item)
  26. {
  27. $this->items[] = $new_item;
  28. }
  29. /**
  30. * Adds an array of items to the urlset
  31. *
  32. * @param array $new_items array of items
  33. * @access public
  34. */
  35. function add_item_array($new_items)
  36. {
  37. $this->items = array_merge($this->items, $new_items);
  38. }
  39. /**
  40. * Generates the sitemap XML data
  41. *
  42. * @param string $file_name (optional) if file name is supplied the XML data is saved in it otherwise returned as a string
  43. * @param bool $gzip (optional) compress sitemap, overwrites config item 'sitemaps_gzip'
  44. * @access public
  45. * @return string
  46. */
  47. function build($file_name = null, $gzip = NULL)
  48. {
  49. $CI =& get_instance();
  50. $map = $CI->config->item('sitemaps_header') . "\n";
  51. foreach($this->items as $item)
  52. {
  53. $item['loc'] = htmlentities($item['loc'], ENT_QUOTES);
  54. $map .= "\t<url>\n\t\t<loc>" . $item['loc'] . "</loc>\n";
  55. $attributes = array("lastmod", "changefreq", "priority");
  56. foreach($attributes AS $attr)
  57. {
  58. if(isset($item[$attr]))
  59. {
  60. $map .= "\t\t<$attr>" . $item[$attr] . "</$attr>\n";
  61. }
  62. }
  63. $map .= "\t</url>\n\n";
  64. }
  65. unset($this->items);
  66. $map .= $CI->config->item('sitemaps_footer');
  67. if( ! is_null($file_name))
  68. {
  69. $fh = @fopen($file_name, 'w');
  70. if ($fh !== FALSE )
  71. {
  72. fwrite($fh, $map);
  73. fclose($fh);
  74. if($CI->config->item('sitemaps_filesize_error') && filesize($file_name) > 1024 * 1024 * 10)
  75. {
  76. show_error('Your sitemap is bigger than 10MB, most search engines will not accept it.');
  77. }
  78. if($gzip OR (is_null($gzip) && $CI->config->item('sitemaps_gzip')))
  79. {
  80. $gzdata = gzencode($map, 9);
  81. $file_gzip = str_replace("{file_name}", $file_name, $CI->config->item('sitemaps_gzip_path'));
  82. $fp = fopen($file_gzip, "w");
  83. fwrite($fp, $gzdata);
  84. fclose($fp);
  85. // Delete the uncompressed sitemap
  86. unlink($file_name);
  87. return $file_gzip;
  88. }
  89. return $file_name;
  90. }
  91. return FALSE;
  92. }
  93. else
  94. {
  95. return $map;
  96. }
  97. }
  98. /**
  99. * Generate a sitemap index file pointing to other sitemaps you previously built
  100. *
  101. * @param array $urls array of urls, each being an array with at least a loc index
  102. * @param string $file_name (optional) if file name is supplied the XML data is saved in it otherwise returned as a string
  103. * @param bool $gzip (optional) compress sitemap, overwrites config item 'sitemaps_gzip'
  104. * @access public
  105. * @return string
  106. */
  107. function build_index($urls, $file_name = null, $gzip = null)
  108. {
  109. $CI =& get_instance();
  110. $index = $CI->config->item('sitemaps_index_header') . "\n";
  111. foreach($urls as $url)
  112. {
  113. $url['loc'] = htmlentities($url['loc'], ENT_QUOTES);
  114. $index .= "\t<sitemap>\n\t\t<loc>" . $url['loc'] . "</loc>\n";
  115. if(isset($url['lastmod']))
  116. {
  117. $index .= "\t\t<lastmod>" . $url['lastmod'] . "</lastmod>\n";
  118. }
  119. $index .= "\t</sitemap>\n\n";
  120. }
  121. $index .= $CI->config->item('sitemaps_index_footer');
  122. if( ! is_null($file_name))
  123. {
  124. $fh = fopen($file_name, 'w');
  125. fwrite($fh, $index);
  126. fclose($fh);
  127. if($CI->config->item('sitemaps_filesize_error') && filesize($file_name) > 1024 * 1024 * 10)
  128. {
  129. show_error('Your sitemap index is bigger than 10MB, most search engines will not accept it.');
  130. }
  131. if($gzip OR (is_null($gzip) && $CI->config->item('sitemaps_index_gzip')))
  132. {
  133. $gzdata = gzencode($index, 9);
  134. $file_gzip = str_replace("{file_name}", $file_name, $CI->config->item('sitemaps_index_gzip_path'));
  135. $fp = fopen($file_gzip, "w");
  136. fwrite($fp, $gzdata);
  137. fclose($fp);
  138. // Delete the uncompressed sitemap index
  139. unlink($file_name);
  140. return $file_gzip;
  141. }
  142. return $file_name;
  143. }
  144. else
  145. {
  146. return $index;
  147. }
  148. }
  149. /**
  150. * Notify search engines of your updates sitemap
  151. *
  152. * @param string $url_xml absolute URL of your sitemap, use Codeigniter's site_url()
  153. * @param array $search_engines array of search engines to ping, see config file for notes
  154. * @access public
  155. * @return array HTTP reponse codes
  156. */
  157. function ping($url_xml, $search_engines = NULL)
  158. {
  159. $CI =& get_instance();
  160. if(is_null($search_engines))
  161. {
  162. $search_engines = $CI->config->item('sitemaps_search_engines');
  163. }
  164. $statuses = array();
  165. foreach($search_engines AS $engine)
  166. {
  167. $status = 0;
  168. if($fp = @fsockopen($engine['host'], 80))
  169. {
  170. $engine['url'] = empty($engine['url']) ? "/ping?sitemap=" : $engine['url'];
  171. $req = 'GET ' . $engine['url'] .
  172. urlencode($url_xml) . " HTTP/1.1\r\n" .
  173. "Host: " . $engine['host'] . "\r\n" .
  174. $CI->config->item('sitemaps_user_agent') .
  175. "Connection: Close\r\n\r\n";
  176. fwrite($fp, $req);
  177. while( ! feof($fp))
  178. {
  179. if(@preg_match('~^HTTP/\d\.\d (\d+)~i', fgets($fp, 128), $m))
  180. {
  181. $status = intval($m[1]);
  182. break;
  183. }
  184. }
  185. fclose($fp);
  186. }
  187. $statuses[] = array("host" => $engine['host'], "status" => $status, "request" => $req);
  188. }
  189. if($CI->config->item('sitemaps_log_http_responses') OR $CI->config->item('sitemaps_debug'))
  190. {
  191. foreach($statuses AS $reponse)
  192. {
  193. $message = "Sitemaps: " . $reponse['host'] . " responded with HTTP status " . $reponse['status'];
  194. if($CI->config->item('sitemaps_log_http_responses'))
  195. {
  196. $level = $reponse['status'] == 200 ? 'debug' : 'error';
  197. log_message($level, $message);
  198. }
  199. if($CI->config->item('sitemaps_debug'))
  200. {
  201. echo "<p>" . $message . " after request:</p>\n<pre>" . $reponse['request'] . "</pre>\n\n";
  202. }
  203. }
  204. }
  205. return $statuses;
  206. }
  207. }