Twitter widget on Wordpress site has stopped feeding


#1

Hi,

Yesterday my Twitter widget on my Wordpress site stopped linking to my latest Twitter feeds. Is there currently a blackout for this service or is it likely something has changed on my site? Here’s the code for the widget:

<?php
class twitter_widget extends WP_Widget 
{
	/** constructor */
    function twitter_widget() 
	{
		global $themename;
		$widget_options = array(
			'classname' => 'twitter_widget',
			'description' => 'Displays Twitter Feed'
		);
        parent::WP_Widget('gymbase_twitter', __('Twitter Feed', $themename), $widget_options);
    }
	
	/** @see WP_Widget::widget */
    function widget($args, $instance) 
	{
        extract($args);

		//these are our widget options
		$title = $instance['title'];
		$login = $instance['login'];
		$count = $instance['count'];

		echo $before_widget;
		?>
		<div class="clearfix">
			<div class="header_left">
				<?php
				if($title) 
				{
					echo $before_title . $title . $after_title;
				}
				?>
			</div>
			<div class="header_right">
				<a href="#" id="latest_tweets_prev" class="scrolling_list_control_left icon_small_arrow left_white"></a>
				<a href="#" id="latest_tweets_next" class="scrolling_list_control_right icon_small_arrow right_white"></a>
			</div>
		</div>
		<div class="scrolling_list_wrapper">
			<ul class="scrolling_list latest_tweets">
			</ul>
		</div>
		<script type="text/javascript">
		jQuery(document).ready(function($){
			//tweets
			$.getJSON('http://twitter.com/statuses/user_timeline.json?screen_name=<?php echo $login; ?>&count=<?php echo $count; ?>&callback=?', function(data) 
			{
				if(data.length)
				{
					var list=$(".latest_tweets");
					var date;
					$(data).each(function(index,value)
					{
						date = new Date(value.created_at);
						list.append($('<li class="icon_small_arrow right_white">').append($('<p>').html(linkify(value.text)+'<abbr class="timeago" title="'+date.toISOString()+'">'+date.toISOString()+'</abbr>')));
					});

					$('.latest_tweets a').attr('target','_blank');

					list.carouFredSel({
						direction: "up",
						items: {
							visible: 3
						},
						scroll: {
							items: 1,
							easing: "swing",
							pauseOnHover: true,
							height: "variable"
						},
						prev: '#latest_tweets_prev',
						next: '#latest_tweets_next',
						auto: {
							play: false
						}
					});	
					$("abbr.timeago").timeago();
				}
			});
		});
		</script>
		<?php
        echo $after_widget;
    }
	
	/** @see WP_Widget::update */
    function update($new_instance, $old_instance) 
	{
		$instance = $old_instance;
		$instance['title'] = strip_tags($new_instance['title']);
		$instance['login'] = strip_tags($new_instance['login']);
		$instance['count'] = strip_tags($new_instance['count']);
		return $instance;
    }
	
	 /** @see WP_Widget::form */
	function form($instance) 
	{	
		global $themename;
		$title = esc_attr($instance['title']);
		$login = esc_attr($instance['login']);
		$count = esc_attr($instance['count']);
		?>
		<p>
			<label for="<?php echo $this->get_field_id('title'); ?>"><?php _e('Title', $themename); ?></label>
			<input class="widefat" id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" type="text" value="<?php echo $title; ?>" />
		</p>
		<p>
			<label for="<?php echo $this->get_field_id('login'); ?>"><?php _e('Login', $themename); ?></label>
			<input class="widefat" id="<?php echo $this->get_field_id('login'); ?>" name="<?php echo $this->get_field_name('login'); ?>" type="text" value="<?php echo $login; ?>" />
		</p>
		<p>
			<label for="<?php echo $this->get_field_id('count'); ?>"><?php _e('Count', $themename); ?></label>
			<input class="widefat" id="<?php echo $this->get_field_id('count'); ?>" name="<?php echo $this->get_field_name('count'); ?>" type="text" value="<?php echo $count; ?>" />
		</p>
		<?php
	}
}
//register widget
add_action('widgets_init', create_function('', 'return register_widget("twitter_widget");'));
?>

#2

See [node:10803] for more information.

Your code makes use of an unversioned endpoint that has been retired.

