Skip to content

Instantly share code, notes, and snippets.

@walterdavis
Created February 28, 2012 15:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save walterdavis/1932987 to your computer and use it in GitHub Desktop.
Save walterdavis/1932987 to your computer and use it in GitHub Desktop.
Drop this script in a folder full of JPEG photos to publish a photo feed
<?php
/**
* Place this file in a folder full of JPEG images to publish an RSS feed of the photos.
*
* - Files are sorted latest-first by modification date.
*
* - File names are used for captions, underscore is replaced with a space, extension
* is removed.
*
* - Requires PHP5
*
* License
*
* Copyright (c) 2009, Walter Lee Davis <waltd@wdstudio.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Walter Davis Studio nor the names of its contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* @author Walter Lee Davis
*/
//CONFIGURATION:
//external URL to the folder containing this file -- trailing slash needed
$url = 'http://example.com/photo_folder/';
//feed name & details
$title = 'My Fabulous Photos';
$subtitle = 'A fabulous collection of photos.';
$author = 'Richard Avedon';
$limit = 20; //only 20 photos
//read the directory
$dir = dirname(__FILE__);
$photos = array();
$latest = 0;
foreach(scandir($dir) as $file){
if(preg_match('/^[^\.].+?\.jpe?g$/i', $file)){
$timestamp = filemtime($dir . '/' . $file);
$latest = ($timestamp > $latest) ? $timestamp : $latest;
$photos[$timestamp] = $file;
}
}
$latest = gmdate('Y-m-d\TH:i:s\Z',$latest);
//sort by date descending
krsort($photos);
//templates
$feed = '<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>{{title}}</title>
<updated>{{latest}}</updated>
<author><name>{{author}}</name></author>
<id>{{url}}</id>
<subtitle>
{{subtitle}}
</subtitle>
<link rel="self" href="{{url}}feed.php"/>
{{entries}}
</feed>
';
$entry = ' <entry>
<title>{{item_title}}</title>
<id>{{id}}</id>
<link rel="enclosure" type="image/jpeg" href="{{url}}{{photo}}" />
<link rel="alternate" href="{{url}}{{photo}}" />
<summary type="html">
{{image_tag}}
</summary>
<published>{{published}}</published>
<updated>{{published}}</updated>
</entry>
';
/**
* recursive variable replacement
*
* @param string $strText Input text including {{variable}} placeholders
* @return string with all templates replaced with existing global vars
* @author Walter Lee Davis
*/
function replace_vars($strText){
$out = preg_replace_callback('/\{\{(.+?)\}\}/im','replace_vars_callback',$strText);
if(strpos($out,'{{') !== false) {
return replace_vars($out);
}
return $out;
}
function replace_vars_callback($arrMatches){
$match = $arrMatches[1];
if(isset($GLOBALS[$match])) return $GLOBALS[$match];
//the spaces between the brackets here are Unicode Word Joiner characters (U+2060)
//not actual spaces. This keeps away the infinite loop.
return '{⁠{' . $match . '}⁠}';
//return $arrMatches[0];
}
//build the current set of entries as an array of strings
$entries = array();
$i = 0;
foreach($photos as $date => $photo){
if($i < $limit){
$published = gmdate('Y-m-d\TH:i:s\Z',$date);
$id = $url . $photo;
$item_title = preg_replace('/_/', ' ', preg_replace('/\.[a-zA-Z]{3,4}$/','',$photo));
$image_tag = htmlspecialchars('<img src="' . $id . '" alt="' . $item_title . '" /><br /><br />');
$entries[] = replace_vars($entry);
$i++;
}else{
break;
}
}
//concatenate into a single string
$entries = implode("\n",$entries);
//build the outer shell
$feed = replace_vars($feed);
//send the result
header('Content-type: application/xml');
print $feed;
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment