Combined Facebook, Twitter & RSS Social Stats with jQuery, PHP & YQL

Combined Facebook, Twitter & RSS Social Stats with jQuery, PHP & YQL

As we increasingly depend on more and more social services, there rises the need to provide a simple way to let our website visitors take part of our diverse social presence.

In this tutorial we are going to create a simple widget, which combines the number of your RSS readers, twitter followers, and fans of your facebook fan page, to give a rough estimate of your social popularity.

We are using jQuery and the tipTip plugin, object-oriented PHP, and Yahoo’s YQL, while demonstrating a number of interesting web development techniques.

Update (Jun 17th, 2013): All the APIs used in this tutorial have been deprecated or changed, so unfortunately the social stats won’t work any more.

Step 1 – PHP

YQL is a free Yahoo web service, which enables us to communicate with numerous third-party APIs through a consistent SQL-like language (and hence the name). It is basically a gateway that sits between you and the other APIs.

This is especially important here, as we are using Yahoo’s YQL for three very different tasks:

  • Fetch your RSS subscriber count with FeedBurner’s awareness API (which comes in the form of an XML file that has to be parsed).
    Note:
    You have to enable the awareness API to use this widget with your own feed. This is done from the Publicize Tab on your feed settings page;
  • Use twitter’s API to get your number of followers;
  • Use Facebook’s new Graph API (link) to get information about the number of fans of your facebook fanpage.

If it weren’t for YQL, we’d have to research and implement three very different solutions, which would slow us down significantly.

includes/subscriber_stats.class.php

class SubscriberStats{

	public	$twitter,$rss,$facebook;
	public	$services = array();

	public function __construct($arr){

		$this->services = $arr;

		$yqlQueries = array();

		// Forming the Feedburner Awaraness API URL from the passed feed URL:
		$feedBurnerAwarenessAPI = 'http://feedburner.google.com/api/awareness'.
		'/1.0/GetFeedData?uri='.end(split('/',trim($arr['feedBurnerURL'],'/')));

		// Building an array with queries:

		if($arr['feedBurnerURL'])
			$yqlQueries[] = '
				SELECT * FROM xml
				WHERE url=\''.$feedBurnerAwarenessAPI.'\'
			';

		if($arr['twitterName'])
			$yqlQueries[] = '
				SELECT * FROM twitter.user.profile
				WHERE id=\''.$arr['twitterName'].'\'
			';

		if($arr['facebookFanPageURL'])
			$yqlQueries[] = '
			SELECT likes FROM facebook.graph
			WHERE id=\''.end(split('/',trim($arr['facebookFanPageURL'],'/'))).'\'
			';

		// Combing them into a YQL multiquery:
		$multiQuery =
		'SELECT * FROM query.multi WHERE queries = "'.join(';',$yqlQueries).'"';

		// Executing the query:
		$result = json_decode(
			file_get_contents('http://query.yahooapis.com/v1/public/yql?q='.
			urlencode($multiQuery).'&format=json&diagnostics=false&'
			'amp;env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys')
		)->query->results->results;

		// The results from the queries are accessible in the $results array:

		$this->rss = $result[0]->rsp->feed->entry->circulation;
		$this->twitter = $result[1]->item->meta[5]->content;
		$this->facebook = $result[2]->json->fan_count;
	}

	public function generate(){

		$total = number_format($this->rss+$this->twitter+$this->facebook);

		echo '
			<div class="subscriberStats">
				<div class="subscriberCount"
				title="'.$total.'+ Total Social Media Followers">'.$total.'</div>

				<div class="socialIcon"
				title="'.number_format($this->rss).' RSS Subscribers">
					<a href="'.$this->services['feedBurnerURL'].'">
					<img src="img/rss.png" alt="RSS" /></a>
				</div>

				<div class="socialIcon"
				title="'.number_format($this->facebook).' Fans on Facebook">
					<a href="'.$this->services['facebookFanPageURL'].'">
					<img src="img/facebook.png" alt="Facebook" /></a>
				</div>

				<div class="socialIcon"
				title="'.number_format($this->twitter).' Twitter Followers">
				<a href="http://twitter.com/'.$this->services['twitterName'].'">
					<img src="img/twitter.png" alt="Twitter" /></a>
				</div>
			</div>
		';
	}
}

