source: branches/2.0/tools/create_listing_file.php @ 4036

Last change on this file since 4036 was 4036, checked in by patdenice, 15 years ago

Replace another depreciated functions.
Depreciated functions were removed in trunk in commit 3747 by Eric.

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