1 <?php
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
21 class GoogleSitemap extends Controller {
22
23 static $cache_expire = 86400;
24
25 static function local_sitemap_path() {
26 return ASSETS_PATH . '/sitemap.xml';
27 }
28
29 static function clear_cache() {
30 $file = self::local_sitemap_path();
31 if (@file_exists($file))
32 unlink($file);
33 }
34
35 36 37
38 protected static $enabled = true;
39
40 41 42
43 protected static $google_notification_enabled = false;
44
45 46 47
48 protected static $use_show_in_sitemap = true;
49
50
51 static function set_use_show_in_sitemap($val = false) {
52 self::$use_show_in_sitemap = $val;
53 }
54
55 public function Items($start=0) {
56 $count = 1000;
57 Versioned::reading_stage('Live');
58 $filter = '';
59 if(self::$use_show_in_sitemap) {
60 $filter .= '"ShowInSiteMap" = 1';
61 }
62
63 $pages = DataObject::get('SiteTree', $filter, '', '', "{$start},{$count}");
64 if (!$pages) return false;
65 $newPages = new DataObjectSet();
66 while($page = $pages->shift()) {
67
68
69
70 if (parse_url($page->AbsoluteLink(), PHP_URL_HOST) != parse_url('http://' . $_SERVER['HTTP_HOST'], PHP_URL_HOST)) continue;
71 if ($page instanceof ErrorPage) continue;
72 if ($page->Priority < 0) continue;
73 if (!$page->canView()) continue;
74
75
76
77 $created = new SS_Datetime();
78 $created->value = $page->Created;
79
80 $now = new SS_Datetime();
81 $now->value = date('Y-m-d H:i:s');
82
83 $versions = $page->Version;
84 $timediff = $now->format('U') - $created->format('U');
85
86
87
88
89 $period = $timediff / ($versions + 1);
90
91 if($period > 60*60*24*365) {
92 $page->ChangeFreq='yearly';
93 } elseif($period > 60*60*24*30) {
94 $page->ChangeFreq='monthly';
95 } elseif($period > 60*60*24*7) {
96 $page->ChangeFreq='weekly';
97 } elseif($period > 60*60*24) {
98 $page->ChangeFreq='daily';
99 } elseif($period > 60*60) {
100 $page->ChangeFreq='hourly';
101 } else {
102 $page->ChangeFreq='always';
103 }
104
105 $newPages->push($page);
106 }
107 return $newPages;
108 }
109
110 111 112 113 114 115 116 117 118 119 120
121 static function ping() {
122 if(!self::$enabled) return false;
123
124
125 if(!GoogleSitemap::$google_notification_enabled || Director::isDev())
126 return;
127
128 $location = urlencode(Director::absoluteBaseURL() . '/sitemap.xml');
129
130 $response = HTTP::sendRequest("www.google.com", "/webmasters/sitemaps/ping",
131 "sitemap=" . $location);
132
133 return $response;
134 }
135
136 137 138
139 public static function enable_google_notification() {
140 self::$google_notification_enabled = true;
141 }
142
143 144 145
146 public static function disable_google_notification() {
147 self::$google_notification_enabled = false;
148 }
149
150 function index($request) {
151 if(self::$enabled) {
152 $cache_path = self::local_sitemap_path();
153 if ($request->requestVar('force')) {
154 self::clear_cache();
155 }
156
157 if (!Director::is_cli()) {
158 if (@file_exists($cache_path) && (@filemtime($cache_path) + self::$cache_expire > time())) {
159 Controller::curr()->getResponse()->addHeader("Content-Type", "text/xml");
160 readfile($cache_path);
161 return;
162 }
163 }
164
165 increase_time_limit_to(1000);
166 increase_memory_limit_to('1000M');
167 $markStart = time();
168 $html = '<?xml version="1.0" encoding="UTF-8"?><urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">';
169 file_put_contents($cache_path, $html);
170
171 $start = 0;
172 $totCount = 0;
173 $f = true;
174 while ($f) {
175 $pages = $this->Items($start);
176 if (!$pages) {
177 $f = false;
178 } else {
179 $html = '';
180 $pCount = $pages->Count();
181 foreach($pages as $page) {
182 $html .= $page->renderWith('SitemapURL');
183 $page->destroy();
184 $totCount++;
185 }
186 file_put_contents($cache_path, $html, FILE_APPEND);
187 $start += $pCount;
188 unset($pages);
189 }
190 }
191 file_put_contents($cache_path, '</urlset>', FILE_APPEND);
192
193 if (Director::is_cli()) {
194 $markEnd = time();
195 echo
196 'start: ' . date('Y-m-d H:i:s', $markStart) . "\n"
197 . ' end: ' . date('Y-m-d H:i:s', $markEnd) . "\n"
198 . 'duration: ' . ($markEnd - $markStart) . "\n"
199 . Director::absoluteURL(Director::makeRelative($cache_path)) ."\n"
200 ;
201 }
202 else {
203 Controller::curr()->getResponse()->addHeader("Content-Type", "text/xml");
204 readfile($cache_path);
205 }
206
207
208
209 } else {
210 return new SS_HTTPResponse('Not allowed', 405);
211 }
212 }
213
214 public static function enable() {
215 self::$enabled = true;
216 }
217
218 public static function disable() {
219 self::$enabled = false;
220 }
221 }
222
223
[Raise a SilverStripe Framework issue/bug](https://github.com/silverstripe/silverstripe-framework/issues/new)
- [Raise a SilverStripe CMS issue/bug](https://github.com/silverstripe/silverstripe-cms/issues/new)
- Please use the
Silverstripe Forums to ask development related questions.
-