source: trunk/include/functions_tag.inc.php @ 2362

Last change on this file since 2362 was 2308, checked in by rvelices, 16 years ago
  • minor sql query optimizations
  • Property svn:eol-style set to LF
  • Property svn:keywords set to Author Date Id Revision
File size: 7.7 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
25/**
26 * Tags available. Each return tag is represented as an array with its id,
27 * its name, its weight (count), its url name. Tags are not sorted.
28 *
29 * The returned list can be a subset of all existing tags due to
30 * permissions, only if a list of forbidden categories is provided
31 *
32 * @param array forbidden categories
33 * @return array
34 */
35function get_available_tags()
36{
37  // we can find top fatter tags among reachable images
38  $query = '
39SELECT tag_id, COUNT(DISTINCT(it.image_id)) counter
40  FROM '.IMAGE_CATEGORY_TABLE.' ic
41    INNER JOIN '.IMAGE_TAG_TABLE.' it ON ic.image_id=it.image_id'.get_sql_condition_FandF
42    (
43      array
44        (
45          'forbidden_categories' => 'category_id',
46          'visible_categories' => 'category_id',
47          'visible_images' => 'ic.image_id'
48        ),
49      '
50  WHERE'
51    ).'
52  GROUP BY tag_id
53  ORDER BY NULL';
54  $tag_counters = simple_hash_from_query($query, 'tag_id', 'counter');
55
56  if ( empty($tag_counters) )
57  {
58    return array();
59  }
60
61  $query = '
62SELECT id, name, url_name
63  FROM '.TAGS_TABLE;
64  $result = pwg_query($query);
65  $tags = array();
66  while ($row = mysql_fetch_assoc($result))
67  {
68    $counter = @$tag_counters[ $row['id'] ];
69    if ( $counter )
70    {
71      $row['counter'] = $counter;
72      array_push($tags, $row);
73    }
74  }
75  return $tags;
76}
77
78/**
79 * All tags, even tags associated to no image.
80 *
81 * @return array
82 */
83function get_all_tags()
84{
85  $query = '
86SELECT id,
87       name,
88       url_name
89  FROM '.TAGS_TABLE.'
90;';
91  $result = pwg_query($query);
92  $tags = array();
93  while ($row = mysql_fetch_assoc($result))
94  {
95    array_push($tags, $row);
96  }
97
98  usort($tags, 'name_compare');
99
100  return $tags;
101}
102
103/**
104 * Giving a set of tags with a counter for each one, calculate the display
105 * level of each tag.
106 *
107 * The level of each tag depends on the average count of tags. This
108 * calcylation method avoid having very different levels for tags having
109 * nearly the same count when set are small.
110 *
111 * @param array tags
112 * @return array
113 */
114function add_level_to_tags($tags)
115{
116  global $conf;
117
118  if (count($tags) == 0)
119  {
120    return $tags;
121  }
122
123  $total_count = 0;
124
125  foreach ($tags as $tag)
126  {
127    $total_count+= $tag['counter'];
128  }
129
130  // average count of available tags will determine the level of each tag
131  $tag_average_count = $total_count / count($tags);
132
133  // tag levels threshold calculation: a tag with an average rate must have
134  // the middle level.
135  for ($i = 1; $i < $conf['tags_levels']; $i++)
136  {
137    $threshold_of_level[$i] =
138      2 * $i * $tag_average_count / $conf['tags_levels'];
139  }
140
141  // display sorted tags
142  foreach (array_keys($tags) as $k)
143  {
144    $tags[$k]['level'] = 1;
145
146    // based on threshold, determine current tag level
147    for ($i = $conf['tags_levels'] - 1; $i >= 1; $i--)
148    {
149      if ($tags[$k]['counter'] > $threshold_of_level[$i])
150      {
151        $tags[$k]['level'] = $i + 1;
152        break;
153      }
154    }
155  }
156
157  return $tags;
158}
159
160/**
161 * return the list of image ids corresponding to given tags. AND & OR mode
162 * supported.
163 *
164 * @param array tag ids
165 * @param string mode
166 * @return array
167 */
168function get_image_ids_for_tags($tag_ids, $mode = 'AND')
169{
170  switch ($mode)
171  {
172    case 'AND':
173    {
174      // strategy is to list images associated to each tag
175      $tag_images = array();
176
177      foreach ($tag_ids as $tag_id)
178      {
179        $query = '
180SELECT image_id
181  FROM '.IMAGE_TAG_TABLE.'
182  WHERE tag_id = '.$tag_id.'
183;';
184        $tag_images[$tag_id] = array_from_query($query, 'image_id');
185      }
186
187      // then we calculate the intersection, the images that are associated to
188      // every tags
189      $items = array_shift($tag_images);
190      foreach ($tag_images as $images)
191      {
192        $items = array_intersect($items, $images);
193      }
194
195      return array_unique($items);
196      break;
197    }
198    case 'OR':
199    {
200      $query = '
201SELECT DISTINCT image_id
202  FROM '.IMAGE_TAG_TABLE.'
203  WHERE tag_id IN ('.implode(',', $tag_ids).')
204;';
205      return array_from_query($query, 'image_id');
206      break;
207    }
208    default:
209    {
210      die('get_image_ids_for_tags: unknown mode, only AND & OR are supported');
211    }
212  }
213}
214
215/**
216 * return a list of tags corresponding to given items.
217 *
218 * @param array items
219 * @param array max_tags
220 * @param array excluded_tag_ids
221 * @return array
222 */
223function get_common_tags($items, $max_tags, $excluded_tag_ids=null)
224{
225  if (empty($items))
226  {
227    return array();
228  }
229  $query = '
230SELECT id, name, url_name, count(*) counter
231  FROM '.IMAGE_TAG_TABLE.'
232    INNER JOIN '.TAGS_TABLE.' ON tag_id = id
233  WHERE image_id IN ('.implode(',', $items).')';
234  if (!empty($excluded_tag_ids))
235  {
236    $query.='
237    AND tag_id NOT IN ('.implode(',', $excluded_tag_ids).')';
238  }
239  $query .='
240  GROUP BY tag_id';
241  if ($max_tags>0)
242  {
243    $query .= '
244  ORDER BY counter DESC
245  LIMIT 0,'.$max_tags;
246  }
247  else
248  {
249    $query .= '
250  ORDER BY NULL';
251  }
252
253  $result = pwg_query($query);
254  $tags = array();
255  while($row = mysql_fetch_assoc($result))
256  {
257    array_push($tags, $row);
258  }
259  usort($tags, 'name_compare');
260  return $tags;
261}
262
263/**
264 * return a list of tags corresponding to any of ids, url_names, names
265 *
266 * @param array ids
267 * @param array url_names
268 * @param array names
269 * @return array
270 */
271function find_tags($ids, $url_names=array(), $names=array() )
272{
273  $where_clauses = array();
274  if ( !empty($ids) )
275  {
276    $where_clauses[] = 'id IN ('.implode(',', $ids).')';
277  }
278  if ( !empty($url_names) )
279  {
280    $where_clauses[] =
281      'url_name IN ('.
282      implode(
283        ',',
284        array_map(
285          create_function('$s', 'return "\'".$s."\'";'),
286          $url_names
287          )
288        )
289      .')';
290  }
291  if ( !empty($names) )
292  {
293    $where_clauses[] =
294      'name IN ('.
295      implode(
296        ',',
297        array_map(
298          create_function('$s', 'return "\'".$s."\'";'),
299          $names
300          )
301        )
302      .')';
303  }
304  if (empty($where_clauses))
305  {
306    return array();
307  }
308
309  $query = '
310SELECT id, url_name, name
311  FROM '.TAGS_TABLE.'
312  WHERE '. implode( '
313    OR ', $where_clauses);
314
315  $result = pwg_query($query);
316  $tags = array();
317  while ($row = mysql_fetch_assoc($result))
318  {
319    array_push($tags, $row);
320  }
321  return $tags;
322}
323?>
Note: See TracBrowser for help on using the repository browser.