source: trunk/admin/include/functions_upload.inc.php @ 12907

Last change on this file since 12907 was 12907, checked in by plg, 12 years ago

feature 2548 (multiple size): better delete derivatives in add_uploaded_file
function when performing an update of a photo.

File size: 13.3 KB
Line 
1<?php
2// +-----------------------------------------------------------------------+
3// | Piwigo - a PHP based photo gallery                                    |
4// +-----------------------------------------------------------------------+
5// | Copyright(C) 2008-2011 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
24include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
25include_once(PHPWG_ROOT_PATH.'admin/include/image.class.php');
26
27// add default event handler for image and thumbnail resize
28add_event_handler('upload_image_resize', 'pwg_image_resize', EVENT_HANDLER_PRIORITY_NEUTRAL, 7);
29add_event_handler('upload_thumbnail_resize', 'pwg_image_resize', EVENT_HANDLER_PRIORITY_NEUTRAL, 9);
30
31function get_upload_form_config()
32{
33  // default configuration for upload
34  $upload_form_config = array(
35    'original_resize' => array(
36      'default' => false,
37      'can_be_null' => false,
38      ),
39 
40    'original_resize_maxwidth' => array(
41      'default' => 2000,
42      'min' => 500,
43      'max' => 20000,
44      'pattern' => '/^\d+$/',
45      'can_be_null' => false,
46      'error_message' => l10n('The original maximum width must be a number between %d and %d'),
47      ),
48 
49    'original_resize_maxheight' => array(
50      'default' => 2000,
51      'min' => 300,
52      'max' => 20000,
53      'pattern' => '/^\d+$/',
54      'can_be_null' => false,
55      'error_message' => l10n('The original maximum height must be a number between %d and %d'),
56      ),
57 
58    'original_resize_quality' => array(
59      'default' => 95,
60      'min' => 50,
61      'max' => 98,
62      'pattern' => '/^\d+$/',
63      'can_be_null' => false,
64      'error_message' => l10n('The original image quality must be a number between %d and %d'),
65      ),
66    );
67
68  return $upload_form_config;
69}
70
71function save_upload_form_config($data, &$errors=array())
72{
73  if (!is_array($data) or empty($data))
74  {
75    return false;
76  }
77
78  $upload_form_config = get_upload_form_config();
79  $updates = array();
80
81  foreach ($data as $field => $value)
82  {
83    if (!isset($upload_form_config[$field]))
84    {
85      continue;
86    }
87    if (is_bool($upload_form_config[$field]['default']))
88    {
89      if (isset($value))
90      {
91        $value = true;
92      }
93      else
94      {
95        $value = false;
96      }
97
98      $updates[] = array(
99        'param' => $field,
100        'value' => boolean_to_string($value)
101        );
102    }
103    elseif ($upload_form_config[$field]['can_be_null'] and empty($value))
104    {
105      $updates[] = array(
106        'param' => $field,
107        'value' => 'false'
108        );
109    }
110    else
111    {
112      $min = $upload_form_config[$field]['min'];
113      $max = $upload_form_config[$field]['max'];
114      $pattern = $upload_form_config[$field]['pattern'];
115     
116      if (preg_match($pattern, $value) and $value >= $min and $value <= $max)
117      {
118         $updates[] = array(
119          'param' => $field,
120          'value' => $value
121          );
122      }
123      else
124      {
125        array_push(
126          $errors,
127          sprintf(
128            $upload_form_config[$field]['error_message'],
129            $min,
130            $max
131            )
132          );
133      }
134    }
135  }
136
137  if (count($errors) == 0)
138  {
139    mass_updates(
140      CONFIG_TABLE,
141      array(
142        'primary' => array('param'),
143        'update' => array('value')
144        ),
145      $updates
146      );
147    return true;
148  }
149
150  return false;
151}
152
153function add_uploaded_file($source_filepath, $original_filename=null, $categories=null, $level=null, $image_id=null, $original_md5sum=null)
154{
155  // 1) move uploaded file to upload/2010/01/22/20100122003814-449ada00.jpg
156  //
157  // 2) keep/resize original
158  //
159  // 3) register in database
160 
161  // TODO
162  // * check md5sum (already exists?)
163 
164  global $conf, $user;
165
166  if (isset($original_md5sum))
167  {
168    $md5sum = $original_md5sum;
169  }
170  else
171  {
172    $md5sum = md5_file($source_filepath);
173  }
174 
175  $file_path = null;
176 
177  if (isset($image_id))
178  {
179    // this photo already exists, we update it
180    $query = '
181SELECT
182    path
183  FROM '.IMAGES_TABLE.'
184  WHERE id = '.$image_id.'
185;';
186    $result = pwg_query($query);
187    while ($row = pwg_db_fetch_assoc($result))
188    {
189      $file_path = $row['path'];
190    }
191   
192    if (!isset($file_path))
193    {
194      die('['.__FUNCTION__.'] this photo does not exist in the database');
195    }
196
197    // delete all physical files related to the photo (thumbnail, web site, HD)
198    delete_element_files(array($image_id));
199  }
200  else
201  {
202    // this photo is new
203   
204    // current date
205    list($dbnow) = pwg_db_fetch_row(pwg_query('SELECT NOW();'));
206    list($year, $month, $day) = preg_split('/[^\d]/', $dbnow, 4);
207 
208    // upload directory hierarchy
209    $upload_dir = sprintf(
210      PHPWG_ROOT_PATH.$conf['upload_dir'].'/%s/%s/%s',
211      $year,
212      $month,
213      $day
214      );
215
216    // compute file path
217    $date_string = preg_replace('/[^\d]/', '', $dbnow);
218    $random_string = substr($md5sum, 0, 8);
219    $filename_wo_ext = $date_string.'-'.$random_string;
220    $file_path = $upload_dir.'/'.$filename_wo_ext.'.';
221
222    list($width, $height, $type) = getimagesize($source_filepath);
223    if (IMAGETYPE_PNG == $type)
224    {
225      $file_path.= 'png';
226    }
227    elseif (IMAGETYPE_GIF == $type)
228    {
229      $file_path.= 'gif';
230    }
231    else
232    {
233      $file_path.= 'jpg';
234    }
235
236    prepare_directory($upload_dir);
237  }
238
239  if (is_uploaded_file($source_filepath))
240  {
241    move_uploaded_file($source_filepath, $file_path);
242  }
243  else
244  {
245    rename($source_filepath, $file_path);
246  }
247
248  if (pwg_image::get_library() != 'gd')
249  {
250    if ($conf['original_resize'])
251    {
252      $need_resize = need_resize($file_path, $conf['original_resize_maxwidth'], $conf['original_resize_maxheight']);
253     
254      if ($need_resize)
255      {
256        $img = new pwg_image($file_path);
257           
258        $img->pwg_resize(
259          $file_path,
260          $conf['original_resize_maxwidth'],
261          $conf['original_resize_maxheight'],
262          $conf['original_resize_quality'],
263          $conf['upload_form_automatic_rotation'],
264          false
265          );
266       
267        $img->destroy();
268      }
269    }
270  }
271
272  $file_infos = pwg_image_infos($file_path);
273 
274  if (isset($image_id))
275  {
276    $update = array(
277      'file' => pwg_db_real_escape_string(isset($original_filename) ? $original_filename : basename($file_path)),
278      'filesize' => $file_infos['filesize'],
279      'width' => $file_infos['width'],
280      'height' => $file_infos['height'],
281      'md5sum' => $md5sum,
282      'added_by' => $user['id'],
283      );
284   
285    if (isset($level))
286    {
287      $update['level'] = $level;
288    }
289
290    single_update(
291      IMAGES_TABLE,
292      $update,
293      array('id' => $image_id)
294      );
295
296    delete_element_derivatives($image_id);
297  }
298  else
299  {
300    // database registration
301    $insert = array(
302      'file' => pwg_db_real_escape_string(isset($original_filename) ? $original_filename : basename($file_path)),
303      'date_available' => $dbnow,
304      'path' => preg_replace('#^'.preg_quote(PHPWG_ROOT_PATH).'#', '', $file_path),
305      'filesize' => $file_infos['filesize'],
306      'width' => $file_infos['width'],
307      'height' => $file_infos['height'],
308      'md5sum' => $md5sum,
309      'added_by' => $user['id'],
310      );
311   
312    if (isset($level))
313    {
314      $insert['level'] = $level;
315    }
316
317    single_insert(IMAGES_TABLE, $insert);
318 
319    $image_id = pwg_db_insert_id(IMAGES_TABLE);
320  }
321
322  if (isset($categories) and count($categories) > 0)
323  {
324    associate_images_to_categories(
325      array($image_id),
326      $categories
327      );
328  }
329 
330  // update metadata from the uploaded file (exif/iptc)
331  if ($conf['use_exif'] and !function_exists('read_exif_data'))
332  {
333    $conf['use_exif'] = false;
334  }
335  sync_metadata(array($image_id));
336
337  invalidate_user_cache();
338
339  return $image_id;
340}
341
342function prepare_directory($directory)
343{
344  if (!is_dir($directory)) {
345    if (substr(PHP_OS, 0, 3) == 'WIN')
346    {
347      $directory = str_replace('/', DIRECTORY_SEPARATOR, $directory);
348    }
349    umask(0000);
350    $recursive = true;
351    if (!@mkdir($directory, 0777, $recursive))
352    {
353      die('[prepare_directory] cannot create directory "'.$directory.'"');
354    }
355  }
356
357  if (!is_writable($directory))
358  {
359    // last chance to make the directory writable
360    @chmod($directory, 0777);
361
362    if (!is_writable($directory))
363    {
364      die('[prepare_directory] directory "'.$directory.'" has no write access');
365    }
366  }
367
368  secure_directory($directory);
369}
370
371function need_resize($image_filepath, $max_width, $max_height)
372{
373  // TODO : the resize check should take the orientation into account. If a
374  // rotation must be applied to the resized photo, then we should test
375  // invert width and height.
376  list($width, $height) = getimagesize($image_filepath);
377 
378  if ($width > $max_width or $height > $max_height)
379  {
380    return true;
381  }
382
383  return false;
384}
385
386function pwg_image_infos($path)
387{
388  list($width, $height) = getimagesize($path);
389  $filesize = floor(filesize($path)/1024);
390 
391  return array(
392    'width'  => $width,
393    'height' => $height,
394    'filesize' => $filesize,
395    );
396}
397
398function is_valid_image_extension($extension)
399{
400  return in_array(strtolower($extension), array('jpg', 'jpeg', 'png', 'gif'));
401}
402
403function file_upload_error_message($error_code)
404{
405  switch ($error_code) {
406    case UPLOAD_ERR_INI_SIZE:
407      return sprintf(
408        l10n('The uploaded file exceeds the upload_max_filesize directive in php.ini: %sB'),
409        get_ini_size('upload_max_filesize', false)
410        );
411    case UPLOAD_ERR_FORM_SIZE:
412      return l10n('The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form');
413    case UPLOAD_ERR_PARTIAL:
414      return l10n('The uploaded file was only partially uploaded');
415    case UPLOAD_ERR_NO_FILE:
416      return l10n('No file was uploaded');
417    case UPLOAD_ERR_NO_TMP_DIR:
418      return l10n('Missing a temporary folder');
419    case UPLOAD_ERR_CANT_WRITE:
420      return l10n('Failed to write file to disk');
421    case UPLOAD_ERR_EXTENSION:
422      return l10n('File upload stopped by extension');
423    default:
424      return l10n('Unknown upload error');
425  }
426}
427
428function get_ini_size($ini_key, $in_bytes=true)
429{
430  $size = ini_get($ini_key);
431
432  if ($in_bytes)
433  {
434    $size = convert_shorthand_notation_to_bytes($size);
435  }
436 
437  return $size;
438}
439
440function convert_shorthand_notation_to_bytes($value)
441{
442  $suffix = substr($value, -1);
443  $multiply_by = null;
444 
445  if ('K' == $suffix)
446  {
447    $multiply_by = 1024;
448  }
449  else if ('M' == $suffix)
450  {
451    $multiply_by = 1024*1024;
452  }
453  else if ('G' == $suffix)
454  {
455    $multiply_by = 1024*1024*1024;
456  }
457 
458  if (isset($multiply_by))
459  {
460    $value = substr($value, 0, -1);
461    $value*= $multiply_by;
462  }
463
464  return $value;
465}
466
467function add_upload_error($upload_id, $error_message)
468{
469  if (!isset($_SESSION['uploads_error']))
470  {
471    $_SESSION['uploads_error'] = array();
472  }
473  if (!isset($_SESSION['uploads_error'][$upload_id]))
474  {
475    $_SESSION['uploads_error'][$upload_id] = array();
476  }
477
478  array_push($_SESSION['uploads_error'][$upload_id], $error_message);
479}
480
481function ready_for_upload_message()
482{
483  global $conf;
484
485  $relative_dir = preg_replace('#^'.PHPWG_ROOT_PATH.'#', '', $conf['upload_dir']);
486
487  if (!is_dir($conf['upload_dir']))
488  {
489    if (!is_writable(dirname($conf['upload_dir'])))
490    {
491      return sprintf(
492        l10n('Create the "%s" directory at the root of your Piwigo installation'),
493        $relative_dir
494        );
495    }
496  }
497  else
498  {
499    if (!is_writable($conf['upload_dir']))
500    {
501      @chmod($conf['upload_dir'], 0777);
502     
503      if (!is_writable($conf['upload_dir']))
504      {
505        return sprintf(
506          l10n('Give write access (chmod 777) to "%s" directory at the root of your Piwigo installation'),
507          $relative_dir
508          );
509      }
510    }
511  }
512
513  return null;
514}
515
516function file_path_for_type($file_path, $type='thumb')
517{
518  // resolve the $file_path depending on the $type
519  if ('thumb' == $type) {
520    $file_path = get_thumbnail_location(
521      array(
522        'path' => $file_path,
523        'tn_ext' => 'jpg',
524        )
525      );
526  }
527
528  if ('high' == $type) {
529    @include_once(PHPWG_ROOT_PATH.'include/functions_picture.inc.php');
530    $file_path = get_high_location(
531      array(
532        'path' => $file_path,
533        'has_high' => 'true'
534        )
535      );
536  }
537
538  return $file_path;
539}
540
541?>
Note: See TracBrowser for help on using the repository browser.