1 <?php
2
3 class MobileExtension extends Extension {
4
5 6 7 8 9 10 11 12
13 private static $auto_redirect = 'js';
14
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
30 private static $mobile_domains = array();
31
32 33 34 35
36 private static $mobile_width = 800;
37
38 39 40 41
42 private static $mobile_theme = 'mobile';
43
44 45 46 47
48 private static $cookie_name = 'mobignore';
49
50 51 52 53
54 private static $cookie_ttl = 0;
55
56 57 58 59 60
61 static function set_auto_redirect($value) {
62 if (in_array($value, array('http', 'js', 'auto', '', 'off')))
63 self::$auto_redirect = $value;
64 }
65
66 67 68 69 70
71 static function setup_domains($value) {
72 self::$mobile_domains = $value;
73 }
74
75 76 77 78 79
80 static function set_mobile_width($value = 800) {
81 self::$mobile_width = intval($value);
82 }
83
84 85 86 87 88
89 static function set_mobile_theme($value = 'mobile') {
90 self::$mobile_theme = $value;
91 }
92
93 static function get_mobile_theme() {
94 return self::$mobile_theme;
95 }
96
97 98 99 100 101
102 static function set_cookie_name($value = 'mobignore') {
103 self::$cookie_name = $value;
104 }
105
106 107 108 109 110
111 static function set_cookie_ttl($value = 0) {
112 self::$cookie_ttl = intval($value);
113 }
114
115 116 117 118 119
120 static function is_mobile_browser() {
121 if (!isset($_SERVER['HTTP_USER_AGENT']) || !$_SERVER['HTTP_USER_AGENT'])
122 return false;
123
124 return preg_match('/android|iphone|ipad|windows phone|silk|jdq39|rim tablet|bb10|symbian|mobile/i', $_SERVER['HTTP_USER_AGENT']);
125 }
126
127 128 129 130 131
132 static function is_mobile_domain() {
133 $domain = self::current_domain();
134
135 if (count(self::$mobile_domains) > 0) {
136 if (isset(self::$mobile_domains[$domain]))
137 return true;
138 }
139 else {
140 if (substr($domain, 0, 2) == 'm.') {
141 return true;
142 }
143 }
144 return false;
145 }
146
147 148 149 150 151
152 static function canonical_domain() {
153 if (!self::is_mobile_domain())
154 return '';
155
156 $domain = self::current_domain();
157 if (count(self::$mobile_domains) > 0) {
158 if (isset(self::$mobile_domains[$domain])) {
159 return self::$mobile_domains[$domain][0];
160 }
161 self::$mobile_domains[0][0];
162 } else if (substr($domain, 0, 2) == 'm.') {
163 $domain = substr($domain, 2);
164 }
165 return $domain;
166 }
167
168 169 170 171 172
173 static function mobile_domain() {
174 if (self::is_mobile_domain())
175 return '';
176
177 $domain = self::current_domain();
178 if (count(self::$mobile_domains) > 0) {
179 foreach(self::$mobile_domains as $mobile_domain => $base_domains) {
180 if (array_search($domain, $base_domains) !== false)
181 return $mobile_domain;
182 }
183 }
184 return 'm.' . $domain;
185 }
186
187 188 189 190 191
192 static function current_domain() {
193 $domain = Director::protocolAndHost();
194 $parts = explode('//', $domain);
195 if (!isset($parts[1]))
196 return false;
197 $domain = $parts[1];
198 if (substr($domain, 0, 4) == 'www.') {
199 $domain = substr($domain, 4);
200 }
201 return $domain;
202 }
203
204 205 206 207 208
209 static function cookie_domain() {
210 $domain = self::current_domain();
211 if (substr($domain, 0, 2) == 'm.')
212 $domain = substr($domain, 2);
213 return '.' . $domain;
214 }
215
216 217 218 219 220
221 static function protocol() {
222 if(isset($_SERVER['HTTP_X_FORWARDED_PROTOCOL']) && strtolower($_SERVER['HTTP_X_FORWARDED_PROTOCOL']) == 'https') return "https://";
223 return (isset($_SERVER['SSL']) || (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off')) ? 'https://' : 'http://';
224 }
225
226 227 228 229 230 231 232 233
234 function MetaTags($includeTitle = true) {
235 $tags = $this->owner->data()->MetaTags($includeTitle);
236 $width = self::$mobile_width;
237 $canonicalUrl = self::protocol() . self::canonical_domain() . $_SERVER['REQUEST_URI'];
238 $mobileUrl = self::protocol() . self::mobile_domain() . $_SERVER['REQUEST_URI'];
239
240 if (self::is_mobile_browser()) {
241 if (self::is_mobile_domain()) {
242 $tags .= "<link rel=\"canonical\" href=\"{$canonicalUrl}\">\n";
243 if ((self::$auto_redirect == 'js' || self::$auto_redirect == 'auto') && !$this->isForceMain()) {
244 $tags .= "
245 <script language=\"JavaScript\">
246 function _getwidth() {
247 var m = 9000, a = [screen.width, window.outerWidth, window.innerWidth, document.documentElement.clientWidth];
248 a.forEach(function(w) {
249 if (w > 0 && w < m) m = w;
250 });
251 return m;
252 }
253 var w = _getwidth();
254 if (w && (w > {$width})) {
255 location.href = '$canonicalUrl';
256 }
257 </script>
258 ";
259 }
260 }
261 else {
262 $tags .= "<link rel=\"alternate\" media=\"only screen and (max-width: {$width}px)\" href=\"{$mobileUrl}\">\n";
263 if ((self::$auto_redirect == 'js' || self::$auto_redirect == 'auto') && !$this->isForceMain()) {
264 $tags .= "
265 <script language=\"JavaScript\">
266 function _getwidth() {
267 var m = 9000, a = [screen.width, window.outerWidth, window.innerWidth, document.documentElement.clientWidth];
268 a.forEach(function(w) {
269 if (w > 0 && w < m) m = w;
270 });
271 return m;
272 }
273 var w = _getwidth();
274 if (w && (w <= {$width})) {
275 location.href = '$mobileUrl';
276 }
277 </script>
278 ";
279 }
280 }
281 }
282 else {
283 if (self::is_mobile_domain()) {
284 $tags .= "<link rel=\"canonical\" href=\"{$canonicalUrl}\">\n";
285 if ((self::$auto_redirect == 'js' || self::$auto_redirect == 'auto') && !$this->isforceMobile()) {
286 $tags .= "
287 <script language=\"JavaScript\">
288 location.href = '$canonicalUrl';
289 </script>
290 ";
291 }
292 }
293 }
294 return $tags;
295 }
296
297 298 299 300 301 302
303 function onAfterInit() {
304 if (isset($_GET['_fv'])) {
305 $fv = $_GET['_fv'];
306 if ($fv == 'main') {
307 Cookie::set(self::$cookie_name, '1', self::$cookie_ttl, null, self::cookie_domain());
308 if (!Director::redirected_to())
309 Director::redirect(Director::absoluteUrl('/' . HTTP::setGetVar('_fv', null), true));
310 return;
311 }
312 if ($fv == 'mobile') {
313
314 Cookie::set(self::$cookie_name, '', self::$cookie_ttl, null, self::cookie_domain());
315 if (!Director::redirected_to())
316 Director::redirect(self::protocol() . self::mobile_domain() . Director::baseUrl() . Director::makeRelative('/' . HTTP::setGetVar('_fv', null)));
317 return;
318 }
319 }
320 elseif ((self::$auto_redirect == 'http') && !Director::redirected_to()) {
321 if (self::is_mobile_browser() && !self::is_mobile_domain() && !$this->isForceMain()) {
322 Director::redirect(self::protocol() . self::mobile_domain() . $_SERVER['REQUEST_URI']);
323 return;
324 }
325 elseif (!self::is_mobile_browser() && self::is_mobile_domain() && !$this->isForceMobile()) {
326 Director::redirect(self::protocol() . self::canonical_domain() . $_SERVER['REQUEST_URI']);
327 return;
328 }
329 }
330
331 $this->owner->isMobileDomain = self::is_mobile_domain();
332 $this->owner->MobileWidth = self::$mobile_width;
333
334 if (self::is_mobile_domain()) {
335 $this->owner->CanonicalUrl = self::protocol() . self::canonical_domain() . $_SERVER['REQUEST_URI'];
336 $this->owner->SwitchToCanonicalUrl = self::protocol() . self::canonical_domain() . Director::baseUrl() . Director::makeRelative('/' . HTTP::setGetVar('_fv', 'main'));
337 }
338 else {
339 $this->owner->MobileUrl = self::protocol() . self::mobile_domain() . $_SERVER['REQUEST_URI'];
340
341 $this->owner->SwitchToMobilelUrl = self::protocol() . self::current_domain() . Director::baseUrl() . Director::makeRelative('/' . HTTP::setGetVar('_fv', 'mobile', '/'));
342 }
343 }
344
345
346 function isForceMain() {
347 if (Cookie::get(self::$cookie_name))
348 return true;
349 return false;
350 }
351
352 function isForceMobile() {
353 return false;
354 }
355 }
[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.
-