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

Last change on this file since 2435 was 2435, checked in by rvelices, 16 years ago
  • image rating on picture page done through ajax (tested safari/ie 6&7/ff)
  • Property svn:eol-style set to LF
  • Property svn:keywords set to Author Date Id Revision
File size: 31.8 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  if ( !empty($order_by) )
827  {
828    global $conf;
829    $conf['order_by'] = 'ORDER BY '.$order_by;
830    $page['super_order_by']=1; // quick_search_result might be faster
831  }
832
833  $search_result = get_quick_search_results($params['query'],
834    implode(',', $where_clauses) );
835  $image_ids = $search_result['items'];
836
837  $image_ids = array_slice($image_ids,
838    $params['page']*$params['per_page'],
839    $params['per_page'] );
840
841  if ( count($image_ids) )
842  {
843    $query = '
844SELECT * FROM '.IMAGES_TABLE.'
845  WHERE id IN ('
846        .wordwrap(implode(', ', $image_ids), 80, "\n")
847        .')';
848
849    $result = pwg_query($query);
850    while ($row = mysql_fetch_assoc($result))
851    {
852      $image = array();
853      foreach ( array('id', 'width', 'height', 'hit') as $k )
854      {
855        if (isset($row[$k]))
856        {
857          $image[$k] = (int)$row[$k];
858        }
859      }
860      foreach ( array('file', 'name', 'comment') as $k )
861      {
862        $image[$k] = $row[$k];
863      }
864      $image = array_merge( $image, ws_std_get_urls($row) );
865      array_push($images, $image);
866    }
867
868    $image_ids = array_flip($image_ids);
869    usort(
870        $images,
871        create_function('$i1,$i2', 'global $image_ids; return $image_ids[$i1["id"]]-$image_ids[$i2["id"]];')
872      );
873  }
874
875
876  return array( 'images' =>
877    array (
878      WS_XML_ATTRIBUTES =>
879        array(
880            'page' => $params['page'],
881            'per_page' => $params['per_page'],
882            'count' => count($images)
883          ),
884       WS_XML_CONTENT => new PwgNamedArray($images, 'image',
885          ws_std_get_image_xml_attributes() )
886      )
887    );
888}
889
890function ws_images_setPrivacyLevel($params, &$service)
891{
892  if (!is_admin() || is_adviser() )
893  {
894    return new PwgError(401, 'Access denied');
895  }
896  if ( empty($params['image_id']) )
897  {
898    return new PwgError(WS_ERR_INVALID_PARAM, "Invalid image_id");
899  }
900  global $conf;
901  if ( !in_array( (int)$params['level'], $conf['available_permission_levels']) )
902  {
903    return new PwgError(WS_ERR_INVALID_PARAM, "Invalid level");
904  }
905  $query = '
906UPDATE '.IMAGES_TABLE.'
907  SET level='.(int)$params['level'].'
908  WHERE id IN ('.implode(',',$params['image_id']).')';
909  $result = pwg_query($query);
910  $affected_rows = mysql_affected_rows();
911  if ($affected_rows)
912  {
913    include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
914    invalidate_user_cache();
915  }
916  return $affected_rows;
917}
918
919/**
920 * perform a login (web service method)
921 */
922function ws_session_login($params, &$service)
923{
924  global $conf;
925
926  if (!$service->isPost())
927  {
928    return new PwgError(405, "This method requires HTTP POST");
929  }
930  if (try_log_user($params['username'], $params['password'],false))
931  {
932    return true;
933  }
934  return new PwgError(999, 'Invalid username/password');
935}
936
937
938/**
939 * performs a logout (web service method)
940 */
941function ws_session_logout($params, &$service)
942{
943  global $user, $conf;
944  if (!is_a_guest())
945  {
946    $_SESSION = array();
947    session_unset();
948    session_destroy();
949    setcookie(session_name(),'',0,
950        ini_get('session.cookie_path'),
951        ini_get('session.cookie_domain')
952      );
953    setcookie($conf['remember_me_name'], '', 0, cookie_path());
954  }
955  return true;
956}
957
958function ws_session_getStatus($params, &$service)
959{
960  global $user;
961  $res = array();
962  $res['username'] = is_a_guest() ? 'guest' : $user['username'];
963  foreach ( array('status', 'template', 'theme', 'language') as $k )
964  {
965    $res[$k] = $user[$k];
966  }
967  $res['charset'] = get_pwg_charset();
968  return $res;
969}
970
971
972/**
973 * returns a list of tags (web service method)
974 */
975function ws_tags_getList($params, &$service)
976{
977  $tags = get_available_tags();
978  if ($params['sort_by_counter'])
979  {
980    usort($tags, create_function('$a,$b', 'return -$a["counter"]+$b["counter"];') );
981  }
982  else
983  {
984    usort($tags, 'tag_alpha_compare');
985  }
986  for ($i=0; $i<count($tags); $i++)
987  {
988    $tags[$i]['id'] = (int)$tags[$i]['id'];
989    $tags[$i]['counter'] = (int)$tags[$i]['counter'];
990    $tags[$i]['url'] = make_index_url(
991        array(
992          'section'=>'tags',
993          'tags'=>array($tags[$i])
994        )
995      );
996  }
997  return array('tags' => new PwgNamedArray($tags, 'tag', array('id','url_name','url', 'counter' )) );
998}
999
1000
1001/**
1002 * returns a list of images for tags (web service method)
1003 */
1004function ws_tags_getImages($params, &$service)
1005{
1006  @include_once(PHPWG_ROOT_PATH.'include/functions_picture.inc.php');
1007  global $conf;
1008
1009  // first build all the tag_ids we are interested in
1010  $params['tag_id'] = array_map( 'intval',$params['tag_id'] );
1011  $tags = find_tags($params['tag_id'], $params['tag_url_name'], $params['tag_name']);
1012  $tags_by_id = array();
1013  foreach( $tags as $tag )
1014  {
1015    $tags['id'] = (int)$tag['id'];
1016    $tags_by_id[ $tag['id'] ] = $tag;
1017  }
1018  unset($tags);
1019  $tag_ids = array_keys($tags_by_id);
1020
1021
1022  $image_ids = array();
1023  $image_tag_map = array();
1024
1025  if ( !empty($tag_ids) )
1026  { // build list of image ids with associated tags per image
1027    if ($params['tag_mode_and'])
1028    {
1029      $image_ids = get_image_ids_for_tags( $tag_ids );
1030    }
1031    else
1032    {
1033      $query = '
1034SELECT image_id, GROUP_CONCAT(tag_id) tag_ids
1035  FROM '.IMAGE_TAG_TABLE.'
1036  WHERE tag_id IN ('.implode(',',$tag_ids).')
1037  GROUP BY image_id';
1038      $result = pwg_query($query);
1039      while ( $row=mysql_fetch_assoc($result) )
1040      {
1041        $row['image_id'] = (int)$row['image_id'];
1042        array_push( $image_ids, $row['image_id'] );
1043        $image_tag_map[ $row['image_id'] ] = explode(',', $row['tag_ids']);
1044      }
1045    }
1046  }
1047
1048  $images = array();
1049  if ( !empty($image_ids))
1050  {
1051    $where_clauses = ws_std_image_sql_filter($params);
1052    $where_clauses[] = get_sql_condition_FandF(
1053        array
1054          (
1055            'forbidden_categories' => 'category_id',
1056            'visible_categories' => 'category_id',
1057            'visible_images' => 'i.id'
1058          ),
1059        '', true
1060      );
1061    $where_clauses[] = 'id IN ('.implode(',',$image_ids).')';
1062    $where_clauses[] = ws_addControls( 'tags.getImages', $params, 'i.' );
1063
1064    $order_by = ws_std_image_sql_order($params);
1065    if (empty($order_by))
1066    {
1067      $order_by = $conf['order_by'];
1068    }
1069    else
1070    {
1071      $order_by = 'ORDER BY '.$order_by;
1072    }
1073
1074    $query = '
1075SELECT DISTINCT i.* FROM '.IMAGES_TABLE.' i
1076  INNER JOIN '.IMAGE_CATEGORY_TABLE.' ON i.id=image_id
1077  WHERE '. implode('
1078    AND ', $where_clauses).'
1079'.$order_by.'
1080LIMIT '.$params['per_page']*$params['page'].','.$params['per_page'];
1081
1082    $result = pwg_query($query);
1083    while ($row = mysql_fetch_assoc($result))
1084    {
1085      $image = array();
1086      foreach ( array('id', 'width', 'height', 'hit') as $k )
1087      {
1088        if (isset($row[$k]))
1089        {
1090          $image[$k] = (int)$row[$k];
1091        }
1092      }
1093      foreach ( array('file', 'name', 'comment') as $k )
1094      {
1095        $image[$k] = $row[$k];
1096      }
1097      $image = array_merge( $image, ws_std_get_urls($row) );
1098
1099      $image_tag_ids = ($params['tag_mode_and']) ? $tag_ids : $image_tag_map[$image['id']];
1100      $image_tags = array();
1101      foreach ($image_tag_ids as $tag_id)
1102      {
1103        $url = make_index_url(
1104                 array(
1105                  'section'=>'tags',
1106                  'tags'=> array($tags_by_id[$tag_id])
1107                )
1108              );
1109        $page_url = make_picture_url(
1110                 array(
1111                  'section'=>'tags',
1112                  'tags'=> array($tags_by_id[$tag_id]),
1113                  'image_id' => $row['id'],
1114                  'image_file' => $row['file'],
1115                )
1116              );
1117        array_push($image_tags, array(
1118                'id' => (int)$tag_id,
1119                'url' => $url,
1120                'page_url' => $page_url,
1121              )
1122            );
1123      }
1124      $image['tags'] = new PwgNamedArray($image_tags, 'tag',
1125              array('id','url_name','url','page_url')
1126            );
1127      array_push($images, $image);
1128    }
1129  }
1130
1131  return array( 'images' =>
1132    array (
1133      WS_XML_ATTRIBUTES =>
1134        array(
1135            'page' => $params['page'],
1136            'per_page' => $params['per_page'],
1137            'count' => count($images)
1138          ),
1139       WS_XML_CONTENT => new PwgNamedArray($images, 'image',
1140          ws_std_get_image_xml_attributes() )
1141      )
1142    );
1143}
1144
1145
1146/**
1147 * expand_id_list($ids) convert a human list expression to a full ordered list
1148 * example : expand_id_list( array(5,2-3,2) ) returns array( 2, 3, 5)
1149 * */
1150function expand_id_list($ids)
1151{
1152  $tid = array();
1153  foreach ( $ids as $id )
1154  {
1155    if ( is_numeric($id) )
1156    {
1157      $tid[] = (int) $id;
1158    }
1159    else
1160    {
1161      $range = explode( '-', $id );
1162      if ( is_numeric($range[0]) and is_numeric($range[1]) )
1163      {
1164        $from = min($range[0],$range[1]);
1165        $to = max($range[0],$range[1]);
1166        for ($i = $from; $i <= $to; $i++)
1167        {
1168          $tid[] = (int) $i;
1169        }
1170      }
1171    }
1172  }
1173  $result = array_unique ($tid); // remove duplicates...
1174  sort ($result);
1175  return $result;
1176}
1177
1178
1179/**
1180 * converts a cat-ids array in image-ids array
1181 * FIXME Function which should already exist somewhere else
1182 * */
1183function get_image_ids_for_cats($cat_ids)
1184{
1185  $cat_list = implode(',', $cat_ids);
1186  $ret_ids = array();
1187  $query = '
1188  SELECT DISTINCT image_id
1189    FROM '.IMAGE_CATEGORY_TABLE.'
1190  WHERE category_id in ('.$cat_list.')
1191  ;';
1192  return array_from_query($query, 'image_id');
1193}
1194
1195?>
Note: See TracBrowser for help on using the repository browser.