source: trunk/include/ws_functions/pwg.images.php @ 28554

Last change on this file since 28554 was 28554, checked in by plg, 10 years ago

feature 2616: better behavior at the end of upload (more like with uploadify, but no page reload)

File size: 41.2 KB
Line 
1<?php
2// +-----------------------------------------------------------------------+
3// | Piwigo - a PHP based photo gallery                                    |
4// +-----------------------------------------------------------------------+
5// | Copyright(C) 2008-2014 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// | UTILITIES                                                             |
26// +-----------------------------------------------------------------------+
27
28/**
29 * Sets associations of an image
30 * @param int $image_id
31 * @param string $categories_string - "cat_id[,rank];cat_id[,rank]"
32 * @param bool $replace_mode - removes old associations
33 */
34function ws_add_image_category_relations($image_id, $categories_string, $replace_mode=false)
35{
36  // let's add links between the image and the categories
37  //
38  // $params['categories'] should look like 123,12;456,auto;789 which means:
39  //
40  // 1. associate with category 123 on rank 12
41  // 2. associate with category 456 on automatic rank
42  // 3. associate with category 789 on automatic rank
43  $cat_ids = array();
44  $rank_on_category = array();
45  $search_current_ranks = false;
46
47  $tokens = explode(';', $categories_string);
48  foreach ($tokens as $token)
49  {
50    @list($cat_id, $rank) = explode(',', $token);
51
52    if (!preg_match('/^\d+$/', $cat_id))
53    {
54      continue;
55    }
56
57    $cat_ids[] = $cat_id;
58
59    if (!isset($rank))
60    {
61      $rank = 'auto';
62    }
63    $rank_on_category[$cat_id] = $rank;
64
65    if ($rank == 'auto')
66    {
67      $search_current_ranks = true;
68    }
69  }
70
71  $cat_ids = array_unique($cat_ids);
72
73  if (count($cat_ids) == 0)
74  {
75    return new PwgError(500,
76      '[ws_add_image_category_relations] there is no category defined in "'.$categories_string.'"'
77      );
78  }
79
80  $query = '
81SELECT id
82  FROM '.CATEGORIES_TABLE.'
83  WHERE id IN ('.implode(',', $cat_ids).')
84;';
85  $db_cat_ids = array_from_query($query, 'id');
86
87  $unknown_cat_ids = array_diff($cat_ids, $db_cat_ids);
88  if (count($unknown_cat_ids) != 0)
89  {
90    return new PwgError(500,
91      '[ws_add_image_category_relations] the following categories are unknown: '.implode(', ', $unknown_cat_ids)
92      );
93  }
94
95  $to_update_cat_ids = array();
96
97  // in case of replace mode, we first check the existing associations
98  $query = '
99SELECT category_id
100  FROM '.IMAGE_CATEGORY_TABLE.'
101  WHERE image_id = '.$image_id.'
102;';
103  $existing_cat_ids = array_from_query($query, 'category_id');
104
105  if ($replace_mode)
106  {
107    $to_remove_cat_ids = array_diff($existing_cat_ids, $cat_ids);
108    if (count($to_remove_cat_ids) > 0)
109    {
110      $query = '
111DELETE
112  FROM '.IMAGE_CATEGORY_TABLE.'
113  WHERE image_id = '.$image_id.'
114    AND category_id IN ('.implode(', ', $to_remove_cat_ids).')
115;';
116      pwg_query($query);
117      update_category($to_remove_cat_ids);
118    }
119  }
120
121  $new_cat_ids = array_diff($cat_ids, $existing_cat_ids);
122  if (count($new_cat_ids) == 0)
123  {
124    return true;
125  }
126
127  if ($search_current_ranks)
128  {
129    $query = '
130SELECT category_id, MAX(rank) AS max_rank
131  FROM '.IMAGE_CATEGORY_TABLE.'
132  WHERE rank IS NOT NULL
133    AND category_id IN ('.implode(',', $new_cat_ids).')
134  GROUP BY category_id
135;';
136    $current_rank_of = simple_hash_from_query(
137      $query,
138      'category_id',
139      'max_rank'
140      );
141
142    foreach ($new_cat_ids as $cat_id)
143    {
144      if (!isset($current_rank_of[$cat_id]))
145      {
146        $current_rank_of[$cat_id] = 0;
147      }
148
149      if ('auto' == $rank_on_category[$cat_id])
150      {
151        $rank_on_category[$cat_id] = $current_rank_of[$cat_id] + 1;
152      }
153    }
154  }
155
156  $inserts = array();
157
158  foreach ($new_cat_ids as $cat_id)
159  {
160    $inserts[] = array(
161      'image_id' => $image_id,
162      'category_id' => $cat_id,
163      'rank' => $rank_on_category[$cat_id],
164      );
165  }
166
167  mass_inserts(
168    IMAGE_CATEGORY_TABLE,
169    array_keys($inserts[0]),
170    $inserts
171    );
172
173  include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
174  update_category($new_cat_ids);
175}
176
177/**
178 * Merge chunks added by pwg.images.addChunk
179 * @param string $output_filepath
180 * @param string $original_sum
181 * @param string $type
182 */
183function merge_chunks($output_filepath, $original_sum, $type)
184{
185  global $conf;
186
187  ws_logfile('[merge_chunks] input parameter $output_filepath : '.$output_filepath);
188
189  if (is_file($output_filepath))
190  {
191    unlink($output_filepath);
192
193    if (is_file($output_filepath))
194    {
195      return new PwgError(500, '[merge_chunks] error while trying to remove existing '.$output_filepath);
196    }
197  }
198
199  $upload_dir = $conf['upload_dir'].'/buffer';
200  $pattern = '/'.$original_sum.'-'.$type.'/';
201  $chunks = array();
202
203  if ($handle = opendir($upload_dir))
204  {
205    while (false !== ($file = readdir($handle)))
206    {
207      if (preg_match($pattern, $file))
208      {
209        ws_logfile($file);
210        $chunks[] = $upload_dir.'/'.$file;
211      }
212    }
213    closedir($handle);
214  }
215
216  sort($chunks);
217
218  if (function_exists('memory_get_usage')) {
219    ws_logfile('[merge_chunks] memory_get_usage before loading chunks: '.memory_get_usage());
220  }
221
222  $i = 0;
223
224  foreach ($chunks as $chunk)
225  {
226    $string = file_get_contents($chunk);
227
228    if (function_exists('memory_get_usage')) {
229      ws_logfile('[merge_chunks] memory_get_usage on chunk '.++$i.': '.memory_get_usage());
230    }
231
232    if (!file_put_contents($output_filepath, $string, FILE_APPEND))
233    {
234      return new PwgError(500, '[merge_chunks] error while writting chunks for '.$output_filepath);
235    }
236
237    unlink($chunk);
238  }
239
240  if (function_exists('memory_get_usage')) {
241    ws_logfile('[merge_chunks] memory_get_usage after loading chunks: '.memory_get_usage());
242  }
243}
244
245/**
246 * Deletes chunks added with pwg.images.addChunk
247 * @param string $original_sum
248 * @param string $type
249 *
250 * Function introduced for Piwigo 2.4 and the new "multiple size"
251 * (derivatives) feature. As we only need the biggest sent photo as
252 * "original", we remove chunks for smaller sizes. We can't make it earlier
253 * in ws_images_add_chunk because at this moment we don't know which $type
254 * will be the biggest (we could remove the thumb, but let's use the same
255 * algorithm)
256 */
257function remove_chunks($original_sum, $type)
258{
259  global $conf;
260
261  $upload_dir = $conf['upload_dir'].'/buffer';
262  $pattern = '/'.$original_sum.'-'.$type.'/';
263  $chunks = array();
264
265  if ($handle = opendir($upload_dir))
266  {
267    while (false !== ($file = readdir($handle)))
268    {
269      if (preg_match($pattern, $file))
270      {
271        $chunks[] = $upload_dir.'/'.$file;
272      }
273    }
274    closedir($handle);
275  }
276
277  foreach ($chunks as $chunk)
278  {
279    unlink($chunk);
280  }
281}
282
283
284// +-----------------------------------------------------------------------+
285// | METHODS                                                               |
286// +-----------------------------------------------------------------------+
287
288/**
289 * API method
290 * Adds a comment to an image
291 * @param mixed[] $params
292 *    @option int image_id
293 *    @option string author
294 *    @option string content
295 *    @option string key
296 */
297function ws_images_addComment($params, $service)
298{
299  $query = '
300SELECT DISTINCT image_id
301  FROM '. IMAGE_CATEGORY_TABLE .'
302      INNER JOIN '.CATEGORIES_TABLE.' ON category_id=id
303  WHERE commentable="true"
304    AND image_id='.$params['image_id'].
305    get_sql_condition_FandF(
306      array(
307        'forbidden_categories' => 'id',
308        'visible_categories' => 'id',
309        'visible_images' => 'image_id'
310        ),
311      ' AND'
312      ).'
313;';
314
315  if (!pwg_db_num_rows(pwg_query($query)))
316  {
317    return new PwgError(WS_ERR_INVALID_PARAM, 'Invalid image_id');
318  }
319
320  $comm = array(
321    'author' => trim($params['author']),
322    'content' => trim($params['content']),
323    'image_id' => $params['image_id'],
324   );
325
326  include_once(PHPWG_ROOT_PATH.'include/functions_comment.inc.php');
327
328  $comment_action = insert_user_comment($comm, $params['key'], $infos);
329
330  switch ($comment_action)
331  {
332    case 'reject':
333      $infos[] = l10n('Your comment has NOT been registered because it did not pass the validation rules');
334      return new PwgError(403, implode("; ", $infos) );
335
336    case 'validate':
337    case 'moderate':
338      $ret = array(
339        'id' => $comm['id'],
340        'validation' => $comment_action=='validate',
341        );
342      return array('comment' => new PwgNamedStruct($ret));
343
344    default:
345      return new PwgError(500, "Unknown comment action ".$comment_action );
346  }
347}
348
349/**
350 * API method
351 * Returns detailed information for an element
352 * @param mixed[] $params
353 *    @option int image_id
354 *    @option int comments_page
355 *    @option int comments_per_page
356 */
357function ws_images_getInfo($params, $service)
358{
359  global $user, $conf;
360
361  $query='
362SELECT *
363  FROM '. IMAGES_TABLE .'
364  WHERE id='. $params['image_id'] .
365    get_sql_condition_FandF(
366      array('visible_images' => 'id'),
367      ' AND'
368      ).'
369LIMIT 1
370;';
371  $result = pwg_query($query);
372
373  if (pwg_db_num_rows($result) == 0)
374  {
375    return new PwgError(404, 'image_id not found');
376  }
377
378  $image_row = pwg_db_fetch_assoc($result);
379  $image_row = array_merge($image_row, ws_std_get_urls($image_row));
380
381  //-------------------------------------------------------- related categories
382  $query = '
383SELECT id, name, permalink, uppercats, global_rank, commentable
384  FROM '. IMAGE_CATEGORY_TABLE .'
385    INNER JOIN '. CATEGORIES_TABLE .' ON category_id = id
386  WHERE image_id = '. $image_row['id'] .
387    get_sql_condition_FandF(
388      array('forbidden_categories' => 'category_id'),
389      ' AND'
390      ).'
391;';
392  $result = pwg_query($query);
393
394  $is_commentable = false;
395  $related_categories = array();
396  while ($row = pwg_db_fetch_assoc($result))
397  {
398    if ($row['commentable']=='true')
399    {
400      $is_commentable = true;
401    }
402    unset($row['commentable']);
403
404    $row['url'] = make_index_url(
405      array(
406        'category' => $row
407        )
408      );
409
410    $row['page_url'] = make_picture_url(
411      array(
412        'image_id' => $image_row['id'],
413        'image_file' => $image_row['file'],
414        'category' => $row
415        )
416      );
417
418    $row['id']=(int)$row['id'];
419    $related_categories[] = $row;
420  }
421  usort($related_categories, 'global_rank_compare');
422
423  if (empty($related_categories))
424  {
425    return new PwgError(401, 'Access denied');
426  }
427
428  //-------------------------------------------------------------- related tags
429  $related_tags = get_common_tags(array($image_row['id']), -1);
430  foreach ($related_tags as $i=>$tag)
431  {
432    $tag['url'] = make_index_url(
433      array(
434        'tags' => array($tag)
435        )
436      );
437    $tag['page_url'] = make_picture_url(
438      array(
439        'image_id' => $image_row['id'],
440        'image_file' => $image_row['file'],
441        'tags' => array($tag),
442        )
443      );
444
445    unset($tag['counter']);
446    $tag['id'] = (int)$tag['id'];
447    $related_tags[$i] = $tag;
448  }
449
450  //------------------------------------------------------------- related rates
451        $rating = array(
452    'score' => $image_row['rating_score'],
453    'count' => 0,
454    'average' => null,
455    );
456        if (isset($rating['score']))
457        {
458                $query = '
459SELECT COUNT(rate) AS count, ROUND(AVG(rate),2) AS average
460  FROM '. RATE_TABLE .'
461  WHERE element_id = '. $image_row['id'] .'
462;';
463                $row = pwg_db_fetch_assoc(pwg_query($query));
464
465                $rating['score'] = (float)$rating['score'];
466                $rating['average'] = (float)$row['average'];
467                $rating['count'] = (int)$row['count'];
468        }
469
470  //---------------------------------------------------------- related comments
471  $related_comments = array();
472
473  $where_comments = 'image_id = '.$image_row['id'];
474  if (!is_admin())
475  {
476    $where_comments .= ' AND validated="true"';
477  }
478
479  $query = '
480SELECT COUNT(id) AS nb_comments
481  FROM '. COMMENTS_TABLE .'
482  WHERE '. $where_comments .'
483;';
484  list($nb_comments) = array_from_query($query, 'nb_comments');
485  $nb_comments = (int)$nb_comments;
486
487  if ($nb_comments>0 and $params['comments_per_page']>0)
488  {
489    $query = '
490SELECT id, date, author, content
491  FROM '. COMMENTS_TABLE .'
492  WHERE '. $where_comments .'
493  ORDER BY date
494  LIMIT '. (int)$params['comments_per_page'] .'
495  OFFSET '. (int)($params['comments_per_page']*$params['comments_page']) .'
496;';
497    $result = pwg_query($query);
498
499    while ($row = pwg_db_fetch_assoc($result))
500    {
501      $row['id'] = (int)$row['id'];
502      $related_comments[] = $row;
503    }
504  }
505
506  $comment_post_data = null;
507  if ($is_commentable and
508      (!is_a_guest()
509        or (is_a_guest() and $conf['comments_forall'] )
510      )
511    )
512  {
513    $comment_post_data['author'] = stripslashes($user['username']);
514    $comment_post_data['key'] = get_ephemeral_key(2, $params['image_id']);
515  }
516
517  $ret = $image_row;
518  foreach (array('id','width','height','hit','filesize') as $k)
519  {
520    if (isset($ret[$k]))
521    {
522      $ret[$k] = (int)$ret[$k];
523    }
524  }
525  foreach (array('path', 'storage_category_id') as $k)
526  {
527    unset($ret[$k]);
528  }
529
530  $ret['rates'] = array(
531    WS_XML_ATTRIBUTES => $rating
532    );
533  $ret['categories'] = new PwgNamedArray(
534    $related_categories,
535    'category',
536    array('id','url', 'page_url')
537    );
538  $ret['tags'] = new PwgNamedArray(
539    $related_tags,
540    'tag',
541    ws_std_get_tag_xml_attributes()
542    );
543  if (isset($comment_post_data))
544  {
545    $ret['comment_post'] = array(
546      WS_XML_ATTRIBUTES => $comment_post_data
547      );
548  }
549  $ret['comments_paging'] = new PwgNamedStruct(
550    array(
551      'page' => $params['comments_page'],
552      'per_page' => $params['comments_per_page'],
553      'count' => count($related_comments),
554      'total_count' => $nb_comments,
555      )
556    );
557  $ret['comments'] = new PwgNamedArray(
558    $related_comments,
559    'comment',
560    array('id','date')
561    );
562
563  if ($service->_responseFormat != 'rest')
564  {
565    return $ret; // for backward compatibility only
566  }
567  else
568  {
569    return array(
570      'image' => new PwgNamedStruct($ret, null, array('name','comment'))
571      );
572  }
573}
574
575/**
576 * API method
577 * Rates an image
578 * @param mixed[] $params
579 *    @option int image_id
580 *    @option float rate
581 */
582function ws_images_rate($params, $service)
583{
584  $query = '
585SELECT DISTINCT id
586  FROM '. IMAGES_TABLE .'
587    INNER JOIN '. IMAGE_CATEGORY_TABLE .' ON id=image_id
588  WHERE id='. $params['image_id']
589    .get_sql_condition_FandF(
590      array(
591        'forbidden_categories' => 'category_id',
592        'forbidden_images' => 'id',
593        ),
594      '    AND'
595      ).'
596  LIMIT 1
597;';
598  if (pwg_db_num_rows(pwg_query($query))==0)
599  {
600    return new PwgError(404, 'Invalid image_id or access denied');
601  }
602
603  include_once(PHPWG_ROOT_PATH.'include/functions_rate.inc.php');
604  $res = rate_picture($params['image_id'], (int)$params['rate']);
605
606  if ($res==false)
607  {
608    global $conf;
609    return new PwgError(403, 'Forbidden or rate not in '. implode(',', $conf['rate_items']));
610  }
611  return $res;
612}
613
614/**
615 * API method
616 * Returns a list of elements corresponding to a query search
617 * @param mixed[] $params
618 *    @option string query
619 *    @option int per_page
620 *    @option int page
621 *    @option string order (optional)
622 */
623function ws_images_search($params, $service)
624{
625  include_once(PHPWG_ROOT_PATH .'include/functions_search.inc.php');
626
627  $images = array();
628  $where_clauses = ws_std_image_sql_filter($params, 'i.');
629  $order_by = ws_std_image_sql_order($params, 'i.');
630
631  $super_order_by = false;
632  if (!empty($order_by))
633  {
634    global $conf;
635    $conf['order_by'] = 'ORDER BY '.$order_by;
636    $super_order_by = true; // quick_search_result might be faster
637  }
638
639  $search_result = get_quick_search_results(
640    $params['query'],
641    array(
642      'super_order_by' => $super_order_by,
643      'images_where' => implode(' AND ', $where_clauses)
644    )
645    );
646
647  $image_ids = array_slice(
648    $search_result['items'],
649    $params['page']*$params['per_page'],
650    $params['per_page']
651    );
652
653  if (count($image_ids))
654  {
655    $query = '
656SELECT *
657  FROM '. IMAGES_TABLE .'
658  WHERE id IN ('. implode(',', $image_ids) .')
659;';
660    $result = pwg_query($query);
661    $image_ids = array_flip($image_ids);
662
663    while ($row = pwg_db_fetch_assoc($result))
664    {
665      $image = array();
666      foreach (array('id', 'width', 'height', 'hit') as $k)
667      {
668        if (isset($row[$k]))
669        {
670          $image[$k] = (int)$row[$k];
671        }
672      }
673      foreach (array('file', 'name', 'comment', 'date_creation', 'date_available') as $k)
674      {
675        $image[$k] = $row[$k];
676      }
677
678      $image = array_merge($image, ws_std_get_urls($row));
679      $images[ $image_ids[ $image['id'] ] ] = $image;
680    }
681    ksort($images, SORT_NUMERIC);
682    $images = array_values($images);
683  }
684
685  return array (
686    'paging' => new PwgNamedStruct(
687      array(
688        'page' => $params['page'],
689        'per_page' => $params['per_page'],
690        'count' => count($images),
691        'total_count' => count($search_result['items']),
692        )
693      ),
694    'images' => new PwgNamedArray(
695      $images,
696      'image',
697      ws_std_get_image_xml_attributes()
698      )
699    );
700}
701
702/**
703 * API method
704 * Sets the level of an image
705 * @param mixed[] $params
706 *    @option int image_id
707 *    @option int level
708 */
709function ws_images_setPrivacyLevel($params, $service)
710{
711  global $conf;
712
713  if (!in_array($params['level'], $conf['available_permission_levels']))
714  {
715    return new PwgError(WS_ERR_INVALID_PARAM, 'Invalid level');
716  }
717
718  $query = '
719UPDATE '. IMAGES_TABLE .'
720  SET level='. (int)$params['level'] .'
721  WHERE id IN ('. implode(',',$params['image_id']) .')
722;';
723  $result = pwg_query($query);
724
725  $affected_rows = pwg_db_changes($result);
726  if ($affected_rows)
727  {
728    include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
729    invalidate_user_cache();
730  }
731  return $affected_rows;
732}
733
734/**
735 * API method
736 * Sets the rank of an image in a category
737 * @param mixed[] $params
738 *    @option int image_id
739 *    @option int category_id
740 *    @option int rank
741 */
742function ws_images_setRank($params, $service)
743{
744  // does the image really exist?
745  $query = '
746SELECT COUNT(*)
747  FROM '. IMAGES_TABLE .'
748  WHERE id = '. $params['image_id'] .'
749;';
750  list($count) = pwg_db_fetch_row(pwg_query($query));
751  if ($count == 0)
752  {
753    return new PwgError(404, 'image_id not found');
754  }
755
756  // is the image associated to this category?
757  $query = '
758SELECT COUNT(*)
759  FROM '. IMAGE_CATEGORY_TABLE .'
760  WHERE image_id = '. $params['image_id'] .'
761    AND category_id = '. $params['category_id'] .'
762;';
763  list($count) = pwg_db_fetch_row(pwg_query($query));
764  if ($count == 0)
765  {
766    return new PwgError(404, 'This image is not associated to this category');
767  }
768
769  // what is the current higher rank for this category?
770  $query = '
771SELECT MAX(rank) AS max_rank
772  FROM '. IMAGE_CATEGORY_TABLE .'
773  WHERE category_id = '. $params['category_id'] .'
774;';
775  $row = pwg_db_fetch_assoc(pwg_query($query));
776
777  if (is_numeric($row['max_rank']))
778  {
779    if ($params['rank'] > $row['max_rank'])
780    {
781      $params['rank'] = $row['max_rank'] + 1;
782    }
783  }
784  else
785  {
786    $params['rank'] = 1;
787  }
788
789  // update rank for all other photos in the same category
790  $query = '
791UPDATE '. IMAGE_CATEGORY_TABLE .'
792  SET rank = rank + 1
793  WHERE category_id = '. $params['category_id'] .'
794    AND rank IS NOT NULL
795    AND rank >= '. $params['rank'] .'
796;';
797  pwg_query($query);
798
799  // set the new rank for the photo
800  $query = '
801UPDATE '. IMAGE_CATEGORY_TABLE .'
802  SET rank = '. $params['rank'] .'
803  WHERE image_id = '. $params['image_id'] .'
804    AND category_id = '. $params['category_id'] .'
805;';
806  pwg_query($query);
807
808  // return data for client
809  return array(
810    'image_id' => $params['image_id'],
811    'category_id' => $params['category_id'],
812    'rank' => $params['rank'],
813    );
814}
815
816/**
817 * API method
818 * Adds a file chunk
819 * @param mixed[] $params
820 *    @option string data
821 *    @option string original_sum
822 *    @option string type = 'file'
823 *    @option int position
824 */
825function ws_images_add_chunk($params, $service)
826{
827  global $conf;
828
829  foreach ($params as $param_key => $param_value)
830  {
831    if ('data' == $param_key)
832    {
833      continue;
834    }
835    ws_logfile(
836      sprintf(
837        '[ws_images_add_chunk] input param "%s" : "%s"',
838        $param_key,
839        is_null($param_value) ? 'NULL' : $param_value
840        )
841      );
842  }
843
844  $upload_dir = $conf['upload_dir'].'/buffer';
845
846  // create the upload directory tree if not exists
847  if (!mkgetdir($upload_dir, MKGETDIR_DEFAULT&~MKGETDIR_DIE_ON_ERROR))
848  {
849    return new PwgError(500, 'error during buffer directory creation');
850  }
851
852  $filename = sprintf(
853    '%s-%s-%05u.block',
854    $params['original_sum'],
855    $params['type'],
856    $params['position']
857    );
858
859  ws_logfile('[ws_images_add_chunk] data length : '.strlen($params['data']));
860
861  $bytes_written = file_put_contents(
862    $upload_dir.'/'.$filename,
863    base64_decode($params['data'])
864    );
865
866  if (false === $bytes_written)
867  {
868    return new PwgError(500,
869      'an error has occured while writting chunk '.$params['position'].' for '.$params['type']
870      );
871  }
872}
873
874/**
875 * API method
876 * Adds a file
877 * @param mixed[] $params
878 *    @option int image_id
879 *    @option string type = 'file'
880 *    @option string sum
881 */
882function ws_images_addFile($params, $service)
883{
884  ws_logfile(__FUNCTION__.', input :  '.var_export($params, true));
885
886  global $conf;
887
888  // what is the path and other infos about the photo?
889  $query = '
890SELECT
891    path, file, md5sum,
892    width, height, filesize
893  FROM '. IMAGES_TABLE .'
894  WHERE id = '. $params['image_id'] .'
895;';
896  $result = pwg_query($query);
897
898  if (pwg_db_num_rows($result) == 0)
899  {
900    return new PwgError(404, "image_id not found");
901  }
902
903  $image = pwg_db_fetch_assoc($result);
904
905  // since Piwigo 2.4 and derivatives, we do not take the imported "thumb" into account
906  if ('thumb' == $params['type'])
907  {
908    remove_chunks($image['md5sum'], $type);
909    return true;
910  }
911
912  // since Piwigo 2.4 and derivatives, we only care about the "original"
913  $original_type = 'file';
914  if ('high' == $params['type'])
915  {
916    $original_type = 'high';
917  }
918
919  $file_path = $conf['upload_dir'].'/buffer/'.$image['md5sum'].'-original';
920
921  merge_chunks($file_path, $image['md5sum'], $original_type);
922  chmod($file_path, 0644);
923
924  include_once(PHPWG_ROOT_PATH.'admin/include/functions_upload.inc.php');
925
926  // if we receive the "file", we only update the original if the "file" is
927  // bigger than current original
928  if ('file' == $params['type'])
929  {
930    $do_update = false;
931
932    $infos = pwg_image_infos($file_path);
933
934    foreach (array('width', 'height', 'filesize') as $image_info)
935    {
936      if ($infos[$image_info] > $image[$image_info])
937      {
938        $do_update = true;
939      }
940    }
941
942    if (!$do_update)
943    {
944      unlink($file_path);
945      return true;
946    }
947  }
948
949  $image_id = add_uploaded_file(
950    $file_path,
951    $image['file'],
952    null,
953    null,
954    $params['image_id'],
955    $image['md5sum'] // we force the md5sum to remain the same
956    );
957}
958
959/**
960 * API method
961 * Adds an image
962 * @param mixed[] $params
963 *    @option string original_sum
964 *    @option string original_filename (optional)
965 *    @option string name (optional)
966 *    @option string author (optional)
967 *    @option string date_creation (optional)
968 *    @option string comment (optional)
969 *    @option string categories (optional) - "cat_id[,rank];cat_id[,rank]"
970 *    @option string tags_ids (optional) - "tag_id,tag_id"
971 *    @option int level
972 *    @option bool check_uniqueness
973 *    @option int image_id (optional)
974 */
975function ws_images_add($params, $service)
976{
977  global $conf, $user;
978
979  foreach ($params as $param_key => $param_value)
980  {
981    ws_logfile(
982      sprintf(
983        '[pwg.images.add] input param "%s" : "%s"',
984        $param_key,
985        is_null($param_value) ? 'NULL' : $param_value
986        )
987      );
988  }
989
990  if ($params['image_id'] > 0)
991  {
992    $query = '
993SELECT COUNT(*)
994  FROM '. IMAGES_TABLE .'
995  WHERE id = '. $params['image_id'] .'
996;';
997    list($count) = pwg_db_fetch_row(pwg_query($query));
998    if ($count == 0)
999    {
1000      return new PwgError(404, 'image_id not found');
1001    }
1002  }
1003
1004  // does the image already exists ?
1005  if ($params['check_uniqueness'])
1006  {
1007    if ('md5sum' == $conf['uniqueness_mode'])
1008    {
1009      $where_clause = "md5sum = '".$params['original_sum']."'";
1010    }
1011    if ('filename' == $conf['uniqueness_mode'])
1012    {
1013      $where_clause = "file = '".$params['original_filename']."'";
1014    }
1015
1016    $query = '
1017SELECT COUNT(*)
1018  FROM '. IMAGES_TABLE .'
1019  WHERE '. $where_clause .'
1020;';
1021    list($counter) = pwg_db_fetch_row(pwg_query($query));
1022    if ($counter != 0)
1023    {
1024      return new PwgError(500, 'file already exists');
1025    }
1026  }
1027
1028  // due to the new feature "derivatives" (multiple sizes) introduced for
1029  // Piwigo 2.4, we only take the biggest photos sent on
1030  // pwg.images.addChunk. If "high" is available we use it as "original"
1031  // else we use "file".
1032  remove_chunks($params['original_sum'], 'thumb');
1033
1034  if (isset($params['high_sum']))
1035  {
1036    $original_type = 'high';
1037    remove_chunks($params['original_sum'], 'file');
1038  }
1039  else
1040  {
1041    $original_type = 'file';
1042  }
1043
1044  $file_path = $conf['upload_dir'].'/buffer/'.$params['original_sum'].'-original';
1045
1046  merge_chunks($file_path, $params['original_sum'], $original_type);
1047  chmod($file_path, 0644);
1048
1049  include_once(PHPWG_ROOT_PATH.'admin/include/functions_upload.inc.php');
1050
1051  $image_id = add_uploaded_file(
1052    $file_path,
1053    $params['original_filename'],
1054    null, // categories
1055    isset($params['level']) ? $params['level'] : null,
1056    $params['image_id'] > 0 ? $params['image_id'] : null,
1057    $params['original_sum']
1058    );
1059
1060  $info_columns = array(
1061    'name',
1062    'author',
1063    'comment',
1064    'date_creation',
1065    );
1066
1067  $update = array();
1068  foreach ($info_columns as $key)
1069  {
1070    if (isset($params[$key]))
1071    {
1072      $update[$key] = $params[$key];
1073    }
1074  }
1075
1076  if (count(array_keys($update)) > 0)
1077  {
1078    single_update(
1079      IMAGES_TABLE,
1080      $update,
1081      array('id' => $image_id)
1082      );
1083  }
1084
1085  $url_params = array('image_id' => $image_id);
1086
1087  // let's add links between the image and the categories
1088  if (isset($params['categories']))
1089  {
1090    ws_add_image_category_relations($image_id, $params['categories']);
1091
1092    if (preg_match('/^\d+/', $params['categories'], $matches))
1093    {
1094      $category_id = $matches[0];
1095
1096      $query = '
1097SELECT id, name, permalink
1098  FROM '. CATEGORIES_TABLE .'
1099  WHERE id = '. $category_id .'
1100;';
1101      $result = pwg_query($query);
1102      $category = pwg_db_fetch_assoc($result);
1103
1104      $url_params['section'] = 'categories';
1105      $url_params['category'] = $category;
1106    }
1107  }
1108
1109  // and now, let's create tag associations
1110  if (isset($params['tag_ids']) and !empty($params['tag_ids']))
1111  {
1112    set_tags(
1113      explode(',', $params['tag_ids']),
1114      $image_id
1115      );
1116  }
1117
1118  invalidate_user_cache();
1119
1120  return array(
1121    'image_id' => $image_id,
1122    'url' => make_picture_url($url_params),
1123    );
1124}
1125
1126/**
1127 * API method
1128 * Adds a image (simple way)
1129 * @param mixed[] $params
1130 *    @option int[] category
1131 *    @option string name (optional)
1132 *    @option string author (optional)
1133 *    @option string comment (optional)
1134 *    @option int level
1135 *    @option string|string[] tags
1136 *    @option int image_id (optional)
1137 */
1138function ws_images_addSimple($params, $service)
1139{
1140  global $conf;
1141
1142  if (!isset($_FILES['image']))
1143  {
1144    return new PwgError(405, 'The image (file) is missing');
1145  }
1146
1147  if ($params['image_id'] > 0)
1148  {
1149    $query='
1150SELECT COUNT(*)
1151  FROM '. IMAGES_TABLE .'
1152  WHERE id = '. $params['image_id'] .'
1153;';
1154    list($count) = pwg_db_fetch_row(pwg_query($query));
1155    if ($count == 0)
1156    {
1157      return new PwgError(404, 'image_id not found');
1158    }
1159  }
1160
1161  include_once(PHPWG_ROOT_PATH.'admin/include/functions_upload.inc.php');
1162
1163  $image_id = add_uploaded_file(
1164    $_FILES['image']['tmp_name'],
1165    $_FILES['image']['name'],
1166    $params['category'],
1167    8,
1168    $params['image_id'] > 0 ? $params['image_id'] : null
1169    );
1170
1171  $info_columns = array(
1172    'name',
1173    'author',
1174    'comment',
1175    'level',
1176    'date_creation',
1177    );
1178
1179  $update = array();
1180  foreach ($info_columns as $key)
1181  {
1182    if (isset($params[$key]))
1183    {
1184      $update[$key] = $params[$key];
1185    }
1186  }
1187
1188  single_update(
1189    IMAGES_TABLE,
1190    $update,
1191    array('id' => $image_id)
1192    );
1193
1194  if (isset($params['tags']) and !empty($params['tags']))
1195  {
1196    include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
1197
1198    $tag_ids = array();
1199    if (is_array($params['tags']))
1200    {
1201      foreach ($params['tags'] as $tag_name)
1202      {
1203        $tag_ids[] = tag_id_from_tag_name($tag_name);
1204      }
1205    }
1206    else
1207    {
1208      $tag_names = preg_split('~(?<!\\\),~', $params['tags']);
1209      foreach ($tag_names as $tag_name)
1210      {
1211        $tag_ids[] = tag_id_from_tag_name(preg_replace('#\\\\*,#', ',', $tag_name));
1212      }
1213    }
1214
1215    add_tags($tag_ids, array($image_id));
1216  }
1217
1218  $url_params = array('image_id' => $image_id);
1219
1220  if (!empty($params['category']))
1221  {
1222    $query = '
1223SELECT id, name, permalink
1224  FROM '. CATEGORIES_TABLE .'
1225  WHERE id = '. $params['category'][0] .'
1226;';
1227    $result = pwg_query($query);
1228    $category = pwg_db_fetch_assoc($result);
1229
1230    $url_params['section'] = 'categories';
1231    $url_params['category'] = $category;
1232  }
1233
1234  // update metadata from the uploaded file (exif/iptc), even if the sync
1235  // was already performed by add_uploaded_file().
1236  require_once(PHPWG_ROOT_PATH.'admin/include/functions_metadata.php');
1237  sync_metadata(array($image_id));
1238
1239  return array(
1240    'image_id' => $image_id,
1241    'url' => make_picture_url($url_params),
1242    );
1243}
1244
1245/**
1246 * API method
1247 * Adds a image (simple way)
1248 * @param mixed[] $params
1249 *    @option int[] category
1250 *    @option string name (optional)
1251 *    @option string author (optional)
1252 *    @option string comment (optional)
1253 *    @option int level
1254 *    @option string|string[] tags
1255 *    @option int image_id (optional)
1256 */
1257function ws_images_upload($params, $service)
1258{
1259  global $conf;
1260
1261  if (get_pwg_token() != $params['pwg_token'])
1262  {
1263    return new PwgError(403, 'Invalid security token');
1264  }
1265
1266  // usleep(100000);
1267
1268  // if (!isset($_FILES['image']))
1269  // {
1270  //   return new PwgError(405, 'The image (file) is missing');
1271  // }
1272 
1273  // file_put_contents('/tmp/plupload.log', "[".date('c')."] ".__FUNCTION__."\n\n", FILE_APPEND);
1274  // file_put_contents('/tmp/plupload.log', '$_FILES = '.var_export($_FILES, true)."\n", FILE_APPEND);
1275  // file_put_contents('/tmp/plupload.log', '$_POST = '.var_export($_POST, true)."\n", FILE_APPEND);
1276
1277  $upload_dir = $conf['upload_dir'].'/buffer';
1278
1279  // create the upload directory tree if not exists
1280  if (!mkgetdir($upload_dir, MKGETDIR_DEFAULT&~MKGETDIR_DIE_ON_ERROR))
1281  {
1282    return new PwgError(500, 'error during buffer directory creation');
1283  }
1284
1285  // Get a file name
1286  if (isset($_REQUEST["name"]))
1287  {
1288    $fileName = $_REQUEST["name"];
1289  }
1290  elseif (!empty($_FILES))
1291  {
1292    $fileName = $_FILES["file"]["name"];
1293  }
1294  else
1295  {
1296    $fileName = uniqid("file_");
1297  }
1298
1299  $filePath = $upload_dir.DIRECTORY_SEPARATOR.$fileName;
1300
1301  // Chunking might be enabled
1302  $chunk = isset($_REQUEST["chunk"]) ? intval($_REQUEST["chunk"]) : 0;
1303  $chunks = isset($_REQUEST["chunks"]) ? intval($_REQUEST["chunks"]) : 0;
1304
1305  // file_put_contents('/tmp/plupload.log', "[".date('c')."] ".__FUNCTION__.', '.$fileName.' '.($chunk+1).'/'.$chunks."\n", FILE_APPEND);
1306
1307  // Open temp file
1308  if (!$out = @fopen("{$filePath}.part", $chunks ? "ab" : "wb"))
1309  {
1310    die('{"jsonrpc" : "2.0", "error" : {"code": 102, "message": "Failed to open output stream."}, "id" : "id"}');
1311  }
1312
1313  if (!empty($_FILES))
1314  {
1315    if ($_FILES["file"]["error"] || !is_uploaded_file($_FILES["file"]["tmp_name"]))
1316    {
1317      die('{"jsonrpc" : "2.0", "error" : {"code": 103, "message": "Failed to move uploaded file."}, "id" : "id"}');
1318    }
1319
1320    // Read binary input stream and append it to temp file
1321    if (!$in = @fopen($_FILES["file"]["tmp_name"], "rb"))
1322    {
1323      die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "Failed to open input stream."}, "id" : "id"}');
1324    }
1325  }
1326  else
1327  {
1328    if (!$in = @fopen("php://input", "rb"))
1329    {
1330      die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "Failed to open input stream."}, "id" : "id"}');
1331    }
1332  }
1333
1334  while ($buff = fread($in, 4096))
1335  {
1336    fwrite($out, $buff);
1337  }
1338
1339  @fclose($out);
1340  @fclose($in);
1341
1342  // Check if file has been uploaded
1343  if (!$chunks || $chunk == $chunks - 1)
1344  {
1345    // Strip the temp .part suffix off
1346    rename("{$filePath}.part", $filePath);
1347 
1348    include_once(PHPWG_ROOT_PATH.'admin/include/functions_upload.inc.php');
1349   
1350    $image_id = add_uploaded_file(
1351      $filePath,
1352      $params['name'],
1353      $params['category'],
1354      $params['level'],
1355      null // image_id = not provided, this is a new photo
1356      );
1357   
1358    $query = '
1359SELECT
1360    id,
1361    name,
1362    path
1363  FROM '.IMAGES_TABLE.'
1364  WHERE id = '.$image_id.'
1365;';
1366    $image_infos = pwg_db_fetch_assoc(pwg_query($query));
1367
1368    $query = '
1369SELECT
1370    COUNT(*) AS nb_photos
1371  FROM '.IMAGE_CATEGORY_TABLE.'
1372  WHERE category_id = '.$params['category'][0].'
1373;';
1374    $category_infos = pwg_db_fetch_assoc(pwg_query($query));
1375
1376    $category_name = get_cat_display_name_from_id($params['category'][0], null);
1377   
1378    return array(
1379      'image_id' => $image_id,
1380      'src' => DerivativeImage::thumb_url($image_infos),
1381      'name' => $image_infos['name'],
1382      'category' => array(
1383        'id' => $params['category'][0],
1384        'nb_photos' => $category_infos['nb_photos'],
1385        'label' => $category_name,
1386        )
1387      );
1388  }
1389}
1390
1391/**
1392 * API method
1393 * Check if an image exists by it's name or md5 sum
1394 * @param mixed[] $params
1395 *    @option string md5sum_list (optional)
1396 *    @option string filename_list (optional)
1397 */
1398function ws_images_exist($params, $service)
1399{
1400  ws_logfile(__FUNCTION__.' '.var_export($params, true));
1401
1402  global $conf;
1403
1404  $split_pattern = '/[\s,;\|]/';
1405  $result = array();
1406
1407  if ('md5sum' == $conf['uniqueness_mode'])
1408  {
1409    // search among photos the list of photos already added, based on md5sum list
1410    $md5sums = preg_split(
1411      $split_pattern,
1412      $params['md5sum_list'],
1413      -1,
1414      PREG_SPLIT_NO_EMPTY
1415    );
1416
1417    $query = '
1418SELECT id, md5sum
1419  FROM '. IMAGES_TABLE .'
1420  WHERE md5sum IN (\''. implode("','", $md5sums) .'\')
1421;';
1422    $id_of_md5 = simple_hash_from_query($query, 'md5sum', 'id');
1423
1424    foreach ($md5sums as $md5sum)
1425    {
1426      $result[$md5sum] = null;
1427      if (isset($id_of_md5[$md5sum]))
1428      {
1429        $result[$md5sum] = $id_of_md5[$md5sum];
1430      }
1431    }
1432  }
1433  else if ('filename' == $conf['uniqueness_mode'])
1434  {
1435    // search among photos the list of photos already added, based on
1436    // filename list
1437    $filenames = preg_split(
1438      $split_pattern,
1439      $params['filename_list'],
1440      -1,
1441      PREG_SPLIT_NO_EMPTY
1442    );
1443
1444    $query = '
1445SELECT id, file
1446  FROM '.IMAGES_TABLE.'
1447  WHERE file IN (\''. implode("','", $filenames) .'\')
1448;';
1449    $id_of_filename = simple_hash_from_query($query, 'file', 'id');
1450
1451    foreach ($filenames as $filename)
1452    {
1453      $result[$filename] = null;
1454      if (isset($id_of_filename[$filename]))
1455      {
1456        $result[$filename] = $id_of_filename[$filename];
1457      }
1458    }
1459  }
1460
1461  return $result;
1462}
1463
1464/**
1465 * API method
1466 * Check is file has been update
1467 * @param mixed[] $params
1468 *    @option int image_id
1469 *    @option string file_sum
1470 */
1471function ws_images_checkFiles($params, $service)
1472{
1473  ws_logfile(__FUNCTION__.', input :  '.var_export($params, true));
1474
1475  $query = '
1476SELECT path
1477  FROM '. IMAGES_TABLE .'
1478  WHERE id = '. $params['image_id'] .'
1479;';
1480  $result = pwg_query($query);
1481
1482  if (pwg_db_num_rows($result) == 0)
1483  {
1484    return new PwgError(404, 'image_id not found');
1485  }
1486
1487  list($path) = pwg_db_fetch_row($result);
1488
1489  $ret = array();
1490
1491  if (isset($params['thumbnail_sum']))
1492  {
1493    // We always say the thumbnail is equal to create no reaction on the
1494    // other side. Since Piwigo 2.4 and derivatives, the thumbnails and web
1495    // sizes are always generated by Piwigo
1496    $ret['thumbnail'] = 'equals';
1497  }
1498
1499  if (isset($params['high_sum']))
1500  {
1501    $ret['file'] = 'equals';
1502    $compare_type = 'high';
1503  }
1504  else if (isset($params['file_sum']))
1505  {
1506    $compare_type = 'file';
1507  }
1508
1509  if (isset($compare_type))
1510  {
1511    ws_logfile(__FUNCTION__.', md5_file($path) = '.md5_file($path));
1512    if (md5_file($path) != $params[$compare_type.'_sum'])
1513    {
1514      $ret[$compare_type] = 'differs';
1515    }
1516    else
1517    {
1518      $ret[$compare_type] = 'equals';
1519    }
1520  }
1521
1522  ws_logfile(__FUNCTION__.', output :  '.var_export($ret, true));
1523
1524  return $ret;
1525}
1526
1527/**
1528 * API method
1529 * Sets details of an image
1530 * @param mixed[] $params
1531 *    @option int image_id
1532 *    @option string file (optional)
1533 *    @option string name (optional)
1534 *    @option string author (optional)
1535 *    @option string date_creation (optional)
1536 *    @option string comment (optional)
1537 *    @option string categories (optional) - "cat_id[,rank];cat_id[,rank]"
1538 *    @option string tags_ids (optional) - "tag_id,tag_id"
1539 *    @option int level (optional)
1540 *    @option string single_value_mode
1541 *    @option string multiple_value_mode
1542 */
1543function ws_images_setInfo($params, $service)
1544{
1545  include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
1546
1547  $query='
1548SELECT *
1549  FROM '. IMAGES_TABLE .'
1550  WHERE id = '. $params['image_id'] .'
1551;';
1552  $result = pwg_query($query);
1553
1554  if (pwg_db_num_rows($result) == 0)
1555  {
1556    return new PwgError(404, 'image_id not found');
1557  }
1558
1559  $image_row = pwg_db_fetch_assoc($result);
1560
1561  // database registration
1562  $update = array();
1563
1564  $info_columns = array(
1565    'name',
1566    'author',
1567    'comment',
1568    'level',
1569    'date_creation',
1570    );
1571
1572  foreach ($info_columns as $key)
1573  {
1574    if (isset($params[$key]))
1575    {
1576      if ('fill_if_empty' == $params['single_value_mode'])
1577      {
1578        if (empty($image_row[$key]))
1579        {
1580          $update[$key] = $params[$key];
1581        }
1582      }
1583      elseif ('replace' == $params['single_value_mode'])
1584      {
1585        $update[$key] = $params[$key];
1586      }
1587      else
1588      {
1589        return new PwgError(500,
1590          '[ws_images_setInfo]'
1591          .' invalid parameter single_value_mode "'.$params['single_value_mode'].'"'
1592          .', possible values are {fill_if_empty, replace}.'
1593          );
1594      }
1595    }
1596  }
1597
1598  if (isset($params['file']))
1599  {
1600    if (!empty($image_row['storage_category_id']))
1601    {
1602      return new PwgError(500,
1603        '[ws_images_setInfo] updating "file" is forbidden on photos added by synchronization'
1604        );
1605    }
1606
1607    $update['file'] = $params['file'];
1608  }
1609
1610  if (count(array_keys($update)) > 0)
1611  {
1612    $update['id'] = $params['image_id'];
1613
1614    single_update(
1615      IMAGES_TABLE,
1616      $update,
1617      array('id' => $update['id'])
1618      );
1619  }
1620
1621  if (isset($params['categories']))
1622  {
1623    ws_add_image_category_relations(
1624      $params['image_id'],
1625      $params['categories'],
1626      ('replace' == $params['multiple_value_mode'] ? true : false)
1627      );
1628  }
1629
1630  // and now, let's create tag associations
1631  if (isset($params['tag_ids']))
1632  {
1633    $tag_ids = array();
1634
1635    foreach (explode(',', $params['tag_ids']) as $candidate)
1636    {
1637      $candidate = trim($candidate);
1638
1639      if (preg_match(PATTERN_ID, $candidate))
1640      {
1641        $tag_ids[] = $candidate;
1642      }
1643    }
1644
1645    if ('replace' == $params['multiple_value_mode'])
1646    {
1647      set_tags(
1648        $tag_ids,
1649        $params['image_id']
1650        );
1651    }
1652    elseif ('append' == $params['multiple_value_mode'])
1653    {
1654      add_tags(
1655        $tag_ids,
1656        array($params['image_id'])
1657        );
1658    }
1659    else
1660    {
1661      return new PwgError(500,
1662        '[ws_images_setInfo]'
1663        .' invalid parameter multiple_value_mode "'.$params['multiple_value_mode'].'"'
1664        .', possible values are {replace, append}.'
1665        );
1666    }
1667  }
1668
1669  invalidate_user_cache();
1670}
1671
1672/**
1673 * API method
1674 * Deletes an image
1675 * @param mixed[] $params
1676 *    @option int|int[] image_id
1677 *    @option string pwg_token
1678 */
1679function ws_images_delete($params, $service)
1680{
1681  if (get_pwg_token() != $params['pwg_token'])
1682  {
1683    return new PwgError(403, 'Invalid security token');
1684  }
1685
1686  if (!is_array($params['image_id']))
1687  {
1688    $params['image_id'] = preg_split(
1689      '/[\s,;\|]/',
1690      $params['image_id'],
1691      -1,
1692      PREG_SPLIT_NO_EMPTY
1693      );
1694  }
1695  $params['image_id'] = array_map('intval', $params['image_id']);
1696
1697  $image_ids = array();
1698  foreach ($params['image_id'] as $image_id)
1699  {
1700    if ($image_id > 0)
1701    {
1702      $image_ids[] = $image_id;
1703    }
1704  }
1705
1706  include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
1707  delete_elements($image_ids, true);
1708  invalidate_user_cache();
1709}
1710
1711/**
1712 * API method
1713 * Checks if Piwigo is ready for upload
1714 * @param mixed[] $params
1715 */
1716function ws_images_checkUpload($params, $service)
1717{
1718  include_once(PHPWG_ROOT_PATH.'admin/include/functions_upload.inc.php');
1719
1720  $ret['message'] = ready_for_upload_message();
1721  $ret['ready_for_upload'] = true;
1722  if (!empty($ret['message']))
1723  {
1724    $ret['ready_for_upload'] = false;
1725  }
1726
1727  return $ret;
1728}
1729
1730?>
Note: See TracBrowser for help on using the repository browser.