Instead of:

$.getJSON('http://twitter.com/statuses/user_timeline.json?screen_name=<?php echo $login; ?>&count=<?

You want:

$.getJSON('https://api.twitter.com/1/statuses/user_timeline.json?screen_name=<?php echo $login; ?>&count=<?

Keep in mind that version 1 of the API is also now deprecated and will be retired in March 2013. You may want to use our [node:10248] instead.


#3

I think i’m having similar issues with the Twitter feed I’m using on my site. The feed has stopped pulling in individual posts. I’m avoiding the timeline because I need a solution that provides SEO benefit to our site.

Here’s my code:
<?php
/* Class to embed twitter comments for a user into a website page (PHP) */
class myTwit{
var $user = false; // User to show public posts
var $cacheFile = ‘twitcache.txt’; // File to save local cache of Twitter update
var $cachExpire = 600; // Seconds that cache is classed as "old"
var $myTwitHeader = false;
var $postLimit = 20; // 20 = max
var $debug = false;
var $targetBlank = true;
var $postClass = false;

function printError($message){ echo htmlspecialchars($message);	exit;}

function debugMsg($message){if ($this->debug == true) echo htmlspecialchars($message).'<br />';}

function formatPlural($val, $qty){
	if ($val > 1) return $val.' '.$qty.'s';
	else return $val.' '.$qty;
}

function intoRelativeTime($seconds){
	if (($seconds / 60 / 60 / 24) > 1) return $this->formatPlural(round($seconds / 60 / 60 / 24), 'day').' ago';
	elseif (($seconds / 60 / 60) > 1) return 'about '.$this->formatPlural(round($seconds / 60 / 60), 'hour').' ago';
	else if (($seconds / 60 ) > 1) return 'about '.$this->formatPlural(round($seconds / 60), 'minute').' ago';
	else return 'about '.round($seconds).' seconds ago';
}

function linkURLs($text){
	$in=array( '`((?:https?|ftp)://\S+[[:alnum:]]/?)`si', '`((?<!//)(www\.\S+[[:alnum:]]/?))`si' );
	$out=array( '<a href="$1"'.$this->targetAppend.'>$1</a> ', '<a href="http://$1" target="_blank">$1</a>' );
	$text = preg_replace($in,$out,$text);
	$text = preg_replace('/@([a-zA-Z0-9-_]+)/','@<a href="http://twitter.com/$1"'.$this->targetAppend.'>$1</a>',$text);
	return $text;
}

function checkCacheFile(){
	if ( (@filemtime($this->cacheFile) < (mktime() - $this->cachExpire) ) || (!is_file($this->cacheFile)) ){
		$this->debugMsg('Cache file outdated');
		$this->updateCache();
	} else {
		$this->debugMsg('Cache file still valid');
	}
}

function updateCache(){
	$uri = 'http://twitter.com/statuses/user_timeline/'.$this->user.'.json';
	$req = new HTTPRequest($uri);
	$tmpdata = $req->DownloadToString();
	$resp = json_decode($tmpdata, true);
	if (isset($resp['error'])) $this->printError('Error getting information from Twitter ['.$resp['error'].']. Please check the username ('.$this->user.')');
	elseif (!is_array($resp)) $this->printError('Error getting information from Twitter. File is not JSON.');
	$handle = @fopen($this->cacheFile, 'w');
	if (!$handle) $this->printError('Could not write to cache file: '.$this->cacheFile.'. Please check read/write permissions.');
	fwrite($handle, $tmpdata);
	fclose($handle);
	$this->debugMsg('Updated cache file: '.$this->cacheFile);
}

function readCache(){
	if( false == ($this->jsonData = @file_get_contents( $this->cacheFile )))
		$this->printError('Could not read cache file: '.$this->cacheFile);
}

function initMyTwit(){
	if (!is_string($this->user)) $this->printError('Please set a user.');
	$this->targetAppend = ($this->targetBlank) ? ' target="_blank"' : '';
	$this->postClassAppend = ($this->postClass) ? ' class="'.$this->postClass.'"' : '';
	$this->checkCacheFile();
	$this->readCache();
	$this->jsonArray = json_decode($this->jsonData, true);
	$output = '<ul class="twitbox">';
	if ($this->myTwitHeader && isset($this->jsonArray[0])){
		$output .= '<li class="mytwitHead"><a href="http://twitter.com/'.$this->user.'"'.$this->targetAppend.'><img src="'.$this->jsonArray[0]['user']['profile_image_url'].'" style="border:0" alt="'.$this->user.'" /></a>'.
		'<div><a href="http://twitter.com/'.$this->user.'"'.$this->targetAppend.'>'.$this->user.'</a><br />'.
		$this->formatPlural($this->jsonArray[0]['user']['followers_count'], 'follower').'</div></li>';
	}		
	for($x=0; $x < count($this->jsonArray) && $x < $this->postLimit; $x++){
		$seconds_ago = mktime() - strtotime($this->jsonArray[$x]['created_at']);
		$ts = strtotime($this->jsonArray[$x]['created_at'])+$this->jsonArray[$x]['user']['utc_offset'];
		$cur_ts = mktime();
		$output .= '<li'.$this->postClassAppend.'>'.$this->linkURLs($this->jsonArray[$x]['text']).
		' <span class="twhen">by <a href="http://twitter.com/'.$this->jsonArray[$x]['user']['screen_name'].'"'.$this->targetAppend.'>'.$this->jsonArray[$x]['user']['screen_name'].'</a> '.
		$this->intoRelativeTime($seconds_ago)."</span></li>\n";
	}
	$output .= '</ul>';
	$this->myTwitData = $output;
}	

}

class HTTPRequest{
var $_fp; // HTTP socket
var $_url; // full URL
var $_host; // HTTP host
var $_protocol; // protocol (HTTP/HTTPS)
var $_uri; // request URI
var $_port; // port
// scan url
function _scan_url(){
$req = $this->_url;
$pos = strpos($req, ‘://’);
$this->_protocol = strtolower(substr($req, 0, $pos));
$req = substr($req, $pos+3);
$pos = strpos($req, ‘/’);
if($pos === false)
$pos = strlen($req);
$host = substr($req, 0, $pos);
if(strpos($host, ‘:’) !== false) {
list($this->_host, $this->_port) = explode(’:’, $host);
}else{
$this->_host = $host;
$this->_port = ($this->_protocol == ‘https’) ? 443 : 80;
}
$this->_uri = substr($req, $pos);
if($this->_uri == ‘’)
$this->_uri = ‘/’;
}
// constructor
function HTTPRequest($url){
$this->_url = $url;
$this->_scan_url();
}
// download URL to string
function DownloadToString(){
$crlf = “\r\n”;
// generate request
$req = ‘GET ’ . $this->_uri . ’ HTTP/1.0’ . $crlf
. 'Host: ’ . $this->_host . $crlf
. ‘User-Agent: PHP’ . $crlf
. $crlf;
// fetch
$this->_fp = @fsockopen(($this->_protocol == ‘https’ ? ‘ssl://’ : ‘’) . $this->_host, $this->_port);
if ($this->_fp){
fwrite($this->_fp, $req);
$response = “”;
while(is_resource($this->_fp) && $this->_fp && !feof($this->_fp))
$response .= fread($this->_fp, 1024);
fclose($this->_fp);
// split header and body
$pos = strpos($response, $crlf . $crlf);
if($pos === false)
return($response);
$header = substr($response, 0, $pos);
$body = substr($response, $pos + 2 * strlen($crlf));
// parse headers
$headers = array();
$lines = explode($crlf, $header);
foreach($lines as $line)
if(($pos = strpos($line, ‘:’)) !== false)
$headers[strtolower(trim(substr($line, 0, $pos)))] = trim(substr($line, $pos+1));
// redirection?
if(isset($headers[‘location’])){
$http = new HTTPRequest($headers[‘location’]);
return($http->DownloadToString($http));
} else{
return($body);
}
} else {
return false;
}
}
}
?>


#4

In this code, you probably want to replace:
$uri = ‘http://twitter.com/statuses/user_timeline/’.$this->user.’.json’;

with

$uri = ‘https://api.twitter.com/1/statuses/user_timeline/’.$this->user.’.json’;

Keep in mind though that v1 is also deprecated and it’s time to move on to API v1.1 by March 2012.


#5

you might also want to check the plugin discribed in this page:
http://www.ramsich.com


#6