Fun with Digg’s API
Digg’s api was released about a week ago a while ago, and since that time, various flash projects have surfaced, probably due to that pesky contest. But I don’t have any flash experience, so PHP, here we come.
We’re going to make various tag clouds, a Reddit clone, Reddit/Better RSS feed, and a live diggs app.
Update - 05/09/07 - 3 PM - Stupid host seems to be having database issues. Great. I wish I could afford a dedicated, or I guess VPS, so I don’t have to put with this crap.
Update - 05/09/07 - 6 PM - It seems that it was a combination of their db sucking and the fact they got rid of some essential pear packages. WTF?
Update - 05/12/07 - 11 AM - Yup. They cut off my MySQL abilities. I can’t connect to any of my databases on xrho.com. This site is fine however. I guess inserting 100+ entries a minute might have annoyed them?
Update - 05/17/07 - 7 PM - The MySQL abilities are still cut off. Fucking netfirms. Also, it seems in one of my updates, it cut off the bottom, which also happened to include the download links. You can download a ZIP or Gzip of the files. Since I’m having problems with that, feel free to download them and run them on your own site. Let me know if you do so I can add the link.
Demos of most of the scripts are available here, and more specifically:
Due to the length of this post, I’m splitting it. I hate making people click through, but it’s long enough to constitute it.
Part A: The Setup
First, we need the Pear package, from http://bugs.joestump.net/code/Services_Digg/Services_Digg-0.0.2.tgz. You can install it using the Pear install command, but I just copied the folder into my directory.
We’re going to be using MySQL database, so create a new database and here is the table structure I used:
-- -- Table structure for table `diggslive` -- CREATE TABLE `diggslive` ( `digging_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, `story_id` INT(10) UNSIGNED NOT NULL, `id` INT(10) UNSIGNED NOT NULL, `username` VARCHAR(250) COLLATE latin1_general_ci NOT NULL, `TIME` INT(10) NOT NULL, `status` VARCHAR(45) COLLATE latin1_general_ci NOT NULL, PRIMARY KEY (`digging_id`), UNIQUE KEY `id` (`id`), KEY `username` (`username`), KEY `story_id` (`story_id`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci AUTO_INCREMENT=137897 ; -- -------------------------------------------------------- -- -- Table structure for table `diggstories` -- CREATE TABLE `diggstories` ( `digg_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, `title` TEXT character SET latin1 COLLATE latin1_general_ci NOT NULL, `description` TEXT character SET latin1 COLLATE latin1_general_ci NOT NULL, `diggs` INT(5) NOT NULL, `comments` INT(4) NOT NULL, `id` INT(10) UNSIGNED NOT NULL, `link` VARCHAR(1000) character SET latin1 COLLATE latin1_general_ci NOT NULL, `submitted` INT(10) NOT NULL, `promoted` INT(10) NOT NULL, `href` VARCHAR(1000) character SET latin1 COLLATE latin1_general_ci NOT NULL, `status` VARCHAR(45) character SET latin1 COLLATE latin1_general_ci NOT NULL, `user_id` INT(10) UNSIGNED NOT NULL, `username` VARCHAR(250) character SET latin1 COLLATE latin1_general_ci NOT NULL, `icon` TEXT character SET latin1 COLLATE latin1_general_ci NOT NULL, `registered` INT(10) NOT NULL, `profileviews` INT(10) UNSIGNED NOT NULL, `topic_long` VARCHAR(100) character SET latin1 COLLATE latin1_general_ci NOT NULL, `topic_short` VARCHAR(100) character SET latin1 COLLATE latin1_general_ci NOT NULL, `container_long` VARCHAR(100) character SET latin1 COLLATE latin1_general_ci NOT NULL, `container_short` VARCHAR(100) character SET latin1 COLLATE latin1_general_ci NOT NULL, `host` VARCHAR(250) COLLATE utf8_bin DEFAULT NULL, PRIMARY KEY (`digg_id`), UNIQUE KEY `href` (`href`), FULLTEXT KEY `title` (`title`), FULLTEXT KEY `description` (`description`), FULLTEXT KEY `title_2` (`title`,`description`), FULLTEXT KEY `link` (`link`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=3818 ; -- -------------------------------------------------------- -- -- Table structure for table `diggusers` -- CREATE TABLE `diggusers` ( `user_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, `username` VARCHAR(250) COLLATE latin1_general_ci NOT NULL, `icon` TEXT COLLATE latin1_general_ci, `registered` INT(10) NOT NULL, `profileviews` INT(10) UNSIGNED NOT NULL DEFAULT '0', PRIMARY KEY (`user_id`), UNIQUE KEY `username` (`username`), KEY `username_2` (`username`) ) ENGINE=INNODB DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci AUTO_INCREMENT=2550 ;
There are 3 tables. Table diggstories will store the all the info about the the popular stories that is given to us through the api. There are 3 FULLTEXT indecies to enable a better search as shown later.
Now for the config file. Edit as necessary for your setup:
config.php:
<?php $dbhost = "localhost"; $dbuser = "root"; $dbpass = ""; $dbname = "digg"; // Connect to DB, now! // Regular connection @mysql_connect($dbhost,$dbuser,$dbpass) or die("MySQL Connection error"); // Persistent conenction // @mysql_pconnect($dbhost,$dbuser,$dbpass) or deadlyerror("MySQL Connection error (persistent) "); @mysql_select_db($dbname) or die("Unable to select database"); ?>
Here are some functions that we’ll use later.
functions.php:
<?php function sqlquote($value) { if(get_magic_quotes_gpc()) { $value = stripslashes($value); } //check if this function exists if( function_exists("mysql_real_escape_string") ) { $value = mysql_real_escape_string($value); } //for PHP version < 4.3.0 use addslashes else { $value = addslashes($value); } return $value; } function dehtml($content) { $content = preg_replace("/&(?!(amp|[#0-9]+|lt|gt|quot|copy|nbsp);)/ix","&",$content); $content = str_replace(array(" ","­","‍","‌","‭","‮"),"",$content); //$content = preg_replace('/&(?![a-z0-9]+;)/i', '&', $content); return str_replace(array("<",">","'","""),array("<",">","'","""),$content); } function timeparse($time) { $since = time() - $time; if($since < 60) { return ($since == 1) ? "$since second ago" : "$since seconds ago"; } elseif($since < 3600) { $since = floor($since/60); return ($since == 1) ? "$since minute ago" : "$since minutes ago"; } elseif($since < 86400) { $since = floor($since/3600); return ($since == 1) ? "$since hour ago" : "$since hours ago"; } else { $since = floor($since/86400); return ($since == 1) ? "$since day ago" : "$since days ago"; } } function toshort($text) { return strtolower(str_replace(" ","_",$text)); } function host($url) { $exploded = explode("/",$url); return str_replace("www.","",$exploded[2]); } ?>
Part B: Getting data
Getting the stories
First off, let’s populate our database with stories. This will take as many stories as possible and inserts them into out `diggstories` table. We are also going to insert our user info that it finds.
insert.php:
<?php ini_set('user_agent', 'Trendds/1.0'); ini_set('max_execution_time', 3600); require 'config.php'; include 'functions.php'; require_once 'Services/Digg.php'; Services_Digg::$appKey = 'http://www.nothingoutoftheordinary.com/Services_Digg_Proxy.php'; Services_Digg::$uri = 'http://services.digg.com'; $count = 3525; $offset = 0; while($offset<$count) { $params = array('count' => 100,'offset' => $offset); $request = Services_Digg::factory('Stories')->popular($params); foreach ($request->stories as $story) { $userinfo = mysql_query("SELECT `user_id`, `profileviews` FROM `diggusers` WHERE `username` = '".sqlquote($story->user->name)."' LIMIT 1"); if(mysql_numrows($userinfo) != 1) { mysql_query("INSERT INTO `diggusers` ( `user_id` , `username`, `icon`, `registered`, `profileviews` ) VALUES ( NULL, '".sqlquote($story->user->name)."', '".sqlquote($story->user->icon)."', '".sqlquote($story->user->registered)."', '".sqlquote($story->user->profileviews)."' ) ") or die("Inserting user: ".mysql_error()); $user_id = mysql_insert_id(); } else { $user_id = mysql_result($userinfo,0,"user_id"); } mysql_query("INSERT INTO `diggstories` ( `digg_id`, `title`, `description`, `diggs`, `comments`, `id`, `link`, `submitted`, `promoted`, `href`, `status`, `user_id` , `username`, `icon`, `registered`, `profileviews`, `topic_long`, `topic_short`, `container_long`, `container_short`, `host` ) VALUES ( NULL, '".sqlquote($story->title)."', '".sqlquote($story->description)."', '".sqlquote($story->diggs)."', '".sqlquote($story->comments)."', '".sqlquote($story->id)."', '".sqlquote($story->link)."', '".sqlquote($story->submit_date)."', '".sqlquote($story->promote_date)."', '".sqlquote($story->href)."', '".sqlquote($story->status)."', '".sqlquote($user_id)."', '".sqlquote($story->user->name)."', '".sqlquote($story->user->icon)."', '".sqlquote($story->user->registered)."', '".sqlquote($story->user->profileviews)."', '".sqlquote($story->topic->name)."', '".sqlquote($story->topic->short_name)."', '".sqlquote($story->container->name)."', '".sqlquote($story->container->short_name)."', '".sqlquote(host($story->link))."' ) ") or mysql_query("UPDATE `diggstories` SET `diggs` = '".sqlquote($story->diggs)."', `comments` = '".sqlquote($story->comments)."' WHERE `id` = '".sqlquote($story->id)."' LIMIT 1 ") or die(mysql_error()); } echo "<br />".$offset; $offset += 100; $count = $request->total; } ?>
The first lines,
ini_set('user_agent', 'Trendds/1.0');
ini_set('max_execution_time', 3600);
set the User-Agent and increases the max execution time, since getting over 3000 stories takes some time, and setting a user agent is required.
Services_Digg::$appKey = 'http://www.nothingoutoftheordinary.com/Services_Digg_Proxy.php';
Services_Digg::$uri = 'http://services.digg.com';
set the api key and uri, as shown in the Pear tests.
Next, we start requesting and inserting the info. This runs through a while and for each loop inserting each story.
After running that, you should now have about a 3000 entry `diggstories` table along with a couple thousand entry `diggusers` table.
In order to keep these updated, we can run update.php every so often. I did 5 minutes, but that seems to be a bit overkill.
update.php:
<?php ini_set('user_agent', 'Trendds/1.0'); ini_set('max_execution_time', 3600); require 'config.php'; include 'functions.php'; require_once 'Services/Digg.php'; Services_Digg::$appKey = 'http://www.nothingoutoftheordinary.com/Services_Digg_Proxy.php'; Services_Digg::$uri = 'http://services.digg.com'; $params = array('count' => 100); $request = Services_Digg::factory('Stories')->popular($params); //print_r($request); //exit; foreach ($request->stories as $story) { $userinfo = mysql_query("SELECT `user_id`, `profileviews` FROM `diggusers` WHERE `username` = '".sqlquote($story->user->name)."' LIMIT 1"); if(mysql_numrows($userinfo) != 1) { mysql_query("INSERT INTO `diggusers` ( `user_id` , `username`, `icon`, `registered`, `profileviews` ) VALUES ( NULL, '".sqlquote($story->user->name)."', '".sqlquote($story->user->icon)."', '".sqlquote($story->user->registered)."', '".sqlquote($story->user->profileviews)."' ) ") or die("Inserting user: ".mysql_error()); $user_id = mysql_insert_id(); } else { $user_id = mysql_result($userinfo,0,"user_id"); } mysql_query("INSERT INTO `diggstories` ( `digg_id`, `title`, `description`, `diggs`, `comments`, `id`, `link`, `submitted`, `promoted`, `href`, `status`, `user_id` , `username`, `icon`, `registered`, `profileviews`, `topic_long`, `topic_short`, `container_long`, `container_short`, `host` ) VALUES ( NULL, '".sqlquote($story->title)."', '".sqlquote($story->description)."', '".sqlquote($story->diggs)."', '".sqlquote($story->comments)."', '".sqlquote($story->id)."', '".sqlquote($story->link)."', '".sqlquote($story->submit_date)."', '".sqlquote($story->promote_date)."', '".sqlquote($story->href)."', '".sqlquote($story->status)."', '".sqlquote($user_id)."', '".sqlquote($story->user->name)."', '".sqlquote($story->user->icon)."', '".sqlquote($story->user->registered)."', '".sqlquote($story->user->profileviews)."', '".sqlquote($story->topic->name)."', '".sqlquote($story->topic->short_name)."', '".sqlquote($story->container->name)."', '".sqlquote($story->container->short_name)."', '".sqlquote(host($story->link))."' ) ") or mysql_query("UPDATE `diggstories` SET `diggs` = '".sqlquote($story->diggs)."', `comments` = '".sqlquote($story->comments)."' WHERE `id` = '".sqlquote($story->id)."' LIMIT 1 ") or die(mysql_error()); } ?>
In order to not refresh or have a cron job (though if you plan on using this more, a cron job would be good), you can just run crondigg.py, or crondigg.pyw if you don’t want to see a window, to keep the database updated. You will need to edit value for url to point to the location of your update.php.
crondigg.py
#! /usr/bin/env python url = 'http://localhost/digg/update.php' wait = 300 import urllib,time while 1: try: print 'Requesting %s \r' % url, urllib.urlopen(url).read() print " " * (len(url)+12),'\r', count = 0 while count < wait: print 'Waiting %d seconds \r' % (wait-count), count+=1 time.sleep(1) except KeyboardInterrupt: import sys sys.exit(2)
Note: This python script was written on Windows, where it works fine. On linux however, it’s a different story. It still works, just the output doesn’t.
Gettings diggs
Next, we’re going to get individual diggs. We’re not going to go back in time and get as many diggs as possible. The database will get really big pretty quickly, so don’t worry about it.
updatediggs.php:
<?php ini_set('user_agent', 'Trendds/1.0'); ini_set('max_execution_time', 3600); require 'config.php'; include 'functions.php'; require_once 'Services/Digg.php'; Services_Digg::$appKey = 'http://www.nothingoutoftheordinary.com/Services_Digg_Proxy.php'; Services_Digg::$uri = 'http://services.digg.com'; $api = Services_Digg::factory('Stories'); // To keep track of the current timestamp. This could just be mysql_result(mysql_query("SELECT `time` FROM `diggslive` ORDER BY `time` DESC LIMIT 1"),0,"time") but a txt file is easier. //$mindate = file_get_contents('lastdiggs.txt')-1; $mindate = mysql_result(mysql_query("SELECT `time` FROM `diggslive` ORDER BY `time` DESC LIMIT 1"),0,"time")-1 ; //$mindate = time() - 3600; $offset = 0; $total = 1; $runs = 0; // Get as many diggs as possible since the last update while ($offset < $total) { $params = array('count' => 100,'min_date' => $mindate,'offset'=>$offset); $diggs = $api->diggs($params); // Go through each digg //print_r($diggs); foreach ($diggs->diggs as $digg) { // This is pretty annoying. It's true if the insert failed. It might not be the most sensible thing, but it's about 2 in the morning, and I like it $inserted = false; // Insert the digg mysql_query("INSERT INTO `diggslive` (`digging_id`, `story_id`, `id`, `username`, `time`, `status`) VALUES ( NULL, '".sqlquote($digg->story)."', '".sqlquote($digg->id)."', '".sqlquote($digg->user)."', '".sqlquote($digg->date)."', '".sqlquote($digg->status)."' )") or setcheck(true); if(!$inserted) { // Increase the digg count of the story, since it just got dugg mysql_query("UPDATE `diggstories` SET `diggs` = `diggs`+1 WHERE `id` = '".sqlquote($digg->id)."' LIMIT 1") or die(mysql_error()); } } // If this is the first run, update the timestamp. We could use time(), but it might be slightly off. If we take the timestamp of a later run, it'll be later than what we got back. if($runs == 0 AND $diggs->timestamp != "") { $timestamp = $diggs->timestamp; $runs = 1; } $total = $diggs->total; print $offset."<br />"; $offset += 100; } // If the timestamp isn't foobared, update the file. If there are network problems or something, this can be wrong. I don't think I've still truely fixed that, but whatever. if(isset($timestamp) AND $timestamp != "" AND is_numeric($timestamp) AND $timestamp > 1000000) { $file = fopen('lastdiggs.txt','w'); fwrite($file,$timestamp); fclose($file); } // This will change the variable to say if it inserted successfully or not, because doing ... or $inserted = true; doesn't work. -_- function setcheck($bool) { global $inserted; $inserted = $bool; } ?>
Before you can use this, you need to insert some digg or something into `diggslive` with `time` set to the current timestamp. After another digg gets inserted, you can get rid of this entry.
This just gets the diggs of all the stories since the last digg we got. The timestamp is one less than the time of the last digg. This is to make sure we got the diggs that occureed at the same second as the previous one.
This also edits a file called lastdigg.txt, which is just an alternative to the sql query.
As I said earlier, the table gets big. Mine was at around 330k entries before I started running deletes. Let’s get rid of any diggs older than a day. We don’t really need them.
removediggs.p:
<?php require 'config.php'; $query = "DELETE FROM `diggslive` WHERE `time` < ".(time() - 24*60*60).""; mysql_query($query)or die(mysql_error()); mysql_query("OPTIMIZE TABLE `diggslive` ") or die(mysql_error()); ?>
To keep this updated, you can run crondiggs.py. This requests your updatediggs.php file every 30 seconds.
crondiggs.py
#! /usr/bin/env python url = 'http://localhost/digg/updatediggs.php' url2 = 'http://localhost/digg/removediggs.php' wait = 30 import urllib,time while 1: try: print 'Requesting %s \r' % url, urllib.urlopen(url).read() if int(time.time()) % 10 == 0: print 'Requesting %s \r' % url2, urllib.urlopen(url2).read() print " " * (len(url)+12),'\r', count = 0 while count < wait: print 'Waiting %d seconds \r' % (wait-count), count+=1 time.sleep(1) except KeyboardInterrupt: import sys sys.exit(2)
Part Gamma: Tag Clouds
Now it’s time to use all this new fangled data we’re collecting, and what’s more Web 2.0 than tag clouds? And since we’re lazy, we’re going to use this tag cloud script.
First cloud set, the container cloud set. The containers are the main topics, like Technology, Science, Sports, etc.
concloud.php:
<?php // most from: http://prism-perfect.net/archive/php-tag-cloud-tutorial/ // connect to database at some point // In the SQL below, change these three things: // thing is the column name that you are making a tag cloud for // id is the primary key // my_table is the name of the database table require 'config.php'; $query = "SELECT container_long AS tag, COUNT(digg_id) AS quantity, container_short FROM diggstories GROUP BY container_long ORDER BY container_long ASC"; $result = mysql_query($query); // here we loop through the results and put them into a simple array: // $tag['thing1'] = 12; // $tag['thing2'] = 25; // etc. so we can use all the nifty array functions // to calculate the font-size of each tag while ($row = mysql_fetch_array($result)) { $shortname[$row['tag']] = $row['container_short']; $tags[$row['tag']] = $row['quantity']; } // change these font sizes if you will $max_size = 250; // max font size in % $min_size = 100; // min font size in % // get the largest and smallest array values $max_qty = max(array_values($tags)); $min_qty = min(array_values($tags)); // find the range of values $spread = $max_qty - $min_qty; if (0 == $spread) { // we don't want to divide by zero $spread = 1; } // determine the font-size increment // this is the increase per tag quantity (times used) $step = ($max_size - $min_size)/($spread); // loop through our tag array foreach ($tags as $key => $value) { // calculate CSS font-size // find the $value in excess of $min_qty // multiply by the font-size increment ($size) // and add the $min_size set above $size = $min_size + (($value - $min_qty) * $step); // uncomment if you want sizes in whole %: // $size = ceil($size); // you'll need to put the link destination in place of the # // (assuming your tag links to some sort of details page) echo '<a href="'.$shortname[$key].'" style="font-size: '.$size.'%"'; // perhaps adjust this title attribute for the things that are tagged echo ' title="'.$value.' things tagged with '.$key.'"'; echo '>'.$key.'</a> '; // notice the space at the end of the link } ?>
That’s pretty boring though. Maybe regular categories, like Apple, Linux/Unix, Playable Web Games, etc, will be more interesting.
catcloud.php
<?php // most from: http://prism-perfect.net/archive/php-tag-cloud-tutorial/ // connect to database at some point // In the SQL below, change these three things: // thing is the column name that you are making a tag cloud for // id is the primary key // my_table is the name of the database table require 'config.php'; require 'functions.php'; $query = "SELECT topic_long AS tag, COUNT(digg_id) AS quantity, topic_short FROM diggstories GROUP BY topic_long ORDER BY topic_long ASC"; $result = mysql_query($query); // here we loop through the results and put them into a simple array: // $tag['thing1'] = 12; // $tag['thing2'] = 25; // etc. so we can use all the nifty array functions // to calculate the font-size of each tag while ($row = mysql_fetch_array($result)) { $shortname[$row['tag']] = $row['topic_short']; $tags[$row['tag']] = $row['quantity']; } // change these font sizes if you will $max_size = 250; // max font size in % $min_size = 100; // min font size in % // get the largest and smallest array values $max_qty = max(array_values($tags)); $min_qty = min(array_values($tags)); // find the range of values $spread = $max_qty - $min_qty; if (0 == $spread) { // we don't want to divide by zero $spread = 1; } // determine the font-size increment // this is the increase per tag quantity (times used) $step = ($max_size - $min_size)/($spread); // loop through our tag array foreach ($tags as $key => $value) { // calculate CSS font-size // find the $value in excess of $min_qty // multiply by the font-size increment ($size) // and add the $min_size set above $size = $min_size + (($value - $min_qty) * $step); // uncomment if you want sizes in whole %: // $size = ceil($size); // you'll need to put the link destination in place of the # // (assuming your tag links to some sort of details page) echo '<a href="http://digg.com/'.$shortname[$key].'" style="font-size: '.$size.'%"'; // perhaps adjust this title attribute for the things that are tagged echo ' title="'.$value.' things tagged with '.$key.'"'; echo '>'.$key.'</a> '; // notice the space at the end of the link } ?>
A little better. How about a user cloud based on submissions?
usercloud.php:
<?php // most from: http://prism-perfect.net/archive/php-tag-cloud-tutorial/ // connect to database at some point // In the SQL below, change these three things: // thing is the column name that you are making a tag cloud for // id is the primary key // my_table is the name of the database table require 'config.php'; $query = "SELECT username AS tag, COUNT(digg_id) AS quantity FROM diggstories GROUP BY username ORDER BY username ASC"; $result = mysql_query($query); // here we loop through the results and put them into a simple array: // $tag['thing1'] = 12; // $tag['thing2'] = 25; // etc. so we can use all the nifty array functions // to calculate the font-size of each tag while ($row = mysql_fetch_array($result)) { //$shortname[$row['tag']] = $row['container_short']; $tags[$row['tag']] = $row['quantity']; } // change these font sizes if you will $max_size = 250; // max font size in % $min_size = 100; // min font size in % // get the largest and smallest array values $max_qty = max(array_values($tags)); $min_qty = min(array_values($tags)); // find the range of values $spread = $max_qty - $min_qty; if (0 == $spread) { // we don't want to divide by zero $spread = 1; } // determine the font-size increment // this is the increase per tag quantity (times used) $step = ($max_size - $min_size)/($spread); // loop through our tag array foreach ($tags as $key => $value) { // calculate CSS font-size // find the $value in excess of $min_qty // multiply by the font-size increment ($size) // and add the $min_size set above $size = $min_size + (($value - $min_qty) * $step); // uncomment if you want sizes in whole %: // $size = ceil($size); // you'll need to put the link destination in place of the # // (assuming your tag links to some sort of details page) echo '<a href="http://digg.com/users/'.urlencode($key).'" style="font-size: '.$size.'%"'; // perhaps adjust this title attribute for the things that are tagged echo ' title="'.$value.' things tagged with '.$key.'"'; echo '>'.$key.'</a> '; // notice the space at the end of the link } ?>
Pretty big, but let’s try bigger. A user cloud based on number of diggs.
diggusercloud.php:
<?php // most from: http://prism-perfect.net/archive/php-tag-cloud-tutorial/ // connect to database at some point // In the SQL below, change these three things: // thing is the column name that you are making a tag cloud for // id is the primary key // my_table is the name of the database table require 'config.php'; $query = "SELECT username AS tag, COUNT(digging_id) AS quantity FROM diggslive GROUP BY username ORDER BY username ASC"; $result = mysql_query($query); // here we loop through the results and put them into a simple array: // $tag['thing1'] = 12; // $tag['thing2'] = 25; // etc. so we can use all the nifty array functions // to calculate the font-size of each tag while ($row = mysql_fetch_array($result)) { $href[$row['tag']] = $row['href']; $tags[$row['tag']] = $row['quantity']; } // change these font sizes if you will $max_size = 250; // max font size in % $min_size = 100; // min font size in % // get the largest and smallest array values $max_qty = max(array_values($tags)); $min_qty = min(array_values($tags)); // find the range of values $spread = $max_qty - $min_qty; if (0 == $spread) { // we don't want to divide by zero $spread = 1; } // determine the font-size increment // this is the increase per tag quantity (times used) $step = ($max_size - $min_size)/($spread); // loop through our tag array foreach ($tags as $key => $value) { // calculate CSS font-size // find the $value in excess of $min_qty // multiply by the font-size increment ($size) // and add the $min_size set above $size = $min_size + (($value - $min_qty) * $step); // uncomment if you want sizes in whole %: // $size = ceil($size); // you'll need to put the link destination in place of the # // (assuming your tag links to some sort of details page) echo '<a href="http://digg.com/users/'.$key.'" style="font-size: '.$size.'%"'; // perhaps adjust this title attribute for the things that are tagged echo ' title="'.$value.' things tagged with '.$key.'"'; echo '>'.$key.'</a> '; // notice the space at the end of the link } ?>
Great. How about a story cloud based on the number of diggs?
diggcloud.php:
<?php // most from: http://prism-perfect.net/archive/php-tag-cloud-tutorial/ // connect to database at some point // In the SQL below, change these three things: // thing is the column name that you are making a tag cloud for // id is the primary key // my_table is the name of the database table require 'config.php'; $query = "SELECT title AS tag, COUNT(digg_id) AS quantity, href FROM diggstories GROUP BY diggs ORDER BY diggs ASC"; $result = mysql_query($query); // here we loop through the results and put them into a simple array: // $tag['thing1'] = 12; // $tag['thing2'] = 25; // etc. so we can use all the nifty array functions // to calculate the font-size of each tag while ($row = mysql_fetch_array($result)) { $href[$row['tag']] = $row['href']; $tags[$row['tag']] = $row['quantity']; } // change these font sizes if you will $max_size = 250; // max font size in % $min_size = 100; // min font size in % // get the largest and smallest array values $max_qty = max(array_values($tags)); $min_qty = min(array_values($tags)); // find the range of values $spread = $max_qty - $min_qty; if (0 == $spread) { // we don't want to divide by zero $spread = 1; } // determine the font-size increment // this is the increase per tag quantity (times used) $step = ($max_size - $min_size)/($spread); // loop through our tag array foreach ($tags as $key => $value) { // calculate CSS font-size // find the $value in excess of $min_qty // multiply by the font-size increment ($size) // and add the $min_size set above $size = $min_size + (($value - $min_qty) * $step); // uncomment if you want sizes in whole %: // $size = ceil($size); // you'll need to put the link destination in place of the # // (assuming your tag links to some sort of details page) echo '<a href="'.$href[$key].'" style="font-size: '.$size.'%"'; // perhaps adjust this title attribute for the things that are tagged echo ' title="'.$value.' things tagged with '.$key.'"'; echo '>'.$key.'</a> '; // notice the space at the end of the link } ?>
But wait, that doesn’t look right. That’s because we can’t use basically the same SQL query as before. It’s grouping the stories by the amount of diggs, so that if there are 3 stories with 750 diggs, and only 1 story with 751 diggs, the 3 stories will be larger. Since the weight of the story is already set as an entry, we don’t need to group it, so we can just use this SQL query:
SELECT title AS tag, diggs, href FROM diggstories ORDER BY title ASC
<?php // most from: http://prism-perfect.net/archive/php-tag-cloud-tutorial/ // connect to database at some point





