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

Last change on this file since 28090 was 27336, checked in by rvelices, 11 years ago

arrayfromquery optimizations: move double if from inside loop to outside + use directly mysqli calls to avoid function call overhead for every row retrieved from db

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