Flickr photosets and photos in a gallery on your Wordpress site. Uses the Flickr API which is still in beta so changes to it may break this plugin (although Flickr claims backwards compatibility). Author: Ramon Darrow Author URI: http://www.worrad.com/ Change log: 0.7 -- "Friendly" URI generation (with mod_rewrite) Security conscious cache file names Support for "new" Flickr URL style 0.6 -- Pagination options Slightly improved navigation Made image caching for EXIF permanent (images don't change once their in Flickr, only the meta data changes) 0.5 -- Thumbnail size choices Option to respect photos marked "private" More robust error handling 0.4 -- EXIF data retrieval implemented from original size images (via partial download of original) Partial downloads of original images (for EXIF) cacheing for improved performance 0.3 -- Flickr "notes" feature implemented (requires stylesheet additions and a javascript file - see installation instructions) Cleaned up XHTML output - simplified markup on album homepage 0.2 -- Flickr results caching implemented - seamless get_file_contents method (if cache is old it fetches from Flickr and returns file contents seamlessly otherwise it just reads from cache) for improved performance 0.1 -- Proof of concept as a WP plugin Modifications by Nick Bouton (http://www.nickbouton.com/) - Added libcurl support, removed use of remote fopen() - Minor bug fixes/CSS-related changes Copyright (c) 2004 Released under the GPL license http://www.gnu.org/licenses/gpl.txt This file is part of WordPress. WordPress is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* Plugin Constants - DO NOT CHANGE */ define ('API_KEY', '3a4570b7e7e2aaf6be97a55b07e89db5'); //DO NOT CHANGE OR STEAL THIS - This is the API key that was assigned to this plugin by Flickr. If you need an API key for your own project goto http://flickr.com/services/api/misc.api_keys.html /* User Constants - Change to suit you */ define ('FLICKR_USER_ROOT', 'http://www.flickr.com/photos/yourname/'); //Used as the root for building the comment URLs (this is a Flickr setting - check with Flickr to see what yours is) define ('FLICKR_EMAIL', 'your@flickr-email.com'); //Your Flickr account logon (email address you registered with) define ('FLICKR_PASSWORD', 'your-pwd'); //Your Flickr account password define ('FLICKR_CACHE_EXPIRE', 3600); //How many seconds to wait between refreshing cache (default = 3600 seconds) define ('FLICKR_CACHE_PATH', '/your-dir/flickr-cache/'); //Path to your Flickr cache files (should be in your wp-content dir) - PHP must be able to write to that dir define ('FLICKR_THUMBNAIL_SIZE', 's'); //Size of the thumbnail you want to appear in the album thumbnail page ('s' = 75px x 75px, 't' = 100px x 75px, 'm' = 240px x 180px) define ('FLICKR_SHOW_PRIVATE', false); //Whether or not to show your "private" Flickr photos define ('USE_FRIENDLY_URLS', true); //Whether or not to use friendly URLs define ('URL_ROOT', 'http://your-url/'); //URL to use as the root for all navigational links define ('ALBUMS_PER_PAGE', 10); //How many albums to show on a page (0 for no paging) define ('PHOTOS_PER_PAGE', 45); //How many photos to show on a page (0 for no paging) define ('EXIF_CHUNK_SIZE', 16); //How many KB of image file to get before trying to read the EXIF data - experiment with changing this until your photos show their EXIF data (not all image editing software respects the EXIF data, so if you've edited your photo before uploading to Flickr your EXIF section may be blank). Some users have had to use as high as 64KB. define ('SHOW_EXIF_DATA', true); //Whether you want to show EXIF data or not /* Main function that builds the output for the album/photosets and individual photos */ function flickr_show_photos ($album = null, $photo = null, $page = 0) { $output = ''; if (is_null($album) && is_null($photo)) // Show list of albums/photosets (none have been selected yet) { $resp = cached_get_file_contents('http://www.flickr.com/services/rest/?method=flickr.photosets.getList&api_key='.API_KEY.'&email='.FLICKR_EMAIL.'&password='.FLICKR_PASSWORD, 'r', FLICKR_CACHE_EXPIRE, FLICKR_CACHE_PATH); // Do the Flickr API call $tree = makeXMLTree($resp); // Parse the result of the Flickr API call if (empty($tree['rsp']['err']) && !empty($tree)) { foreach ($tree['rsp']['photosets'] as $album_id => $album_details) // Loop though albums/photosets { if ((ALBUMS_PER_PAGE == 0) || (($count >= $page * ALBUMS_PER_PAGE) && ($count < ($page + 1) * ALBUMS_PER_PAGE))) { if (FLICKR_SHOW_PRIVATE) { $resp = cached_get_file_contents('http://www.flickr.com/services/rest/?method=flickr.photosets.getPhotos&api_key='.API_KEY.'&email='.FLICKR_EMAIL.'&password='.FLICKR_PASSWORD.'&photoset_id='.$album_id, 'r', FLICKR_CACHE_EXPIRE, FLICKR_CACHE_PATH); // Do the Flickr API call } else { $resp = cached_get_file_contents('http://www.flickr.com/services/rest/?method=flickr.photosets.getPhotos&api_key='.API_KEY.'&photoset_id='.$album_id, 'r', FLICKR_CACHE_EXPIRE, FLICKR_CACHE_PATH); // Do the Flickr API call } $count_tree = makeXMLTree($resp); // Parse the results of the Flickr API call unset($count_tree['rsp'][$album_id]['primary']); // Unset unwanted parts of the result tree unset($count_tree['rsp'][$album_id]['secret']); unset($count_tree['rsp'][$album_id]['photos']); #$album_details['photos'] = count($count_tree['rsp'][$album_id]); $album_details['photos']=count($count_tree['rsp'][$album_id]) - 1; if($album_details['photos'] != 0) { $thumbnail = "http://photos{$album_details['server']}.flickr.com/{$album_details['primary']}_{$album_details['secret']}_s.jpg"; // Build URL to small square thumbnail $output .= "
\n"; if (USE_FRIENDLY_URLS) { $output .= ""; } else { $output .= ""; } $output .= "\"{$album_details['title']}\""; $output .= "\n"; $output .= "