When we create an object of this class, the construct method is called, and a YQL query is created and executed.

To request the data from YQL’s servers, we just use file_get_contents() with the query passed as a parameter of the URL address. This returns a JSON object (basically a JavaScript object) which we can decode into a native PHP array with the in-build json_decode() function.

The results of these queries are saved locally and are made available for use in the generate() method which renders all the needed markup.

And now lets see how this class is used:

subscriber_count.php

require "includes/subscriber_stats.class.php";

$cacheFileName = "cache.txt";

// IMPORTANT: after making changes to this file (or the SubscriberStats class)
// remeber to delete cache.txt from your server, otherwise you wont see your changes.

// If a cache file exists and it is less than 6*60*60 seconds (6 hours) old, use it:

if(file_exists($cacheFileName) && time() - filemtime($cacheFileName) > 6*60*60)
{
	$stats = unserialize(file_get_contents($cacheFileName));
}

if(!$stats)
{
	// If no cache was found, fetch the subscriber stats and create a new cache:

	$stats = new SubscriberStats(array(
		'facebookFanPageURL'	=> 'http://www.facebook.com/smashmag',
		'feedBurnerURL'			=> 'http://feeds.feedburner.com/Tutorialzine',
		'twitterName'			=> 'Tutorialzine'
	));

	// Serialize turns the object into a string,
	// which can later be restored with unserialize():

	file_put_contents($cacheFileName,serialize($stats));
}

//	You can access the individual stats like this:
//	$stats->twitter;
//	$stats->facebook;
//	$stats->rss;

//	Output the markup for the stats:

$stats->generate();

Sending a query to YQL’s servers and receiving a response is a relatively slow process and would be unwise to request the same information on every page load (not to mention that we could get banned from the API for abuse).

This is why we implement a simple caching system. The idea is simple: if a cache file does not exist (or is older than 6 hours), connect to YQL, create a new cache file and output the XHTML markup. Otherwise, just read the cache and output directly. This way we send a request to the API only once every six hours which is perfect for any practical purposes.

Combined Social Media Followers Count

Combined Social Media Followers Count

Step 2 – XHTML

As mentioned in the PHP section above, the generate() method renders all the XHTML markup used to display the stats. Here is what the generated code looks like:

sample code

<div class="subscriberStats">
    <div class="subscriberCount"  title="25,382+ Total Social Media Followers>25,382</div>

    <div class="socialIcon" title="5,921 RSS Subscribers">
        <a href="http://feeds.feedburner.com/Tutorialzine">
        <img alt="RSS" src="img/rss.png" /></a>
    </div>

    <div class="socialIcon" title="16,813 Fans on Facebook">
        <a href="http://www.facebook.com/smashmag">
        <img alt="Facebook" src="img/facebook.png" /></a>
    </div>

    <div class="socialIcon" title="2,648 Twitter Followers">
        <a href="http://twitter.com/Tutorialzine">
        <img alt="Twitter" src="img/twitter.png" /></a>
    </div>
</div>

This code is fetched via AJAX and displayed on the page. Notice the title attributes. They are used as the contents of the fancy tooltips which are created by jQuery and the tipTip plugin, which we will discuss in a moment.

Step 3 – CSS

The CSS code is also quite simple and straightforward. The subscriberStats is the main outer div, inside it we have a number of .socialIcon divs and the subscrberCount.

css/styles.css

.subscriberStats{
	height:35px;
	padding:5px;
	width:220px;
}

.socialIcon{
	float:left;
	height:32px;
	width:32px;
}

a img{
	border:none;
}

.subscriberCount{
	border-bottom:1px dotted #CCCCCC;
	color:#999999;
	float:left;
	font-size:28px;
	line-height:32px;
	margin-right:10px;
}

#main{
	height:100px;
	margin:140px auto 50px;
	position:relative;
	width:200px;
}

All of these are floated to the left. Also notice that we disable the borders on the icon images on line 14, which are displayed by default and ruin your design.

Step 4 – jQuery

