|
1 <?php |
|
2 // $Id: xmlsitemap.pages.inc,v 1.1.4.4 2009/07/02 14:20:24 earnie Exp $ |
|
3 |
|
4 |
|
5 /** |
|
6 * @file |
|
7 * XML sitemap page callbacks. |
|
8 */ |
|
9 |
|
10 /** |
|
11 * @addtogroup xmlsitemap |
|
12 * @{ |
|
13 */ |
|
14 |
|
15 /***************************************************************************** |
|
16 * Menu callbacks / form builders, submit/validate functions. |
|
17 ****************************************************************************/ |
|
18 |
|
19 /** |
|
20 * Menu callback; display the sitemap. |
|
21 * |
|
22 * @param $chunk |
|
23 * An integer specifying which chunk of the sitemap is being requested. |
|
24 * If not set and there is more than one chunk, display the sitemap index. |
|
25 */ |
|
26 function xmlsitemap_output($chunk = NULL) { |
|
27 global $user; |
|
28 $chunk_size = variable_get('xmlsitemap_chunk_size', XMLSITEMAP_DEFAULT_SITEMAP_LINKS); |
|
29 $link_count = xmlsitemap_link_count(); |
|
30 $chunk_count = xmlsitemap_chunk_count(); |
|
31 // A sitemap may only have a set number of index links (links to other sitemap |
|
32 // files) and a set number of site links in each of the "other" sitemap files. |
|
33 // This code adjusts the number of site links specified by the user if the |
|
34 // set number of index links has been reached but will not set that number |
|
35 // greater than the set number of site links in a file. |
|
36 if ($chunk_count > XMLSITEMAP_MAX_SITEMAP_INDEX_LINKS && |
|
37 $chunk_size < XMLSITEMAP_MAX_SITEMAP_LINKS) { |
|
38 // Determine the number of chunks we are over the maximum index links. |
|
39 $chunk_adjust = $chunk_count - XMLSITEMAP_MAX_SITEMAP_INDEX_LINKS; |
|
40 // Determine the number of links to adjust the chunk size. |
|
41 $chunk_adjust = $chunk_adjust * $chunk_size; |
|
42 if (($chunk_size + $chunk_adjust) <= XMLSITEMAP_MAX_SITEMAP_LINKS) { |
|
43 $chunk_size += $chunk_adjust; |
|
44 } |
|
45 else { |
|
46 $chunk_size = XMLSITEMAP_MAX_SITEMAP_LINKS; |
|
47 } |
|
48 variable_set('xmlsitemap_chunk_size', $chunk_size); |
|
49 watchdog('xmlsitemap', 'Chunk size has been updated to @chunk-size.', array('@chunk-size' => $chunk_size)); |
|
50 } |
|
51 elseif($chunk_count > XMLSITEMAP_MAX_SITEMAP_INDEX_LINKS) { |
|
52 watchdog('xmlsitemap', 'The maximum number of allowed links has been reached.', NULL, WATCHDOG_ERROR); |
|
53 } |
|
54 if (isset($chunk) && !is_numeric($chunk)) { |
|
55 drupal_not_found(); |
|
56 exit(); |
|
57 } |
|
58 $id = xmlsitemap_language_id(); |
|
59 if (variable_get('xmlsitemap_sitemap_needs_update', FALSE)) { |
|
60 variable_set('xmlsitemap_update_timestamp', REQUEST_TIME); |
|
61 db_query("DELETE FROM {xmlsitemap} WHERE type ='frontpage'"); |
|
62 $row = new stdClass(); |
|
63 $row->module = 'xmlsitemap'; |
|
64 $row->type = 'frontpage'; |
|
65 $changefreq = variable_get('xmlsitemap_front_page_changefreq', 3600); |
|
66 $row->changed = REQUEST_TIME - $changefreq; |
|
67 $row->changefreq = $changefreq; |
|
68 $row->priority = variable_get('xmlsitemap_front_page_priority', 1); |
|
69 drupal_write_record('xmlsitemap', $row); |
|
70 module_invoke_all('xmlsitemap_links'); |
|
71 variable_set('xmlsitemap_sitemap_needs_update', FALSE); |
|
72 $result = _xmlsitemap_create_cache_files(); |
|
73 if (variable_get("xmlsitemap_create_cache_result_$id", -1) !== $result) { |
|
74 variable_set("xmlsitemap_create_cache_result_$id", $result); |
|
75 } |
|
76 } |
|
77 elseif (_xmlsitemap_check_cache_files()) { |
|
78 $result = _xmlsitemap_create_cache_files(); |
|
79 if (variable_get("xmlsitemap_create_cache_result_$id", -1) !== $result) { |
|
80 variable_set("xmlsitemap_create_cache_result_$id", $result); |
|
81 } |
|
82 } |
|
83 if (!isset($chunk)) { |
|
84 if (($chunks = (integer) $link_count / $chunk_size) != variable_get('xmlsitemap_previous_chunks_count', -1)) { |
|
85 variable_set('xmlsitemap_previous_chunks_count', $chunks); |
|
86 if (!variable_get('menu_rebuild_needed', FALSE)) { |
|
87 variable_set('menu_rebuild_needed', TRUE); |
|
88 } |
|
89 } |
|
90 } |
|
91 if (isset($result) && !$result) { |
|
92 drupal_not_found(); |
|
93 exit(); |
|
94 } |
|
95 $parent_directory = variable_get('xmlsitemap_cache_directory', file_directory_path() .'/xmlsitemap'); |
|
96 $headers = array("Content-type: text/xml; charset=utf-8"); |
|
97 if (isset($chunk)) { |
|
98 if ($chunk < $link_count / $chunk_size) { |
|
99 file_transfer("$parent_directory/xsm-$id-$chunk.xml", $headers); |
|
100 } |
|
101 } |
|
102 else { |
|
103 file_transfer("$parent_directory/xsm-$id.xml", $headers); |
|
104 } |
|
105 } |
|
106 |
|
107 /***************************************************************************** |
|
108 * Private functions. |
|
109 ****************************************************************************/ |
|
110 |
|
111 /** |
|
112 * Check the cache files. |
|
113 * |
|
114 * @return |
|
115 * TRUE if the cache files must be updated / created, FALSE otherwise. |
|
116 */ |
|
117 function _xmlsitemap_check_cache_files() { |
|
118 $chunk_size = variable_get('xmlsitemap_chunk_size', 1000); |
|
119 $link_count = xmlsitemap_link_count(); |
|
120 $id = xmlsitemap_language_id(); |
|
121 $parent_directory = variable_get('xmlsitemap_cache_directory', file_directory_path() .'/xmlsitemap'); |
|
122 // If the directory that should contains the cache files doesn't exist, then |
|
123 // the cache files must be created. |
|
124 if (!file_check_directory($parent_directory, FILE_CREATE_DIRECTORY)) { |
|
125 return TRUE; |
|
126 } |
|
127 $update_timestamp = variable_get('xmlsitemap_update_timestamp', REQUEST_TIME); |
|
128 // If the cache files creation has failed last time, the cache files must be |
|
129 // created. |
|
130 if (variable_get("xmlsitemap_create_cache_result_$id", -1) !== TRUE) { |
|
131 return TRUE; |
|
132 } |
|
133 // If the main cache file doesn't exist, then the cache files must be |
|
134 // created. |
|
135 if (!file_exists($parent_directory ."/xsm-$id.xml")) { |
|
136 return TRUE; |
|
137 } |
|
138 // If the main cache file has been created before the sitemap content has |
|
139 // been updated, then the cache files must be updated. |
|
140 if (filemtime($parent_directory ."/xsm-$id.xml") < $update_timestamp) { |
|
141 return TRUE; |
|
142 } |
|
143 // Check also the other cache files. |
|
144 if ($link_count > $chunk_size) { |
|
145 for ($chunk = 0; $chunk < $link_count / $chunk_size; ++$chunk) { |
|
146 if (!file_exists($parent_directory ."/xsm-$id-$chunk.xml")) { |
|
147 return TRUE; |
|
148 } |
|
149 if (filemtime($parent_directory ."/xsm-$id-$chunk.xml") < $update_timestamp) { |
|
150 return TRUE; |
|
151 } |
|
152 } |
|
153 } |
|
154 return FALSE; |
|
155 } |
|
156 |
|
157 /** |
|
158 * Create a sitemap chunk cache file. |
|
159 * |
|
160 * @param $fp |
|
161 * A file resource used to write in. |
|
162 * @param $chunk_size |
|
163 * The number of links the chunk must cointain. |
|
164 * @param $chunk |
|
165 * The progressive number associated with the sitemap chunk (starting from |
|
166 * 0). |
|
167 */ |
|
168 function _xmlsitemap_create_cache_chunk($fp, $chunk_size, $chunk = 0) { |
|
169 fwrite($fp, '<?xml version="1.0" encoding="UTF-8"?>' . "\n"); |
|
170 if ($xsl = _xmlsitemap_xsl()) { |
|
171 fwrite($fp, '<?xml-stylesheet type="text/xsl" href="' . $xsl . '" ?>' . "\n"); |
|
172 } |
|
173 fwrite($fp, '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"' . "\n"); |
|
174 fwrite($fp, ' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"' . "\n"); |
|
175 fwrite($fp, ' xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9' . "\n"); |
|
176 fwrite($fp, ' http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">' . "\n"); |
|
177 $start = $chunk * $chunk_size; |
|
178 $links = db_query_range("SELECT xsm.loc, xsm.module, xsm.type, xsm.id, xsm.sid, xsm.changed, xsm.changefreq, xsm.priority". xmlsitemap_sitemap_query() ."ORDER BY xsm.priority DESC, xsm.changed DESC, xsm.changefreq, xsm.loc", $start, $chunk_size); |
|
179 while ($link = db_fetch_object($links)) { |
|
180 if ($link->type == 'frontpage') { |
|
181 $url = url(NULL, array('absolute' => TRUE)); |
|
182 } |
|
183 else { |
|
184 $url = url($link->loc, array('absolute' => TRUE)); |
|
185 } |
|
186 $link->url = $url; |
|
187 if ($link->module && function_exists($link->module .'_xmlsitemap_link_status')) { |
|
188 $function = $link->module .'_xmlsitemap_link_status'; |
|
189 $link->status = $function($link->type, $link->id, $link->sid); |
|
190 } |
|
191 else { |
|
192 $link->status = 0; |
|
193 } |
|
194 drupal_alter('xmlsitemap_data', $link); |
|
195 if (($link->status & XMLSITEMAP_LINK_DISABLED) != XMLSITEMAP_LINK_DISABLED) { |
|
196 fwrite($fp, ' <url>' . "\n"); |
|
197 fwrite($fp, ' <loc>'. check_url($link->url) .'</loc>' . "\n"); |
|
198 fwrite($fp, ' <lastmod>'. gmdate(DATE_W3C, $link->changed) .'</lastmod>' . "\n"); |
|
199 fwrite($fp, ' <changefreq>'. xmlsitemap_sitemap_frequency($link->changefreq) .'</changefreq>' . "\n"); |
|
200 fwrite($fp, ' <priority>'. number_format($link->priority, 1) .'</priority>' . "\n"); |
|
201 fwrite($fp, ' </url>' . "\n"); |
|
202 } |
|
203 } |
|
204 fwrite($fp, '</urlset>'); |
|
205 } |
|
206 |
|
207 /** |
|
208 * Determine path for a xml stylesheet. |
|
209 * |
|
210 * @return |
|
211 * - The stylesheet path or FALSE. |
|
212 */ |
|
213 function _xmlsitemap_xsl() { |
|
214 if (variable_get('xmlsitemap_use_stylesheet', FALSE)) { |
|
215 $paths = array( |
|
216 variable_get('xmlsitemap_cache_directory', file_directory_path() . '/xmlsitemap') . '/gss.xsl', |
|
217 drupal_get_path('module', 'xmlsitemap') . '/gss/gss.xsl', |
|
218 ); |
|
219 foreach ($paths as $path) { |
|
220 if (file_exists($path)) { |
|
221 return base_path() . $path; |
|
222 } |
|
223 } |
|
224 } |
|
225 return FALSE; |
|
226 } |
|
227 |
|
228 /** |
|
229 * Create the cache files containing the sitemap. |
|
230 * |
|
231 * @return |
|
232 * TRUE if the operation has been successfull, FALSE otherwise. |
|
233 */ |
|
234 function _xmlsitemap_create_cache_files() { |
|
235 $chunk_size = variable_get('xmlsitemap_chunk_size', 1000); |
|
236 $link_count = xmlsitemap_link_count(); |
|
237 $id = xmlsitemap_language_id(); |
|
238 $parent_directory = variable_get('xmlsitemap_cache_directory', file_directory_path() .'/xmlsitemap'); |
|
239 // If the directory doesn't exist, then create it. |
|
240 if (!file_check_directory($parent_directory, FILE_CREATE_DIRECTORY)) { |
|
241 return TRUE; |
|
242 } |
|
243 if ($link_count > $chunk_size) { |
|
244 if (!$fp = fopen($parent_directory ."/xsm-$id.xml", 'wb')) { |
|
245 watchdog('xmlsitemap', 'Could not create the cache file @file.', array('@file' => $parent_directory ."/xsm-$id.xml"), WATCHDOG_ERROR); |
|
246 return FALSE; |
|
247 } |
|
248 fwrite($fp, '<?xml version="1.0" encoding="UTF-8"?>' . "\n"); |
|
249 if ($xsl = _xmlsitemap_xsl()) { |
|
250 fwrite($fp, '<?xml-stylesheet type="text/xsl" href="' . $xsl . '" ?>' . "\n"); |
|
251 } |
|
252 fwrite($fp, '<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"' . "\n"); |
|
253 fwrite($fp, ' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"' . "\n"); |
|
254 fwrite($fp, ' xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9' . "\n"); |
|
255 fwrite($fp, ' http://www.sitemaps.org/schemas/sitemap/0.9/siteindex.xsd">' . "\n"); |
|
256 for ($chunk = 0; $chunk < $link_count / $chunk_size; ++$chunk) { |
|
257 fwrite($fp, ' <sitemap>' . "\n"); |
|
258 fwrite($fp, ' <loc>'. url("sitemap$chunk.xml", array('absolute' => TRUE)) .'</loc>' . "\n"); |
|
259 $from = $chunk * $chunk_size; |
|
260 $changed = db_result(db_query_range("SELECT xsm.changed". xmlsitemap_sitemap_query() ."ORDER BY xsm.priority DESC, xsm.changed DESC", $from, $chunk_size)); |
|
261 fwrite($fp, ' <lastmod>'. gmdate(DATE_W3C, $changed) .'</lastmod>' . "\n"); |
|
262 fwrite($fp, ' </sitemap>' . "\n"); |
|
263 } |
|
264 fwrite($fp, '</sitemapindex>'); |
|
265 fclose($fp); |
|
266 // Set standard file permissions for webserver-generated files. |
|
267 @chmod($parent_directory ."/xsm-$id.xml", 0664); |
|
268 for ($chunk = 0; $chunk < $link_count / $chunk_size; ++$chunk) { |
|
269 if (!$fp = fopen($parent_directory ."/xsm-$id-$chunk.xml", 'wb')) { |
|
270 watchdog('xmlsitemap', 'Could not create the cache file @file.', array('@file' => $parent_directory ."/xsm-$id-$chunk.xml"), WATCHDOG_ERROR); |
|
271 return FALSE; |
|
272 } |
|
273 _xmlsitemap_create_cache_chunk($fp, $chunk_size, $chunk); |
|
274 fclose($fp); |
|
275 // Set standard file permissions for webserver-generated files. |
|
276 @chmod($parent_directory ."/xsm-$id-$chunk.xml", 0664); |
|
277 } |
|
278 } |
|
279 else { |
|
280 if (!$fp = fopen($parent_directory ."/xsm-$id.xml", 'wb')) { |
|
281 watchdog('xmlsitemap', 'Could not create the cache file @file.', array('@file' => $parent_directory ."/xsm-$id.xml"), WATCHDOG_ERROR); |
|
282 return FALSE; |
|
283 } |
|
284 _xmlsitemap_create_cache_chunk($fp, $chunk_size); |
|
285 fclose($fp); |
|
286 // Set standard file permissions for webserver-generated files. |
|
287 @chmod($parent_directory ."/xsm-$id.xml", 0664); |
|
288 } |
|
289 return TRUE; |
|
290 } |
|
291 |
|
292 /** |
|
293 * @} End of "addtogroup xmlsitemap". |
|
294 */ |
|
295 |