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

Last change on this file since 2496 was 2496, checked in by rvelices, 16 years ago
  • remove hello_world plugin (not working anymore)
  • web service method images.add works only for admins now
  • fix template-common js web service calls did not have the parameters url encoded
  • improve admin user_list - submitting the form with no user selected triggers a javascript alert (had fun with jquery selectors)
  • Property svn:eol-style set to LF
  • Property svn:keywords set to Author Date Id Revision
File size: 34.2 KB
Line 
1<?php
2// +-----------------------------------------------------------------------+
3// | Piwigo - a PHP based picture gallery                                  |
4// +-----------------------------------------------------------------------+
5// | Copyright(C) 2008      Piwigo Team                  http://piwigo.org |
6// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
7// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
8// +-----------------------------------------------------------------------+
9// | This program is free software; you can redistribute it and/or modify  |
10// | it under the terms of the GNU General Public License as published by  |
11// | the Free Software Foundation                                          |
12// |                                                                       |
13// | This program is distributed in the hope that it will be useful, but   |
14// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
15// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
16// | General Public License for more details.                              |
17// |                                                                       |
18// | You should have received a copy of the GNU General Public License     |
19// | along with this program; if not, write to the Free Software           |
20// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
21// | USA.                                                                  |
22// +-----------------------------------------------------------------------+
23
24/**** IMPLEMENTATION OF WEB SERVICE METHODS ***********************************/
25
26/**
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{
32  global $conf, $calling_partner_id;
33
34  if ( strpos($methodName,'reflection.')===0 )
35  { // OK for reflection
36    return $res;
37  }
38
39  if ( !is_autorize_status(ACCESS_GUEST) and
40      strpos($methodName,'pwg.session.')!==0 )
41  {
42    return new PwgError(401, 'Access denied');
43  }
44
45  if ( !$conf['ws_access_control'] )
46  {
47    return $res; // No controls are requested
48  }
49  $query = '
50SELECT * FROM '.WEB_SERVICES_ACCESS_TABLE."
51 WHERE `name` = '$calling_partner_id'
52   AND NOW() <= end; ";
53  $result = pwg_query($query);
54  $row = mysql_fetch_assoc($result);
55  if ( empty($row) )
56  {
57    return new PwgError(403, 'Partner id does not exist or is expired');
58  }
59  if ( !empty($row['request'])
60      and strpos($methodName, $row['request'])==false
61      and strpos($methodName, 'session')==false
62      and strpos($methodName, 'getVersion')==false )
63  { // session and getVersion are allowed to diagnose any failure reason
64    return new PwgError(403, 'Method not allowed');
65  }
66
67  return $res;
68}
69
70/**
71 * ws_addControls
72 * returns additionnal controls if requested
73 * usable for 99% of Web Service methods
74 *
75 * - Args
76 * $methodName: is the requested method
77 * $partner: is the key
78 * $tbl_name: is the alias_name in the query (sometimes called correlation name)
79 *            null if !getting picture informations
80 * - Logic
81 * Access_control is not active: Return
82 * Key is incorrect: Return 0 = 1 (False condition for MySQL)
83 * One of Params doesn't match with type of request: return 0 = 1 again
84 * Access list(id/cat/tag) is converted in expended image-id list
85 * image-id list: converted to an in-where-clause
86 *
87 * The additionnal in-where-clause is return
88 */
89function ws_addControls( $methodName, &$params, $tbl_name )
90{
91  global $conf, $calling_partner_id;
92  if ( !$conf['ws_access_control'] or !isset($calling_partner_id) )
93  {
94    return '1=1'; // No controls are requested
95  }
96
97// Is it an active Partner?
98  $query = '
99SELECT * FROM '.WEB_SERVICES_ACCESS_TABLE."
100 WHERE `name` = '$calling_partner_id'
101   AND NOW() <= end; ";
102$result = pwg_query($query);
103  if ( mysql_num_rows( $result ) == 0 )
104  {
105    return '0=1'; // Unknown partner or Obsolate agreement
106  }
107
108  $row = mysql_fetch_array($result);
109
110// Overide general object limit
111  $params['per_page'] = $row['limit'];
112
113// Target restrict
114// 3 cases: list, cat or tag
115// Behind / we could found img-ids, cat-ids or tag-ids
116  $target = $row['access'];
117  if ( $target == '')
118  {
119    return '1=1'; // No controls are requested
120  }
121  list($type, $str_ids) = explode('/',$target); // Find type list
122
123// (array) 1,2,21,3,22,4,5,9-12,6,11,12,13,2,4,6,
124  $arr_ids = expand_id_list( explode( ',',$str_ids ) );
125  $addings = implode(',', $arr_ids);
126// (string) 1,2,3,4,5,6,9,10,11,12,13,21,22,
127  if ( $type == 'list')
128  {
129    return $tbl_name . 'id IN ( ' . $addings . ' ) ';
130  }
131
132  if ( $type == 'cat' )
133  {
134    $addings = implode(',', get_image_ids_for_cats($arr_ids));
135    return $tbl_name . 'id IN ( ' . $addings . ' ) ';
136  }
137
138  if ( $type == 'tag' )
139  {
140    $addings = implode(',', get_image_ids_for_tags($arr_ids, 'OR'));
141    return $tbl_name . 'id IN ( ' . $addings . ' ) ';
142  }
143  // Unmanaged new type?
144  return ' 0 = 1 '; // ???
145}
146
147/**
148 * returns a "standard" (for our web service) array of sql where clauses that
149 * filters the images (images table only)
150 */
151function ws_std_image_sql_filter( $params, $tbl_name='' )
152{
153  $clauses = array();
154  if ( is_numeric($params['f_min_rate']) )
155  {
156    $clauses[] = $tbl_name.'average_rate>'.$params['f_min_rate'];
157  }
158  if ( is_numeric($params['f_max_rate']) )
159  {
160    $clauses[] = $tbl_name.'average_rate<='.$params['f_max_rate'];
161  }
162  if ( is_numeric($params['f_min_hit']) )
163  {
164    $clauses[] = $tbl_name.'hit>'.$params['f_min_hit'];
165  }
166  if ( is_numeric($params['f_max_hit']) )
167  {
168    $clauses[] = $tbl_name.'hit<='.$params['f_max_hit'];
169  }
170  if ( isset($params['f_min_date_posted']) )
171  {
172    $clauses[] = $tbl_name."date_available>='".$params['f_min_date_posted']."'";
173  }
174  if ( isset($params['f_max_date_posted']) )
175  {
176    $clauses[] = $tbl_name."date_available<'".$params['f_max_date_posted']."'";
177  }
178  if ( isset($params['f_min_date_created']) )
179  {
180    $clauses[] = $tbl_name."date_creation>='".$params['f_min_date_created']."'";
181  }
182  if ( isset($params['f_max_date_created']) )
183  {
184    $clauses[] = $tbl_name."date_creation<'".$params['f_max_date_created']."'";
185  }
186  if ( is_numeric($params['f_min_ratio']) )
187  {
188    $clauses[] = $tbl_name.'width/'.$tbl_name.'height>'.$params['f_min_ratio'];
189  }
190  if ( is_numeric($params['f_max_ratio']) )
191  {
192    $clauses[] = $tbl_name.'width/'.$tbl_name.'height<='.$params['f_max_ratio'];
193  }
194  if ( $params['f_with_thumbnail'] )
195  {
196    $clauses[] = $tbl_name.'tn_ext IS NOT NULL';
197  }
198  return $clauses;
199}
200
201/**
202 * returns a "standard" (for our web service) ORDER BY sql clause for images
203 */
204function ws_std_image_sql_order( $params, $tbl_name='' )
205{
206  $ret = '';
207  if ( empty($params['order']) )
208  {
209    return $ret;
210  }
211  $matches = array();
212  preg_match_all('/([a-z_]+) *(?:(asc|desc)(?:ending)?)? *(?:, *|$)/i',
213    $params['order'], $matches);
214  for ($i=0; $i<count($matches[1]); $i++)
215  {
216    switch ($matches[1][$i])
217    {
218      case 'date_created':
219        $matches[1][$i] = 'date_creation'; break;
220      case 'date_posted':
221        $matches[1][$i] = 'date_available'; break;
222      case 'rand': case 'random':
223        $matches[1][$i] = 'RAND()'; break;
224    }
225    $sortable_fields = array('id', 'file', 'name', 'hit', 'average_rate',
226      'date_creation', 'date_available', 'RAND()' );
227    if ( in_array($matches[1][$i], $sortable_fields) )
228    {
229      if (!empty($ret))
230        $ret .= ', ';
231      if ($matches[1][$i] != 'RAND()' )
232      {
233        $ret .= $tbl_name;
234      }
235      $ret .= $matches[1][$i];
236      $ret .= ' '.$matches[2][$i];
237    }
238  }
239  return $ret;
240}
241
242/**
243 * returns an array map of urls (thumb/element) for image_row - to be returned
244 * in a standard way by different web service methods
245 */
246function ws_std_get_urls($image_row)
247{
248  $ret = array(
249    'tn_url' => get_thumbnail_url($image_row),
250    'element_url' => get_element_url($image_row)
251  );
252  global $user;
253  if ($user['enabled_high'] and $image_row['has_high'] )
254  {
255    $ret['high_url'] = get_high_url($image_row);
256  }
257  return $ret;
258}
259
260/**
261 * returns an array of image attributes that are to be encoded as xml attributes
262 * instead of xml elements
263 */
264function ws_std_get_image_xml_attributes()
265{
266  return array(
267    'id','tn_url','element_url','high_url', 'file','width','height','hit'
268    );
269}
270
271/**
272 * returns PWG version (web service method)
273 */
274function ws_getVersion($params, &$service)
275{
276  global $conf;
277  if ($conf['show_version'])
278    return PHPWG_VERSION;
279  else
280    return new PwgError(403, 'Forbidden');
281}
282
283function ws_caddie_add($params, &$service)
284{
285  if (!is_admin())
286  {
287    return new PwgError(401, 'Access denied');
288  }
289  if ( empty($params['image_id']) )
290  {
291    return new PwgError(WS_ERR_INVALID_PARAM, "Invalid image_id");
292  }
293  global $user;
294  $query = '
295SELECT id
296  FROM '.IMAGES_TABLE.' LEFT JOIN '.CADDIE_TABLE.' ON id=element_id AND user_id='.$user['id'].'
297  WHERE id IN ('.implode(',',$params['image_id']).')
298    AND element_id IS NULL';
299  $datas = array();
300  foreach ( array_from_query($query, 'id') as $id )
301  {
302    array_push($datas, array('element_id'=>$id, 'user_id'=>$user['id']) );
303  }
304  if (count($datas))
305  {
306    include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
307    mass_inserts(CADDIE_TABLE, array('element_id','user_id'), $datas);
308  }
309  return count($datas);
310}
311
312/**
313 * returns images per category (web service method)
314 */
315function ws_categories_getImages($params, &$service)
316{
317  @include_once(PHPWG_ROOT_PATH.'include/functions_picture.inc.php');
318  global $user, $conf;
319
320  $images = array();
321
322  //------------------------------------------------- get the related categories
323  $where_clauses = array();
324  foreach($params['cat_id'] as $cat_id)
325  {
326    $cat_id = (int)$cat_id;
327    if ($cat_id<=0)
328      continue;
329    if ($params['recursive'])
330    {
331      $where_clauses[] = 'uppercats REGEXP \'(^|,)'.$cat_id.'(,|$)\'';
332    }
333    else
334    {
335      $where_clauses[] = 'id='.$cat_id;
336    }
337  }
338  if (!empty($where_clauses))
339  {
340    $where_clauses = array( '('.
341    implode('
342    OR ', $where_clauses) . ')'
343      );
344  }
345  $where_clauses[] = get_sql_condition_FandF(
346        array('forbidden_categories' => 'id'),
347        NULL, true
348      );
349
350  $query = '
351SELECT id, name, permalink, image_order
352  FROM '.CATEGORIES_TABLE.'
353  WHERE '. implode('
354    AND ', $where_clauses);
355  $result = pwg_query($query);
356  $cats = array();
357  while ($row = mysql_fetch_assoc($result))
358  {
359    $row['id'] = (int)$row['id'];
360    $cats[ $row['id'] ] = $row;
361  }
362
363  //-------------------------------------------------------- get the images
364  if ( !empty($cats) )
365  {
366    $where_clauses = ws_std_image_sql_filter( $params, 'i.' );
367    $where_clauses[] = 'category_id IN ('
368      .implode(',', array_keys($cats) )
369      .')';
370    $where_clauses[] = get_sql_condition_FandF( array(
371          'visible_images' => 'i.id'
372        ), null, true
373      );
374    $where_clauses[] = ws_addControls( 'categories.getImages', $params, 'i.' );
375
376    $order_by = ws_std_image_sql_order($params, 'i.');
377    if ( empty($order_by)
378          and count($params['cat_id'])==1
379          and isset($cats[ $params['cat_id'][0] ]['image_order'])
380        )
381    {
382      $order_by = $cats[ $params['cat_id'][0] ]['image_order'];
383    }
384    $order_by = empty($order_by) ? $conf['order_by'] : 'ORDER BY '.$order_by;
385
386    $query = '
387SELECT i.*, GROUP_CONCAT(category_id) cat_ids
388  FROM '.IMAGES_TABLE.' i
389    INNER JOIN '.IMAGE_CATEGORY_TABLE.' ON i.id=image_id
390  WHERE '. implode('
391    AND ', $where_clauses).'
392GROUP BY i.id
393'.$order_by.'
394LIMIT '.$params['per_page']*$params['page'].','.$params['per_page'];
395
396    $result = pwg_query($query);
397    while ($row = mysql_fetch_assoc($result))
398    {
399      $image = array();
400      foreach ( array('id', 'width', 'height', 'hit') as $k )
401      {
402        if (isset($row[$k]))
403        {
404          $image[$k] = (int)$row[$k];
405        }
406      }
407      foreach ( array('file', 'name', 'comment') as $k )
408      {
409        $image[$k] = $row[$k];
410      }
411      $image = array_merge( $image, ws_std_get_urls($row) );
412
413      $image_cats = array();
414      foreach ( explode(',', $row['cat_ids']) as $cat_id )
415      {
416        $url = make_index_url(
417                array(
418                  'category' => $cats[$cat_id],
419                  )
420                );
421        $page_url = make_picture_url(
422                array(
423                  'category' => $cats[$cat_id],
424                  'image_id' => $row['id'],
425                  'image_file' => $row['file'],
426                  )
427                );
428        array_push( $image_cats,  array(
429              WS_XML_ATTRIBUTES => array (
430                  'id' => (int)$cat_id,
431                  'url' => $url,
432                  'page_url' => $page_url,
433                )
434            )
435          );
436      }
437
438      $image['categories'] = new PwgNamedArray(
439            $image_cats,'category', array('id','url','page_url')
440          );
441      array_push($images, $image);
442    }
443  }
444
445  return array( 'images' =>
446    array (
447      WS_XML_ATTRIBUTES =>
448        array(
449            'page' => $params['page'],
450            'per_page' => $params['per_page'],
451            'count' => count($images)
452          ),
453       WS_XML_CONTENT => new PwgNamedArray($images, 'image',
454          ws_std_get_image_xml_attributes() )
455      )
456    );
457}
458
459
460/**
461 * returns a list of categories (web service method)
462 */
463function ws_categories_getList($params, &$service)
464{
465  global $user,$conf;
466
467  $where = array();
468
469  if (!$params['recursive'])
470  {
471    if ($params['cat_id']>0)
472      $where[] = '(id_uppercat='.(int)($params['cat_id']).'
473    OR id='.(int)($params['cat_id']).')';
474    else
475      $where[] = 'id_uppercat IS NULL';
476  }
477  else if ($params['cat_id']>0)
478  {
479    $where[] = 'uppercats REGEXP \'(^|,)'.
480      (int)($params['cat_id'])
481      .'(,|$)\'';
482  }
483
484  if ($params['public'])
485  {
486    $where[] = 'status = "public"';
487    $where[] = 'visible = "true"';
488    $where[]= 'user_id='.$conf['guest_id'];
489  }
490  else
491  {
492    $where[]= 'user_id='.$user['id'];
493  }
494
495  $query = '
496SELECT id, name, permalink, uppercats, global_rank,
497    nb_images, count_images AS total_nb_images,
498    date_last, max_date_last, count_categories AS nb_categories
499  FROM '.CATEGORIES_TABLE.'
500   INNER JOIN '.USER_CACHE_CATEGORIES_TABLE.' ON id=cat_id
501  WHERE '. implode('
502    AND ', $where);
503
504  $result = pwg_query($query);
505
506  $cats = array();
507  while ($row = mysql_fetch_assoc($result))
508  {
509    $row['url'] = make_index_url(
510        array(
511          'category' => $row
512          )
513      );
514    foreach( array('id','nb_images','total_nb_images','nb_categories') as $key)
515    {
516      $row[$key] = (int)$row[$key];
517    }
518    array_push($cats, $row);
519  }
520  usort($cats, 'global_rank_compare');
521  return array(
522      'categories' =>
523          new PwgNamedArray($cats,'category',
524            array('id','url','nb_images','total_nb_images','nb_categories','date_last','max_date_last')
525          )
526    );
527}
528
529
530/**
531 * returns detailed information for an element (web service method)
532 */
533function ws_images_addComment($params, &$service)
534{
535  if (!$service->isPost())
536  {
537    return new PwgError(405, "This method requires HTTP POST");
538  }
539  $params['image_id'] = (int)$params['image_id'];
540  $query = '
541SELECT DISTINCT image_id
542  FROM '.IMAGE_CATEGORY_TABLE.' INNER JOIN '.CATEGORIES_TABLE.' ON category_id=id
543  WHERE commentable="true"
544    AND image_id='.$params['image_id'].
545    get_sql_condition_FandF(
546      array(
547        'forbidden_categories' => 'id',
548        'visible_categories' => 'id',
549        'visible_images' => 'image_id'
550      ),
551      ' AND'
552    );
553  if ( !mysql_num_rows( pwg_query( $query ) ) )
554  {
555    return new PwgError(WS_ERR_INVALID_PARAM, "Invalid image_id");
556  }
557
558  include_once(PHPWG_ROOT_PATH.'include/functions_comment.inc.php');
559
560  $comm = array(
561    'author' => trim( stripslashes($params['author']) ),
562    'content' => trim( stripslashes($params['content']) ),
563    'image_id' => $params['image_id'],
564   );
565
566  include_once(PHPWG_ROOT_PATH.'include/functions_comment.inc.php');
567
568  $comment_action = insert_user_comment(
569      $comm, $params['key'], $infos
570    );
571
572  switch ($comment_action)
573  {
574    case 'reject':
575      array_push($infos, l10n('comment_not_added') );
576      return new PwgError(403, implode("\n", $infos) );
577    case 'validate':
578    case 'moderate':
579      $ret = array(
580          'id' => $comm['id'],
581          'validation' => $comment_action=='validate',
582        );
583      return new PwgNamedStruct(
584          'comment',
585          $ret,
586          null, array()
587        );
588    default:
589      return new PwgError(500, "Unknown comment action ".$comment_action );
590  }
591}
592
593/**
594 * returns detailed information for an element (web service method)
595 */
596function ws_images_getInfo($params, &$service)
597{
598  @include_once(PHPWG_ROOT_PATH.'include/functions_picture.inc.php');
599  global $user, $conf;
600  $params['image_id'] = (int)$params['image_id'];
601  if ( $params['image_id']<=0 )
602  {
603    return new PwgError(WS_ERR_INVALID_PARAM, "Invalid image_id");
604  }
605
606  $query='
607SELECT * FROM '.IMAGES_TABLE.'
608  WHERE id='.$params['image_id'].
609    get_sql_condition_FandF(
610      array('visible_images' => 'id'),
611      ' AND'
612    ).' AND '.
613    ws_addControls( 'images.getInfo', $params, '' ).'
614LIMIT 1;';
615
616  $image_row = mysql_fetch_assoc(pwg_query($query));
617  if ($image_row==null)
618  {
619    return new PwgError(404, "image_id not found");
620  }
621  $image_row = array_merge( $image_row, ws_std_get_urls($image_row) );
622
623  //-------------------------------------------------------- related categories
624  $query = '
625SELECT id, name, permalink, uppercats, global_rank, commentable
626  FROM '.IMAGE_CATEGORY_TABLE.'
627    INNER JOIN '.CATEGORIES_TABLE.' ON category_id = id
628  WHERE image_id = '.$image_row['id'].
629  get_sql_condition_FandF(
630      array( 'forbidden_categories' => 'category_id' ),
631      ' AND'
632    ).'
633;';
634  $result = pwg_query($query);
635  $is_commentable = false;
636  $related_categories = array();
637  while ($row = mysql_fetch_assoc($result))
638  {
639    if ($row['commentable']=='true')
640    {
641      $is_commentable = true;
642    }
643    unset($row['commentable']);
644    $row['url'] = make_index_url(
645        array(
646          'category' => $row
647          )
648      );
649
650    $row['page_url'] = make_picture_url(
651        array(
652          'image_id' => $image_row['id'],
653          'image_file' => $image_row['file'],
654          'category' => $row
655          )
656      );
657    $row['id']=(int)$row['id'];
658    array_push($related_categories, $row);
659  }
660  usort($related_categories, 'global_rank_compare');
661  if ( empty($related_categories) )
662  {
663    return new PwgError(401, 'Access denied');
664  }
665
666  //-------------------------------------------------------------- related tags
667  $related_tags = get_common_tags( array($image_row['id']), -1 );
668  foreach( $related_tags as $i=>$tag)
669  {
670    $tag['url'] = make_index_url(
671        array(
672          'tags' => array($tag)
673          )
674      );
675    $tag['page_url'] = make_picture_url(
676        array(
677          'image_id' => $image_row['id'],
678          'image_file' => $image_row['file'],
679          'tags' => array($tag),
680          )
681      );
682    unset($tag['counter']);
683    $tag['id']=(int)$tag['id'];
684    $related_tags[$i]=$tag;
685  }
686  //------------------------------------------------------------- related rates
687  $query = '
688SELECT COUNT(rate) AS count
689     , ROUND(AVG(rate),2) AS average
690     , ROUND(STD(rate),2) AS stdev
691  FROM '.RATE_TABLE.'
692  WHERE element_id = '.$image_row['id'].'
693;';
694  $rating = mysql_fetch_assoc(pwg_query($query));
695  $rating['count'] = (int)$rating['count'];
696
697  //---------------------------------------------------------- related comments
698  $related_comments = array();
699
700  $where_comments = 'image_id = '.$image_row['id'];
701  if ( !is_admin() )
702  {
703    $where_comments .= '
704    AND validated="true"';
705  }
706
707  $query = '
708SELECT COUNT(id) nb_comments
709  FROM '.COMMENTS_TABLE.'
710  WHERE '.$where_comments;
711  list($nb_comments) = array_from_query($query, 'nb_comments');
712  $nb_comments = (int)$nb_comments;
713
714  if ( $nb_comments>0 and $params['comments_per_page']>0 )
715  {
716    $query = '
717SELECT id, date, author, content
718  FROM '.COMMENTS_TABLE.'
719  WHERE '.$where_comments.'
720  ORDER BY date
721  LIMIT '.$params['comments_per_page']*(int)$params['comments_page'].
722    ','.$params['comments_per_page'];
723
724    $result = pwg_query($query);
725    while ($row = mysql_fetch_assoc($result))
726    {
727      $row['id']=(int)$row['id'];
728      array_push($related_comments, $row);
729    }
730  }
731
732  $comment_post_data = null;
733  if ($is_commentable and
734      (!is_a_guest()
735        or (is_a_guest() and $conf['comments_forall'] )
736      )
737      )
738  {
739    include_once(PHPWG_ROOT_PATH.'include/functions_comment.inc.php');
740    $comment_post_data['author'] = $user['username'];
741    $comment_post_data['key'] = get_comment_post_key($params['image_id']);
742  }
743
744  $ret = $image_row;
745  foreach ( array('id','width','height','hit','filesize') as $k )
746  {
747    if (isset($ret[$k]))
748    {
749      $ret[$k] = (int)$ret[$k];
750    }
751  }
752  foreach ( array('path', 'storage_category_id') as $k )
753  {
754    unset($ret[$k]);
755  }
756
757  $ret['rates'] = array( WS_XML_ATTRIBUTES => $rating );
758  $ret['categories'] = new PwgNamedArray($related_categories, 'category', array('id','url', 'page_url') );
759  $ret['tags'] = new PwgNamedArray($related_tags, 'tag', array('id','url_name','url','page_url') );
760  if ( isset($comment_post_data) )
761  {
762    $ret['comment_post'] = array( WS_XML_ATTRIBUTES => $comment_post_data );
763  }
764  $ret['comments'] = array(
765     WS_XML_ATTRIBUTES =>
766        array(
767          'page' => $params['comments_page'],
768          'per_page' => $params['comments_per_page'],
769          'count' => count($related_comments),
770          'nb_comments' => $nb_comments,
771        ),
772     WS_XML_CONTENT => new PwgNamedArray($related_comments, 'comment', array('id','date') )
773      );
774
775  return new PwgNamedStruct('image',$ret, null, array('name','comment') );
776}
777
778
779/**
780 * rates the image_id in the parameter
781 */
782function ws_images_Rate($params, &$service)
783{
784  $image_id = (int)$params['image_id'];
785  $query = '
786SELECT DISTINCT id FROM '.IMAGES_TABLE.'
787  INNER JOIN '.IMAGE_CATEGORY_TABLE.' ON id=image_id
788  WHERE id='.$image_id
789  .get_sql_condition_FandF(
790    array(
791        'forbidden_categories' => 'category_id',
792        'forbidden_images' => 'id',
793      ),
794    '    AND'
795    ).'
796    LIMIT 1';
797  if ( mysql_num_rows( pwg_query($query) )==0 )
798  {
799    return new PwgError(404, "Invalid image_id or access denied" );
800  }
801  $rate = (int)$params['rate'];
802  include_once(PHPWG_ROOT_PATH.'include/functions_rate.inc.php');
803  $res = rate_picture( $image_id, $rate );
804  if ($res==false)
805  {
806    global $conf;
807    return new PwgError( 403, "Forbidden or rate not in ". implode(',',$conf['rate_items']));
808  }
809  return $res;
810}
811
812
813/**
814 * returns a list of elements corresponding to a query search
815 */
816function ws_images_search($params, &$service)
817{
818  global $page;
819  $images = array();
820  include_once( PHPWG_ROOT_PATH .'include/functions_search.inc.php' );
821  include_once(PHPWG_ROOT_PATH.'include/functions_picture.inc.php');
822
823  $where_clauses = ws_std_image_sql_filter( $params, 'i.' );
824  $order_by = ws_std_image_sql_order($params, 'i.');
825
826  $super_order_by = false;
827  if ( !empty($order_by) )
828  {
829    global $conf;
830    $conf['order_by'] = 'ORDER BY '.$order_by;
831    $super_order_by=true; // quick_search_result might be faster
832  }
833
834  $search_result = get_quick_search_results($params['query'],
835      $super_order_by,
836      implode(',', $where_clauses)
837    );
838
839  $image_ids = array_slice(
840      $search_result['items'],
841      $params['page']*$params['per_page'],
842      $params['per_page']
843    );
844
845  if ( count($image_ids) )
846  {
847    $query = '
848SELECT * FROM '.IMAGES_TABLE.'
849  WHERE id IN ('.implode(',', $image_ids).')';
850
851    $image_ids = array_flip($image_ids);
852    $result = pwg_query($query);
853    while ($row = mysql_fetch_assoc($result))
854    {
855      $image = array();
856      foreach ( array('id', 'width', 'height', 'hit') as $k )
857      {
858        if (isset($row[$k]))
859        {
860          $image[$k] = (int)$row[$k];
861        }
862      }
863      foreach ( array('file', 'name', 'comment') as $k )
864      {
865        $image[$k] = $row[$k];
866      }
867      $image = array_merge( $image, ws_std_get_urls($row) );
868      $images[$image_ids[$image['id']]] = $image;
869    }
870    ksort($images, SORT_NUMERIC);
871    $images = array_values($images);
872  }
873
874
875  return array( 'images' =>
876    array (
877      WS_XML_ATTRIBUTES =>
878        array(
879            'page' => $params['page'],
880            'per_page' => $params['per_page'],
881            'count' => count($images)
882          ),
883       WS_XML_CONTENT => new PwgNamedArray($images, 'image',
884          ws_std_get_image_xml_attributes() )
885      )
886    );
887}
888
889function ws_images_setPrivacyLevel($params, &$service)
890{
891  if (!is_admin() || is_adviser() )
892  {
893    return new PwgError(401, 'Access denied');
894  }
895  if ( empty($params['image_id']) )
896  {
897    return new PwgError(WS_ERR_INVALID_PARAM, "Invalid image_id");
898  }
899  global $conf;
900  if ( !in_array( (int)$params['level'], $conf['available_permission_levels']) )
901  {
902    return new PwgError(WS_ERR_INVALID_PARAM, "Invalid level");
903  }
904  $query = '
905UPDATE '.IMAGES_TABLE.'
906  SET level='.(int)$params['level'].'
907  WHERE id IN ('.implode(',',$params['image_id']).')';
908  $result = pwg_query($query);
909  $affected_rows = mysql_affected_rows();
910  if ($affected_rows)
911  {
912    include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
913    invalidate_user_cache();
914  }
915  return $affected_rows;
916}
917
918function ws_images_add($params, &$service)
919{
920  global $conf;
921  if (!is_admin() || is_adviser() )
922  {
923    return new PwgError(401, 'Access denied');
924  }
925
926  // name
927  // category_id
928  // file_content
929  // file_sum
930  // thumbnail_content
931  // thumbnail_sum
932
933  // $fh_log = fopen('/tmp/php.log', 'w');
934  // fwrite($fh_log, time()."\n");
935  // fwrite($fh_log, 'input:  '.$params['file_sum']."\n");
936  // fwrite($fh_log, 'input:  '.$params['thumbnail_sum']."\n");
937
938  // current date
939  list($dbnow) = mysql_fetch_row(pwg_query('SELECT NOW();'));
940  list($year, $month, $day) = preg_split('/[^\d]/', $dbnow, 4);
941
942  $upload_dir = sprintf(
943    PHPWG_ROOT_PATH.'upload/%s/%s/%s',
944    $year,
945    $month,
946    $day
947    );
948
949  //fwrite($fh_log, $upload_dir."\n");
950
951  if (!is_dir($upload_dir)) {
952    umask(0000);
953    $recursive = true;
954    mkdir($upload_dir, 0777, $recursive);
955  }
956
957  $date_string = preg_replace('/[^\d]/', '', $dbnow);
958  $random_string = substr($params['file_sum'], 0, 8);
959
960  $filename_wo_ext = $date_string.'-'.$random_string;
961
962  $file_path = $upload_dir.'/'.$filename_wo_ext.'.jpg';
963  $fh_file = fopen($file_path, 'w');
964  fwrite($fh_file, base64_decode($params['file_content']));
965  fclose($fh_file);
966
967  // check dumped file md5sum with expected md5sum
968
969  $thumbnail_dir = $upload_dir.'/thumbnail';
970  if (!is_dir($thumbnail_dir)) {
971    umask(0000);
972    mkdir($thumbnail_dir, 0777);
973  }
974
975  $thumbnail_path = sprintf(
976    '%s/%s%s.%s',
977    $thumbnail_dir,
978    $conf['prefix_thumbnail'],
979    $filename_wo_ext,
980    'jpg'
981    );
982  $fh_thumbnail = fopen($thumbnail_path, 'w');
983  fwrite($fh_thumbnail, base64_decode($params['thumbnail_content']));
984  fclose($fh_thumbnail);
985
986  // check dumped thumbnail md5
987
988  // fwrite($fh_log, 'output: '.md5_file($file_path)."\n");
989  // fwrite($fh_log, 'output: '.md5_file($thumbnail_path)."\n");
990
991  // database registration
992  $insert = array(
993    'file' => $filename_wo_ext.'.jpg',
994    'date_available' => $dbnow,
995    'tn_ext' => 'jpg',
996    'name' => $params['name'],
997    'path' => $file_path,
998    );
999
1000  include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
1001  mass_inserts(
1002    IMAGES_TABLE,
1003    array_keys($insert),
1004    array($insert)
1005    );
1006
1007  $image_id = mysql_insert_id();
1008
1009  $insert = array(
1010    'category_id' => $params['category_id'],
1011    'image_id'=> $image_id,
1012    );
1013  mass_inserts(
1014    IMAGE_CATEGORY_TABLE,
1015    array_keys($insert),
1016    array($insert)
1017    );
1018
1019  // fclose($fh_log);
1020}
1021
1022/**
1023 * perform a login (web service method)
1024 */
1025function ws_session_login($params, &$service)
1026{
1027  global $conf;
1028
1029  if (!$service->isPost())
1030  {
1031    return new PwgError(405, "This method requires HTTP POST");
1032  }
1033  if (try_log_user($params['username'], $params['password'],false))
1034  {
1035    return true;
1036  }
1037  return new PwgError(999, 'Invalid username/password');
1038}
1039
1040
1041/**
1042 * performs a logout (web service method)
1043 */
1044function ws_session_logout($params, &$service)
1045{
1046  global $user, $conf;
1047  if (!is_a_guest())
1048  {
1049    $_SESSION = array();
1050    session_unset();
1051    session_destroy();
1052    setcookie(session_name(),'',0,
1053        ini_get('session.cookie_path'),
1054        ini_get('session.cookie_domain')
1055      );
1056    setcookie($conf['remember_me_name'], '', 0, cookie_path());
1057  }
1058  return true;
1059}
1060
1061function ws_session_getStatus($params, &$service)
1062{
1063  global $user;
1064  $res = array();
1065  $res['username'] = is_a_guest() ? 'guest' : $user['username'];
1066  foreach ( array('status', 'template', 'theme', 'language') as $k )
1067  {
1068    $res[$k] = $user[$k];
1069  }
1070  $res['charset'] = get_pwg_charset();
1071  return $res;
1072}
1073
1074
1075/**
1076 * returns a list of tags (web service method)
1077 */
1078function ws_tags_getList($params, &$service)
1079{
1080  $tags = get_available_tags();
1081  if ($params['sort_by_counter'])
1082  {
1083    usort($tags, create_function('$a,$b', 'return -$a["counter"]+$b["counter"];') );
1084  }
1085  else
1086  {
1087    usort($tags, 'tag_alpha_compare');
1088  }
1089  for ($i=0; $i<count($tags); $i++)
1090  {
1091    $tags[$i]['id'] = (int)$tags[$i]['id'];
1092    $tags[$i]['counter'] = (int)$tags[$i]['counter'];
1093    $tags[$i]['url'] = make_index_url(
1094        array(
1095          'section'=>'tags',
1096          'tags'=>array($tags[$i])
1097        )
1098      );
1099  }
1100  return array('tags' => new PwgNamedArray($tags, 'tag', array('id','url_name','url', 'counter' )) );
1101}
1102
1103
1104/**
1105 * returns a list of images for tags (web service method)
1106 */
1107function ws_tags_getImages($params, &$service)
1108{
1109  @include_once(PHPWG_ROOT_PATH.'include/functions_picture.inc.php');
1110  global $conf;
1111
1112  // first build all the tag_ids we are interested in
1113  $params['tag_id'] = array_map( 'intval',$params['tag_id'] );
1114  $tags = find_tags($params['tag_id'], $params['tag_url_name'], $params['tag_name']);
1115  $tags_by_id = array();
1116  foreach( $tags as $tag )
1117  {
1118    $tags['id'] = (int)$tag['id'];
1119    $tags_by_id[ $tag['id'] ] = $tag;
1120  }
1121  unset($tags);
1122  $tag_ids = array_keys($tags_by_id);
1123
1124
1125  $image_ids = array();
1126  $image_tag_map = array();
1127
1128  if ( !empty($tag_ids) )
1129  { // build list of image ids with associated tags per image
1130    if ($params['tag_mode_and'])
1131    {
1132      $image_ids = get_image_ids_for_tags( $tag_ids );
1133    }
1134    else
1135    {
1136      $query = '
1137SELECT image_id, GROUP_CONCAT(tag_id) tag_ids
1138  FROM '.IMAGE_TAG_TABLE.'
1139  WHERE tag_id IN ('.implode(',',$tag_ids).')
1140  GROUP BY image_id';
1141      $result = pwg_query($query);
1142      while ( $row=mysql_fetch_assoc($result) )
1143      {
1144        $row['image_id'] = (int)$row['image_id'];
1145        array_push( $image_ids, $row['image_id'] );
1146        $image_tag_map[ $row['image_id'] ] = explode(',', $row['tag_ids']);
1147      }
1148    }
1149  }
1150
1151  $images = array();
1152  if ( !empty($image_ids))
1153  {
1154    $where_clauses = ws_std_image_sql_filter($params);
1155    $where_clauses[] = get_sql_condition_FandF(
1156        array
1157          (
1158            'forbidden_categories' => 'category_id',
1159            'visible_categories' => 'category_id',
1160            'visible_images' => 'i.id'
1161          ),
1162        '', true
1163      );
1164    $where_clauses[] = 'id IN ('.implode(',',$image_ids).')';
1165    $where_clauses[] = ws_addControls( 'tags.getImages', $params, 'i.' );
1166
1167    $order_by = ws_std_image_sql_order($params);
1168    if (empty($order_by))
1169    {
1170      $order_by = $conf['order_by'];
1171    }
1172    else
1173    {
1174      $order_by = 'ORDER BY '.$order_by;
1175    }
1176
1177    $query = '
1178SELECT DISTINCT i.* FROM '.IMAGES_TABLE.' i
1179  INNER JOIN '.IMAGE_CATEGORY_TABLE.' ON i.id=image_id
1180  WHERE '. implode('
1181    AND ', $where_clauses).'
1182'.$order_by.'
1183LIMIT '.$params['per_page']*$params['page'].','.$params['per_page'];
1184
1185    $result = pwg_query($query);
1186    while ($row = mysql_fetch_assoc($result))
1187    {
1188      $image = array();
1189      foreach ( array('id', 'width', 'height', 'hit') as $k )
1190      {
1191        if (isset($row[$k]))
1192        {
1193          $image[$k] = (int)$row[$k];
1194        }
1195      }
1196      foreach ( array('file', 'name', 'comment') as $k )
1197      {
1198        $image[$k] = $row[$k];
1199      }
1200      $image = array_merge( $image, ws_std_get_urls($row) );
1201
1202      $image_tag_ids = ($params['tag_mode_and']) ? $tag_ids : $image_tag_map[$image['id']];
1203      $image_tags = array();
1204      foreach ($image_tag_ids as $tag_id)
1205      {
1206        $url = make_index_url(
1207                 array(
1208                  'section'=>'tags',
1209                  'tags'=> array($tags_by_id[$tag_id])
1210                )
1211              );
1212        $page_url = make_picture_url(
1213                 array(
1214                  'section'=>'tags',
1215                  'tags'=> array($tags_by_id[$tag_id]),
1216                  'image_id' => $row['id'],
1217                  'image_file' => $row['file'],
1218                )
1219              );
1220        array_push($image_tags, array(
1221                'id' => (int)$tag_id,
1222                'url' => $url,
1223                'page_url' => $page_url,
1224              )
1225            );
1226      }
1227      $image['tags'] = new PwgNamedArray($image_tags, 'tag',
1228              array('id','url_name','url','page_url')
1229            );
1230      array_push($images, $image);
1231    }
1232  }
1233
1234  return array( 'images' =>
1235    array (
1236      WS_XML_ATTRIBUTES =>
1237        array(
1238            'page' => $params['page'],
1239            'per_page' => $params['per_page'],
1240            'count' => count($images)
1241          ),
1242       WS_XML_CONTENT => new PwgNamedArray($images, 'image',
1243          ws_std_get_image_xml_attributes() )
1244      )
1245    );
1246}
1247
1248
1249/**
1250 * expand_id_list($ids) convert a human list expression to a full ordered list
1251 * example : expand_id_list( array(5,2-3,2) ) returns array( 2, 3, 5)
1252 * */
1253function expand_id_list($ids)
1254{
1255  $tid = array();
1256  foreach ( $ids as $id )
1257  {
1258    if ( is_numeric($id) )
1259    {
1260      $tid[] = (int) $id;
1261    }
1262    else
1263    {
1264      $range = explode( '-', $id );
1265      if ( is_numeric($range[0]) and is_numeric($range[1]) )
1266      {
1267        $from = min($range[0],$range[1]);
1268        $to = max($range[0],$range[1]);
1269        for ($i = $from; $i <= $to; $i++)
1270        {
1271          $tid[] = (int) $i;
1272        }
1273      }
1274    }
1275  }
1276  $result = array_unique ($tid); // remove duplicates...
1277  sort ($result);
1278  return $result;
1279}
1280
1281
1282/**
1283 * converts a cat-ids array in image-ids array
1284 * FIXME Function which should already exist somewhere else
1285 * */
1286function get_image_ids_for_cats($cat_ids)
1287{
1288  $cat_list = implode(',', $cat_ids);
1289  $ret_ids = array();
1290  $query = '
1291  SELECT DISTINCT image_id
1292    FROM '.IMAGE_CATEGORY_TABLE.'
1293  WHERE category_id in ('.$cat_list.')
1294  ;';
1295  return array_from_query($query, 'image_id');
1296}
1297
1298?>
Note: See TracBrowser for help on using the repository browser.