"; if (USE_FRIENDLY_URLS) { $output .= ""; } else { $output .= ""; } $output .= "{$album_details['title']}\n"; $output .= "

\n"; $output .= "
This photoset has {$album_details['photos']} pictures
\n"; $output .= "
{$album_details['description']}
\n"; $output .= "
\n"; # ADDED $output .= "\n"; } else { $count--; } } $count++; } $pages = @(count($tree['rsp']['photosets']) / ALBUMS_PER_PAGE); if ($pages > 1) { $output .= "

Pages: "; for ($i = 0; $i < $pages; $i++) { if (USE_FRIENDLY_URLS) { $output .= "".($i + 1)." "; } else { $output .= "".($i + 1)." "; } } $output .= "

\n"; } } else { $output .= "
\n"; $output .= "Sorry, Flickr is experiencing a problem. Click here for the actual error message.\n"; $output .= "
\n"; $output .= "
\n"; $output .= "
Here is the response from Flickr:\n\n
".htmlentities($resp)."
\n\nAnd here is the response after passing through the parser:\n\n
".htmlentities(var_export($tree, true))."
\n"; $output .= "
\n\n"; } } elseif (!is_null($album) && is_null($photo)) // Show list of photos in the selected album/photoset { if (USE_FRIENDLY_URLS) { $resp = cached_get_file_contents('http://www.flickr.com/services/rest/?method=flickr.photosets.getList&api_key='.API_KEY.'&email='.FLICKR_EMAIL.'&password='.FLICKR_PASSWORD, 'r', FLICKR_CACHE_EXPIRE, FLICKR_CACHE_PATH); // Do the Flickr API call $tree = makeXMLTree($resp); // Parse the result of the Flickr API call if (empty($tree['rsp']['err']) && !empty($tree)) { foreach ($tree['rsp']['photosets'] as $album_id => $album_details) // Loop though albums/photosets { if (sanitize_title($album_details['title']) == sanitize_title($album)) { $album = $album_id; break; } } } else { $output .= "
\n"; $output .= "
An error occurred.  Here is the response from Flickr:\n\n".htmlentities($resp)."\n\nAnd here is the response after passing through the parser:\n\n".var_export($tree, true)."
\n"; $output .= "
\n"; } } $resp = cached_get_file_contents('http://www.flickr.com/services/rest/?method=flickr.photosets.getList&api_key='.API_KEY.'&email='.FLICKR_EMAIL.'&password='.FLICKR_PASSWORD, 'r', FLICKR_CACHE_EXPIRE, FLICKR_CACHE_PATH); // Do the Flickr API call $top_level_tree = makeXMLTree($resp); // Parse the results of the Flickr API call if (!empty($top_level_tree['rsp']['err']) || empty($top_level_tree)) { $output .= "
\n"; $output .= "
An error occurred.  Here is the response from Flickr:\n\n".htmlentities($resp)."\n\nAnd here is the response after passing through the parser:\n\n".var_export($top_level_tree, true)."
\n"; $output .= "
\n"; } if (FLICKR_SHOW_PRIVATE) { $resp = cached_get_file_contents('http://www.flickr.com/services/rest/?method=flickr.photosets.getPhotos&api_key='.API_KEY.'&email='.FLICKR_EMAIL.'&password='.FLICKR_PASSWORD.'&photoset_id='.$album, 'r', FLICKR_CACHE_EXPIRE, FLICKR_CACHE_PATH); // Do the Flickr API call } else { $resp = cached_get_file_contents('http://www.flickr.com/services/rest/?method=flickr.photosets.getPhotos&api_key='.API_KEY.'&photoset_id='.$album, 'r', FLICKR_CACHE_EXPIRE, FLICKR_CACHE_PATH); // Do the Flickr API call } $tree = makeXMLTree($resp); // Parse the results of the Flickr API call unset($tree['rsp'][$album]['primary']); // Unset unwanted parts of the result tree unset($tree['rsp'][$album]['secret']); unset($tree['rsp'][$album]['server']); unset($tree['rsp'][$album]['photos']); if (empty($tree['rsp']['err']) && !empty($tree)) { $output .= "
\n"; $output .= "
{$top_level_tree['rsp']['photosets'][$album]['title']}
\n"; # ADDED $output .= "\n"; foreach ($tree['rsp'][$album] as $photo_id => $photo_details) // Loop through photos in the selected album/photoset { if ((PHOTOS_PER_PAGE == 0) || (($count >= $page * PHOTOS_PER_PAGE) && ($count < ($page + 1) * PHOTOS_PER_PAGE))) { $thumbnail = "http://photos{$photo_details['server']}.flickr.com/{$photo_id}_{$photo_details['secret']}_".FLICKR_THUMBNAIL_SIZE.".jpg"; // Build URL to thumbnail if (USE_FRIENDLY_URLS) { $output .= ""; } else { $output .= ""; } $output .= "\"\" 1) { $output .= "

