diff options
Diffstat (limited to 'BSF/tools/create_listing_file.php')
-rw-r--r-- | BSF/tools/create_listing_file.php | 1696 |
1 files changed, 1696 insertions, 0 deletions
diff --git a/BSF/tools/create_listing_file.php b/BSF/tools/create_listing_file.php new file mode 100644 index 000000000..8b1ee34ee --- /dev/null +++ b/BSF/tools/create_listing_file.php @@ -0,0 +1,1696 @@ +<?php +// +-----------------------------------------------------------------------+ +// | Piwigo - a PHP based picture gallery | +// +-----------------------------------------------------------------------+ +// | Copyright(C) 2008 Piwigo Team http://piwigo.org | +// | Copyright(C) 2003-2008 PhpWebGallery Team http://phpwebgallery.net | +// | Copyright(C) 2002-2003 Pierrick LE GALL http://le-gall.net/pierrick | +// +-----------------------------------------------------------------------+ +// | 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. | +// +-----------------------------------------------------------------------+ + +// +-----------------------------------------------------------------------+ +// | User configuration | +// +-----------------------------------------------------------------------+ + +// ****** Gallery configuration ****** // +// Script version +$conf['version'] = 'branch 1.7'; + +// URL of main gallery +// Example : http://www.my.domain/my/directory +$conf['gallery'] = 'http://demo.piwigo.net/'; + +// prefix for thumbnails in "thumbnail" sub directories +$conf['prefix_thumbnail'] = 'TN-'; + +// $conf['file_ext'] lists all extensions (case insensitive) allowed +// for your Piwigo installation +$conf['file_ext'] = array('jpg','JPG','jpeg','JPEG', + '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','jpeg','JPEG', + 'png','PNG','gif','GIF'); + +// ****** Time limitation functionality ****** // +// max execution time before refresh in seconds +$conf['max_execution_time'] = (5*ini_get('max_execution_time'))/6; // 25 seconds with default PHP configuration +// force the use of refresh method +// in order to have live informations +// or +// to fix system witch are not safe mode but not autorized set_time_limit +$conf['force_refresh_method'] = true; + +// refresh delay is seconds +$conf['refresh_delay'] = 0; + +// ****** EXIF support functionality ****** // +// $conf['use_exif'] set to true if you want to use Exif information +$conf['use_exif'] = true; + +// use_exif_mapping: same behaviour as use_iptc_mapping +$conf['use_exif_mapping'] = array( + 'date_creation' => 'DateTimeOriginal' + ); + +// ****** IPTC support functionality ****** // +// $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 Piwigo find image +// information ? This setting is used during metadata synchronisation. It +// associates a piwigo_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'); + +// ****** Directory protection functionality ****** // +// Define if directories have to be protected if they are not +$conf['protect'] = false; + +// true/false : show/hide warnings +$conf['protect_warnings'] = true; + +// ****** Thumbnails generation functionality ****** // +// Define if images have to be reduced if they are not +$conf['thumbnail'] = false; + +// Define method to generate thumbnails : +// - fixed (width and height required); +// - width (only width required); +// - height (only height required); +// - ratio (only ratio is required) +// - exif (no other parameter required) +$conf['thumbnail_method'] = 'ratio'; + +// Height in pixels (greater than 0) +$conf['thumbnail_height'] = 128; + +// Width in pixels (greater than 0) +$conf['thumbnail_width'] = 128; + +// Ratio between original and thumbnail size (strictly between 0 and 1) +$conf['thumbnail_ratio'] = 0.2; + +// Define thumbnail format : jpeg, png or gif (will be verified) +$conf['thumbnail_format'] = 'jpeg'; + +// ****** Directory mapping ****** // +// directories names +$conf['thumbs'] = 'thumbnail'; // thumbnails +$conf['high'] = 'pwg_high'; // high resolution +$conf['represent'] = 'pwg_representative'; // non pictures representative files + + +// +-----------------------------------------------------------------------+ +// | Overload configurations | +// +-----------------------------------------------------------------------+ +@include(dirname(__FILE__).'/'.basename(__FILE__, '.php').'_local.inc.php'); + + +// +-----------------------------------------------------------------------+ +// | Advanced script configuration | +// +-----------------------------------------------------------------------+ + +// url of icon directory in yoga template +$pwg_conf['icon_dir'] = $conf['gallery'].'/template/yoga/icon/'; + +// list of actions managed by this script +$pwg_conf['scan_action'] = array('clean', 'test', 'generate'); + +// url of this script +$pwg_conf['this_url'] = + (empty($_SERVER['HTTPS']) ? 'http://' : 'https://') + .str_replace(':'.$_SERVER['SERVER_PORT'], '', $_SERVER['HTTP_HOST']) + .($_SERVER['SERVER_PORT'] != 80 ? ':'.$_SERVER['SERVER_PORT'] : '') + .$_SERVER['PHP_SELF']; + +// list of reserved directory names +$pwg_conf['reserved_directory_names'] = array($conf['thumbs'], $conf['high'], $conf['represent'], ".", "..", ".svn"); + +// content of index.php generated in protect action +$pwg_conf['protect_content'] = '<?php header("Location: '.$conf['gallery'].'") ?>'; + +// backup of PHP safe_mode INI parameter (used for time limitation) +$pwg_conf['safe_mode'] = (ini_get('safe_mode') == '1') ? true : false; + +// This parameter will be fixed in pwg_init() +$pwg_conf['gd_version_major'] = ''; +$pwg_conf['gd_version_full'] = ''; +$pwg_conf['gd_supported_format'] = array(); + +// +-----------------------------------------------------------------------+ +// | Functions | +// +-----------------------------------------------------------------------+ + +/** + * write line in log file + * + * @param string line + * @return string + */ +function pwg_log($line) +{ + $log_file = fopen(__FILE__.'.log', 'a'); + fwrite($log_file, $line); + fclose($log_file); +} + +/** + * Check web server graphical capabilities + * + * @return string + */ +function pwg_check_graphics() +{ + //~ pwg_log('>>>>> pwg_check_graphics() >>>>>'."\n"); + + global $conf, $pwg_conf; + $log = ''; + + // Verify gd library for thumbnail generation + if ($conf['thumbnail'] and !is_callable('gd_info')) + { + $log .= ' <code class="warning">Warning -</code> Your server can not generate thumbnails. Thumbnail creation switched off.<br />'."\n"; + // Switch off thumbnail generation + $conf['thumbnail'] = false; + return $log; + } + + // Verify thumnail format + if ($conf['thumbnail']) + { + $info = gd_info(); + + // Backup GD major version + $pwg_conf['gd_version_full'] = ereg_replace('[[:alpha:][:space:]()]+', '', $info['GD Version']); + list($pwg_conf['gd_version_major']) = preg_split('/[.]+/', $pwg_conf['gd_version_full']); + + // Backup input/output format support + array_push($pwg_conf['gd_supported_format'], $info['JPG Support'] ? 'jpeg' : NULL); + array_push($pwg_conf['gd_supported_format'], $info['PNG Support'] ? 'png' : NULL); + array_push($pwg_conf['gd_supported_format'], ($info['GIF Read Support'] and $info['GIF Create Support']) ? 'gif' : NULL); + + // Check output format support + if (!in_array($conf['thumbnail_format'], $pwg_conf['gd_supported_format'])) + { + $log .= ' <code class="warning">Warning -</code> Your server does not support thumbnail\'s <code>'; + $log .= $conf['thumbnail_format'].'</code> format. Thumbnail creation switched off.<br />'."\n"; + } + + switch ($conf['thumbnail_method']) + { + case 'exif': + { + // exif_thumbnail() must be callable + if (!is_callable('exif_thumbnail')) + { + $log .= ' <code class="warning">Warning -</code> Your server does not support thumbnail creation through EXIF datas. Thumbnail creation switched off.<br />'."\n"; + } + break; + } + case 'fixed': + { + // $conf['thumbnail_width'] > 0 + if (!is_numeric($conf['thumbnail_width']) or $conf['thumbnail_width'] <= 0) + { + $log .= ' <code class="failure">Failure -</code> Bad value <code>thumbnail_width = '; + $log .= var_export($conf['thumbnail_width'], true).'</code>. Thumbnail creation switched off.<br />'."\n"; + } + // $conf['thumbnail_height'] > 0 + if (!is_numeric($conf['thumbnail_height']) or $conf['thumbnail_height'] <= 0) + { + $log .= ' <code class="failure">Failure -</code> Bad value <code>thumbnail_height = '; + $log .= var_export($conf['thumbnail_height'], true).'</code>. Thumbnail creation switched off.<br />'."\n"; + } + break; + } + case 'ratio': + { + // 0 < $conf['thumbnail_ratio'] < 1 + if (!is_numeric($conf['thumbnail_ratio']) or $conf['thumbnail_ratio'] <= 0 or $conf['thumbnail_ratio'] >= 1) + { + $log .= ' <code class="failure">Failure -</code> Bad value <code>thumbnail_ratio = '; + $log .= var_export($conf['thumbnail_ratio'], true).'</code>. Thumbnail creation switched off.<br />'."\n"; + } + break; + } + case 'width': + { + // $conf['thumbnail_width'] > 0 + if (!is_numeric($conf['thumbnail_width']) or $conf['thumbnail_width'] <= 0) + { + $log .= ' <code class="failure">Failure -</code> Bad value <code>thumbnail_width = '; + $log .= var_export($conf['thumbnail_width'], true).'</code>. Thumbnail creation switched off.<br />'."\n"; + } + break; + } + case 'height': + { + // $conf['thumbnail_height'] > 0 + if (!is_numeric($conf['thumbnail_height']) or $conf['thumbnail_height'] <= 0) + { + $log .= ' <code class="failure">Failure -</code> Bad value <code>thumbnail_height = '; + $log .= var_export($conf['thumbnail_height'], true).'</code>. Thumbnail creation switched off.<br />'."\n"; + } + break; + } + default: + { + // unknown method + $log .= ' <code class="failure">Failure -</code> Bad value <code>thumbnail_method = '; + $log .= var_export($conf['thumbnail_method'], true).'</code>. Thumbnail creation switched off.<br />'."\n"; + break; + } + } + + if (strlen($log)) + { + $conf['thumbnail'] = false; + } + } + + //~ pwg_log('<<<<< pwg_check_graphics() returns '.var_export($log, TRUE).' <<<<<'."\n"); + return $log; +} + +/** + * returns xml </dirX> lines + * + * @param integer $dir_start + * @param integer $dir_number + * @return string + */ +function pwg_close_level($dir_start, $dir_number) +{ + //~ pwg_log('>>>>> pwg_close_level($dir_start = '.var_export($dir_start, TRUE).', $dir_number = '.var_export($dir_number, TRUE).') >>>>>'."\n"); + + $lines =''; + do + { + $lines .= str_repeat(' ', 2*$dir_start).'</dir'.$dir_start.">\n"; + $dir_number--; + $dir_start--; + } + while(($dir_number > 0) && ($dir_start >= 0)); + + //~ pwg_log('<<<<< pwg_close_level returns '.var_export($lines, TRUE).' <<<<<'."\n"); + return $lines; +} + +/** + * return a cleaned IPTC value + * + * @param string value + * @return string + */ +function pwg_clean_iptc_value($value) +{ + //~ pwg_log('>>>>> pwg_clean_iptc_value ($value = '.var_export($value, TRUE).') >>>>>'."\n"); + + // strip leading zeros (weird Kodak Scanner software) + while (isset($value[0]) and $value[0] == chr(0)) + { + $value = substr($value, 1); + } + // remove binary nulls + $value = str_replace(chr(0x00), ' ', $value); + + //~ pwg_log('<<<<< pwg_clean_iptc_value() returns '.var_export($value, TRUE).' <<<<<'."\n"); + return $value; +} + +/** + * returns informations from IPTC metadata, mapping is done at the beginning + * of the function + * + * @param string $filename + * @param string $map + * @return array + */ +function pwg_get_iptc_data($filename, $map) +{ + //~ pwg_log('>>>>> pwg_get_iptc_data ($filename = '.var_export($filename, TRUE).', $map = '.var_export($map, TRUE).') >>>>>'."\n"); + + $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('pwg_clean_iptc_value', $iptc[$iptc_key])); + } + else + { + $value = pwg_clean_iptc_value($iptc[$iptc_key][0]); + } + + foreach (array_keys($map, $iptc_key) as $pwg_key) + { + $result[$pwg_key] = $value; + } + } + } + } + } + + //~ pwg_log('<<<<< pwg_get_iptc_data() returns '.var_export($result, TRUE).' <<<<<'."\n"); + return $result; +} + +/** + * returns informations from IPTC metadata + * + * @param string $file + * @return array iptc + */ +function pwg_get_sync_iptc_data($file) +{ + //~ pwg_log('>>>>> pwg_get_sync_iptc_data ($file = '.var_export($file, TRUE).') >>>>>'."\n"); + + global $conf; + + $map = $conf['use_iptc_mapping']; + $datefields = array('date_creation', 'date_available'); + + $iptc = pwg_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)) + { + $value = $matches[1].'-'.$matches[2].'-'.$matches[3]; + } + } + if ($pwg_key == 'keywords') + { + // official keywords separator is the comma + $value = preg_replace('/[.;]/', ',', $value); + $value = preg_replace('/^,+|,+$/', '', $value); + } + $iptc[$pwg_key] = htmlentities($value); + } + + $iptc['keywords'] = isset($iptc['keywords']) ? implode(',', array_unique(explode(',', $iptc['keywords']))) : NULL; + + //~ pwg_log('<<<<< pwg_get_sync_iptc_data() returns '.var_export($iptc, TRUE).' <<<<<'."\n"); + return $iptc; +} + +/** + * return extension of the representative file + * + * @param string $file_dir + * @param string $file_short + * @return string + */ +function pwg_get_representative_ext($file_dir, $file_short) +{ + //~ pwg_log('>>>>> pwg_get_representative_ext($file_dir = '.var_export($file_dir, TRUE).', $file_short = '.var_export($file_short, TRUE).') >>>>>'."\n"); + + global $conf; + + $rep_ext = ''; + foreach ($conf['picture_ext'] as $ext) + { + if (file_exists($file_dir.'/'.$conf['represent'].'/'.$file_short.'.'.$ext)) + { + $rep_ext = $ext; + break; + } + } + + //~ pwg_log('<<<<< pwg_get_representative_ext() returns '.var_export($rep_ext, TRUE).' <<<<<'."\n"); + return $rep_ext; +} + +/** + * return 'true' if high resolution picture exists else '' + * + * @param string $file_dir + * @param string $file_base + * @return boolean + */ +function pwg_get_high($file_dir, $file_base) +{ + //~ pwg_log('>>>>> pwg_get_high($file = '.var_export($file_dir, TRUE).', $line = '.var_export($file_base, TRUE).') >>>>>'."\n"); + + global $conf; + + $high = false; + if (file_exists($file_dir.'/'.$conf['high'].'/'.$file_base)) + { + $high = true; + } + + //~ pwg_log('<<<<< pwg_get_high() returns '.var_export($high, TRUE).' <<<<<'."\n"); + return $high; +} + +/** + * return filename without extension + * + * @param string $filename + * @return string + */ +function pwg_get_filename_wo_extension($filename) +{ + //~ pwg_log('>>>>> _get_filename_wo_extension($filename = '.var_export($filename, TRUE).') >>>>>'."\n"); + + $short_name = substr($filename, 0, strrpos($filename, '.')); + + //~ pwg_log('<<<<< _get_filename_wo_extension() returns '.var_export($short_name, TRUE).' <<<<<'."\n"); + return $short_name; +} + +/** + * return extension of the thumbnail and complete error_log + * + * @param string $file_dir + * @param string $file_short + * @param string $file_ext + * @param string &$error_log + * @return string + */ +function pwg_get_thumbnail_ext($file_dir, $file_short, $file_ext, &$error_log) +{ + //~ pwg_log('>>>>> pwg_get_thumbnail_ext($file_dir = '.var_export($file_dir, TRUE).', $file_short = '.var_export($file_short, TRUE).') >>>>>'."\n"); + + global $conf; + + $thumb_ext = ''; + foreach ($conf['picture_ext'] as $ext) + { + if (file_exists($file_dir.'/'.$conf['thumbs'].'/'.$conf['prefix_thumbnail'].$file_short.'.'.$ext)) + { + $thumb_ext = $ext; + break; + } + } + + if ($thumb_ext == '') + { + if ($conf['thumbnail']) + { + $log = pwg_icon_file($file_dir, $file_short, $file_ext); + if (strpos($log, 'success')) + { + $thumb_ext = $conf['thumbnail_format']; + } + $error_log .= $log; + } + } + + //~ pwg_log('<<<<< pwg_get_thumbnail_ext() returns '.var_export($thumb_ext, TRUE).' <<<<<'."\n"); + return $thumb_ext; +} + + +/** + * return error logs + * + * @param string $file_dir + * @param string $file_short + * @param string $file_ext + * @return string + */ +function pwg_icon_file($file_dir, $file_short, $file_ext) +{ + //~ pwg_log('>>>>> pwg_icon_file($file_dir = '.var_export($file_dir, TRUE).', $file_short = '.var_export($file_short, TRUE).') >>>>>'."\n"); + + global $conf, $pwg_conf; + + $error_log = ''; + + // Get original properties (width, height) + if ($image_size = getimagesize($file_dir.'/'.$file_short.'.'.$file_ext)) + { + $src_width = $image_size[0]; + $src_height = $image_size[1]; + } + else + { + $error_log .= ' <code class="failure">Failure -</code> Can not generate icon for <code>'; + $error_log .= $file_dir.'/'.$file_short.'.'.$file_ext.'</code>'; + $error_log .= ' <img src="'.$pwg_conf['icon_dir'].'add_tag.png" title="width/height are unreadable" /><br />'."\n"; + return $error_log; + } + + // Check input format + $dst_format = $conf['thumbnail_format']; + $src_format = ($file_ext == 'jpg' or $file_ext == 'JPG') ? 'jpeg' : strtolower($file_ext); + if (!in_array($src_format, $pwg_conf['gd_supported_format'])) + { + $error_log .= ' <code class="failure">Failure -</code> Can not generate icon for <code>'; + $error_log .= $file_dir.'/'.$file_short.'.'.$file_ext.'</code>'; + $error_log .= ' <img src="'.$pwg_conf['icon_dir'].'add_tag.png" title="format not supported" /><br />'."\n"; + return $error_log; + } + + // Calculate icon properties (width, height) + switch ($conf['thumbnail_method']) + { + case 'fixed': + { + $dst_width = $conf['thumbnail_width']; + $dst_height = $conf['thumbnail_height']; + break; + } + case 'width': + { + $dst_width = $conf['thumbnail_width']; + $dst_height = $dst_width * $src_height / $src_width; + break; + } + case 'height': + { + $dst_height = $conf['thumbnail_height']; + $dst_width = $dst_height * $src_width / $src_height; + break; + } + case 'ratio': + { + $dst_width = round($src_width * $conf['thumbnail_ratio']); + $dst_height = round($src_height * $conf['thumbnail_ratio']); + break; + } + case 'exif': + default: + { + // Nothing to do + } + } + + // Creating icon + if ($conf['thumbnail_method'] == 'exif') + { + $src = exif_thumbnail($file_dir.'/'.$file_short.'.'.$file_ext, $width, $height, $imagetype); + if ($src === false) + { + $error_log .= ' <code class="failure">Failure -</code> No EXIF thumbnail in <code>'; + $error_log .= $file_dir.'/'.$file_short.'.'.$file_ext.'</code><br />'."\n"; + return $error_log; + } + $dst = imagecreatefromstring($src); + if ($src === false) + { + $error_log .= ' <code class="failure">Failure -</code> EXIF thumbnail format not supported in <code>'; + $error_log .= $file_dir.'/'.$file_short.'.'.$file_ext.'</code><br />'."\n"; + return $error_log; + } + } + else + { + if (($pwg_conf['gd_version_major'] != 2)) // or ($conf['thumbnail_format'] == 'gif')) + { + $dst = imagecreate($dst_width, $dst_height); + } + else + { + $dst = imagecreatetruecolor($dst_width, $dst_height); + } + $src = call_user_func('imagecreatefrom'.$src_format, $file_dir.'/'.$file_short.'.'.$file_ext); + if (!$src) + { + $error_log .= ' <code class="failure">Failure -</code> Internal error for <code>imagecreatefrom'.$src_format.'()</code>'; + $error_log .= 'with <code>'.$file_dir.'/'.$file_short.'.'.$file_ext.'</code><br />'."\n"; + return $error_log; + } + + if (($pwg_conf['gd_version_major'] != 2)) + { + if (!imagecopyresized($dst, $src, 0, 0, 0, 0, $dst_width, $dst_height, $src_width, $src_height)) + { + $error_log .= ' <code class="failure">Failure -</code> Internal error for <code>imagecopyresized()</code>'; + $error_log .= 'with <code>'.$file_dir.'/'.$file_short.'.'.$file_ext.'</code><br />'."\n"; + return $error_log; + } + } + else + { + if (!imagecopyresampled($dst, $src, 0, 0, 0, 0, $dst_width, $dst_height, $src_width, $src_height)) + { + $error_log .= ' <code class="failure">Failure -</code> Internal error for <code>imagecopyresampled()</code>'; + $error_log .= 'with <code>'.$file_dir.'/'.$file_short.'.'.$file_ext.'</code><br />'."\n"; + return $error_log; + } + } + } + + if (!call_user_func('image'.$dst_format, $dst, $file_dir.'/'.$conf['thumbs'].'/'.$conf['prefix_thumbnail'].$file_short.'.'.$conf['thumbnail_format'])) + { + $error_log .= ' <code class="failure">Failure -</code> Can not write <code>'; + $error_log .= $file_dir.'/'.$conf['thumbs'].'/'.$conf['prefix_thumbnail'].$file_short.'.'.$file_ext.'</code> to generate thumbnail<br />'."\n"; + return $error_log; + } + + $error_log .= ' <code class="success">Success -</code> Thumbnail generated for <code>'; + $error_log .= $file_dir.'/'.$file_short.'.'.$file_ext.'</code><br />'."\n"; + + //~ pwg_log('<<<<< pwg_icon_file() returns '.var_export($error_log, TRUE).' <<<<<'."\n"); + return $error_log; +} + +/** + * completes xml line <element .../> and returns error log + * + * @param string $file + * @param string &$line + * @return string + */ +function pwg_scan_file($file_full, &$line) +{ + //~ pwg_log('>>>>> pwg_scan_file($file = '.var_export($file_full, TRUE).', $line = '.var_export($line, TRUE).') >>>>>'."\n"); + + global $conf, $pwg_conf; + + $error_log =''; + + $file_base = basename($file_full); + $file_short = pwg_get_filename_wo_extension($file_base); + $file_ext = pwg_get_file_extension($file_base); + $file_dir = dirname($file_full); + + $element['file'] = $file_base; + $element['path'] = dirname($pwg_conf['this_url']).substr($file_dir, 1).'/'.$file_base; + + if (in_array($file_ext, $conf['picture_ext'])) + { + // Here we scan a picture : thumbnail is mandatory, high is optionnal, representative is not scanned + $element['tn_ext'] = pwg_get_thumbnail_ext($file_dir, $file_short, $file_ext, $error_log); + if ($element['tn_ext'] != '') + { + // picture has a thumbnail, get image width, heigth, size in Mo + $element['filesize'] = floor(filesize($file_full) / 1024); + if ($image_size = getimagesize($file_full)) + { + $element['width'] = $image_size[0]; + $element['height'] = $image_size[1]; + } + + // get high resolution + if (pwg_get_high($file_dir, $file_base)) + { + $element['has_high'] = 'true'; + + $high_file = $file_dir.'/'.$conf['high'].'/'.$file_base; + $element['high_filesize'] = floor(filesize($high_file) / 1024); + } + + // get EXIF meta datas + if ($conf['use_exif']) + { + // Verify activation of exif module + if (extension_loaded('exif')) + { + if ($exif = read_exif_data($file_full)) + { + foreach ($conf['use_exif_mapping'] as $pwg_key => $exif_key ) + { + if (isset($exif[$exif_key])) + { + if ( in_array($pwg_key, array('date_creation','date_available') ) ) + { + if (preg_match('/^(\d{4}):(\d{2}):(\d{2})/', $exif[$exif_key], $matches)) + { + $element[$pwg_key] = $matches[1].'-'.$matches[2].'-'.$matches[3]; + } + } + else + { + $element[$pwg_key] = $exif[$exif_key]; + } + } + } + } + } + } + + // get IPTC meta datas + if ($conf['use_iptc']) + { + $iptc = pwg_get_sync_iptc_data($file_full); + if (count($iptc) > 0) + { + foreach (array_keys($iptc) as $key) + { + $element[$key] = addslashes($iptc[$key]); + } + } + } + + } + else + { + $error_log .= ' <code class="failure">Failure -</code> Thumbnail is missing for <code>'.$file_dir.'/'.$file_base.'</code>'; + $error_log .= ' <img src="'.$pwg_conf['icon_dir'].'add_tag.png" title="'.$file_dir.'/thumbnail/'.$conf['prefix_thumbnail'].$file_short; + $error_log .= '.xxx ('.implode(', ', $conf['picture_ext']).')" /><br />'."\n"; + } + } + else + { + // Here we scan a non picture file : thumbnail and high are unused, representative is optionnal + $element['tn_ext'] = pwg_get_thumbnail_ext($file_dir, $file_short, $file_ext, $log); + $ext = pwg_get_representative_ext($file_dir, $file_short); + if ($ext != '') + { + $element['representative_ext'] = $ext; + } + } + + if (strlen($error_log) == 0) + { + $line = pwg_get_indent('element').'<element '; + foreach($element as $key => $value) + { + $line .= $key.'="'.$value.'" '; + } + $line .= '/>'."\n"; + } + + //~ pwg_log('<<<<< pwg_scan_file() returns '.var_export($error_log, TRUE).' <<<<<'."\n"); + return $error_log; +} + +/** + * returns current level in tree + * + * @return integer + */ +function pwg_get_level($dir) +{ + //~ pwg_log('>>>>> pwg_get_level($dir = '.var_export($dir, TRUE).') >>>>>'."\n"); + + $level = substr_count($dir, '/') - 1; // -1 because of ./ at the beginning of path + + //~ pwg_log('<<<<< pwg_get_level() returns '.var_export($level, TRUE).' <<<<<'."\n"); + return $level; +} + +/** + * returns indentation of element + * + * @param string $element_type : 'root', 'element', 'dir' + * @return string + */ +function pwg_get_indent($element_type) +{ + //~ pwg_log('>>>>> pwg_get_indent($element_type = '.var_export($element_type, TRUE).') >>>>>'."\n"); + + $level = substr_count($_SESSION['scan_list_fold'][0], '/') - 1; // because of ./ at the beginning + switch($element_type) + { + case 'dir' : + { + $indent = str_repeat(' ', 2*pwg_get_level($_SESSION['scan_list_fold'][0])); + break; + } + case 'root' : + { + $indent = str_repeat(' ', 2*pwg_get_level($_SESSION['scan_list_fold'][0])+2); + break; + } + case 'element' : + { + $indent = str_repeat(' ', 2*pwg_get_level($_SESSION['scan_list_fold'][0])+4); + break; + } + default : + { + $indent = ''; + break; + } + } + + //~ pwg_log('<<<<< pwg_get_indent() returns '.var_export(strlen($indent), TRUE).' spaces <<<<<'."\n"); + return $indent; +} + +/** + * create index.php in directory and reserved sub_directories, return logs + * + * @param string dir + * @return string + */ +function pwg_protect_directories($directory) +{ + //~ pwg_log('>>>>> pwg_protect_directories($directory = '.var_export($directory, true).') >>>>>'."\n"); + + global $conf; + + $error_log = ''; + $dirlist = array($directory, $directory.'/'.$conf['thumbs'], $directory.'/'.$conf['high'], $directory.'/'.$conf['represent']); + + foreach ($dirlist as $dir) + { + if (file_exists($dir)) + { + if (!file_exists($dir.'/index.php')) + { + $file = @fopen($dir.'/index.php', 'w'); + if ($file != false) + { + fwrite($file, $pwg_conf['protect_content']); // the return code should be verified + $error_log .= ' <code class="success">Success -</code> index.php created in directory <a href="'.$dir.'">'.$dir."</a><br />\n"; + } + else + { + $error_log .= ' <code class="failure">Failure -</code> Can not create index.php in directory <code>'.$dir."</code><br />\n"; + } + } + else + { + if ($conf['protect_warnings']) + { + $error_log .= ' <code class="warning">Warning -</code> index.php already exists in directory <a href="'.$dir.'">'.$dir."</a><br />\n"; + } + } + } + } + + //~ pwg_log('<<<<< pwg_protect_directories() returns '.var_export($error_log, true).' <<<<<'."\n"); + return $error_log; +} + +/** + * returns file extension (.xxx) + * + * @param string $file + * @return string + */ +function pwg_get_file_extension($file) +{ + //~ pwg_log('>>>>> pwg_get_file_extension($file = '.var_export($file, true).') >>>>>'."\n"); + + $ext = substr(strrchr($file, '.'), 1, strlen ($file)); + + //~ pwg_log('<<<<< pwg_get_file_extension() returns '.var_export($ext, true).' <<<<<'."\n"); + return $ext; +} + +/** + * completes directory list of supported files and returns error logs + * + * @param string $directory + * @return string + */ +function pwg_get_file_list($directory) +{ + //~ pwg_log('>>>>> pwg_get_file_list($directory = '.var_export($directory, true).') >>>>>'."\n"); + + global $conf, $pwg_conf; + + $errorLog = ''; + $dir = opendir($directory); + while (($file = readdir($dir)) !== false) + { + switch (filetype($directory."/".$file)) + { + case 'file' : + { + if (in_array(pwg_get_file_extension($file), $conf['file_ext'])) + { + // The file pointed is a regular file with a supported extension + array_push($_SESSION['scan_list_file'], $directory.'/'.$file); + //~ pwg_log('--->> Push in $_SESSION[scan_list_file] value "'.$directory.'/'.$file.'"'."\n"); + if (!preg_match('/^[a-zA-Z0-9-_.]+$/', $file)) + { + $errorLog .= ' <code class="failure">Failure -</code> Invalid file name for <code>'.$file.'</code> in <code>'.$directory.'</code>'; + $errorLog .= ' <img src="'.$pwg_conf['icon_dir'].'add_tag.png"'; + $errorLog .= ' title="Name should be composed of letters, figures, -, _ or . ONLY" /><br />'."\n"; + } + } + break; // End of filetype FILE + } + case 'dir' : + { + if(!in_array($file, $pwg_conf['reserved_directory_names'])) + { + // The file pointed is a directory but neither system directory nor reserved by PWG + array_push($_SESSION['scan_list_fold'], $directory.'/'.$file); + //~ pwg_log('--->> Push in $_SESSION[scan_list_fold] value "'.$directory.'/'.$file.'"'."\n"); + if (!preg_match('/^[a-zA-Z0-9-_.]+$/', $file)) + { + $errorLog .= ' <code class="failure">Failure -</code> Invalid directory name for <code>'.$directory.'/'.$file.'</code>'; + $errorLog .= ' <img src="'.$pwg_conf['icon_dir'].'add_tag.png"'; + $errorLog .= ' title="Name should be composed of letters, figures, -, _ or . ONLY" /><br />'."\n"; + } + } + break; // End of filetype DIR + } + case 'fifo' : + case 'char' : + case 'block' : + case 'link' : + case 'unknown': + default : + { + // PWG does not manage these cases + break; + } + } + } + closedir($dir); + + //~ pwg_log('<<<<< pwg_get_file_list() returns '.var_export($errorLog, true).' <<<<<'."\n"); + + return $errorLog; +} + +/** + * 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 pwg_get_moment() +{ + //~ pwg_log('>>>>> pwg_get_moment() >>>>>'."\n"); + + $t1 = explode(' ', microtime()); + $t2 = explode('.', $t1[0]); + $t2 = $t1[1].'.'.$t2[1]; + + //~ pwg_log('<<<<< pwg_get_moment() returns '.var_export($t2, true).' <<<<<'."\n"); + return $t2; +} + +/** + * return true if HTTP_REFERER and PHP_SELF are similar + * + * return boolean + */ +function pwg_referer_is_me() +{ + global $pwg_conf; + + //~ pwg_log('>>>>> pwg_referer_is_me() >>>>>'."\n"); + + $response = false; + $caller = (isset($_SERVER['HTTP_REFERER'])) ? $_SERVER['HTTP_REFERER'] : ''; + + if (strcasecmp($pwg_conf['this_url'], $caller) == 0) { + $response = true; + } + + //~ pwg_log('<<<<< pwg_referer_is_me() returns '.var_export($response, true).' <<<<<'."\n"); + return $response; +} + +// +-----------------------------------------------------------------------+ +// | pwg_<ACTION>_<STEP> Functions | +// +-----------------------------------------------------------------------+ + +function pwg_test_start() +{ + //~ pwg_log('>>>>> pwg_test_start() >>>>>'."\n"); + + global $g_message, $conf; + + if (isset($_REQUEST['version'])) + { + if ($_REQUEST['version'] != $conf['version']) + { + $g_message = '0'; + } + else + { + $g_message = '1'; + } + } + else + { + $g_message = '1'; + } + $_SESSION['scan_step'] = 'exit'; + + //~ pwg_log('<<<<< pwg_test_start() <<<<<'."\n"); +} + +function pwg_test_exit() +{ + //~ pwg_log('>>>>> pwg_test_exit() >>>>>'."\n"); + + global $g_header, $g_message, $g_footer, $conf, $pwg_conf; + + if (pwg_referer_is_me()) + { + $g_header = ' : <span class="success">Test</span>'."\n"; + $g_footer = '<a href="'.$pwg_conf['this_url'].'" title="Main menu"><img src="'.$pwg_conf['icon_dir'].'up.png" /></a>'."\n"; + + // Write version + $g_message = ' <h3>Script version</h3>'."\n"; + $g_message .= ' This script is tagged : <code class="failure">'.$conf['version'].'</code>'."\n"; + // write GD support + if (!is_callable('gd_info')) + { + $g_message .= ' <code class="failure">Failure -</code> Your server can not generate imagess<br />'."\n"; + } + else + { + $info = gd_info(); + $gd_full_version = ereg_replace('[[:alpha:][:space:]()]+', '', $info['GD Version']); + list($gd_version) = preg_split('/[.]+/', $gd_full_version); + + $g_message .= ' <h3>Image generation</h3>'."\n"; + $g_message .= ' <code class="success">Success -</code> Your server can generate images<br />'."\n"; + $g_message .= ' <code class="warning">Warning -</code> Your server support GD'.$gd_version.' (v'.$gd_full_version.')<br />'."\n"; + $format_list = array(); + $format = ($info['GIF Create Support']) ? '<code>gif</code>' : NULL; + array_push($format_list, $format); + $format = ($info['JPG Support']) ? '<code>jpg</code>' : NULL; + array_push($format_list, $format); + $format = ($info['PNG Support']) ? '<code>png</code>' : NULL; + array_push($format_list, $format); + $g_message .= ' <code class="warning">Warning -</code> Your server support format: '.implode(', ', $format_list)."\n"; + } + + $g_message .= ' <h3>Directory parsing</h3>'."\n"; + if ($pwg_conf['safe_mode']) + { + $g_message .= ' <code class="warning">Warning -</code> Your server does not support to resize execution time'."\n"; + } + else + { + $g_message .= ' <code class="success">Success -</code> Your server supports to resize execution time'."\n"; + } + } + else + { + // compare version in GET parameter with $conf['version'] + if ($g_message == '1') + { + exit('<pre>PWG-INFO-2: test successful</pre>'); + } + else + { + exit('<pre>PWG-ERROR-4: Piwigo versions differs</pre>'); + } + } + + //~ pwg_log('<<<<< pwg_test_exit() <<<<<'."\n"); +} + +function pwg_clean_start() +{ + //~ pwg_log('>>>>> pwg_clean_start() >>>>>'."\n"); + + global $g_message; + + if(@unlink('./listing.xml')) + { + $g_message = '1'; + } + else + { + $g_message = '0'; + } + + $_SESSION['scan_step'] = 'exit'; + + //~ pwg_log('<<<<< pwg_clean_start() <<<<<'."\n"); +} + +function pwg_clean_exit() +{ + //~ pwg_log('>>>>> pwg_clean_exit() >>>>>'."\n"); + + global $g_header, $g_message, $g_footer, $conf, $pwg_conf; + + if(pwg_referer_is_me()) + { + $g_header = ' : <span class="success">Clean</span>'; + if ($g_message == '1') + { + $g_message = ' <code class="success">Success -</code> <code>listing.xml</code> file deleted'."\n"; + } + else + { + $g_message = ' <code class="failure">Failure -</code> <code>listing.xml</code> does not exist or is read only'."\n"; + } + $g_footer = '<a href="'.$pwg_conf['this_url'].'" title="Main menu"><img src="'.$pwg_conf['icon_dir'].'up.png" /></a>'; + } + else + { + if ($g_message == '1') + { + exit('<pre>PWG-INFO-3 : listing.xml file deleted</pre>'); + } + else + { + exit('<pre>PWG-ERROR-3 : listing.xml does not exist</pre>'); + } + } + + //~ pwg_log('<<<<< pwg_clean_exit() <<<<<'."\n"); +} + +function pwg_generate_start() +{ + //~ pwg_log('>>>>> pwg_generate_start() >>>>>'."\n"); + //~ pwg_log("GENARATE start >>>\n".var_export($_SESSION['scan_list_fold'], true)."\n".var_export($_SESSION['scan_list_file'], true)."\nGENERATE start >>>\n"); + + global $g_listing, $pwg_conf, $conf; + + // Flush line <informations> + $xml_header_url = dirname($pwg_conf['this_url']); + $xml_header_date = date('Y-m-d'); + $xml_header_version = htmlentities($conf['version']); + + $attrs = array(); + if ($conf['use_iptc']) + { + $attrs = array_merge($attrs, array_keys($conf['use_iptc_mapping']) ); + } + if ($conf['use_exif']) + { + $attrs = array_merge($attrs, array_keys($conf['use_exif_mapping']) ); + } + $xml_header_metadata = implode(',',array_unique($attrs)); + + $xml_header = '<informations'; + $xml_header .= ' generation_date="'.$xml_header_date.'"'; + $xml_header .= ' phpwg_version="'.$xml_header_version.'"'; + $xml_header .= ' metadata="'.$xml_header_metadata.'"'; + $xml_header .= ' url="'.$xml_header_url.'"'; + $xml_header .= '>'."\n"; + + fwrite($g_listing, $xml_header); + + // Initialization of directory and file lists + $_SESSION['scan_list_fold'] = array(); + $_SESSION['scan_list_file'] = array(); + $_SESSION['scan_logs'] .= pwg_get_file_list('.'); + sort($_SESSION['scan_list_fold']); + + // Erase first file list because root directory does not contain images. + $_SESSION['scan_list_file'] = array(); + + // What are we doing at next step + if(count($_SESSION['scan_list_fold']) > 0) + { + $_SESSION['scan_step'] = 'list'; + } + else + { + $_SESSION['scan_step'] = 'stop'; + } + + //~ pwg_log("GENARATE start <<<\n".var_export($_SESSION['scan_list_fold'], true)."\n".var_export($_SESSION['scan_list_file'], true)."\nGENERATE start <<<\n"); + //~ pwg_log('<<<<< pwg_generate_start() <<<<<'."\n"); +} + +function pwg_generate_list() +{ + //~ pwg_log('>>>>> pwg_generate_list() >>>>>'."\n"); + //~ pwg_log("GENARATE list >>>\n".var_export($_SESSION['scan_list_fold'], true)."\n".var_export($_SESSION['scan_list_file'], true)."\nGENERATE list >>>\n"); + + global $g_listing; + + // Flush line <dirX name=""> in xml file + $dirname = basename($_SESSION['scan_list_fold'][0]); + $line = pwg_get_indent('dir').'<dir'.pwg_get_level($_SESSION['scan_list_fold'][0]).' name="'.$dirname.'">'."\n"; + fwrite($g_listing, $line); + + // Get list of files and directories + $_SESSION['scan_logs'] .= pwg_get_file_list($_SESSION['scan_list_fold'][0]); + sort($_SESSION['scan_list_fold']); // Mandatory to keep the tree order + sort($_SESSION['scan_list_file']); // Easier to read when sorted + + // Flush line <root> + $line = pwg_get_indent('root').'<root>'."\n"; + fwrite($g_listing, $line); + + // What are we doing at next step + $_SESSION['scan_step'] = 'scan'; + + //~ pwg_log("GENARATE list <<<\n".var_export($_SESSION['scan_list_fold'], true)."\n".var_export($_SESSION['scan_list_file'], true)."\nGENERATE list <<<\n"); + //~ pwg_log('<<<<< pwg_generate_list() <<<<<'."\n"); +} + +function pwg_generate_scan() +{ + //~ pwg_log('>>>>> pwg_generate_scan() >>>>>'."\n"); + //~ pwg_log("GENARATE scan >>>\n".var_export($_SESSION['scan_list_fold'], true)."\n".var_export($_SESSION['scan_list_file'], true)."\nGENERATE scan >>>\n"); + + global $g_listing, $conf; + + while (pwg_continue() and count($_SESSION['scan_list_file']) > 0) + { + $line = ''; + $_SESSION['scan_logs'] .= pwg_scan_file($_SESSION['scan_list_file'][0], $line); + + if (strlen($line) > 0) + { + fwrite($g_listing, $line); + } + //~ pwg_log('---<< Pull of $_SESSION[scan_list_file] value "'.$_SESSION['scan_list_file'][0].'"'."\n"); + array_shift($_SESSION['scan_list_file']); + $_SESSION['scan_cnt_file']++; + } + + if (count($_SESSION['scan_list_file']) <= 0) + { + $_SESSION['scan_step'] = 'prot'; + } + + //~ pwg_log("GENERATE scan <<<\n".var_export($_SESSION['scan_list_fold'], true)."\n".var_export($_SESSION['scan_list_file'], true)."\nGENERATE scan <<<\n"); + //~ pwg_log('<<<<< pwg_generate_scan() <<<<<'."\n"); +} + +function pwg_generate_prot() +{ + //~ pwg_log('>>>>> pwg_generate_prot() >>>>>'."\n"); + //~ pwg_log("GENARATE prot >>>\n".var_export($_SESSION['scan_list_fold'], true)."\n".var_export($_SESSION['scan_list_file'], true)."\nGENERATE prot >>>\n"); + + global $conf, $g_listing; + + // Flush line </root> + $line = pwg_get_indent('root').'</root>'."\n"; + fwrite($g_listing, $line); + + if ($conf['protect']) + { + $_SESSION['scan_logs'] .= pwg_protect_directories($_SESSION['scan_list_fold'][0]); + } + + // How many directories to close + $current_level = pwg_get_level($_SESSION['scan_list_fold'][0]); + if (isset($_SESSION['scan_list_fold'][1])) + { + //~ pwg_log('---<< Pull of $_SESSION[scan_list_fold] value "'.$_SESSION['scan_list_fold'][0].'"'."\n"); + array_shift($_SESSION['scan_list_fold']); + $_SESSION['scan_cnt_fold']++; + $next_level = pwg_get_level($_SESSION['scan_list_fold'][0]); + $_SESSION['scan_step'] = 'list'; + } + else + { + $next_level = -1; + $_SESSION['scan_cnt_fold']++; + $_SESSION['scan_step'] = 'stop'; + } + + if ($current_level == $next_level) + { + fwrite($g_listing, pwg_close_level($current_level, 1)); + } + else + { + if (($current_level > $next_level)) + { + fwrite($g_listing, pwg_close_level($current_level, $current_level-$next_level+1)); + } // Nothing to do if current_level < next_level + } + + //~ pwg_log("GENERATE prot <<<\n".var_export($_SESSION['scan_list_fold'], true)."\n".var_export($_SESSION['scan_list_file'], true)."\nGENERATE prot <<<\n"); + //~ pwg_log('<<<<< pwg_generate_prot() <<<<<'."\n"); +} + +function pwg_generate_stop() +{ + //~ pwg_log('>>>>> pwg_generate_stop() >>>>>'."\n"); + //~ pwg_log("GENARATE stop >>>\n".var_export($_SESSION['scan_list_fold'], true)."\n".var_export($_SESSION['scan_list_file'], true)."\nGENERATE stop >>>\n"); + + global $pwg_conf, $g_listing, $g_header, $g_message, $g_footer; + + // Flush line </informations> + fwrite($g_listing, '</informations>'."\n"); + + // backup error log before cleaning session + $time_elapsed = number_format(pwg_get_moment() - $_SESSION['scan_time'], 3, '.', ' '); + + $g_header = ' : <span class="success">Generate</span>'; + $g_message = ' <div>'."\n".$_SESSION['scan_logs'].' </div>'."\n"; + $g_message .= ' <div><code class="success">'.$_SESSION['scan_cnt_fold'].'</code> directories parsed<br />'."\n"; + $g_message .= ' <code class="success">'.$_SESSION['scan_cnt_file'].'</code> files scanned</div>'."\n"; + $g_message .= ' <div>View <a href="listing.xml">listing.xml</a></div>'."\n"; + $g_message .= ' <div style="{text-align: right;}">Listing generated in : <code>'.$time_elapsed.' s</code></div>'; + $g_footer = '<a href="'.$pwg_conf['this_url'].'" title="Main menu"><img src="'.$pwg_conf['icon_dir'].'up.png" /></a>'; + + // What are we doing at next step + $_SESSION['scan_step'] = 'exit'; + + //~ pwg_log("GENARATE stop <<<\n".var_export($_SESSION['scan_list_fold'], true)."\n".var_export($_SESSION['scan_list_file'], true)."\nGENERATE stop <<<\n"); + //~ pwg_log('<<<<< pwg_generate_stop() <<<<<'."\n"); +} + +// +-----------------------------------------------------------------------+ +// | ALWAYS CALLED FUNCTIONS | +// +-----------------------------------------------------------------------+ + +/** + * This function check step and time ellapsed to determine end of loop + * + * @return bool + */ +function pwg_continue() +{ + //~ pwg_log('>>>>> pwg_continue() >>>>>'."\n"); + + global $conf, $pwg_conf, $g_refresh, $g_header, $g_message, $g_footer, $start_time; + + if (!isset($_SESSION['scan_step']) or $_SESSION['scan_step'] == 'exit') + { + // evident end of process + $return = false; + } + else + { + if ($pwg_conf['safe_mode'] or $conf['force_refresh_method']) + { + // can not reset the time + $time_elapsed = pwg_get_moment() - $start_time; + if ($time_elapsed < $conf['max_execution_time']) + { + $return = true; + } + else + { + $start_time = $_SESSION['scan_time']; + $formated_time = number_format(pwg_get_moment() - $start_time, 3, '.', ' '); + + $g_refresh = '<meta http-equiv="Refresh" content="'.$conf['refresh_delay'].'">'."\n"; + $g_header = ' : <span class="success">'.ucfirst($_SESSION['scan_action']).'</span>'; + $g_message = ''; + if ($_SESSION['scan_cnt_fold'] != 0) + { + $g_message .= '<code class="success">'.$_SESSION['scan_cnt_fold'].'</code> directories scanned<br />'."\n"; + } + if ($_SESSION['scan_cnt_file'] != 0) + { + $g_message .= '<code class="success">'.$_SESSION['scan_cnt_file'].'</code> files scanned<br />'."\n"; + } + $nb = count($_SESSION['scan_list_fold']); + if ($nb > 0) + { + $g_message .= '<code class="warning">'.$nb.'</code> directories to scan<br />'."\n"; + } + $nb = count($_SESSION['scan_list_file']); + if ($nb > 0) + { + $g_message .= '<code class="warning">'.$nb.'</code> files to scan<br />'."\n"; + } + $g_message .= ' <div style="{text-align: right;}">Time elapsed : <code>'.$formated_time.' s</code></div>'; + $g_footer = '<a href="'.$pwg_conf['this_url'].'?action='.$_SESSION['scan_action'].'" title="Continue"><img src="'.$pwg_conf['icon_dir'].'right.png" /></a>'."\n"; + + $return = false; + } + } + else + { + // reset the time + set_time_limit(intval(ini_get('max_execution_time'))); + $return = true; + } + } + //~ pwg_log('<<<<< pwg_continue() returns '.var_export($return, true).' <<<<<'."\n"); + + return $return; +} + +/** + * This function : + * -> Verify the script call + * -> Lock the script + * -> Open listing.xml if action is 'generate' + * -> Initialize output and session variables + * + * @return nothing + */ +function pwg_init() +{ + //~ pwg_log('>>>>> pwg_init() >>>>>'."\n"); + + global $g_message, $g_listing, $g_footer, $conf, $pwg_conf, $start_time; + $init_message = ''; + + // Lock other script sessions, this lock will be remove during 'exit' step + if (!isset($_SESSION['scan_step'])) + { + $fp = @fopen(__FILE__.'.lock', 'x+'); // return false if __FILE__.lock exists or if cannot create + if ($fp == false) + { + $g_header = $_SESSION['scan_action']; + $g_message = ' <code class="failure">Failure -</code> Another script is running'; + $g_message .= ' <img src="'.$pwg_conf['icon_dir'].'add_tag.png" title="Delete file '.__FILE__.'.lock and retry" />'; + $g_message .= "\n"; + $g_footer = '<a href="'.$pwg_conf['this_url'].'" title="Main menu"><img src="'.$pwg_conf['icon_dir'].'up.png" /></a>'."\n"; + $_SESSION['scan_step'] = 'exit'; + //~ pwg_log('<<<<< pwg_init() failure <<<<<'."\n"); + return; + } + else + { + fwrite($fp, session_id()); // Writing session_id to trace lock + fclose($fp); + $_SESSION['scan_step'] = 'init'; + } + } + + // Verify and backup parameter action. This backup will be removed during step 'exit' + if (isset($_REQUEST['action'])) + { + if (in_array($_REQUEST['action'], $pwg_conf['scan_action'])) + { + if (isset($_SESSION['scan_action'])) + { + if ($_SESSION['scan_action'] != $_REQUEST['action']) + { + // Fatal error + $g_message = ' <code class="failure">Failure -</code> Parameter <code>action</code> differs between url and session'; + $g_message .= "\n"; + $g_footer = '<a href="'.$pwg_conf['this_url'].'" title="Main menu"><img src="'.$pwg_conf['icon_dir'].'up.png" /></a>'."\n"; + $_SESSION['scan_step'] = 'exit'; + //~ pwg_log('<<<<< pwg_init() failure <<<<<'."\n"); + return; + } + } + else + { + $_SESSION['scan_action'] = $_REQUEST['action']; + } + } + else + { + // Fatal error + $g_message = ' <code class="failure">Failure -</code> Problem with <code>action</code> parameter'; + $g_message .= ' <img src="'.$pwg_conf['icon_dir'].'add_tag.png" title="empty, '.implode(', ', $pwg_conf['scan_action']).'" />'; + $g_message .= "\n"; + $g_footer = '<a href="'.$pwg_conf['this_url'].'" title="Main menu"><img src="'.$pwg_conf['icon_dir'].'up.png" /></a>'."\n"; + $_SESSION['scan_step'] = 'exit'; + //~ pwg_log('<<<<< pwg_init() failure <<<<<'."\n"); + return; + } + } + else + { + // Here we are on welcome page + $g_message = ' <ul>'."\n"; + $g_message .= ' <li><a href="'.$pwg_conf['this_url'].'?action=test" title="Display/Compare script version">Test</a></li>'."\n"; + $g_message .= ' <li><a href="'.$pwg_conf['this_url'].'?action=clean" title="Delete listing.xml if exists">Clean</a></li>'."\n"; + $g_message .= ' <li><a href="'.$pwg_conf['this_url'].'?action=generate" title="Scan all images from this directory and write informations in listing.xml">Listing</a></li>'."\n"; + $g_message .= ' </ul>'."\n"; + $g_footer = '<a href="'.$conf['gallery'].'/admin.php?page=site_manager" title="Main gallery :: site manager">'; + $g_footer .= '<img src="'.$pwg_conf['icon_dir'].'home.png" /></a>'."\n"; + $_SESSION['scan_step'] = 'exit'; + $_SESSION['scan_action'] = ''; + } + + // Actions to do at the init of generate + if ($_SESSION['scan_action'] == 'generate') + { + // Open XML file + $mode = ($_SESSION['scan_step'] == 'init') ? 'w' : 'a'; // Erase old listing.xml at the beginning of generation (mode w) + $g_listing = @fopen('listing.xml', $mode); + if ($g_listing === false) + { + $g_header = $_SESSION['scan_action']; + $g_message = ' <code class="failure">Failure -</code> Can not write file <code>listing.xml</code>'; + $g_message .= "\n"; + $g_footer = '<a href="'.$pwg_conf['this_url'].'" title="Main menu"><img src="'.$pwg_conf['icon_dir'].'up.png" /></a>'."\n"; + $_SESSION['scan_step'] = 'exit'; + //~ pwg_log('<<<<< pwg_init() failure <<<<<'."\n"); + return; + } + + // Check graphical capabilities + $init_message = pwg_check_graphics(); + } + + // Initializing session counters. This counters will be completely unset during step 'exit' + if ($_SESSION['scan_step'] == 'init') + { + $_SESSION['scan_list_file'] = array(); + $_SESSION['scan_list_fold'] = array(); + $_SESSION['scan_cnt_file'] = 0; + $_SESSION['scan_cnt_fold'] = 0; + $_SESSION['scan_time'] = $start_time; + $_SESSION['scan_step'] = 'start'; + $_SESSION['scan_logs'] = $init_message; + } + + //~ pwg_log('<<<<< pwg_init() success <<<<<'."\n"); +} + +/** + * This function : + * -> Close listing.xml if action is 'generate' + * -> Unlock the script + * -> Erase session variables + * + * @return nothing + */ +function pwg_exit() +{ + //~ pwg_log('>>>>> pwg_exit() >>>>>'."\n"); + + global $g_listing; + + // Close XML file + if ($_SESSION['scan_action'] == 'generate' and $g_listing != false) + { + fclose($g_listing); + } + + // Unlock script + unlink(__FILE__.'.lock'); + + // Erase session counters + unset($_SESSION['scan_list_file']); + unset($_SESSION['scan_list_fold']); + unset($_SESSION['scan_cnt_file']); + unset($_SESSION['scan_cnt_fold']); + unset($_SESSION['scan_time']); + unset($_SESSION['scan_step']); + $local_action = $_SESSION['scan_action']; + unset($_SESSION['scan_action']); + unset($_SESSION['scan_logs']); + session_destroy(); + + // Call specific action post process + if (is_callable('pwg_'.$local_action.'_exit')) + { + call_user_func('pwg_'.$local_action.'_exit'); + } + + //~ pwg_log('<<<<< pwg_exit() <<<<<'."\n"); +} + +// +-----------------------------------------------------------------------+ +// | Script | +// +-----------------------------------------------------------------------+ +session_save_path('.'); +session_start(); + +$start_time = pwg_get_moment(); + +// Initializing message for web page +$g_refresh = ''; +$g_header = ''; +$g_message = ''; +$g_footer = ''; +$g_listing = ''; + +pwg_init(); + +while(pwg_continue()) +{ + if (is_callable('pwg_'.$_SESSION['scan_action'].'_'.$_SESSION['scan_step'])) + { + call_user_func('pwg_'.$_SESSION['scan_action'].'_'.$_SESSION['scan_step']); // Run the step : start, list, scan, stop are available + } + else + { + $g_header = $_SESSION['scan_action']; + $g_message = ' <code class="failure">Failure -</code> INTERNAL STEP ERROR : <code>pwg_'.$_SESSION['scan_action'].'_'.$_SESSION['scan_step'].'()</code> undefined'; + $g_message .= "\n"; + $g_footer = '<a href="'.$pwg_conf['this_url'].'" title="Main menu"><img src="'.$pwg_conf['icon_dir'].'up.png" /></a>'."\n"; + $_SESSION['scan_step'] = 'exit'; + } +} + +if ($_SESSION['scan_step'] == 'exit') +{ + pwg_exit(); +} + +?> +<html> + <head> + <?php echo $g_refresh; ?> + <title>Manage remote gallery</title> + </head> + <style type="text/css"> + code {font-weight: bold} + img {border-style: none; vertical-align: middle} + ul {list-style-image: url(<?php echo $pwg_conf['icon_dir']; ?>add_tag.png)} + .success {color: green} + .warning {color: orange} + .failure {color: red} + .header {text-align: center; font-variant: small-caps; font-weight: bold;} + .p {color: #F93;} + .w {color: #ccc;} + .g {color: #69C;} + .pwg {text-decoration: none; border-bottom-style: dotted; border-bottom-width: 1px;} + .content {width: 75%; position: absolute; top: 10%; left: 12%;} + .footer {text-align: right;} + .pwg_block {float: left;} + </style> + <body> + <div class="content"> + <fieldset class="header"> + <span class="p">Pi</span> + <span class="w">wi</span> + <span class="g">go</span> + remote site<? echo $g_header; ?> + </fieldset> + <fieldset> +<?php echo $g_message; ?> + </fieldset> + <fieldset class="footer"> + <div class="pwg_block"> + Powered by <a href="http://piwigo.org" class="pwg"><span class="p">Pi</span><span class="w">wi</span><span class="g">go</span></a> + </div> + <?php echo $g_footer; ?> + </fieldset> + </div> + </body> +</html> |