Add Google Analytics for Mobile
Add Google Analytics for Mobile

--- a/common-template.inc.php
+++ b/common-template.inc.php
@@ -1,11 +1,37 @@
 <?php
+  // Copyright 2009 Google Inc. All Rights Reserved.
+  $GA_ACCOUNT = "MO-22173039-1";
+  $GA_PIXEL = "/ga.php";
+
+  function googleAnalyticsGetImageUrl() {
+    global $GA_ACCOUNT, $GA_PIXEL;
+    $url = "";
+    $url .= $GA_PIXEL . "?";
+    $url .= "utmac=" . $GA_ACCOUNT;
+    $url .= "&utmn=" . rand(0, 0x7fffffff);
+    $referer = $_SERVER["HTTP_REFERER"];
+    $query = $_SERVER["QUERY_STRING"];
+    $path = $_SERVER["REQUEST_URI"];
+    if (empty($referer)) {
+      $referer = "-";
+    }
+    $url .= "&utmr=" . urlencode($referer);
+    if (!empty($path)) {
+      $url .= "&utmp=" . urlencode($path);
+    }
+    $url .= "&guid=ON";
+    return str_replace("&", "&amp;", $url);
+  }
+
 function include_header($pageTitle, $pageType, $opendiv = true, $geolocate = false, $datepicker = false)
 {
 	echo '
 <!DOCTYPE html> 
-<html> 
-	<head> 
+<html lang="en">
+	<head>
+        <meta charset="UTF-8">
 	<title>' . $pageTitle . '</title>';
+        <meta name="google-site-verification" content="-53T5Qn4TB_de1NyfR_ZZkEVdUNcNFSaYKSFkWKx-sY" />
 	if ($datepicker) echo '<link rel="stylesheet"  href="css/jquery.ui.datepicker.mobile.css" />';
 	if (isDebugServer()) echo '<link rel="stylesheet"  href="css/jquery-mobile-1.0a3.css" />
          <script type="text/javascript" src="js/jquery-1.5.js"></script>
@@ -44,6 +70,27 @@
     body {
         background-color: #F0F0F0;
     }
+    #jqm-homeheader {
+        text-align: center;
+    }        
+    
+    // source http://webaim.org/techniques/skipnav/
+    #skip a, #skip a:hover, #skip a:visited 
+{ 
+position:absolute; 
+left:0px; 
+top:-500px; 
+width:1px; 
+height:1px; 
+overflow:hidden;
+} 
+
+#skip a:active, #skip a:focus 
+{ 
+position:static; 
+width:auto; 
+height:auto; 
+}
 </style>';
 	if (strstr($_SERVER['HTTP_USER_AGENT'], 'iPhone') || strstr($_SERVER['HTTP_USER_AGENT'], 'iPod')) {
 		echo '<meta name="apple-mobile-web-app-capable" content="yes" />
@@ -77,6 +124,9 @@
 	}
 	echo '</head>
 <body>
+    <div id="skip">
+    <a href="#maincontent">Skip to content</a>
+    </div>
  ';
 	if ($opendiv) {
 		echo '<div data-role="page"> 
@@ -89,6 +139,7 @@
 	<div data-role="header"> 
 		<h1>' . $pageTitle . '</h1>
 	</div><!-- /header -->
+        <a name="maincontent" id="maincontent"></a>
         <div data-role="content"> ';
 	}
 }
@@ -102,6 +153,10 @@
 	}
 	echo '<div id="footer"><a href="about.php">About/Contact Us</a>&nbsp;<a href="feedback.php">Feedback/Bug Report</a></a>';
 	echo '</div>';
+        if (!isDebug()) {
+         $googleAnalyticsImageUrl = googleAnalyticsGetImageUrl();
+  echo '<img src="' . $googleAnalyticsImageUrl . '" />';
+    }
 }
 function timePlaceSettings($geolocate = false)
 {
@@ -117,21 +172,21 @@
 	}
 	echo '<div data-role="collapsible" data-collapsed="' . !$geoerror . '">
         <h3>Change Time/Place (' . (isset($_SESSION['time']) ? $_SESSION['time'] : "Current Time,") . ' ' . ucwords(service_period()) . ')...</h3>