Pages: "; for ($i = 0; $i < $pages; $i++) { if (USE_FRIENDLY_URLS) { $output .= "".($i + 1)." "; } else { $output .= "".($i + 1)." "; } } $output .= "

\n"; } $output .= "
\n

» View as a slide show

\n"; } else { $output .= "
\n"; $output .= "
An error occurred.  Here is the response from Flickr:\n\n".htmlentities($resp)."\n\nAnd here is the response after passing through the parser:\n\n".var_export($tree, true)."
\n"; $output .= "
\n"; } } elseif (!is_null($album) && !is_null($photo)) // Show the selected photo in the slected album/photoset { if (USE_FRIENDLY_URLS) { $resp = cached_get_file_contents('http://www.flickr.com/services/rest/?method=flickr.photosets.getList&api_key='.API_KEY.'&email='.FLICKR_EMAIL.'&password='.FLICKR_PASSWORD, 'r', FLICKR_CACHE_EXPIRE, FLICKR_CACHE_PATH); // Do the Flickr API call $tree = makeXMLTree($resp); // Parse the result of the Flickr API call if (empty($tree['rsp']['err']) && !empty($tree)) { foreach ($tree['rsp']['photosets'] as $album_id => $album_details) // Loop though albums/photosets { if (sanitize_title($album_details['title']) == sanitize_title($album)) { $album_orig = $album; $album = $album_id; } } } else { $output .= "
\n"; $output .= "
An error occurred.  Here is the response from Flickr:\n\n".htmlentities($resp)."\n\nAnd here is the response after passing through the parser:\n\n".var_export($tree, true)."
\n"; $output .= "
\n"; } } if (FLICKR_SHOW_PRIVATE) { $resp = cached_get_file_contents('http://www.flickr.com/services/rest/?method=flickr.photosets.getPhotos&api_key='.API_KEY.'&email='.FLICKR_EMAIL.'&password='.FLICKR_PASSWORD.'&photoset_id='.$album, 'r', FLICKR_CACHE_EXPIRE, FLICKR_CACHE_PATH); // Do the Flickr API call } else { $resp = cached_get_file_contents('http://www.flickr.com/services/rest/?method=flickr.photosets.getPhotos&api_key='.API_KEY.'&photoset_id='.$album, 'r', FLICKR_CACHE_EXPIRE, FLICKR_CACHE_PATH); // Do the Flickr API call } $top_level_tree = makeXMLTree($resp); // Parse the results of the Flickr API call unset($top_level_tree['rsp'][$album]['primary']); // Unset unwanted parts of the result tree unset($top_level_tree['rsp'][$album]['secret']); unset($top_level_tree['rsp'][$album]['photos']); if (empty($top_level_tree['rsp']['err']) && !empty($top_level_tree)) { $prev = $tmp_prev = $next = $tmp_next = $photo; $control = 1; foreach ($top_level_tree['rsp'][$album] as $photo_id => $photo_details) // Loop through photos in the album/photoset to setup navigation (determine previous and next photos in set) { if ($control == 0) // Selected photo was the last one, so this one is the next one { $next = $photo_id; // Set ID of the next photo break; // Break out of the foreach loop } if ($photo_id == $photo) // This is the selected photo { $prev = $tmp_prev; // Set ID of the previous photo $control--; // Decrement control variable to tell next iteration of loop that the selected photo was found } $tmp_prev = $photo_id; // Keep the last photo in a temporary variable in case next photo is the selected on } } else { $output .= "
\n"; $output .= "
An error occurred.  Here is the response from Flickr:\n\n".htmlentities($resp)."\n\nAnd here is the response after passing through the parser:\n\n".var_export($top_level_tree, true)."
\n"; $output .= "
\n"; } if (FLICKR_SHOW_PRIVATE) { $resp = cached_get_file_contents('http://www.flickr.com/services/rest/?method=flickr.photos.getInfo&api_key='.API_KEY.'&email='.FLICKR_EMAIL.'&password='.FLICKR_PASSWORD.'&photo_id='.$photo, 'r', FLICKR_CACHE_EXPIRE, FLICKR_CACHE_PATH); // Do the Flickr API call } else { $resp = cached_get_file_contents('http://www.flickr.com/services/rest/?method=flickr.photos.getInfo&api_key='.API_KEY.'&photo_id='.$photo, 'r', FLICKR_CACHE_EXPIRE, FLICKR_CACHE_PATH); // Do the Flickr API call } $tree = makeXMLTree($resp); // Parse the results of the Flickr API call $tree['rsp']['photo']['description'] = nl2br($tree['rsp']['photo']['description']); if (empty($tree['rsp']['err']) && !empty($tree)) { $image = "http://photos{$top_level_tree['rsp'][$album][$photo]['server']}.flickr.com/{$photo}_{$top_level_tree['rsp'][$album][$photo]['secret']}.jpg"; // Build URL to medium size image $original = "http://photos{$top_level_tree['rsp'][$album][$photo]['server']}.flickr.com/{$photo}_{$top_level_tree['rsp'][$album][$photo]['secret']}_o.jpg"; // Build URL to original size image $tmp = parse_url($original); $cache_file = FLICKR_CACHE_PATH.basename($tmp['path']); if(function_exists('exif_read_data')) { copy_raw_file($original, $cache_file, EXIF_CHUNK_SIZE); // Get the first part of the image file so we can grab EXIF data $exif_data = exif_read_data($cache_file, 'ANY_TAG'); // Extract the EXIF headers } $output .= "
\n"; $output .= "

