)
- you can style the tweetlinks via CSS for class "tweet-link"
license: Creative Commons Attribution 3.0 Unported License
(http://creativecommons.org/licenses/by/3.0/)
attribution text:
'Original work by Harald Kraft,
published in this blog.'
*/
/* globals */
$insideitem = FALSE; // boolean whether inside item or not
$node = ""; // string representing the current tag
$title = ""; // title of the current node
$description = ""; // description of the current node
$date = ""; // date of the current node
$displayname = ""; // user's nickname as provided by the feed
$userurl = ""; // user's url as provided by the feed
$link = ""; // link url of the current node
$currtime = strtotime("now"); // set to the current time
$itemcounter = 0; // counter how many items have been dealt with
/* user specific CONFIGURATION */
$TWITTER_RSSURL = "http://twitter.com/statuses/user_timeline/23913556.rss"; // the desired rss url
$MAX_ITEMS = 4; // the amount of tweets you want to show
$FANCY_TIME = TRUE; // if set to TRUE show "2 days ago" instead of timestamps
$USE_CURL = FALSE; // if set to TRUE, use curl instead of fopen (might be necessary on some webservers)
/* If FANCY_TIME was set, return fancy ("2 days ago"), otherwise
* just format the tweet's time according to the string in the
* call of date().
*/
function formattime( $time ) {
global $FANCY_TIME;
// return fancy time if desired
// otherwise format timestamp as configured
if( $FANCY_TIME ) {
return toFancytime( $time );
}
else {
return date( 'D, d M Y H:i', strtotime( $time ) );
}
}
/* Convert tweet's timestamp to "2 days ago" and such
*/
function toFancytime( $time ) {
global $currtime;
$timediff = $currtime - strtotime( $time );
//echo "DEBUG: currtime=".$currtime." timediff=".$timediff;
// return value of floor() is still float, therefore intval()
if( $days = intval( (floor($timediff/86400) ) ) ) {
if( $days == 1 ) {
return "about 1 day ago";
}
else {
return $days . " days ago";
}
}
else if( $hours = intval( (floor($timediff/3600) ) ) ) {
if( $hours == 1 ) {
return "about 1 hour ago";
}
else {
return $hours . " hours ago";
}
}
else if( $mins = intval( (floor($timediff/60) ) ) ) {
if( $mins == 1 ) {
return "about 1 minute ago";
}
else {
return $mins . " minutes ago";
}
}
else {
$secs = intval( $timediff );
return $secs . " seconds ago";
}
}
/* startElement() is called when the parser encounters an opening tag.
* Since tweets are located within - -tags, a flag is set.
*/
function startElement( $parser, $tagname, $attributes ) {
global $insideitem, $node;
$node = strtoupper( $tagname );
if( $node == "ITEM" ) {
$insideitem = true;
}
}
/* endElement() is called when the parser encounters a closing tag
* and there complete data of a node is available.
* This function uses the variables set by characterData() in order
* to build HTML output.
* - Tweets are pasted as list items.
* - The RSS feed's username (retrieved from the feed itself) will be
* removed from single tweets.
* - HTTP links are made clickable.
*/
function endElement( $parser, $tagname ) {
global $insideitem, $node, $title, $description, $link, $displayname, $date;
global $MAX_ITEMS, $itemcounter;
$node = strtoupper( $tagname );
// if inside channel node, getting user's nickname from title
if( ( $node == "TITLE" ) && ( $insideitem == FALSE ) ) {
// fetching user's nickname
$displayname = trim( str_replace( 'Twitter / ', '', $title ) );
//echo "DEBUG: displayname=".$displayname;
}
if( $node == "ITEM" ) {
//echo "DEBUG: count=".$itemcounter." max=".$MAX_ITEMS;
if( $itemcounter < $MAX_ITEMS ) {
// remove user's nickname from description string
$printdesc = str_replace( $displayname . ': ', '', trim($description) );
// translate special characters into html
$printdesc = htmlspecialchars( $printdesc, ENT_QUOTES, 'UTF-8' );
// make links clickable
$printdesc = preg_replace( "/http:\/\/([.]?[a-zA-Z0-9_\/-])*/i", "$0", $printdesc );
//$printdesc = eregi_replace( "http://([.]?[a-zA-Z0-9_/-])*", "\\0", $printdesc );
/* final product: HTML output */
print( " " . $printdesc . "
\n" );
print( " ");
print( "\n" );
// clear variables
$title = "";
$description = "";
$printdesc = "";
$link = "";
$date = "";
$insideitem = FALSE;
$itemcounter++;
}
else {
// end parsing, in order to save execution time?
}
}
}
/* characterData() is called between encounters of start and
* end tag by the parser.
* This function retrieves the actual XML data (recognized by XML tags)
* and stores it in internal variables:
* $description, $date, $link per tweet (identified being inside - )
* $title, $userurl just once per rss retieve
*/
function characterData( $parser, $data ) {
global $insideitem, $node, $title, $description, $link, $userurl, $date;
if( $insideitem ) {
switch( $node ) {
case "DESCRIPTION":
$description .= $data; // use append, because one tag might
// have more than one characterData event
break;
case "PUBDATE":
$date .= $data;
break;
case "LINK":
$link .= $data;
break;
}
}
else {
// outside of
- are user's title and url
switch( $node ) {
case "TITLE":
$title .= $data;
//echo "DEBUG title=".$title;
break;
case "LINK":
// fetching user's url
$userurl .= $data;
//echo "DEBUG: userurl=".$userurl;
break;
}
}
}
/* -- main function --
* Creates a parser, sets handling functions and retrieves
* user's rssfeed (via curl or fopen).
* Actual work is done handling functions; cleans up after
* finishing.
*/
function parsetwitter() {
global $USE_CURL, $TWITTER_RSSURL;
// setup a parser for XML
$parser = xml_parser_create();
// set handling functions
xml_set_element_handler( $parser, "startElement", "endElement" );
xml_set_character_data_handler( $parser, "characterData" );
if( $USE_CURL ) {
//echo "DEBUG: using curl \n";
// open the feed via curl
$xml = curl_init( $TWITTER_RSSURL )
or die( "Error reading RSS data via curl_init: " . $TWITTER_RSSURL );
// set curl specific options
curl_setopt( $xml, CURLOPT_HEADER, FALSE );
curl_setopt( $xml, CURLOPT_RETURNTRANSFER, TRUE );
$data = curl_exec( $xml );
// close feed (because the data is already in $data)
curl_close( $xml );
// parse data
xml_parse( $parser, $data );
/* ERROR HANDLING? */
}
else {
//echo "DEBUG: using fopen \n";
// open the feed via fopen
$xml = fopen( $TWITTER_RSSURL, "r" )
or die( "Error reading RSS data via fopen: " . $TWITTER_RSSURL );
// read 4KB pieces and parse each piece
while( $data = fread( $xml, 4096 ) ) {
xml_parse( $parser, $data, feof($xml) );
/* ERROR HANDLING? */
}
// close feed
fclose( $xml );
}
// and finally free the parser
xml_parser_free( $parser );
}
?>