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

Last change on this file since 2029 was 2029, checked in by rub, 17 years ago

Resolved issue 0000697: with generic user a author name is necessary to comment picture.

+ Change way to determinate if user is a guest (use functions like is_admin)

  • 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 2029 2007-06-05 22:01:15Z rub $
7// | last update   : $Date: 2007-06-05 22:01:15 +0000 (Tue, 05 Jun 2007) $
8// | last modifier : $Author: rub $
9// | revision      : $Revision: 2029 $
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, permalink, 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('file', 'name', 'comment') 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' => $cats[$cat_id],
390                  )
391                );
392        $page_url = make_picture_url(
393                array(
394                  'category' => $cats[$cat_id],
395                  'image_id' => $row['id'],
396                  'image_file' => $row['file'],
397                  )
398                );
399        array_push( $image_cats,  array(
400              WS_XML_ATTRIBUTES => array (
401                  'id' => (int)$cat_id,
402                  'url' => $url,
403                  'page_url' => $page_url,
404                )
405            )
406          );
407      }
408
409      $image['categories'] = new PwgNamedArray(
410            $image_cats,'category', array('id','url','page_url')
411          );
412      array_push($images, $image);
413    }
414  }
415
416  return array( 'images' =>
417    array (
418      WS_XML_ATTRIBUTES =>
419        array(
420            'page' => $params['page'],
421            'per_page' => $params['per_page'],
422            'count' => count($images)
423          ),
424       WS_XML_CONTENT => new PwgNamedArray($images, 'image',
425          ws_std_get_image_xml_attributes() )
426      )
427    );
428}
429
430
431/**
432 * returns a list of categories (web service method)
433 */
434function ws_categories_getList($params, &$service)
435{
436  global $user,$conf;
437
438  $where = array();
439
440  if (!$params['recursive'])
441  {
442    if ($params['cat_id']>0)
443      $where[] = '(id_uppercat='.(int)($params['cat_id']).'
444    OR id='.(int)($params['cat_id']).')';
445    else
446      $where[] = 'id_uppercat IS NULL';
447  }
448  else if ($params['cat_id']>0)
449  {
450    $where[] = 'uppercats REGEXP \'(^|,)'.
451      (int)($params['cat_id'])
452      .'(,|$)\'';
453  }
454
455  if ($params['public'])
456  {
457    $where[] = 'status = "public"';
458    $where[] = 'visible = "true"';
459    $where[]= 'user_id='.$conf['guest_id'];
460  }
461  else
462  {
463    $where[] = 'id NOT IN ('.$user['forbidden_categories'].')';
464    $where[]= 'user_id='.$user['id'];
465  }
466
467  $query = '
468SELECT id, name, permalink, uppercats, global_rank,
469    nb_images, count_images AS total_nb_images,
470    date_last, max_date_last, count_categories AS nb_categories
471  FROM '.CATEGORIES_TABLE.'
472   INNER JOIN '.USER_CACHE_CATEGORIES_TABLE.' ON id=cat_id
473  WHERE '. implode('
474    AND ', $where);
475  $query .= '
476ORDER BY global_rank';
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    AND category_id NOT IN ('.$user['forbidden_categories'].')
604;';
605  $result = pwg_query($query);
606  $is_commentable = false;
607  $related_categories = array();
608  while ($row = mysql_fetch_assoc($result))
609  {
610    if ($row['commentable']=='true')
611    {
612      $is_commentable = true;
613    }
614    unset($row['commentable']);
615    $row['url'] = make_index_url(
616        array(
617          'category' => $row
618          )
619      );
620
621    $row['page_url'] = make_picture_url(
622        array(
623          'image_id' => $image_row['id'],
624          'image_file' => $image_row['file'],
625          'category' => $row
626          )
627      );
628    $row['id']=(int)$row['id'];
629    array_push($related_categories, $row);
630  }
631  usort($related_categories, 'global_rank_compare');
632  if ( empty($related_categories) )
633  {
634    return new PwgError(401, 'Access denied');
635  }
636
637  //-------------------------------------------------------------- related tags
638  $related_tags = get_common_tags( array($image_row['id']), -1 );
639  foreach( $related_tags as $i=>$tag)
640  {
641    $tag['url'] = make_index_url(
642        array(
643          'tags' => array($tag)
644          )
645      );
646    $tag['page_url'] = make_picture_url(
647        array(
648          'image_id' => $image_row['id'],
649          'image_file' => $image_row['file'],
650          'tags' => array($tag),
651          )
652      );
653    unset($tag['counter']);
654    $tag['id']=(int)$tag['id'];
655    $related_tags[$i]=$tag;
656  }
657  //------------------------------------------------------------- related rates
658  $query = '
659SELECT COUNT(rate) AS count
660     , ROUND(AVG(rate),2) AS average
661     , ROUND(STD(rate),2) AS stdev
662  FROM '.RATE_TABLE.'
663  WHERE element_id = '.$image_row['id'].'
664;';
665  $rating = mysql_fetch_assoc(pwg_query($query));
666  $rating['count'] = (int)$rating['count'];
667
668  //---------------------------------------------------------- related comments
669  $related_comments = array();
670 
671  $where_comments = 'image_id = '.$image_row['id'];
672  if ( !is_admin() )
673  {
674    $where_comments .= '
675    AND validated="true"';
676  }
677
678  $query = '
679SELECT COUNT(id) nb_comments
680  FROM '.COMMENTS_TABLE.'
681  WHERE '.$where_comments;
682  list($nb_comments) = array_from_query($query, 'nb_comments');
683  $nb_comments = (int)$nb_comments;
684
685  if ( $nb_comments>0 and $params['comments_per_page']>0 )
686  {
687    $query = '
688SELECT id, date, author, content
689  FROM '.COMMENTS_TABLE.'
690  WHERE '.$where_comments.'
691  ORDER BY date
692  LIMIT '.$params['comments_per_page']*(int)$params['comments_page'].
693    ','.$params['comments_per_page'];
694
695    $result = pwg_query($query);
696    while ($row = mysql_fetch_assoc($result))
697    {
698      $row['id']=(int)$row['id'];
699      array_push($related_comments, $row);
700    }
701  }
702 
703  $comment_post_data = null;
704  if ($is_commentable and 
705      (!is_a_guest()
706        or (is_a_guest() and $conf['comments_forall'] )
707      )
708      )
709  {
710    include_once(PHPWG_ROOT_PATH.'include/functions_comment.inc.php');
711    $comment_post_data['author'] = $user['username'];   
712    $comment_post_data['key'] = get_comment_post_key($params['image_id']);
713  }
714
715  $ret = $image_row;
716  foreach ( array('id','width','height','hit','filesize') as $k )
717  {
718    if (isset($ret[$k]))
719    {
720      $ret[$k] = (int)$ret[$k];
721    }
722  }
723  foreach ( array('path', 'storage_category_id') as $k )
724  {
725    unset($ret[$k]);
726  }
727
728  $ret['rates'] = array( WS_XML_ATTRIBUTES => $rating );
729  $ret['categories'] = new PwgNamedArray($related_categories, 'category', array('id','url', 'page_url') );
730  $ret['tags'] = new PwgNamedArray($related_tags, 'tag', array('id','url_name','url','page_url') );
731  if ( isset($comment_post_data) )
732  {
733    $ret['comment_post'] = array( WS_XML_ATTRIBUTES => $comment_post_data );
734  }
735  $ret['comments'] = array(
736     WS_XML_ATTRIBUTES => 
737        array(
738          'page' => $params['comments_page'],
739          'per_page' => $params['comments_per_page'],
740          'count' => count($related_comments),
741          'nb_comments' => $nb_comments,
742        ),
743     WS_XML_CONTENT => new PwgNamedArray($related_comments, 'comment', array('id','date') )
744      );
745
746  return new PwgNamedStruct('image',$ret, null, array('name','comment') );
747}
748
749/**
750 * returns a list of elements corresponding to a query search
751 */
752function ws_images_search($params, &$service)
753{
754  global $page;
755  $images = array();
756  include_once( PHPWG_ROOT_PATH .'include/functions_search.inc.php' );
757  include_once(PHPWG_ROOT_PATH.'include/functions_picture.inc.php');
758
759  $where_clauses = ws_std_image_sql_filter( $params );
760  $order_by = ws_std_image_sql_order($params);
761
762  if ( !empty($where_clauses) and !empty($order_by) )
763  {
764    $page['super_order_by']=1; // quick_search_result might be faster
765  }
766  $search_result = get_quick_search_results($params['query']);
767
768  global $image_ids; //needed for sorting by rank (usort)
769  if ( ( !isset($search_result['as_is'])
770      or !empty($where_clauses)
771      or !empty($order_by) )
772      and !empty($search_result['items']) )
773  {
774    $where_clauses[] = 'id IN ('
775        .wordwrap(implode(', ', $search_result['items']), 80, "\n")
776        .')';
777    $where_clauses[] = get_sql_condition_FandF(
778        array
779          (
780            'forbidden_categories' => 'category_id',
781            'visible_categories' => 'category_id',
782            'visible_images' => 'id'
783          ),
784        '', true
785      );
786    $query = '
787SELECT DISTINCT id FROM '.IMAGES_TABLE.' INNER JOIN '.IMAGE_CATEGORY_TABLE.' ON id=image_id
788  WHERE '.implode('
789    AND ', $where_clauses);
790    if (!empty($order_by))
791    {
792      $query .= '
793  ORDER BY '.$order_by;
794    }
795    $image_ids = array_from_query($query, 'id');
796    global $ranks;
797    $ranks = array_flip( $search_result['items'] );
798    usort(
799      $image_ids,
800      create_function('$i1,$i2', 'global $ranks; return $ranks[$i1]-$ranks[$i2];')
801    );
802    unset ($ranks);
803  }
804  else
805  {
806    $image_ids = $search_result['items'];
807  }
808 
809  $image_ids = array_slice($image_ids,
810    $params['page']*$params['per_page'],
811    $params['per_page'] );
812
813  if ( count($image_ids) )
814  {
815    $query = '
816SELECT * FROM '.IMAGES_TABLE.'
817  WHERE id IN ('
818        .wordwrap(implode(', ', $image_ids), 80, "\n")
819        .')';
820
821    $result = pwg_query($query);
822    while ($row = mysql_fetch_assoc($result))
823    {
824      $image = array();
825      foreach ( array('id', 'width', 'height', 'hit') as $k )
826      {
827        if (isset($row[$k]))
828        {
829          $image[$k] = (int)$row[$k];
830        }
831      }
832      foreach ( array('file', 'name', 'comment') as $k )
833      {
834        $image[$k] = $row[$k];
835      }
836      $image = array_merge( $image, ws_std_get_urls($row) );
837      array_push($images, $image);
838    }
839
840    $image_ids = array_flip($image_ids);
841    usort(
842        $images,
843        create_function('$i1,$i2', 'global $image_ids; return $image_ids[$i1["id"]]-$image_ids[$i2["id"]];')
844      );
845  }
846
847
848  return array( 'images' =>
849    array (
850      WS_XML_ATTRIBUTES =>
851        array(
852            'page' => $params['page'],
853            'per_page' => $params['per_page'],
854            'count' => count($images)
855          ),
856       WS_XML_CONTENT => new PwgNamedArray($images, 'image',
857          ws_std_get_image_xml_attributes() )
858      )
859    );
860}
861
862/**
863 * perform a login (web service method)
864 */
865function ws_session_login($params, &$service)
866{
867  global $conf;
868
869  if (!$service->isPost())
870  {
871    return new PwgError(405, "This method requires HTTP POST");
872  }
873  if (try_log_user($params['username'], $params['password'],false))
874  {
875    return true;
876  }
877  return new PwgError(999, 'Invalid username/password');
878}
879
880
881/**
882 * performs a logout (web service method)
883 */
884function ws_session_logout($params, &$service)
885{
886  global $user, $conf;
887  if (!is_a_guest())
888  {
889    $_SESSION = array();
890    session_unset();
891    session_destroy();
892    setcookie(session_name(),'',0,
893        ini_get('session.cookie_path'),
894        ini_get('session.cookie_domain')
895      );
896    setcookie($conf['remember_me_name'], '', 0, cookie_path());
897  }
898  return true;
899}
900
901function ws_session_getStatus($params, &$service)
902{
903  global $user, $lang_info;
904  $res = array();
905  $res['username'] = is_a_guest() ? 'guest' : $user['username'];
906  foreach ( array('status', 'template', 'theme', 'language') as $k )
907  {
908    $res[$k] = $user[$k];
909  }
910  foreach ( array('charset') as $k )
911  {
912    $res[$k] = $lang_info[$k];
913  }
914  return $res;
915}
916
917
918/**
919 * returns a list of tags (web service method)
920 */
921function ws_tags_getList($params, &$service)
922{
923  $tags = get_available_tags();
924  if ($params['sort_by_counter'])
925  {
926    usort($tags, create_function('$a,$b', 'return -$a["counter"]+$b["counter"];') );
927  }
928  else
929  {
930    usort($tags, 'name_compare');
931  }
932  for ($i=0; $i<count($tags); $i++)
933  {
934    $tags[$i]['id'] = (int)$tags[$i]['id'];
935    $tags[$i]['counter'] = (int)$tags[$i]['counter'];
936    $tags[$i]['url'] = make_index_url(
937        array(
938          'section'=>'tags',
939          'tags'=>array($tags[$i])
940        )
941      );
942  }
943  return array('tags' => new PwgNamedArray($tags, 'tag', array('id','url_name','url', 'counter' )) );
944}
945
946
947/**
948 * returns a list of images for tags (web service method)
949 */
950function ws_tags_getImages($params, &$service)
951{
952  @include_once(PHPWG_ROOT_PATH.'include/functions_picture.inc.php');
953  global $conf;
954 
955  // first build all the tag_ids we are interested in
956  $params['tag_id'] = array_map( 'intval',$params['tag_id'] );
957  $tags = find_tags($params['tag_id'], $params['tag_url_name'], $params['tag_name']);
958  $tags_by_id = array();
959  foreach( $tags as $tag )
960  {
961    $tags['id'] = (int)$tag['id'];
962    $tags_by_id[ $tag['id'] ] = $tag;
963  }
964  unset($tags);
965  $tag_ids = array_keys($tags_by_id);
966
967
968  $image_ids = array();
969  $image_tag_map = array();
970
971  if ( !empty($tag_ids) )
972  { // build list of image ids with associated tags per image
973    if ($params['tag_mode_and'])
974    {
975      $image_ids = get_image_ids_for_tags( $tag_ids );
976    }
977    else
978    {
979      $query = '
980SELECT image_id, GROUP_CONCAT(tag_id) tag_ids
981  FROM '.IMAGE_TAG_TABLE.'
982  WHERE tag_id IN ('.implode(',',$tag_ids).')
983  GROUP BY image_id';
984      $result = pwg_query($query);
985      while ( $row=mysql_fetch_assoc($result) )
986      {
987        $row['image_id'] = (int)$row['image_id'];
988        array_push( $image_ids, $row['image_id'] );
989        $image_tag_map[ $row['image_id'] ] = explode(',', $row['tag_ids']);
990      }
991    }
992  }
993
994  $images = array();
995  if ( !empty($image_ids))
996  {
997    $where_clauses = ws_std_image_sql_filter($params);
998    $where_clauses[] = get_sql_condition_FandF(
999        array
1000          (
1001            'forbidden_categories' => 'category_id',
1002            'visible_categories' => 'category_id',
1003            'visible_images' => 'i.id'
1004          ),
1005        '', true
1006      );
1007    $where_clauses[] = 'id IN ('.implode(',',$image_ids).')';
1008    $where_clauses[] = ws_addControls( 'tags.getImages', $params, 'i.' );
1009
1010    $order_by = ws_std_image_sql_order($params);
1011    if (empty($order_by))
1012    {
1013      $order_by = $conf['order_by'];
1014    }
1015    else
1016    {
1017      $order_by = 'ORDER BY '.$order_by;
1018    }
1019
1020    $query = '
1021SELECT DISTINCT i.* FROM '.IMAGES_TABLE.' i
1022  INNER JOIN '.IMAGE_CATEGORY_TABLE.' ON i.id=image_id
1023  WHERE '. implode('
1024    AND ', $where_clauses).'
1025'.$order_by.'
1026LIMIT '.$params['per_page']*$params['page'].','.$params['per_page'];
1027
1028    $result = pwg_query($query);
1029    while ($row = mysql_fetch_assoc($result))
1030    {
1031      foreach ( array('id', 'width', 'height', 'hit') as $k )
1032      {
1033        if (isset($row[$k]))
1034        {
1035          $image[$k] = (int)$row[$k];
1036        }
1037      }
1038      foreach ( array('file', 'name', 'comment') as $k )
1039      {
1040        $image[$k] = $row[$k];
1041      }
1042      $image = array_merge( $image, ws_std_get_urls($row) );
1043
1044      $image_tag_ids = ($params['tag_mode_and']) ? $tag_ids : $image_tag_map[$image['id']];
1045      $image_tags = array();
1046      foreach ($image_tag_ids as $tag_id)
1047      {
1048        $url = make_index_url(
1049                 array(
1050                  'section'=>'tags',
1051                  'tags'=> array($tags_by_id[$tag_id])
1052                )
1053              );
1054        $page_url = make_picture_url(
1055                 array(
1056                  'section'=>'tags',
1057                  'tags'=> array($tags_by_id[$tag_id]),
1058                  'image_id' => $row['id'],
1059                  'image_file' => $row['file'],
1060                )
1061              );
1062        array_push($image_tags, array(
1063                'id' => (int)$tag_id,
1064                'url' => $url,
1065                'page_url' => $page_url,
1066              )
1067            );
1068      }
1069      $image['tags'] = new PwgNamedArray($image_tags, 'tag',
1070              array('id','url_name','url','page_url')
1071            );
1072      array_push($images, $image);
1073    }
1074  }
1075
1076  return array( 'images' =>
1077    array (
1078      WS_XML_ATTRIBUTES =>
1079        array(
1080            'page' => $params['page'],
1081            'per_page' => $params['per_page'],
1082            'count' => count($images)
1083          ),
1084       WS_XML_CONTENT => new PwgNamedArray($images, 'image',
1085          ws_std_get_image_xml_attributes() )
1086      )
1087    );
1088}
1089
1090
1091/**
1092 * expand_id_list($ids) convert a human list expression to a full ordered list
1093 * example : expand_id_list( array(5,2-3,2) ) returns array( 2, 3, 5)
1094 * */
1095function expand_id_list($ids)
1096{
1097  $tid = array();
1098  foreach ( $ids as $id )
1099  {
1100    if ( is_numeric($id) )
1101    {
1102      $tid[] = (int) $id;
1103    }
1104    else
1105    {
1106      $range = explode( '-', $id );
1107      if ( is_numeric($range[0]) and is_numeric($range[1]) )
1108      {
1109        $from = min($range[0],$range[1]);
1110        $to = max($range[0],$range[1]);
1111        for ($i = $from; $i <= $to; $i++)
1112        {
1113          $tid[] = (int) $i;
1114        }
1115      }
1116    }
1117  }
1118  $result = array_unique ($tid); // remove duplicates...
1119  sort ($result);
1120  return $result;
1121}
1122
1123
1124/**
1125 * converts a cat-ids array in image-ids array
1126 * FIXME Function which should already exist somewhere else
1127 * */
1128function get_image_ids_for_cats($cat_ids)
1129{
1130  $cat_list = implode(',', $cat_ids);
1131  $ret_ids = array();
1132  $query = '
1133  SELECT DISTINCT image_id
1134    FROM '.IMAGE_CATEGORY_TABLE.'
1135  WHERE category_id in ('.$cat_list.')
1136  ;';
1137  return array_from_query($query, 'image_id');
1138}
1139
1140?>
Note: See TracBrowser for help on using the repository browser.