<?php // +-----------------------------------------------------------------------+ // | PhpWebGallery - a PHP based picture gallery | // | Copyright (C) 2002-2003 Pierrick LE GALL - pierrick@phpwebgallery.net | // | Copyright (C) 2003-2004 PhpWebGallery Team - http://phpwebgallery.net | // +-----------------------------------------------------------------------+ // | branch : BSF (Best So Far) // | file : $RCSfile$ // | last update : $Date$ // | last modifier : $Author$ // | revision : $Revision$ // +-----------------------------------------------------------------------+ // | This program 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 | // | | // | 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. | // +-----------------------------------------------------------------------+ // +-----------------------------------------------------------------------+ // | parameters | // +-----------------------------------------------------------------------+ // prefix for thumbnails in "thumbnail" sub directories $conf['prefix_thumbnail'] = 'TN-'; // $conf['file_ext'] lists all extensions (case insensitive) allowed for // your PhpWebGallery installation $conf['file_ext'] = array('jpg','JPG','png','PNG','gif','GIF','mpg','zip', 'avi','mp3','ogg'); // $conf['picture_ext'] must be a subset of $conf['file_ext'] $conf['picture_ext'] = array('jpg','JPG','png','PNG','gif','GIF'); // $conf['version'] is used to verify the compatibility of the generated // listing.xml file and the PhpWebGallery version you're running $conf['version'] = 'BSF'; // $conf['use_exif'] set to true if you want to use Exif Date as "creation // date" for the element, otherwise, set to false $conf['use_exif'] = true; // $conf['use_iptc'] set to true if you want to use IPTC informations of the // element according to get_sync_iptc_data function mapping, otherwise, set // to false $conf['use_iptc'] = false; // use_iptc_mapping : in which IPTC fields will PhpWebGallery find image // information ? This setting is used during metadata synchronisation. It // associates a phpwebgallery_images column name to a IPTC key $conf['use_iptc_mapping'] = array( 'keywords' => '2#025', 'date_creation' => '2#055', 'author' => '2#122', 'name' => '2#005', 'comment' => '2#120' ); // +-----------------------------------------------------------------------+ // | functions | // +-----------------------------------------------------------------------+ /** * returns informations from IPTC metadata, mapping is done at the beginning * of the function * * @param string $filename * @return array */ function get_iptc_data($filename, $map) { $result = array(); // Read IPTC data $iptc = array(); $imginfo = array(); getimagesize($filename, $imginfo); if (isset($imginfo['APP13'])) { $iptc = iptcparse($imginfo['APP13']); if (is_array($iptc)) { $rmap = array_flip($map); foreach (array_keys($rmap) as $iptc_key) { if (isset($iptc[$iptc_key][0])) { if ($iptc_key == '2#025') { $value = implode(',', array_map('clean_iptc_value',$iptc[$iptc_key])); } else { $value = clean_iptc_value($iptc[$iptc_key][0]); } foreach (array_keys($map, $iptc_key) as $pwg_key) { $result[$pwg_key] = $value; } } } } } return $result; } /** * return a cleaned IPTC value * * @param string value * @return string */ function clean_iptc_value($value) { // strip leading zeros (weird Kodak Scanner software) while ($value[0] == chr(0)) { $value = substr($value, 1); } // remove binary nulls $value = str_replace(chr(0x00), ' ', $value); return htmlentities($value); } function get_sync_iptc_data($file) { global $conf; $map = $conf['use_iptc_mapping']; $datefields = array('date_creation', 'date_available'); $iptc = get_iptc_data($file, $map); foreach ($iptc as $pwg_key => $value) { if (in_array($pwg_key, $datefields)) { if ( preg_match('/(\d{4})(\d{2})(\d{2})/', $value, $matches)) { $iptc[$pwg_key] = $matches[1].'-'.$matches[2].'-'.$matches[3]; } } } if (isset($iptc['keywords'])) { // keywords separator is the comma, nothing else. Allowed characters in // keywords : [A-Za-z0-9], "-" and "_". All other characters will be // considered as separators $iptc['keywords'] = preg_replace('/[^\w-]+/', ',', $iptc['keywords']); $iptc['keywords'] = preg_replace('/^,+|,+$/', '', $iptc['keywords']); } return $iptc; } /** * returns a float value coresponding to the number of seconds since the * unix epoch (1st January 1970) and the microseconds are precised : * e.g. 1052343429.89276600 * * @return float */ function get_moment() { $t1 = explode(' ', microtime()); $t2 = explode('.', $t1[0]); $t2 = $t1[1].'.'.$t2[1]; return $t2; } /** * returns the number of seconds (with 3 decimals precision) between the * start time and the end time given. * * @param float start * @param float end * @return void */ function get_elapsed_time($start, $end) { return number_format($end - $start, 3, '.', ' ').' s'; } /** * returns an array with all picture files according to $conf['file_ext'] * * @param string $dir * @return array */ function get_pwg_files($dir) { global $conf; $pictures = array(); if ($opendir = opendir($dir)) { while ($file = readdir($opendir)) { if (in_array(get_extension($file), $conf['file_ext'])) { array_push($pictures, $file); if (!preg_match('/^[a-zA-Z0-9-_.]+$/', $file)) { echo 'PWG-WARNING-2: "'.$file.'" : '; echo 'The name of the file should be composed of '; echo 'letters, figures, "-", "_" or "." ONLY'; echo "\n"; } } } } return $pictures; } /** * returns an array with all thumbnails according to $conf['picture_ext'] * and $conf['prefix_thumbnail'] * * @param string $dir * @return array */ function get_thumb_files($dir) { global $conf; $prefix_length = strlen($conf['prefix_thumbnail']); $thumbnails = array(); if ($opendir = @opendir($dir.'/thumbnail')) { while ($file = readdir($opendir)) { if (in_array(get_extension($file), $conf['picture_ext']) and substr($file,0,$prefix_length) == $conf['prefix_thumbnail']) { array_push($thumbnails, $file); } } } return $thumbnails; } /** * returns an array with representative picture files of a directory * according to $conf['picture_ext'] * * @param string $dir * @return array */ function get_representative_files($dir) { global $conf; $pictures = array(); if ($opendir = @opendir($dir.'/pwg_representative')) { while ($file = readdir($opendir)) { if (in_array(get_extension($file), $conf['picture_ext'])) { array_push($pictures, $file); } } } return $pictures; } /** * search in $basedir the sub-directories and calls get_pictures * * @return void */ function get_dirs($basedir, $indent, $level) { $fs_dirs = array(); $dirs = ""; if ($opendir = opendir($basedir)) { while ($file = readdir($opendir)) { if ($file != '.' and $file != '..' and $file != 'thumbnail' and $file != 'pwg_high' and $file != 'pwg_representative' and is_dir ($basedir.'/'.$file)) { array_push($fs_dirs, $file); if (!preg_match('/^[a-zA-Z0-9-_.]+$/', $file)) { echo 'PWG-WARNING-1: "'.$file.'" : '; echo 'The name of the directory should be composed of '; echo 'letters, figures, "-", "_" or "." ONLY'; echo "\n"; } } } } // write of the dirs foreach ($fs_dirs as $fs_dir) { $dirs.= "\n".$indent.'<dir'.$level.' name="'.$fs_dir.'">'; $dirs.= get_pictures($basedir.'/'.$fs_dir, $indent.' '); $dirs.= get_dirs($basedir.'/'.$fs_dir, $indent.' ', $level + 1); $dirs.= "\n".$indent.'</dir'.$level.'>'; } return $dirs; } // get_extension returns the part of the string after the last "." function get_extension($filename) { return substr(strrchr($filename, '.'), 1, strlen ($filename)); } // get_filename_wo_extension returns the part of the string before the last // ".". // get_filename_wo_extension('test.tar.gz') -> 'test.tar' function get_filename_wo_extension($filename) { return substr($filename, 0, strrpos($filename, '.')); } function get_pictures($dir, $indent) { global $conf, $page; // fs means FileSystem : $fs_files contains files in the filesystem found // in $dir that can be managed by PhpWebGallery (see get_pwg_files // function), $fs_thumbnails contains thumbnails, $fs_representatives // contains potentially representative pictures for non picture files $fs_files = get_pwg_files($dir); $fs_thumbnails = get_thumb_files($dir); $fs_representatives = get_representative_files($dir); $elements = array(); $print_dir = preg_replace('/^\.\//', '', $dir); $print_dir = preg_replace('/\/*$/', '/', $print_dir); foreach ($fs_files as $fs_file) { $element = array(); $element['file'] = $fs_file; $element['path'] = $page['url'].$print_dir.$fs_file; $element['filesize'] = floor(filesize($dir.'/'.$fs_file) / 1024); $file_wo_ext = get_filename_wo_extension($fs_file); foreach ($conf['picture_ext'] as $ext) { $test = $conf['prefix_thumbnail'].$file_wo_ext.'.'.$ext; if (!in_array($test, $fs_thumbnails)) { continue; } else { $element['tn_ext'] = $ext; break; } } // 2 cases : the element is a picture or not. Indeed, for a picture // thumbnail is mandatory and for non picture element, thumbnail and // representative is optionnal if (in_array(get_extension($fs_file), $conf['picture_ext'])) { // if we found a thumnbnail corresponding to our picture... if (isset($element['tn_ext'])) { if ($image_size = @getimagesize($dir.'/'.$fs_file)) { $element['width'] = $image_size[0]; $element['height'] = $image_size[1]; } if ($conf['use_exif']) { if ($exif = @read_exif_data($dir.'/'.$fs_file)) { if (isset($exif['DateTime'])) { preg_match('/^(\d{4}):(\d{2}):(\d{2})/' ,$exif['DateTime'] ,$matches); $element['date_creation'] = $matches[1].'-'.$matches[2].'-'.$matches[3]; } } } if ($conf['use_iptc']) { $iptc = get_sync_iptc_data($dir.'/'.$fs_file); if (count($iptc) > 0) { foreach (array_keys($iptc) as $key) { $element[$key] = addslashes($iptc[$key]); } } } array_push($elements, $element); } else { echo 'PWG-ERROR-1: The thumbnail is missing for '.$dir.'/'.$fs_file; echo '-> '.$dir.'/thumbnail/'; echo $conf['prefix_thumbnail'].$file_wo_ext.'.xxx'; echo ' ("xxx" can be : '; echo implode(', ', $conf['picture_ext']); echo ')'."\n"; } } else { foreach ($conf['picture_ext'] as $ext) { $candidate = $file_wo_ext.'.'.$ext; if (!in_array($candidate, $fs_representatives)) { continue; } else { $element['representative_ext'] = $ext; break; } } array_push($elements, $element); } } $xml = "\n".$indent.'<root>'; $attributes = array('file','tn_ext','representative_ext','filesize', 'width','height','date_creation','author','keywords', 'name','comment','path'); foreach ($elements as $element) { $xml.= "\n".$indent.' '; $xml.= '<element'; foreach ($attributes as $attribute) { if (isset($element{$attribute})) { $xml.= ' '.$attribute.'="'.$element{$attribute}.'"'; } } $xml.= ' />'; } $xml.= "\n".$indent.'</root>'; return $xml; } // +-----------------------------------------------------------------------+ // | script | // +-----------------------------------------------------------------------+ if (isset($_GET['action'])) { $page['action'] = $_GET['action']; } else { $page['action'] = 'generate'; } echo '<pre>'; switch ($page['action']) { case 'generate' : { $start = get_moment(); $listing = '<informations'; $listing.= ' generation_date="'.date('Y-m-d').'"'; $listing.= ' phpwg_version="'.$conf{'version'}.'"'; $end = strrpos($_SERVER['PHP_SELF'], '/') + 1; $local_folder = substr($_SERVER['PHP_SELF'], 0, $end); $page['url'] = 'http://'.$_SERVER['HTTP_HOST'].$local_folder; $listing.= ' url="'.$page['url'].'"'; $listing.= '/>'."\n"; $listing.= get_dirs('.', '', 0); if ($fp = @fopen("./listing.xml","w")) { fwrite($fp, $listing); fclose($fp); echo 'PWG-INFO-1: listing.xml created in '; echo get_elapsed_time($start, get_moment()); echo "\n"; } else { echo "PWG-ERROR-2: I can't write the file listing.xml"."\n"; } break; } case 'test' : { if (isset($_GET['version'])) { if ($_GET['version'] != $conf['version']) { echo 'PWG-ERROR-4: PhpWebGallery versions differs'."\n"; } else { echo 'PWG-INFO-2: test successful'."\n"; } } else { echo 'PWG-INFO-2: test successful'."\n"; } break; } case 'clean' : { if( @unlink('./listing.xml')) { echo 'PWG-INFO-3 : listing.xml file deleted'."\n"; } else { echo 'PWG-ERROR-3 : listing.xml does not exist'."\n"; } break; } } echo '</pre>'; ?>