<?php
//VERSION 1.5
/* <!--/Creative Commons License-->
<!-- <rdf:RDF xmlns="http://web.resource.org/cc/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<Work rdf:about="">
<license rdf:resource="http://creativecommons.org/licenses/by/2.5/" />
<dc:title>makeSSPxml</dc:title>
<dc:date>2006</dc:date>
<dc:description>A PHP class designed to take data from Flickr as well as from SSP xml files and dynamically produce a SSP xml file.</dc:description>
<dc:creator><Agent><dc:title>Rory Jaffe</dc:title></Agent></dc:creator>
<dc:rights><Agent><dc:title>Rory Jaffe</dc:title></Agent></dc:rights>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/Text" />
<dc:source rdf:resource="http://thejaffes.org/" />
</Work>
<License rdf:about="http://creativecommons.org/licenses/by/2.5/"><permits rdf:resource="http://web.resource.org/cc/Reproduction"/><permits rdf:resource="http://web.resource.org/cc/Distribution"/><requires rdf:resource="http://web.resource.org/cc/Notice"/><requires rdf:resource="http://web.resource.org/cc/Attribution"/><permits rdf:resource="http://web.resource.org/cc/DerivativeWorks"/></License></rdf:RDF> --> */
class makeSSPxml {
//replace following string with your key. This is the only change needed to this file
const APIkey = '&api_key=PUT YOUR KEY HERE' ; # refer as self::APIkey
const RESTreq = 'http://www.flickr.com/services/rest/?method=' ; # self::RESTreq
//internal variables
protected $xmlLocation, $refreshNeeded, $fileLife;
protected $useCaption=true, $useThumb=true, $useLink=true, $isDebug=false, $haltOnError=true, $useAlbumThumb=true ;
protected $albumThumb ;
protected $xmlOutput="<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<gallery>\n";
protected $numImages=100;
protected $searchParms ;
protected function My_simplexml_load_file($URL) //this is needed if file access is disabled in your server configuration
{
$ch = curl_init($URL);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
$xml = simplexml_load_string(curl_exec($ch));
curl_close($ch);
return $xml;
}
//constructor
public function __construct($relpath, $lifetime) {
//requires PHP 5.0 or greater
if (version_compare(PHP_VERSION,'5.0.0','<')) {
die('Requires PHP 5.0.0 or greater') ;
}
$this->xmlLocation = $relpath ;
if (file_exists($this->xmlLocation)) {
$this->fileLife = filemtime($this->xmlLocation)+$lifetime-time() ;
if ($this->fileLife <= 0) {
$this->fileLife = $lifetime ;
$this->refreshNeeded = true ;
} else {
$this->refreshNeeded = false ;
}
} else {
$this->fileLife = $lifetime ;
$this->refreshNeeded = true ;
}
}
//turn on/off optional features (can save xml file size this way)
public function thumbs($yesorno) { $this->useThumb = $yesorno ; }
public function links($yesorno) { $this->useLink = $yesorno ; }
public function captions($yesorno) { $this->useCaption = $yesorno ; }
public function debug($yesorno) { $this->isDebug = $yesorno ; }
public function number($count) { $this->numImages = min($count,500) ; }
public function stop_if_error($yesorno) { $this->haltOnError = $yesorno ; }
public function album_thumbs($yesorno) {$this->useAlbumThumb = $yesorno ; }
public function set_thumb($url) {$this->albumThumb = $url ;}
//converts the Flickr xml to SSP xml
protected function make_album($photos,$title,$desc,$albthumb) {
$title = htmlspecialchars($title) ;
$desc = htmlspecialchars($desc) ;
$thumb = ($this->useAlbumThumb && !empty($albthumb)) ? "tn=\"$albthumb\" " : '' ;
$album = "\t<album title=\"$title\" description=\"$desc\" lgpath=\"http://static.flickr.com/\" $thumb>\n" ;
foreach ($photos as $single) {
$mainurl = $single['server'].'/'.$single['id'].'_'.$single['secret'] ;
$album .= "\t\t<img src=\"".$mainurl.'.jpg"' ;
if ($this->useThumb) $album .= ' tn="http://static.flickr.com/'.$mainurl.'_s.jpg"' ;
if ($this->useLink) $album .= ' link="http://static.flickr.com/'.$mainurl.'_b.jpg"' ;
if ($this->useCaption) {
$caption = htmlspecialchars($single['title']) ;
$album .= ' caption="'.$caption.'"' ;
}
$album .= " />\n" ;
}
$album .= "\t</album>\n" ;
return $album ;
}
//use following if want page to expire when cached xml file expires
public function emit_headers() {
header('Cache-Control: max-age='.$this->fileLife.', must-revalidate');
header('Expires: '.gmdate('D, d M Y H:i:s', time() + $this->fileLife).' GMT'); #date format string constant DATE_RFC1123 in PHP 5.1.1 and later
}
//called at end to save xml file
public function finish() {
if (!$this->refreshNeeded) return;
$this->xmlOutput .= '</gallery>' ;
$tmpname = tempnam(dirname($this->xmlLocation),'sspclass'); //just to be safe, will put it in final destination directory
file_put_contents($tmpname,$this->xmlOutput) ;
chmod($tmpname,0644) ;//tmpfile was 0600, won't display on web page
if (!rename($tmpname,$this->xmlLocation)) { //atomic operation, avoid race conditions, but may fail on WinXP server
copy($tmpname,$this->xmlLocation) ;//may be forced to do this on WinXP machine, not atomic
unlink($tmpname) ; //remove temp even if copy fails
}
}
//makes an album out of a particular user's favorites
public function add_favorites($user,$title='',$desc='') {
if (!$this->refreshNeeded) return;
if ($title=='' || $desc=='' || ($this->useAlbumThumb && empty($this->albumThumb))) {
$xml = $this->My_simplexml_load_file(self::RESTreq.'flickr.people.getInfo'.self::APIkey.'&user_id='.$user) ;
if ($xml!==false && (count($xml->xpath('./err')))==0) {
if ($title=='') $title = $xml->person->username ;
if ($desc=='') $desc = $xml->person->realname .', from '. $xml->person->location ;
if ($this->useAlbumThumb && empty($this->albumThumb)) $this->albumThumb = (empty($xml->person['iconserver'])) ? 'http://www.flickr.com/images/buddyicon.jpg' : "http://static.flickr.com/{$xml->person[iconserver]}/buddyicons/$user.jpg" ;
} else {
$this->error_handler($xml,__METHOD__.'(getInfo)') ;
}
}
$xml = $this->My_simplexml_load_file(self::RESTreq.'flickr.favorites.getPublicList'.self::APIkey.'&user_id='.$user.'&per_page='.$this->numImages) ;
if ($xml!==false && (count($xml->xpath('./err')))==0) {
$this->xmlOutput .= $this->make_album($xml->photos->photo,$title,$desc,$this->albumThumb) ;
} else {
$this->error_handler($xml,__METHOD__.'(getPublicList)') ;
}
$this->reset() ;
}
//adds interesting photos
public function add_interesting($title='Flickr interestingness photos',$desc='Most interesting photos from today') {
if (!$this->refreshNeeded) return;
$search = (empty($this->searchParms)) ? '' : ('&'.http_build_query($this->searchParms)) ;
if ($desc=='Most interesting photos from today' && !empty($this->searchParms['date'])) {
$desc = 'Most interesting photos from '.$this->searchParms['date'] ;
}
$xml = $this->My_simplexml_load_file(self::RESTreq.'flickr.interestingness.getList'.self::APIkey.'&per_page='.$this->numImages.$search) ;
if ($xml!==false && (count($xml->xpath('./err')))==0) {
$this->xmlOutput .= $this->make_album($xml->photos->photo,$title,$desc,$this->albumThumb) ;
} else {
$this->error_handler($xml,__METHOD__) ;
}
$this->reset() ;
}
public function add_photoset($setno) {
if (!$this->refreshNeeded) return;
$xml = $this->My_simplexml_load_file(self::RESTreq.'flickr.photosets.getInfo'.self::APIkey.'&photoset_id='.$setno) ;
if ($xml!==false && (count($xml->xpath('./err')))==0) {
$title = $xml->photoset->title ;
$desc = $xml->photoset->description ;
$numphotos = $xml->photoset['photos'] ;
$xml = $this->My_simplexml_load_file(self::RESTreq.'flickr.photosets.getPhotos'.self::APIkey.'&photoset_id='.$setno) ; //cannot specify number images in photosets
if ($xml!==false && (count($xml->xpath('./err')))==0) {
if ($this->useAlbumThumb && empty($this->albumThumb)) {
$selected = $xml->xpath('//photo[@isprimary="1"]');
if (!empty($selected[0])) {
$single = $selected[0];
$this->albumThumb = 'http://static.flickr.com/'.$single['server'].'/'.$single['id'].'_'.$single['secret'].'_s.jpg' ;
} //end if selected
} //end if useAlbumThumb
if ($numphotos > $this->numImages) {//need to cut down size of set
$i = 1 ;
foreach ($xml->photoset->photo as $individual) {
$limited_set[] = $individual ;
if (++$i > $this->numImages) break ;
}
$this->xmlOutput .= $this->make_album($limited_set,$title,$desc,$this->albumThumb);
} else { //don't need to reduce set size
$this->xmlOutput .= $this->make_album($xml->photoset->photo,$title,$desc,$this->albumThumb);
}
} else {
$this->error_handler($xml,__METHOD__.'(getPhotos)') ;
}
} else {
$this->error_handler($xml,__METHOD__.'(getInfo)') ;
}
$this->reset() ;
}
public function add_pool($pool,$title='',$desc='') {
if (!$this->refreshNeeded) return;
if ($title=='' || $desc=='') {
$xml = $this->My_simplexml_load_file(self::RESTreq.'flickr.groups.getInfo'.self::APIkey.'&group_id='.$pool) ;
if ($xml!==false && (count($xml->xpath('./err')))==0) {
if ($title=='') $title = $xml->group->name ;
if ($desc=='') $desc = $xml->group->description ;
} else {
$this->error_handler($xml,__METHOD__.'(getInfo)') ;
}
}
if ($this->useAlbumThumb && empty($this->albumThumb)) {
$xml = $this->My_simplexml_load_file('http://www.flickr.com/groups_feed.gne?id=' . $pool .'&format=rss_200' ) ;
$this->albumThumb = strtok($xml->channel->image->url,'?') ;
}
$search = (empty($this->searchParms)) ? '' : ('&'.http_build_query($this->searchParms)) ;
$xml = $this->My_simplexml_load_file(self::RESTreq.'flickr.groups.pools.getPhotos'.self::APIkey.'&group_id='.$pool.'&per_page='.$this->numImages.$search) ;
if ($xml!==false && (count($xml->xpath('./err')))==0) {
$this->xmlOutput .= $this->make_album($xml->photos->photo,$title,$desc,$this->albumThumb) ;
} else {
$this->error_handler($xml,__METHOD__.'(getPhotos)') ;
}
$this->reset() ;
}
public function add_search($title='',$desc='') {
if (!$this->refreshNeeded) return;
$xml = $this->My_simplexml_load_file(self::RESTreq.'flickr.photos.search'.self::APIkey.'&'.http_build_query($this->searchParms).'&per_page='.$this->numImages) ;
if ($xml!==false && (count($xml->xpath('./err')))==0) {
$this->xmlOutput .= $this->make_album($xml->photos->photo,$title,$desc,$this->albumThumb) ;
} else {
$this->error_handler($xml,__METHOD__) ;
}
$this->reset() ;
}
public function add_tags($tags,$title='',$desc='',$tagmode='all') {
if (!$this->refreshNeeded) return;
$xml = $this->My_simplexml_load_file(self::RESTreq.'flickr.photos.search'.self::APIkey.'&tags='.$tags.'&tag_mode='.$tagmode.'&per_page='.$this->numImages.'&'.http_build_query($this->searchParms)) ;
if ($xml!==false && (count($xml->xpath('./err')))==0) {
$this->xmlOutput .= $this->make_album($xml->photos->photo,$title,$desc,$this->albumThumb) ;
} else {
$this->error_handler($xml,__METHOD__) ;
}
$this->reset() ;
}
public function add_xml($relpath) {
if (!$this->refreshNeeded) return;
$xml = $this->My_simplexml_load_file($relpath) ;
if ($xml !== false) {
$albums = $xml->xpath('//album') ;
if (count($albums)!=0) {
foreach ($albums as $one) {
$this->xmlOutput .= $one->asXML() ;
}
}
} else {
$this->error_handler($xml,__METHOD__) ;
}
$this->reset() ;
}
//function to dump debug information, abort making xml file
protected function error_handler($xml,$funcname) {
if ($this->haltOnError) {
$this->refreshNeeded = false ;
$this->fileLife = 60 ;
}
if ($this->isDebug) {
if ($xml===false) {
echo "<p>Empty xml fetch in $funcname.</p>" ;
} else {
echo "<p>Error returned from xml request in $funcname — Error #{$xml->err[code]}, “{$xml->err[msg]}”</p>" ;
}
}
}
public function search_parameter($name,$value) {
$this->searchParms[$name] = $value ;
}
public function group_thumb($nsid) {
$xml = $this->My_simplexml_load_file('http://www.flickr.com/groups_feed.gne?id='.$nsid.'&format=rss_200' ) ;
return strtok($xml->channel->image->url,'?') ;
}
public function indiv_thumb($nsid) {
$xml = $this->My_simplexml_load_file(self::RESTreq.'flickr.people.getInfo'.self::APIkey.'&user_id='.$nsid) ;
$icons = $xml->person['iconserver'] ;
return (empty($icons)) ? 'http://www.flickr.com/images/buddyicon.jpg' :
"http://static.flickr.com/$icons/buddyicons/$nsid.jpg" ;
}
protected function reset() {
unset($this->searchParms) ;
unset($this->albumThumb) ;
}
//The __toString method will only be called when it is directly combined with echo() or print(). Do not use (string) cast.
public function __toString() {
return $this->xmlOutput ;
}
}//end class makeSSPxml
?>