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

Last change on this file since 2297 was 2297, checked in by plg, 16 years ago

Modification: new header on PHP files, PhpWebGallery renamed Piwigo.

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