-        <form action="" method="post">
+        <form action="'.basename($_SERVER['PHP_SELF']).'" method="post">
         <div class="ui-body"> 
 		<div data-role="fieldcontain">
 	            <label for="geolocate"> Current Location: </label>
-			<input type="text" id="geolocate" name="geolocate" value="' . (isset($_SESSION['lat']) && isset($_SESSION['lon']) ? $_SESSION['lat'] . "," . $_SESSION['lon'] : "Enter co-ordinates or address here") . '"/> <a href="#" style="display:none" name="here" id="here"/>Here?</a>
+			<input type="text" id="geolocate" name="geolocate" value="' . (isset($_SESSION['lat']) && isset($_SESSION['lon']) ? $_SESSION['lat'] . "," . $_SESSION['lon'] : "Enter co-ordinates or address here") . '"/> <a href="#" style="display:none" name="here" id="here">Here?</a>
 	        </div>
     		<div data-role="fieldcontain">
 		        <label for="time"> Time: </label>
-		    	<input type="time" name="time" id="time" value="' . (isset($_SESSION['time']) ? $_SESSION['time'] : date("H:i")) . '"/> <a href="#" name="currentTime" id="currentTime"/>Current Time?</a>
+		    	<input type="time" name="time" id="time" value="' . (isset($_SESSION['time']) ? $_SESSION['time'] : date("H:i")) . '"/> <a href="#" name="currentTime" id="currentTime">Current Time?</a>
 	        </div>
 		<div data-role="fieldcontain">
 		    <label for="service_period"> Service Period:  </label>
-			<select name="service_period">';
+			<select name="service_period" id="service_period">';
 	foreach ($service_periods as $service_period) {
-		echo "<option value=\"$service_period\"" . (service_period() === $service_period ? "SELECTED" : "") . '>' . ucwords($service_period) . '</option>';
+		echo "<option value=\"$service_period\"" . (service_period() === $service_period ? " SELECTED" : "") . '>' . ucwords($service_period) . '</option>';
 	}
 	echo '</select>
 			<a href="#" style="display:none" name="currentPeriod" id="currentPeriod"/>Current Period?</a>

file:b/ga.php (new)
--- /dev/null
+++ b/ga.php
@@ -1,1 +1,187 @@
+<?php
 
