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

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

Web service first version.

  • Property svn:eol-style set to native
File size: 19.7 KB
Line 
1<?php
2// +-----------------------------------------------------------------------+
3// | PhpWebGallery - a PHP based picture gallery                           |
4// | Copyright (C) 2003-2007 PhpWebGallery Team - http://phpwebgallery.net |
5// +-----------------------------------------------------------------------+
6// | branch        : BSF (Best So Far)
7// | file          : $URL: svn+ssh://rvelices@svn.gna.org/svn/phpwebgallery/trunk/action.php $
8// | last update   : $Date: 2006-12-21 18:49:12 -0500 (Thu, 21 Dec 2006) $
9// | last modifier : $Author: rvelices $
10// | revision      : $Rev: 1678 $
11// +-----------------------------------------------------------------------+
12// | This program is free software; you can redistribute it and/or modify  |
13// | it under the terms of the GNU General Public License as published by  |
14// | the Free Software Foundation                                          |
15// |                                                                       |
16// | This program is distributed in the hope that it will be useful, but   |
17// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
18// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
19// | General Public License for more details.                              |
20// |                                                                       |
21// | You should have received a copy of the GNU General Public License     |
22// | along with this program; if not, write to the Free Software           |
23// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
24// | USA.                                                                  |
25// +-----------------------------------------------------------------------+
26
27/**** IMPLEMENTATION OF WEB SERVICE METHODS ***********************************/
28
29/**
30 * returns a "standard" (for our web service) array of sql where clauses that
31 * filters the images (images table only)
32 */ 
33function ws_std_image_sql_filter( $params, $tbl_name='' )
34{
35  $clauses = array();
36  if ( is_numeric($params['f_min_rate']) )
37  {
38    $clauses[] = $tbl_name.'average_rate>'.$params['f_min_rate'];
39  }
40  if ( is_numeric($params['f_max_rate']) )
41  {
42    $clauses[] = $tbl_name.'average_rate<='.$params['f_max_rate'];
43  }
44  if ( is_numeric($params['f_min_hit']) )
45  {
46    $clauses[] = $tbl_name.'hit>'.$params['f_min_hit'];
47  }
48  if ( is_numeric($params['f_max_hit']) )
49  {
50    $clauses[] = $tbl_name.'hit<='.$params['f_max_hit'];
51  }
52  if ( isset($params['f_min_date_posted']) )
53  {
54    $clauses[] = $tbl_name."date_available>='".$params['f_min_date_posted']."'";
55  }
56  if ( isset($params['f_max_date_posted']) )
57  {
58    $clauses[] = $tbl_name."date_available<'".$params['f_max_date_posted']."'";
59  }
60  if ( isset($params['f_min_date_created']) )
61  {
62    $clauses[] = $tbl_name."date_creation>='".$params['f_min_date_created']."'";
63  }
64  if ( isset($params['f_max_date_created']) )
65  {
66    $clauses[] = $tbl_name."date_creation<'".$params['f_max_date_created']."'";
67  }
68  if ( is_numeric($params['f_min_ratio']) )
69  {
70    $clauses[] = $tbl_name.'width/'.$tbl_name.'height>'.$params['f_min_ratio'];
71  }
72  if ( is_numeric($params['f_max_ratio']) )
73  {
74    $clauses[] = $tbl_name.'width/'.$tbl_name.'height<='.$params['f_max_ratio'];
75  }
76  if ( $params['f_with_thumbnail'] )
77  {
78    $clauses[] = $tbl_name.'tn_ext IS NOT NULL';
79  }
80  return $clauses;
81}
82
83/**
84 * returns a "standard" (for our web service) ORDER BY sql clause for images
85 */ 
86function ws_std_image_sql_order( $params, $tbl_name='' )
87{
88  $ret = '';
89  if ( empty($params['order']) )
90  {
91    return $ret;
92  }
93  $matches = array();
94  preg_match_all('/([a-z_]+) *(?:(asc|desc)(?:ending)?)? *(?:, *|$)/i',
95    $params['order'], $matches);
96  for ($i=0; $i<count($matches[1]); $i++)
97  {
98    switch ($matches[1][$i])
99    {
100      case 'date_created':
101        $matches[1][$i] = 'date_creation'; break;
102      case 'date_posted':
103        $matches[1][$i] = 'date_available'; break;
104      case 'rand': case 'random':
105        $matches[1][$i] = 'RAND()'; break;
106    }
107    $sortable_fields = array('id', 'file', 'name', 'hit', 'average_rate', 
108      'date_creation', 'date_available', 'RAND()' );
109    if ( in_array($matches[1][$i], $sortable_fields) )
110    {
111      if (!empty($ret))
112        $ret .= ', ';
113      if ($matches[1][$i] != 'RAND()' )
114      {
115        $ret .= $tbl_name;
116      }
117      $ret .= $matches[1][$i];
118      $ret .= ' '.$matches[2][$i];
119    }
120  }
121  return $ret;
122}
123
124/**
125 * returns an array map of urls (thumb/element) for image_row - to be returned
126 * in a standard way by different web service methods
127 */ 
128function ws_std_get_urls($image_row)
129{
130  $ret = array(
131    'tn_url' => get_thumbnail_url($image_row), 
132    'element_url' => get_element_url($image_row)
133  );
134  global $user;
135  if ($user['enabled_high'] and $image_row['has_high'] )
136  {
137    $ret['high_url'] = get_high_url($image_row);
138  }
139  return $ret;
140}
141
142
143function ws_getVersion($params, &$service)
144{
145  return PHPWG_VERSION;
146}
147
148/**
149 * returns images per category (wb service method)
150 */ 
151function ws_categories_getImages($params, &$service)
152{
153  @include_once(PHPWG_ROOT_PATH.'include/functions_picture.inc.php');
154  global $user, $conf;
155
156  $images = array();
157
158  //------------------------------------------------- get the related categories
159  $where_clauses = array();
160  foreach($params['cat_id'] as $cat_id)
161  {
162    $cat_id = (int)$cat_id;
163    if ($cat_id<=0)
164      continue;
165    if ($params['recursive'])
166    {
167      $where_clauses[] = 'uppercats REGEXP \'(^|,)'.$cat_id.'(,|$)\'';
168    }
169    else
170    {
171      $where_clauses[] = 'id='.$cat_id;
172    }
173  }
174  if (!empty($where_clauses))
175  {
176    $where_clauses = array( '('.
177    implode('
178    OR ', $where_clauses) . ')'
179      );
180  }
181  $where_clauses[] = 'id NOT IN ('.$user['forbidden_categories'].')';
182
183  $query = '
184SELECT id, name, image_order
185  FROM '.CATEGORIES_TABLE.'
186  WHERE '. implode('
187    AND ', $where_clauses);
188  $result = pwg_query($query);
189  $cats = array();
190  while ($row = mysql_fetch_assoc($result))
191  {
192    $row['id'] = (int)$row['id'];
193    $cats[ $row['id'] ] = $row;
194  }
195
196  //-------------------------------------------------------- get the images
197  if ( !empty($cats) )
198  {
199    $where_clauses = ws_std_image_sql_filter( $params, 'i.' );
200    $where_clauses[] = 'category_id IN ('
201      .implode(',', array_keys($cats) )
202      .')';
203    $order_by = ws_std_image_sql_order($params, 'i.');
204    if (empty($order_by))
205    {// TODO check for category order by (image_order)
206      $order_by = $conf['order_by'];
207    }
208    else
209    {
210      $order_by = 'ORDER BY '.$order_by;
211    }
212    $query = '
213SELECT i.*, GROUP_CONCAT(category_id) cat_ids
214  FROM '.IMAGES_TABLE.' i
215    INNER JOIN '.IMAGE_CATEGORY_TABLE.' ON i.id=image_id
216  WHERE '. implode('
217    AND ', $where_clauses).'
218GROUP BY i.id
219'.$order_by.'
220LIMIT '.$params['per_page']*$params['page'].','.$params['per_page'];
221
222    $result = pwg_query($query);
223    while ($row = mysql_fetch_assoc($result))
224    {
225      $image = array();
226      foreach ( array('id', 'width', 'height', 'hit') as $k )
227      {
228        if (isset($row[$k]))
229        {
230          $image[$k] = (int)$row[$k];
231        }
232      }
233      foreach ( array('name', 'file') as $k )
234      {
235        $image[$k] = $row[$k];
236      }
237      $image = array_merge( $image, ws_std_get_urls($row) );
238
239      $image_cats = array();
240      foreach ( explode(',', $row['cat_ids']) as $cat_id )
241      {
242        $url = make_index_url(
243                array(
244                  'category' => $cat_id,
245                  'cat_name' => $cats[$cat_id]['name'],
246                  )
247                );
248        $page_url = make_picture_url(
249                array(
250                  'category' => $cat_id,
251                  'cat_name' => $cats[$cat_id]['name'],
252                  'image_id' => $row['id'],
253                  'image_file' => $row['file'],
254                  )
255                );
256        array_push( $image_cats,  array(
257              WS_XML_ATTRIBUTES => array (
258                  'id' => (int)$cat_id,
259                  'url' => $url,
260                  'page_url' => $page_url,
261                )
262            )
263          );
264      }
265
266      $image['categories'] = new PwgNamedArray(
267            $image_cats,'category', array('id','url','page_url')
268          );
269      array_push($images, $image);
270    }
271  }
272
273  return array( 'images' =>
274    array (
275      WS_XML_ATTRIBUTES =>
276        array(
277            'page' => $params['page'],
278            'per_page' => $params['per_page'],
279            'count' => count($images)
280          ),
281       WS_XML_CONTENT => new PwgNamedArray($images, 'image', 
282          array('id', 'tn_url', 'element_url', 'file','width','height','hit') )
283      )
284    );
285}
286
287/**
288 * returns a list of categories
289 */
290function ws_categories_getList($params, &$service)
291{
292  global $user;
293 
294  $query = '
295SELECT id, name, uppercats, global_rank,
296    max_date_last, count_images AS nb_images, count_categories AS nb_categories
297  FROM '.CATEGORIES_TABLE.'
298   INNER JOIN '.USER_CACHE_CATEGORIES_TABLE.' ON id=cat_id';
299
300  $where = array();
301  $where[]= 'user_id='.$user['id'];
302  if ($params['cat_id']>0)
303  {
304    $where[] = 'uppercats REGEXP \'(^|,)'.
305      (int)($params['cat_id'])
306      .'(,|$)\'';
307  }
308
309  if (!$params['recursive'])
310  {
311    if ($params['cat_id']>0)
312      $where[] = 'id_uppercat='.(int)($params['cat_id']);
313    else
314      $where[] = 'id_uppercat IS NULL';
315  }
316
317  if ($params['public'])
318  {
319    $where[] = 'status = "public"';
320  }
321  else
322  {
323    $where[] = 'id NOT IN ('.$user['forbidden_categories'].')';
324  }
325
326  $query .= '
327  WHERE '. implode('
328    AND ', $where);
329  $query .= '
330ORDER BY global_rank';
331
332  $result = pwg_query($query);
333
334  $cats = array();
335  while ($row = mysql_fetch_assoc($result))
336  {
337    $row['url'] = make_index_url(
338        array(
339          'category' => $row['id'],
340          'cat_name' => $row['name'],
341          )
342      );
343    foreach( array('id','nb_images','nb_categories') as $key)
344    {
345      $row[$key] = (int)$row[$key];
346    }
347    array_push($cats, $row);
348  }
349  usort($cats, 'global_rank_compare');
350  return array(
351      'categories' =>
352          new PwgNamedArray($cats,'category', 
353            array('id','url','nb_images','nb_categories','max_date_last')
354          )
355    );
356}
357
358function ws_images_getInfo($params, &$service)
359{
360  @include_once(PHPWG_ROOT_PATH.'include/functions_picture.inc.php');
361  global $user;
362  $params['image_id'] = (int)$params['image_id'];
363  if ( $params['image_id']<=0 )
364  {
365    return new PwgError(WS_ERR_INVALID_PARAM, "Invalid image_id");
366  }
367  $query='
368SELECT * FROM '.IMAGES_TABLE.'
369  WHERE id='.$params['image_id'].'
370LIMIT 1';
371  $image_row = mysql_fetch_assoc(pwg_query($query));
372  if ($image_row==null)
373  {
374    return new PwgError(999, "image_id not found");
375  }
376  array_merge( $image_row, ws_std_get_urls($image_row) );
377
378  //-------------------------------------------------------- related categories
379  $query = '
380SELECT c.id,c.name,c.uppercats,c.global_rank
381  FROM '.IMAGE_CATEGORY_TABLE.'
382    INNER JOIN '.CATEGORIES_TABLE.' c ON category_id = id
383  WHERE image_id = '.$image_row['id'].'
384    AND category_id NOT IN ('.$user['forbidden_categories'].')
385;';
386  $result = pwg_query($query);
387  $related_categories = array();
388  while ($row = mysql_fetch_assoc($result))
389  {
390    $row['url'] = make_index_url(
391        array(
392          'category' => $row['id'],
393          'cat_name' => $row['name'],
394          )
395      );
396
397    $row['page_url'] = make_picture_url(
398        array(
399          'image_id' => $image_row['id'],
400          'image_file' => $image_row['file'],
401          'category' => $row['id'],
402          'cat_name' => $row['name'],
403          )
404      );
405    array_push($related_categories, $row);
406  }
407  usort($related_categories, 'global_rank_compare');
408  if ( empty($related_categories) )
409  {
410    return new PwgError(401, 'Access denied');
411  }
412
413  //-------------------------------------------------------------- related tags
414  $query = '
415SELECT id, name, url_name
416  FROM '.IMAGE_TAG_TABLE.'
417    INNER JOIN '.TAGS_TABLE.' ON tag_id = id
418  WHERE image_id = '.$image_row['id'].'
419;';
420  $result = pwg_query($query);
421  $related_tags = array();
422  while ($row = mysql_fetch_assoc($result))
423  {
424    $row['url'] = make_index_url(
425        array(
426          'tags' => array($row)
427          )
428      );
429    $row['page_url'] = make_picture_url(
430        array(
431          'image_id' => $image_row['id'],
432          'image_file' => $image_row['file'],
433          'tags' => array($row),
434          )
435      );
436    array_push($related_tags, $row);
437  }
438  //---------------------------------------------------------- related comments
439  $query = '
440SELECT COUNT(id) nb_comments
441  FROM '.COMMENTS_TABLE.'
442  WHERE image_id = '.$image_row['id'];
443  list($nb_comments) = array_from_query($query, 'nb_comments');
444
445  $query = '
446SELECT id, date, author, content
447  FROM '.COMMENTS_TABLE.'
448  WHERE image_id = '.$image_row['id'].'
449    AND validated="true"';
450  $query .= '
451  ORDER BY date DESC
452  LIMIT 0, 5';
453
454  $result = pwg_query($query);
455  $related_comments = array();
456  while ($row = mysql_fetch_assoc($result))
457  {
458    array_push($related_comments, $row);
459  }
460
461  //------------------------------------------------------------- related rates
462  $query = '
463SELECT COUNT(rate) AS count
464     , ROUND(AVG(rate),2) AS average
465     , ROUND(STD(rate),2) AS stdev
466  FROM '.RATE_TABLE.'
467  WHERE element_id = '.$image_row['id'].'
468;';
469  $row = mysql_fetch_assoc(pwg_query($query));
470
471  $ret = $image_row;
472  $ret['rates'] = array( WS_XML_ATTRIBUTES => $row );
473  $ret['categories'] = new PwgNamedArray($related_categories, 'category', array('id','url', 'page_url') );
474  $ret['tags'] = new PwgNamedArray($related_tags, 'tag', array('id','url_name','url','page_url') );
475  $ret['comments'] = array(
476     WS_XML_ATTRIBUTES => array('nb_comments' => $nb_comments),
477     WS_XML_CONTENT => new PwgNamedArray($related_comments, 'comment', array('id') )
478      );
479  unset($ret['path']);
480  unset($ret['storage_category_id']);
481  return new PwgNamedStruct('image',$ret, null, array('name','comment') );
482}
483
484
485function ws_session_login($params, &$service)
486{
487  global $conf;
488
489  if (!$service->isPost())
490  {
491    return new PwgError(400, "This method requires POST");
492  }
493
494  $username = $params['username'];
495  // retrieving the encrypted password of the login submitted
496  $query = '
497SELECT '.$conf['user_fields']['id'].' AS id,
498       '.$conf['user_fields']['password'].' AS password
499  FROM '.USERS_TABLE.'
500  WHERE '.$conf['user_fields']['username'].' = \''.$username.'\'
501;';
502  $row = mysql_fetch_assoc(pwg_query($query));
503
504  if ($row['password'] == $conf['pass_convert']($params['password']))
505  {
506    log_user($row['id'], false);
507    return true;
508  }
509  return new PwgError(999, 'Invalid username/password');
510}
511
512function ws_session_logout($params, &$service)
513{
514  global $user, $conf;
515  if (!$user['is_the_guest'])
516  {
517    $_SESSION = array();
518    session_unset();
519    session_destroy();
520    setcookie(session_name(),'',0,
521        ini_get('session.cookie_path'),
522        ini_get('session.cookie_domain')
523      );
524    setcookie($conf['remember_me_name'], '', 0, cookie_path());
525  }
526  return true;
527}
528
529function ws_session_getStatus($params, &$service)
530{
531  global $user;
532  $res = array();
533  $res['username'] = $user['is_the_guest'] ? 'guest' : $user['username'];
534  $res['status'] = $user['status'];
535  return $res;
536}
537
538
539function ws_tags_getList($params, &$service)
540{
541  global $user;
542  $tags = get_available_tags(explode(',', $user['forbidden_categories']));
543  if ($params['sort_by_counter'])
544  {
545    usort($tags, create_function('$a,$b', 'return -$a["counter"]+$b["counter"];') );
546  }
547  else
548  {
549    usort($tags, 'name_compare');
550  }
551  for ($i=0; $i<count($tags); $i++)
552  {
553    $tags[$i]['id'] = (int)$tags[$i]['tag_id'];
554    $tags[$i]['counter'] = (int)$tags[$i]['counter'];
555    unset($tags[$i]['tag_id']);
556    $tags[$i]['url'] = make_index_url(
557        array(
558          'section'=>'tags',
559          'tags'=>array($tags[$i])
560        )
561      );
562  }
563  return array('tags' => new PwgNamedArray($tags, 'tag', array('id','url_name','url', 'counter' )) );
564}
565
566function ws_tags_getImages($params, &$service)
567{
568  @include_once(PHPWG_ROOT_PATH.'include/functions_picture.inc.php');
569  global $user, $conf;
570
571  // first build all the tag_ids we are interested in
572  $tag_ids = array();
573  $tags = get_available_tags();
574  $tags_by_id = array();
575  for( $i=0; $i<count($tags); $i++ )
576  {
577    $tags[$i]['tag_id']=(int)$tags[$i]['tag_id'];
578    $tags[$i]['id']=(int)$tags[$i]['tag_id']; //required by make_xxx_url
579  }
580  foreach( $tags as $tag )
581  {
582    $tags_by_id[ $tag['tag_id'] ] = $tag;
583    if (
584        in_array($tag['name'], $params['tag_name'])
585      or
586        in_array($tag['url_name'], $params['tag_url_name'])
587       )
588    {
589      $tag_ids[] = $tag['tag_id'];
590    }
591  }
592  unset($tags);
593
594  foreach( $params['tag_id'] as $tag_id )
595  {
596    if ( (int)$tag_id > 0 )
597    {
598      $tag_ids[] = $tag_id;
599    }
600  }
601
602  $tag_ids = array_unique( $tag_ids );
603
604  $image_ids = array();
605  $image_tag_map = array();
606
607  if ( !empty($tag_ids) )
608  { // build list of image ids with associated tags per image
609    if ($params['tag_mode_and'])
610    {
611      $image_ids = get_image_ids_for_tags( $tag_ids );
612    }
613    else
614    {
615      $query = '
616SELECT image_id, GROUP_CONCAT(tag_id) tag_ids
617  FROM '.IMAGE_TAG_TABLE.'
618  WHERE tag_id IN ('.implode(',',$tag_ids).')
619  GROUP BY image_id';
620      $result = pwg_query($query);
621      while ( $row=mysql_fetch_assoc($result) )
622      {
623        $row['image_id'] = (int)$row['image_id'];
624        array_push( $image_ids, $row['image_id'] );
625        $image_tag_map[ $row['image_id'] ] = explode(',', $row['tag_ids']);
626      }
627    }
628  }
629
630  $images = array();
631  if ( !empty($image_ids))
632  {
633    $where_clauses = ws_std_image_sql_filter($params);
634    $where_clauses[] = 'category_id NOT IN ('.$user['forbidden_categories'].')';
635    $where_clauses[] = 'id IN ('.implode(',',$image_ids).')';
636    $order_by = ws_std_image_sql_order($params);
637    if (empty($order_by))
638    {
639      $order_by = $conf['order_by'];
640    }
641    else
642    {
643      $order_by = 'ORDER BY '.$order_by;
644    }
645
646    $query = '
647SELECT DISTINCT i.* FROM '.IMAGES_TABLE.' i
648  INNER JOIN '.IMAGE_CATEGORY_TABLE.' ON i.id=image_id
649  WHERE '. implode('
650    AND ', $where_clauses).'
651'.$order_by.'
652LIMIT '.$params['per_page']*$params['page'].','.$params['per_page'];
653
654    $result = pwg_query($query);
655    while ($row = mysql_fetch_assoc($result))
656    {
657      foreach ( array('id', 'width', 'height', 'hit') as $k )
658      {
659        if (isset($row[$k]))
660        {
661          $image[$k] = (int)$row[$k];
662        }
663      }
664      foreach ( array('name', 'file') as $k )
665      {
666        $image[$k] = $row[$k];
667      }
668      $image = array_merge( $image, ws_std_get_urls($row) );
669
670      $image_tag_ids = ($params['tag_mode_and']) ? $tag_ids : $image_tag_map[$image['id']];
671      $image_tags = array();
672      foreach ($image_tag_ids as $tag_id)
673      {
674        $url = make_index_url(
675                 array(
676                  'section'=>'tags',
677                  'tags'=> array($tags_by_id[$tag_id])
678                )
679              );
680        $page_url = make_picture_url(
681                 array(
682                  'section'=>'tags',
683                  'tags'=> array($tags_by_id[$tag_id]),
684                  'image_id' => $row['id'],
685                  'image_file' => $row['file'],
686                )
687              );
688        array_push($image_tags, array(
689                'id' => (int)$tag_id,
690                'url' => $url,
691                'page_url' => $page_url,
692              )
693            );
694      }
695      $image['tags'] = new PwgNamedArray($image_tags, 'tag', 
696              array('id','url_name','url','page_url') 
697            );
698      array_push($images, $image);
699    }
700  }
701
702  return array( 'images' =>
703    array (
704      WS_XML_ATTRIBUTES =>
705        array(
706            'page' => $params['page'],
707            'per_page' => $params['per_page'],
708            'count' => count($images)
709          ),
710       WS_XML_CONTENT => new PwgNamedArray($images, 'image', 
711          array('id', 'tn_url', 'element_url', 'file','width','height','hit') )
712      )
713    );
714}
715
716?>
Note: See TracBrowser for help on using the repository browser.