{$tree['rsp']['photo']['title']}

\n"; $output .= "\n"; $output .= "\"\"\n"; $output .= "

"; if (($prev != $photo) && ($next != $photo)) // Show both previous and next navigation { if (USE_FRIENDLY_URLS) { $output .= "« Previous Picture"; $output .= " « Album Home » \n"; $output .= "Next Picture »\n"; } else { $output .= "« Previous Picture"; $output .= " « Album Home » \n"; $output .= "Next Picture »\n"; } } elseif (($prev != $photo) && ($next == $photo)) // Show only previous navigation { if (USE_FRIENDLY_URLS) { $output .= "« Previous Picture\n"; $output .= " « Album Home\n"; } else { $output .= "« Previous Picture\n"; $output .= " « Album Home\n"; } } elseif (($prev == $photo) && ($next != $photo)) // Show only next navigation { if (USE_FRIENDLY_URLS) { $output .= "Album Home » \n"; $output .= "Next Picture »"; } else { $output .= "Album Home » \n"; $output .= "Next Picture »"; } } $output .= "

\n"; $output .= "
\n"; $output .= "

{$tree['rsp']['photo']['description']}

\n"; $output .= "
\n"; $output .= "
\n"; if (!empty($exif_data['DateTime']) && SHOW_EXIF_DATA) { $output .= "