After including the jQuery library to the page, we just need to listen to the $(document).ready event, which is executed when all the markup of the page is accessible (this happens before things like images are loaded and comes earlier than the onload event).

js/script.js

$(document).ready(function(){

	// Using the load AJAX method to fetch the subscriber markup
	// from subscriber_count.php:

	$('#main').load('subscriber_count.php',function(){

		// Once loaded, convert the title attributes to tooltips
		// with the tipTip jQuery plugin:

		$('.subscriberStats div').tipTip({defaultPosition:'top'});
	})

});

#main is the div where we want to insert the stats. This could be your sidebar or website header. The load method fetches the markup from suscriber_count.php and displays it on the page.  The callback function is called after this and all the div titles are replaced with fancy tooltips by the tipTip plugin.

With this our combined social stats widget is complete!

Conclusion

With services like YQL working with third party APIs is a charm. Not only it provides a common interface to a sea of technologies, but it also guarantees that you will be able to access to the services you want even as the underlying APIs change overtime.

What do you think? How would you improve this code?

Join our newsletter and get our PSDs!20,176 people learn about HTML5, JS and more. Join them!

by Martin Angelov

Martin is a web developer with an eye for design from Bulgaria. He founded Tutorialzine in 2009 and it still is his favorite side project.

51 Comments

  1. Miles says:

    Simply great! I've said it once, and I'll say it many, many times again:

    You have the best, free, tutorials on the web!
    Imaginative, without w3c bugs, using many technologies, and so on...

    Keep up the good work - and I'm REALLY looking forward to zinescripts!
    (thx for the follow btw!)

    Miles.

  2. esranull says:

    very very nice working thanks a lot

  3. Batfan says:

    Wow, very original! Nice work!

  4. Amir says:

    This is a great and unique work!
    Great website, one of my top favorites!
    keep up the good work.

  5. christian says:

    very nice tutorial!!! the best tutorial creator on the web!!!
    just wanna ask if you can also follow me on my twitter..thanks!!

  6. Now that's Very Cool!! :)

    Always a Pleasure reading your fabulous tutorials!!!

    My appreciation for sharing YOU! :)
    Blessed Light,
    Aline [ArtWave]

  7. aaaawesome!!!

    now this should be a wp-plugin (even if it's easy & maybe better by itself), okey I'm on it! =)

  8. Cool usage of PHP and YQL. Your tutorial is very good in details :). I love this. Thanks for sharing.

  9. I always wonder how sites like Smashing Magazine can count the number of their subscribers. Now I know. Thanks for the helpful post.

  10. Beben says:

    awesome, we can get one nominal from third .. ;)
    thanks...

  11. really nice thanks

  12. hmm cool nice tutorial... thanks for sharing Martin...

  13. Chandrima says:

    Great one!

  14. Jonathan Dusza says:

    i'm bout to try modding this but has anyone added MySpace of other social media sites into this?

  15. Eko Priyanto says:

    very very nice working thanks a lot

  16. Jonathan Dusza says:

    here's better question, i want to count facebook personal page(s), group pages + the fan page. my modded code is displaying the right info for my additional data but wont actually pull the #s.

  17. vipin sahu says:

    How can i add the Buzz followers in the list
    Thanks

  18. Beso says:

    wow, very nice tutorial... Thanks for sharing!

  19. Everton says:

    Hi

    Great guide - really need this! Can you post an idiots guide of where these files need to go on WP please

    Thanks

    EB

  20. Tonev says:

    Can you add YouTube to the stats too? or at least some documentation how to get the amount of YouTube subscribers ?

  21. ValsiS says:

    work, but don;t copy the code from the site, download the demo

  22. Albert says:

    The Twitter count has stopped working. Any ideas?

    1. Martin Angelov says:

      Twitter recently changed their APIs and it seems that the method I used to fetch the followers count is not available any more.

      I updated the code to work with the new APIs. I don't think that twitter are going to make such radical changes any more, so this solution is going to work in the foreseeable future.

      You can re-download the archive and replace includes/subscriber_stats.class.php with the new version.

  23. Codeforest says:

    I think I finally discovered the best development tutorial site ever.

    Nice work, nice demos, nice tutorials. Keep up the good work

  24. Telma says:

    Thank you very much ..I really need this working in my wordpress posts. ;)

    1. Martin Angelov says:

      You'd need to modify your sidebar.php and include it. This is actually the same code that I use for this site's followers count at the top right.

      1. Laurent says:

        Hi Martin, Can you explain quickly with part of the code we need to use to put in the sidebar.php, i'm really interested in it !
        Thanks

  25. go6obg says:

    great! i've found the site 2 months ago, and it's very helpful ! Great stuff!

    p.s. Your name sounds familiar, if it is so - браво, супер добри уроци! само успех за напред :)

  26. Telma says:

    Thank you for your answer Martin...and there is any other way for this work to every single post that i create, I mean I need to count the number of twitter and likes in each post.

    Thank You very much for your attention

  27. Ozoneekiz says:

    thank for

    fix twiter script.

    many thank's.

    pd. my previous comment, which referred to this problem has disappeared.

  28. Cremsnit says:

    Hello, I have some problems with: includes/subscriber_stats.class.php on line 15 and 32, please help me and tell me what to do..

    When I have updates on Facebook, Twitter and RSS, I refresh the page, erase the cache.txt but this error appear every time!

  29. Dave says:

    This is fantastic, but slightly confusing for a PHP/jQuery newbie like me. What are the chances of offering this as a plugin/widget for WordPress? Would get tons of support and downloads.

    Best,

    Dave

  30. kuya says:

    there is an error when viewing facebook fans, but I fix it by replacing fan_count become "likes" in the file "includes / subscriber_stats.class.php"

    1. Lei says:

      there is an error when viewing facebook fans, but I fix it by replacing fan_count become “likes” in the file “includes / subscriber_stats.class.php”

  31. Nejc says:

    The Facebook count has stopped working... :(

    1. Martin Angelov says:

      Fixed!

      1. eikros says:

        the Twitter count is not working in the demo. can you update it?

  32. vrushank says:

    Thanx for always giving such nice tuts.

  33. Lei says:

    The Twitter count has stopped working.

    1. mrc says:

      twitter doesnt work :(

  34. Jonathan says:

    twitter is still not working. anyone have any luck w/this? is this thread still active at all?

  35. Jonathan says:

    line #26 of subscriber_stats.class.php uses:

    SELECT * FROM twitter.user.profile

    however the download for this tutorial uses:

    SELECT * FROM twitter.users WHERE id=\''.$arr['twitterName'].'\'';

    neither obviously work. also, the PHP function SPLIT() is deprecated

  36. Jonathan says:

    I now have this working but using completely different code. Visit these links for reference:

    [link]http://www.xpertdeveloper.com/2012/01/get-twitter-follower-count-with-php/[/link]
    [link]http://www.xpertdeveloper.com/2012/01/facebook-page-detail-using-graph-api-and-php/[/link]

    You can also message me @ [code]jonathan*at*jdusza*dot*com*[/code]

    1. eikros says:

      can you share with us?

      1. eikros says:

        twitter counter update (as Jonathan says):
        if($arr['twitterName']) {
        $url = "http://twitter.com/users/show/".$arr['twitterName'];
        $response = file_get_contents ( $url );
        $t_profile = new SimpleXMLElement ( $response );
        $twitter_count = $t_profile->followers_count;
        }
        then..
        $this->twitter = strval($twitter_count);

  37. Caroline says:

    Before I start do anything in WordPress, where is the first code supposed to be inserted and should it be inside php-tags?

  38. Jolanthe says:

    Would be great if it was possible to also add in coding for other subscription services, such as FeedBlitz.

  39. Ulra says:

    Great script. Said the feedburner api is closed...

  40. The Google Feedburner APIs are no longer available. Thank you for your interest.

  41. Thanks for useful tutorial
    But know is added new social media from google, google+
    How to add this to the php class ?

  42. zavera says:

    Really fabulous work!

Add Comment

Add a Reply

HTML is escaped automatically. Surround code blocks with <pre></pre> for readability.
Perks:   **bold**   __italics__   [some text](http://example.com) for links