content = new Content(&$this);
$this->user = new User(&$this);
$this->list = new Playlist(&$this);
$this->activity = new Activity(&$this);
}
}
class MagnifyXML{
// static utility class to get around SimpleXMLElement brain-damage
public static $ns;
public static function mapNS($simple){
self::$ns = $simple->getDocNamespaces();
}
public static function extractLinks(){
$args = func_get_args();
$simple = array_shift($args);
( $simple instanceof SimpleXMLElement ) or die;
$simple->registerXPathNameSpace('atom','http://www.w3.org/2005/Atom');
$links = array();
foreach($args as $rel){
$result = $simple->xpath("atom:link[@rel='$rel']/@href");
$links[] = $result ? (string) $result[0] : NULL;
}
return $links;
}
}
abstract class Resource {
protected $group,$parser,$dispatcher;
function __construct($dispatcher){
$this->dispatcher = $dispatcher;
$this->chain_construct();
}
abstract function chain_construct();
protected function fetch($resource, $param = array() ){
define('BASE_URL','/api/');
$url='http://'.CHANNEL.'.'.BASE_URL
.$this->group
.'/'
.$resource.'?'.http_build_query($param);
$headers = array(
"X-Magnify-Key: ".KEY
);
// We use cURL rather than libXML's builtin retrieval
// so that the key can be passed in the header
$session = curl_init($url);
curl_setopt($session,CURLOPT_RETURNTRANSFER,true);
curl_setopt($session,CURLOPT_HTTPHEADER, $headers);
$reply = curl_exec($session)
or die("Could not retrieve Magnify XML");
curl_close($session);
try{
$simple = @new SimpleXMLElement($reply);
} catch(Exception $e){
die("Could not parse Magnify XML");
}
MagnifyXML::mapNS($simple);
return $simple;
}
// universal resources
function show($id){
$simple = $this->fetch('show', array('id' => $id ) );
return call_user_func($this->parser,$simple->entry);
}
function browse($page = 1, $per_page = 10, $sort = 'recent'){
$simple = $this->fetch('browse', array( 'page' => $page, 'per_page' => $per_page, 'sort' => $sort ) );
return new Feed($simple, $this->parser);
}
function find($vq, $page = 1, $per_page = 10, $sort = 'recent'){
$simple = $this->fetch('find', array( 'page' => $page, 'per_page' => $per_page, 'vq' => $vq, sort => $sort ) );
return new Feed($simple, $this->parser);
}
}
class Content extends Resource {
function chain_construct(){
$this->group = 'content';
$this->parser = create_function(
'$entry',
'
$content_entry = new Content_Entry($entry);
return $content_entry;
'
);
}
function user($id, $page = 1, $per_page = 10){
$simple = $this->fetch('user', array( 'page' => $page, 'per_page' => $per_page, 'id' => $id) );
return new Feed($simple, $this->parser);
}
}
class User extends Resource {
function chain_construct(){
$this->group = 'user';
$this->parser = create_function(
'$entry',
'
$user_entry = new User_Entry($entry);
return $user_entry;
'
);
}
function browse(){
return NULL;
}
}
class Playlist extends Resource {
function chain_construct(){
$this->group = 'list';
$this->parser = create_function(
'$entry',
'
$list_entry = new Playlist_Entry($entry);
return $list_entry;
'
);
$this->show_parser = create_function(
'$entry',
'
$content_entry = new Content_Entry($entry);
return $content_entry;
'
);
}
function find(){
return NULL;
}
function user($id, $page = 1, $per_page = 10){
$simple = $this->fetch('user', array( 'page' => $page, 'per_page' => $per_page, 'id' => $id ) );
return new Feed($simple, $this->parser);
}
function show($id, $page = 1, $per_page = 10, $sort = 'recent'){
$simple = $this->fetch('show', array( 'page' => $page, 'per_page' => $per_page, 'id' => $id, 'sort' => $sort ) );
return new Feed($simple, $this->show_parser);
}
}
class Activity extends Resource {
function chain_construct(){
$this->group = 'activity';
$this->parser = create_function(
'$entry',
'
$activity_entry = new Activity_Entry($entry);
return $activity_entry;
'
);
}
function show(){
return NULL;
}
function find(){
return NULL;
}
function browse(){
return NULL;
}
function content($id, $page = 1, $per_page = 10){
$simple = $this->fetch('content',array( 'page' => $page, 'per_page' => $per_page, 'id' => $id ) );
return new Activity_Feed($simple, $this->parser);
}
}
class Feed implements Iterator {
public $title, $content, $updated;
public $totalResults, $itemsPerPage, $startIndex;
private $self, $alternate, $user;
public $entries = array();
private $valid = FALSE;
function rewind(){
$this->valid = (FALSE !== reset($this->entries));
}
function current(){
return current($this->entries);
}
function key(){
return key($this->entries);
}
function next(){
$this->valid = (FALSE !== next($this->entries));
}
function valid(){
return $this->valid;
}
function __construct($feed, $parser){
// normal Atom elements
$this->title = (string) $feed->title;
$this->content = (string) $feed->content;
$this->updated = (string) $feed->updated;
// opensearch elements
$opensearch = $feed->children( MagnifyXML::$ns['opensearch'] );
$this->totalResults = (string) $opensearch->totalResults;
$this->itemsPerPage = (string) $opensearch->itemsPerPage;
$this->startIndex = (string) $opensearch->startIndex;
// link elements
list($this->self, $this->next, $this->previous) = MagnifyXML::extractLinks($feed, 'self','next','previous');
foreach($feed->entry as $entry){
$this->entries[] = call_user_func($parser,$entry);
}
}
}
class Activity_Feed extends Feed {
// WARNING
// the individual activity feeds returned by Activity_Feed methods are intended only as
// convenient interfaces and still refer to entries in the parent feed
// destroying the original object will render them useless
private $clone_control = NULL;
function __clone(){
if($this->clone_control){
foreach($this->entries as $key => $entry){
if($this->clone_control != $entry->activity){
unset($this->entries[$key]);
}
}
unset($this->clone_control);
}
}
public function getComments(){
$this->clone_control = "comment";
$comments = clone $this;
return $comments;
}
public function getTags(){
$this->clone_control = "tagged";
$tags = clone $this;
return $tags;
}
public function getReviews(){
$this->clone_control = "review";
$reviews = clone $this;
return $reviews;
}
}
abstract class Entry {
public $id;
function __construct(){
}
function getId(){
return $this->id;
}
}
class Content_Entry extends Entry {
public $title, $content, $thumbnail, $author, $author_url, $author_id, $self, $alternate;
private $iframe_url;
function __construct($entry){
// normal Atom elements
$this->title = (string) $entry->title;
$this->content = (string) $entry->content;
$this->updated = (string) $entry->updated;
// magnify and media ns elements
$magnify = $entry->children( MagnifyXML::$ns['magnify'] );
$media = $entry->children( MagnifyXML::$ns['media'] );
$this->id = (string) $magnify->id;
$this->thumbnail = (string) $media->thumbnail->attributes()->url;
$this->iframe_url = (string) $media->content->attributes()->url;
// links
list($this->self, $this->user, $this->alternate) = MagnifyXML::extractLinks($entry, 'self','user','alternate');
// author construct
$this->author = (string) $entry->author->name;
$this->author_id = (string) $entry->author->children( MagnifyXML::$ns['magnify'] )->id;
$this->author_url = (string) $entry->author->uri;
}
function drawThumbnail($param = array() ){
$param{'width'} = isset($param{'width'}) ? $param{'width'} : 120;
$param{'height'} = isset($param{'height'}) ? $param{'height'} : $param{'width'} / 1.33;
return '
';
}
function drawIframe($param = array() ){
$param{'width'} = isset($param{'width'}) ? $param{'width'} : 320;
$param{'height'} = isset($param{'height'}) ? $param{'height'} : $param{'width'} * 1.1;
return '';
}
}
class Playlist_Entry extends Entry{
public $title, $updated, $author, $author_url, $author_id, $content, $thumbnail;
function __construct($entry){
$this->title = (string) $entry->title;
$this->content = (string) $entry->content;
$this->updated = (string) $entry->updated;
$magnify = $entry->children( MagnifyXML::$ns['magnify'] );
$media = $entry->children( MagnifyXML::$ns['media'] );
$opensearch = $entry->children( MagnifyXML::$ns['opensearch'] );
$this->id = (string) $magnify->id;
$this->thumbnail = (string) $media->thumbnail->attributes()->url;
$this->total = (string) $opensearch->totalResults;
$this->author = (string) $entry->author->name;
$this->author_id = (string) $entry->author->children( MagnifyXML::$ns['magnify'] )->id;
$this->author_url = (string) $entry->author->uri;
}
function drawThumbnail($param = array() ){
$param{'width'} = isset($param{'width'}) ? $param{'width'} : 120;
$param{'height'} = isset($param{'height'}) ? $param{'height'} : $param{'width'} / 1.33;
return '
';
}
}
class User_Entry extends Entry {
public $name, $handle, $photo, $self, $content, $list, $alternate;
function __construct($entry){
$this->name = (string) $entry->name;
$magnify = $entry->children( MagnifyXML::$ns['magnify'] );
$this->handle = (string) $magnify->handle;
$this->photo = (string) $magnify->photo;
$this->id = (string) $magnify->id;
}
function drawThumbnail($param = array() ){
$param{'width'} = isset($param{'width'}) ? $param{'width'} : 70;
$param{'height'} = isset($param{'height'}) ? $param{'height'} : $param{'width'};
return '
';
}
}
class Activity_Entry extends Entry {
public $author, $author_url, $author_id, $content, $activity, $tags, $rating, $updated;
function __construct($entry){
$this->activity = (string) $entry->children( MagnifyXML::$ns['magnify'] )->activity;
$this->updated = (string) $entry->updated;
$matches = array();
if($this->activity == 'review' && $entry->content && preg_match('/Rating: (\d+)\.(.+)/',$entry->content,&$matches)){
$this->rating = $matches[1];
$this->content = $matches[2];
}
else { $this->content = (string) $entry->content; }
if($this->activity == 'tagged' && $entry->children( MagnifyXML::$ns['media'] )->keywords){
$this->tags = explode(',', $entry->children( MagnifyXML::$ns['media'] )->keywords);
}
$this->author = (string) $entry->author->name;
$this->author_id = (string) $entry->author->children( MagnifyXML::$ns['magnify'] )->id;
$this->author_url = (string) $entry->author->uri;
}
}
?>