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

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

feature 2548 (multiple sizes): adapt the web API method pwg.images.add (used
by pLoader, Digikam, Lightroom, iPhoto), pwg.images.checkFiles (pLoader only).

The "resize" parameter was removed for pwg.images.add since this behavior
becomes the default behavior in Piwigo 2.4.

Just like pwg.images.addSimple, pwg.images.add now uses the add_uploaded_file
function (next step is to merge pwg.images.add and pwg.images.addSimple)

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  else
297  {
298    // database registration
299    $insert = array(
300      'file' => pwg_db_real_escape_string(isset($original_filename) ? $original_filename : basename($file_path)),
301      'date_available' => $dbnow,
302      'path' => preg_replace('#^'.preg_quote(PHPWG_ROOT_PATH).'#', '', $file_path),
303      'filesize' => $file_infos['filesize'],
304      'width' => $file_infos['width'],
305      'height' => $file_infos['height'],
306      'md5sum' => $md5sum,
307      'added_by' => $user['id'],
308      );
309   
310    if (isset($level))
311    {
312      $insert['level'] = $level;
313    }
314
315    single_insert(IMAGES_TABLE, $insert);
316 
317    $image_id = pwg_db_insert_id(IMAGES_TABLE);
318  }
319
320  if (isset($categories) and count($categories) > 0)
321  {
322    associate_images_to_categories(
323      array($image_id),
324      $categories
325      );
326  }
327 
328  // update metadata from the uploaded file (exif/iptc)
329  if ($conf['use_exif'] and !function_exists('read_exif_data'))
330  {
331    $conf['use_exif'] = false;
332  }
333  sync_metadata(array($image_id));
334
335  invalidate_user_cache();
336
337  return $image_id;
338}
339
340function prepare_directory($directory)
341{
342  if (!is_dir($directory)) {
343    if (substr(PHP_OS, 0, 3) == 'WIN')
344    {
345      $directory = str_replace('/', DIRECTORY_SEPARATOR, $directory);
346    }
347    umask(0000);
348    $recursive = true;
349    if (!@mkdir($directory, 0777, $recursive))
350    {
351      die('[prepare_directory] cannot create directory "'.$directory.'"');
352    }
353  }
354
355  if (!is_writable($directory))
356  {
357    // last chance to make the directory writable
358    @chmod($directory, 0777);
359
360    if (!is_writable($directory))
361    {
362      die('[prepare_directory] directory "'.$directory.'" has no write access');
363    }
364  }
365
366  secure_directory($directory);
367}
368
369function need_resize($image_filepath, $max_width, $max_height)
370{
371  // TODO : the resize check should take the orientation into account. If a
372  // rotation must be applied to the resized photo, then we should test
373  // invert width and height.
374  list($width, $height) = getimagesize($image_filepath);
375 
376  if ($width > $max_width or $height > $max_height)
377  {
378    return true;
379  }
380
381  return false;
382}
383
384function pwg_image_infos($path)
385{
386  list($width, $height) = getimagesize($path);
387  $filesize = floor(filesize($path)/1024);
388 
389  return array(
390    'width'  => $width,
391    'height' => $height,
392    'filesize' => $filesize,
393    );
394}
395
396function is_valid_image_extension($extension)
397{
398  return in_array(strtolower($extension), array('jpg', 'jpeg', 'png', 'gif'));
399}
400
401function file_upload_error_message($error_code)
402{
403  switch ($error_code) {
404    case UPLOAD_ERR_INI_SIZE:
405      return sprintf(
406        l10n('The uploaded file exceeds the upload_max_filesize directive in php.ini: %sB'),
407        get_ini_size('upload_max_filesize', false)
408        );
409    case UPLOAD_ERR_FORM_SIZE:
410      return l10n('The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form');
411    case UPLOAD_ERR_PARTIAL:
412      return l10n('The uploaded file was only partially uploaded');
413    case UPLOAD_ERR_NO_FILE:
414      return l10n('No file was uploaded');
415    case UPLOAD_ERR_NO_TMP_DIR:
416      return l10n('Missing a temporary folder');
417    case UPLOAD_ERR_CANT_WRITE:
418      return l10n('Failed to write file to disk');
419    case UPLOAD_ERR_EXTENSION:
420      return l10n('File upload stopped by extension');
421    default:
422      return l10n('Unknown upload error');
423  }
424}
425
426function get_ini_size($ini_key, $in_bytes=true)
427{
428  $size = ini_get($ini_key);
429
430  if ($in_bytes)
431  {
432    $size = convert_shorthand_notation_to_bytes($size);
433  }
434 
435  return $size;
436}
437
438function convert_shorthand_notation_to_bytes($value)
439{
440  $suffix = substr($value, -1);
441  $multiply_by = null;
442 
443  if ('K' == $suffix)
444  {
445    $multiply_by = 1024;
446  }
447  else if ('M' == $suffix)
448  {
449    $multiply_by = 1024*1024;
450  }
451  else if ('G' == $suffix)
452  {
453    $multiply_by = 1024*1024*1024;
454  }
455 
456  if (isset($multiply_by))
457  {
458    $value = substr($value, 0, -1);
459    $value*= $multiply_by;
460  }
461
462  return $value;
463}
464
465function add_upload_error($upload_id, $error_message)
466{
467  if (!isset($_SESSION['uploads_error']))
468  {
469    $_SESSION['uploads_error'] = array();
470  }
471  if (!isset($_SESSION['uploads_error'][$upload_id]))
472  {
473    $_SESSION['uploads_error'][$upload_id] = array();
474  }
475
476  array_push($_SESSION['uploads_error'][$upload_id], $error_message);
477}
478
479function ready_for_upload_message()
480{
481  global $conf;
482
483  $relative_dir = preg_replace('#^'.PHPWG_ROOT_PATH.'#', '', $conf['upload_dir']);
484
485  if (!is_dir($conf['upload_dir']))
486  {
487    if (!is_writable(dirname($conf['upload_dir'])))
488    {
489      return sprintf(
490        l10n('Create the "%s" directory at the root of your Piwigo installation'),
491        $relative_dir
492        );
493    }
494  }
495  else
496  {
497    if (!is_writable($conf['upload_dir']))
498    {
499      @chmod($conf['upload_dir'], 0777);
500     
501      if (!is_writable($conf['upload_dir']))
502      {
503        return sprintf(
504          l10n('Give write access (chmod 777) to "%s" directory at the root of your Piwigo installation'),
505          $relative_dir
506          );
507      }
508    }
509  }
510
511  return null;
512}
513
514function file_path_for_type($file_path, $type='thumb')
515{
516  // resolve the $file_path depending on the $type
517  if ('thumb' == $type) {
518    $file_path = get_thumbnail_location(
519      array(
520        'path' => $file_path,
521        'tn_ext' => 'jpg',
522        )
523      );
524  }
525
526  if ('high' == $type) {
527    @include_once(PHPWG_ROOT_PATH.'include/functions_picture.inc.php');
528    $file_path = get_high_location(
529      array(
530        'path' => $file_path,
531        'has_high' => 'true'
532        )
533      );
534  }
535
536  return $file_path;
537}
538
539?>
Note: See TracBrowser for help on using the repository browser.