source: branches/2.5/admin/include/functions_upload.inc.php @ 29905

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

update Piwigo headers to 2013 (the end of the world didn't occur as expected on r12922)

File size: 13.5 KB
Line 
1<?php
2// +-----------------------------------------------------------------------+
3// | Piwigo - a PHP based photo gallery                                    |
4// +-----------------------------------------------------------------------+
5// | Copyright(C) 2008-2013 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(), &$form_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        $form_errors[$field] = '['.$min.' .. '.$max.']';
135      }
136    }
137  }
138
139  if (count($errors) == 0)
140  {
141    mass_updates(
142      CONFIG_TABLE,
143      array(
144        'primary' => array('param'),
145        'update' => array('value')
146        ),
147      $updates
148      );
149    return true;
150  }
151
152  return false;
153}
154
155function add_uploaded_file($source_filepath, $original_filename=null, $categories=null, $level=null, $image_id=null, $original_md5sum=null)
156{
157  // 1) move uploaded file to upload/2010/01/22/20100122003814-449ada00.jpg
158  //
159  // 2) keep/resize original
160  //
161  // 3) register in database
162
163  // TODO
164  // * check md5sum (already exists?)
165
166  global $conf, $user;
167
168  if (isset($original_md5sum))
169  {
170    $md5sum = $original_md5sum;
171  }
172  else
173  {
174    $md5sum = md5_file($source_filepath);
175  }
176
177  $file_path = null;
178
179  if (isset($image_id))
180  {
181    // this photo already exists, we update it
182    $query = '
183SELECT
184    path
185  FROM '.IMAGES_TABLE.'
186  WHERE id = '.$image_id.'
187;';
188    $result = pwg_query($query);
189    while ($row = pwg_db_fetch_assoc($result))
190    {
191      $file_path = $row['path'];
192    }
193
194    if (!isset($file_path))
195    {
196      die('['.__FUNCTION__.'] this photo does not exist in the database');
197    }
198
199    // delete all physical files related to the photo (thumbnail, web site, HD)
200    delete_element_files(array($image_id));
201  }
202  else
203  {
204    // this photo is new
205
206    // current date
207    list($dbnow) = pwg_db_fetch_row(pwg_query('SELECT NOW();'));
208    list($year, $month, $day) = preg_split('/[^\d]/', $dbnow, 4);
209
210    // upload directory hierarchy
211    $upload_dir = sprintf(
212      PHPWG_ROOT_PATH.$conf['upload_dir'].'/%s/%s/%s',
213      $year,
214      $month,
215      $day
216      );
217
218    // compute file path
219    $date_string = preg_replace('/[^\d]/', '', $dbnow);
220    $random_string = substr($md5sum, 0, 8);
221    $filename_wo_ext = $date_string.'-'.$random_string;
222    $file_path = $upload_dir.'/'.$filename_wo_ext.'.';
223
224    list($width, $height, $type) = getimagesize($source_filepath);
225    if (IMAGETYPE_PNG == $type)
226    {
227      $file_path.= 'png';
228    }
229    elseif (IMAGETYPE_GIF == $type)
230    {
231      $file_path.= 'gif';
232    }
233    else
234    {
235      $file_path.= 'jpg';
236    }
237
238    prepare_directory($upload_dir);
239  }
240
241  if (is_uploaded_file($source_filepath))
242  {
243    move_uploaded_file($source_filepath, $file_path);
244  }
245  else
246  {
247    rename($source_filepath, $file_path);
248  }
249  @chmod($file_path, 0644);
250
251  if (pwg_image::get_library() != 'gd')
252  {
253    if ($conf['original_resize'])
254    {
255      $need_resize = need_resize($file_path, $conf['original_resize_maxwidth'], $conf['original_resize_maxheight']);
256
257      if ($need_resize)
258      {
259        $img = new pwg_image($file_path);
260
261        $img->pwg_resize(
262          $file_path,
263          $conf['original_resize_maxwidth'],
264          $conf['original_resize_maxheight'],
265          $conf['original_resize_quality'],
266          $conf['upload_form_automatic_rotation'],
267          false
268          );
269
270        $img->destroy();
271      }
272    }
273  }
274
275  // we need to save the rotation angle in the database to compute
276  // width/height of "multisizes"
277  $rotation_angle = pwg_image::get_rotation_angle($file_path);
278  $rotation = pwg_image::get_rotation_code_from_angle($rotation_angle);
279 
280  $file_infos = pwg_image_infos($file_path);
281
282  if (isset($image_id))
283  {
284    $update = array(
285      'file' => pwg_db_real_escape_string(isset($original_filename) ? $original_filename : basename($file_path)),
286      'filesize' => $file_infos['filesize'],
287      'width' => $file_infos['width'],
288      'height' => $file_infos['height'],
289      'md5sum' => $md5sum,
290      'added_by' => $user['id'],
291      'rotation' => $rotation,
292      );
293
294    if (isset($level))
295    {
296      $update['level'] = $level;
297    }
298
299    single_update(
300      IMAGES_TABLE,
301      $update,
302      array('id' => $image_id)
303      );
304  }
305  else
306  {
307    // database registration
308    $file = pwg_db_real_escape_string(isset($original_filename) ? $original_filename : basename($file_path));
309    $insert = array(
310      'file' => $file,
311      'name' => get_name_from_file($file),
312      'date_available' => $dbnow,
313      'path' => preg_replace('#^'.preg_quote(PHPWG_ROOT_PATH).'#', '', $file_path),
314      'filesize' => $file_infos['filesize'],
315      'width' => $file_infos['width'],
316      'height' => $file_infos['height'],
317      'md5sum' => $md5sum,
318      'added_by' => $user['id'],
319      'rotation' => $rotation,
320      );
321
322    if (isset($level))
323    {
324      $insert['level'] = $level;
325    }
326
327    single_insert(IMAGES_TABLE, $insert);
328
329    $image_id = pwg_db_insert_id(IMAGES_TABLE);
330  }
331
332  if (isset($categories) and count($categories) > 0)
333  {
334    associate_images_to_categories(
335      array($image_id),
336      $categories
337      );
338  }
339
340  // update metadata from the uploaded file (exif/iptc)
341  if ($conf['use_exif'] and !function_exists('read_exif_data'))
342  {
343    $conf['use_exif'] = false;
344  }
345  sync_metadata(array($image_id));
346
347  invalidate_user_cache();
348
349  // cache thumbnail
350  $query = '
351SELECT
352    id,
353    path
354  FROM '.IMAGES_TABLE.'
355  WHERE id = '.$image_id.'
356;';
357  $image_infos = pwg_db_fetch_assoc(pwg_query($query));
358
359  set_make_full_url();
360  // in case we are on uploadify.php, we have to replace the false path
361  $thumb_url = preg_replace('#admin/include/i#', 'i', DerivativeImage::thumb_url($image_infos));
362  unset_make_full_url();
363 
364  fetchRemote($thumb_url, $dest);
365 
366
367  return $image_id;
368}
369
370function prepare_directory($directory)
371{
372  if (!is_dir($directory)) {
373    if (substr(PHP_OS, 0, 3) == 'WIN')
374    {
375      $directory = str_replace('/', DIRECTORY_SEPARATOR, $directory);
376    }
377    umask(0000);
378    $recursive = true;
379    if (!@mkdir($directory, 0777, $recursive))
380    {
381      die('[prepare_directory] cannot create directory "'.$directory.'"');
382    }
383  }
384
385  if (!is_writable($directory))
386  {
387    // last chance to make the directory writable
388    @chmod($directory, 0777);
389
390    if (!is_writable($directory))
391    {
392      die('[prepare_directory] directory "'.$directory.'" has no write access');
393    }
394  }
395
396  secure_directory($directory);
397}
398
399function need_resize($image_filepath, $max_width, $max_height)
400{
401  // TODO : the resize check should take the orientation into account. If a
402  // rotation must be applied to the resized photo, then we should test
403  // invert width and height.
404  list($width, $height) = getimagesize($image_filepath);
405
406  if ($width > $max_width or $height > $max_height)
407  {
408    return true;
409  }
410
411  return false;
412}
413
414function pwg_image_infos($path)
415{
416  list($width, $height) = getimagesize($path);
417  $filesize = floor(filesize($path)/1024);
418
419  return array(
420    'width'  => $width,
421    'height' => $height,
422    'filesize' => $filesize,
423    );
424}
425
426function is_valid_image_extension($extension)
427{
428  return in_array(strtolower($extension), array('jpg', 'jpeg', 'png', 'gif'));
429}
430
431function file_upload_error_message($error_code)
432{
433  switch ($error_code) {
434    case UPLOAD_ERR_INI_SIZE:
435      return sprintf(
436        l10n('The uploaded file exceeds the upload_max_filesize directive in php.ini: %sB'),
437        get_ini_size('upload_max_filesize', false)
438        );
439    case UPLOAD_ERR_FORM_SIZE:
440      return l10n('The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form');
441    case UPLOAD_ERR_PARTIAL:
442      return l10n('The uploaded file was only partially uploaded');
443    case UPLOAD_ERR_NO_FILE:
444      return l10n('No file was uploaded');
445    case UPLOAD_ERR_NO_TMP_DIR:
446      return l10n('Missing a temporary folder');
447    case UPLOAD_ERR_CANT_WRITE:
448      return l10n('Failed to write file to disk');
449    case UPLOAD_ERR_EXTENSION:
450      return l10n('File upload stopped by extension');
451    default:
452      return l10n('Unknown upload error');
453  }
454}
455
456function get_ini_size($ini_key, $in_bytes=true)
457{
458  $size = ini_get($ini_key);
459
460  if ($in_bytes)
461  {
462    $size = convert_shorthand_notation_to_bytes($size);
463  }
464
465  return $size;
466}
467
468function convert_shorthand_notation_to_bytes($value)
469{
470  $suffix = substr($value, -1);
471  $multiply_by = null;
472
473  if ('K' == $suffix)
474  {
475    $multiply_by = 1024;
476  }
477  else if ('M' == $suffix)
478  {
479    $multiply_by = 1024*1024;
480  }
481  else if ('G' == $suffix)
482  {
483    $multiply_by = 1024*1024*1024;
484  }
485
486  if (isset($multiply_by))
487  {
488    $value = substr($value, 0, -1);
489    $value*= $multiply_by;
490  }
491
492  return $value;
493}
494
495function add_upload_error($upload_id, $error_message)
496{
497  if (!isset($_SESSION['uploads_error']))
498  {
499    $_SESSION['uploads_error'] = array();
500  }
501  if (!isset($_SESSION['uploads_error'][$upload_id]))
502  {
503    $_SESSION['uploads_error'][$upload_id] = array();
504  }
505
506  array_push($_SESSION['uploads_error'][$upload_id], $error_message);
507}
508
509function ready_for_upload_message()
510{
511  global $conf;
512
513  $relative_dir = preg_replace('#^'.PHPWG_ROOT_PATH.'#', '', $conf['upload_dir']);
514
515  if (!is_dir($conf['upload_dir']))
516  {
517    if (!is_writable(dirname($conf['upload_dir'])))
518    {
519      return sprintf(
520        l10n('Create the "%s" directory at the root of your Piwigo installation'),
521        $relative_dir
522        );
523    }
524  }
525  else
526  {
527    if (!is_writable($conf['upload_dir']))
528    {
529      @chmod($conf['upload_dir'], 0777);
530
531      if (!is_writable($conf['upload_dir']))
532      {
533        return sprintf(
534          l10n('Give write access (chmod 777) to "%s" directory at the root of your Piwigo installation'),
535          $relative_dir
536          );
537      }
538    }
539  }
540
541  return null;
542}
543?>
Note: See TracBrowser for help on using the repository browser.