Member Avatar

diafol

OK, as promised, here's an updated 'quick(!) and dirty' class for retrieving and setting data via the Daniweb API. It allows the extraction of data based around:

DATA RETRIEVAL & SETTING

non-OAuth

  • forums
  • articles
  • posts
  • members
  • activity points
  • endorsements
  • reputation

OAuth (requires client_id and secret key)

  • who am i? (me - more data than from non-OAuth members)
  • articles (expansion of non-OAuth articles)
  • watched articles (watch and unwatch)
  • voting on posts (upvote and downvote)
  • PMs (currently inactive)

Direct URL retrieval

  • getLink

RSS

  • get data for RSS

This is in no way 'production'-standard code. It is intended for picking apart in order to build your own solutions, e.g. if you intend on using the API or entering the API contest. NB - there is very poor error checking / no exception handling.

Also check out pritaeas' class(es).

USAGE

non-OAuth

require 'dwapi.class.php';
$dw = new dwAPI;

echo $dw->getForums(); //echo json output of all forums
echo $dw->getForums(false,17) //echo data about the PHP (#17) forum
echo $dw->getList('http://www.daniweb.com/api/members/1/posts?filter=solved'); // get direct url data. NO CHECKS!

OAuth

//set $client_id and $client_secret
require 'dwapi.class.php';
$dw = new dwAPI($client_id, $client_secret);
echo $dw->getMe(); //get my data

RSS

require 'dwapi.class.php';
$dw = new dwAPI;

echo $dw->formatFeed($dw->getRSS(17),5); //echo first 5 links from PHP (#17) 

Hope it helps. Oh, and as always, please feel free to point out errors, improvements and any daft implementations. diafol :)

commented: This is Nice! +11
commented: Nice. +14
<?php
/**
  * This is the all-purpose dwAPI Class for accessing Daniweb API data.
  *
  * The dwAPI class is presented as an example of how to interact with
  * the Daniweb API Data as can be found at 
  * http://www.daniweb.com/api/documentation
  * 
  * It should allow access to non-OAuth data without need for
  * modification. 
  *
  * Operations for OAuth data may require a client id and 
  * a client secret key. These can be sought at 
  * http://www.daniweb.com/api/applications
  * 
  * @author  Alan Davies <ardavies@tiscali.co.uk>
  * @version 1.0.1 
  */

class dwAPI{

	private $conn = false;
	private $url;
	private $connFGC = false;
	private $connCURL = false;
	private $connType;
	
