) - 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( " " . formattime($date) . ""); 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 ); } ?>