Skip to content

Commit

Permalink
Merge branch '0.5' into 0.6
Browse files Browse the repository at this point in the history
  • Loading branch information
dhensby committed Feb 1, 2017
2 parents 9c2491e + a3fc0af commit fadf65c
Show file tree
Hide file tree
Showing 31 changed files with 181 additions and 639 deletions.
18 changes: 10 additions & 8 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
# See https://github.com/silverstripe-labs/silverstripe-travis-support for setup details

language: php
php:
- 5.3
language: php

env:
- DB=MYSQL CORE_RELEASE=3.0
- DB=PGSQL CORE_RELEASE=3.0
sudo: false

matrix:
include:
- php: 5.3
env: DB=MYSQL CORE_RELEASE=3.0
- php: 5.4
env: DB=PGSQL CORE_RELEASE=3.0
- php: 5.5
env: DB=SQLITE CORE_RELEASE=3.0
- php: 5.6
env: DB=MYSQL CORE_RELEASE=3.0

before_script:
- git clone git://github.com/silverstripe-labs/silverstripe-travis-support.git ~/travis-support
- php ~/travis-support/travis_setup.php --source `pwd` --target ~/builds/ss --require silverstripe/cms
- cd ~/builds/ss

script:
- phpunit mobile/tests/
script:
- vendor/bin/phpunit mobile/tests/
36 changes: 26 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,18 @@ The mobile module provides detection for mobile devices,
and can serve a different SilverStripe theme to them.
The module can either use redirection to a separate mobile
domain, or serve mobile optimised content under the same URLs.
It includes a default "blackcandymobile" theme to demonstrate the effects.