Taken {$exif_data['DateTime']} with a {$exif_data['Make']} {$exif_data['Model']}

\n"; $output .= "

Exposure Time: {$exif_data['ExposureTime']}
\n"; $output .= "F Number: {$exif_data['FNumber']}
\n"; $output .= "Exposure Program: {$exif_data['ExposureProgram']}
\n"; $output .= "ISO Speed Ratings: {$exif_data['ISOSpeedRatings']}
\n"; $output .= "Focal Length: {$exif_data['FocalLength']}
\n"; $output .= "Exposure Bias: {$exif_data['ExposureBiasValue']}
\n"; $output .= "Max Aperture: {$exif_data['MaxApertureValue']}
\n"; $output .= "Metering Mode: {$exif_data['MeteringMode']}
\n"; $output .= "Flash: {$exif_data['Flash']}
\n"; $output .= "Digital Zoom Ratio: {$exif_data['DigitalZoomRatio']}
\n"; $output .= "

\n"; } $output .= "

View the original "; if (!empty($exif_data['COMPUTED'])) { $output .= "size ({$exif_data['COMPUTED']['Width']} x {$exif_data['COMPUTED']['Height']})"; } else { $output .= "photo"; } $output .= "

\n"; if (is_array($tree['rsp']['photo']['tags'])) // Output "see similar" links if tags exist { $output .= "

See similar photos on Flickr: "; foreach ($tree['rsp']['photo']['tags'] as $tag_id => $tag_details) // Loop through tags { $output .= "{$tag_details['value']} "; } $output .= "

\n"; } $output .= "

See this photo on Flickr ({$tree['rsp']['photo']['comments']} Comments)

