1. #1
    Sencha User
    Join Date
    Apr 2012
    Posts
    11
    Vote Rating
    0
    Dyyryath is on a distinguished road

      0  

    Default Device Detection with PHP / Sencha Touch 2

    Device Detection with PHP / Sencha Touch 2


    We have two mobile sites, one plain HTML for old devices and one built using Sencha Touch 2 for newer devices. When it came time to deploy them, I started looking for ways to make sure users ended up at the correct site based on their device's capabilities.

    I did some searching, but didn't find anything that was quite the right fit for my purposes. With that in mind, here's what I've finally come up with. It's working with a pretty simple set of rules right now, but we'll probably expand on them some now that we're sure that it is working correctly. Maybe this will give someone else who might be looking for a similar solution a headstart.

    The first step was reliably detecting the user's device. There are quite a few options out there, but I settled on http://wurfl.sourceforge.net/. Specifically, their PHP API. I took a hard look at http://www.apachemobilefilter.org/, which can use WURFL data to handle device detection using Perl and an Apache module, but in testing it had problems accurately detecting devices, despite using the same data set as the WURFL PHP API. In the end, the PHP API seemed like the most reliable solution.

    I wasn't sure how Sencha would play with PHP, but it actually works just fine.

    Obviously, you'll need to have PHP installed and working on your webserver. I'm using Apache on CentOS, so that's pretty painless. I installed the WURFL data and PHP API into my application directory following their instructions and tested it by writing a quick 'detect.php' file:

    Code:
    <?php  include_once './wurfl_config.php';
    
    
      $requestingDevice = $wurflManager->getDeviceForHttpRequest($_SERVER);
    
    
      $is_wireless = ($requestingDevice->getCapability('is_wireless_device') == 'true');
      $is_smarttv = ($requestingDevice->getCapability('is_smarttv') == 'true');
      $is_tablet = ($requestingDevice->getCapability('is_tablet') == 'true');
      $is_phone = ($requestingDevice->getCapability('can_assign_phone_number') == 'true');
      $is_mobile_device = ($is_wireless || $is_tablet);
      
      $os_name = $requestingDevice->getCapability('device_os');
      $os_version = $requestingDevice->getCapability('device_os_version');
    
    
    if (!$is_mobile_device)
    {
        if ($is_smarttv)
        {
            echo "This is a Smart TV";
        }
        else
        {
            echo "This is a Desktop Web Browser";
        }
    }
    else
    {
      echo "<p><p>Device OS: " . $requestingDevice->getCapability('device_os') . "  " . $requestingDevice->getCapability('device_os_version');
    
    
      echo "<p>Browser: " . $requestingDevice->getCapability('mobile_browser') . "  " . $requestingDevice->getCapability('mobile_browser_version');
    }
    ?>
    That actually turned out to be pretty useful since I went to a couple of local Verizon & AT&T stores and hit that page with every device they had to see what kind of response I'd get. It was so handy, in fact, I left it up: http://a.fayobserver.com/detect.php

    Once I had WURFL up and running correctly, I renamed my app's index.html page 'index.php' and added the following PHP to the top:

    Code:
    <?php
      if ($_SERVER['REMOTE_ADDR'] != '127.0.0.1')
      {
        include_once './wurfl_config.php';
        
        $requestingDevice = $wurflManager->getDeviceForHttpRequest($_SERVER);
        
        $is_wireless = ($requestingDevice->getCapability('is_wireless_device') == 'true');
        $is_smarttv = ($requestingDevice->getCapability('is_smarttv') == 'true');
        $is_tablet = ($requestingDevice->getCapability('is_tablet') == 'true');
        $is_phone = ($requestingDevice->getCapability('can_assign_phone_number') == 'true');
        $is_mobile_device = ($is_wireless || $is_tablet);
        
        $os_name = $requestingDevice->getCapability('device_os');
        $os_version = $requestingDevice->getCapability('device_os_version');
        
        # -- Build the redirect URL
        $url = $_SERVER["SCRIPT_URL"];
        if ($_GET["path"])
        {
          $url = $url . 'articles' . $_GET["path"];
        }
        
        # -- If this is Android
        if ($os_name == 'Android')
        {
          # -- New versions scroll like , send them to the basic site for now
          if ($os_version >= 4) { header('Location: http://m.fayobserver.com' . $url); exit; }
          
          # -- Old versions also go to the basic site
          if ($os_version <= 2.2) { header('Location: http://m.fayobserver.com' . $url); exit; }
        }
        # -- If this is IOS
        else if ($os_name == 'iPhone OS')
        {
          # -- Old versions go to the basic site
          if ($os_version < 4) { header('Location: http://m.fayobserver.com' . $url); exit; }
        }
        # -- If this is a Blackberry
        else if ($os_name = 'RIM OS')
        {
          # -- Old versions go to the basic site
          if ($os_version < 6)
          {
            header('Location: http://m.fayobserver.com' . $url); exit;
          }
        }
        # -- If it's not Android, iOS or Blackberry, it goes to the basic site
        else
        {
          header('Location: http://m.fayobserver.com' . $url);   
        }
        
        # -- If we came with a query parameter from the desktop site, reformat it for our app
        if ($_GET["path"])
        {
          header('Location: http://a.fayobserver.com/#articles' . $_GET["path"]);
        }
      }
    ?>
    The first conditional statement just keeps the code from executing on my dev box while I work and when I use the build tools. There are also some definitions for tablets and TVs that I'm not using yet, but I'll need them later. The rest is pretty self-explanatory.

    We're using a similar script on the basic site to redirect more advanced devices to the advanced Sencha site if they can handle it.

    I've had to do some additional rewriting in Apache to handle deep-linking and that anchor tag that Sencha uses for routes, but that wouldn't apply to most people.

    Finally, I updated the indexHtmlPath entry in app.json to point to index.php instead of index.html. In addition, the build tools incorrectly put 'index.html' in the cache.manifest file, so I have to update that manually after each build, but other than that, it works like a champ.

  2. #2
    Ext JS Premium Member
    Join Date
    Aug 2007
    Location
    Antwerp, Belgium
    Posts
    559
    Vote Rating
    29
    joeri has a spectacular aura about joeri has a spectacular aura about joeri has a spectacular aura about

      0  

    Default


    If you're looking for something more light-weight than WURFL, or WURFL's license doesn't fit with your project (we couldn't use it for ours without paying), you can use this library instead:
    http://code.google.com/p/php-mobile-detect/

  3. #3
    Sencha Premium Member dawesi's Avatar
    Join Date
    Mar 2007
    Location
    Melbourne, Australia (aka GMT+10)
    Posts
    1,083
    Vote Rating
    44
    dawesi has a spectacular aura about dawesi has a spectacular aura about

      0  

    Default


    another lightweight option is http://detectmobilebrowsers.com/
    Teahouse Training Company
    Official Certified Sencha Trainer

    Australia / New Zealand / Singapore / Hong Kong & APAC



    SenchaWorld.com - Sencha webinars, videos, etc
    SenchaForge.org - (coming soon)
    TeahouseHQ.com - Sencha ecosystem training portal

    Code Validation : JSLint | JSONLint | JSONPLint

Thread Participants: 2