+/**
+  Copyright 2009 Google Inc. All Rights Reserved.
+**/
+
+  // Tracker version.
+  define("VERSION", "4.4sh");
+
+  define("COOKIE_NAME", "__utmmobile");
+
+  // The path the cookie will be available to, edit this to use a different
+  // cookie path.
+  define("COOKIE_PATH", "/");
+
+  // Two years in seconds.
+  define("COOKIE_USER_PERSISTENCE", 63072000);
+
+  // 1x1 transparent GIF
+  $GIF_DATA = array(
+      chr(0x47), chr(0x49), chr(0x46), chr(0x38), chr(0x39), chr(0x61),
+      chr(0x01), chr(0x00), chr(0x01), chr(0x00), chr(0x80), chr(0xff),
+      chr(0x00), chr(0xff), chr(0xff), chr(0xff), chr(0x00), chr(0x00),
+      chr(0x00), chr(0x2c), chr(0x00), chr(0x00), chr(0x00), chr(0x00),
+      chr(0x01), chr(0x00), chr(0x01), chr(0x00), chr(0x00), chr(0x02),
+      chr(0x02), chr(0x44), chr(0x01), chr(0x00), chr(0x3b)
+  );
+
+  // The last octect of the IP address is removed to anonymize the user.
+  function getIP($remoteAddress) {
+    if (empty($remoteAddress)) {
+      return "";
+    }
+
+    // Capture the first three octects of the IP address and replace the forth
+    // with 0, e.g. 124.455.3.123 becomes 124.455.3.0
+    $regex = "/^([^.]+\.[^.]+\.[^.]+\.).*/";
+    if (preg_match($regex, $remoteAddress, $matches)) {
+      return $matches[1] . "0";
+    } else {
+      return "";
+    }
+  }
+
+  // Generate a visitor id for this hit.
+  // If there is a visitor id in the cookie, use that, otherwise
+  // use the guid if we have one, otherwise use a random number.
+  function getVisitorId($guid, $account, $userAgent, $cookie) {
+
+    // If there is a value in the cookie, don't change it.
+    if (!empty($cookie)) {
+      return $cookie;
+    }
+
+    $message = "";
+    if (!empty($guid)) {
+      // Create the visitor id using the guid.
+      $message = $guid . $account;
+    } else {
+      // otherwise this is a new user, create a new random id.
+      $message = $userAgent . uniqid(getRandomNumber(), true);
+    }
+
+    $md5String = md5($message);
+
+    return "0x" . substr($md5String, 0, 16);
+  }
+
+  // Get a random number string.
+  function getRandomNumber() {
+    return rand(0, 0x7fffffff);
+  }
+
+  // Writes the bytes of a 1x1 transparent gif into the response.
+  function writeGifData() {
+    global $GIF_DATA;
+    header("Content-Type: image/gif");
+    header("Cache-Control: " .
+           "private, no-cache, no-cache=Set-Cookie, proxy-revalidate");
+    header("Pragma: no-cache");
+    header("Expires: Wed, 17 Sep 1975 21:32:10 GMT");
+    echo join($GIF_DATA);
+  }
+
+  // Make a tracking request to Google Analytics from this server.
+  // Copies the headers from the original request to the new one.
+  // If request containg utmdebug parameter, exceptions encountered
+  // communicating with Google Analytics are thown.
+  function sendRequestToGoogleAnalytics($utmUrl) {
+    $options = array(
+      "http" => array(
+          "method" => "GET",
+          "user_agent" => $_SERVER["HTTP_USER_AGENT"],
+          "header" => ("Accepts-Language: " . $_SERVER["HTTP_ACCEPT_LANGUAGE"]))
+    );
+    if (!empty($_GET["utmdebug"])) {
+      $data = file_get_contents(
+          $utmUrl, false, stream_context_create($options));
+    } else {
+      $data = @file_get_contents(
+          $utmUrl, false, stream_context_create($options));
+    }
+  }
+
+  // Track a page view, updates all the cookies and campaign tracker,
+  // makes a server side request to Google Analytics and writes the transparent
+  // gif byte data to the response.
+  function trackPageView() {
+    $timeStamp = time();
+    $domainName = $_SERVER["SERVER_NAME"];
+    if (empty($domainName)) {
+      $domainName = "";
+    }
+
+    // Get the referrer from the utmr parameter, this is the referrer to the
+    // page that contains the tracking pixel, not the referrer for tracking
+    // pixel.
+    $documentReferer = $_GET["utmr"];
+    if (empty($documentReferer) && $documentReferer !== "0") {
+      $documentReferer = "-";
+    } else {
+      $documentReferer = urldecode($documentReferer);
+    }
+    $documentPath = $_GET["utmp"];
+    if (empty($documentPath)) {
+      $documentPath = "";
+    } else {
+      $documentPath = urldecode($documentPath);
+    }
+
+    $account = $_GET["utmac"];
+    $userAgent = $_SERVER["HTTP_USER_AGENT"];
+    if (empty($userAgent)) {
+      $userAgent = "";
+    }
+
+    // Try and get visitor cookie from the request.
+    $cookie = $_COOKIE[COOKIE_NAME];
+
+    $guidHeader = $_SERVER["HTTP_X_DCMGUID"];
+    if (empty($guidHeader)) {
+      $guidHeader = $_SERVER["HTTP_X_UP_SUBNO"];
+    }
+    if (empty($guidHeader)) {
+      $guidHeader = $_SERVER["HTTP_X_JPHONE_UID"];
+    }
+    if (empty($guidHeader)) {
+      $guidHeader = $_SERVER["HTTP_X_EM_UID"];
+    }
+
+    $visitorId = getVisitorId($guidHeader, $account, $userAgent, $cookie);
+
+    // Always try and add the cookie to the response.
+    setrawcookie(
+        COOKIE_NAME,
+        $visitorId,
+        $timeStamp + COOKIE_USER_PERSISTENCE,
+        COOKIE_PATH);
+
+    $utmGifLocation = "http://www.google-analytics.com/__utm.gif";
+
+    // Construct the gif hit url.
+    $utmUrl = $utmGifLocation . "?" .
+        "utmwv=" . VERSION .
+        "&utmn=" . getRandomNumber() .
+        "&utmhn=" . urlencode($domainName) .
+        "&utmr=" . urlencode($documentReferer) .
+        "&utmp=" . urlencode($documentPath) .
+        "&utmac=" . $account .
+        "&utmcc=__utma%3D999.999.999.999.999.1%3B" .
+        "&utmvid=" . $visitorId .
+        "&utmip=" . getIP($_SERVER["REMOTE_ADDR"]);
+
+    sendRequestToGoogleAnalytics($utmUrl);
+
+    // If the debug parameter is on, add a header to the response that contains
+    // the url that was used to contact Google Analytics.
+    if (!empty($_GET["utmdebug"])) {
+      header("X-GA-MOBILE-URL:" . $utmUrl);
+    }
+    // Finally write the gif data to the response.
+    writeGifData();
+  }
+?><?php
+  trackPageView();
+?>
+

