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

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