<?php
/**
* Gamertag class gets gamertag info from Duncan Mackensie's webservice
*
* Thanks go to Duncan for the service as it is brilliant and no other such
* service exists.
*
* http://duncanmackenzie.net/blog/put-up-a-rest-api-for-xbox-gamertag-data/default.aspx
*
* Also, if you build anything that uses this class that may gain any serious
* traffic please notify Duncan as he has requested at:
*
* http://duncanmackenzie.net/Blog/using-my-xbox-live-data-service
*
*/
class Gamertag {
    
/**
     * Webservice base url
     */
    
protected $webservice = 'http://xboxapi.duncanmackenzie.net/gamertag.ashx?GamerTag=%GAMERTAG%';
    
    
/**
     * The gamerdata, populated as needed
     */
    
private $gamerdata = array(
        
'Gamertag' => ''    
    
);
    
    
/**
     * The resulting XML from the webservice.
     */
    
private $feed = null;
    
    
/**
     * Whether the feed has been parsed yet.
     */
    
private $feed_parsed = false;
    
/**
     * When the feed was retrieved.
     * This allows sane serialisation and logic about whether to refresh the
     * feed or simply use a cached version
     */
    
private $feed_retrieved = false;
    
    
/**
     * Constructor requires the gamertag.
     * NB. no validation is done at this stage.
     */
    
public function __construct($gamertag){
        
$this->gamerdata['Gamertag'] = $gamertag;
    }
    
    
    
/**
     * the __sleep function defines what data to save in serialisation
     * @todo I can't remember what this is supposed to return...
     */
    
public function __sleep(){
        return array();
    }
    
    
/**
     * How to wake up the object after serialisation.
     */
    
public function __wakeup(){
    
    }
    
    
/**
     * toString simply returns the gamertag
     */
    
public function __toString(){
        return
$this->gamerdata['Gamertag'];
    }
    
    
/**
     * Retrieves the XML from a webservice.
     */
    
public function getXML(){
        
$url = str_replace( '%GAMERTAG%', urlencode($this->gamerdata['Gamertag']), $this->webservice);
        
$xml = file_get_contents($url);
        return
$xml;
    }
    
    
/**
     * Retrieves an element from the feed, or a string snippet.
     */
    
public function retrieve( $element, $string = null, $multiple = false ){
        if(
is_null($string) ){
            
$string = $this->feed;
        }
        if(
false === $string ){
            return
$multiple ? array() : '';
        }
        
$element = preg_quote($element, '#');
        
$regex = '#<'.$element.'>(.*?)</'.$element.'>#s';
        if( !
$multiple){
            
preg_match($regex, $string, $match);
            return !
is_null($match[1]) ? $match[1] : "";
        }else{
            
preg_match_all($regex, $string, $match, PREG_PATTERN_ORDER);
            
//print_r(compact('regex','match','string'));
            
return $match[1] ;
        }
    }
    
    
/**
     * This is an XML parser that ignores attributes.
     * We don't need them. If we do later, then I will change the function.
     */
    
public function parseXML(){
        
$this->feed = $this->getXML();
        
$this->feed_retrieved = time();
        
//reset current array
        
$this->gamerdata = array();
        
        
//get basic info
    
$this->gamerdata['Gamertag'] = $this->retrieve('Gamertag');
        
$this->gamerdata['AccountStatus'] = $this->retrieve('AccountStatus');
        
$this->gamerdata['State'] = $this->retrieve('State');
        
$this->gamerdata['ProfileUrl'] = $this->retrieve('ProfileUrl');
        
$this->gamerdata['TileUrl'] = $this->retrieve('TileUrl');
    
$this->gamerdata['AvatarFullUrl'] = 'http://avatar.xboxlive.com/avatar/'.rawurlencode($this->gamerdata['Gamertag']).'/avatar-body.png';
        
$this->gamerdata['Country'] = $this->retrieve('Country');
        
$this->gamerdata['Location'] = $this->retrieve('Location');
        
$this->gamerdata['Bio'] = $this->retrieve('Bio');
        
$this->gamerdata['Reputation'] = $this->retrieve('Reputation');
        
$this->gamerdata['ReputationImageUrl'] = $this->retrieve('ReputationImageUrl');
        
$this->gamerdata['Zone'] = $this->retrieve('Zone');
        
$this->gamerdata['GamerScore'] = $this->retrieve('GamerScore');
        
        
//get presence info
        
$PresenceInfo = $this->retrieve('PresenceInfo');
        
$this->gamerdata['PresenceInfo']['Valid'] = $this->retrieve('Valid', $PresenceInfo);
        
$this->gamerdata['PresenceInfo']['Info'] = $this->retrieve('Info', $PresenceInfo);
        
$this->gamerdata['PresenceInfo']['Info2'] = $this->retrieve('Info2', $PresenceInfo);
        
$this->gamerdata['PresenceInfo']['LastSeen'] = $this->dateFix( $this->retrieve('LastSeen', $PresenceInfo) );
        
$this->gamerdata['PresenceInfo']['Online'] = $this->retrieve('Online', $PreseceInfo);
        
$this->gamerdata['PresenceInfo']['StatusText'] = $this->retrieve('StatusText', $PresenceInfo);
        
$this->gamerdata['PresenceInfo']['Title'] = $this->retrieve('Title', $PresenceInfo);
        
        
//get recent games info
        
$Games = $this->retrieve('XboxUserGameInfo', null, true);
        
$this->gamerdata['RecentGames'] = array();
        foreach(
$Games as $i => $game){
            
$this->gamerdata['RecentGames'][$i]['Name'] = $this->retrieve('Name', $game);
            
$this->gamerdata['RecentGames'][$i]['TotalAchievements'] = $this->retrieve('TotalAchievements', $game);
            
$this->gamerdata['RecentGames'][$i]['TotalGamerScore'] = $this->retrieve('TotalGamerScore', $game);
            
$this->gamerdata['RecentGames'][$i]['Image32Url'] = $this->retrieve('Image32Url', $game);
            
$this->gamerdata['RecentGames'][$i]['Image64Url'] = $this->retrieve('Image64Url', $game);
            
$this->gamerdata['RecentGames'][$i]['LastPlayed'] = $this->dateFix( $this->retrieve('LastPlayed', $game) );
            
$this->gamerdata['RecentGames'][$i]['Achievements'] = $this->retrieve('Achievements', $game);
            
$this->gamerdata['RecentGames'][$i]['GamerScore'] = $this->retrieve('GamerScore', $game);
            
$this->gamerdata['RecentGames'][$i]['DetailsURL'] = $this->retrieve('DetailsURL', $game);
        }
        
$this->feed_parsed = true;
    }
    
    public function
dateFix($date_string){
        return
date('r',strtotime($date_string));
    }
    
    public function
getString(){
        if(!
$this->feed_parsed){
            
$this->parseXML();
        }
        return
print_r($this->gamerdata, true);
    }
    
    public function
getFeed(){
        if(!
$this->feed_parsed){
            
$this->parseXML();
        }
        return
$this->feed;
    }
    
    public function
getArray(){
        if(!
$this->feed_parsed){
            
$this->parseXML();
        }
        return
$this->gamerdata;
    }
    
    public function
getJSON(){
        if(!
$this->feed_parsed){
            
$this->parseXML();
        }
        if(
function_exists(json_encode)){
            return
json_encode($this->gamerdata);
        }else{
            
//non-native PHP JSON Encode...
            
if(!$this->JSON){
        require
dirname(__FILE__).DIRECTORY_SEPARATOR."JSON.php";
                
$this->JSON = new Services_JSON();
            }
            return
$this->JSON->encode($this->gamerdata);
        }
    }
    
    public function
isValid(){
        if(!
$this->feed_parsed){
            
$this->parseXML();
        }
        return (
$this->gamerdata['State'] == 'Invalid' && $this->gamerdata['AccountStatus'] == 'Unknown') ? false : true;
    }
}

1