<?php

$settings 
= array (
    
'oauth_access_token' => '',
    
'oauth_access_token_secret' => '',
    
'consumer_key' => '',
    
'consumer_secret' => ''
);

###############################################################################################

/* Copyright (c) 2014 Brad Greco <brad@bgreco.net>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 */

$user str_replace('@'''$_GET['user']);

if(!
$user)
    die(
"Must provide user parameter: either Twitter username or 'home'");

if(
strtolower($user) == 'home') {
    
$url 'https://api.twitter.com/1.1/statuses/home_timeline.json';
    
$get '?count=50';
} else {
    
$url 'https://api.twitter.com/1.1/statuses/user_timeline.json';
    
$get "?screen_name=$user";
}

try {
    
$twitter = new TwitterAPIExchange($settings);
    
$response $twitter->setGetfield($get)
        ->
buildOauth($url'GET')
        ->
performRequest();
    
generate_feed($response, isset($_GET['debug']));
    
//generate_feed(file_get_contents('response2.txt'), isset($_GET['debug']));
} catch (Exception $e) {
    echo 
$e->getMessage();
}

function 
generate_feed($response$debug false) {
    
$entries '';
    
$max_time 0;
    if(!
$err) {
        
$tweets json_decode($response1);
        if(
$debug) {
            
header('Content-type: text/plain');
            
print_r($tweets);
            die();
        }
        if(
$tweets['errors']) {
            
$entries "
    <entry>
        <title>Fetch error</title>
        <id>tag:bgreco.net,2014:" 
$_GET['user'] . "-" time() . "</id>
        <updated>" 
date(DATE_ATOMtime()) . "</updated>
        <content type='html'>" 
$tweets['errors'][0]['message'] . "</content>
    </entry>"
;
        } else {
            foreach(
$tweets as $tweet) {
                
$user $tweet['user']['screen_name'];
                
$id $tweet['id_str'];
                
$link "https://twitter.com/$user/status/$id";
                
$text_plain xml_character_encode($tweet['user']['name'] . ': ' tweet_text($tweet));
                
$text_html tweet_html($tweet);
                
$time strtotime($tweet['created_at']);
                
$max_time max($max_time$time);
                
$date date(DATE_ATOM$time);

                
$entries .= "
    <entry>
        <title>
$text_plain</title>
        <link href='
$link' />
        <id>tag:bgreco.net,2014:
$user-$id</id>
        <updated>
$date</updated>
        <content type='html'>
$text_html</content>
    </entry>"
;
            }
        }
    }
    
    
header('Content-type: application/atom+xml');
    
$host $_SERVER['SERVER_NAME'];
    
$self $_SERVER['PHP_SELF'];

    echo 
"<?xml version='1.0' encoding='utf-8'?>
<feed xmlns='http://www.w3.org/2005/Atom'>
    <title>Twitter - @
$user</title>
    <link rel='self' type='application/atom+xml' href='http://
$host$self?user=$user'/>
    <updated>" 
date(DATE_ATOM$max_time) . "</updated>
    <author><name>
$user</name></author>
    <id>tag:bgreco.net,2014:twitter-
$user</id>
    <icon>http://abs.twimg.com/favicons/favicon.ico</icon>
$entries
</feed>"
;
}

function 
tweet_text($tweet) {
    if(
$tweet['retweeted_status'])
        
$text 'RT @' $tweet['retweeted_status']['user']['screen_name'] . ': ' $tweet['retweeted_status']['text'];
    else
        
$text $tweet['text'];
    return 
$text;
}

function 
tweet_html($tweet) {
    if(
$tweet['retweeted_status'])
        
$img $tweet['retweeted_status']['user']['profile_image_url'];
    else
        
$img $tweet['user']['profile_image_url'];
    
    
$text "<table border='0'><tr><td valign='top'><img src='$img'></td><td valign='top'><b><a href='https://twitter.com/" $tweet['user']['screen_name'] . "'>" $tweet['user']['name'] . '</a>:</b><br>';
    
$text .= tweet_text($tweet);
    foreach(
$tweet['entities']['urls'] as $url) {
        
$text str_replace($url['url'], "<a href='" $url['expanded_url'] . "'>" $url['display_url'] . "</a>"$text);
    }
    foreach(
$tweet['entities']['hashtags'] as $hashtag) {
        
$text str_replace('#' $hashtag['text'], "<a href='https://twitter.com/search?q=%23" $hashtag['text'] . "'>#" $hashtag['text'] . "</a>"$text);
    }
    foreach(
$tweet['entities']['user_mentions'] as $mentions) {
        
$text str_replace('@' $mentions['screen_name'], "<a href='https://twitter.com/" $mentions['screen_name'] . "'>@" $mentions['screen_name'] . "</a>"$text);
    }
    
$text str_replace("\n""<br>\n"str_replace("\r"""$text));
    
$text .= '</td></tr></table>';
    return 
xml_character_encode($text);
}

