<?php
/*
Plugin Name: Latest twitter sidebar widget
Plugin URI: http://www.tacticaltechnique.com/wordpress/latest-twitter-sidebar-widget/
Description: Creates a sidebar widget that displays the latest Twitter update for any given user.
Author: Corey Salzano
Version: 0.110224
Author URI: http://www.tacticaltechnique.com/
*/
$verion = "0.110224";
// no edits required
// this plugin requires that PHP curl and PHP json be installed on your server
function latest_twitter_sidebar_widget() {
$saved_options = array( );
$saved_options = get_option("widget_latest_twitter");
if( !$saved_options ){
// set defaults
$default_options = array( );
$default_options['user'] = 'salzano';
$default_options['count'] = '3';
// the $prefix and $suffix are included before and after all updates as a group
$default_options['prefix'] = "";
$default_options['suffix'] = "<br> ";
// these items wrap each Twitter update
$default_options['beforeUpdate'] = "<p><i>\"";
$default_options['afterUpdate'] = "\"</i></p>";
update_option( "widget_latest_twitter",$default_options );
$saved_options = $default_options;
}
$username = $saved_options['user'];
$updateCount = $saved_options['count'];
$prefix = stripslashes($saved_options['prefix']);
$suffix = stripslashes($saved_options['suffix']);
$beforeUpdate = stripslashes($saved_options['beforeUpdate']);
$afterUpdate = stripslashes($saved_options['afterUpdate']);
if ( !function_exists('fix_twitter_update') ){
function fix_twitter_update($origTweet,$entities) {
if( $entities == null ){ return $origTweet; }
foreach( $entities->urls as $url ){
$index[$url->indices[0]] = "<a href=\"".$url->url."\">".$url->url."</a>";
$endEntity[(int)$url->indices[0]] = (int)$url->indices[1];
}
foreach( $entities->hashtags as $hashtag ){
$index[$hashtag->indices[0]] = "<a href=\"".$hashtag->url."\">".$hashtag->text."</a>";
$endEntity[$hashtag->indices[0]] = $hashtag->indices[1];
}
foreach( $entities->user_mentions as $user_mention ){
$index[$user_mention->indices[0]] = "<a href=\"http://twitter.com/".$user_mention->screen_name."\">@".$user_mention->screen_name."</a>";
$endEntity[$user_mention->indices[0]] = $user_mention->indices[1];
}
$fixedTweet="";
for($i=0;$i<strlen($origTweet);$i++){
if(strlen($index[(int)$i])>0){
$fixedTweet .= $index[(int)$i];
$i = $endEntity[(int)$i]-1;
} else{
$fixedTweet .= substr($origTweet,$i,1);
}
}
return $fixedTweet;
}
}
if ( !function_exists('curl_query') ){
function curl_query( $url, $userAgent ){
if ( function_exists('curl_init')) {
$curl = curl_init( $url );
curl_setopt($curl, CURLOPT_REFERER, get_bloginfo('home'));
curl_setopt($curl, CURLOPT_URL, $url );
curl_setopt($curl, CURLOPT_USERAGENT, $userAgent );
curl_setopt($curl, CURLOPT_TIMEOUT, 60);
curl_setopt($curl, CURLE_OPERATION_TIMEOUTED, 30);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
if (!$result = curl_exec($curl)) {
return "ERROR: " . curl_error($curl);
} else{
return $result;
}
} else{
// return a JSON error like twitter does so we can check for one type of error
return json_encode( array( "error" => "curl not installed on this server, sorry charlie"));
}
}
}
$fileName = dirname(__FILE__) ."/". $username . ".json";
if( file_exists( $fileName )){
$fileModified = filemtime( $fileName );
} else{
$fileModified = 0;
}
$today = time( );
$hoursSince = round(($today - $fileModified)/3600, 3);
if( $fileModified ){
if( $hoursSince < .5 ){
$saveNewFile = false;
//open file
$theFile = fopen( $fileName, "r" );
if( !$theFile ){
$saveNewFile = true;
} else{
$jsonData = fread( $theFile, filesize( $fileName ));
if( !$jsonData ){ $saveNewFile = true; }
fclose( $theFile );
}
} else{
//too old
$saveNewFile = true;
}
} else{
//no file
$saveNewFile = true;
}
if( $saveNewFile ){
//get new data from twitter
$saveNewFile = true;
$jsonURL = "http://api.twitter.com/1/statuses/user_timeline.json?screen_name=" . $username . "&include_entities=true";
$jsonData = curl_query( $jsonURL, "Latest twitter widget WP plugin " . $version );
}
$haveTwitterData = true;
// $jsonData now has the feed content
if( !$jsonData ){
// no tweets
$haveTwitterData = false;
}
// check for errors--rate limit or curl not installed
// data returned will be: {"error":"Rate limit exceeded. Clients may not make more than 150 requests per hour.","request":"\/1\/statuses\/user_timeline.json?screen_name=salzano&include_entities=true"}
$tweets = json_decode( $jsonData );
if( strlen( $tweets->error )){
//don't have tweets because of an error
$haveTwitterData = false;
}
// the data is good, save the file
if( $haveTwitterData && $saveNewFile ){
//save new file
$theFile = fopen( $fileName, "w" );
fwrite( $theFile, $jsonData );
fclose( $theFile );
}
// output the widget
// $jsonData now has the feed content, $tweets has been json_decoded
echo "<li id=\"latest-twitter-widget\"><a href=\"http://twitter.com/".$username."\">";
$icon = get_bloginfo('home')."/wp-content/plugins/latest-twitter-sidebar-widget/twitter.png";
echo "<img id=\"latest-twitter-widget-icon\" src=\"".$icon."\"></a>";
echo stripslashes( $prefix );
if( $haveTwitterData ){
$i=1;
foreach( $tweets as $tweet ){
if( $i > $updateCount ){ break; }
echo $beforeUpdate;
echo fix_twitter_update( $tweet->text, $tweet->entities );
echo $afterUpdate;
$i++;
}
}
echo "<div id=\"latest-twitter-follow-link\"><a href=\"http://twitter.com/$username\">follow @$username on twitter</a></div>";
echo stripslashes( $suffix ) . "</li>";
}
function init_latest_twitter(){
register_sidebar_widget("Latest twitter", "latest_twitter_sidebar_widget");
register_widget_control("Latest twitter", "latest_twitter_control");
}
function latest_twitter_control() {
if ( !function_exists('quot') ){
function quot($txt){
return str_replace( "\"", """, $txt );
}
}
$options = get_option("widget_latest_twitter");
if( !$options ){
// set defaults
$default_options = array( );
$default_options['user'] = 'salzano';
$default_options['count'] = '3';
$default_options['prefix'] = "";
$default_options['suffix'] = "<br> ";
$default_options['beforeUpdate'] = "<p><i>\"";
$default_options['afterUpdate'] = "\"</i></p>";
$options = $default_options;
update_option( "widget_latest_twitter",$default_options );
}
if ( $_POST['latest-twitter-submit'] ) {
// get posted values from form submission
$new_options['user'] = strip_tags(stripslashes($_POST['latest-twitter-user']));
$new_options['count'] = strip_tags(stripslashes($_POST['latest-twitter-count']));
$new_options['prefix'] = $_POST['latest-twitter-prefix'];
$new_options['suffix'] = $_POST['latest-twitter-suffix'];
$new_options['beforeUpdate'] = $_POST['latest-twitter-beforeUpdate'];
$new_options['afterUpdate'] = $_POST['latest-twitter-afterUpdate'];
// if the posted options are different, save them
if ( $options != $new_options ) {
$options = $new_options;
update_option('widget_latest_twitter', $options);
}
}
// format options as valid html
$username = htmlspecialchars($options['user'], ENT_QUOTES);
$updateCount = htmlspecialchars($options['count'], ENT_QUOTES);
$prefix = stripslashes(quot($options['prefix']));
$suffix = stripslashes(quot($options['suffix']));
$beforeUpdate = stripslashes(quot($options['beforeUpdate']));
$afterUpdate = stripslashes(quot($options['afterUpdate']));
?>
<div>
<label for="latest-twitter-user" style="line-height:35px;display:block;">Twitter user: @<input type="text" size="8" id="latest-twitter-user" name="latest-twitter-user" value="<?php echo $username; ?>" /></label>
<label for="latest-twitter-count" style="line-height:35px;display:block;">Show this many twitter updates: <input type="text" id="latest-twitter-count" size="2" name="latest-twitter-count" value="<?php echo $updateCount; ?>" /></label>
<label for="latest-twitter-prefix" style="line-height:35px;display:block;">Before everything: <input type="text" id="latest-twitter-prefix" size="5" name="latest-twitter-prefix" value="<?php echo $prefix; ?>" /></label>
<label for="latest-twitter-suffix" style="line-height:35px;display:block;">After everything: <input type="text" id="latest-twitter-suffix" size="5" name="latest-twitter-suffix" value="<?php echo $suffix; ?>" /></label>
<label for="latest-twitter-beforeUpdate" style="line-height:35px;display:block;">Before each tweet: <input type="text" id="latest-twitter-beforeUpdate" size="5" name="latest-twitter-beforeUpdate" value="<?php echo $beforeUpdate; ?>" /></label>
<label for="latest-twitter-afterUpdate" style="line-height:35px;display:block;">After each tweet: <input type="text" id="latest-twitter-afterUpdate" size="5" name="latest-twitter-afterUpdate" value="<?php echo $afterUpdate; ?>" /></label>
<input type="hidden" name="latest-twitter-submit" id="latest-twitter-submit" value="1" />
</div>
<?php
}
function latest_twitter_widget_css( ){
echo "<link type=\"text/css\" rel=\"stylesheet\" href=\"" . get_bloginfo('wpurl') ."/wp-content/plugins/latest-twitter-sidebar-widget/latest_twitter_widget.css\" />" . "\n";
}
add_action("plugins_loaded", "init_latest_twitter");
add_action('wp_head', 'latest_twitter_widget_css');
?>