Note: The W3C recommends a ["One web" approach](http://www.w3.org/TR/mobile-bp/#d0e347)
The codebase relies on server-side device detection based on user agent strings,
which is an [unreliable](http://www.brettjankord.com/2013/01/10/active-development-on-categorizr-has-come-to-an-end/) way to determine if a device is considered to be "mobile".

The W3C recommends a ["One web" approach](http://www.w3.org/TR/mobile-bp/#d0e347)
that uses ["Responsive Design"](http://www.alistapart.com/articles/responsive-web-design/)
to adapt content, rather than create isolated mobile experiences under their own domain.
Most of the work on mobile optimization will be in client-side techniques
like JavaScript and CSS (e.g. through media queries).
like JavaScript and CSS (e.g. through media queries).

Responsive design is not covered by this module, and can be achieved with standard
SilverStripe functionality.

The module also exposes this state in SilverStripe controllers
so custom logic and CSS/JavaScript includes can be adapted to mobile usage.
Expand All @@ -41,13 +46,22 @@ A new theme called "blackcandymobile" will be created in your themes folder afte
invoking the database (dev) build. This theme is a good starting point which you can modify
to create your own mobile theme.

If the themes folder can't be written to by the web server during dev/build, please
manually copy "blackcandymobile" into your themes folder from the mobile folder.
## Themes

We provide two themes as a starting point which you can modify to create your own mobile theme:

* ["blackcandymobile"](https://github.com/silverstripe-themes/silverstripe-blackcandymobile):
Modelled to work with the "blackcandy" theme which comes with the SilverStripe 2.x default installation.
* ["jquerymobile"](https://github.com/silverstripe-themes/silverstripe-jquerymobile):
Creates a basic navigation interface through [jQuery Mobile](http://jquerymobile.com)

Alternatively, the module contains a "jquerymobile" sample theme
which creates a basic navigation interface through [jQuery Mobile](http://jquerymobile.com).
To use this theme, copy it to `/themes` in the same way,
and set it in your `SiteConfig` as described below.
Either download the themes from github, or add them via [composer](http://getcomposer.org):

{
"require": {"silverstripe-themes/blackcandymobile": "*"}
}

Alternatively, you can start your own mobile theme of course.

## Configuration

Expand All @@ -68,6 +82,9 @@ the one that mobile users of your site will see.

Please keep in mind that the mobile domain must point to your site before it will work.

In order to force extended tablet device detection, set `MobileBrowserDetection::$tablet_is_mobile`
either to `TRUE` (forces mobile template) or `FALSE` (forces desktop template).

### Search Engine Optimization ###

The module follows [Google's recommendations](http://googlewebmastercentral.blogspot.com/2011/02/making-websites-mobile-friendly.html)
Expand All @@ -85,6 +102,5 @@ Google will detect this change by using a different user agent, and index accord

* Search form in the default theme
* Integrate with subsites module to serve different content for a mobile site
* Integrate with third-party mobile detection, e.g. WURFL or Apache Mobile Filter or browscap (see http://nz.php.net/get_browser)
* Device feature detection e.g. "Does this device support SSL?" or "Does this device support XHTML?" for progressive enhancement
* Dynamic image insertion and resizing via HTML5 data attributes
96 changes: 87 additions & 9 deletions code/MobileBrowserDetector.php
Original file line number Diff line number Diff line change
@@ -1,10 +1,23 @@
<?php
/**
* Helper class for detecting known mobiles agents.
* Helper class for detecting known mobile agents.
* This is a flawed approach to begin with, since there's no reliable way
* to detect "mobile" device characteristics through the user agent string.
*
* CAUTION: Does NOT detect Windows 8 tablets, since there's no user-agent distinction between
* tablets and desktops in Windows 8.
*
* @package mobile
*/
class MobileBrowserDetector {

/**
* @var Boolean Consider tablet devices as "mobile" devices in {@link is_mobile()}.
* Set to FALSE to force non-mobile display if a tablet is detected,
* or to NULL to fall back to the standard mobile detection.
*/
public static $tablet_is_mobile = null;

/**
* List of known mobiles, found in the HTTP_USER_AGENT variable
* @see MobileBrowserDetector::is_mobile() for how they're used.
Expand Down Expand Up @@ -44,17 +57,28 @@ public static function is_win_phone() {
}

/**
* Is the current HTTP_USER_AGENT a known mobile device string?
* Rough detection of "mobile" browsers based on their user agent strings.
* Includes tablets (see {@link is_tablet()}). Sets HTTP cache headers.
*
* CAUTION: Does NOT detect Windows 8 tablets, since there's no user-agent distinction between
* tablets and desktops in Windows 8.
*
* @see http://mobiforge.com/developing/story/setting-http-headers-advise-transcoding-proxies
*
*
* @param String User agent (defaults to $_SERVER)
* @return bool
*/
public static function is_mobile() {
public static function is_mobile($agent = null) {
$isMobile = false;
$agent = $_SERVER['HTTP_USER_AGENT'];
if(!$agent) $agent = $_SERVER['HTTP_USER_AGENT'];
$accept = isset($_SERVER['HTTP_ACCEPT']) ? $_SERVER['HTTP_ACCEPT'] : '';

switch(true) {
$isTablet = self::is_tablet($agent);
if(self::$tablet_is_mobile === TRUE && $isTablet) {
$isMobile = true;
} else if(self::$tablet_is_mobile === FALSE && $isTablet) {
$isMobile = false;
} else {switch(true) {
case(self::is_iphone()):
$isMobile = true;
break;
Expand All @@ -72,8 +96,7 @@ public static function is_mobile() {
break;
case(self::is_win_phone()):
$isMobile = true;
break;
case(self::is_windows()):
break;case(self::is_windows()):
$isMobile = true;
break;
case(preg_match('/(up.browser|up.link|mmp|symbian|smartphone|midp|wap|vodafone|o2|pocket|kindle|mobile|pda|psp|treo)/i', $agent)):
Expand All @@ -87,7 +110,7 @@ public static function is_mobile() {
break;
case(in_array(strtolower(substr($agent, 0, 4)), self::mobile_index_list())):
$isMobile = true;
break;
break;}
}

if(!headers_sent()) {
Expand All @@ -97,4 +120,59 @@ public static function is_mobile() {

return $isMobile;
}

/**
* Rough detection of "tablet" user agents, based on their user agent string.
*
* CAUTION: Does NOT detect Windows 8 tablets, since there's no user-agent distinction between
* tablets and desktops in Windows 8.
*
* Loosely based off the (now discontinued) Categorizr library:
* http://www.brettjankord.com/2012/01/16/categorizr-a-modern-device-detection-script/
*
* @param String User agent (defaults to $_SERVER)
* @return boolean
*/
public static function is_tablet($agent = null) {
if(!$agent) $agent = $_SERVER['HTTP_USER_AGENT'];

// Check if user agent is a Tablet
if(
(preg_match('/iP(a|ro)d/i', $agent))
|| (preg_match('/tablet/i', $agent)) && (!preg_match('/RX-34/i', $agent)) || (preg_match('/FOLIO/i', $agent))
) {
return true;
}
// Check if user agent is an Android Tablet
else if (
(preg_match('/Linux/i', $agent))
&& (preg_match('/Android/i', $agent))
&& (!preg_match('/Fennec|mobi|HTC.Magic|HTCX06HT|Nexus.One|SC-02B|fone.945/i', $agent))
&& (!preg_match('/Mobile/i', $agent))
) {
// see http://googlewebmastercentral.blogspot.de/2011/03/mo-better-to-also-detect-mobile-user.html
// see http://googlewebmastercentral.blogspot.de/2012/11/giving-tablet-users-full-sized-web.html
return true;
}
// Check if user agent is a Kindle or Kindle Fire
else if (
(preg_match('/Kindle/i', $agent))
|| (preg_match('/Mac.OS/i', $agent))
&& (preg_match('/Silk/i', $agent))
) {
return true;
}
// Check if user agent is a pre Android 3.0 Tablet
else if (
(preg_match('/GT-P10|SC-01C|SHW-M180S|SGH-T849|SCH-I800|SHW-M180L|SPH-P100|SGH-I987|zt180|HTC(.Flyer|\_Flyer)|Sprint.ATP51|ViewPad7|pandigital(sprnova|nova)|Ideos.S7|Dell.Streak.7|Advent.Vega|A101IT|A70BHT|MID7015|Next2|nook/i', $agent))
|| (preg_match('/MB511/i', $agent))
&& (preg_match('/RUTEM/i', $agent))
) {
return true;
}
// Browser is either a mobile handset or desktop.
else {
return false;
}
}
}
22 changes: 1 addition & 21 deletions code/MobileSiteConfigExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,6 @@
*/
class MobileSiteConfigExtension extends DataExtension {

/**
* The path the default mobile theme should be copied
* to when {@link SiteConfig} is first created in the database.
*
* @see MobileSiteConfigExtension::requireDefaultRecords()
* @var string
*/
protected static $theme_copy_path;

public static function set_theme_copy_path($path) {
self::$theme_copy_path = $path;
}

public static function get_theme_copy_path() {
if(!self::$theme_copy_path) {
return '../' . THEMES_DIR . '/blackcandymobile';
} else {
return self::$theme_copy_path;
}
}

/**
* Extra statics variable to merge into {@link SiteConfig}
*/
Expand Down Expand Up @@ -57,6 +36,7 @@ static function add_to_class($class, $extensionClass, $args = null) {
}



/**
* @return String The first available domain, with the current protocol prefixed,
* suitable for redirections etc.
Expand Down
2 changes: 1 addition & 1 deletion code/MobileSiteControllerExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public function onAfterInit() {
else {
$fullSiteCookie = Cookie::get('fullSite');
}

if(is_numeric($fullSiteCookie)) {
// Full site requested
if($fullSiteCookie) {
Expand Down
11 changes: 9 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@
}
],
"require": {
"silverstripe/framework": "3.*"
"silverstripe/framework": "~3.0.0"
},
"require-dev": {
"phpunit/phpunit": "^3.7"
},
"suggests": {
"silverstripe-themes/blackcandymobile": "*",
"silverstripe-themes/jquerymobile": "*"
}
}
}
45 changes: 45 additions & 0 deletions tests/MobileBrowserDetectorTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php
class MobileBrowserDetectorTest extends SapphireTest {

public function testIsTablet() {
$this->assertTrue(MobileBrowserDetector::is_tablet(
'Mozilla/5.0 (Linux; U; Android 3.0; en-us; Xoom Build/HRI39) AppleWebKit/534.13 (KHTML, like Gecko) Version/4.0 Safari/534.13',
'XOOM tablet, contains "android" but not "mobile"'
));
$this->assertFalse(MobileBrowserDetector::is_tablet(
'Mozilla/5.0 (Linux; U; Android 2.2.1; en-us; Nexus One Build/FRG83) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1',
'Nexus One, contains "mobile" and "android"'
));
// This is where this approach falls down ... can't detect MS Surface usage.
// See http://www.brettjankord.com/2013/01/10/active-development-on-categorizr-has-come-to-an-end/
$this->assertFalse(MobileBrowserDetector::is_tablet(
'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; ARM; Trident/6.0; Touch)'
));
}

public function testTabletIsMobile() {
$tabletUa = 'Mozilla/5.0 (Linux; U; Android 3.0; en-us; Xoom Build/HRI39) AppleWebKit/534.13 (KHTML, like Gecko) Version/4.0 Safari/534.13';
$mobileUa = 'Mozilla/5.0 (Linux; U; Android 2.2.1; en-us; Nexus One Build/FRG83) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1';
$desktopUa = 'Mozilla/5.0 (Windows; U; MSIE 9.0; WIndows NT 9.0; en-US))';

$orig = MobileBrowserDetector::$tablet_is_mobile;

MobileBrowserDetector::$tablet_is_mobile = true;
$this->assertTrue(MobileBrowserDetector::is_mobile($tabletUa));
$this->assertTrue(MobileBrowserDetector::is_mobile($mobileUa));
$this->assertFalse(MobileBrowserDetector::is_mobile($desktopUa));

MobileBrowserDetector::$tablet_is_mobile = false;
$this->assertFalse(MobileBrowserDetector::is_mobile($tabletUa));
$this->assertTrue(MobileBrowserDetector::is_mobile($mobileUa));
$this->assertFalse(MobileBrowserDetector::is_mobile($desktopUa));

MobileBrowserDetector::$tablet_is_mobile = null;
// Technically this is a bug, but its the standard module check
$this->assertFalse(MobileBrowserDetector::is_mobile($tabletUa));
$this->assertTrue(MobileBrowserDetector::is_mobile($mobileUa));
$this->assertFalse(MobileBrowserDetector::is_mobile($desktopUa));

MobileBrowserDetector::$tablet_is_mobile = $orig;
}
}
2 changes: 2 additions & 0 deletions tests/MobileSiteConfigExtensionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
*/
class MobileSiteConfigExtensionTest extends SapphireTest {

protected $usesDatabase = true;

public function setUp() {
parent::setUp();
MobileSiteConfigExtension::set_theme_copy_path(TEMP_FOLDER . '/mobile-test-copy-theme/');
Expand Down
5 changes: 0 additions & 5 deletions tests/MobileSiteTreeExtensionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,6 @@ class MobileSiteTreeExtensionTest extends FunctionalTest {
'SiteConfig' => array('MobileSiteConfigExtension'),
);

public function setUp() {
parent::setUp();
MobileSiteConfigExtension::set_theme_copy_path(TEMP_FOLDER . '/mobile-test-copy-theme/');
}

public function testShowsCanonicalLinkOnMobile() {
$page = $this->objFromFixture('Page', 'page');

Expand Down
Loading

0 comments on commit fadf65c

Please sign in to comment.