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

Last change on this file since 2218 was 2135, checked in by rvelices, 17 years ago
  • fix plugin menu link broken with xamp (realpath behaves differently)
  • complete quick search rewriting
    • now we can quote phrases as in google "New York" is not the same as New York
    • user comments not searched anymore (faster)
    • the big full text query does not use joins anymore (faster)
    • related tags not shown on the index page, but now you can see the matching tags and matching categories
  • Property svn:eol-style set to LF
  • Property svn:keywords set to Author Date Id Revision
File size: 29.4 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 2135 2007-10-12 03:27:34Z rvelices $
7// | last update   : $Date: 2007-10-12 03:27:34 +0000 (Fri, 12 Oct 2007) $
8// | last modifier : $Author: rvelices $
9// | revision      : $Revision: 2135 $
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      (!is_a_guest()
709        or (is_a_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, 'i.' );
763  $order_by = ws_std_image_sql_order($params, 'i.');
764
765  if ( !empty($order_by) )
766  {
767    global $conf;
768    $conf['order_by'] = 'ORDER BY '.$order_by;
769    $page['super_order_by']=1; // quick_search_result might be faster
770  }
771
772  $search_result = get_quick_search_results($params['query'],
773    implode(',', $where_clauses) );
774  $image_ids = $search_result['items'];
775
776  $image_ids = array_slice($image_ids,
777    $params['page']*$params['per_page'],
778    $params['per_page'] );
779
780  if ( count($image_ids) )
781  {
782    $query = '
783SELECT * FROM '.IMAGES_TABLE.'
784  WHERE id IN ('
785        .wordwrap(implode(', ', $image_ids), 80, "\n")
786        .')';
787
788    $result = pwg_query($query);
789    while ($row = mysql_fetch_assoc($result))
790    {
791      $image = array();
792      foreach ( array('id', 'width', 'height', 'hit') as $k )
793      {
794        if (isset($row[$k]))
795        {
796          $image[$k] = (int)$row[$k];
797        }
798      }
799      foreach ( array('file', 'name', 'comment') as $k )
800      {
801        $image[$k] = $row[$k];
802      }
803      $image = array_merge( $image, ws_std_get_urls($row) );
804      array_push($images, $image);
805    }
806
807    $image_ids = array_flip($image_ids);
808    usort(
809        $images,
810        create_function('$i1,$i2', 'global $image_ids; return $image_ids[$i1["id"]]-$image_ids[$i2["id"]];')
811      );
812  }
813
814
815  return array( 'images' =>
816    array (
817      WS_XML_ATTRIBUTES =>
818        array(
819            'page' => $params['page'],
820            'per_page' => $params['per_page'],
821            'count' => count($images)
822          ),
823       WS_XML_CONTENT => new PwgNamedArray($images, 'image',
824          ws_std_get_image_xml_attributes() )
825      )
826    );
827}
828
829/**
830 * perform a login (web service method)
831 */
832function ws_session_login($params, &$service)
833{
834  global $conf;
835
836  if (!$service->isPost())
837  {
838    return new PwgError(405, "This method requires HTTP POST");
839  }
840  if (try_log_user($params['username'], $params['password'],false))
841  {
842    return true;
843  }
844  return new PwgError(999, 'Invalid username/password');
845}
846
847
848/**
849 * performs a logout (web service method)
850 */
851function ws_session_logout($params, &$service)
852{
853  global $user, $conf;
854  if (!is_a_guest())
855  {
856    $_SESSION = array();
857    session_unset();
858    session_destroy();
859    setcookie(session_name(),'',0,
860        ini_get('session.cookie_path'),
861        ini_get('session.cookie_domain')
862      );
863    setcookie($conf['remember_me_name'], '', 0, cookie_path());
864  }
865  return true;
866}
867
868function ws_session_getStatus($params, &$service)
869{
870  global $user, $lang_info;
871  $res = array();
872  $res['username'] = is_a_guest() ? 'guest' : $user['username'];
873  foreach ( array('status', 'template', 'theme', 'language') as $k )
874  {
875    $res[$k] = $user[$k];
876  }
877  $res['charset'] = get_pwg_charset();
878  return $res;
879}
880
881
882/**
883 * returns a list of tags (web service method)
884 */
885function ws_tags_getList($params, &$service)
886{
887  $tags = get_available_tags();
888  if ($params['sort_by_counter'])
889  {
890    usort($tags, create_function('$a,$b', 'return -$a["counter"]+$b["counter"];') );
891  }
892  else
893  {
894    usort($tags, 'name_compare');
895  }
896  for ($i=0; $i<count($tags); $i++)
897  {
898    $tags[$i]['id'] = (int)$tags[$i]['id'];
899    $tags[$i]['counter'] = (int)$tags[$i]['counter'];
900    $tags[$i]['url'] = make_index_url(
901        array(
902          'section'=>'tags',
903          'tags'=>array($tags[$i])
904        )
905      );
906  }
907  return array('tags' => new PwgNamedArray($tags, 'tag', array('id','url_name','url', 'counter' )) );
908}
909
910
911/**
912 * returns a list of images for tags (web service method)
913 */
914function ws_tags_getImages($params, &$service)
915{
916  @include_once(PHPWG_ROOT_PATH.'include/functions_picture.inc.php');
917  global $conf;
918
919  // first build all the tag_ids we are interested in
920  $params['tag_id'] = array_map( 'intval',$params['tag_id'] );
921  $tags = find_tags($params['tag_id'], $params['tag_url_name'], $params['tag_name']);
922  $tags_by_id = array();
923  foreach( $tags as $tag )
924  {
925    $tags['id'] = (int)$tag['id'];
926    $tags_by_id[ $tag['id'] ] = $tag;
927  }
928  unset($tags);
929  $tag_ids = array_keys($tags_by_id);
930
931
932  $image_ids = array();
933  $image_tag_map = array();
934
935  if ( !empty($tag_ids) )
936  { // build list of image ids with associated tags per image
937    if ($params['tag_mode_and'])
938    {
939      $image_ids = get_image_ids_for_tags( $tag_ids );
940    }
941    else
942    {
943      $query = '
944SELECT image_id, GROUP_CONCAT(tag_id) tag_ids
945  FROM '.IMAGE_TAG_TABLE.'
946  WHERE tag_id IN ('.implode(',',$tag_ids).')
947  GROUP BY image_id';
948      $result = pwg_query($query);
949      while ( $row=mysql_fetch_assoc($result) )
950      {
951        $row['image_id'] = (int)$row['image_id'];
952        array_push( $image_ids, $row['image_id'] );
953        $image_tag_map[ $row['image_id'] ] = explode(',', $row['tag_ids']);
954      }
955    }
956  }
957
958  $images = array();
959  if ( !empty($image_ids))
960  {
961    $where_clauses = ws_std_image_sql_filter($params);
962    $where_clauses[] = get_sql_condition_FandF(
963        array
964          (
965            'forbidden_categories' => 'category_id',
966            'visible_categories' => 'category_id',
967            'visible_images' => 'i.id'
968          ),
969        '', true
970      );
971    $where_clauses[] = 'id IN ('.implode(',',$image_ids).')';
972    $where_clauses[] = ws_addControls( 'tags.getImages', $params, 'i.' );
973
974    $order_by = ws_std_image_sql_order($params);
975    if (empty($order_by))
976    {
977      $order_by = $conf['order_by'];
978    }
979    else
980    {
981      $order_by = 'ORDER BY '.$order_by;
982    }
983
984    $query = '
985SELECT DISTINCT i.* FROM '.IMAGES_TABLE.' i
986  INNER JOIN '.IMAGE_CATEGORY_TABLE.' ON i.id=image_id
987  WHERE '. implode('
988    AND ', $where_clauses).'
989'.$order_by.'
990LIMIT '.$params['per_page']*$params['page'].','.$params['per_page'];
991
992    $result = pwg_query($query);
993    while ($row = mysql_fetch_assoc($result))
994    {
995      $image = array();
996      foreach ( array('id', 'width', 'height', 'hit') as $k )
997      {
998        if (isset($row[$k]))
999        {
1000          $image[$k] = (int)$row[$k];
1001        }
1002      }
1003      foreach ( array('file', 'name', 'comment') as $k )
1004      {
1005        $image[$k] = $row[$k];
1006      }
1007      $image = array_merge( $image, ws_std_get_urls($row) );
1008
1009      $image_tag_ids = ($params['tag_mode_and']) ? $tag_ids : $image_tag_map[$image['id']];
1010      $image_tags = array();
1011      foreach ($image_tag_ids as $tag_id)
1012      {
1013        $url = make_index_url(
1014                 array(
1015                  'section'=>'tags',
1016                  'tags'=> array($tags_by_id[$tag_id])
1017                )
1018              );
1019        $page_url = make_picture_url(
1020                 array(
1021                  'section'=>'tags',
1022                  'tags'=> array($tags_by_id[$tag_id]),
1023                  'image_id' => $row['id'],
1024                  'image_file' => $row['file'],
1025                )
1026              );
1027        array_push($image_tags, array(
1028                'id' => (int)$tag_id,
1029                'url' => $url,
1030                'page_url' => $page_url,
1031              )
1032            );
1033      }
1034      $image['tags'] = new PwgNamedArray($image_tags, 'tag',
1035              array('id','url_name','url','page_url')
1036            );
1037      array_push($images, $image);
1038    }
1039  }
1040
1041  return array( 'images' =>
1042    array (
1043      WS_XML_ATTRIBUTES =>
1044        array(
1045            'page' => $params['page'],
1046            'per_page' => $params['per_page'],
1047            'count' => count($images)
1048          ),
1049       WS_XML_CONTENT => new PwgNamedArray($images, 'image',
1050          ws_std_get_image_xml_attributes() )
1051      )
1052    );
1053}
1054
1055
1056/**
1057 * expand_id_list($ids) convert a human list expression to a full ordered list
1058 * example : expand_id_list( array(5,2-3,2) ) returns array( 2, 3, 5)
1059 * */
1060function expand_id_list($ids)
1061{
1062  $tid = array();
1063  foreach ( $ids as $id )
1064  {
1065    if ( is_numeric($id) )
1066    {
1067      $tid[] = (int) $id;
1068    }
1069    else
1070    {
1071      $range = explode( '-', $id );
1072      if ( is_numeric($range[0]) and is_numeric($range[1]) )
1073      {
1074        $from = min($range[0],$range[1]);
1075        $to = max($range[0],$range[1]);
1076        for ($i = $from; $i <= $to; $i++)
1077        {
1078          $tid[] = (int) $i;
1079        }
1080      }
1081    }
1082  }
1083  $result = array_unique ($tid); // remove duplicates...
1084  sort ($result);
1085  return $result;
1086}
1087
1088
1089/**
1090 * converts a cat-ids array in image-ids array
1091 * FIXME Function which should already exist somewhere else
1092 * */
1093function get_image_ids_for_cats($cat_ids)
1094{
1095  $cat_list = implode(',', $cat_ids);
1096  $ret_ids = array();
1097  $query = '
1098  SELECT DISTINCT image_id
1099    FROM '.IMAGE_CATEGORY_TABLE.'
1100  WHERE category_id in ('.$cat_list.')
1101  ;';
1102  return array_from_query($query, 'image_id');
1103}
1104
1105?>
Note: See TracBrowser for help on using the repository browser.