<?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.1
Author URI: http://www.ericbyers.com/

Variables available:

User
----
$user_runs -- Total Number Ran
$user_screenname -- Nike+ ScreenName
$user_distance -- Total Distance Ran
$user_minutes -- Total Minutes Ran
$user_pace -- Your Average Pace
$user_calories -- Total Calories Burned
$unit -- Mile or Meter
$units -- Miles or Meters

Goals
-----

Challenges
----------

*/


$username 'user@domain.com'// Nike+ username (usually your email address).
$password '';                // Nike+ password.

#==============================================

$cache_path "tmp/"// Relative path to store cached file to with trailing slash.
$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";

$data['user'] = "/nikeplus/v1/services/app/get_user_data.jhtml";
#$data['goals'] = "/nikeplus/v1/services/app/goal_list.jhtml";
#$data['challenges'] = "/nikeplus/v1/services/widget/get_challenges_for_user.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($cache_file$url_data) {
    global 
$debug$cache_path$cache_limit$url_auth;
    
    
$current_time time();
    
$cache_time   = @filemtime($cache_path $cache_file);
    
    if (
$debug 0) {
        echo 
$cache_file "<br>";
        echo 
$url_data "<br>";
        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'https://www.nike.com' $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 the data
     
if (ereg("success"$data)) {
         return 
$data;
     }
     return 
false;

}

foreach (
$data as $type => $url) {

    
// Pull the data
    
$data get_nike_data("nike_" $type ".xml"$url);

    
// Check to see if we got the data, if we didn't, error and exit.
    
if ($data === false) {
        echo 
"Could not get Nike+ Data";
    
// Where the magic happens
    
} else {
        
// User Data goes here.
        
if ($type == 'user') {
            
            
// Pull out user data from XML
            
$user_runs XPathValue("plusService/userTotals/totalRuns",$data);
            
$user_minutes XPathValue("plusService/userTotals/totalDuration",$data)/(1000 60);
            
$user_distance XPathValue("plusService/userTotals/totalDistance",$data);
            
$user_calories XPathValue("plusService/userTotals/totalCalories",$data);
            
$user_screenname XPathValue("plusService/userOptions/screenName",$data);
            
            if (
ereg("CDATA",$screenName)) {
                   
$pos1 strpos($user_screenname"CDATA") + 6;
                
$pos2 strpos($user_screenname"]");
                
$screenName substr($user_screenname$pos1$pos2 $pos1);
            }

            if (
XPathValue("plusService/userOptions/distanceUnit",$data) == "mi") {
                
$units "miles";
                
$unit "mile";
                
$user_distance 0.6214 $user_distance;
            } else {
                
$units "meters";
                
$unit "meter";
            }
            
            
// Convert pace from decimal to roman with rounding.  Nike+ website does not run so this may be slightly off.
            
$user_pace explode('.'$user_minutes/$user_distance);
            
$user_pace $user_pace[0] . ":" str_pad(round(("." $user_pace[1]) * 60), 2'0'STR_PAD_LEFT);
    
            
// Number format for awesome runners
            
$user_minutes number_format($user_minutes2);
            
$user_distance  number_format($user_distance2);
        
        
// Goal Data goes here.
        
} else if ($type == 'goals') {
    
        
// Challenges Data goes here.
        
} if ($type == 'challenges') {
            
        }
    }
}

echo 
"
<li><b>Number of Runs:</b> $user_runs</li>
<li><b>Distance:</b> $user_distance</li>
<li><b>Average:</b> $user_pace min/$unit</li>
<li><b>Calories Burned:</b> $user_calories</li>
"
;
?>