file:a/index.php -> file:b/index.php
--- a/index.php
+++ b/index.php
@@ -5,9 +5,10 @@
 <div data-role="page">
 	<div data-role="content">
 			<div id="jqm-homeheader">
-	    	<center><h3>busness time</h3><br><small>Canberra Bus Timetables and Trip Planner</small></center>
+	    	<h1>busness time</h1><br><small>Canberra Bus Timetables and Trip Planner</small>
 	</div> 
-	    <a href="tripPlanner.php" data-role="button" data-icon="navigation">Launch Trip Planner...</a>
+	<a name="maincontent" id="maincontent"></a>
+	   <a href="tripPlanner.php" data-role="button" data-icon="navigation">Launch Trip Planner...</a>
             <ul data-role="listview" data-inset="true" data-theme="c" data-dividertheme="b">
                 <li data-role="list-divider">Timetables - Stops</li>
                 <li><a href="stopList.php">Major (Timing Point) Stops</a></li>
@@ -19,7 +20,7 @@
                 <li data-role="list-divider">Timetables - Routes</li>
                 <li><a href="routeList.php">Routes By Final Destination</a></li>
 		<li><a href="routeList.php?bynumber=yes">Routes By Number</a></li>
-		<li><a href="routeList.php?bysuburb=yes">Stops By Suburb</a></li>
+		<li><a href="routeList.php?bysuburb=yes">Routes By Suburb</a></li>
 		<li><a class="nearby" href="routeList.php?nearby=yes">Nearby Routes</a></li>
             </ul>
 <?php

file:a/stop.php -> file:b/stop.php
--- a/stop.php
+++ b/stop.php
@@ -48,7 +48,7 @@
 }
 include_header($stop[1], "stop");
 timePlaceSettings();
-echo '<div data-role="content" class="ui-content" role="main">';
+echo '<div data-role="content" class="ui-content" role="main">        <a name="maincontent" id="maincontent"></a>';
 echo $stopLinks;
 if (sizeof($stops) > 0) {
 	echo '<p>' . staticmap($stopPositions) . '</p>';

file:a/trip.php -> file:b/trip.php
--- a/trip.php
+++ b/trip.php
@@ -34,12 +34,12 @@
 		$viaPoints[] = $stop[1];
 	}
 }
-echo 'Via: ' . implode(", ", $viaPoints) . '</small>';
-echo '<p> Other Trips: ';
+echo '<p><h2>Via:</h2> ' . implode(", ", $viaPoints) . '</small></p>';
+echo '<p><h2>Other Trips:</h2> ';
 foreach ($routetrips as $othertrip) {
 	echo '<a href="trip.php?tripid=' . $othertrip[1] . "&routeid=" . $routeid . '">' . midnight_seconds_to_time($othertrip[0]) . '</a> ';
 }
-echo '</p> Other directions/timing periods: ';
+echo '</p><p><h2>Other directions/timing periods:</h2> ';
 $url = $APIurl . "/json/routesearch?routeshortname=" . $trips[1]->route_short_name;
 $json = json_decode(getPage($url));
 foreach ($json as $row) {