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

Last change on this file since 1853 was 1853, checked in by vdigital, 17 years ago

New / Web Services:

  • ws_checker.php makes its own web service request to control availability
  • config_default.inc.php : comment for cURL support needed for checker
  • ws_function authorize session and getVersion for any partner
  • help review

New Admin Menu: review.

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