source: branches/branch-1_7/include/ws_functions.inc.php @ 2271

Last change on this file since 2271 was 2120, checked in by rvelices, 17 years ago

merge rev 2119 from trunk

  • bug 755: admin permalinks page - fix category field sort
  • web service functions: 1 fix and 3 optimizations
  • Property svn:eol-style set to LF
  • Property svn:keywords set to Author Date Id Revision
File size: 30.5 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 2120 2007-10-03 23:38:37Z rvelices $
7// | last update   : $Date: 2007-10-03 23:38:37 +0000 (Wed, 03 Oct 2007) $
8// | last modifier : $Author: rvelices $
9// | revision      : $Revision: 2120 $
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[] = get_sql_condition_FandF(
320        array('forbidden_categories' => 'id'),
321        NULL, true
322      );
323
324  $query = '
325SELECT id, name, permalink, image_order
326  FROM '.CATEGORIES_TABLE.'
327  WHERE '. implode('
328    AND ', $where_clauses);
329  $result = pwg_query($query);
330  $cats = array();
331  while ($row = mysql_fetch_assoc($result))
332  {
333    $row['id'] = (int)$row['id'];
334    $cats[ $row['id'] ] = $row;
335  }
336
337  //-------------------------------------------------------- get the images
338  if ( !empty($cats) )
339  {
340    $where_clauses = ws_std_image_sql_filter( $params, 'i.' );
341    $where_clauses[] = 'category_id IN ('
342      .implode(',', array_keys($cats) )
343      .')';
344    $where_clauses[] = get_sql_condition_FandF( array(
345          'visible_images' => 'i.id'
346        ), null, true
347      );
348    $where_clauses[] = ws_addControls( 'categories.getImages', $params, 'i.' );
349
350    $order_by = ws_std_image_sql_order($params, 'i.');
351    if ( empty($order_by)
352          and count($params['cat_id'])==1
353          and isset($cats[ $params['cat_id'][0] ]['image_order'])
354        )
355    {
356      $order_by = $cats[ $params['cat_id'][0] ]['image_order'];
357    }
358    $order_by = empty($order_by) ? $conf['order_by'] : 'ORDER BY '.$order_by;
359
360    $query = '
361SELECT i.*, GROUP_CONCAT(category_id) cat_ids
362  FROM '.IMAGES_TABLE.' i
363    INNER JOIN '.IMAGE_CATEGORY_TABLE.' ON i.id=image_id
364  WHERE '. implode('
365    AND ', $where_clauses).'
366GROUP BY i.id
367'.$order_by.'
368LIMIT '.$params['per_page']*$params['page'].','.$params['per_page'];
369
370    $result = pwg_query($query);
371    while ($row = mysql_fetch_assoc($result))
372    {
373      $image = array();
374      foreach ( array('id', 'width', 'height', 'hit') as $k )
375      {
376        if (isset($row[$k]))
377        {
378          $image[$k] = (int)$row[$k];
379        }
380      }
381      foreach ( array('file', 'name', 'comment') as $k )
382      {
383        $image[$k] = $row[$k];
384      }
385      $image = array_merge( $image, ws_std_get_urls($row) );
386
387      $image_cats = array();
388      foreach ( explode(',', $row['cat_ids']) as $cat_id )
389      {
390        $url = make_index_url(
391                array(
392                  'category' => $cats[$cat_id],
393                  )
394                );
395        $page_url = make_picture_url(
396                array(
397                  'category' => $cats[$cat_id],
398                  'image_id' => $row['id'],
399                  'image_file' => $row['file'],
400                  )
401                );
402        array_push( $image_cats,  array(
403              WS_XML_ATTRIBUTES => array (
404                  'id' => (int)$cat_id,
405                  'url' => $url,
406                  'page_url' => $page_url,
407                )
408            )
409          );
410      }
411
412      $image['categories'] = new PwgNamedArray(
413            $image_cats,'category', array('id','url','page_url')
414          );
415      array_push($images, $image);
416    }
417  }
418
419  return array( 'images' =>
420    array (
421      WS_XML_ATTRIBUTES =>
422        array(
423            'page' => $params['page'],
424            'per_page' => $params['per_page'],
425            'count' => count($images)
426          ),
427       WS_XML_CONTENT => new PwgNamedArray($images, 'image',
428          ws_std_get_image_xml_attributes() )
429      )
430    );
431}
432
433
434/**
435 * returns a list of categories (web service method)
436 */
437function ws_categories_getList($params, &$service)
438{
439  global $user,$conf;
440
441  $where = array();
442
443  if (!$params['recursive'])
444  {
445    if ($params['cat_id']>0)
446      $where[] = '(id_uppercat='.(int)($params['cat_id']).'
447    OR id='.(int)($params['cat_id']).')';
448    else
449      $where[] = 'id_uppercat IS NULL';
450  }
451  else if ($params['cat_id']>0)
452  {
453    $where[] = 'uppercats REGEXP \'(^|,)'.
454      (int)($params['cat_id'])
455      .'(,|$)\'';
456  }
457
458  if ($params['public'])
459  {
460    $where[] = 'status = "public"';
461    $where[] = 'visible = "true"';
462    $where[]= 'user_id='.$conf['guest_id'];
463  }
464  else
465  {
466    $where[]= 'user_id='.$user['id'];
467  }
468
469  $query = '
470SELECT id, name, permalink, 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
478  $result = pwg_query($query);
479
480  $cats = array();
481  while ($row = mysql_fetch_assoc($result))
482  {
483    $row['url'] = make_index_url(
484        array(
485          'category' => $row
486          )
487      );
488    foreach( array('id','nb_images','total_nb_images','nb_categories') as $key)
489    {
490      $row[$key] = (int)$row[$key];
491    }
492    array_push($cats, $row);
493  }
494  usort($cats, 'global_rank_compare');
495  return array(
496      'categories' =>
497          new PwgNamedArray($cats,'category',
498            array('id','url','nb_images','total_nb_images','nb_categories','date_last','max_date_last')
499          )
500    );
501}
502
503
504/**
505 * returns detailed information for an element (web service method)
506 */
507function ws_images_addComment($params, &$service)
508{
509  if (!$service->isPost())
510  {
511    return new PwgError(405, "This method requires HTTP POST");
512  }
513  $params['image_id'] = (int)$params['image_id'];
514  $query = '
515SELECT DISTINCT image_id
516  FROM '.IMAGE_CATEGORY_TABLE.' INNER JOIN '.CATEGORIES_TABLE.' ON category_id=id
517  WHERE commentable="true"
518    AND image_id='.$params['image_id'].
519    get_sql_condition_FandF(
520      array(
521        'forbidden_categories' => 'id',
522        'visible_categories' => 'id',
523        'visible_images' => 'image_id'
524      ),
525      ' AND'
526    );
527  if ( !mysql_num_rows( pwg_query( $query ) ) )
528  {
529    return new PwgError(WS_ERR_INVALID_PARAM, "Invalid image_id");
530  }
531
532  include_once(PHPWG_ROOT_PATH.'include/functions_comment.inc.php');
533
534  $comm = array(
535    'author' => trim( stripslashes($params['author']) ),
536    'content' => trim( stripslashes($params['content']) ),
537    'image_id' => $params['image_id'],
538   );
539
540  include_once(PHPWG_ROOT_PATH.'include/functions_comment.inc.php');
541
542  $comment_action = insert_user_comment(
543      $comm, $params['key'], $infos
544    );
545
546  switch ($comment_action)
547  {
548    case 'reject':
549      array_push($infos, l10n('comment_not_added') );
550      return new PwgError(403, implode("\n", $infos) );
551    case 'validate':
552    case 'moderate':
553      $ret = array(
554          'id' => $comm['id'],
555          'validation' => $comment_action=='validate',
556        );
557      return new PwgNamedStruct(
558          'comment',
559          $ret,
560          null, array()
561        );
562    default:
563      return new PwgError(500, "Unknown comment action ".$comment_action );
564  }
565}
566
567/**
568 * returns detailed information for an element (web service method)
569 */
570function ws_images_getInfo($params, &$service)
571{
572  @include_once(PHPWG_ROOT_PATH.'include/functions_picture.inc.php');
573  global $user, $conf;
574  $params['image_id'] = (int)$params['image_id'];
575  if ( $params['image_id']<=0 )
576  {
577    return new PwgError(WS_ERR_INVALID_PARAM, "Invalid image_id");
578  }
579
580  $query='
581SELECT * FROM '.IMAGES_TABLE.'
582  WHERE id='.$params['image_id'].
583    get_sql_condition_FandF(
584      array('visible_images' => 'id'),
585      ' AND'
586    ).' AND '.
587    ws_addControls( 'images.getInfo', $params, '' ).'
588LIMIT 1;';
589
590  $image_row = mysql_fetch_assoc(pwg_query($query));
591  if ($image_row==null)
592  {
593    return new PwgError(404, "image_id not found");
594  }
595  $image_row = array_merge( $image_row, ws_std_get_urls($image_row) );
596
597  //-------------------------------------------------------- related categories
598  $query = '
599SELECT id, name, permalink, uppercats, global_rank, commentable
600  FROM '.IMAGE_CATEGORY_TABLE.'
601    INNER JOIN '.CATEGORIES_TABLE.' ON category_id = id
602  WHERE image_id = '.$image_row['id'].
603  get_sql_condition_FandF(
604      array( 'forbidden_categories' => 'category_id' ),
605      ' AND'
606    ).'
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
621          )
622      );
623
624    $row['page_url'] = make_picture_url(
625        array(
626          'image_id' => $image_row['id'],
627          'image_file' => $image_row['file'],
628          'category' => $row
629          )
630      );
631    $row['id']=(int)$row['id'];
632    array_push($related_categories, $row);
633  }
634  usort($related_categories, 'global_rank_compare');
635  if ( empty($related_categories) )
636  {
637    return new PwgError(401, 'Access denied');
638  }
639
640  //-------------------------------------------------------------- related tags
641  $related_tags = get_common_tags( array($image_row['id']), -1 );
642  foreach( $related_tags as $i=>$tag)
643  {
644    $tag['url'] = make_index_url(
645        array(
646          'tags' => array($tag)
647          )
648      );
649    $tag['page_url'] = make_picture_url(
650        array(
651          'image_id' => $image_row['id'],
652          'image_file' => $image_row['file'],
653          'tags' => array($tag),
654          )
655      );
656    unset($tag['counter']);
657    $tag['id']=(int)$tag['id'];
658    $related_tags[$i]=$tag;
659  }
660  //------------------------------------------------------------- related rates
661  $query = '
662SELECT COUNT(rate) AS count
663     , ROUND(AVG(rate),2) AS average
664     , ROUND(STD(rate),2) AS stdev
665  FROM '.RATE_TABLE.'
666  WHERE element_id = '.$image_row['id'].'
667;';
668  $rating = mysql_fetch_assoc(pwg_query($query));
669  $rating['count'] = (int)$rating['count'];
670
671  //---------------------------------------------------------- related comments
672  $related_comments = array();
673
674  $where_comments = 'image_id = '.$image_row['id'];
675  if ( !is_admin() )
676  {
677    $where_comments .= '
678    AND validated="true"';
679  }
680
681  $query = '
682SELECT COUNT(id) nb_comments
683  FROM '.COMMENTS_TABLE.'
684  WHERE '.$where_comments;
685  list($nb_comments) = array_from_query($query, 'nb_comments');
686  $nb_comments = (int)$nb_comments;
687
688  if ( $nb_comments>0 and $params['comments_per_page']>0 )
689  {
690    $query = '
691SELECT id, date, author, content
692  FROM '.COMMENTS_TABLE.'
693  WHERE '.$where_comments.'
694  ORDER BY date
695  LIMIT '.$params['comments_per_page']*(int)$params['comments_page'].
696    ','.$params['comments_per_page'];
697
698    $result = pwg_query($query);
699    while ($row = mysql_fetch_assoc($result))
700    {
701      $row['id']=(int)$row['id'];
702      array_push($related_comments, $row);
703    }
704  }
705
706  $comment_post_data = null;
707  if ($is_commentable and
708      (!$user['is_the_guest']
709        or ($user['is_the_guest'] and $conf['comments_forall'] )
710      )
711      )
712  {
713    include_once(PHPWG_ROOT_PATH.'include/functions_comment.inc.php');
714    $comment_post_data['author'] = $user['username'];
715    $comment_post_data['key'] = get_comment_post_key($params['image_id']);
716  }
717
718  $ret = $image_row;
719  foreach ( array('id','width','height','hit','filesize') as $k )
720  {
721    if (isset($ret[$k]))
722    {
723      $ret[$k] = (int)$ret[$k];
724    }
725  }
726  foreach ( array('path', 'storage_category_id') as $k )
727  {
728    unset($ret[$k]);
729  }
730
731  $ret['rates'] = array( WS_XML_ATTRIBUTES => $rating );
732  $ret['categories'] = new PwgNamedArray($related_categories, 'category', array('id','url', 'page_url') );
733  $ret['tags'] = new PwgNamedArray($related_tags, 'tag', array('id','url_name','url','page_url') );
734  if ( isset($comment_post_data) )
735  {
736    $ret['comment_post'] = array( WS_XML_ATTRIBUTES => $comment_post_data );
737  }
738  $ret['comments'] = array(
739     WS_XML_ATTRIBUTES =>
740        array(
741          'page' => $params['comments_page'],
742          'per_page' => $params['comments_per_page'],
743          'count' => count($related_comments),
744          'nb_comments' => $nb_comments,
745        ),
746     WS_XML_CONTENT => new PwgNamedArray($related_comments, 'comment', array('id','date') )
747      );
748
749  return new PwgNamedStruct('image',$ret, null, array('name','comment') );
750}
751
752/**
753 * returns a list of elements corresponding to a query search
754 */
755function ws_images_search($params, &$service)
756{
757  global $page;
758  $images = array();
759  include_once( PHPWG_ROOT_PATH .'include/functions_search.inc.php' );
760  include_once(PHPWG_ROOT_PATH.'include/functions_picture.inc.php');
761
762  $where_clauses = ws_std_image_sql_filter( $params );
763  $order_by = ws_std_image_sql_order($params);
764
765  if ( !empty($where_clauses) and !empty($order_by) )
766  {
767    $page['super_order_by']=1; // quick_search_result might be faster
768  }
769  $search_result = get_quick_search_results($params['query']);
770
771  global $image_ids; //needed for sorting by rank (usort)
772  if ( ( !isset($search_result['as_is'])
773      or !empty($where_clauses)
774      or !empty($order_by) )
775      and !empty($search_result['items']) )
776  {
777    $where_clauses[] = 'id IN ('
778        .wordwrap(implode(', ', $search_result['items']), 80, "\n")
779        .')';
780    $where_clauses[] = get_sql_condition_FandF(
781        array
782          (
783            'forbidden_categories' => 'category_id',
784            'visible_categories' => 'category_id',
785            'visible_images' => 'id'
786          ),
787        '', true
788      );
789    $query = '
790SELECT DISTINCT id FROM '.IMAGES_TABLE.' INNER JOIN '.IMAGE_CATEGORY_TABLE.' ON id=image_id
791  WHERE '.implode('
792    AND ', $where_clauses);
793    if (!empty($order_by))
794    {
795      $query .= '
796  ORDER BY '.$order_by;
797    }
798    $image_ids = array_from_query($query, 'id');
799    global $ranks;
800    $ranks = array_flip( $search_result['items'] );
801    usort(
802      $image_ids,
803      create_function('$i1,$i2', 'global $ranks; return $ranks[$i1]-$ranks[$i2];')
804    );
805    unset ($ranks);
806  }
807  else
808  {
809    $image_ids = $search_result['items'];
810  }
811
812  $image_ids = array_slice($image_ids,
813    $params['page']*$params['per_page'],
814    $params['per_page'] );
815
816  if ( count($image_ids) )
817  {
818    $query = '
819SELECT * FROM '.IMAGES_TABLE.'
820  WHERE id IN ('
821        .wordwrap(implode(', ', $image_ids), 80, "\n")
822        .')';
823
824    $result = pwg_query($query);
825    while ($row = mysql_fetch_assoc($result))
826    {
827      $image = array();
828      foreach ( array('id', 'width', 'height', 'hit') as $k )
829      {
830        if (isset($row[$k]))
831        {
832          $image[$k] = (int)$row[$k];
833        }
834      }
835      foreach ( array('file', 'name', 'comment') as $k )
836      {
837        $image[$k] = $row[$k];
838      }
839      $image = array_merge( $image, ws_std_get_urls($row) );
840      array_push($images, $image);
841    }
842
843    $image_ids = array_flip($image_ids);
844    usort(
845        $images,
846        create_function('$i1,$i2', 'global $image_ids; return $image_ids[$i1["id"]]-$image_ids[$i2["id"]];')
847      );
848  }
849
850
851  return array( 'images' =>
852    array (
853      WS_XML_ATTRIBUTES =>
854        array(
855            'page' => $params['page'],
856            'per_page' => $params['per_page'],
857            'count' => count($images)
858          ),
859       WS_XML_CONTENT => new PwgNamedArray($images, 'image',
860          ws_std_get_image_xml_attributes() )
861      )
862    );
863}
864
865/**
866 * perform a login (web service method)
867 */
868function ws_session_login($params, &$service)
869{
870  global $conf;
871
872  if (!$service->isPost())
873  {
874    return new PwgError(405, "This method requires HTTP POST");
875  }
876  if (try_log_user($params['username'], $params['password'],false))
877  {
878    return true;
879  }
880  return new PwgError(999, 'Invalid username/password');
881}
882
883
884/**
885 * performs a logout (web service method)
886 */
887function ws_session_logout($params, &$service)
888{
889  global $user, $conf;
890  if (!$user['is_the_guest'])
891  {
892    $_SESSION = array();
893    session_unset();
894    session_destroy();
895    setcookie(session_name(),'',0,
896        ini_get('session.cookie_path'),
897        ini_get('session.cookie_domain')
898      );
899    setcookie($conf['remember_me_name'], '', 0, cookie_path());
900  }
901  return true;
902}
903
904function ws_session_getStatus($params, &$service)
905{
906  global $user, $lang_info;
907  $res = array();
908  $res['username'] = $user['is_the_guest'] ? 'guest' : $user['username'];
909  foreach ( array('status', 'template', 'theme', 'language') as $k )
910  {
911    $res[$k] = $user[$k];
912  }
913  foreach ( array('charset') as $k )
914  {
915    $res[$k] = $lang_info[$k];
916  }
917  return $res;
918}
919
920
921/**
922 * returns a list of tags (web service method)
923 */
924function ws_tags_getList($params, &$service)
925{
926  $tags = get_available_tags();
927  if ($params['sort_by_counter'])
928  {
929    usort($tags, create_function('$a,$b', 'return -$a["counter"]+$b["counter"];') );
930  }
931  else
932  {
933    usort($tags, 'name_compare');
934  }
935  for ($i=0; $i<count($tags); $i++)
936  {
937    $tags[$i]['id'] = (int)$tags[$i]['id'];
938    $tags[$i]['counter'] = (int)$tags[$i]['counter'];
939    $tags[$i]['url'] = make_index_url(
940        array(
941          'section'=>'tags',
942          'tags'=>array($tags[$i])
943        )
944      );
945  }
946  return array('tags' => new PwgNamedArray($tags, 'tag', array('id','url_name','url', 'counter' )) );
947}
948
949
950/**
951 * returns a list of images for tags (web service method)
952 */
953function ws_tags_getImages($params, &$service)
954{
955  @include_once(PHPWG_ROOT_PATH.'include/functions_picture.inc.php');
956  global $conf;
957
958  // first build all the tag_ids we are interested in
959  $params['tag_id'] = array_map( 'intval',$params['tag_id'] );
960  $tags = find_tags($params['tag_id'], $params['tag_url_name'], $params['tag_name']);
961  $tags_by_id = array();
962  foreach( $tags as $tag )
963  {
964    $tags['id'] = (int)$tag['id'];
965    $tags_by_id[ $tag['id'] ] = $tag;
966  }
967  unset($tags);
968  $tag_ids = array_keys($tags_by_id);
969
970
971  $image_ids = array();
972  $image_tag_map = array();
973
974  if ( !empty($tag_ids) )
975  { // build list of image ids with associated tags per image
976    if ($params['tag_mode_and'])
977    {
978      $image_ids = get_image_ids_for_tags( $tag_ids );
979    }
980    else
981    {
982      $query = '
983SELECT image_id, GROUP_CONCAT(tag_id) tag_ids
984  FROM '.IMAGE_TAG_TABLE.'
985  WHERE tag_id IN ('.implode(',',$tag_ids).')
986  GROUP BY image_id';
987      $result = pwg_query($query);
988      while ( $row=mysql_fetch_assoc($result) )
989      {
990        $row['image_id'] = (int)$row['image_id'];
991        array_push( $image_ids, $row['image_id'] );
992        $image_tag_map[ $row['image_id'] ] = explode(',', $row['tag_ids']);
993      }
994    }
995  }
996
997  $images = array();
998  if ( !empty($image_ids))
999  {
1000    $where_clauses = ws_std_image_sql_filter($params);
1001    $where_clauses[] = get_sql_condition_FandF(
1002        array
1003          (
1004            'forbidden_categories' => 'category_id',
1005            'visible_categories' => 'category_id',
1006            'visible_images' => 'i.id'
1007          ),
1008        '', true
1009      );
1010    $where_clauses[] = 'id IN ('.implode(',',$image_ids).')';
1011    $where_clauses[] = ws_addControls( 'tags.getImages', $params, 'i.' );
1012
1013    $order_by = ws_std_image_sql_order($params);
1014    if (empty($order_by))
1015    {
1016      $order_by = $conf['order_by'];
1017    }
1018    else
1019    {
1020      $order_by = 'ORDER BY '.$order_by;
1021    }
1022
1023    $query = '
1024SELECT DISTINCT i.* FROM '.IMAGES_TABLE.' i
1025  INNER JOIN '.IMAGE_CATEGORY_TABLE.' ON i.id=image_id
1026  WHERE '. implode('
1027    AND ', $where_clauses).'
1028'.$order_by.'
1029LIMIT '.$params['per_page']*$params['page'].','.$params['per_page'];
1030
1031    $result = pwg_query($query);
1032    while ($row = mysql_fetch_assoc($result))
1033    {
1034      $image = array();
1035      foreach ( array('id', 'width', 'height', 'hit') as $k )
1036      {
1037        if (isset($row[$k]))
1038        {
1039          $image[$k] = (int)$row[$k];
1040        }
1041      }
1042      foreach ( array('file', 'name', 'comment') as $k )
1043      {
1044        $image[$k] = $row[$k];
1045      }
1046      $image = array_merge( $image, ws_std_get_urls($row) );
1047
1048      $image_tag_ids = ($params['tag_mode_and']) ? $tag_ids : $image_tag_map[$image['id']];
1049      $image_tags = array();
1050      foreach ($image_tag_ids as $tag_id)
1051      {
1052        $url = make_index_url(
1053                 array(
1054                  'section'=>'tags',
1055                  'tags'=> array($tags_by_id[$tag_id])
1056                )
1057              );
1058        $page_url = make_picture_url(
1059                 array(
1060                  'section'=>'tags',
1061                  'tags'=> array($tags_by_id[$tag_id]),
1062                  'image_id' => $row['id'],
1063                  'image_file' => $row['file'],
1064                )
1065              );
1066        array_push($image_tags, array(
1067                'id' => (int)$tag_id,
1068                'url' => $url,
1069                'page_url' => $page_url,
1070              )
1071            );
1072      }
1073      $image['tags'] = new PwgNamedArray($image_tags, 'tag',
1074              array('id','url_name','url','page_url')
1075            );
1076      array_push($images, $image);
1077    }
1078  }
1079
1080  return array( 'images' =>
1081    array (
1082      WS_XML_ATTRIBUTES =>
1083        array(
1084            'page' => $params['page'],
1085            'per_page' => $params['per_page'],
1086            'count' => count($images)
1087          ),
1088       WS_XML_CONTENT => new PwgNamedArray($images, 'image',
1089          ws_std_get_image_xml_attributes() )
1090      )
1091    );
1092}
1093
1094
1095/**
1096 * expand_id_list($ids) convert a human list expression to a full ordered list
1097 * example : expand_id_list( array(5,2-3,2) ) returns array( 2, 3, 5)
1098 * */
1099function expand_id_list($ids)
1100{
1101  $tid = array();
1102  foreach ( $ids as $id )
1103  {
1104    if ( is_numeric($id) )
1105    {
1106      $tid[] = (int) $id;
1107    }
1108    else
1109    {
1110      $range = explode( '-', $id );
1111      if ( is_numeric($range[0]) and is_numeric($range[1]) )
1112      {
1113        $from = min($range[0],$range[1]);
1114        $to = max($range[0],$range[1]);
1115        for ($i = $from; $i <= $to; $i++)
1116        {
1117          $tid[] = (int) $i;
1118        }
1119      }
1120    }
1121  }
1122  $result = array_unique ($tid); // remove duplicates...
1123  sort ($result);
1124  return $result;
1125}
1126
1127
1128/**
1129 * converts a cat-ids array in image-ids array
1130 * FIXME Function which should already exist somewhere else
1131 * */
1132function get_image_ids_for_cats($cat_ids)
1133{
1134  $cat_list = implode(',', $cat_ids);
1135  $ret_ids = array();
1136  $query = '
1137  SELECT DISTINCT image_id
1138    FROM '.IMAGE_CATEGORY_TABLE.'
1139  WHERE category_id in ('.$cat_list.')
1140  ;';
1141  return array_from_query($query, 'image_id');
1142}
1143
1144?>
Note: See TracBrowser for help on using the repository browser.