	//OAuth
	public $access_token;
	private $client_id = false;
	private $client_secret = false;


/**
  * Simple constructor to test for retrieval method (curl and file_get_contents)
  * It can also optionally set client id / secret key for OAuth calls
  * 
  * @param int	$client_id		Optional. YOUR Daniweb Client ID
  * @param str	$client_secret	Optional. YOUR Daniweb Secret Key
  */
	public function __construct($client_id=false, $client_secret=false)
	{
		if($client_id) $this->client_id = $client_id;
		if($client_secret) $this->client_secret = $client_secret;
		$this->connFGC = ini_get('allow_url_fopen');
		$this->connCURL = extension_loaded('curl');
		if(!$this->connFGC && !$this->connCURL){
			echo 	"<h3>dwAPI: NO RETRIEVAL METHOD AVAILABLE:</h3>
					<p>file_get_contents() is disabled and cURL is not loaded.</p>";
			exit;	
		}else{
			$this->connType = ($this->connCURL) ? 'curl' : 'file'; 	
		}
		if($client_id && $client_secret)$this->connect();
	}



/**
  * Route all requests through this to get JSON data
  *
  * @return str Returns the JSON string.
  */
	private function returnData()
	{
		if(!$this->conn) $this->setConn();
		//echo $this->url;
		return $this->conn->getJSON($this->url);	
	}



/**
  * Method to manually set the data retrieval method
  *
  * @param str 	$connectionType 	Set to file|curl 
  */
	public function setConnectionType($connectionType){
		if(strtolower($connectionType) == 'file' && $this->connFGC) $this->connType = 'file';
		if(strtolower($connectionType) == 'curl' && $this->connCURL) $this->connType = 'curl';
		$this->setConn();
	}
	
	
	
/**
  * Method to instatiate the retrieval method
  * Just sets the $conn
  */
	private function setConn(){
		$this->conn = ($this->connType == 'curl') ? new dwCurlGet : new dwFileGet;	
	}



/**
  * Method for validating/converting data to /{:IDS} format
  * This data should be in '/1;2;5' or '/5' format
  * N.B. This is pretty poor and could/should be improved
  *
  * @param mixed[] 	array|int|str 	$val 		
  *
  * @return str Returns the correct format for the /{:IDS}.
  */
	private function idsConvert($val)
	{
		if(is_array($val)){
			foreach($val as $item){
				if(!is_int($item)){
					echo "<h3>dwAPI: BAD IDS ARRAY</h3><p>Non integer value detected in array: $item.</p>";
					exit;	
				}
			}
			$out = implode(";", $val);	
		}elseif(is_int($val)){
			$out = $val;
		}else{
			if(preg_match('/[^\d;]/',$val)){
				echo "<h3>dwAPI: BAD IDS STRING</h3><p>Separate <strong>integers</strong> with <strong>semi-colons</strong>. No spaces or any other characters.</p>";
				exit;
			}else{
				$out = $val;	
			}
		}
		return '/' . $out;		
	}


	
/**
  * Method to query the API for forums data,
  * e.g. 
  * http://www.daniweb.com/api/forums
  * http://www.daniweb.com/api/forums/children?include_self=
  * http://www.daniweb.com/api/forums/descendants?include_self=
  * http://www.daniweb.com/api/forums/{:IDS}
  * http://www.daniweb.com/api/forums/{:IDS}/ancestors?include_self=
  * http://www.daniweb.com/api/forums/{:IDS}/children?include_self=
  * http://www.daniweb.com/api/forums/{:IDS}/descendants?include_self=
  *
  * Querystring parameters: include_self
  
  * @param bool 					$self 		Optional. Can be true|false 
  * @param mixed[] 	array|int|str 	$ids 		Optional.
  * @param str 						$related 	Optional. Can be one of ancestors|children|descendants
  *
  * @return str Returns the JSON string via returnData method.
  */
	public function getForums($self=false, $ids=false, $related=false)
	{
		$incSelf = ($self) ? '?include_self=' : '';
		$url1 = '';
		$incRelated = ($related && in_array($related, array("ancestors","children","descendants"))) ? '/' . $related : ''; 
		if($ids)
		{
			if($ids){
				if($cleanIDS = $this->idsConvert($ids)){
					$url1 .= $cleanIDS;
				}
			}
		}
		$this->url = 'http://www.daniweb.com/api/forums' . $url1 . $incRelated . $incSelf;
		return $this->returnData();
	}

	
	
/**
  * Method to query the API for article data,
  * e.g. 
  * http://www.daniweb.com/api/articles
  * http://www.daniweb.com/api/articles/{:IDS}
  * http://www.daniweb.com/api/forums/{:IDS}/articles
  * http://www.daniweb.com/api/members/{:IDS}/articles?forum_id=
  * Querystring parameters: filter, orderby, page, forum_id
  * recommeded|viewed|watching filter param values are OAuth-only
  *
  * @param str $type Optional. Can be articles|forums|members 
  * @param mixed[] array|int|str $ids Optional. Can be multiple or single ID - see above
  * @param str $filter Optional. Can be one of unanswered|solved|threads|news|reviews|interviews|tutorials|code|whitepapers|recommeded|viewed|watching
  * @param str $order Optional. Can be one of firstpost|lastpost
  * @param int $page Optional. This is the page#
  * @param int $forum Optional. This is the forum id#
  *
  * @return str Returns the JSON string via returnData method.
  */
    public function getArticles($type=false,$ids=false,$filter=false,$order=false,$page=false,$forum=false)
	{
		$url1 = '/articles';
		$endType = '';
		switch($type)
		{
			case false:
			case 'articles':
				if($ids){
					if($cleanIDS = $this->idsConvert($ids)){
						$url1 .= $cleanIDS;
					}
				}
				break;
			case 'forums':
			case 'members':
				$url1 = '/'. $type;
				$endType = '/articles';
				if($ids && is_int($ids)){
					 $url1 .= '/' . $ids;
				}else{
					echo "<h3>dwAPI: INVALID ID</h3><p>The id has to be an integer. ID given: $ids</p>";
					exit;	
				}
				break;			
		}
		$qs = array();
		if($filter && in_array($filter, array('unanswered','solved','threads','news','reviews','interviews','tutorials','code','whitepapers','recommended'
,'viewed','watching'))) $qs[] = 'filter=' . $filter;
		if($order && in_array($order, array('firstpost','lastpost'))) $qs[] = 'orderby=' . $order;
		if($page && is_int($page)) $qs[] = 'page=' . $page;
		if($forum && is_int($forum)) $qs[] = 'forum_id=' . $forum;
		$qString = (!empty($qs)) ? '?' . implode('&',$qs) : '';
		$this->url = 'http://www.daniweb.com/api' . $url1 . $endType . $qString;
		//OAuth Request
		if(in_array($filter, array('recommended','viewed','watching'))){
			if (isset($this->access_token)) 
			{ 
				$this->url .= "&access_token={$this->access_token}";
				return $this->returnData();
			}else{
				return $this->returnOAuthRequired();	
			}
		//Normal non-OAuth request	
		}else{
			return $this->returnData();
		}
	}	



/**
  * Method to query the API for posts data,
  * e.g. 
  * http://www.daniweb.com/api/posts
  * http://www.daniweb.com/api/posts/{:IDS}
  * http://www.daniweb.com/api/articles/{:ID}/posts
  * http://www.daniweb.com/api/forums/{:ID}/posts
  * http://www.daniweb.com/api/members/{:ID}/posts?filter=
  *
  * @param str $type Optional. Can be posts|articles|forums|members 
  * @param mixed[] array|int|str $ids Optional. Can be multiple or single ID - see above
  * @param str $filter Optional. Can be one of solved|upvoted|downvoted
  * @param int $page Optional. This is the page#
  *
  * @return str Returns the JSON string via returnData method.
  */
	public function getPosts($type=false,$ids=false,$filter=false,$page=false)
	{
		$url1 = '/posts';
		$endType = '';
		
		switch($type)
		{
			case false:
			case 'posts':
				if($ids){
					if($cleanIDS = $this->idsConvert($ids)){
						$url1 .= $cleanIDS;
					}
				}
				break;
			case 'articles':
			case 'forums':
			case 'members':
				$url1 = '/'. $type;
				$endType = '/posts';
				if($ids && is_int($ids)){
					 $url1 .= '/' . $ids;
				}else{
					echo "<h3>dwAPI: INVALID ID</h3><p>The id has to be an integer. ID given: $ids</p>";
					exit;	
				}
				break;			
		}
		$qs = array();
		if($filter && in_array($filter, array('solved','upvoted','downvoted'))) $qs[] = 'filter=' . $filter;
		if($page && is_int($page)) $qs[] = 'page=' . $page;
		$qString = (!empty($qs)) ? '?' . implode('&',$qs) : '';
		$this->url = 'http://www.daniweb.com/api' . $url1 . $endType . $qString;
		return $this->returnData();
	}



/**
  * Method to query the API for member data,
  * e.g. 
  * http://www.daniweb.com/api/members?username=
  * http://www.daniweb.com/api/members?page=
  * http://www.daniweb.com/api/members/{:IDS}?page=
  *
  * @param mixed[] array|int|str $member_ids Optional. Member#s 
  * @param str $username Optional. This is a valid username
  * @param int $page Optional. This is the page#
  *
  * @return str Returns the JSON string via returnData method.
  */
	public function getMembers($member_ids=false,$username=false,$page=false)
	{
		$url1 = '/members';
		if($member_ids){
			if($cleanIDS = $this->idsConvert($member_ids)){
				$url1 .= $cleanIDS;
			}
		}
		
		$qs ='';
		if($page && is_int($page)) $qs = '?page=' . $page;
		if($username) $qs = '?username=' . $username;
		$this->url = 'http://www.daniweb.com/api' . $url1 . $qs;
		return $this->returnData();
	}



/**
  * Method to query the API for endorsement data,
  * e.g. 
  * http://www.daniweb.com/api/members/{:ID}/endorsements
  *
  * @param int $member_id 	This is the member#
  *
  * @return str Returns the JSON string via returnData method.
  */
	public function getEndorsements($member_id)
	{
		if($member_id && is_int($member_id)){
			 $url1 = '/' . $member_id . '/endorsements';
		}else{
			echo "<h3>dwAPI: INVALID ID</h3><p>The id has to be an integer. ID given: $specify</p>";
			exit;	
		}
		$this->url = 'http://www.daniweb.com/api/members' . $url1;
		return $this->returnData();
	}



/**
  * Method to query the API for activity points data,
  * e.g. 
  * http://www.daniweb.com/api/members/{:ID}/activities
  *
  * @param int $member_id 	This is the member#
  *
  * @return str Returns the JSON string via returnData method.
  */
	public function getActivities($member_id)
	{
		if($member_id && is_int($member_id)){
			 $url1 = '/' . $member_id . '/activities';
		}else{
			echo "<h3>dwAPI: INVALID ID</h3><p>The id has to be an integer. ID given: $specify</p>";
			exit;	
		}
		$this->url = 'http://www.daniweb.com/api/members' . $url1;
		return $this->returnData();
	}



/**
  * Method to query the API for reputation data,
  * e.g. 
  * http://www.daniweb.com/api/posts/{:ID}/comments
  * http://www.daniweb.com/api/members/{:ID}/comments?page=
  *
  * @param str $type 	This can be 'members' or 'posts'
  *	@param int $id 		This refers to the id of the member# or the post#
  * @param int $page	Optional. Refers to page#
  *
  * @return str Returns the JSON string via returnData method.
  */
	public function getReputation($type, $id, $page=false)
	{
		if(in_array($type, array("members","posts")) && is_int($id)){
			 $url1 = '/' . $type . '/' . $id . '/comments';
			 if($page && is_int($page)) $url .= '?page=' . $page;
		}else{
			echo "<h3>dwAPI: INVALID PARAMETERS</h3><p>The type has to be either 'members' or 'posts' and the id has to be an integer. TYPE given: $type and ID given: $id</p>";
			exit;	
		}
		$this->url = 'http://www.daniweb.com/api' . $url1;
		return $this->returnData();
	}



/**
  * Shortcut method to query the API with a direct url,
  * e.g. http://www.daniweb.com/api/members/1/posts?filter=solved
  *
  * @param str $url URL string.
  *
  * @return str Returns the JSON string via returnData method.
  */
	public function getList($url)
	{
		$this->url = $url;
		return $this->returnData();
	}



/**
  * Method to manually apply connection details for OAuth calls,
  *	
  * @param int $client_id 		YOUR client id number.
  * @param str $client_secret 	YOUR secret key.
  */
	public function addConnectionDetails($client_id, $client_secret)
	{
		$this->client_id = $client_id;
		$this->client_secret = $client_secret;
		$this->connect();
	}



/**
  * Method to connect to Daniweb for OAuth calls. This is primarily the
  * code found on the Daniweb API page (not mine!)
  */
	private function connect()
	{
		if(!$this->client_id || !$this->client_secret){
			echo 	"<h3>dwAPI: CLIENT ID and CLIENT SECRET REQUIRED:</h3>
					<p>You tried to connect without full client credentials.</p>";
			exit;
		}
		
		$current_url = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'];
		if (isset($_REQUEST['access_token']) AND $access_token = $_REQUEST['access_token']) 
		{ 
			$this->access_token = $access_token;		
			//echo file_get_contents("http://www.daniweb.com/api/me/outbox?access_token={$access_token}",true);
		}
		else
		{
			// Send your website visitor to our authorization page along with a way to get back
			if (!isset($_REQUEST['code']))
			{
				header("Location: http://www.daniweb.com/api/oauth?client_id={$this->client_id}&redirect_uri=".urlencode($current_url));
			}
			
			// Upon authorizing your access, they will be redirected to your redirect_uri
			//	and Code will be passed along as a query string parameter
			
			// Initialize cURL to send a POST request
			$ch = curl_init('http://www.daniweb.com/api/access_token');
			curl_setopt($ch, CURLOPT_RETURNTRANSFER, false);
			curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
			curl_setopt($ch, CURLOPT_POST, true);
			
			// Use the Code to acquire a temporary Access Token
			//	to use for the current session
			//	You can save the Code to retrieve a new Access Token
			//	when it expires (and invalidate the existing Access Token
			//	if it hasn't expired yet)
			curl_setopt($ch, CURLOPT_POSTFIELDS, array(
				'code' => $_REQUEST['code'],
				'redirect_uri' => $current_url,
				'client_id' => $this->client_id,
				'client_secret' => $this->client_secret
			));
			curl_exec($ch);
			curl_close($ch);
		}
	}

	
/**
  * Method get 'Who am I' details via OAuth,
  *	
  * @return str Returns the JSON string via returnData method.
  */
	public function returnOAuthRequired()
	{
		return "<h3>dwAPI: OAuth CREDENTIALS REQUIRED</h3><p>You need to pass your client_id and client secret key in order to get this data.</p>";
	}


	
/**
  * Method get 'Who am I' details via OAuth,
  *	
  * @return str Returns the JSON string via returnData method.
  */
	public function getMe()
	{
		if (isset($this->access_token)) 
		{ 
			$this->url = "http://www.daniweb.com/api/me?access_token={$this->access_token}";
			return $this->returnData();
		}else{
			return $this->returnOAuthRequired();	
		}
	}


	
/**
  * Method get PMs via OAuth,
  *	
  * @param str $folder PM folder name can be inbox|outbox
  *
  * @return str Returns the JSON string via returnData method.
  */
  
/*
For some reason the inbox/outbox doesn't seem to work
	public function getPMs($folder)
	{
		if (isset($this->access_token)) 
		{ 
			if(in_array($folder, array('inbox', 'outbox'))){ 		
				$this->url = "http://www.daniweb.com/api/$folder?access_token={$this->access_token}";
				return $this->returnData();
			}else{
				echo "<h3>dwAPI: PROVIDE A VALID PM FOLDER</h3><p>Use 'inbox' or 'outbox' as parameters</p>";
				exit;
			}
		}else{
			return $this->returnOAuthRequired();	
		}
	}
*/



/**
  * Method watch an article via OAuth,
  *	
  * @param int $article Article#
  *
  * @return str Returns the JSON string via returnData method.
  */
	public function watchArticle($article)
	{
		if (isset($this->access_token)) 
		{ 
			$this->url = "http://www.daniweb.com/api/articles/$article/watch?access_token={$this->access_token}";
			return $this->returnData();
		}else{
			return $this->returnOAuthRequired();	
		}
	}



/**
  * Method unwatch an article via OAuth,
  *	
  * @param int $article Article#
  *
  * @return str Returns the JSON string via returnData method.
  */
	public function unwatchArticle($article)
	{
		if (isset($this->access_token)) 
		{ 
			$this->url = "http://www.daniweb.com/api/articles/$article/watch?remove=true&access_token={$this->access_token}";
			return $this->returnData();
		}else{
			return $this->returnOAuthRequired();	
		}
	}



/**
  * Method upvote or downvote a post via OAuth,
  *	
  * @param int $post Post#
  * @param int $vote Default = 1 Optional, Upvote = 1, Downvote = -1
  *
  * @return str Returns the JSON string via returnData method.
  */
	public function votePost($post, $vote=1)
	{
		if (isset($this->access_token)) 
		{ 
			if(($vote == 1 || $vote == -1) && is_int($post)){
				$this->url = "http://www.daniweb.com/api/posts/$post/vote?vote=$vote&access_token={$this->access_token}";
				return $this->returnData();
			}
		}else{
			return $this->returnOAuthRequired();	
		}
	}



/**
  * Method get RSS data,
  * e.g.
  * http://www.daniweb.com/rss/pull/{FORUM ID #}
  * http://www.daniweb.com/rss/pull/{ARTICLE TYPE}
  * http://www.daniweb.com/rss/pull/{FORUM ID #}/{ARTICLE TYPE}	
  *
  * @param int $forum_id Optional, Provide forum_id# 
  * @param str article_type Optional, Can be one of unanswered|solved|news|reviews|interviews|tutorials|code|whitepapers
  *
  * @return str Returns the JSON string via returnData method.
  */
	public function getRSS($forum_id=false, $article_type=false)
	{
		$f_id = ($forum_id && is_int($forum_id)) ? '/' . $forum_id : '';
		$a_type = ($article_type && in_array($article_type, array('unanswered','solved','news','reviews','interviews','tutorials','code','whitepapers'))) ? '/' . $article_type : '';
		$this->url = "http://www.daniweb.com/rss/pull" . $f_id . $a_type;
		return $this->returnData();
	}



/**
  * Method getting formatted RSS data,
  *
  * @param str $feed Provide feed data
  * @param int $limit Optional, Limit number of links to return 
  *
  * @return str Returns a link list from the original feed data.
  */
	public function formatFeed($feed, $limit=false)
	{
		$output = '';
		$articles = new SimpleXMLElement($feed);
		$n = count($articles->channel->item);
		if($limit && is_int($limit) && $limit < $n) $n = $limit;
		for($i=0;$i<$n;$i++) {
			$article = $articles->channel->item[$i]; 
			$output .= '<a href="' . $article->link . '">' . $article->title . '</a><br />';
		}
		return $output;
	}


	
/**
  * Returns data as a PHP associative array.
  *
  * @param str $str JSON string.
  *
  * @return mixed[] Returns the associative array.
  */
  	public function json2Array($str)
	{
		return json_decode($str,true);	
	}

}



