source: branches/branch-1_7/tools/create_listing_file.php @ 1937

Last change on this file since 1937 was 1937, checked in by plg, 18 years ago

Change PWG version to "branch 1.7"

  • Property svn:eol-style set to LF
  • Property svn:keywords set to Author Date Id Revision
File size: 54.4 KB
Line 
1<?php
2// +-----------------------------------------------------------------------+
3// | PhpWebGallery - a PHP based picture gallery                           |
4// | Copyright (C) 2002-2003 Pierrick LE GALL - pierrick@phpwebgallery.net |
5// | Copyright (C) 2003-2005 PhpWebGallery Team - http://phpwebgallery.net |
6// +-----------------------------------------------------------------------+
7// | branch        : BSF (Best So Far)
8// | file          : $RCSfile$
9// | last update   : $Date: 2007-04-06 17:34:28 +0000 (Fri, 06 Apr 2007) $
10// | last modifier : $Author: plg $
11// | revision      : $Revision: 1937 $
12// +-----------------------------------------------------------------------+
13// | This program is free software; you can redistribute it and/or modify  |
14// | it under the terms of the GNU General Public License as published by  |
15// | the Free Software Foundation                                          |
16// |                                                                       |
17// | This program is distributed in the hope that it will be useful, but   |
18// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
19// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
20// | General Public License for more details.                              |
21// |                                                                       |
22// | You should have received a copy of the GNU General Public License     |
23// | along with this program; if not, write to the Free Software           |
24// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
25// | USA.                                                                  |
26// +-----------------------------------------------------------------------+
27
28// +-----------------------------------------------------------------------+
29// |                                User configuration                     |
30// +-----------------------------------------------------------------------+
31
32// ****** Gallery configuration ****** //
33// Script version
34$conf['version'] = 'branch 1.7';
35
36// URL of main gallery
37// Example : http://www.my.domain/my/directory
38$conf['gallery'] = 'http://';
39
40// prefix for thumbnails in "thumbnail" sub directories
41$conf['prefix_thumbnail'] = 'TN-';
42
43// $conf['file_ext'] lists all extensions (case insensitive) allowed for your PhpWebGallery installation
44$conf['file_ext'] = array('jpg','JPG','jpeg','JPEG','png','PNG','gif','GIF','mpg','zip', 'avi','mp3','ogg');
45
46// $conf['picture_ext'] must be a subset of $conf['file_ext']
47$conf['picture_ext'] = array('jpg','JPG','jpeg','JPEG','png','PNG','gif','GIF');
48
49// ****** Time limitation functionality ****** //
50// max execution time before refresh in seconds
51$conf['max_execution_time'] = (5*ini_get('max_execution_time'))/6; // 25 seconds with default PHP configuration
52
53// refresh delay is seconds
54$conf['refresh_delay'] = 0;
55
56// ****** EXIF support functionality ****** //
57// $conf['use_exif'] set to true if you want to use Exif information
58$conf['use_exif'] = false;
59
60// use_exif_mapping: same behaviour as use_iptc_mapping
61$conf['use_exif_mapping'] = array(
62  'date_creation' => 'DateTimeOriginal'
63  );
64
65// ****** IPTC support functionality ****** //
66// $conf['use_iptc'] set to true if you want to use IPTC informations of the
67// element according to get_sync_iptc_data function mapping, otherwise, set
68// to false
69$conf['use_iptc'] = false;
70
71// use_iptc_mapping : in which IPTC fields will PhpWebGallery find image
72// information ? This setting is used during metadata synchronisation. It
73// associates a phpwebgallery_images column name to a IPTC key
74$conf['use_iptc_mapping'] = array(
75  'keywords'        => '2#025',
76  'date_creation'   => '2#055',
77  'author'          => '2#122',
78  'name'            => '2#005',
79  'comment'         => '2#120');
80
81// ****** Directory protection functionality ****** //
82// Define if directories have to be protected if they are not
83$conf['protect'] = false;
84
85// index.php content for command 'protect'
86$conf['protect_content'] = '<?php header("Location: '.$conf['gallery'].'") ?>';
87
88// true/false : show/hide warnings
89$conf['protect_warnings'] = true;
90
91// ****** Thumbnails generation functionality ****** //
92// Define if images have to be reduced if they are not
93$conf['thumbnail'] = false;
94
95// Define method to generate thumbnails :
96// - fixed (width and height required);
97// - width (only width required);
98// - height (only height required);
99// - ratio (only ratio is required)
100// - exif (no other parameter required)
101$conf['thumbnail_method'] = 'ratio';
102
103// Height in pixels (greater than 0)
104$conf['thumbnail_height'] = 128;
105
106// Width in pixels (greater than 0)
107$conf['thumbnail_width'] = 128;
108
109// Ratio between original and thumbnail size (strictly between 0 and 1)
110$conf['thumbnail_ratio'] = 0.2;
111
112// Define thumbnail format : jpeg, png or gif (will be verified)
113$conf['thumbnail_format'] = 'jpeg';
114
115// ****** Directory mapping ****** //
116// directories names
117$conf['thumbs'] = 'thumbnail'; // thumbnails
118$conf['high'] = 'pwg_high'; // high resolution
119$conf['represent'] = 'pwg_representative'; // non pictures representative files
120
121// +-----------------------------------------------------------------------+
122// |                                Advanced script configuration          |
123// +-----------------------------------------------------------------------+
124
125// url of icon directory in yoga template
126$pwg_conf['icon_dir'] = $conf['gallery'].'/template/yoga/icon/';
127
128// list of actions managed by this script
129$pwg_conf['scan_action'] = array('clean', 'test', 'generate');
130
131// url of this script
132$pwg_conf['this_url'] = 'http://'.$_SERVER['SERVER_NAME'].$_SERVER['PHP_SELF'];
133
134// list of reserved directory names
135$pwg_conf['reserved_directory_names'] = array($conf['thumbs'], $conf['high'], $conf['represent'], ".", "..", ".svn");
136
137// content of index.php generated in protect action
138$pwg_conf['protect_content'] = '<?php header("Location: '.$conf['gallery'].'") ?>';
139
140// backup of PHP safe_mode INI parameter (used for time limitation)
141$pwg_conf['safe_mode'] = (ini_get('safe_mode') == '1') ? true : false;
142
143// This parameter will be fixed in pwg_init()
144$pwg_conf['gd_version_major'] = '';
145$pwg_conf['gd_version_full'] = '';
146$pwg_conf['gd_supported_format'] = array();
147
148// +-----------------------------------------------------------------------+
149// |                               Functions                               |
150// +-----------------------------------------------------------------------+
151
152/**
153 * write line in log file
154 *
155 * @param string line
156 * @return string
157 */
158function pwg_log($line)
159{
160  $log_file = fopen(__FILE__.'.log', 'a');
161  fwrite($log_file, $line);
162  fclose($log_file);
163}
164
165/**
166 * Check web server graphical capabilities
167 *
168 * @return string
169 */
170function pwg_check_graphics()
171{
172  //~ pwg_log('>>>>> pwg_check_graphics() >>>>>'."\n");
173 
174  global $conf, $pwg_conf;
175  $log = '';
176 
177  // Verify gd library for thumbnail generation
178  if ($conf['thumbnail'] and !is_callable('gd_info'))
179  {
180    $log .= '          <code class="warning">Warning -</code> Your server can not generate thumbnails. Thumbnail creation switched off.<br />'."\n";
181    // Switch off thumbnail generation
182    $conf['thumbnail'] = false;
183    return $log;
184  }
185 
186  // Verify thumnail format
187  if ($conf['thumbnail'])
188  {
189    $info = gd_info();
190   
191    // Backup GD major version
192    $pwg_conf['gd_version_full'] = ereg_replace('[[:alpha:][:space:]()]+', '', $info['GD Version']);
193    list($pwg_conf['gd_version_major']) = preg_split('/[.]+/', $pwg_conf['gd_version_full']);
194   
195    // Backup input/output format support
196    array_push($pwg_conf['gd_supported_format'], $info['JPG Support'] ? 'jpeg' : NULL);
197    array_push($pwg_conf['gd_supported_format'], $info['PNG Support'] ? 'png' : NULL);
198    array_push($pwg_conf['gd_supported_format'], ($info['GIF Read Support'] and $info['GIF Create Support']) ? 'gif' : NULL);
199   
200    // Check output format support
201    if (!in_array($conf['thumbnail_format'], $pwg_conf['gd_supported_format']))
202    {
203      $log .= '          <code class="warning">Warning -</code> Your server does not support thumbnail\'s <code>';
204      $log .= $conf['thumbnail_format'].'</code> format. Thumbnail creation switched off.<br />'."\n";
205    }
206   
207    switch ($conf['thumbnail_method'])
208    {
209      case 'exif':
210      {
211        // exif_thumbnail() must be callable
212        if (!is_callable('exif_thumbnail'))
213        {
214          $log .= '          <code class="warning">Warning -</code> Your server does not support thumbnail creation through EXIF datas. Thumbnail creation switched off.<br />'."\n";
215        }
216        break;
217      }
218      case 'fixed':
219      {
220        // $conf['thumbnail_width'] > 0
221        if (!is_numeric($conf['thumbnail_width']) or $conf['thumbnail_width'] <= 0)
222        {
223          $log .= '          <code class="failure">Failure -</code> Bad value <code>thumbnail_width = ';
224          $log .= var_export($conf['thumbnail_width'], true).'</code>. Thumbnail creation switched off.<br />'."\n";
225        }
226        // $conf['thumbnail_height'] > 0
227        if (!is_numeric($conf['thumbnail_height']) or $conf['thumbnail_height'] <= 0)
228        {
229          $log .= '          <code class="failure">Failure -</code> Bad value <code>thumbnail_height = ';
230          $log .= var_export($conf['thumbnail_height'], true).'</code>. Thumbnail creation switched off.<br />'."\n";
231        }
232        break;
233      }
234      case 'ratio':
235      {
236        // 0 < $conf['thumbnail_ratio'] < 1
237        if (!is_numeric($conf['thumbnail_ratio']) or $conf['thumbnail_ratio'] <= 0 or $conf['thumbnail_ratio'] >= 1)
238        {
239          $log .= '          <code class="failure">Failure -</code> Bad value <code>thumbnail_ratio = ';
240          $log .= var_export($conf['thumbnail_ratio'], true).'</code>. Thumbnail creation switched off.<br />'."\n";
241        }
242        break;
243      }
244      case 'width':
245      {
246        // $conf['thumbnail_width'] > 0
247        if (!is_numeric($conf['thumbnail_width']) or $conf['thumbnail_width'] <= 0)
248        {
249          $log .= '          <code class="failure">Failure -</code> Bad value <code>thumbnail_width = ';
250          $log .= var_export($conf['thumbnail_width'], true).'</code>. Thumbnail creation switched off.<br />'."\n";
251        }
252        break;
253      }
254      case 'height':
255      {
256        // $conf['thumbnail_height'] > 0
257        if (!is_numeric($conf['thumbnail_height']) or $conf['thumbnail_height'] <= 0)
258        {
259          $log .= '          <code class="failure">Failure -</code> Bad value <code>thumbnail_height = ';
260          $log .= var_export($conf['thumbnail_height'], true).'</code>. Thumbnail creation switched off.<br />'."\n";
261        }
262        break;
263      }
264      default:
265      {
266        // unknown method
267          $log .= '          <code class="failure">Failure -</code> Bad value <code>thumbnail_method = ';
268          $log .= var_export($conf['thumbnail_method'], true).'</code>. Thumbnail creation switched off.<br />'."\n";
269        break;
270      }
271    }
272   
273    if (strlen($log))
274    {
275      $conf['thumbnail'] = false;
276    }
277  }
278 
279  //~ pwg_log('<<<<< pwg_check_graphics() returns '.var_export($log, TRUE).' <<<<<'."\n");
280  return $log;
281}
282
283/**
284 * returns xml </dirX> lines
285 *
286 * @param integer $dir_start
287 * @param integer $dir_number
288 * @return string
289 */
290function pwg_close_level($dir_start, $dir_number)
291{
292  //~ pwg_log('>>>>> pwg_close_level($dir_start = '.var_export($dir_start, TRUE).', $dir_number = '.var_export($dir_number, TRUE).') >>>>>'."\n");
293 
294  $lines ='';
295  do
296  {
297    $lines .= str_repeat(' ', 2*$dir_start).'</dir'.$dir_start.">\n";
298    $dir_number--;
299    $dir_start--;
300  }
301  while(($dir_number > 0) && ($dir_start >= 0));
302 
303  //~ pwg_log('<<<<< pwg_close_level returns '.var_export($lines, TRUE).' <<<<<'."\n");
304  return $lines;
305}
306
307/**
308 * return a cleaned IPTC value
309 *
310 * @param string value
311 * @return string
312 */
313function pwg_clean_iptc_value($value)
314{
315  //~ pwg_log('>>>>> pwg_clean_iptc_value ($value = '.var_export($value, TRUE).') >>>>>'."\n");
316 
317  // strip leading zeros (weird Kodak Scanner software)
318  while (isset($value[0]) and $value[0] == chr(0))
319  {
320    $value = substr($value, 1);
321  }
322  // remove binary nulls
323  $value = str_replace(chr(0x00), ' ', $value);
324
325  //~ pwg_log('<<<<< pwg_clean_iptc_value() returns '.var_export($value, TRUE).' <<<<<'."\n");
326  return $value;
327}
328
329/**
330 * returns informations from IPTC metadata, mapping is done at the beginning
331 * of the function
332 *
333 * @param string $filename
334 * @param string $map
335 * @return array
336 */
337function pwg_get_iptc_data($filename, $map)
338{
339  //~ pwg_log('>>>>> pwg_get_iptc_data ($filename = '.var_export($filename, TRUE).', $map = '.var_export($map, TRUE).') >>>>>'."\n");
340 
341  $result = array();
342
343  // Read IPTC data
344  $iptc = array();
345
346  $imginfo = array();
347  getimagesize($filename, $imginfo);
348
349  if (isset($imginfo['APP13']))
350  {
351    $iptc = iptcparse($imginfo['APP13']);
352    if (is_array($iptc))
353    {
354      $rmap = array_flip($map);
355      foreach (array_keys($rmap) as $iptc_key)
356      {
357        if (isset($iptc[$iptc_key][0]))
358        {
359          if ($iptc_key == '2#025')
360          {
361            $value = implode(',', array_map('pwg_clean_iptc_value', $iptc[$iptc_key]));
362          }
363          else
364          {
365            $value = pwg_clean_iptc_value($iptc[$iptc_key][0]);
366          }
367
368          foreach (array_keys($map, $iptc_key) as $pwg_key)
369          {
370            $result[$pwg_key] = $value;
371          }
372        }
373      }
374    }
375  }
376 
377  //~ pwg_log('<<<<< pwg_get_iptc_data() returns '.var_export($result, TRUE).' <<<<<'."\n");
378  return $result;
379}
380
381/**
382 * returns informations from IPTC metadata
383 *
384 * @param string $file
385 * @return array iptc
386 */
387function pwg_get_sync_iptc_data($file)
388{
389  //~ pwg_log('>>>>> pwg_get_sync_iptc_data ($file = '.var_export($file, TRUE).') >>>>>'."\n");
390
391  global $conf;
392
393  $map = $conf['use_iptc_mapping'];
394  $datefields = array('date_creation', 'date_available');
395
396  $iptc = pwg_get_iptc_data($file, $map);
397
398  foreach ($iptc as $pwg_key => $value)
399  {
400    if (in_array($pwg_key, $datefields))
401    {
402      if ( preg_match('/(\d{4})(\d{2})(\d{2})/', $value, $matches))
403      {
404        $value = $matches[1].'-'.$matches[2].'-'.$matches[3];
405      }
406    }
407    if ($pwg_key == 'keywords')
408    {
409      // official keywords separator is the comma
410      $value = preg_replace('/[.;]/', ',', $value);
411      $value = preg_replace('/^,+|,+$/', '', $value);
412    }
413    $iptc[$pwg_key] = htmlentities($value);
414  }
415
416  $iptc['keywords'] = isset($iptc['keywords']) ? implode(',', array_unique(explode(',', $iptc['keywords']))) : NULL;
417
418  //~ pwg_log('<<<<< pwg_get_sync_iptc_data() returns '.var_export($iptc, TRUE).' <<<<<'."\n");
419  return $iptc;
420}
421
422/**
423 * return extension of the representative file
424 *
425 * @param string $file_dir
426 * @param string $file_short
427 * @return string
428 */
429function pwg_get_representative_ext($file_dir, $file_short)
430{
431  //~ pwg_log('>>>>> pwg_get_representative_ext($file_dir = '.var_export($file_dir, TRUE).', $file_short = '.var_export($file_short, TRUE).') >>>>>'."\n");
432 
433  global $conf;
434 
435  $rep_ext = '';
436  foreach ($conf['picture_ext'] as $ext)
437  {
438    if (file_exists($file_dir.'/'.$conf['represent'].'/'.$file_short.'.'.$ext))
439    {
440      $rep_ext = $ext;
441      break;
442    }
443  }
444 
445  //~ pwg_log('<<<<< pwg_get_representative_ext() returns '.var_export($rep_ext, TRUE).' <<<<<'."\n");
446  return $rep_ext; 
447}
448
449/**
450 * return 'true' if high resolution picture exists else ''
451 *
452 * @param string $file_dir
453 * @param string $file_base
454 * @return boolean
455 */
456function pwg_get_high($file_dir, $file_base)
457{
458  //~ pwg_log('>>>>> pwg_get_high($file = '.var_export($file_dir, TRUE).', $line = '.var_export($file_base, TRUE).') >>>>>'."\n");
459 
460  global $conf;
461 
462  $high = false;
463  if (file_exists($file_dir.'/'.$conf['high'].'/'.$file_base))
464  {
465    $high = true;
466  }
467 
468  //~ pwg_log('<<<<< pwg_get_high() returns '.var_export($high, TRUE).' <<<<<'."\n");
469  return $high; 
470}
471
472/**
473 * return filename without extension
474 *
475 * @param string $filename
476 * @return string
477 */
478function pwg_get_filename_wo_extension($filename)
479{
480  //~ pwg_log('>>>>> _get_filename_wo_extension($filename = '.var_export($filename, TRUE).') >>>>>'."\n");
481 
482  $short_name = substr($filename, 0, strrpos($filename, '.'));
483 
484  //~ pwg_log('<<<<< _get_filename_wo_extension() returns '.var_export($short_name, TRUE).' <<<<<'."\n");
485  return $short_name;
486}
487
488/**
489 * return extension of the thumbnail and complete error_log
490 *
491 * @param string $file_dir
492 * @param string $file_short
493 * @param string $file_ext
494 * @param string &$error_log
495 * @return string
496 */
497function pwg_get_thumbnail_ext($file_dir, $file_short, $file_ext, &$error_log)
498{
499  //~ pwg_log('>>>>> pwg_get_thumbnail_ext($file_dir = '.var_export($file_dir, TRUE).', $file_short = '.var_export($file_short, TRUE).') >>>>>'."\n");
500 
501  global $conf;
502 
503  $thumb_ext = '';
504  foreach ($conf['picture_ext'] as $ext)
505  {
506    if (file_exists($file_dir.'/'.$conf['thumbs'].'/'.$conf['prefix_thumbnail'].$file_short.'.'.$ext))
507    {
508      $thumb_ext = $ext;
509      break;
510    }
511  }
512 
513  if ($thumb_ext == '')
514  {
515    if ($conf['thumbnail'])
516    {
517      $log = pwg_icon_file($file_dir, $file_short, $file_ext);
518      if (strpos($log, 'success'))
519      {
520        $thumb_ext = $conf['thumbnail_format'];
521      }
522      $error_log .= $log; 
523    }
524  }
525 
526  //~ pwg_log('<<<<< pwg_get_thumbnail_ext() returns '.var_export($thumb_ext, TRUE).' <<<<<'."\n");
527  return $thumb_ext; 
528}
529
530
531/**
532 * return error logs
533 *
534 * @param string $file_dir
535 * @param string $file_short
536 * @param string $file_ext
537 * @return string
538 */
539function pwg_icon_file($file_dir, $file_short, $file_ext)
540{
541  //~ pwg_log('>>>>> pwg_icon_file($file_dir = '.var_export($file_dir, TRUE).', $file_short = '.var_export($file_short, TRUE).') >>>>>'."\n");
542 
543  global $conf, $pwg_conf;
544 
545  $error_log = '';
546 
547  // Get original properties (width, height)
548  if ($image_size = getimagesize($file_dir.'/'.$file_short.'.'.$file_ext))
549  {
550    $src_width = $image_size[0];
551    $src_height = $image_size[1];
552  }
553  else
554  {
555    $error_log .= '          <code class="failure">Failure -</code> Can not generate icon for <code>';
556    $error_log .= $file_dir.'/'.$file_short.'.'.$file_ext.'</code>';
557    $error_log .= ' <img src="'.$pwg_conf['icon_dir'].'add_tag.png" title="width/height are unreadable" /><br />'."\n";
558    return $error_log;
559  }
560 
561  // Check input format
562  $dst_format = $conf['thumbnail_format'];
563  $src_format = ($file_ext == 'jpg' or $file_ext == 'JPG') ? 'jpeg' : strtolower($file_ext);
564  if (!in_array($src_format, $pwg_conf['gd_supported_format']))
565  {
566    $error_log .= '          <code class="failure">Failure -</code> Can not generate icon for <code>';
567    $error_log .= $file_dir.'/'.$file_short.'.'.$file_ext.'</code>';
568    $error_log .= ' <img src="'.$pwg_conf['icon_dir'].'add_tag.png" title="format not supported" /><br />'."\n";
569    return $error_log;
570  }
571 
572  // Calculate icon properties (width, height)
573  switch ($conf['thumbnail_method'])
574  {
575    case 'fixed':
576    {
577      $dst_width  = $conf['thumbnail_width'];
578      $dst_height = $conf['thumbnail_height'];
579      break;
580    }
581    case 'width':
582    {
583      $dst_width  = $conf['thumbnail_width'];
584      $dst_height = $dst_width * $src_height / $src_width;
585      break;
586    }
587    case 'height':
588    {
589      $dst_height = $conf['thumbnail_height'];
590      $dst_width  = $dst_height * $src_width / $src_height;
591      break;
592    }
593    case 'ratio':
594    {
595      $dst_width  = round($src_width * $conf['thumbnail_ratio']);
596      $dst_height = round($src_height * $conf['thumbnail_ratio']);
597      break;
598    }
599    case 'exif':
600    default:
601    {
602      // Nothing to do
603    }
604  }
605 
606  // Creating icon
607  if ($conf['thumbnail_method'] == 'exif')
608  {
609    $src = exif_thumbnail($file_dir.'/'.$file_short.'.'.$file_ext, $width, $height, $imagetype);
610    if ($src === false)
611    {
612      $error_log .= '          <code class="failure">Failure -</code> No EXIF thumbnail in <code>';
613      $error_log .= $file_dir.'/'.$file_short.'.'.$file_ext.'</code><br />'."\n";
614      return $error_log;
615    }
616    $dst = imagecreatefromstring($src);
617    if ($src === false)
618    {
619      $error_log .= '          <code class="failure">Failure -</code> EXIF thumbnail format not supported in <code>';
620      $error_log .= $file_dir.'/'.$file_short.'.'.$file_ext.'</code><br />'."\n";
621      return $error_log;
622    }
623  }
624  else
625  {
626    if (($pwg_conf['gd_version_major'] != 2)) // or ($conf['thumbnail_format'] == 'gif'))
627    {
628      $dst = imagecreate($dst_width, $dst_height);
629    }
630    else
631    {
632      $dst = imagecreatetruecolor($dst_width, $dst_height);
633    }
634    $src = call_user_func('imagecreatefrom'.$src_format, $file_dir.'/'.$file_short.'.'.$file_ext);
635    if (!$src)
636    {
637      $error_log .= '          <code class="failure">Failure -</code> Internal error for <code>imagecreatefrom'.$src_format.'()</code>';
638      $error_log .= 'with <code>'.$file_dir.'/'.$file_short.'.'.$file_ext.'</code><br />'."\n";
639      return $error_log;
640    }
641     
642    if (($pwg_conf['gd_version_major'] != 2))
643    {
644      if (!imagecopyresized($dst, $src, 0, 0, 0, 0, $dst_width, $dst_height, $src_width, $src_height))
645      {
646        $error_log .= '          <code class="failure">Failure -</code> Internal error for <code>imagecopyresized()</code>';
647        $error_log .= 'with <code>'.$file_dir.'/'.$file_short.'.'.$file_ext.'</code><br />'."\n";
648        return $error_log;
649      }
650    }
651    else
652    {
653      if (!imagecopyresampled($dst, $src, 0, 0, 0, 0, $dst_width, $dst_height, $src_width, $src_height))
654      {
655        $error_log .= '          <code class="failure">Failure -</code> Internal error for <code>imagecopyresampled()</code>';
656        $error_log .= 'with <code>'.$file_dir.'/'.$file_short.'.'.$file_ext.'</code><br />'."\n";
657        return $error_log;
658      }
659    }
660  }
661 
662  if (!call_user_func('image'.$dst_format, $dst, $file_dir.'/'.$conf['thumbs'].'/'.$conf['prefix_thumbnail'].$file_short.'.'.$conf['thumbnail_format']))
663  {
664    $error_log .= '          <code class="failure">Failure -</code> Can not write <code>';
665    $error_log .= $file_dir.'/'.$conf['thumbs'].'/'.$conf['prefix_thumbnail'].$file_short.'.'.$file_ext.'</code> to generate thumbnail<br />'."\n";
666    return $error_log;
667  }
668 
669  $error_log .= '          <code class="success">Success -</code> Thumbnail generated for <code>';
670  $error_log .= $file_dir.'/'.$file_short.'.'.$file_ext.'</code><br />'."\n";
671
672  //~ pwg_log('<<<<< pwg_icon_file() returns '.var_export($error_log, TRUE).' <<<<<'."\n");
673  return $error_log; 
674}
675
676/**
677 * completes xml line <element .../> and returns error log
678 *
679 * @param string $file
680 * @param string &$line
681 * @return string
682 */
683function pwg_scan_file($file_full, &$line)
684{
685  //~ pwg_log('>>>>> pwg_scan_file($file = '.var_export($file_full, TRUE).', $line = '.var_export($line, TRUE).') >>>>>'."\n");
686 
687  global $conf, $pwg_conf;
688 
689  $error_log ='';
690 
691  $file_base  = basename($file_full);
692  $file_short = pwg_get_filename_wo_extension($file_base);
693  $file_ext   = pwg_get_file_extension($file_base);
694  $file_dir   = dirname($file_full);
695
696  $element['file'] = $file_base;
697  $element['path'] = 'http://'.dirname($_SERVER['SERVER_NAME'].$_SERVER['PHP_SELF']).substr($file_dir, 1).'/'.$file_base;
698 
699  if (in_array($file_ext, $conf['picture_ext']))
700  {
701    // Here we scan a picture : thumbnail is mandatory, high is optionnal, representative is not scanned
702    $element['tn_ext'] = pwg_get_thumbnail_ext($file_dir, $file_short, $file_ext, $error_log);
703    if ($element['tn_ext'] != '')
704    {
705      // picture has a thumbnail, get image width, heigth, size in Mo
706      $element['filesize'] = floor(filesize($file_full) / 1024);
707      if ($image_size = getimagesize($file_full))
708      {
709        $element['width'] = $image_size[0];
710        $element['height'] = $image_size[1];
711      }
712     
713      // get high resolution
714      if (pwg_get_high($file_dir, $file_base))
715      {
716        $element['has_high'] = 'true';
717       
718        $high_file = $file_dir.'/'.$conf['high'].'/'.$file_base;
719        $element['high_filesize'] = floor(filesize($high_file) / 1024);
720      }
721     
722      // get EXIF meta datas
723      if ($conf['use_exif'])
724      {
725        // Verify activation of exif module
726        if (extension_loaded('exif'))
727        {
728          if ($exif = read_exif_data($file_full))
729          {
730            foreach ($conf['use_exif_mapping'] as $pwg_key => $exif_key )
731            {
732              if (isset($exif[$exif_key]))
733              {
734                if ( in_array($pwg_key, array('date_creation','date_available') ) )
735                {
736                  if (preg_match('/^(\d{4}):(\d{2}):(\d{2})/', $exif[$exif_key], $matches))
737                    {
738                      $element[$pwg_key] = $matches[1].'-'.$matches[2].'-'.$matches[3];
739                    }
740                }
741                else
742                {
743                  $element[$pwg_key] = $exif[$exif_key];
744                }
745              }
746            }
747          }
748        }
749      }
750     
751      // get IPTC meta datas
752      if ($conf['use_iptc'])
753      {
754        $iptc = pwg_get_sync_iptc_data($file_full);
755        if (count($iptc) > 0)
756        {
757          foreach (array_keys($iptc) as $key)
758          {
759            $element[$key] = addslashes($iptc[$key]);
760          }
761        }
762      }
763     
764    }
765    else
766    {
767      $error_log .= '          <code class="failure">Failure -</code> Thumbnail is missing for <code>'.$file_dir.'/'.$file_base.'</code>';
768      $error_log .= ' <img src="'.$pwg_conf['icon_dir'].'add_tag.png" title="'.$file_dir.'/thumbnail/'.$conf['prefix_thumbnail'].$file_short;
769      $error_log .= '.xxx ('.implode(', ', $conf['picture_ext']).')" /><br />'."\n";
770    }
771  }
772  else
773  {
774    // Here we scan a non picture file : thumbnail and high are unused, representative is optionnal
775    $ext = pwg_get_representative_ext($file_dir, $file_short);
776    if ($ext != '')
777    {
778      $element['representative_ext'] = $ext;
779    }
780  }
781 
782  if (strlen($error_log) == 0)
783  {
784    $line = pwg_get_indent('element').'<element ';
785    foreach($element as $key => $value)
786    {
787      $line .= $key.'="'.$value.'" ';
788    }
789    $line .= '/>'."\n";
790  }
791 
792  //~ pwg_log('<<<<< pwg_scan_file() returns '.var_export($error_log, TRUE).' <<<<<'."\n");
793  return $error_log;
794}
795
796/**
797 * returns current level in tree
798 *
799 * @return integer
800 */
801function pwg_get_level($dir)
802{
803  //~ pwg_log('>>>>> pwg_get_level($dir = '.var_export($dir, TRUE).') >>>>>'."\n");
804 
805  $level = substr_count($dir, '/') - 1; // -1 because of ./ at the beginning of path
806 
807  //~ pwg_log('<<<<< pwg_get_level() returns '.var_export($level, TRUE).' <<<<<'."\n");
808  return $level;
809}
810
811/**
812 * returns indentation of element
813 *
814 * @param string $element_type : 'root', 'element', 'dir'
815 * @return string
816 */
817function pwg_get_indent($element_type)
818{
819  //~ pwg_log('>>>>> pwg_get_indent($element_type = '.var_export($element_type, TRUE).') >>>>>'."\n");
820 
821  $level = substr_count($_SESSION['scan_list_fold'][0], '/') - 1; // because of ./ at the beginning
822  switch($element_type)
823  {
824    case 'dir' :
825    {
826      $indent = str_repeat(' ', 2*pwg_get_level($_SESSION['scan_list_fold'][0]));
827      break;
828    }
829    case 'root' :
830    {
831      $indent = str_repeat(' ', 2*pwg_get_level($_SESSION['scan_list_fold'][0])+2);
832      break;
833    }
834    case 'element' :
835    {
836      $indent = str_repeat(' ', 2*pwg_get_level($_SESSION['scan_list_fold'][0])+4);
837      break;
838    }
839    default :
840    {
841      $indent = '';
842      break;
843    }
844  }
845 
846  //~ pwg_log('<<<<< pwg_get_indent() returns '.var_export(strlen($indent), TRUE).' spaces <<<<<'."\n");
847  return $indent;
848}
849
850/**
851 * create index.php in directory and reserved sub_directories, return logs
852 *
853 * @param string dir
854 * @return string
855 */
856function pwg_protect_directories($directory)
857{
858  //~ pwg_log('>>>>> pwg_protect_directories($directory = '.var_export($directory, true).') >>>>>'."\n");
859 
860  global $conf;
861 
862  $error_log = '';
863  $dirlist = array($directory, $directory.'/'.$conf['thumbs'], $directory.'/'.$conf['high'], $directory.'/'.$conf['represent']);
864 
865  foreach ($dirlist as $dir)
866  {
867    if (file_exists($dir))
868    {
869      if (!file_exists($dir.'/index.php'))
870      {
871        $file = @fopen($dir.'/index.php', 'w');
872        if ($file != false)
873        {
874          fwrite($file, $conf['protect_content']); // the return code should be verified
875          $error_log .= '          <code class="success">Success -</code> index.php created in directory <a href="'.$dir.'">'.$dir."</a><br />\n";
876        }
877        else
878        {
879          $error_log .= '          <code class="failure">Failure -</code> Can not create index.php in directory <code>'.$dir."</code><br />\n";
880        }
881      }
882      else
883      {
884        if ($conf['protect_warnings'])
885        {
886          $error_log .= '          <code class="warning">Warning -</code> index.php already exists in directory <a href="'.$dir.'">'.$dir."</a><br />\n";
887        }
888      }
889    }
890  }
891 
892  //~ pwg_log('<<<<< pwg_protect_directories() returns '.var_export($error_log, true).' <<<<<'."\n");
893  return $error_log;
894}
895
896/**
897 * returns file extension (.xxx)
898 *
899 * @param string $file
900 * @return string
901 */
902function pwg_get_file_extension($file)
903{
904  //~ pwg_log('>>>>> pwg_get_file_extension($file = '.var_export($file, true).') >>>>>'."\n");
905 
906  $ext = substr(strrchr($file, '.'), 1, strlen ($file));
907 
908  //~ pwg_log('<<<<< pwg_get_file_extension() returns '.var_export($ext, true).' <<<<<'."\n");
909  return $ext;
910}
911
912/**
913 * completes directory list of supported files and returns error logs
914 *
915 * @param string $directory
916 * @return string
917 */
918function pwg_get_file_list($directory)
919{
920  //~ pwg_log('>>>>> pwg_get_file_list($directory = '.var_export($directory, true).') >>>>>'."\n");
921 
922  global $conf, $pwg_conf;
923
924  $errorLog = '';
925  $dir = opendir($directory);
926  while (($file = readdir($dir)) !== false)
927  {
928    switch (filetype($directory."/".$file))
929    {
930      case 'file' :
931      {
932        if (in_array(pwg_get_file_extension($file), $conf['file_ext']))
933        {
934          // The file pointed is a regular file with a supported extension
935          array_push($_SESSION['scan_list_file'], $directory.'/'.$file);
936          //~ pwg_log('--->> Push in $_SESSION[scan_list_file] value "'.$directory.'/'.$file.'"'."\n");
937          if (!preg_match('/^[a-zA-Z0-9-_.]+$/', $file))
938          {
939            $errorLog .= '          <code class="failure">Failure -</code> Invalid file name for <code>'.$file.'</code> in <code>'.$directory.'</code>';
940            $errorLog .= ' <img src="'.$pwg_conf['icon_dir'].'add_tag.png"';
941            $errorLog .= ' title="Name should be composed of letters, figures, -, _ or . ONLY" /><br />'."\n";
942          }
943        }
944        break; // End of filetype FILE
945      }
946      case 'dir' :
947      {
948        if(!in_array($file, $pwg_conf['reserved_directory_names']))
949        {
950          // The file pointed is a directory but neither system directory nor reserved by PWG
951          array_push($_SESSION['scan_list_fold'], $directory.'/'.$file);
952          //~ pwg_log('--->> Push in $_SESSION[scan_list_fold] value "'.$directory.'/'.$file.'"'."\n");
953          if (!preg_match('/^[a-zA-Z0-9-_.]+$/', $file))
954          {
955            $errorLog .= '          <code class="failure">Failure -</code> Invalid directory name for <code>'.$directory.'/'.$file.'</code>';
956            $errorLog .= ' <img src="'.$pwg_conf['icon_dir'].'add_tag.png"';
957            $errorLog .= ' title="Name should be composed of letters, figures, -, _ or . ONLY" /><br />'."\n";
958          }
959        }
960        break; // End of filetype DIR
961      }
962      case 'fifo' :
963      case 'char' :
964      case 'block' :
965      case 'link' :
966      case 'unknown':
967      default :
968      {
969        // PWG does not manage these cases
970        break;
971      }
972    }
973  }
974  closedir($dir);
975 
976  //~ pwg_log('<<<<< pwg_get_file_list() returns '.var_export($errorLog, true).' <<<<<'."\n");
977
978  return $errorLog;
979}
980
981/**
982 * returns a float value coresponding to the number of seconds since the
983 * unix epoch (1st January 1970) and the microseconds are precised :
984 * e.g. 1052343429.89276600
985 *
986 * @return float
987 */
988function pwg_get_moment()
989{
990  //~ pwg_log('>>>>> pwg_get_moment() >>>>>'."\n");
991 
992  $t1 = explode(' ', microtime());
993  $t2 = explode('.', $t1[0]);
994  $t2 = $t1[1].'.'.$t2[1];
995
996  //~ pwg_log('<<<<< pwg_get_moment() returns '.var_export($t2, true).' <<<<<'."\n");
997  return $t2;
998}
999
1000/**
1001 * return true if HTTP_REFERER and PHP_SELF are similar
1002 *
1003 * return boolean
1004 */
1005function pwg_referer_is_me()
1006{
1007  //~ pwg_log('>>>>> pwg_referer_is_me() >>>>>'."\n");
1008 
1009  $response = false;
1010  $server = 'http://'.$_SERVER['SERVER_NAME'].$_SERVER['PHP_SELF'];
1011  $caller = (isset($_SERVER['HTTP_REFERER'])) ? $_SERVER['HTTP_REFERER'] : '';
1012
1013  if (strcasecmp($server, $caller) == 0) {
1014    $response = true;
1015  }
1016
1017  //~ pwg_log('<<<<< pwg_referer_is_me() returns '.var_export($response, true).' <<<<<'."\n");
1018  return $response;
1019}
1020
1021// +-----------------------------------------------------------------------+
1022// |                                pwg_<ACTION>_<STEP> Functions          |
1023// +-----------------------------------------------------------------------+
1024
1025function pwg_test_start()
1026{
1027  //~ pwg_log('>>>>> pwg_test_start() >>>>>'."\n");
1028
1029  global $g_message, $conf;
1030 
1031  if (isset($_REQUEST['version']))
1032  {
1033    if ($_REQUEST['version'] != $conf['version'])
1034    {
1035      $g_message = '0';
1036    }
1037    else
1038    {
1039      $g_message = '1';
1040    }
1041  }
1042  else
1043  {
1044    $g_message  = '1';
1045  }
1046  $_SESSION['scan_step'] = 'exit';
1047 
1048  //~ pwg_log('<<<<< pwg_test_start() <<<<<'."\n");
1049}
1050
1051function pwg_test_exit()
1052{
1053  //~ pwg_log('>>>>> pwg_test_exit() >>>>>'."\n");
1054
1055  global $g_header, $g_message, $g_footer, $conf, $pwg_conf;
1056 
1057  if (pwg_referer_is_me())
1058  {
1059    $g_header  = ' : <span class="success">Test</span>'."\n";
1060    $g_footer  = '<a href="'.$pwg_conf['this_url'].'" title="Main menu"><img src="'.$pwg_conf['icon_dir'].'up.png" /></a>'."\n";
1061   
1062    // Write version
1063    $g_message  = '        <h3>Script version</h3>'."\n";
1064    $g_message .= '        This script is tagged : <code class="failure">'.$conf['version'].'</code>'."\n";
1065    // write GD support
1066    if (!is_callable('gd_info'))
1067    {
1068      $g_message .= '        <code class="failure">Failure -</code> Your server can not generate imagess<br />'."\n";
1069    }
1070    else
1071    {
1072      $info = gd_info();
1073      $gd_full_version = ereg_replace('[[:alpha:][:space:]()]+', '', $info['GD Version']);
1074      list($gd_version) = preg_split('/[.]+/', $gd_full_version);
1075     
1076      $g_message .= '        <h3>Image generation</h3>'."\n";
1077      $g_message .= '        <code class="success">Success -</code> Your server can generate images<br />'."\n";
1078      $g_message .= '        <code class="warning">Warning -</code> Your server support GD'.$gd_version.' (v'.$gd_full_version.')<br />'."\n";
1079      $format_list = array();
1080      $format = ($info['GIF Create Support']) ? '<code>gif</code>' : NULL;
1081      array_push($format_list, $format);
1082      $format = ($info['JPG Support']) ? '<code>jpg</code>' : NULL;
1083      array_push($format_list, $format);
1084      $format = ($info['PNG Support']) ? '<code>png</code>' : NULL;
1085      array_push($format_list, $format);
1086      $g_message .= '        <code class="warning">Warning -</code> Your server support format: '.implode(', ', $format_list)."\n";
1087    }
1088   
1089    $g_message .= '        <h3>Directory parsing</h3>'."\n";
1090    if ($pwg_conf['safe_mode'])
1091    {
1092      $g_message .= '        <code class="warning">Warning -</code> Your server does not support to resize execution time'."\n";
1093    }
1094    else
1095    {
1096      $g_message .= '        <code class="success">Success -</code> Your server supports to resize execution time'."\n";
1097    }
1098  }
1099  else
1100  {
1101    // compare version in GET parameter with $conf['version']
1102    if ($g_message == '1')
1103    {
1104      exit('<pre>PWG-INFO-2: test successful</pre>');
1105    }
1106    else
1107    {
1108      exit('<pre>PWG-ERROR-4: PhpWebGallery versions differs</pre>');
1109    }
1110  }
1111 
1112  //~ pwg_log('<<<<< pwg_test_exit() <<<<<'."\n");
1113}
1114
1115function pwg_clean_start()
1116{
1117  //~ pwg_log('>>>>> pwg_clean_start() >>>>>'."\n");
1118 
1119  global $g_message;
1120 
1121  if(@unlink('./listing.xml'))
1122  {
1123    $g_message = '1';
1124  }
1125  else
1126  {
1127    $g_message = '0';
1128  }
1129
1130  $_SESSION['scan_step'] = 'exit';
1131 
1132  //~ pwg_log('<<<<< pwg_clean_start() <<<<<'."\n");
1133}
1134
1135function pwg_clean_exit()
1136{
1137  //~ pwg_log('>>>>> pwg_clean_exit() >>>>>'."\n");
1138
1139  global $g_header, $g_message, $g_footer, $conf, $pwg_conf;
1140 
1141  if(pwg_referer_is_me())
1142  {
1143    $g_header = ' : <span class="success">Clean</span>';
1144    if ($g_message == '1')
1145    {
1146      $g_message = '        <code class="success">Success -</code> <code>listing.xml</code> file deleted'."\n";
1147    }
1148    else
1149    {
1150      $g_message = '        <code class="failure">Failure -</code> <code>listing.xml</code> does not exist or is read only'."\n";
1151    }
1152    $g_footer = '<a href="'.$pwg_conf['this_url'].'" title="Main menu"><img src="'.$pwg_conf['icon_dir'].'up.png" /></a>';
1153  }
1154  else
1155  {
1156    if ($g_message == '1')
1157    {
1158      exit('<pre>PWG-INFO-3 : listing.xml file deleted</pre>');
1159    }
1160    else
1161    {
1162      exit('<pre>PWG-ERROR-3 : listing.xml does not exist</pre>');
1163    }
1164  }
1165 
1166  //~ pwg_log('<<<<< pwg_clean_exit() <<<<<'."\n");
1167}
1168
1169function pwg_generate_start()
1170{
1171  //~ pwg_log('>>>>> pwg_generate_start() >>>>>'."\n");
1172  //~ pwg_log("GENARATE start >>>\n".var_export($_SESSION['scan_list_fold'], true)."\n".var_export($_SESSION['scan_list_file'], true)."\nGENERATE start >>>\n");
1173
1174  global $g_listing, $conf;
1175 
1176  // Flush line <informations>
1177  $xml_header_url = 'http://'.dirname($_SERVER['SERVER_NAME'].$_SERVER['PHP_SELF']).'/';
1178  $xml_header_date = date('Y-m-d');
1179  $xml_header_version = htmlentities($conf['version']);
1180 
1181  $attrs = array();
1182  if ($conf['use_iptc'])
1183  {
1184    $attrs = array_merge($attrs, array_keys($conf['use_iptc_mapping']) );
1185  }
1186  if ($conf['use_exif'])
1187  {
1188    $attrs = array_merge($attrs, array_keys($conf['use_exif_mapping']) );
1189  }
1190  $xml_header_metadata = implode(',',array_unique($attrs));
1191 
1192  $xml_header = '<informations';
1193  $xml_header .= ' generation_date="'.$xml_header_date.'"';
1194  $xml_header .= ' phpwg_version="'.$xml_header_version.'"';
1195  $xml_header .= ' metadata="'.$xml_header_metadata.'"';
1196  $xml_header .= ' url="'.$xml_header_url.'"';
1197  $xml_header .= '>'."\n";
1198 
1199  fwrite($g_listing, $xml_header);
1200 
1201  // Initialization of directory and file lists
1202  $_SESSION['scan_list_fold'] = array();
1203  $_SESSION['scan_list_file'] = array();
1204  $_SESSION['scan_logs'] .= pwg_get_file_list('.');
1205  sort($_SESSION['scan_list_fold']);
1206         
1207  // Erase first file list because root directory does not contain images.
1208  $_SESSION['scan_list_file'] = array();
1209           
1210  // What are we doing at next step
1211  if(count($_SESSION['scan_list_fold']) > 0)
1212  {
1213    $_SESSION['scan_step'] = 'list';
1214  }
1215  else
1216  {
1217    $_SESSION['scan_step'] = 'stop';
1218  }
1219 
1220  //~ pwg_log("GENARATE start <<<\n".var_export($_SESSION['scan_list_fold'], true)."\n".var_export($_SESSION['scan_list_file'], true)."\nGENERATE start <<<\n");
1221  //~ pwg_log('<<<<< pwg_generate_start() <<<<<'."\n");
1222}
1223
1224function pwg_generate_list()
1225{
1226  //~ pwg_log('>>>>> pwg_generate_list() >>>>>'."\n");
1227  //~ pwg_log("GENARATE list >>>\n".var_export($_SESSION['scan_list_fold'], true)."\n".var_export($_SESSION['scan_list_file'], true)."\nGENERATE list >>>\n");
1228 
1229  global $g_listing;
1230 
1231  // Flush line <dirX name=""> in xml file
1232  $dirname = basename($_SESSION['scan_list_fold'][0]);
1233  $line = pwg_get_indent('dir').'<dir'.pwg_get_level($_SESSION['scan_list_fold'][0]).' name="'.$dirname.'">'."\n";
1234  fwrite($g_listing, $line);
1235 
1236  // Get list of files and directories
1237  $_SESSION['scan_logs'] .= pwg_get_file_list($_SESSION['scan_list_fold'][0]);
1238  sort($_SESSION['scan_list_fold']); // Mandatory to keep the tree order
1239  sort($_SESSION['scan_list_file']); // Easier to read when sorted
1240 
1241  // Flush line <root>
1242  $line = pwg_get_indent('root').'<root>'."\n";
1243  fwrite($g_listing, $line);
1244 
1245  // What are we doing at next step
1246  $_SESSION['scan_step'] = 'scan';
1247 
1248  //~ pwg_log("GENARATE list <<<\n".var_export($_SESSION['scan_list_fold'], true)."\n".var_export($_SESSION['scan_list_file'], true)."\nGENERATE list <<<\n");
1249  //~ pwg_log('<<<<< pwg_generate_list() <<<<<'."\n");
1250}
1251
1252function pwg_generate_scan()
1253{
1254  //~ pwg_log('>>>>> pwg_generate_scan() >>>>>'."\n");
1255  //~ pwg_log("GENARATE scan >>>\n".var_export($_SESSION['scan_list_fold'], true)."\n".var_export($_SESSION['scan_list_file'], true)."\nGENERATE scan >>>\n");
1256 
1257  global $g_listing, $conf;
1258 
1259  while (pwg_continue() and count($_SESSION['scan_list_file']) > 0)
1260  {
1261    $line = '';
1262    $_SESSION['scan_logs'] .= pwg_scan_file($_SESSION['scan_list_file'][0], $line);
1263   
1264    if (strlen($line) > 0)
1265    {
1266      fwrite($g_listing, $line);
1267    }
1268    //~ pwg_log('---<< Pull of $_SESSION[scan_list_file] value "'.$_SESSION['scan_list_file'][0].'"'."\n");
1269    array_shift($_SESSION['scan_list_file']);
1270    $_SESSION['scan_cnt_file']++;
1271  }
1272         
1273  if (count($_SESSION['scan_list_file']) <= 0)
1274  {
1275    $_SESSION['scan_step'] = 'prot';
1276  }
1277 
1278  //~ pwg_log("GENERATE scan <<<\n".var_export($_SESSION['scan_list_fold'], true)."\n".var_export($_SESSION['scan_list_file'], true)."\nGENERATE scan <<<\n");
1279  //~ pwg_log('<<<<< pwg_generate_scan() <<<<<'."\n");
1280}
1281
1282function pwg_generate_prot()
1283{
1284  //~ pwg_log('>>>>> pwg_generate_prot() >>>>>'."\n");
1285  //~ pwg_log("GENARATE prot >>>\n".var_export($_SESSION['scan_list_fold'], true)."\n".var_export($_SESSION['scan_list_file'], true)."\nGENERATE prot >>>\n");
1286 
1287  global $conf, $g_listing;
1288 
1289  // Flush line </root>
1290  $line = pwg_get_indent('root').'</root>'."\n";
1291  fwrite($g_listing, $line);
1292 
1293  if ($conf['protect'])
1294  {
1295    $_SESSION['scan_logs'] .= pwg_protect_directories($_SESSION['scan_list_fold'][0]);
1296  }
1297 
1298  // How many directories to close
1299  $current_level = pwg_get_level($_SESSION['scan_list_fold'][0]);
1300  if (isset($_SESSION['scan_list_fold'][1]))
1301  {
1302    //~ pwg_log('---<< Pull of $_SESSION[scan_list_fold] value "'.$_SESSION['scan_list_fold'][0].'"'."\n");
1303    array_shift($_SESSION['scan_list_fold']);
1304    $_SESSION['scan_cnt_fold']++;
1305    $next_level = pwg_get_level($_SESSION['scan_list_fold'][0]);
1306    $_SESSION['scan_step'] = 'list';
1307  }
1308  else
1309  {
1310    $next_level = -1;
1311    $_SESSION['scan_cnt_fold']++;
1312    $_SESSION['scan_step'] = 'stop';
1313  }
1314 
1315  if ($current_level == $next_level)
1316  {
1317    fwrite($g_listing, pwg_close_level($current_level, 1));
1318  }
1319  else
1320  {
1321    if (($current_level > $next_level))
1322    {
1323      fwrite($g_listing, pwg_close_level($current_level, $current_level-$next_level+1));
1324    } // Nothing to do if current_level < next_level
1325  }
1326
1327  //~ pwg_log("GENERATE prot <<<\n".var_export($_SESSION['scan_list_fold'], true)."\n".var_export($_SESSION['scan_list_file'], true)."\nGENERATE prot <<<\n");
1328  //~ pwg_log('<<<<< pwg_generate_prot() <<<<<'."\n");
1329}
1330
1331function pwg_generate_stop()
1332{
1333  //~ pwg_log('>>>>> pwg_generate_stop() >>>>>'."\n");
1334  //~ pwg_log("GENARATE stop >>>\n".var_export($_SESSION['scan_list_fold'], true)."\n".var_export($_SESSION['scan_list_file'], true)."\nGENERATE stop >>>\n");
1335 
1336  global $pwg_conf, $g_listing, $g_header, $g_message, $g_footer;
1337 
1338  // Flush line </informations>
1339  fwrite($g_listing, '</informations>'."\n");
1340 
1341  // backup error log before cleaning session
1342  $time_elapsed = number_format(pwg_get_moment() - $_SESSION['scan_time'], 3, '.', ' ');
1343 
1344  $g_header   = ' : <span class="success">Generate</span>';
1345  $g_message  = '        <div>'."\n".$_SESSION['scan_logs'].'        </div>'."\n";
1346  $g_message .= '        <div><code class="success">'.$_SESSION['scan_cnt_fold'].'</code> directories parsed<br />'."\n";
1347  $g_message .= '        <code class="success">'.$_SESSION['scan_cnt_file'].'</code> files scanned</div>'."\n";
1348  $g_message .= '        <div>View <a href="listing.xml">listing.xml</a></div>'."\n";
1349  $g_message .= '        <div style="{text-align: right;}">Listing generated in : <code>'.$time_elapsed.' s</code></div>';
1350  $g_footer   = '<a href="'.$pwg_conf['this_url'].'" title="Main menu"><img src="'.$pwg_conf['icon_dir'].'up.png" /></a>';
1351     
1352  // What are we doing at next step
1353  $_SESSION['scan_step'] = 'exit';
1354 
1355  //~ pwg_log("GENARATE stop <<<\n".var_export($_SESSION['scan_list_fold'], true)."\n".var_export($_SESSION['scan_list_file'], true)."\nGENERATE stop <<<\n");
1356  //~ pwg_log('<<<<< pwg_generate_stop() <<<<<'."\n");
1357}
1358
1359// +-----------------------------------------------------------------------+
1360// |                                ALWAYS CALLED FUNCTIONS                |
1361// +-----------------------------------------------------------------------+
1362
1363/**
1364 * This function check step and time ellapsed to determine end of loop
1365 *
1366 * @return bool
1367 */
1368function pwg_continue()
1369{
1370  //~ pwg_log('>>>>> pwg_continue() >>>>>'."\n");
1371 
1372  global $conf, $pwg_conf, $g_refresh, $g_header, $g_message, $g_footer, $start_time;
1373 
1374  if (!isset($_SESSION['scan_step']) or $_SESSION['scan_step'] == 'exit')
1375  {
1376    // evident end of process
1377    $return = false;
1378  }
1379  else
1380  {
1381    if ($pwg_conf['safe_mode'])
1382    {
1383      // can not reset the time
1384      $time_elapsed = pwg_get_moment() - $start_time;
1385      if ($time_elapsed < $conf['max_execution_time'])
1386      {
1387        $return = true;
1388      }
1389      else
1390      {
1391        $start_time = $_SESSION['scan_time'];
1392        $formated_time = number_format(pwg_get_moment() - $start_time, 3, '.', ' ');
1393
1394        $g_refresh = '<meta http-equiv="Refresh" content="'.$conf['refresh_delay'].'">'."\n";
1395        $g_header  = ' : <span class="success">'.ucfirst($_SESSION['scan_action']).'</span>';
1396        $g_message = '';
1397        if ($_SESSION['scan_cnt_fold'] != 0)
1398        {
1399          $g_message .= '<code class="success">'.$_SESSION['scan_cnt_fold'].'</code> directories scanned<br />'."\n";
1400        }
1401        if ($_SESSION['scan_cnt_file'] != 0)
1402        {
1403          $g_message .= '<code class="success">'.$_SESSION['scan_cnt_file'].'</code> files scanned<br />'."\n";
1404        }
1405        $nb = count($_SESSION['scan_list_fold']);
1406        if ($nb > 0)
1407        {
1408          $g_message .= '<code class="warning">'.$nb.'</code> directories to scan<br />'."\n";
1409        }
1410        $nb = count($_SESSION['scan_list_file']);
1411        if ($nb > 0)
1412        {
1413          $g_message .= '<code class="warning">'.$nb.'</code> files to scan<br />'."\n";
1414        }
1415        $g_message .= '        <div style="{text-align: right;}">Time elapsed : <code>'.$formated_time.' s</code></div>';
1416        $g_footer  = '<a href="'.$pwg_conf['this_url'].'?action='.$_SESSION['scan_action'].'" title="Continue"><img src="'.$pwg_conf['icon_dir'].'right.png" /></a>'."\n";
1417       
1418        $return = false;
1419      }
1420    }
1421    else
1422    {
1423      // reset the time
1424      set_time_limit(intval(ini_get('max_execution_time')));
1425      $return = true;
1426    }
1427  }
1428  //~ pwg_log('<<<<< pwg_continue() returns '.var_export($return, true).' <<<<<'."\n");
1429 
1430  return $return;
1431}
1432
1433/**
1434 * This function :
1435 * -> Verify the script call
1436 * -> Lock the script
1437 * -> Open listing.xml if action is 'generate'
1438 * -> Initialize output and session variables
1439 *
1440 * @return nothing
1441 */
1442function pwg_init()
1443{
1444  //~ pwg_log('>>>>> pwg_init() >>>>>'."\n");
1445
1446  global $g_message, $g_listing, $g_footer, $conf, $pwg_conf, $start_time;
1447  $init_message = '';
1448 
1449  // Lock other script sessions, this lock will be remove during 'exit' step
1450  if (!isset($_SESSION['scan_step']))
1451  {
1452    $fp = @fopen(__FILE__.'.lock', 'x+'); // return false if __FILE__.lock exists or if cannot create
1453    if ($fp == false)
1454    {
1455      $g_header   = $_SESSION['scan_action'];
1456      $g_message  = '        <code class="failure">Failure -</code> Another script is running';
1457      $g_message .= ' <img src="'.$pwg_conf['icon_dir'].'add_tag.png" title="Delete file '.__FILE__.'.lock and retry" />';
1458      $g_message .= "\n";
1459      $g_footer   = '<a href="'.$pwg_conf['this_url'].'" title="Main menu"><img src="'.$pwg_conf['icon_dir'].'up.png" /></a>'."\n";
1460      $_SESSION['scan_step'] = 'exit';
1461      //~ pwg_log('<<<<< pwg_init() failure <<<<<'."\n");
1462      return;
1463    }
1464    else
1465    {
1466      fwrite($fp, session_id()); // Writing session_id to trace lock
1467      fclose($fp);
1468      $_SESSION['scan_step'] = 'init';
1469    }
1470  }
1471 
1472  // Verify and backup parameter action. This backup will be removed during step 'exit'
1473  if (isset($_REQUEST['action']))
1474  {
1475    if (in_array($_REQUEST['action'], $pwg_conf['scan_action']))
1476    {
1477      if (isset($_SESSION['scan_action']))
1478      {
1479        if ($_SESSION['scan_action'] != $_REQUEST['action'])
1480        {
1481          // Fatal error
1482          $g_message  = '        <code class="failure">Failure -</code> Parameter <code>action</code> differs between url and session';
1483          $g_message .= "\n";
1484          $g_footer   = '<a href="'.$pwg_conf['this_url'].'" title="Main menu"><img src="'.$pwg_conf['icon_dir'].'up.png" /></a>'."\n";
1485          $_SESSION['scan_step'] = 'exit';
1486          //~ pwg_log('<<<<< pwg_init() failure <<<<<'."\n");
1487          return;
1488        }
1489      }
1490      else
1491      {
1492        $_SESSION['scan_action'] = $_REQUEST['action'];
1493      }
1494    }
1495    else
1496    {
1497      // Fatal error
1498      $g_message  = '        <code class="failure">Failure -</code> Problem with <code>action</code> parameter';
1499      $g_message .= ' <img src="'.$pwg_conf['icon_dir'].'add_tag.png" title="empty, '.implode(', ', $pwg_conf['scan_action']).'" />';
1500      $g_message .= "\n";
1501      $g_footer   = '<a href="'.$pwg_conf['this_url'].'" title="Main menu"><img src="'.$pwg_conf['icon_dir'].'up.png" /></a>'."\n";
1502      $_SESSION['scan_step'] = 'exit';
1503      //~ pwg_log('<<<<< pwg_init() failure <<<<<'."\n");
1504      return;
1505    }
1506  }
1507  else
1508  {
1509    // Here we are on welcome page
1510    $g_message  = '        <ul>'."\n";
1511    $g_message .= '          <li><a href="'.$pwg_conf['this_url'].'?action=test" title="Display/Compare script version">Test</a></li>'."\n";
1512    $g_message .= '          <li><a href="'.$pwg_conf['this_url'].'?action=clean" title="Delete listing.xml if exists">Clean</a></li>'."\n";
1513    $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";
1514    $g_message .= '        </ul>'."\n";
1515    $g_footer   = '<a href="'.$conf['gallery'].'/admin.php?page=site_manager" title="Main gallery :: site manager">';
1516    $g_footer  .= '<img src="'.$pwg_conf['icon_dir'].'home.png" /></a>'."\n";
1517    $_SESSION['scan_step'] = 'exit';
1518    $_SESSION['scan_action'] = '';
1519  }
1520 
1521  // Actions to do at the init of generate
1522  if ($_SESSION['scan_action'] == 'generate')
1523  {
1524    // Open XML file
1525    $mode = ($_SESSION['scan_step'] == 'init') ? 'w' : 'a'; // Erase old listing.xml at the beginning of generation (mode w)
1526    $g_listing = @fopen('listing.xml', $mode);
1527    if ($g_listing === false)
1528    {
1529      $g_header   = $_SESSION['scan_action'];
1530      $g_message  = '        <code class="failure">Failure -</code> Can not write file <code>listing.xml</code>';
1531      $g_message .= "\n";
1532      $g_footer   = '<a href="'.$pwg_conf['this_url'].'" title="Main menu"><img src="'.$pwg_conf['icon_dir'].'up.png" /></a>'."\n";
1533      $_SESSION['scan_step'] = 'exit';
1534      //~ pwg_log('<<<<< pwg_init() failure <<<<<'."\n");
1535      return;
1536    }
1537   
1538    // Check graphical capabilities
1539    $init_message = pwg_check_graphics();
1540  }
1541   
1542  // Initializing session counters. This counters will be completely unset during step 'exit'
1543  if ($_SESSION['scan_step'] == 'init')
1544  {
1545    $_SESSION['scan_list_file'] = array();
1546    $_SESSION['scan_list_fold'] = array();
1547    $_SESSION['scan_cnt_file'] = 0;
1548    $_SESSION['scan_cnt_fold'] = 0;
1549    $_SESSION['scan_time'] = $start_time;
1550    $_SESSION['scan_step'] = 'start';
1551    $_SESSION['scan_logs'] = $init_message;
1552  }
1553 
1554  //~ pwg_log('<<<<< pwg_init() success <<<<<'."\n");
1555}
1556
1557/**
1558 * This function :
1559 * -> Close listing.xml if action is 'generate'
1560 * -> Unlock the script
1561 * -> Erase session variables
1562 *
1563 * @return nothing
1564 */
1565function pwg_exit()
1566{
1567  //~ pwg_log('>>>>> pwg_exit() >>>>>'."\n");
1568 
1569  global $g_listing;
1570 
1571  // Close XML file
1572  if ($_SESSION['scan_action'] == 'generate' and $g_listing != false)
1573  {
1574    fclose($g_listing);
1575  }
1576 
1577  // Unlock script
1578  unlink(__FILE__.'.lock');
1579 
1580  // Erase session counters
1581  unset($_SESSION['scan_list_file']);
1582  unset($_SESSION['scan_list_fold']);
1583  unset($_SESSION['scan_cnt_file']);
1584  unset($_SESSION['scan_cnt_fold']);
1585  unset($_SESSION['scan_time']);
1586  unset($_SESSION['scan_step']);
1587  $local_action = $_SESSION['scan_action'];
1588  unset($_SESSION['scan_action']);
1589  unset($_SESSION['scan_logs']);
1590  session_destroy();
1591 
1592  // Call specific action post process
1593  if (is_callable('pwg_'.$local_action.'_exit'))
1594  {
1595    call_user_func('pwg_'.$local_action.'_exit');
1596  }
1597 
1598  //~ pwg_log('<<<<< pwg_exit() <<<<<'."\n");
1599}
1600
1601// +-----------------------------------------------------------------------+
1602// |                                Script                                 |
1603// +-----------------------------------------------------------------------+
1604session_save_path('.');
1605session_start();
1606
1607$start_time = pwg_get_moment();
1608
1609// Initializing message for web page
1610$g_refresh = '';
1611$g_header  = '';
1612$g_message = '';
1613$g_footer  = '';
1614$g_listing = '';
1615
1616pwg_init();
1617
1618while(pwg_continue())
1619{
1620  if (is_callable('pwg_'.$_SESSION['scan_action'].'_'.$_SESSION['scan_step']))
1621  {
1622    call_user_func('pwg_'.$_SESSION['scan_action'].'_'.$_SESSION['scan_step']); // Run the step : start, list, scan, stop are available
1623  }
1624  else
1625  {
1626    $g_header   = $_SESSION['scan_action'];
1627    $g_message  = '        <code class="failure">Failure -</code> INTERNAL STEP ERROR : <code>pwg_'.$_SESSION['scan_action'].'_'.$_SESSION['scan_step'].'()</code> undefined';
1628    $g_message .= "\n";
1629    $g_footer   = '<a href="'.$pwg_conf['this_url'].'" title="Main menu"><img src="'.$pwg_conf['icon_dir'].'up.png" /></a>'."\n";
1630    $_SESSION['scan_step'] = 'exit';
1631  }
1632}
1633
1634if ($_SESSION['scan_step'] == 'exit')
1635{
1636  pwg_exit();
1637}
1638
1639?>
1640<html>
1641  <head>
1642  <?php echo $g_refresh; ?>
1643  <title>Manage remote gallery</title>
1644  </head>
1645    <style type="text/css">
1646      code {font-weight: bold}
1647      img {border-style: none; vertical-align: middle}
1648      ul {list-style-image: url(<?php echo $pwg_conf['icon_dir']; ?>add_tag.png)}     
1649      .success {color: green}
1650      .warning {color: orange}
1651      .failure {color: red}
1652      .header {text-align: center; font-variant: small-caps; font-weight: bold;}
1653      .p {color: #F93;}
1654      .w {color: #ccc;}
1655      .g {color: #69C;}
1656      .pwg {text-decoration: none; border-bottom-style: dotted; border-bottom-width: 1px;}
1657      .content {width: 75%; position: absolute; top: 10%; left: 12%;}
1658      .footer {text-align: right;}
1659      .pwg_block {float: left;}
1660    </style>
1661  <body>
1662    <div class="content">
1663      <fieldset class="header">
1664        <span class="p">Php</span>
1665        <span class="w">Web</span>
1666        <span class="g">Gallery</span>
1667        &nbsp;remote site<? echo $g_header; ?>
1668      </fieldset>
1669      <fieldset>
1670<?php echo $g_message; ?>
1671      </fieldset>
1672      <fieldset class="footer">
1673        <div class="pwg_block">
1674          Powered by <a href="http://www.phpwebgallery.net" class="pwg"><span class="p">Php</span><span class="w">Web</span><span class="g">Gallery</span></a>
1675        </div>
1676        <?php echo $g_footer; ?>
1677      </fieldset>
1678    </div>
1679  </body>
1680</html>
Note: See TracBrowser for help on using the repository browser.