<?php
/*
Basic Nike+ iPod Stats Script
Description: 
    Outputs basic stats about a run, with caching.  
    Improvements on Nike+ iPod Stats Script created by Ernie Oporto (http://www.shokk.com/blog).
Author: Eric Byers
Version: 1.2
Author URI: http://www.ericbyers.com/
*/

$username    "user@domain.com";   // Nike+ username (usually your email address).
$password    "password";          // Nike+ password.
$cache_path  "tmp/";              // Relative path to store cached file to with trailing slash.
$cache_file  "nikeplus.txt";      // Filename to write cache to.
$cache_limit 3600;                // Time to cache file in seconds.

$debug 0// Used for internal testing, leave at 0 to not display any debugging output.

#==============================================
$title "Nike+ iPod Stats";
$url_auth "https://www.nike.com/nikeplus/v1/services/app/external_profile_login.jhtml?login=$username&password=$password&locale=en_us";
$url_data "http://www.nike.com/nikeplus/v1/services/app/get_user_data.jhtml";


function 
GetElementByName ($xml$start$end) {
    
$startpos strpos($xml$start);
    if (
$startpos === false) {
        return 
false;
    }
    
$endpos strpos($xml$end);
    
$endpos $endpos+strlen($end);   
    
$endpos $endpos-$startpos;
    
$endpos $endpos strlen($end);
    
$tag substr ($xml$startpos$endpos);
    
$tag substr ($tagstrlen($start));
    return 
$tag;
 }
 
 function 
XPathValue($XPath,$XML) {
    
$XPathArray explode("/",$XPath);
    
$node $XML;
    while (list(
$key,$value) = each($XPathArray)) {
        
$node GetElementByName($node"<$value>""</$value>");
    }
   
    return 
$node;
}

function 
get_nike_data() {
    global 
$debug$cache_path$cache_file$cache_limit$url_auth$url_data;
    
    
$current_time time();
    
$cache_time   = @filemtime($cache_path $cache_file);
    
    if (
$debug 0) {
        echo 
"Cache file age: ";
        echo 
$current_time $cache_time;
        echo 
" seconds <br />";
        
    }
    
    if (((
$current_time $cache_time) > $cache_limit) || !file_exists($cache_path $cache_file)) {
        if (
function_exists('curl_init')) {
            if (
$debug 0) {
                echo 
"Attempting to retrieve file from Nike+<br />";
            }
            
$x curl_init();
            
curl_setopt($xCURLOPT_VERBOSE1);
            
curl_setopt($xCURLOPT_COOKIEJAR'cookie.txt');
            
curl_setopt($xCURLOPT_SSL_VERIFYPEERfalse);
            
curl_setopt($xCURLOPT_SSL_VERIFYPEERFALSE);
            
curl_setopt($xCURLOPT_TIMEOUT120);
            
curl_setopt($xCURLOPT_HEADER0);
            
curl_setopt($xCURLOPT_FOLLOWLOCATION0);
            
curl_setopt($xCURLOPT_HTTPHEADER, array("Accept: */*","Accept-Language: en"));
            
curl_setopt($xCURLOPT_ENCODING"gzip, deflate");
            
curl_setopt($xCURLOPT_URL$url_auth);
            
curl_setopt($xCURLOPT_RETURNTRANSFER1);
    
            
$auth curl_exec($x);
            
            
// If curl call is successfull.
            
if (ereg("success"$auth)) {
                if (
$debug 0) {
                    echo 
"Call to Nike+ successfull <br />";
                }
                
curl_setopt($xCURLOPT_URL$url_data);
                
$data curl_exec($x);
                
curl_close($x);
                 
                 
// If data is valid write it out
                 
if (ereg("success"$data)) {
                     if (
$debug 0) {
                         echo 
"Valid data retrieved from Nike+ <br />";
                     }
                     if (!
is_dir($cache_path)) {
                         if (
$debug 0) {
                             echo 
"Creating cache directory <br />";
                         }
                         
mkdir($cache_path);
                     }
                     if (
$debug 0) {
                         echo 
"Caching Nike+ file locally <br/>";
                     }
                     
$handle fopen($cache_path $cache_file"w+");
                     
fwrite($handle$data);
                     
fclose($handle);
                
                 }
            }
         } else {
            echo 
"<b><font color=\"red\">Please install curl options for PHP!</font></b><br />\n";
         }
         
     }
     
// Default to reading the cache file in case above fails.
     
if (!ereg("success"$data) && file_exists($cache_path $cache_file)) {
         if (
$debug 0) {
             echo 
"Using cache file<br />";
         }
         
$data file_get_contents($cache_path $cache_file);
     }
     
     
// If it was a success return it.
     
if (ereg("success"$data)) {
         return 
$data;
     }
     return 
false;

}
$data get_nike_data();

if (
$data === false) {
    echo 
"Could not get data!";

} else {

    
# Process all data
    
$runs XPathValue("plusService/userTotals/totalRuns",$data);
    
$totalMins XPathValue("plusService/userTotals/totalDuration",$data)/(1000 60);
    
$distance XPathValue("plusService/userTotals/totalDistance",$data);
    
$calories XPathValue("plusService/userTotals/totalCalories",$data);
    
$screenName XPathValue("plusService/userOptions/screenName",$data);
    if (
ereg("CDATA",$screenName)) {
           
$pos1 strpos($screenName"CDATA") + 6;
        
$pos2 strpos($screenName"]");
        
$screenName substr($screenName$pos1$pos2 $pos1);
    }

    if (
XPathValue("plusService/userOptions/distanceUnit",$data) == "mi") {
        
$units "miles";
        
$unit "mile";
        
$distance 0.6214 $distance;
    } else {
        
$units "meters";
        
$unit "meter";
    }
    
    
# Print all data
    
print "<b><u>$title</u></b><br />\n";
    print 
"<b>Screen Name:</b>  $screenName<br />\n";
    print 
"<b>Distance:</b>  " number_format($distance,2) . " $units<br />\n";
    print 
"<b>Total Run:</b>  " number_format($totalMins,2) . " mins<br />\n";
    print 
"<b>Average</b>:  " number_format($totalMins/$distance,2) . " min/" $unit "<br />\n";
    print 
"<b>Calories Burned</b>:  $calories";
}
?>