/**
  * iConn is a simple interface for data retrieval.
  *
  * iConn is for providing a consistent interface to data
  * retrieval via different methods, namely cURL and 
  * file_get_contents()
  *
  * @author  Alan Davies <ardavies@tiscali.co.uk>
  * @version 1.0.0 
  */
interface iConn{
	function getJSON($url);
}



/**
  * dwFileGet allows simple data retrieval via file_get_contents.
  *
  * dwFileGet provides a method of retrieving data. It
  * implements the iConn interface and currently has one method,
  * just to get json data from the api url  
  
  * @author  Alan Davies <ardavies@tiscali.co.uk>
  * @version 1.0.0 
  */
class dwFileGet implements iConn{
	public function getJSON($url){
		$result = false;
		if($content = file_get_contents($url))
		{
			$result = $content;	
		}
		return $result;	
	}
}



/**
  * dwCurlGet allows simple data retrieval via cURL.
  *
  * dwCurlGet provides a method of retrieving data. It
  * implements the iConn interface and currently has one method,
  * just to get json data from the api url  
  * Thanks to pritaeas for most of the code below from 
  * http://www.daniweb.com/web-development/php/code/451390/daniweb-api-rss-class
  *
  * @version 1.0.0 
  */
class dwCurlGet implements iConn{
	public function getJSON($url){
		$result = false;
		$ch = curl_init();
		if ($ch)
		{
			curl_setopt($ch, CURLOPT_URL, $url);
			curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
			$curl = curl_exec($ch);
			if ($curl)
			{
				$result = $curl;
			}
			curl_close($ch);
		}
		return $result;
	}
}
Member Avatar

LastMitch

I'll be making changes and posting back here with an ammended class asap.

This is nice! Thanks for sharing and updating the codes.