\n"; $output .= "
\n"; if (is_array($tree['rsp']['photo']['notes'])) // Output notes imgmap if notes exist { $output .= "\n"; foreach ($tree['rsp']['photo']['notes'] as $note_id => $note_details) // Loop through notes { $output .= "\"\"\n"; } $output .= "\n"; } $output .= "
\n"; } else { $output .= "
\n"; $output .= "
An error occurred.  Here is the response from Flickr:\n\n".htmlentities($resp)."\n\nAnd here is the response after passing through the parser:\n\n".var_export($tree, true)."
\n"; $output .= "
\n"; } } echo $output; } /* Function that reads file from the cache if it is younger than a certain age and otherwise grabs a fresh copy of it from remote source */ function cached_get_file_contents ($file, $file_mode, $cache_timeout = 3600, $cache_path = '../', $debug = false) { clearstatcache(); // Clear file stats so we get an accurate file creation time for cache files if (function_exists('sha1')) // Prefer SHA1 because collision space is much larger than MD5, but MD5 will work too { $cache_filename = $cache_path . "/" . sha1($file) .".cached"; // Path to cached file } else { $cache_filename = $cache_path . "/" . md5($file) .".cached"; // Path to cached file } if ($debug) { print "local_cache creation_time =" . @filemtime($cache_filename) . " actual time = " . time() . " timeout = " . $timeout_seconds ."\n"; } if (( @file_exists($cache_filename) && (( @filemtime($cache_filename) + $cache_timeout) > ( time())))) // If file exists and is young enough then do nothing because it will return file contents of cache { if ($debug) { print "using cached file ($cache_filename)\n"; } } else // If file doesn't exist or is too old get a fresh copy from remote source { if ($debug) { print "cacheing file ($file) to local ($cache_filename)\n"; } $curl_handle = curl_init(); if( !$curl_handle ) { return @file_get_contents ($cache_filename); // Return the file contents form the cache } curl_setopt ($curl_handle, CURLOPT_URL, $file); curl_setopt ($curl_handle, CURLOPT_RETURNTRANSFER, 1); curl_setopt ($curl_handle, CURLOPT_CONNECTTIMEOUT, 1); $buffer = curl_exec($curl_handle); curl_close($curl_handle); $f2 = @fopen($cache_filename,"w+"); // Open local cache file fwrite($f2,$buffer); // Write to the local cache @fclose($f2); } return file_get_contents ($cache_filename); // Return the file contents from the cache } /* Function gets the raw contents of a remote file and puts it in a local file. By default retrieves the whole file, but you can specify to retrieve only a certain number of kilobytes. */ function copy_raw_file($source, $dest, $kbytes = 0, $debug = false) { clearstatcache(); // Clear file stats so we get an accurate file creation time for cache files if ($debug) { print "local_cache creation_time =" . @filemtime($dest) ."\n"; } if ( @file_exists($dest)) // If file exists then do nothing because it will return file contents of cache { if ($debug) { print "using cached file ($dest)\n"; } } else { if ($debug) { print "cacheing file ($source) to local ($dest)\n"; } $curl_handle = curl_init(); curl_setopt ($curl_handle, CURLOPT_URL, $source); curl_setopt ($curl_handle, CURLOPT_RETURNTRANSFER, 1); curl_setopt ($curl_handle, CURLOPT_CONNECTTIMEOUT, 1); $buffer = curl_exec($curl_handle); curl_close($curl_handle); $f2 = @fopen($dest, 'w+'); // File to copy to (local) fwrite($f2, $buffer); // Write the 1 KB to the dest file @fclose($f2); // Close dest file } } /* Function that parses the XML results from the Flickr API (based on torsten@jserver.de's makeXMLTree function found at http://www.php.net/manual/en/ref.xml.php) */ function makeXMLTree ($data) { $output = array(); $parser = xml_parser_create(); xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0); xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 0); xml_parse_into_struct($parser, $data, $values, $tags); xml_parser_free($parser); $hash_stack = array(); foreach ($values as $key => $val) // Loop through all the values the XML parser gave us { switch ($val['type']) { case 'open': switch ($val['tag']) { case 'photoset': // Grab photoset attributes array_push($hash_stack, $val['attributes']['id']); array_push($hash_stack, 'primary'); eval("\$output['" . implode($hash_stack, "']['") . "'] = \"{$val['attributes']['primary']}\";"); array_pop($hash_stack); array_push($hash_stack, 'secret'); eval("\$output['" . implode($hash_stack, "']['") . "'] = \"{$val['attributes']['secret']}\";"); array_pop($hash_stack); array_push($hash_stack, 'server'); eval("\$output['" . implode($hash_stack, "']['") . "'] = \"{$val['attributes']['server']}\";"); array_pop($hash_stack); array_push($hash_stack, 'photos'); eval("\$output['" . implode($hash_stack, "']['") . "'] = \"{$val['attributes']['photos']}\";"); array_pop($hash_stack); break; default: array_push($hash_stack, $val['tag']); break; } break; case 'close': array_pop($hash_stack); break; case 'complete': switch ($val['tag']) { case 'photo': // Grab photo attributes array_push($hash_stack, $val['attributes']['id']); array_push($hash_stack, 'secret'); eval("\$output['" . implode($hash_stack, "']['") . "'] = \"{$val['attributes']['secret']}\";"); array_pop($hash_stack); array_push($hash_stack, 'server'); eval("\$output['" . implode($hash_stack, "']['") . "'] = \"{$val['attributes']['server']}\";"); array_pop($hash_stack); array_push($hash_stack, 'isprimary'); eval("\$output['" . implode($hash_stack, "']['") . "'] = \"{$val['attributes']['isprimary']}\";"); array_pop($hash_stack); array_push($hash_stack, 'license'); eval("\$output['" . implode($hash_stack, "']['") . "'] = \"{$val['attributes']['license']}\";"); array_pop($hash_stack); array_pop($hash_stack); break; case 'note': // Grab note attributes array_push($hash_stack, $val['attributes']['id']); array_push($hash_stack, 'author'); eval("\$output['" . implode($hash_stack, "']['") . "'] = \"{$val['attributes']['author']}\";"); array_pop($hash_stack); array_push($hash_stack, 'authorname'); eval("\$output['" . implode($hash_stack, "']['") . "'] = \"{$val['attributes']['authorname']}\";"); array_pop($hash_stack); array_push($hash_stack, 'x'); eval("\$output['" . implode($hash_stack, "']['") . "'] = \"{$val['attributes']['x']}\";"); array_pop($hash_stack); array_push($hash_stack, 'y'); eval("\$output['" . implode($hash_stack, "']['") . "'] = \"{$val['attributes']['y']}\";"); array_pop($hash_stack); array_push($hash_stack, 'w'); eval("\$output['" . implode($hash_stack, "']['") . "'] = \"{$val['attributes']['w']}\";"); array_pop($hash_stack); array_push($hash_stack, 'h'); eval("\$output['" . implode($hash_stack, "']['") . "'] = \"{$val['attributes']['h']}\";"); array_pop($hash_stack); array_push($hash_stack, 'value'); eval("\$output['" . implode($hash_stack, "']['") . "'] = \"".htmlentities($val['value'])."\";"); array_pop($hash_stack); array_pop($hash_stack); break; case 'tag': // Grab tag attributes array_push($hash_stack, $val['attributes']['id']); array_push($hash_stack, 'author'); eval("\$output['" . implode($hash_stack, "']['") . "'] = \"{$val['attributes']['author']}\";"); array_pop($hash_stack); array_push($hash_stack, 'value'); eval("\$output['" . implode($hash_stack, "']['") . "'] = \"{$val['value']}\";"); array_pop($hash_stack); array_pop($hash_stack); break; case 'err': // Grab error attributes array_push($hash_stack, $val['tag']); array_push($hash_stack, 'code'); eval("\$output['" . implode($hash_stack, "']['") . "'] = \"{$val['attributes']['code']}\";"); array_pop($hash_stack); array_push($hash_stack, 'msg'); eval("\$output['" . implode($hash_stack, "']['") . "'] = \"{$val['attributes']['msg']}\";"); array_pop($hash_stack); array_pop($hash_stack); break; default: array_push($hash_stack, $val['tag']); @eval("\$output['" . implode($hash_stack, "']['") . "'] = \"{$val['value']}\";"); array_pop($hash_stack); break; } } } return $output; } if (!function_exists('file_get_contents')) { function file_get_contents($filename, $incpath = false, $resource_context = null) { if (false === $fh = fopen($filename, 'rb', $incpath)) { echo 'file_get_contents() failed to open stream: No such file or directory'; return false; } clearstatcache(); if ($fsize = @filesize($filename)) { $data = fread($fh, $fsize); } else { $data = ''; while (!feof($fh)) { $data .= fread($fh, 8192); } } fclose($fh); return $data; } } ?>