-
-
Save johnraff/6138936 to your computer and use it in GitHub Desktop.
Access Twitter with OAuth, get json feed and output html for embedding in web page.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* tweets2html.php | |
* | |
* Modified by John Crawley 2013/07/24 | |
* to output html from Twitter feed for embedding in web page. | |
* | |
* Based on twitterfeed.php by Russell Beattie (2012-10-16) | |
* (http://www.russellbeattie.com/blog/twitterfeedphp-get-your-authenticated-twitter-stream-as-an-atom-feed) | |
* | |
* Also incorporates code adapted from: | |
* Yiming Liu's version: | |
* (http://blog.yimingliu.com/2013/02/07/a-twitter-timeline-to-atom-feed-proxy/) | |
* Twitterfeed+ by Patrick Nagel, 2013-04-06 | |
* (https://patrick-nagel.net/scripts/twitterfeedplus/twitterfeedplus.php) | |
* and URL un-shortening by Marty (2012-11-12) | |
* (http://www.internoetics.com/2012/11/12/resolve-short-urls-to-their-destination-url-php-api/) | |
* | |
* | |
* Timestamps are simplified and relative. | |
* Short links are expanded: t.co from Twitter entities, | |
* and one further step if necessary. | |
* Long URLs are truncated for display. | |
* Links are added to @mentions and #hashtags | |
* HTML (ul) is wrapped in variable $tweetlist for embedding in web page, | |
* and cached to avoid multiple calls to Twitter. | |
* Licence: new material GPL3, other as per original authors. | |
* | |
* Usage instructions: | |
* 1) Go to https://dev.twitter.com/apps and create a new App. | |
* 2) Use the Authentication button to create the tokens/secrets needed. | |
* 3) Copy the results into the appropriate spots below. | |
* 4) The script is currently set to output a user timeline. | |
* Check the Twitter api docs: https://dev.twitter.com/docs/api/1.1 | |
* and adjust $api_url and $api_params to suit your needs. | |
* ( Do not set 'include_entities' => 'false' ) | |
* 5) Set $cache_path, make sure the directory exists, is writable | |
* by the server and outside the web root. | |
* 6) Adjust any other settings to taste. | |
* 7) Put this file in your include path, and include it somewhere near | |
* the start of your php with: require_once('tweets2html.php'); | |
* NB This file contains your twitter app keys and secrets so be sure | |
* to put it above your web root, and give it minimum read permissions. | |
* 8) Call the html where you need it with: <?php echo($tweetlist); ?> | |
* | |
*/ | |
// Twitter App Settings (https://dev.twitter.com/apps): | |
// FILL THESE IN | |
$settings = array( | |
'consumer_key' => '*REPLACEME*', | |
'consumer_secret' => '*REPLACEME*', | |
'access_token' => '*REPLACEME*', | |
'access_token_secret' => '*REPLACEME*' | |
); | |
// API docs: https://dev.twitter.com/docs/api/1.1 | |
$api_url = 'https://api.twitter.com/1.1/statuses/user_timeline.json'; | |
$api_params = array( | |
'screen_name' => '*REPLACEME*', | |
'count' => 7, | |
'exclude_replies' => 'true', | |
'include_rts' => 'false', | |
'contributor_details' => 'false', | |
'trim_user' => 'true', | |
'include_entities' => 'true' | |
); | |
// Other settings: | |
// date_default_timezone_set('Asia/Tokyo'); // may (should?) be set elsewhere in your site | |
$url_max_display_length = 25; // long urls will be truncated to this | |
$error_message = 'Unable to display tweets.'; // display if getting tweets fails | |
$timestamp_title = 'View on Twitter'; // title for tweet's timestamp link | |
// Makes relative timestamps for tweets - edit to taste | |
function reltime($datetime) | |
{ | |
$diff=(time() - $datetime); | |
$day=60*60*24; | |
if ($diff<$day) //Under a day | |
{ | |
$reltime = 'Today'; | |
}else{ | |
$reltime = round($diff/$day) . ' days ago'; | |
} | |
return $reltime; | |
} | |
// Caching - set path to cache directory: | |
// Make sure this folder exists, is writable by server and | |
// preferably outside the web root. | |
$cache_path = '../cache'; // path relative to web root. | |
$cache_life = 60*60; // (seconds) | |
// cache will be used if newer than 1 hr | |
// settings end here // | |
////////////////////////////////////////////////////////////////////// | |
$cache_file = $_SERVER['DOCUMENT_ROOT'].'/'.$cache_path.'/tweetlist.html'; | |
if (file_exists($cache_file)) { | |
$timediff = (time() - filemtime($cache_file)); | |
if ($timediff < $cache_life) { | |
$tweetlist = file_get_contents($cache_file); | |
return; // do not run rest of script | |
} | |
} | |
// OAuth: | |
function oauth_encode($data){ | |
if(is_array($data)){ | |
return array_map('oauth_encode', $data); | |
} else if(is_scalar($data)) { | |
return str_ireplace(array('+', '%7E'), array(' ', '~'), rawurlencode($data)); | |
} else { | |
return ''; | |
} | |
} | |
// OAuth base settings | |
$oauth_params = array( | |
'oauth_consumer_key' => $settings['consumer_key'], | |
'oauth_nonce' => md5(microtime() . mt_rand()), | |
'oauth_signature_method' => 'HMAC-SHA1', | |
'oauth_timestamp' => time(), | |
'oauth_token' => $settings['access_token'], | |
'oauth_version' => '1.0', | |
); | |
// Sign OAuth params | |
$sign_params = array_merge($oauth_params, $api_params); | |
uksort($sign_params, 'strcmp'); | |
foreach ($sign_params as $k => $v) { | |
$sparam[] = oauth_encode($k) . '=' . oauth_encode($v); | |
} | |
$sparams = implode('&', $sparam); | |
$base_string = 'GET&' . oauth_encode($api_url) . '&' . oauth_encode($sparams); | |
$signing_key = oauth_encode($settings['consumer_secret']) . '&' . oauth_encode($settings['access_token_secret']); | |
$oauth_params['oauth_signature'] = oauth_encode(base64_encode(hash_hmac('sha1', $base_string, $signing_key, TRUE))); | |
// Set Authorization header: | |
uksort($oauth_params, 'strcmp'); | |
foreach ($oauth_params as $k => $v) { | |
$hparam[] = $k . '="' . $v . '"'; | |
} | |
$hparams = implode(', ', $hparam); | |
$headers = array(); | |
$headers['Expect'] = ''; | |
$headers['Authorization'] = 'OAuth ' . $hparams; | |
foreach ($headers as $k => $v) { | |
$curlheaders[] = trim($k . ': ' . $v); | |
} | |
// Format params: | |
foreach ($api_params as $k => $v) { | |
$rparam[] = $k . '=' . $v; | |
} | |
$rparams = implode('&', $rparam); | |
////////////////////////////////////////////////////////////////////////// | |
// Un-shorten URL | |
function resolveShortURL($url) { | |
$ch = curl_init("$url"); | |
curl_setopt($ch, CURLOPT_HEADER, 1); | |
curl_setopt($ch, CURLOPT_NOBODY, 1); | |
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0); | |
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); | |
curl_setopt($ch, CURLOPT_TIMEOUT, 5 ); | |
$yy = curl_exec($ch); | |
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); | |
curl_close($ch); | |
if($httpCode == 404) { | |
return ""; | |
} | |
$w = explode("\n",$yy); | |
$Redirect = array_values( preg_grep( '/[Ll]ocation/', $w ) ); | |
if(count($Redirect) > 0) { | |
$url = $Redirect[0]; | |
$url = str_ireplace("Location:", "", "$url"); | |
$url = trim("$url"); | |
return $url; | |
} | |
return ""; | |
} | |
// Get domain from URL | |
function getdomain($url) { | |
$url = trim($url); | |
$url = preg_replace("/^(http(s)?:\/\/)*(www.)*/is", "", $url); | |
$url = preg_replace("/\/.*$/is" , "" ,$url); | |
return $url; | |
} | |
// Array of top URL shorteners | |
$shorteners = array( "tiny.cc", "is.gd", "own.ly", "rubyurl.com", "bit.ly", "tinyurl.com", | |
"moourl.com", "cli.gs", "ka.lm", "u.nu", "yep.it", "shrten.com", "miniurl.com", "snipurl.com", | |
"short.ie", "idek.net", "w3t.org", "shiturl.com", "dwarfurl.com", "doiop.com", "smallurl.in", | |
"notlong.com", "fyad.org", "safe.mn", "hex.io", "own.ly", "lnkd.in", "fb.me", "amzn.to", | |
"goo.gl", "j.mp", "mcaf.ee", "lnk.ms", "youtu.be", "wp.me", "fwd4.me", "su.pr", "t.co", | |
"snurl.com", "tr.im", "twurl.cc", "fat.ly", "ow.ly", "bbc.in"); | |
// Truncate url for display | |
function truncate_url($url, $maxlength) | |
{ | |
$url = preg_replace('/^https?:\/\//','',$url,1); | |
if (strlen($url) > $maxlength) | |
{ | |
$url = substr($url,0,($maxlength -1)) . '…'; | |
} | |
return $url; | |
} | |
////////////////////////////////////////////////////////////////////////// | |
// GET: | |
$ch = curl_init(); | |
curl_setopt($ch, CURLOPT_URL, $api_url . '?' . $rparams); | |
curl_setopt($ch, CURLOPT_HTTPHEADER, $curlheaders); | |
curl_setopt($ch, CURLOPT_HEADER, false); | |
curl_setopt($ch, CURLINFO_HEADER_OUT, true); | |
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); | |
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); | |
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); | |
curl_setopt($ch, CURLOPT_TIMEOUT, 10 ); | |
$response = curl_exec($ch); | |
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE); | |
$info = curl_getinfo($ch); | |
$error = curl_error($ch); | |
$errno = curl_errno($ch); | |
curl_close($ch); | |
if($code != 200){ | |
error_log( "Error\n$code" ); | |
error_log(print_r($response,TRUE)); | |
error_log(print_r($info,TRUE)); | |
$tweetlist = "<ul><li>$error_message</li></ul>"; | |
return; | |
} | |
$all = json_decode($response, TRUE); | |
$tweetlist = "<ul>\n"; | |
foreach($all as $tweet){ | |
$id = $tweet['id_str']; | |
$text = htmlspecialchars($tweet['text']); | |
// $tweeter_name = htmlspecialchars($tweet['user']['name']); | |
// $tweeter_screen_name = $tweet['user']['screen_name']; | |
$tweeter_id = $tweet['user']['id_str']; | |
// $tweeter_url = $tweet['user']['url']; | |
// $tweeter_profile_image_url = $tweet['user']['profile_image_url']; | |
$source = htmlspecialchars($tweet['source']); | |
$created_time = strtotime($tweet['created_at']); | |
if(isset($tweet['entities'])){ | |
if(isset($tweet['entities']['urls'])){ | |
// expand t.co URLs, and possible second shortened URL after that. | |
$urls = $tweet['entities']['urls']; | |
foreach($urls as $url){ | |
$url_orig = $url['url']; | |
$url_expanded = $url['expanded_url']; | |
if(in_array(getdomain($url_expanded), $shorteners)) { | |
$url_reexpanded = resolveShortURL($url_expanded); | |
if($url_reexpanded) { | |
$url_expanded = $url_reexpanded; | |
} | |
} | |
$url_expanded_tagged = '<a href="'.$url_expanded.'">'.truncate_url($url_expanded,$url_max_display_length).'</a>'; | |
$text = str_replace($url_orig, $url_expanded_tagged, $text); | |
} | |
} | |
if(isset($tweet['entities']['user_mentions'])){ | |
// add link to @ mentions | |
$mentions = $tweet['entities']['user_mentions']; | |
foreach($mentions as $mention){ | |
$mention_name = htmlspecialchars($mention['name']); | |
$mention_screen_name = $mention['screen_name']; | |
$mention_tagged = '<a href="http://twitter.com/'.$mention_screen_name.'" title="'.$mention_name.'">@'.$mention_screen_name.'</a>'; | |
$text = str_replace("@$mention_screen_name", $mention_tagged, $text); | |
} | |
} | |
if(isset($tweet['entities']['hashtags'])){ | |
// add link to # hashtags | |
$hashtags = $tweet['entities']['hashtags']; | |
foreach($hashtags as $hashtag){ | |
$hashtext_orig = $hashtag['text']; | |
$hashtext = htmlspecialchars($hashtext_orig); | |
$hashtag_tagged = '<a href="http://twitter.com/search?q=%23'.$hashtext.'&src=hash">#'.$hashtext.'</a>'; | |
$text = str_replace("#$hashtext_orig", $hashtag_tagged, $text); | |
} | |
} | |
} | |
$timestamp = '<span class="tweet_time"><a href="http://twitter.com/'.$tweeter_id.'/status/'.$id.'" title="'.$timestamp_title.'">'.reltime($created_time).'</a></span>'; | |
$text = '<span class="tweet_text">'.$text.'</span>'; | |
$tweetlist .= '<li>'.$timestamp.' '.$text."</li>\n"; | |
} | |
$tweetlist .= "</ul>\n"; | |
//$tweetlist .= "<!--\n".print_r($all,TRUE)."\n-->"; // for debugging | |
file_put_contents($cache_file, $tweetlist, LOCK_EX); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Based on Russell Beattie's twitterfeed.php : https://gist.github.com/russellbeattie/3898467
and Liu Yiming's adaptation to use Twitter entities: https://gist.github.com/yimingliu/4735445
with material from Patrick Nagel:https://patrick-nagel.net/scripts/twitterfeedplus/twitterfeedplus.php
and Marty: http://www.internoetics.com/2012/11/12/resolve-short-urls-to-their-destination-url-php-api/
Creates a variable $tweetlist which holds an html <ul> containing the tweets for embedding in a web page as a customizable widget.