function 
xml_character_encode($string$trans='') {
    
$trans = (is_array($trans)) ? $trans get_html_translation_table(HTML_ENTITIESENT_QUOTES);
    foreach (
$trans as $k=>$v)
        
$trans[$k]= "&#".ord($k).";";
    return 
strtr($string$trans);
}

/**
 * Twitter-API-PHP : Simple PHP wrapper for the v1.1 API
 * 
 * PHP version 5.3.10
 * 
 * @category Awesomeness
 * @package  Twitter-API-PHP
 * @author   James Mallison <me@j7mbo.co.uk>
 * @license  MIT License
 * @link     http://github.com/j7mbo/twitter-api-php
 */
class TwitterAPIExchange
{
    private 
$oauth_access_token;
    private 
$oauth_access_token_secret;
    private 
$consumer_key;
    private 
$consumer_secret;
    private 
$postfields;
    private 
$getfield;
    protected 
$oauth;
    public 
$url;

    
/**
     * Create the API access object. Requires an array of settings::
     * oauth access token, oauth access token secret, consumer key, consumer secret
     * These are all available by creating your own application on dev.twitter.com
     * Requires the cURL library
     * 
     * @param array $settings
     */
    
public function __construct(array $settings)
    {
        if (!
in_array('curl'get_loaded_extensions())) 
        {
            throw new 
Exception('You need to install cURL, see: http://curl.haxx.se/docs/install.html');
        }
        
        if (!isset(
$settings['oauth_access_token'])
            || !isset(
$settings['oauth_access_token_secret'])
            || !isset(
$settings['consumer_key'])
            || !isset(
$settings['consumer_secret']))
        {
            throw new 
Exception('Make sure you are passing in the correct parameters');
        }

        
$this->oauth_access_token $settings['oauth_access_token'];
        
$this->oauth_access_token_secret $settings['oauth_access_token_secret'];
        
$this->consumer_key $settings['consumer_key'];
        
$this->consumer_secret $settings['consumer_secret'];
    }
    
    
/**
     * Set postfields array, example: array('screen_name' => 'J7mbo')
     * 
     * @param array $array Array of parameters to send to API
     * 
     * @return TwitterAPIExchange Instance of self for method chaining
     */
    
public function setPostfields(array $array)
    {
        if (!
is_null($this->getGetfield())) 
        { 
            throw new 
Exception('You can only choose get OR post fields.'); 
        }
        
        if (isset(
$array['status']) && substr($array['status'], 01) === '@')
        {
            
$array['status'] = sprintf("\0%s"$array['status']);
        }
        
        
$this->postfields $array;
        
        return 
$this;
    }
    
    
/**
     * Set getfield string, example: '?screen_name=J7mbo'
     * 
     * @param string $string Get key and value pairs as string
     * 
     * @return \TwitterAPIExchange Instance of self for method chaining
     */
    
public function setGetfield($string)
    {
        if (!
is_null($this->getPostfields())) 
        { 
            throw new 
Exception('You can only choose get OR post fields.'); 
        }
        
        
$search = array('#'',''+'':');
        
$replace = array('%23''%2C''%2B''%3A');
        
$string str_replace($search$replace$string);  
        
        
$this->getfield $string;
        
        return 
$this;
    }
    
    
/**
     * Get getfield string (simple getter)
     * 
     * @return string $this->getfields
     */
    
public function getGetfield()
    {
        return 
$this->getfield;
    }
    
    
/**
     * Get postfields array (simple getter)
     * 
     * @return array $this->postfields
     */
    
public function getPostfields()
    {
        return 
$this->postfields;
    }
    
    
/**
     * Build the Oauth object using params set in construct and additionals
     * passed to this method. For v1.1, see: https://dev.twitter.com/docs/api/1.1
     * 
     * @param string $url The API url to use. Example: https://api.twitter.com/1.1/search/tweets.json
     * @param string $requestMethod Either POST or GET
     * @return \TwitterAPIExchange Instance of self for method chaining
     */
    
public function buildOauth($url$requestMethod)
    {
        if (!
in_array(strtolower($requestMethod), array('post''get')))
        {
            throw new 
Exception('Request method must be either POST or GET');
        }
        
        
$consumer_key $this->consumer_key;
        
$consumer_secret $this->consumer_secret;
        
$oauth_access_token $this->oauth_access_token;
        
$oauth_access_token_secret $this->oauth_access_token_secret;
        
        
$oauth = array( 
            
'oauth_consumer_key' => $consumer_key,
            
'oauth_nonce' => time(),
            
'oauth_signature_method' => 'HMAC-SHA1',
            
'oauth_token' => $oauth_access_token,
            
'oauth_timestamp' => time(),
            
'oauth_version' => '1.0'
        
);
        
        
$getfield $this->getGetfield();
        
        if (!
is_null($getfield))
        {
            
$getfields str_replace('?'''explode('&'$getfield));
            foreach (
$getfields as $g)
            {
                
$split explode('='$g);
                
$oauth[$split[0]] = $split[1];
            }
        }
        
        
$base_info $this->buildBaseString($url$requestMethod$oauth);
        
$composite_key rawurlencode($consumer_secret) . '&' rawurlencode($oauth_access_token_secret);
        
$oauth_signature base64_encode(hash_hmac('sha1'$base_info$composite_keytrue));
        
$oauth['oauth_signature'] = $oauth_signature;
        
        
$this->url $url;
        
$this->oauth $oauth;
        
        return 
$this;
    }
    
    
/**
     * Perform the actual data retrieval from the API
     * 
     * @param boolean $return If true, returns data.
     * 
     * @return string json If $return param is true, returns json data.
     */
    
public function performRequest($return true)
    {
        if (!
is_bool($return)) 
        { 
            throw new 
Exception('performRequest parameter must be true or false'); 
        }
        
        
$header = array($this->buildAuthorizationHeader($this->oauth), 'Expect:');
        
        
$getfield $this->getGetfield();
        
$postfields $this->getPostfields();

        
$options = array( 
            
CURLOPT_HTTPHEADER => $header,
            
CURLOPT_HEADER => false,
            
CURLOPT_URL => $this->url,
            
CURLOPT_RETURNTRANSFER => true,
            
CURLOPT_TIMEOUT => 10,
            
//CURLOPT_VERBOSE => true,
        
);

        if (!
is_null($postfields))
        {
            
$options[CURLOPT_POSTFIELDS] = $postfields;
        }
        else
        {
            if (
$getfield !== '')
            {
                
$options[CURLOPT_URL] .= $getfield;
            }
        }

        
$feed curl_init();
        
curl_setopt_array($feed$options);
        
$json curl_exec($feed);
        
curl_close($feed);

        if (
$return) { return $json; }
    }
    
    
/**
     * Private method to generate the base string used by cURL
     * 
     * @param string $baseURI
     * @param string $method
     * @param array $params
     * 
     * @return string Built base string
     */
    
private function buildBaseString($baseURI$method$params
    {
        
$return = array();
        
ksort($params);
        
        foreach(
$params as $key=>$value)
        {
            
$return[] = "$key=" $value;
        }
        
        return 
$method "&" rawurlencode($baseURI) . '&' rawurlencode(implode('&'$return)); 
    }
    
    
/**
     * Private method to generate authorization header used by cURL
     * 
     * @param array $oauth Array of oauth data generated by buildOauth()
     * 
     * @return string $return Header used by cURL for request
     */    
    
private function buildAuthorizationHeader($oauth
    {
        
$return 'Authorization: OAuth ';
        
$values = array();
        
        foreach(
$oauth as $key => $value)
        {
            
$values[] = "$key=\"" rawurlencode($value) . "\"";
        }
        
        
$return .= implode(', '$values);
        return 
$return;
    }

}