source: trunk/include/ws_functions.inc.php @ 11962

Revision 11962, 76.5 KB checked in by plg, 8 years ago (diff)

feature 2406 added: if the user wants a new album in the upload form, the album
is created before the start of the upload. The ergonomy is now simpler, the
page is smaller and cleaner.

bug 2373 fixed: now that album is created before upload, uploadify.php gets the
category_id and the level: as soon as it is uploaded (function add_uploaded_file)
the photo gets its final privacy level and is directly associated to the album.
This way, we can have an error on a photo without making orphan all photos of
the same upload group.

feature 2405 added: as soon as a photo is uploaded, its thumbnail is displayed
in the "Uploaded Photos" fieldset, without waiting for other photos to be
uploaded. The latest photos comes first.

I have slighlty changed the integration of colorbox in core. Now we have 2
styles available and by default, we use style2 (overlay in black, title and
control icons outside the popup). It is also used for zooming on bulk manager
in unit mode.

display change: on each uploading photos, instead of showing the transfer
speed, we display the transfer progression in %

bug fixed: the color of the "Start Upload" button was not correct because the
button was not a submit button but a simple type=button.

language: "Upload" button becomes "Start Upload" button.

  • Property svn:eol-style set to LF
RevLine 
[1698]1<?php
2// +-----------------------------------------------------------------------+
[8728]3// | Piwigo - a PHP based photo gallery                                    |
[2297]4// +-----------------------------------------------------------------------+
[8728]5// | Copyright(C) 2008-2011 Piwigo Team                  http://piwigo.org |
[2297]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// +-----------------------------------------------------------------------+
[1698]23
24/**** IMPLEMENTATION OF WEB SERVICE METHODS ***********************************/
25
26/**
[1768]27 * Event handler for method invocation security check. Should return a PwgError
28 * if the preconditions are not satifsied for method invocation.
29 */
30function ws_isInvokeAllowed($res, $methodName, $params)
31{
[2572]32  global $conf;
[2119]33
[1849]34  if ( strpos($methodName,'reflection.')===0 )
35  { // OK for reflection
36    return $res;
37  }
[2119]38
[1849]39  if ( !is_autorize_status(ACCESS_GUEST) and
40      strpos($methodName,'pwg.session.')!==0 )
[1768]41  {
[1849]42    return new PwgError(401, 'Access denied');
43  }
[2119]44
[1768]45  return $res;
46}
47
48/**
[1698]49 * returns a "standard" (for our web service) array of sql where clauses that
[1711]50 * filters the images (images table only)
51 */
[1698]52function ws_std_image_sql_filter( $params, $tbl_name='' )
53{
54  $clauses = array();
55  if ( is_numeric($params['f_min_rate']) )
56  {
[11893]57    $clauses[] = $tbl_name.'rating_score>'.$params['f_min_rate'];
[1698]58  }
59  if ( is_numeric($params['f_max_rate']) )
60  {
[11893]61    $clauses[] = $tbl_name.'rating_score<='.$params['f_max_rate'];
[1698]62  }
63  if ( is_numeric($params['f_min_hit']) )
64  {
65    $clauses[] = $tbl_name.'hit>'.$params['f_min_hit'];
66  }
67  if ( is_numeric($params['f_max_hit']) )
68  {
69    $clauses[] = $tbl_name.'hit<='.$params['f_max_hit'];
70  }
[9576]71  if ( isset($params['f_min_date_available']) )
[1698]72  {
[9576]73    $clauses[] = $tbl_name."date_available>='".$params['f_min_date_available']."'";
[1698]74  }
[9576]75  if ( isset($params['f_max_date_available']) )
[1698]76  {
[9576]77    $clauses[] = $tbl_name."date_available<'".$params['f_max_date_available']."'";
[1698]78  }
79  if ( isset($params['f_min_date_created']) )
80  {
81    $clauses[] = $tbl_name."date_creation>='".$params['f_min_date_created']."'";
82  }
83  if ( isset($params['f_max_date_created']) )
84  {
85    $clauses[] = $tbl_name."date_creation<'".$params['f_max_date_created']."'";
86  }
87  if ( is_numeric($params['f_min_ratio']) )
88  {
89    $clauses[] = $tbl_name.'width/'.$tbl_name.'height>'.$params['f_min_ratio'];
90  }
91  if ( is_numeric($params['f_max_ratio']) )
92  {
93    $clauses[] = $tbl_name.'width/'.$tbl_name.'height<='.$params['f_max_ratio'];
94  }
95  if ( $params['f_with_thumbnail'] )
96  {
97    $clauses[] = $tbl_name.'tn_ext IS NOT NULL';
98  }
99  return $clauses;
100}
101
102/**
103 * returns a "standard" (for our web service) ORDER BY sql clause for images
[1711]104 */
[1698]105function ws_std_image_sql_order( $params, $tbl_name='' )
106{
107  $ret = '';
108  if ( empty($params['order']) )
109  {
110    return $ret;
111  }
112  $matches = array();
113  preg_match_all('/([a-z_]+) *(?:(asc|desc)(?:ending)?)? *(?:, *|$)/i',
114    $params['order'], $matches);
115  for ($i=0; $i<count($matches[1]); $i++)
116  {
117    switch ($matches[1][$i])
118    {
119      case 'date_created':
120        $matches[1][$i] = 'date_creation'; break;
121      case 'date_posted':
122        $matches[1][$i] = 'date_available'; break;
123      case 'rand': case 'random':
[4367]124        $matches[1][$i] = DB_RANDOM_FUNCTION.'()'; break;
[1698]125    }
[11893]126    $sortable_fields = array('id', 'file', 'name', 'hit', 'rating_score',
[4367]127      'date_creation', 'date_available', DB_RANDOM_FUNCTION.'()' );
[1698]128    if ( in_array($matches[1][$i], $sortable_fields) )
129    {
130      if (!empty($ret))
131        $ret .= ', ';
[4367]132      if ($matches[1][$i] != DB_RANDOM_FUNCTION.'()' )
[1698]133      {
134        $ret .= $tbl_name;
135      }
136      $ret .= $matches[1][$i];
137      $ret .= ' '.$matches[2][$i];
138    }
139  }
140  return $ret;
141}
142
143/**
144 * returns an array map of urls (thumb/element) for image_row - to be returned
145 * in a standard way by different web service methods
[1711]146 */
[1698]147function ws_std_get_urls($image_row)
148{
149  $ret = array(
[1711]150    'tn_url' => get_thumbnail_url($image_row),
[1698]151    'element_url' => get_element_url($image_row)
152  );
153  global $user;
154  if ($user['enabled_high'] and $image_row['has_high'] )
155  {
156    $ret['high_url'] = get_high_url($image_row);
157  }
158  return $ret;
159}
160
[1845]161/**
162 * returns an array of image attributes that are to be encoded as xml attributes
163 * instead of xml elements
164 */
165function ws_std_get_image_xml_attributes()
166{
167  return array(
[11116]168    'id','tn_url','element_url','high_url', 'file','width','height','hit','date_available','date_creation'
[1845]169    );
170}
[1698]171
[1781]172/**
173 * returns PWG version (web service method)
174 */
[1698]175function ws_getVersion($params, &$service)
176{
[1852]177  global $conf;
[9742]178  if ($conf['show_version'] or is_admin() )
[1852]179    return PHPWG_VERSION;
180  else
181    return new PwgError(403, 'Forbidden');
[1698]182}
183
[10017]184/**
185 * returns general informations (web service method)
186 */
187function ws_getInfos($params, &$service)
188{
[10061]189  if (!is_admin())
[10017]190  {
[10061]191    return new PwgError(403, 'Forbidden');
[10017]192  }
[10061]193
194  $infos['version'] = PHPWG_VERSION;
[11893]195
[10017]196  $query = 'SELECT COUNT(*) FROM '.IMAGES_TABLE.';';
197  list($infos['nb_elements']) = pwg_db_fetch_row(pwg_query($query));
198
199  $query = 'SELECT COUNT(*) FROM '.CATEGORIES_TABLE.';';
200  list($infos['nb_categories']) = pwg_db_fetch_row(pwg_query($query));
201
202  $query = 'SELECT COUNT(*) FROM '.CATEGORIES_TABLE.' WHERE dir IS NULL;';
203  list($infos['nb_virtual']) = pwg_db_fetch_row(pwg_query($query));
204
205  $query = 'SELECT COUNT(*) FROM '.CATEGORIES_TABLE.' WHERE dir IS NOT NULL;';
206  list($infos['nb_physical']) = pwg_db_fetch_row(pwg_query($query));
207
208  $query = 'SELECT COUNT(*) FROM '.IMAGE_CATEGORY_TABLE.';';
209  list($infos['nb_image_category']) = pwg_db_fetch_row(pwg_query($query));
210
211  $query = 'SELECT COUNT(*) FROM '.TAGS_TABLE.';';
212  list($infos['nb_tags']) = pwg_db_fetch_row(pwg_query($query));
213
214  $query = 'SELECT COUNT(*) FROM '.IMAGE_TAG_TABLE.';';
215  list($infos['nb_image_tag']) = pwg_db_fetch_row(pwg_query($query));
216
217  $query = 'SELECT COUNT(*) FROM '.USERS_TABLE.';';
218  list($infos['nb_users']) = pwg_db_fetch_row(pwg_query($query));
219
220  $query = 'SELECT COUNT(*) FROM '.GROUPS_TABLE.';';
221  list($infos['nb_groups']) = pwg_db_fetch_row(pwg_query($query));
222
223  $query = 'SELECT COUNT(*) FROM '.COMMENTS_TABLE.';';
224  list($infos['nb_comments']) = pwg_db_fetch_row(pwg_query($query));
225
226  // first element
227  if ($infos['nb_elements'] > 0)
228  {
229    $query = 'SELECT MIN(date_available) FROM '.IMAGES_TABLE.';';
230    list($infos['first_date']) = pwg_db_fetch_row(pwg_query($query));
231  }
232
233  // unvalidated comments
[10061]234  if ($infos['nb_comments'] > 0)
[10017]235  {
236    $query = 'SELECT COUNT(*) FROM '.COMMENTS_TABLE.' WHERE validated=\'false\';';
237    list($infos['nb_unvalidated_comments']) = pwg_db_fetch_row(pwg_query($query));
238  }
239
240  foreach ($infos as $name => $value)
241  {
242    $output[] = array(
243      'name' => $name,
244      'value' => $value,
245    );
246  }
247
248  return array('infos' => new PwgNamedArray($output, 'item'));
249}
250
[2429]251function ws_caddie_add($params, &$service)
252{
253  if (!is_admin())
254  {
255    return new PwgError(401, 'Access denied');
256  }
[2770]257  $params['image_id'] = array_map( 'intval',$params['image_id'] );
[2429]258  if ( empty($params['image_id']) )
259  {
260    return new PwgError(WS_ERR_INVALID_PARAM, "Invalid image_id");
261  }
262  global $user;
263  $query = '
264SELECT id
265  FROM '.IMAGES_TABLE.' LEFT JOIN '.CADDIE_TABLE.' ON id=element_id AND user_id='.$user['id'].'
266  WHERE id IN ('.implode(',',$params['image_id']).')
267    AND element_id IS NULL';
268  $datas = array();
269  foreach ( array_from_query($query, 'id') as $id )
270  {
271    array_push($datas, array('element_id'=>$id, 'user_id'=>$user['id']) );
272  }
273  if (count($datas))
274  {
275    include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
276    mass_inserts(CADDIE_TABLE, array('element_id','user_id'), $datas);
277  }
278  return count($datas);
279}
[1781]280
[1698]281/**
[1781]282 * returns images per category (web service method)
[1711]283 */
[1698]284function ws_categories_getImages($params, &$service)
285{
286  @include_once(PHPWG_ROOT_PATH.'include/functions_picture.inc.php');
287  global $user, $conf;
288
289  $images = array();
290
291  //------------------------------------------------- get the related categories
292  $where_clauses = array();
293  foreach($params['cat_id'] as $cat_id)
294  {
295    $cat_id = (int)$cat_id;
296    if ($cat_id<=0)
297      continue;
298    if ($params['recursive'])
299    {
[4367]300      $where_clauses[] = 'uppercats '.DB_REGEX_OPERATOR.' \'(^|,)'.$cat_id.'(,|$)\'';
[1698]301    }
302    else
303    {
304      $where_clauses[] = 'id='.$cat_id;
305    }
306  }
307  if (!empty($where_clauses))
308  {
309    $where_clauses = array( '('.
310    implode('
311    OR ', $where_clauses) . ')'
312      );
313  }
[2119]314  $where_clauses[] = get_sql_condition_FandF(
315        array('forbidden_categories' => 'id'),
316        NULL, true
317      );
[1698]318
319  $query = '
[1866]320SELECT id, name, permalink, image_order
[1698]321  FROM '.CATEGORIES_TABLE.'
322  WHERE '. implode('
323    AND ', $where_clauses);
324  $result = pwg_query($query);
325  $cats = array();
[4325]326  while ($row = pwg_db_fetch_assoc($result))
[1698]327  {
328    $row['id'] = (int)$row['id'];
329    $cats[ $row['id'] ] = $row;
330  }
331
332  //-------------------------------------------------------- get the images
333  if ( !empty($cats) )
334  {
335    $where_clauses = ws_std_image_sql_filter( $params, 'i.' );
336    $where_clauses[] = 'category_id IN ('
337      .implode(',', array_keys($cats) )
338      .')';
[1781]339    $where_clauses[] = get_sql_condition_FandF( array(
340          'visible_images' => 'i.id'
341        ), null, true
342      );
[1756]343
[1698]344    $order_by = ws_std_image_sql_order($params, 'i.');
[1852]345    if ( empty($order_by)
346          and count($params['cat_id'])==1
347          and isset($cats[ $params['cat_id'][0] ]['image_order'])
348        )
[1698]349    {
[1852]350      $order_by = $cats[ $params['cat_id'][0] ]['image_order'];
[1698]351    }
[1852]352    $order_by = empty($order_by) ? $conf['order_by'] : 'ORDER BY '.$order_by;
353
[1698]354    $query = '
[6652]355SELECT i.*, GROUP_CONCAT(category_id) AS cat_ids
[1698]356  FROM '.IMAGES_TABLE.' i
357    INNER JOIN '.IMAGE_CATEGORY_TABLE.' ON i.id=image_id
358  WHERE '. implode('
359    AND ', $where_clauses).'
360GROUP BY i.id
361'.$order_by.'
[4334]362LIMIT '.(int)$params['per_page'].' OFFSET '.(int)($params['per_page']*$params['page']);
[1698]363
364    $result = pwg_query($query);
[4325]365    while ($row = pwg_db_fetch_assoc($result))
[1698]366    {
367      $image = array();
368      foreach ( array('id', 'width', 'height', 'hit') as $k )
369      {
370        if (isset($row[$k]))
371        {
372          $image[$k] = (int)$row[$k];
373        }
374      }
[11116]375      foreach ( array('file', 'name', 'comment', 'date_creation', 'date_available') as $k )
[1698]376      {
377        $image[$k] = $row[$k];
378      }
379      $image = array_merge( $image, ws_std_get_urls($row) );
380
381      $image_cats = array();
382      foreach ( explode(',', $row['cat_ids']) as $cat_id )
383      {
384        $url = make_index_url(
385                array(
[1861]386                  'category' => $cats[$cat_id],
[1698]387                  )
388                );
389        $page_url = make_picture_url(
390                array(
[1861]391                  'category' => $cats[$cat_id],
[1698]392                  'image_id' => $row['id'],
393                  'image_file' => $row['file'],
394                  )
395                );
396        array_push( $image_cats,  array(
397              WS_XML_ATTRIBUTES => array (
398                  'id' => (int)$cat_id,
399                  'url' => $url,
400                  'page_url' => $page_url,
401                )
402            )
403          );
404      }
405
406      $image['categories'] = new PwgNamedArray(
407            $image_cats,'category', array('id','url','page_url')
408          );
409      array_push($images, $image);
410    }
411  }
412
413  return array( 'images' =>
414    array (
415      WS_XML_ATTRIBUTES =>
416        array(
417            'page' => $params['page'],
418            'per_page' => $params['per_page'],
419            'count' => count($images)
420          ),
[1711]421       WS_XML_CONTENT => new PwgNamedArray($images, 'image',
[1845]422          ws_std_get_image_xml_attributes() )
[1698]423      )
424    );
425}
426
[1781]427
[1698]428/**
[1781]429 * returns a list of categories (web service method)
[1698]430 */
431function ws_categories_getList($params, &$service)
432{
[1820]433  global $user,$conf;
[1698]434
[11155]435  if ($params['tree_output'])
436  {
437    if (!isset($_GET['format']) or !in_array($_GET['format'], array('php', 'json')))
438    {
439      // the algorithm used to build a tree from a flat list of categories
440      // keeps original array keys, which is not compatible with
441      // PwgNamedArray.
442      //
443      // PwgNamedArray is useful to define which data is an attribute and
444      // which is an element in the XML output. The "hierarchy" output is
445      // only compatible with json/php output.
[11893]446
[11155]447      return new PwgError(405, "The tree_output option is only compatible with json/php output formats");
448    }
449  }
450
[4884]451  $where = array('1=1');
452  $join_type = 'INNER';
453  $join_user = $user['id'];
[1698]454
455  if (!$params['recursive'])
456  {
457    if ($params['cat_id']>0)
[1820]458      $where[] = '(id_uppercat='.(int)($params['cat_id']).'
459    OR id='.(int)($params['cat_id']).')';
[1698]460    else
461      $where[] = 'id_uppercat IS NULL';
462  }
[1820]463  else if ($params['cat_id']>0)
464  {
[4367]465    $where[] = 'uppercats '.DB_REGEX_OPERATOR.' \'(^|,)'.
[1820]466      (int)($params['cat_id'])
467      .'(,|$)\'';
468  }
[1698]469
470  if ($params['public'])
471  {
472    $where[] = 'status = "public"';
[1711]473    $where[] = 'visible = "true"';
[11893]474
[4884]475    $join_user = $conf['guest_id'];
[1698]476  }
[4884]477  elseif (is_admin())
[1698]478  {
[4884]479    // in this very specific case, we don't want to hide empty
480    // categories. Function calculate_permissions will only return
481    // categories that are either locked or private and not permitted
[11893]482    //
[4884]483    // calculate_permissions does not consider empty categories as forbidden
484    $forbidden_categories = calculate_permissions($user['id'], $user['status']);
485    $where[]= 'id NOT IN ('.$forbidden_categories.')';
486    $join_type = 'LEFT';
[1698]487  }
488
[1711]489  $query = '
[11155]490SELECT id, name, permalink, uppercats, global_rank, id_uppercat,
[7550]491    comment,
[1845]492    nb_images, count_images AS total_nb_images,
493    date_last, max_date_last, count_categories AS nb_categories
[1711]494  FROM '.CATEGORIES_TABLE.'
[4884]495   '.$join_type.' JOIN '.USER_CACHE_CATEGORIES_TABLE.' ON id=cat_id AND user_id='.$join_user.'
[1698]496  WHERE '. implode('
497    AND ', $where);
498
499  $result = pwg_query($query);
500
501  $cats = array();
[4325]502  while ($row = pwg_db_fetch_assoc($result))
[1698]503  {
504    $row['url'] = make_index_url(
505        array(
[1861]506          'category' => $row
[1698]507          )
508      );
[1845]509    foreach( array('id','nb_images','total_nb_images','nb_categories') as $key)
[1698]510    {
511      $row[$key] = (int)$row[$key];
512    }
[2572]513
[11962]514    if ($params['fullname'])
515    {
516      $row['name'] = strip_tags(get_cat_display_name_cache($row['uppercats'], null, false));
517    }
518    else
519    {
520      $row['name'] = strip_tags(
521        trigger_event(
522          'render_category_name',
523          $row['name'],
524          'ws_categories_getList'
525          )
526        );
527    }
[11893]528
[7550]529    $row['comment'] = strip_tags(
530      trigger_event(
531        'render_category_description',
532        $row['comment'],
533        'ws_categories_getList'
534        )
535      );
[11893]536
[1698]537    array_push($cats, $row);
538  }
539  usort($cats, 'global_rank_compare');
[11155]540
541  if ($params['tree_output'])
[11893]542  {
[11155]543    return categories_flatlist_to_tree($cats);
544  }
545  else
546  {
547    return array(
548      'categories' => new PwgNamedArray(
549        $cats,
550        'category',
551        array(
552          'id',
553          'url',
554          'nb_images',
555          'total_nb_images',
556          'nb_categories',
557          'date_last',
558          'max_date_last',
559          )
[2548]560        )
[11155]561      );
562  }
[1698]563}
564
[2563]565/**
566 * returns the list of categories as you can see them in administration (web
567 * service method).
568 *
569 * Only admin can run this method and permissions are not taken into
570 * account.
571 */
572function ws_categories_getAdminList($params, &$service)
573{
574  if (!is_admin())
575  {
576    return new PwgError(401, 'Access denied');
577  }
[1781]578
[2563]579  $query = '
580SELECT
581    category_id,
582    COUNT(*) AS counter
583  FROM '.IMAGE_CATEGORY_TABLE.'
584  GROUP BY category_id
585;';
586  $nb_images_of = simple_hash_from_query($query, 'category_id', 'counter');
587
588  $query = '
589SELECT
590    id,
591    name,
[7550]592    comment,
[2563]593    uppercats,
594    global_rank
595  FROM '.CATEGORIES_TABLE.'
596;';
597  $result = pwg_query($query);
598  $cats = array();
599
[4325]600  while ($row = pwg_db_fetch_assoc($result))
[2563]601  {
602    $id = $row['id'];
603    $row['nb_images'] = isset($nb_images_of[$id]) ? $nb_images_of[$id] : 0;
[4903]604    $row['name'] = strip_tags(
605      trigger_event(
606        'render_category_name',
607        $row['name'],
608        'ws_categories_getAdminList'
609        )
610      );
[7550]611    $row['comment'] = strip_tags(
612      trigger_event(
613        'render_category_description',
614        $row['comment'],
615        'ws_categories_getAdminList'
616        )
617      );
[2563]618    array_push($cats, $row);
[2585]619  }
620
[2563]621  usort($cats, 'global_rank_compare');
622  return array(
623    'categories' => new PwgNamedArray(
624      $cats,
625      'category',
626      array(
627        'id',
628        'nb_images',
629        'name',
630        'uppercats',
631        'global_rank',
632        )
633      )
634    );
635}
636
[1781]637/**
638 * returns detailed information for an element (web service method)
639 */
[1849]640function ws_images_addComment($params, &$service)
641{
[1852]642  if (!$service->isPost())
643  {
644    return new PwgError(405, "This method requires HTTP POST");
645  }
[1849]646  $params['image_id'] = (int)$params['image_id'];
647  $query = '
[2119]648SELECT DISTINCT image_id
[1849]649  FROM '.IMAGE_CATEGORY_TABLE.' INNER JOIN '.CATEGORIES_TABLE.' ON category_id=id
[2119]650  WHERE commentable="true"
[1849]651    AND image_id='.$params['image_id'].
652    get_sql_condition_FandF(
653      array(
654        'forbidden_categories' => 'id',
655        'visible_categories' => 'id',
656        'visible_images' => 'image_id'
657      ),
658      ' AND'
659    );
[4325]660  if ( !pwg_db_num_rows( pwg_query( $query ) ) )
[1849]661  {
662    return new PwgError(WS_ERR_INVALID_PARAM, "Invalid image_id");
663  }
[2119]664
[1849]665  $comm = array(
[6437]666    'author' => trim( $params['author'] ),
667    'content' => trim( $params['content'] ),
[1849]668    'image_id' => $params['image_id'],
669   );
670
671  include_once(PHPWG_ROOT_PATH.'include/functions_comment.inc.php');
[2119]672
673  $comment_action = insert_user_comment(
[1849]674      $comm, $params['key'], $infos
675    );
676
677  switch ($comment_action)
678  {
679    case 'reject':
[5021]680      array_push($infos, l10n('Your comment has NOT been registered because it did not pass the validation rules') );
[7782]681      return new PwgError(403, implode("; ", $infos) );
[1849]682    case 'validate':
683    case 'moderate':
[2119]684      $ret = array(
[1849]685          'id' => $comm['id'],
686          'validation' => $comment_action=='validate',
687        );
688      return new PwgNamedStruct(
689          'comment',
[2119]690          $ret,
691          null, array()
[1849]692        );
693    default:
694      return new PwgError(500, "Unknown comment action ".$comment_action );
695  }
696}
697
698/**
699 * returns detailed information for an element (web service method)
700 */
[1698]701function ws_images_getInfo($params, &$service)
702{
703  @include_once(PHPWG_ROOT_PATH.'include/functions_picture.inc.php');
[1849]704  global $user, $conf;
[1698]705  $params['image_id'] = (int)$params['image_id'];
706  if ( $params['image_id']<=0 )
707  {
708    return new PwgError(WS_ERR_INVALID_PARAM, "Invalid image_id");
709  }
[1781]710
[1698]711  $query='
712SELECT * FROM '.IMAGES_TABLE.'
[1711]713  WHERE id='.$params['image_id'].
714    get_sql_condition_FandF(
715      array('visible_images' => 'id'),
716      ' AND'
[2516]717    ).'
718LIMIT 1';
[1711]719
[4325]720  $image_row = pwg_db_fetch_assoc(pwg_query($query));
[1698]721  if ($image_row==null)
722  {
[1852]723    return new PwgError(404, "image_id not found");
[1698]724  }
[1845]725  $image_row = array_merge( $image_row, ws_std_get_urls($image_row) );
[1698]726
727  //-------------------------------------------------------- related categories
728  $query = '
[1866]729SELECT id, name, permalink, uppercats, global_rank, commentable
[1698]730  FROM '.IMAGE_CATEGORY_TABLE.'
[1849]731    INNER JOIN '.CATEGORIES_TABLE.' ON category_id = id
[2119]732  WHERE image_id = '.$image_row['id'].
733  get_sql_condition_FandF(
734      array( 'forbidden_categories' => 'category_id' ),
735      ' AND'
736    ).'
[1698]737;';
738  $result = pwg_query($query);
[1849]739  $is_commentable = false;
[1698]740  $related_categories = array();
[4325]741  while ($row = pwg_db_fetch_assoc($result))
[1698]742  {
[1849]743    if ($row['commentable']=='true')
744    {
745      $is_commentable = true;
746    }
747    unset($row['commentable']);
[1698]748    $row['url'] = make_index_url(
749        array(
[1861]750          'category' => $row
[1698]751          )
752      );
753
754    $row['page_url'] = make_picture_url(
755        array(
756          'image_id' => $image_row['id'],
757          'image_file' => $image_row['file'],
[1861]758          'category' => $row
[1698]759          )
760      );
[1849]761    $row['id']=(int)$row['id'];
[1698]762    array_push($related_categories, $row);
763  }
764  usort($related_categories, 'global_rank_compare');
765  if ( empty($related_categories) )
766  {
767    return new PwgError(401, 'Access denied');
768  }
769
770  //-------------------------------------------------------------- related tags
[1815]771  $related_tags = get_common_tags( array($image_row['id']), -1 );
772  foreach( $related_tags as $i=>$tag)
[1698]773  {
[1815]774    $tag['url'] = make_index_url(
[1698]775        array(
[1815]776          'tags' => array($tag)
[1698]777          )
778      );
[1815]779    $tag['page_url'] = make_picture_url(
[1698]780        array(
781          'image_id' => $image_row['id'],
782          'image_file' => $image_row['file'],
[1815]783          'tags' => array($tag),
[1698]784          )
785      );
[1815]786    unset($tag['counter']);
[1849]787    $tag['id']=(int)$tag['id'];
[1815]788    $related_tags[$i]=$tag;
[1698]789  }
[1849]790  //------------------------------------------------------------- related rates
[11893]791        $rating = array('score'=>$image_row['rating_score'], 'count'=>0, 'average'=>null);
[11827]792        if (isset($rating['score']))
793        {
794                $query = '
[1849]795SELECT COUNT(rate) AS count
796     , ROUND(AVG(rate),2) AS average
797  FROM '.RATE_TABLE.'
798  WHERE element_id = '.$image_row['id'].'
799;';
[11827]800                $row = pwg_db_fetch_assoc(pwg_query($query));
801                $rating['score'] = (float)$rating['score'];
802                $rating['average'] = (float)$row['average'];
803                $rating['count'] = (int)$row['count'];
804        }
[1849]805
[1698]806  //---------------------------------------------------------- related comments
[1849]807  $related_comments = array();
[2119]808
[1849]809  $where_comments = 'image_id = '.$image_row['id'];
810  if ( !is_admin() )
811  {
812    $where_comments .= '
813    AND validated="true"';
814  }
815
[1698]816  $query = '
[6652]817SELECT COUNT(id) AS nb_comments
[1698]818  FROM '.COMMENTS_TABLE.'
[1849]819  WHERE '.$where_comments;
[1698]820  list($nb_comments) = array_from_query($query, 'nb_comments');
[1849]821  $nb_comments = (int)$nb_comments;
[1698]822
[1849]823  if ( $nb_comments>0 and $params['comments_per_page']>0 )
824  {
825    $query = '
[1698]826SELECT id, date, author, content
827  FROM '.COMMENTS_TABLE.'
[1849]828  WHERE '.$where_comments.'
829  ORDER BY date
[4334]830  LIMIT '.(int)$params['comments_per_page'].
831    ' OFFSET '.(int)($params['comments_per_page']*$params['comments_page']);
[1698]832
[1849]833    $result = pwg_query($query);
[4325]834    while ($row = pwg_db_fetch_assoc($result))
[1849]835    {
836      $row['id']=(int)$row['id'];
837      array_push($related_comments, $row);
838    }
839  }
[2119]840
[1849]841  $comment_post_data = null;
[2119]842  if ($is_commentable and
[2029]843      (!is_a_guest()
844        or (is_a_guest() and $conf['comments_forall'] )
[1849]845      )
846      )
[1698]847  {
[4304]848    $comment_post_data['author'] = stripslashes($user['username']);
[7495]849    $comment_post_data['key'] = get_ephemeral_key(2, $params['image_id']);
[1698]850  }
851
[1849]852  $ret = $image_row;
853  foreach ( array('id','width','height','hit','filesize') as $k )
854  {
855    if (isset($ret[$k]))
856    {
857      $ret[$k] = (int)$ret[$k];
858    }
859  }
860  foreach ( array('path', 'storage_category_id') as $k )
861  {
862    unset($ret[$k]);
863  }
[1698]864
[1849]865  $ret['rates'] = array( WS_XML_ATTRIBUTES => $rating );
[1698]866  $ret['categories'] = new PwgNamedArray($related_categories, 'category', array('id','url', 'page_url') );
[2585]867  $ret['tags'] = new PwgNamedArray($related_tags, 'tag', array('id','url_name','url','name','page_url') );
[1849]868  if ( isset($comment_post_data) )
869  {
870    $ret['comment_post'] = array( WS_XML_ATTRIBUTES => $comment_post_data );
871  }
[1698]872  $ret['comments'] = array(
[2119]873     WS_XML_ATTRIBUTES =>
[1849]874        array(
875          'page' => $params['comments_page'],
876          'per_page' => $params['comments_per_page'],
877          'count' => count($related_comments),
878          'nb_comments' => $nb_comments,
879        ),
880     WS_XML_CONTENT => new PwgNamedArray($related_comments, 'comment', array('id','date') )
[1698]881      );
[1845]882
[1698]883  return new PwgNamedStruct('image',$ret, null, array('name','comment') );
884}
885
[2435]886
[1837]887/**
[2435]888 * rates the image_id in the parameter
889 */
890function ws_images_Rate($params, &$service)
891{
892  $image_id = (int)$params['image_id'];
893  $query = '
894SELECT DISTINCT id FROM '.IMAGES_TABLE.'
895  INNER JOIN '.IMAGE_CATEGORY_TABLE.' ON id=image_id
896  WHERE id='.$image_id
897  .get_sql_condition_FandF(
898    array(
899        'forbidden_categories' => 'category_id',
900        'forbidden_images' => 'id',
901      ),
902    '    AND'
903    ).'
904    LIMIT 1';
[4325]905  if ( pwg_db_num_rows( pwg_query($query) )==0 )
[2435]906  {
907    return new PwgError(404, "Invalid image_id or access denied" );
908  }
909  $rate = (int)$params['rate'];
910  include_once(PHPWG_ROOT_PATH.'include/functions_rate.inc.php');
911  $res = rate_picture( $image_id, $rate );
912  if ($res==false)
913  {
914    global $conf;
915    return new PwgError( 403, "Forbidden or rate not in ". implode(',',$conf['rate_items']));
916  }
917  return $res;
918}
919
920
921/**
[1837]922 * returns a list of elements corresponding to a query search
923 */
924function ws_images_search($params, &$service)
925{
926  global $page;
927  $images = array();
928  include_once( PHPWG_ROOT_PATH .'include/functions_search.inc.php' );
929  include_once(PHPWG_ROOT_PATH.'include/functions_picture.inc.php');
[1698]930
[2135]931  $where_clauses = ws_std_image_sql_filter( $params, 'i.' );
932  $order_by = ws_std_image_sql_order($params, 'i.');
[1837]933
[2451]934  $super_order_by = false;
[2135]935  if ( !empty($order_by) )
[1837]936  {
[2135]937    global $conf;
938    $conf['order_by'] = 'ORDER BY '.$order_by;
[2451]939    $super_order_by=true; // quick_search_result might be faster
[1837]940  }
941
[2135]942  $search_result = get_quick_search_results($params['query'],
[2451]943      $super_order_by,
944      implode(',', $where_clauses)
945    );
[2119]946
[2451]947  $image_ids = array_slice(
948      $search_result['items'],
949      $params['page']*$params['per_page'],
950      $params['per_page']
951    );
[1837]952
953  if ( count($image_ids) )
954  {
955    $query = '
956SELECT * FROM '.IMAGES_TABLE.'
[2451]957  WHERE id IN ('.implode(',', $image_ids).')';
[1837]958
[2451]959    $image_ids = array_flip($image_ids);
[1837]960    $result = pwg_query($query);
[4325]961    while ($row = pwg_db_fetch_assoc($result))
[1837]962    {
963      $image = array();
964      foreach ( array('id', 'width', 'height', 'hit') as $k )
965      {
966        if (isset($row[$k]))
967        {
968          $image[$k] = (int)$row[$k];
969        }
970      }
[11116]971      foreach ( array('file', 'name', 'comment', 'date_creation', 'date_available') as $k )
[1837]972      {
973        $image[$k] = $row[$k];
974      }
975      $image = array_merge( $image, ws_std_get_urls($row) );
[2451]976      $images[$image_ids[$image['id']]] = $image;
[1837]977    }
[2451]978    ksort($images, SORT_NUMERIC);
979    $images = array_values($images);
[1837]980  }
981
982
983  return array( 'images' =>
984    array (
985      WS_XML_ATTRIBUTES =>
986        array(
987            'page' => $params['page'],
988            'per_page' => $params['per_page'],
989            'count' => count($images)
990          ),
991       WS_XML_CONTENT => new PwgNamedArray($images, 'image',
[1845]992          ws_std_get_image_xml_attributes() )
[1837]993      )
994    );
995}
996
[2413]997function ws_images_setPrivacyLevel($params, &$service)
998{
[8126]999  if (!is_admin())
[2413]1000  {
1001    return new PwgError(401, 'Access denied');
1002  }
[4513]1003  if (!$service->isPost())
1004  {
1005    return new PwgError(405, "This method requires HTTP POST");
1006  }
[2770]1007  $params['image_id'] = array_map( 'intval',$params['image_id'] );
[2413]1008  if ( empty($params['image_id']) )
1009  {
1010    return new PwgError(WS_ERR_INVALID_PARAM, "Invalid image_id");
1011  }
1012  global $conf;
1013  if ( !in_array( (int)$params['level'], $conf['available_permission_levels']) )
1014  {
1015    return new PwgError(WS_ERR_INVALID_PARAM, "Invalid level");
1016  }
[4513]1017
[2413]1018  $query = '
1019UPDATE '.IMAGES_TABLE.'
1020  SET level='.(int)$params['level'].'
1021  WHERE id IN ('.implode(',',$params['image_id']).')';
1022  $result = pwg_query($query);
[5930]1023  $affected_rows = pwg_db_changes($result);
[2413]1024  if ($affected_rows)
1025  {
1026    include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
1027    invalidate_user_cache();
1028  }
1029  return $affected_rows;
1030}
1031
[11372]1032function ws_images_setRank($params, &$service)
1033{
1034  if (!is_admin())
1035  {
1036    return new PwgError(401, 'Access denied');
1037  }
[11893]1038
[11372]1039  if (!$service->isPost())
1040  {
1041    return new PwgError(405, "This method requires HTTP POST");
1042  }
1043
1044  // is the image_id valid?
1045  $params['image_id'] = (int)$params['image_id'];
1046  if ($params['image_id'] <= 0)
1047  {
1048    return new PwgError(WS_ERR_INVALID_PARAM, "Invalid image_id");
1049  }
1050
1051  // is the category valid?
1052  $params['category_id'] = (int)$params['category_id'];
1053  if ($params['category_id'] <= 0)
1054  {
1055    return new PwgError(WS_ERR_INVALID_PARAM, "Invalid category_id");
1056  }
1057
1058  // is the rank valid?
1059  $params['rank'] = (int)$params['rank'];
1060  if ($params['rank'] <= 0)
1061  {
1062    return new PwgError(WS_ERR_INVALID_PARAM, "Invalid rank");
1063  }
[11893]1064
[11372]1065  // does the image really exist?
1066  $query='
1067SELECT
1068    *
1069  FROM '.IMAGES_TABLE.'
1070  WHERE id = '.$params['image_id'].'
1071;';
1072
1073  $image_row = pwg_db_fetch_assoc(pwg_query($query));
1074  if ($image_row == null)
1075  {
1076    return new PwgError(404, "image_id not found");
1077  }
[11893]1078
[11372]1079  // is the image associated to this category?
1080  $query = '
1081SELECT
1082    image_id,
1083    category_id,
1084    rank
1085  FROM '.IMAGE_CATEGORY_TABLE.'
1086  WHERE image_id = '.$params['image_id'].'
1087    AND category_id = '.$params['category_id'].'
1088;';
1089  $category_row = pwg_db_fetch_assoc(pwg_query($query));
1090  if ($category_row == null)
1091  {
1092    return new PwgError(404, "This image is not associated to this category");
1093  }
1094
1095  // what is the current higher rank for this category?
1096  $query = '
1097SELECT
1098    MAX(rank) AS max_rank
1099  FROM '.IMAGE_CATEGORY_TABLE.'
1100  WHERE category_id = '.$params['category_id'].'
1101;';
1102  $result = pwg_query($query);
1103  $row = pwg_db_fetch_assoc($result);
1104
1105  if (is_numeric($row['max_rank']))
1106  {
1107    if ($params['rank'] > $row['max_rank'])
1108    {
1109      $params['rank'] = $row['max_rank'] + 1;
1110    }
1111  }
1112  else
1113  {
1114    $params['rank'] = 1;
1115  }
1116
1117  // update rank for all other photos in the same category
1118  $query = '
1119UPDATE '.IMAGE_CATEGORY_TABLE.'
1120  SET rank = rank + 1
1121  WHERE category_id = '.$params['category_id'].'
1122    AND rank IS NOT NULL
1123    AND rank >= '.$params['rank'].'
1124;';
1125  pwg_query($query);
1126
1127  // set the new rank for the photo
1128  $query = '
1129UPDATE '.IMAGE_CATEGORY_TABLE.'
1130  SET rank = '.$params['rank'].'
1131  WHERE image_id = '.$params['image_id'].'
1132    AND category_id = '.$params['category_id'].'
1133;';
1134  pwg_query($query);
1135
1136  // return data for client
1137  return array(
1138    'image_id' => $params['image_id'],
1139    'category_id' => $params['category_id'],
1140    'rank' => $params['rank'],
1141    );
1142}
1143
[3193]1144function ws_images_add_chunk($params, &$service)
1145{
[5014]1146  global $conf;
[11893]1147
[4900]1148  ws_logfile('[ws_images_add_chunk] welcome');
[3193]1149  // data
1150  // original_sum
1151  // type {thumb, file, high}
1152  // position
[3488]1153
[8126]1154  if (!is_admin())
[3193]1155  {
1156    return new PwgError(401, 'Access denied');
1157  }
1158
[4511]1159  if (!$service->isPost())
1160  {
1161    return new PwgError(405, "This method requires HTTP POST");
1162  }
1163
[4900]1164  foreach ($params as $param_key => $param_value) {
1165    if ('data' == $param_key) {
1166      continue;
1167    }
[11893]1168
[4900]1169    ws_logfile(
1170      sprintf(
1171        '[ws_images_add_chunk] input param "%s" : "%s"',
1172        $param_key,
1173        is_null($param_value) ? 'NULL' : $param_value
1174        )
1175      );
1176  }
1177
[5014]1178  $upload_dir = $conf['upload_dir'].'/buffer';
[3193]1179
1180  // create the upload directory tree if not exists
1181  if (!is_dir($upload_dir)) {
1182    umask(0000);
1183    $recursive = true;
1184    if (!@mkdir($upload_dir, 0777, $recursive))
1185    {
1186      return new PwgError(500, 'error during buffer directory creation');
1187    }
1188  }
1189
1190  if (!is_writable($upload_dir))
1191  {
1192    // last chance to make the directory writable
1193    @chmod($upload_dir, 0777);
1194
1195    if (!is_writable($upload_dir))
1196    {
1197      return new PwgError(500, 'buffer directory has no write access');
1198    }
1199  }
1200
1201  secure_directory($upload_dir);
1202
1203  $filename = sprintf(
1204    '%s-%s-%05u.block',
1205    $params['original_sum'],
1206    $params['type'],
1207    $params['position']
1208    );
1209
[3240]1210  ws_logfile('[ws_images_add_chunk] data length : '.strlen($params['data']));
1211
[3193]1212  $bytes_written = file_put_contents(
1213    $upload_dir.'/'.$filename,
[3240]1214    base64_decode($params['data'])
[3193]1215    );
1216
1217  if (false === $bytes_written) {
1218    return new PwgError(
1219      500,
1220      'an error has occured while writting chunk '.$params['position'].' for '.$params['type']
1221      );
1222  }
1223}
1224
1225function merge_chunks($output_filepath, $original_sum, $type)
1226{
[5014]1227  global $conf;
[11893]1228
[3193]1229  ws_logfile('[merge_chunks] input parameter $output_filepath : '.$output_filepath);
1230
[4348]1231  if (is_file($output_filepath))
1232  {
1233    unlink($output_filepath);
[4513]1234
[4348]1235    if (is_file($output_filepath))
1236    {
1237      new PwgError(500, '[merge_chunks] error while trying to remove existing '.$output_filepath);
1238      exit();
1239    }
1240  }
[4513]1241
[5014]1242  $upload_dir = $conf['upload_dir'].'/buffer';
[3193]1243  $pattern = '/'.$original_sum.'-'.$type.'/';
1244  $chunks = array();
[3488]1245
[3193]1246  if ($handle = opendir($upload_dir))
1247  {
1248    while (false !== ($file = readdir($handle)))
1249    {
1250      if (preg_match($pattern, $file))
1251      {
1252        ws_logfile($file);
1253        array_push($chunks, $upload_dir.'/'.$file);
1254      }
1255    }
1256    closedir($handle);
1257  }
1258
1259  sort($chunks);
[3240]1260
[4425]1261  if (function_exists('memory_get_usage')) {
1262    ws_logfile('[merge_chunks] memory_get_usage before loading chunks: '.memory_get_usage());
1263  }
[3488]1264
[3514]1265  $i = 0;
[4513]1266
[3240]1267  foreach ($chunks as $chunk)
1268  {
1269    $string = file_get_contents($chunk);
[3488]1270
[4425]1271    if (function_exists('memory_get_usage')) {
1272      ws_logfile('[merge_chunks] memory_get_usage on chunk '.++$i.': '.memory_get_usage());
1273    }
[3488]1274
[3240]1275    if (!file_put_contents($output_filepath, $string, FILE_APPEND))
1276    {
[4346]1277      new PwgError(500, '[merge_chunks] error while writting chunks for '.$output_filepath);
1278      exit();
[3240]1279    }
[3488]1280
[3193]1281    unlink($chunk);
1282  }
[3240]1283
[4425]1284  if (function_exists('memory_get_usage')) {
1285    ws_logfile('[merge_chunks] memory_get_usage after loading chunks: '.memory_get_usage());
1286  }
[3193]1287}
1288
[4346]1289/*
1290 * The $file_path must be the path of the basic "web sized" photo
1291 * The $type value will automatically modify the $file_path to the corresponding file
1292 */
1293function add_file($file_path, $type, $original_sum, $file_sum)
1294{
[8249]1295  include_once(PHPWG_ROOT_PATH.'admin/include/functions_upload.inc.php');
[11893]1296
[4347]1297  $file_path = file_path_for_type($file_path, $type);
[4346]1298
1299  $upload_dir = dirname($file_path);
[4900]1300  if (substr(PHP_OS, 0, 3) == 'WIN')
1301  {
1302    $upload_dir = str_replace('/', DIRECTORY_SEPARATOR, $upload_dir);
1303  }
[4513]1304
[4900]1305  ws_logfile('[add_file] file_path  : '.$file_path);
1306  ws_logfile('[add_file] upload_dir : '.$upload_dir);
[11893]1307
[4346]1308  if (!is_dir($upload_dir)) {
1309    umask(0000);
1310    $recursive = true;
1311    if (!@mkdir($upload_dir, 0777, $recursive))
1312    {
1313      new PwgError(500, '[add_file] error during '.$type.' directory creation');
1314      exit();
1315    }
1316  }
1317
1318  if (!is_writable($upload_dir))
1319  {
1320    // last chance to make the directory writable
1321    @chmod($upload_dir, 0777);
1322
1323    if (!is_writable($upload_dir))
1324    {
1325      new PwgError(500, '[add_file] '.$type.' directory has no write access');
1326      exit();
1327    }
1328  }
1329
1330  secure_directory($upload_dir);
1331
1332  // merge the thumbnail
1333  merge_chunks($file_path, $original_sum, $type);
1334  chmod($file_path, 0644);
1335
1336  // check dumped thumbnail md5
1337  $dumped_md5 = md5_file($file_path);
1338  if ($dumped_md5 != $file_sum) {
1339    new PwgError(500, '[add_file] '.$type.' transfer failed');
1340    exit();
1341  }
1342
1343  list($width, $height) = getimagesize($file_path);
1344  $filesize = floor(filesize($file_path)/1024);
1345
1346  return array(
1347    'width' => $width,
1348    'height' => $height,
1349    'filesize' => $filesize,
1350    );
1351}
1352
[4348]1353function ws_images_addFile($params, &$service)
1354{
1355  // image_id
1356  // type {thumb, file, high}
1357  // sum
1358
1359  global $conf;
[8126]1360  if (!is_admin())
[4348]1361  {
1362    return new PwgError(401, 'Access denied');
1363  }
1364
1365  $params['image_id'] = (int)$params['image_id'];
1366  if ($params['image_id'] <= 0)
1367  {
1368    return new PwgError(WS_ERR_INVALID_PARAM, "Invalid image_id");
1369  }
1370
1371  //
1372  // what is the path?
1373  //
1374  $query = '
1375SELECT
1376    path,
1377    md5sum
1378  FROM '.IMAGES_TABLE.'
1379  WHERE id = '.$params['image_id'].'
1380;';
[6500]1381  list($file_path, $original_sum) = pwg_db_fetch_row(pwg_query($query));
[4348]1382
1383  // TODO only files added with web API can be updated with web API
1384
1385  //
1386  // makes sure directories are there and call the merge_chunks
1387  //
1388  $infos = add_file($file_path, $params['type'], $original_sum, $params['sum']);
1389
1390  //
1391  // update basic metadata from file
1392  //
1393  $update = array();
[4513]1394
[4348]1395  if ('high' == $params['type'])
1396  {
1397    $update['high_filesize'] = $infos['filesize'];
[10160]1398    $update['high_width'] = $infos['width'];
1399    $update['high_height'] = $infos['height'];
[4348]1400    $update['has_high'] = 'true';
1401  }
1402
1403  if ('file' == $params['type'])
1404  {
1405    $update['filesize'] = $infos['filesize'];
1406    $update['width'] = $infos['width'];
1407    $update['height'] = $infos['height'];
1408  }
1409
1410  // we may have nothing to update at database level, for example with a
1411  // thumbnail update
1412  if (count($update) > 0)
1413  {
1414    $update['id'] = $params['image_id'];
[4513]1415
[4348]1416    include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
1417    mass_updates(
1418      IMAGES_TABLE,
1419      array(
1420        'primary' => array('id'),
1421        'update'  => array_diff(array_keys($update), array('id'))
1422        ),
1423      array($update)
1424      );
1425  }
1426}
1427
[2463]1428function ws_images_add($params, &$service)
1429{
[8464]1430  global $conf, $user;
[8126]1431  if (!is_admin())
[2496]1432  {
1433    return new PwgError(401, 'Access denied');
1434  }
1435
[3662]1436  foreach ($params as $param_key => $param_value) {
1437    ws_logfile(
1438      sprintf(
1439        '[pwg.images.add] input param "%s" : "%s"',
1440        $param_key,
1441        is_null($param_value) ? 'NULL' : $param_value
1442        )
1443      );
1444  }
[2496]1445
[2592]1446  // does the image already exists ?
[4954]1447  if ('md5sum' == $conf['uniqueness_mode'])
1448  {
1449    $where_clause = "md5sum = '".$params['original_sum']."'";
1450  }
1451  if ('filename' == $conf['uniqueness_mode'])
1452  {
1453    $where_clause = "file = '".$params['original_filename']."'";
1454  }
[11893]1455
[2592]1456  $query = '
1457SELECT
1458    COUNT(*) AS counter
1459  FROM '.IMAGES_TABLE.'
[4954]1460  WHERE '.$where_clause.'
[2592]1461;';
[4325]1462  list($counter) = pwg_db_fetch_row(pwg_query($query));
[2592]1463  if ($counter != 0) {
1464    return new PwgError(500, 'file already exists');
1465  }
1466
[2463]1467  // current date
[4325]1468  list($dbnow) = pwg_db_fetch_row(pwg_query('SELECT NOW();'));
[2463]1469  list($year, $month, $day) = preg_split('/[^\d]/', $dbnow, 4);
[2496]1470
[2501]1471  // upload directory hierarchy
[2463]1472  $upload_dir = sprintf(
[5014]1473    $conf['upload_dir'].'/%s/%s/%s',
[2463]1474    $year,
1475    $month,
1476    $day
1477    );
1478
[2501]1479  // compute file path
[2463]1480  $date_string = preg_replace('/[^\d]/', '', $dbnow);
1481  $random_string = substr($params['file_sum'], 0, 8);
1482  $filename_wo_ext = $date_string.'-'.$random_string;
[2501]1483  $file_path = $upload_dir.'/'.$filename_wo_ext.'.jpg';
[2496]1484
[4346]1485  // add files
1486  $file_infos  = add_file($file_path, 'file',  $params['original_sum'], $params['file_sum']);
1487  $thumb_infos = add_file($file_path, 'thumb', $params['original_sum'], $params['thumbnail_sum']);
[2463]1488
[3193]1489  if (isset($params['high_sum']))
[2670]1490  {
[4346]1491    $high_infos = add_file($file_path, 'high', $params['original_sum'], $params['high_sum']);
[2670]1492  }
1493
[2463]1494  // database registration
1495  $insert = array(
[4911]1496    'file' => !empty($params['original_filename']) ? $params['original_filename'] : $filename_wo_ext.'.jpg',
[2463]1497    'date_available' => $dbnow,
1498    'tn_ext' => 'jpg',
1499    'name' => $params['name'],
1500    'path' => $file_path,
[4346]1501    'filesize' => $file_infos['filesize'],
1502    'width' => $file_infos['width'],
1503    'height' => $file_infos['height'],
[3065]1504    'md5sum' => $params['original_sum'],
[8464]1505    'added_by' => $user['id'],
[2463]1506    );
1507
[2569]1508  $info_columns = array(
1509    'name',
1510    'author',
1511    'comment',
1512    'level',
1513    'date_creation',
1514    );
1515
1516  foreach ($info_columns as $key)
1517  {
1518    if (isset($params[$key]))
1519    {
1520      $insert[$key] = $params[$key];
1521    }
1522  }
1523
[3193]1524  if (isset($params['high_sum']))
[2670]1525  {
1526    $insert['has_high'] = 'true';
[4346]1527    $insert['high_filesize'] = $high_infos['filesize'];
[10160]1528    $insert['high_width'] = $high_infos['width'];
1529    $insert['high_height'] = $high_infos['height'];
[2670]1530  }
1531
[2463]1532  include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
1533  mass_inserts(
1534    IMAGES_TABLE,
1535    array_keys($insert),
1536    array($insert)
1537    );
1538
[4892]1539  $image_id = pwg_db_insert_id(IMAGES_TABLE);
[2463]1540
[2569]1541  // let's add links between the image and the categories
1542  if (isset($params['categories']))
1543  {
[2919]1544    ws_add_image_category_relations($image_id, $params['categories']);
[2553]1545  }
[2569]1546
1547  // and now, let's create tag associations
[3660]1548  if (isset($params['tag_ids']) and !empty($params['tag_ids']))
[2553]1549  {
[2569]1550    set_tags(
1551      explode(',', $params['tag_ids']),
1552      $image_id
1553      );
[2553]1554  }
[2585]1555
[4685]1556  // update metadata from the uploaded file (exif/iptc)
1557  require_once(PHPWG_ROOT_PATH.'admin/include/functions_metadata.php');
1558  update_metadata(array($image_id=>$file_path));
[11893]1559
[2501]1560  invalidate_user_cache();
[2463]1561}
1562
[8249]1563function ws_images_addSimple($params, &$service)
1564{
1565  global $conf;
[8274]1566  if (!is_admin())
[8249]1567  {
1568    return new PwgError(401, 'Access denied');
1569  }
1570
1571  if (!$service->isPost())
1572  {
1573    return new PwgError(405, "This method requires HTTP POST");
1574  }
[11118]1575
1576  if (!isset($_FILES['image']))
1577  {
1578    return new PwgError(405, "The image (file) parameter is missing");
1579  }
[11893]1580
[9191]1581  $params['image_id'] = (int)$params['image_id'];
1582  if ($params['image_id'] > 0)
1583  {
1584    include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
[8249]1585
[9191]1586    $query='
1587SELECT *
1588  FROM '.IMAGES_TABLE.'
1589  WHERE id = '.$params['image_id'].'
1590;';
1591
1592    $image_row = pwg_db_fetch_assoc(pwg_query($query));
1593    if ($image_row == null)
1594    {
1595      return new PwgError(404, "image_id not found");
1596    }
1597  }
1598
[8249]1599  // category
1600  $params['category'] = (int)$params['category'];
[9191]1601  if ($params['category'] <= 0 and $params['image_id'] <= 0)
[8249]1602  {
1603    return new PwgError(WS_ERR_INVALID_PARAM, "Invalid category_id");
1604  }
1605
1606  include_once(PHPWG_ROOT_PATH.'admin/include/functions_upload.inc.php');
1607
1608  $image_id = add_uploaded_file(
1609    $_FILES['image']['tmp_name'],
1610    $_FILES['image']['name'],
[9191]1611    $params['category'] > 0 ? array($params['category']) : null,
1612    8,
1613    $params['image_id'] > 0 ? $params['image_id'] : null
[8249]1614    );
1615
1616  $info_columns = array(
1617    'name',
1618    'author',
1619    'comment',
1620    'level',
1621    'date_creation',
1622    );
1623
1624  foreach ($info_columns as $key)
1625  {
1626    if (isset($params[$key]))
1627    {
1628      $update[$key] = $params[$key];
1629    }
1630  }
1631
1632  if (count(array_keys($update)) > 0)
1633  {
1634    $update['id'] = $image_id;
1635
1636    include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
1637    mass_updates(
1638      IMAGES_TABLE,
1639      array(
1640        'primary' => array('id'),
1641        'update'  => array_diff(array_keys($update), array('id'))
1642        ),
1643      array($update)
1644      );
1645  }
1646
1647
1648  if (isset($params['tags']) and !empty($params['tags']))
1649  {
1650    $tag_ids = array();
1651    $tag_names = explode(',', $params['tags']);
1652    foreach ($tag_names as $tag_name)
1653    {
1654      $tag_id = tag_id_from_tag_name($tag_name);
1655      array_push($tag_ids, $tag_id);
1656    }
1657
1658    add_tags($tag_ids, array($image_id));
1659  }
1660
[9191]1661  $url_params = array('image_id' => $image_id);
1662
1663  if ($params['category'] > 0)
1664  {
1665    $query = '
[8249]1666SELECT id, name, permalink
1667  FROM '.CATEGORIES_TABLE.'
1668  WHERE id = '.$params['category'].'
1669;';
[9191]1670    $result = pwg_query($query);
1671    $category = pwg_db_fetch_assoc($result);
[8249]1672
[9191]1673    $url_params['section'] = 'categories';
1674    $url_params['category'] = $category;
1675  }
1676
[9944]1677  // update metadata from the uploaded file (exif/iptc), even if the sync
1678  // was already performed by add_uploaded_file().
1679  $query = '
1680SELECT
1681    path
1682  FROM '.IMAGES_TABLE.'
1683  WHERE id = '.$image_id.'
1684;';
1685  list($file_path) = pwg_db_fetch_row(pwg_query($query));
[11893]1686
[9944]1687  require_once(PHPWG_ROOT_PATH.'admin/include/functions_metadata.php');
1688  update_metadata(array($image_id=>$file_path));
1689
[8249]1690  return array(
1691    'image_id' => $image_id,
[9191]1692    'url' => make_picture_url($url_params),
[8249]1693    );
1694}
1695
[1781]1696/**
1697 * perform a login (web service method)
1698 */
[1698]1699function ws_session_login($params, &$service)
1700{
1701  global $conf;
1702
1703  if (!$service->isPost())
1704  {
[1852]1705    return new PwgError(405, "This method requires HTTP POST");
[1698]1706  }
[1744]1707  if (try_log_user($params['username'], $params['password'],false))
[1698]1708  {
1709    return true;
1710  }
1711  return new PwgError(999, 'Invalid username/password');
1712}
1713
[1781]1714
1715/**
1716 * performs a logout (web service method)
1717 */
[1698]1718function ws_session_logout($params, &$service)
1719{
[2029]1720  if (!is_a_guest())
[1698]1721  {
[2757]1722    logout_user();
[1698]1723  }
1724  return true;
1725}
1726
1727function ws_session_getStatus($params, &$service)
1728{
[2356]1729  global $user;
[1698]1730  $res = array();
[4304]1731  $res['username'] = is_a_guest() ? 'guest' : stripslashes($user['username']);
[6437]1732  foreach ( array('status', 'theme', 'language') as $k )
[1849]1733  {
1734    $res[$k] = $user[$k];
1735  }
[7212]1736  $res['pwg_token'] = get_pwg_token();
[2126]1737  $res['charset'] = get_pwg_charset();
[11756]1738
1739  list($dbnow) = pwg_db_fetch_row(pwg_query('SELECT NOW();'));
1740  $res['current_datetime'] = $dbnow;
[11893]1741
[1698]1742  return $res;
1743}
1744
1745
[1781]1746/**
1747 * returns a list of tags (web service method)
1748 */
[1698]1749function ws_tags_getList($params, &$service)
1750{
[1711]1751  $tags = get_available_tags();
[1698]1752  if ($params['sort_by_counter'])
1753  {
1754    usort($tags, create_function('$a,$b', 'return -$a["counter"]+$b["counter"];') );
1755  }
1756  else
1757  {
[2409]1758    usort($tags, 'tag_alpha_compare');
[1698]1759  }
1760  for ($i=0; $i<count($tags); $i++)
1761  {
[1815]1762    $tags[$i]['id'] = (int)$tags[$i]['id'];
[1698]1763    $tags[$i]['counter'] = (int)$tags[$i]['counter'];
1764    $tags[$i]['url'] = make_index_url(
1765        array(
1766          'section'=>'tags',
1767          'tags'=>array($tags[$i])
1768        )
1769      );
1770  }
[2585]1771  return array('tags' => new PwgNamedArray($tags, 'tag', array('id','url_name','url', 'name', 'counter' )) );
[1698]1772}
1773
[2584]1774/**
1775 * returns the list of tags as you can see them in administration (web
1776 * service method).
1777 *
1778 * Only admin can run this method and permissions are not taken into
1779 * account.
1780 */
1781function ws_tags_getAdminList($params, &$service)
1782{
1783  if (!is_admin())
1784  {
1785    return new PwgError(401, 'Access denied');
1786  }
[2585]1787
[2584]1788  $tags = get_all_tags();
1789  return array(
1790    'tags' => new PwgNamedArray(
1791      $tags,
1792      'tag',
1793      array(
1794        'name',
1795        'id',
1796        'url_name',
1797        )
1798      )
1799    );
1800}
[1781]1801
1802/**
1803 * returns a list of images for tags (web service method)
1804 */
[1698]1805function ws_tags_getImages($params, &$service)
1806{
1807  @include_once(PHPWG_ROOT_PATH.'include/functions_picture.inc.php');
[1816]1808  global $conf;
[2119]1809
[1698]1810  // first build all the tag_ids we are interested in
[1852]1811  $params['tag_id'] = array_map( 'intval',$params['tag_id'] );
1812  $tags = find_tags($params['tag_id'], $params['tag_url_name'], $params['tag_name']);
[1698]1813  $tags_by_id = array();
1814  foreach( $tags as $tag )
1815  {
[1852]1816    $tags['id'] = (int)$tag['id'];
[1815]1817    $tags_by_id[ $tag['id'] ] = $tag;
[1698]1818  }
1819  unset($tags);
[1852]1820  $tag_ids = array_keys($tags_by_id);
[1698]1821
1822
[8726]1823  $where_clauses = ws_std_image_sql_filter($params);
1824  if (!empty($where_clauses))
1825  {
1826    $where_clauses = implode( ' AND ', $where_clauses);
1827  }
1828  $image_ids = get_image_ids_for_tags(
1829    $tag_ids,
1830    $params['tag_mode_and'] ? 'AND' : 'OR',
1831    $where_clauses,
1832    ws_std_image_sql_order($params) );
[1781]1833
[8726]1834
1835  $image_ids = array_slice($image_ids, (int)($params['per_page']*$params['page']), (int)$params['per_page'] );
[11893]1836
[8726]1837  $image_tag_map = array();
1838  if ( !empty($image_ids) and !$params['tag_mode_and'] )
[1698]1839  { // build list of image ids with associated tags per image
[8726]1840    $query = '
[6652]1841SELECT image_id, GROUP_CONCAT(tag_id) AS tag_ids
[1698]1842  FROM '.IMAGE_TAG_TABLE.'
[8726]1843  WHERE tag_id IN ('.implode(',',$tag_ids).') AND image_id IN ('.implode(',',$image_ids).')
[1698]1844  GROUP BY image_id';
[8726]1845    $result = pwg_query($query);
1846    while ( $row=pwg_db_fetch_assoc($result) )
1847    {
1848      $row['image_id'] = (int)$row['image_id'];
1849      array_push( $image_ids, $row['image_id'] );
1850      $image_tag_map[ $row['image_id'] ] = explode(',', $row['tag_ids']);
[1698]1851    }
1852  }
1853
1854  $images = array();
[8726]1855  if (!empty($image_ids))
[1698]1856  {
[8726]1857    $rank_of = array_flip($image_ids);
1858    $result = pwg_query('
1859SELECT * FROM '.IMAGES_TABLE.'
1860  WHERE id IN ('.implode(',',$image_ids).')');
[4325]1861    while ($row = pwg_db_fetch_assoc($result))
[1698]1862    {
[2119]1863      $image = array();
[8726]1864      $image['rank'] = $rank_of[ $row['id'] ];
[1698]1865      foreach ( array('id', 'width', 'height', 'hit') as $k )
1866      {
1867        if (isset($row[$k]))
1868        {
1869          $image[$k] = (int)$row[$k];
1870        }
1871      }
[11116]1872      foreach ( array('file', 'name', 'comment', 'date_creation', 'date_available') as $k )
[1698]1873      {
1874        $image[$k] = $row[$k];
1875      }
1876      $image = array_merge( $image, ws_std_get_urls($row) );
1877
1878      $image_tag_ids = ($params['tag_mode_and']) ? $tag_ids : $image_tag_map[$image['id']];
1879      $image_tags = array();
1880      foreach ($image_tag_ids as $tag_id)
1881      {
1882        $url = make_index_url(
1883                 array(
1884                  'section'=>'tags',
1885                  'tags'=> array($tags_by_id[$tag_id])
1886                )
1887              );
1888        $page_url = make_picture_url(
1889                 array(
1890                  'section'=>'tags',
1891                  'tags'=> array($tags_by_id[$tag_id]),
1892                  'image_id' => $row['id'],
1893                  'image_file' => $row['file'],
1894                )
1895              );
1896        array_push($image_tags, array(
1897                'id' => (int)$tag_id,
1898                'url' => $url,
1899                'page_url' => $page_url,
1900              )
1901            );
1902      }
[1711]1903      $image['tags'] = new PwgNamedArray($image_tags, 'tag',
1904              array('id','url_name','url','page_url')
[1698]1905            );
1906      array_push($images, $image);
1907    }
[8726]1908    usort($images, 'rank_compare');
1909    unset($rank_of);
[1698]1910  }
1911
1912  return array( 'images' =>
1913    array (
1914      WS_XML_ATTRIBUTES =>
1915        array(
1916            'page' => $params['page'],
1917            'per_page' => $params['per_page'],
1918            'count' => count($images)
1919          ),
[1711]1920       WS_XML_CONTENT => new PwgNamedArray($images, 'image',
[1845]1921          ws_std_get_image_xml_attributes() )
[1698]1922      )
1923    );
1924}
[2583]1925
1926function ws_categories_add($params, &$service)
1927{
[8126]1928  if (!is_admin())
[2583]1929  {
1930    return new PwgError(401, 'Access denied');
1931  }
1932
1933  include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
1934
1935  $creation_output = create_virtual_category(
1936    $params['name'],
1937    $params['parent']
1938    );
1939
1940  if (isset($creation_output['error']))
1941  {
1942    return new PwgError(500, $creation_output['error']);
1943  }
[2585]1944
[2644]1945  invalidate_user_cache();
[2757]1946
[2583]1947  return $creation_output;
1948}
[2634]1949
1950function ws_tags_add($params, &$service)
1951{
[8126]1952  if (!is_admin())
[2634]1953  {
1954    return new PwgError(401, 'Access denied');
1955  }
1956
1957  include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
1958
1959  $creation_output = create_tag($params['name']);
1960
1961  if (isset($creation_output['error']))
1962  {
1963    return new PwgError(500, $creation_output['error']);
1964  }
1965
1966  return $creation_output;
1967}
[2683]1968
1969function ws_images_exist($params, &$service)
1970{
[4954]1971  global $conf;
[11893]1972
[8126]1973  if (!is_admin())
[2683]1974  {
1975    return new PwgError(401, 'Access denied');
1976  }
1977
[4954]1978  $split_pattern = '/[\s,;\|]/';
1979
1980  if ('md5sum' == $conf['uniqueness_mode'])
1981  {
1982    // search among photos the list of photos already added, based on md5sum
1983    // list
1984    $md5sums = preg_split(
1985      $split_pattern,
1986      $params['md5sum_list'],
1987      -1,
1988      PREG_SPLIT_NO_EMPTY
[2683]1989    );
[2757]1990
[4954]1991    $query = '
[2683]1992SELECT
1993    id,
1994    md5sum
1995  FROM '.IMAGES_TABLE.'
[2757]1996  WHERE md5sum IN (\''.implode("','", $md5sums).'\')
[2683]1997;';
[4954]1998    $id_of_md5 = simple_hash_from_query($query, 'md5sum', 'id');
[2683]1999
[4954]2000    $result = array();
[2757]2001
[4954]2002    foreach ($md5sums as $md5sum)
2003    {
2004      $result[$md5sum] = null;
2005      if (isset($id_of_md5[$md5sum]))
2006      {
2007        $result[$md5sum] = $id_of_md5[$md5sum];
2008      }
2009    }
2010  }
[11893]2011
[4954]2012  if ('filename' == $conf['uniqueness_mode'])
[2683]2013  {
[4954]2014    // search among photos the list of photos already added, based on
2015    // filename list
2016    $filenames = preg_split(
2017      $split_pattern,
2018      $params['filename_list'],
2019      -1,
2020      PREG_SPLIT_NO_EMPTY
2021    );
2022
2023    $query = '
2024SELECT
2025    id,
2026    file
2027  FROM '.IMAGES_TABLE.'
2028  WHERE file IN (\''.implode("','", $filenames).'\')
2029;';
2030    $id_of_filename = simple_hash_from_query($query, 'file', 'id');
2031
2032    $result = array();
2033
2034    foreach ($filenames as $filename)
[2683]2035    {
[4954]2036      $result[$filename] = null;
2037      if (isset($id_of_filename[$filename]))
2038      {
2039        $result[$filename] = $id_of_filename[$filename];
2040      }
[2683]2041    }
2042  }
2043
2044  return $result;
2045}
[2919]2046
[4347]2047function ws_images_checkFiles($params, &$service)
2048{
[8126]2049  if (!is_admin())
[4347]2050  {
2051    return new PwgError(401, 'Access denied');
2052  }
2053
2054  // input parameters
2055  //
2056  // image_id
2057  // thumbnail_sum
2058  // file_sum
2059  // high_sum
2060
2061  $params['image_id'] = (int)$params['image_id'];
2062  if ($params['image_id'] <= 0)
2063  {
2064    return new PwgError(WS_ERR_INVALID_PARAM, "Invalid image_id");
2065  }
2066
2067  $query = '
2068SELECT
2069    path
2070  FROM '.IMAGES_TABLE.'
2071  WHERE id = '.$params['image_id'].'
2072;';
2073  $result = pwg_query($query);
[6500]2074  if (pwg_db_num_rows($result) == 0) {
[4347]2075    return new PwgError(404, "image_id not found");
2076  }
[6500]2077  list($path) = pwg_db_fetch_row($result);
[4347]2078
2079  $ret = array();
2080
2081  foreach (array('thumb', 'file', 'high') as $type) {
2082    $param_name = $type;
2083    if ('thumb' == $type) {
2084      $param_name = 'thumbnail';
2085    }
2086
2087    if (isset($params[$param_name.'_sum'])) {
[8249]2088      include_once(PHPWG_ROOT_PATH.'admin/include/functions_upload.inc.php');
[4347]2089      $type_path = file_path_for_type($path, $type);
2090      if (!is_file($type_path)) {
2091        $ret[$param_name] = 'missing';
2092      }
2093      else {
2094        if (md5_file($type_path) != $params[$param_name.'_sum']) {
2095          $ret[$param_name] = 'differs';
2096        }
2097        else {
2098          $ret[$param_name] = 'equals';
2099        }
2100      }
2101    }
2102  }
2103
2104  return $ret;
2105}
2106
[2919]2107function ws_images_setInfo($params, &$service)
2108{
2109  global $conf;
[8126]2110  if (!is_admin())
[2919]2111  {
2112    return new PwgError(401, 'Access denied');
2113  }
2114
[4511]2115  if (!$service->isPost())
2116  {
2117    return new PwgError(405, "This method requires HTTP POST");
2118  }
2119
[2919]2120  $params['image_id'] = (int)$params['image_id'];
2121  if ($params['image_id'] <= 0)
2122  {
2123    return new PwgError(WS_ERR_INVALID_PARAM, "Invalid image_id");
2124  }
2125
[7613]2126  include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
2127
[2919]2128  $query='
2129SELECT *
2130  FROM '.IMAGES_TABLE.'
2131  WHERE id = '.$params['image_id'].'
2132;';
2133
[4325]2134  $image_row = pwg_db_fetch_assoc(pwg_query($query));
[2919]2135  if ($image_row == null)
2136  {
2137    return new PwgError(404, "image_id not found");
2138  }
2139
2140  // database registration
[4460]2141  $update = array();
[2919]2142
2143  $info_columns = array(
2144    'name',
2145    'author',
2146    'comment',
2147    'level',
2148    'date_creation',
2149    );
2150
2151  foreach ($info_columns as $key)
2152  {
2153    if (isset($params[$key]))
2154    {
[4460]2155      if ('fill_if_empty' == $params['single_value_mode'])
2156      {
2157        if (empty($image_row[$key]))
2158        {
2159          $update[$key] = $params[$key];
2160        }
2161      }
2162      elseif ('replace' == $params['single_value_mode'])
2163      {
2164        $update[$key] = $params[$key];
2165      }
2166      else
2167      {
2168        new PwgError(
2169          500,
2170          '[ws_images_setInfo]'
2171          .' invalid parameter single_value_mode "'.$params['single_value_mode'].'"'
2172          .', possible values are {fill_if_empty, replace}.'
2173          );
2174        exit();
2175      }
[2919]2176    }
2177  }
2178
[4460]2179  if (count(array_keys($update)) > 0)
[2919]2180  {
[4460]2181    $update['id'] = $params['image_id'];
2182
[2919]2183    mass_updates(
2184      IMAGES_TABLE,
2185      array(
2186        'primary' => array('id'),
2187        'update'  => array_diff(array_keys($update), array('id'))
2188        ),
2189      array($update)
2190      );
2191  }
[3145]2192
[2919]2193  if (isset($params['categories']))
2194  {
2195    ws_add_image_category_relations(
2196      $params['image_id'],
[4445]2197      $params['categories'],
[4460]2198      ('replace' == $params['multiple_value_mode'] ? true : false)
[2919]2199      );
2200  }
2201
2202  // and now, let's create tag associations
2203  if (isset($params['tag_ids']))
2204  {
[4445]2205    $tag_ids = explode(',', $params['tag_ids']);
2206
[4460]2207    if ('replace' == $params['multiple_value_mode'])
[4445]2208    {
2209      set_tags(
2210        $tag_ids,
2211        $params['image_id']
2212        );
2213    }
[4460]2214    elseif ('append' == $params['multiple_value_mode'])
[4445]2215    {
2216      add_tags(
2217        $tag_ids,
2218        array($params['image_id'])
2219        );
2220    }
[4460]2221    else
2222    {
2223      new PwgError(
2224        500,
2225        '[ws_images_setInfo]'
2226        .' invalid parameter multiple_value_mode "'.$params['multiple_value_mode'].'"'
2227        .', possible values are {replace, append}.'
2228        );
2229      exit();
2230    }
[2919]2231  }
2232
2233  invalidate_user_cache();
2234}
2235
[8266]2236function ws_images_delete($params, &$service)
2237{
2238  global $conf;
[8274]2239  if (!is_admin())
[8266]2240  {
2241    return new PwgError(401, 'Access denied');
2242  }
2243
2244  if (!$service->isPost())
2245  {
2246    return new PwgError(405, "This method requires HTTP POST");
2247  }
2248
2249  if (empty($params['pwg_token']) or get_pwg_token() != $params['pwg_token'])
2250  {
2251    return new PwgError(403, 'Invalid security token');
2252  }
2253
2254  $params['image_id'] = preg_split(
2255    '/[\s,;\|]/',
2256    $params['image_id'],
2257    -1,
2258    PREG_SPLIT_NO_EMPTY
2259    );
2260  $params['image_id'] = array_map('intval', $params['image_id']);
2261
2262  $image_ids = array();
2263  foreach ($params['image_id'] as $image_id)
2264  {
2265    if ($image_id > 0)
2266    {
2267      array_push($image_ids, $image_id);
2268    }
2269  }
2270
2271  include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
2272  delete_elements($image_ids, true);
2273}
2274
[4445]2275function ws_add_image_category_relations($image_id, $categories_string, $replace_mode=false)
[2919]2276{
2277  // let's add links between the image and the categories
2278  //
2279  // $params['categories'] should look like 123,12;456,auto;789 which means:
2280  //
2281  // 1. associate with category 123 on rank 12
2282  // 2. associate with category 456 on automatic rank
2283  // 3. associate with category 789 on automatic rank
2284  $cat_ids = array();
2285  $rank_on_category = array();
2286  $search_current_ranks = false;
2287
2288  $tokens = explode(';', $categories_string);
2289  foreach ($tokens as $token)
2290  {
[2920]2291    @list($cat_id, $rank) = explode(',', $token);
[2919]2292
[4445]2293    if (!preg_match('/^\d+$/', $cat_id))
2294    {
2295      continue;
2296    }
2297
[2919]2298    array_push($cat_ids, $cat_id);
2299
2300    if (!isset($rank))
2301    {
2302      $rank = 'auto';
2303    }
2304    $rank_on_category[$cat_id] = $rank;
2305
2306    if ($rank == 'auto')
2307    {
2308      $search_current_ranks = true;
2309    }
2310  }
2311
2312  $cat_ids = array_unique($cat_ids);
2313
[4445]2314  if (count($cat_ids) == 0)
[2919]2315  {
[4445]2316    new PwgError(
2317      500,
2318      '[ws_add_image_category_relations] there is no category defined in "'.$categories_string.'"'
2319      );
2320    exit();
2321  }
[4513]2322
[4445]2323  $query = '
2324SELECT
2325    id
2326  FROM '.CATEGORIES_TABLE.'
2327  WHERE id IN ('.implode(',', $cat_ids).')
2328;';
2329  $db_cat_ids = array_from_query($query, 'id');
2330
2331  $unknown_cat_ids = array_diff($cat_ids, $db_cat_ids);
2332  if (count($unknown_cat_ids) != 0)
2333  {
2334    new PwgError(
2335      500,
2336      '[ws_add_image_category_relations] the following categories are unknown: '.implode(', ', $unknown_cat_ids)
2337      );
2338    exit();
2339  }
[4513]2340
[4445]2341  $to_update_cat_ids = array();
[4513]2342
[4445]2343  // in case of replace mode, we first check the existing associations
2344  $query = '
2345SELECT
2346    category_id
2347  FROM '.IMAGE_CATEGORY_TABLE.'
2348  WHERE image_id = '.$image_id.'
2349;';
2350  $existing_cat_ids = array_from_query($query, 'category_id');
2351
2352  if ($replace_mode)
2353  {
2354    $to_remove_cat_ids = array_diff($existing_cat_ids, $cat_ids);
2355    if (count($to_remove_cat_ids) > 0)
[2919]2356    {
2357      $query = '
[4445]2358DELETE
2359  FROM '.IMAGE_CATEGORY_TABLE.'
2360  WHERE image_id = '.$image_id.'
2361    AND category_id IN ('.implode(', ', $to_remove_cat_ids).')
2362;';
2363      pwg_query($query);
2364      update_category($to_remove_cat_ids);
2365    }
2366  }
[4513]2367
[4445]2368  $new_cat_ids = array_diff($cat_ids, $existing_cat_ids);
2369  if (count($new_cat_ids) == 0)
2370  {
2371    return true;
2372  }
[4513]2373
[4445]2374  if ($search_current_ranks)
2375  {
2376    $query = '
[2919]2377SELECT
2378    category_id,
2379    MAX(rank) AS max_rank
2380  FROM '.IMAGE_CATEGORY_TABLE.'
2381  WHERE rank IS NOT NULL
[4445]2382    AND category_id IN ('.implode(',', $new_cat_ids).')
[2919]2383  GROUP BY category_id
2384;';
[4445]2385    $current_rank_of = simple_hash_from_query(
2386      $query,
2387      'category_id',
2388      'max_rank'
2389      );
[2919]2390
[4445]2391    foreach ($new_cat_ids as $cat_id)
2392    {
2393      if (!isset($current_rank_of[$cat_id]))
[2919]2394      {
[4445]2395        $current_rank_of[$cat_id] = 0;
[2919]2396      }
[4513]2397
[4445]2398      if ('auto' == $rank_on_category[$cat_id])
2399      {
2400        $rank_on_category[$cat_id] = $current_rank_of[$cat_id] + 1;
2401      }
[2919]2402    }
[4445]2403  }
[4513]2404
[4445]2405  $inserts = array();
[4513]2406
[4445]2407  foreach ($new_cat_ids as $cat_id)
2408  {
2409    array_push(
2410      $inserts,
2411      array(
2412        'image_id' => $image_id,
2413        'category_id' => $cat_id,
2414        'rank' => $rank_on_category[$cat_id],
2415        )
[2919]2416      );
2417  }
[4513]2418
[4445]2419  include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
2420  mass_inserts(
2421    IMAGE_CATEGORY_TABLE,
2422    array_keys($inserts[0]),
2423    $inserts
2424    );
[4513]2425
[4445]2426  update_category($new_cat_ids);
[2919]2427}
[3193]2428
[3454]2429function ws_categories_setInfo($params, &$service)
2430{
2431  global $conf;
[8126]2432  if (!is_admin())
[3454]2433  {
2434    return new PwgError(401, 'Access denied');
2435  }
2436
[4511]2437  if (!$service->isPost())
2438  {
2439    return new PwgError(405, "This method requires HTTP POST");
2440  }
2441
[3454]2442  // category_id
2443  // name
2444  // comment
2445
2446  $params['category_id'] = (int)$params['category_id'];
2447  if ($params['category_id'] <= 0)
2448  {
2449    return new PwgError(WS_ERR_INVALID_PARAM, "Invalid category_id");
2450  }
2451
2452  // database registration
2453  $update = array(
2454    'id' => $params['category_id'],
2455    );
2456
2457  $info_columns = array(
2458    'name',
2459    'comment',
2460    );
2461
2462  $perform_update = false;
2463  foreach ($info_columns as $key)
2464  {
2465    if (isset($params[$key]))
2466    {
2467      $perform_update = true;
2468      $update[$key] = $params[$key];
2469    }
2470  }
2471
2472  if ($perform_update)
2473  {
2474    include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
2475    mass_updates(
2476      CATEGORIES_TABLE,
2477      array(
2478        'primary' => array('id'),
2479        'update'  => array_diff(array_keys($update), array('id'))
2480        ),
2481      array($update)
2482      );
2483  }
[3488]2484
[3454]2485}
2486
[11746]2487function ws_categories_setRepresentative($params, &$service)
2488{
2489  global $conf;
[11893]2490
[11746]2491  if (!is_admin())
2492  {
2493    return new PwgError(401, 'Access denied');
2494  }
2495
2496  if (!$service->isPost())
2497  {
2498    return new PwgError(405, "This method requires HTTP POST");
2499  }
2500
2501  // category_id
2502  // image_id
2503
2504  $params['category_id'] = (int)$params['category_id'];
2505  if ($params['category_id'] <= 0)
2506  {
2507    return new PwgError(WS_ERR_INVALID_PARAM, "Invalid category_id");
2508  }
2509
2510  // does the category really exist?
2511  $query='
2512SELECT
2513    *
2514  FROM '.CATEGORIES_TABLE.'
2515  WHERE id = '.$params['category_id'].'
2516;';
2517  $row = pwg_db_fetch_assoc(pwg_query($query));
2518  if ($row == null)
2519  {
2520    return new PwgError(404, "category_id not found");
2521  }
2522
2523  $params['image_id'] = (int)$params['image_id'];
2524  if ($params['image_id'] <= 0)
2525  {
2526    return new PwgError(WS_ERR_INVALID_PARAM, "Invalid image_id");
2527  }
[11893]2528
[11746]2529  // does the image really exist?
2530  $query='
2531SELECT
2532    *
2533  FROM '.IMAGES_TABLE.'
2534  WHERE id = '.$params['image_id'].'
2535;';
2536
2537  $row = pwg_db_fetch_assoc(pwg_query($query));
2538  if ($row == null)
2539  {
2540    return new PwgError(404, "image_id not found");
2541  }
2542
2543  // apply change
2544  $query = '
2545UPDATE '.CATEGORIES_TABLE.'
2546  SET representative_picture_id = '.$params['image_id'].'
2547  WHERE id = '.$params['category_id'].'
2548;';
2549  pwg_query($query);
2550
2551  $query = '
2552UPDATE '.USER_CACHE_CATEGORIES_TABLE.'
2553  SET user_representative_picture_id = NULL
2554  WHERE cat_id = '.$params['category_id'].'
2555;';
2556  pwg_query($query);
2557}
2558
[8266]2559function ws_categories_delete($params, &$service)
2560{
2561  global $conf;
[8274]2562  if (!is_admin())
[8266]2563  {
2564    return new PwgError(401, 'Access denied');
2565  }
2566
2567  if (!$service->isPost())
2568  {
2569    return new PwgError(405, "This method requires HTTP POST");
2570  }
2571
2572  if (empty($params['pwg_token']) or get_pwg_token() != $params['pwg_token'])
2573  {
2574    return new PwgError(403, 'Invalid security token');
2575  }
2576
2577  $modes = array('no_delete', 'delete_orphans', 'force_delete');
2578  if (!in_array($params['photo_deletion_mode'], $modes))
2579  {
2580    return new PwgError(
2581      500,
2582      '[ws_categories_delete]'
2583      .' invalid parameter photo_deletion_mode "'.$params['photo_deletion_mode'].'"'
2584      .', possible values are {'.implode(', ', $modes).'}.'
2585      );
2586  }
2587
2588  $params['category_id'] = preg_split(
2589    '/[\s,;\|]/',
2590    $params['category_id'],
2591    -1,
2592    PREG_SPLIT_NO_EMPTY
2593    );
2594  $params['category_id'] = array_map('intval', $params['category_id']);
2595
2596  $category_ids = array();
2597  foreach ($params['category_id'] as $category_id)
2598  {
2599    if ($category_id > 0)
2600    {
2601      array_push($category_ids, $category_id);
2602    }
2603  }
2604
2605  if (count($category_ids) == 0)
2606  {
2607    return;
2608  }
2609
2610  $query = '
2611SELECT id
2612  FROM '.CATEGORIES_TABLE.'
2613  WHERE id IN ('.implode(',', $category_ids).')
2614;';
2615  $category_ids = array_from_query($query, 'id');
2616
2617  if (count($category_ids) == 0)
2618  {
2619    return;
2620  }
[11893]2621
[8266]2622  include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
2623  delete_categories($category_ids, $params['photo_deletion_mode']);
2624  update_global_rank();
2625}
2626
[8272]2627function ws_categories_move($params, &$service)
2628{
2629  global $conf, $page;
[11893]2630
[8274]2631  if (!is_admin())
[8272]2632  {
2633    return new PwgError(401, 'Access denied');
2634  }
2635
2636  if (!$service->isPost())
2637  {
2638    return new PwgError(405, "This method requires HTTP POST");
2639  }
2640
2641  if (empty($params['pwg_token']) or get_pwg_token() != $params['pwg_token'])
2642  {
2643    return new PwgError(403, 'Invalid security token');
2644  }
2645
2646  $params['category_id'] = preg_split(
2647    '/[\s,;\|]/',
2648    $params['category_id'],
2649    -1,
2650    PREG_SPLIT_NO_EMPTY
2651    );
2652  $params['category_id'] = array_map('intval', $params['category_id']);
2653
2654  $category_ids = array();
2655  foreach ($params['category_id'] as $category_id)
2656  {
2657    if ($category_id > 0)
2658    {
2659      array_push($category_ids, $category_id);
2660    }
2661  }
2662
2663  if (count($category_ids) == 0)
2664  {
2665    return new PwgError(403, 'Invalid category_id input parameter, no category to move');
2666  }
2667
2668  // we can't move physical categories
2669  $categories_in_db = array();
[11893]2670
[8272]2671  $query = '
2672SELECT
2673    id,
2674    name,
2675    dir
2676  FROM '.CATEGORIES_TABLE.'
2677  WHERE id IN ('.implode(',', $category_ids).')
2678;';
2679  $result = pwg_query($query);
2680  while ($row = pwg_db_fetch_assoc($result))
2681  {
2682    $categories_in_db[$row['id']] = $row;
2683    // we break on error at first physical category detected
2684    if (!empty($row['dir']))
2685    {
2686      $row['name'] = strip_tags(
2687        trigger_event(
2688          'render_category_name',
2689          $row['name'],
2690          'ws_categories_move'
2691          )
2692        );
[11893]2693
[8272]2694      return new PwgError(
2695        403,
2696        sprintf(
2697          'Category %s (%u) is not a virtual category, you cannot move it',
2698          $row['name'],
2699          $row['id']
2700          )
2701        );
2702    }
2703  }
2704
2705  if (count($categories_in_db) != count($category_ids))
2706  {
2707    $unknown_category_ids = array_diff($category_ids, array_keys($categories_in_db));
[11893]2708
[8272]2709    return new PwgError(
2710      403,
2711      sprintf(
2712        'Category %u does not exist',
2713        $unknown_category_ids[0]
2714        )
2715      );
2716  }
2717
2718  // does this parent exists? This check should be made in the
2719  // move_categories function, not here
2720  //
2721  // 0 as parent means "move categories at gallery root"
2722  if (!is_numeric($params['parent']))
2723  {
2724    return new PwgError(403, 'Invalid parent input parameter');
2725  }
[11893]2726
[8272]2727  if (0 != $params['parent']) {
2728    $params['parent'] = intval($params['parent']);
2729    $subcat_ids = get_subcat_ids(array($params['parent']));
2730    if (count($subcat_ids) == 0)
2731    {
2732      return new PwgError(403, 'Unknown parent category id');
2733    }
2734  }
2735
2736  $page['infos'] = array();
2737  $page['errors'] = array();
2738  include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
2739  move_categories($category_ids, $params['parent']);
2740  invalidate_user_cache();
2741
2742  if (count($page['errors']) != 0)
2743  {
2744    return new PwgError(403, implode('; ', $page['errors']));
2745  }
2746}
2747
[3193]2748function ws_logfile($string)
2749{
[3662]2750  global $conf;
[3488]2751
[3662]2752  if (!$conf['ws_enable_log']) {
2753    return true;
2754  }
2755
[3193]2756  file_put_contents(
[3662]2757    $conf['ws_log_filepath'],
[3193]2758    '['.date('c').'] '.$string."\n",
2759    FILE_APPEND
2760    );
2761}
[6049]2762
2763function ws_images_checkUpload($params, &$service)
2764{
2765  global $conf;
2766
[8126]2767  if (!is_admin())
[6049]2768  {
2769    return new PwgError(401, 'Access denied');
2770  }
2771
[8249]2772  include_once(PHPWG_ROOT_PATH.'admin/include/functions_upload.inc.php');
[6051]2773  $ret['message'] = ready_for_upload_message();
2774  $ret['ready_for_upload'] = true;
[11893]2775
[6051]2776  if (!empty($ret['message']))
2777  {
2778    $ret['ready_for_upload'] = false;
2779  }
[11893]2780
[6051]2781  return $ret;
2782}
[8273]2783
2784function ws_plugins_getList($params, &$service)
2785{
2786  global $conf;
[11893]2787
[8273]2788  if (!is_admin())
2789  {
2790    return new PwgError(401, 'Access denied');
2791  }
2792
2793  include_once(PHPWG_ROOT_PATH.'admin/include/plugins.class.php');
2794  $plugins = new plugins();
2795  $plugins->sort_fs_plugins('name');
2796  $plugin_list = array();
2797
2798  foreach($plugins->fs_plugins as $plugin_id => $fs_plugin)
2799  {
2800    if (isset($plugins->db_plugins_by_id[$plugin_id]))
2801    {
2802      $state = $plugins->db_plugins_by_id[$plugin_id]['state'];
2803    }
2804    else
2805    {
2806      $state = 'uninstalled';
2807    }
2808
2809    array_push(
2810      $plugin_list,
2811      array(
2812        'id' => $plugin_id,
2813        'name' => $fs_plugin['name'],
2814        'version' => $fs_plugin['version'],
2815        'state' => $state,
2816        'description' => $fs_plugin['description'],
2817        )
2818      );
2819  }
2820
2821  return $plugin_list;
2822}
2823
2824function ws_plugins_performAction($params, &$service)
2825{
2826  global $template;
[11893]2827
[8273]2828  if (!is_admin())
2829  {
2830    return new PwgError(401, 'Access denied');
2831  }
2832
2833  if (empty($params['pwg_token']) or get_pwg_token() != $params['pwg_token'])
2834  {
2835    return new PwgError(403, 'Invalid security token');
2836  }
2837
2838  define('IN_ADMIN', true);
2839  include_once(PHPWG_ROOT_PATH.'admin/include/plugins.class.php');
2840  $plugins = new plugins();
2841  $errors = $plugins->perform_action($params['action'], $params['plugin']);
2842
[11893]2843
[8273]2844  if (!empty($errors))
2845  {
2846    return new PwgError(500, $errors);
2847  }
2848  else
2849  {
2850    if (in_array($params['action'], array('activate', 'deactivate')))
2851    {
2852      $template->delete_compiled_templates();
2853    }
2854    return true;
2855  }
2856}
2857
[8297]2858function ws_themes_performAction($params, &$service)
2859{
2860  global $template;
[11893]2861
[8726]2862  if (!is_admin())
[8297]2863  {
2864    return new PwgError(401, 'Access denied');
2865  }
2866
2867  if (empty($params['pwg_token']) or get_pwg_token() != $params['pwg_token'])
2868  {
2869    return new PwgError(403, 'Invalid security token');
2870  }
2871
2872  define('IN_ADMIN', true);
2873  include_once(PHPWG_ROOT_PATH.'admin/include/themes.class.php');
2874  $themes = new themes();
2875  $errors = $themes->perform_action($params['action'], $params['theme']);
[11893]2876
[8297]2877  if (!empty($errors))
2878  {
2879    return new PwgError(500, $errors);
2880  }
2881  else
2882  {
2883    if (in_array($params['action'], array('activate', 'deactivate')))
2884    {
2885      $template->delete_compiled_templates();
2886    }
2887    return true;
2888  }
2889}
[10235]2890
[10686]2891function ws_images_resizethumbnail($params, &$service)
[10235]2892{
2893  if (!is_admin())
2894  {
2895    return new PwgError(401, 'Access denied');
2896  }
2897
[10563]2898  if (empty($params['image_id']) and empty($params['image_path']))
2899  {
2900    return new PwgError(403, "image_id or image_path is missing");
2901  }
2902
2903  include_once(PHPWG_ROOT_PATH.'admin/include/functions_upload.inc.php');
[10641]2904  include_once(PHPWG_ROOT_PATH.'admin/include/image.class.php');
[10563]2905
2906  if (!empty($params['image_id']))
2907  {
2908    $query='
[10235]2909SELECT id, path, tn_ext, has_high
[10563]2910  FROM '.IMAGES_TABLE.'
2911  WHERE id = '.(int)$params['image_id'].'
[10235]2912;';
[10563]2913    $image = pwg_db_fetch_assoc(pwg_query($query));
[10235]2914
[10563]2915    if ($image == null)
2916    {
2917      return new PwgError(403, "image_id not found");
2918    }
2919
2920    $image_path = $image['path'];
2921    $thumb_path = get_thumbnail_path($image);
2922  }
2923  else
[10235]2924  {
[10563]2925    $image_path = $params['image_path'];
2926    $thumb_path = file_path_for_type($image_path, 'thumb');
[10235]2927  }
2928
[10686]2929  if (!file_exists($image_path) or !is_valid_image_extension(get_extension($image_path)))
[10235]2930  {
2931    return new PwgError(403, "image can't be resized");
2932  }
2933
[10563]2934  $result = false;
[10686]2935  prepare_directory(dirname($thumb_path));
2936  $img = new pwg_image($image_path, $params['library']);
[10563]2937
[10686]2938  $result =  $img->pwg_resize(
2939    $thumb_path,
2940    $params['maxwidth'],
2941    $params['maxheight'],
2942    $params['quality'],
2943    false, // automatic rotation is not needed for thumbnails.
2944    true, // strip metadata
2945    get_boolean($params['crop']),
2946    get_boolean($params['follow_orientation'])
2947  );
2948
2949  $img->destroy();
2950  return $result;
2951}
2952
2953function ws_images_resizewebsize($params, &$service)
2954{
2955  if (!is_admin())
[10235]2956  {
[10686]2957    return new PwgError(401, 'Access denied');
2958  }
[10563]2959
[10686]2960  include_once(PHPWG_ROOT_PATH.'include/functions_picture.inc.php');
2961  include_once(PHPWG_ROOT_PATH.'admin/include/functions_upload.inc.php');
2962  include_once(PHPWG_ROOT_PATH.'admin/include/image.class.php');
[10641]2963
[10686]2964  $query='
2965SELECT id, path, tn_ext, has_high
2966  FROM '.IMAGES_TABLE.'
2967  WHERE id = '.(int)$params['image_id'].'
2968;';
2969  $image = pwg_db_fetch_assoc(pwg_query($query));
[10641]2970
[10686]2971  if ($image == null)
2972  {
2973    return new PwgError(403, "image_id not found");
[10235]2974  }
[10686]2975
2976  $image_path = $image['path'];
2977  $hd_path = get_high_path($image);
2978
2979  if (empty($image['has_high']) or !file_exists($hd_path) or !is_valid_image_extension(get_extension($image_path)))
[10235]2980  {
[10686]2981    return new PwgError(403, "image can't be resized");
2982  }
[10641]2983
[10686]2984  $result = false;
[10747]2985  $img = new pwg_image($hd_path, $params['library']);
[10454]2986
[10686]2987  $result = $img->pwg_resize(
2988    $image_path,
2989    $params['maxwidth'],
2990    $params['maxheight'],
2991    $params['quality'],
2992    $params['automatic_rotation'],
2993    false // strip metadata
2994    );
[10641]2995
[10686]2996  $img->destroy();
2997
2998  global $conf;
2999  $conf['use_exif'] = false;
3000  $conf['use_iptc'] = false;
3001  update_metadata(array($image['id'] => $image['path']));
3002
[10563]3003  return $result;
[10235]3004}
[10511]3005
3006function ws_extensions_update($params, &$service)
3007{
3008  if (!is_webmaster())
3009  {
3010    return new PwgError(401, l10n('Webmaster status is required.'));
3011  }
3012
3013  if (empty($params['pwg_token']) or get_pwg_token() != $params['pwg_token'])
3014  {
3015    return new PwgError(403, 'Invalid security token');
3016  }
3017
3018  if (empty($params['type']) or !in_array($params['type'], array('plugins', 'themes', 'languages')))
3019  {
3020    return new PwgError(403, "invalid extension type");
3021  }
3022
3023  if (empty($params['id']) or empty($params['revision']))
3024  {
3025    return new PwgError(null, 'Wrong parameters');
3026  }
3027
3028  include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
3029  include_once(PHPWG_ROOT_PATH.'admin/include/'.$params['type'].'.class.php');
3030
3031  $type = $params['type'];
3032  $extension_id = $params['id'];
3033  $revision = $params['revision'];
3034
3035  $extension = new $type();
3036
3037  if ($type == 'plugins')
3038  {
3039    if (isset($extension->db_plugins_by_id[$extension_id]) and $extension->db_plugins_by_id[$extension_id]['state'] == 'active')
3040    {
3041      $extension->perform_action('deactivate', $extension_id);
3042
3043      redirect(PHPWG_ROOT_PATH
3044        . 'ws.php'
3045        . '?method=pwg.extensions.update'
3046        . '&type=plugins'
3047        . '&id=' . $extension_id
3048        . '&revision=' . $revision
3049        . '&reactivate=true'
3050        . '&pwg_token=' . get_pwg_token()
3051        . '&format=json'
3052      );
3053    }
[11893]3054
[10511]3055    $upgrade_status = $extension->extract_plugin_files('upgrade', $revision, $extension_id);
3056    $extension_name = $extension->fs_plugins[$extension_id]['name'];
3057
3058    if (isset($params['reactivate']))
3059    {
3060      $extension->perform_action('activate', $extension_id);
3061    }
3062  }
3063  elseif ($type == 'themes')
3064  {
3065    $upgrade_status = $extension->extract_theme_files('upgrade', $revision, $extension_id);
3066    $extension_name = $extension->fs_themes[$extension_id]['name'];
3067  }
3068  elseif ($type == 'languages')
3069  {
3070    $upgrade_status = $extension->extract_language_files('upgrade', $revision, $extension_id);
3071    $extension_name = $extension->fs_languages[$extension_id]['name'];
3072  }
3073
3074  global $template;
3075  $template->delete_compiled_templates();
3076
3077  switch ($upgrade_status)
3078  {
3079    case 'ok':
3080      return sprintf(l10n('%s has been successfully updated.'), $extension_name);
3081
3082    case 'temp_path_error':
3083      return new PwgError(null, l10n('Can\'t create temporary file.'));
3084
3085    case 'dl_archive_error':
3086      return new PwgError(null, l10n('Can\'t download archive.'));
3087
3088    case 'archive_error':
3089      return new PwgError(null, l10n('Can\'t read or extract archive.'));
3090
3091    default:
3092      return new PwgError(null, sprintf(l10n('An error occured during extraction (%s).'), $upgrade_status));
3093  }
3094}
3095
3096function ws_extensions_ignoreupdate($params, &$service)
3097{
3098  global $conf;
3099
3100  define('IN_ADMIN', true);
3101  include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
3102
3103  if (!is_webmaster())
3104  {
3105    return new PwgError(401, 'Access denied');
3106  }
3107
3108  if (empty($params['pwg_token']) or get_pwg_token() != $params['pwg_token'])
3109  {
3110    return new PwgError(403, 'Invalid security token');
3111  }
3112
3113  $conf['updates_ignored'] = unserialize($conf['updates_ignored']);
3114
[10538]3115  // Reset ignored extension
[10511]3116  if ($params['reset'])
3117  {
[10596]3118    if (!empty($params['type']) and isset($conf['updates_ignored'][$params['type']]))
3119    {
3120      $conf['updates_ignored'][$params['type']] = array();
3121    }
3122    else
3123    {
3124      $conf['updates_ignored'] = array(
3125        'plugins'=>array(),
3126        'themes'=>array(),
3127        'languages'=>array()
3128      );
3129    }
[10511]3130    conf_update_param('updates_ignored', pwg_db_real_escape_string(serialize($conf['updates_ignored'])));
3131    unset($_SESSION['extensions_need_update']);
3132    return true;
3133  }
3134
3135  if (empty($params['id']) or empty($params['type']) or !in_array($params['type'], array('plugins', 'themes', 'languages')))
3136  {
3137    return new PwgError(403, 'Invalid parameters');
3138  }
3139
3140  // Add or remove extension from ignore list
3141  if (!in_array($params['id'], $conf['updates_ignored'][$params['type']]))
3142  {
3143    array_push($conf['updates_ignored'][$params['type']], $params['id']);
3144  }
3145  conf_update_param('updates_ignored', pwg_db_real_escape_string(serialize($conf['updates_ignored'])));
3146  unset($_SESSION['extensions_need_update']);
3147  return true;
3148}
[10538]3149
3150function ws_extensions_checkupdates($params, &$service)
3151{
3152  global $conf;
3153
3154  define('IN_ADMIN', true);
3155  include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
3156  include_once(PHPWG_ROOT_PATH.'admin/include/updates.class.php');
3157  $update = new updates();
3158
3159  if (!is_admin())
3160  {
3161    return new PwgError(401, 'Access denied');
3162  }
3163
3164  $result = array();
3165
3166  if (!isset($_SESSION['need_update']))
3167    $update->check_piwigo_upgrade();
3168
3169  $result['piwigo_need_update'] = $_SESSION['need_update'];
3170
3171  $conf['updates_ignored'] = unserialize($conf['updates_ignored']);
3172
3173  if (!isset($_SESSION['extensions_need_update']))
3174    $update->check_extensions();
3175  else
3176    $update->check_updated_extensions();
3177
3178  if (!is_array($_SESSION['extensions_need_update']))
3179    $result['ext_need_update'] = null;
3180  else
3181    $result['ext_need_update'] = !empty($_SESSION['extensions_need_update']);
3182
3183  return $result;
3184}
[11893]3185?>
Note: See TracBrowser for help on using the repository browser.