source: trunk/include/functions_category.inc.php @ 20384

Last change on this file since 20384 was 19703, checked in by plg, 11 years ago

update Piwigo headers to 2013 (the end of the world didn't occur as expected on r12922)

  • Property svn:eol-style set to LF
File size: 12.7 KB
Line 
1<?php
2// +-----------------------------------------------------------------------+
3// | Piwigo - a PHP based photo gallery                                    |
4// +-----------------------------------------------------------------------+
5// | Copyright(C) 2008-2013 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 * Provides functions to handle categories.
26 *
27 *
28 */
29
30/**
31 * Is the category accessible to the connected user ?
32 *
33 * Note : if the user is not authorized to see this category, page creation
34 * ends (exit command in this function)
35 *
36 * @param int category id to verify
37 * @return void
38 */
39function check_restrictions($category_id)
40{
41  global $user;
42
43  // $filter['visible_categories'] and $filter['visible_images']
44  // are not used because it's not necessary (filter <> restriction)
45  if (in_array($category_id, explode(',', $user['forbidden_categories'])))
46  {
47    access_denied();
48  }
49}
50
51function get_categories_menu()
52{
53  global $page, $user, $filter, $conf;
54
55  $query = '
56SELECT ';
57  // From CATEGORIES_TABLE
58  $query.= '
59  id, name, permalink, nb_images, global_rank,';
60  // From USER_CACHE_CATEGORIES_TABLE
61  $query.= '
62  date_last, max_date_last, count_images, count_categories';
63
64  // $user['forbidden_categories'] including with USER_CACHE_CATEGORIES_TABLE
65  $query.= '
66FROM '.CATEGORIES_TABLE.' INNER JOIN '.USER_CACHE_CATEGORIES_TABLE.'
67  ON id = cat_id and user_id = '.$user['id'];
68
69  // Always expand when filter is activated
70  if (!$user['expand'] and !$filter['enabled'])
71  {
72    $where = '
73(id_uppercat is NULL';
74    if (isset($page['category']))
75    {
76      $where .= ' OR id_uppercat IN ('.$page['category']['uppercats'].')';
77    }
78    $where .= ')';
79  }
80  else
81  {
82    $where = '
83  '.get_sql_condition_FandF
84    (
85      array
86        (
87          'visible_categories' => 'id',
88        ),
89      null,
90      true
91    );
92  }
93
94  $where = trigger_event('get_categories_menu_sql_where',
95    $where, $user['expand'], $filter['enabled'] );
96
97  $query.= '
98WHERE '.$where.'
99;';
100
101  $result = pwg_query($query);
102  $cats = array();
103  $selected_category = isset($page['category']) ? $page['category'] : null;
104  while ($row = pwg_db_fetch_assoc($result))
105  {
106    $child_date_last = @$row['max_date_last']> @$row['date_last'];
107    $row = array_merge($row,
108      array(
109        'NAME' => trigger_event(
110          'render_category_name',
111          $row['name'],
112          'get_categories_menu'
113          ),
114        'TITLE' => get_display_images_count(
115          $row['nb_images'],
116          $row['count_images'],
117          $row['count_categories'],
118          false,
119          ' / '
120          ),
121        'URL' => make_index_url(array('category' => $row)),
122        'LEVEL' => substr_count($row['global_rank'], '.') + 1,
123        'SELECTED' => $selected_category['id'] == $row['id'] ? true : false,
124        'IS_UPPERCAT' => $selected_category['id_uppercat'] == $row['id'] ? true : false,
125        )
126      );
127    if ($conf['index_new_icon'])
128    {
129      $row['icon_ts'] = get_icon($row['max_date_last'], $child_date_last);
130    }
131    $cats[] = $row;
132    if ($row['id']==@$page['category']['id']) //save the number of subcats for later optim
133      $page['category']['count_categories'] = $row['count_categories'];
134  }
135  usort($cats, 'global_rank_compare');
136
137  // Update filtered data
138  if (function_exists('update_cats_with_filtered_data'))
139  {
140    update_cats_with_filtered_data($cats);
141  }
142
143  return $cats;
144}
145
146
147/**
148 * Retrieve informations about a category in the database
149 *
150 * Returns an array with following keys :
151 *
152 *  - comment
153 *  - dir : directory, might be empty for virtual categories
154 *  - name : an array with indexes from 0 (lowest cat name) to n (most
155 *           uppercat name findable)
156 *  - nb_images
157 *  - id_uppercat
158 *  - site_id
159 *  -
160 *
161 * @param int category id
162 * @return array
163 */
164function get_cat_info( $id )
165{
166  $query = '
167SELECT *
168  FROM '.CATEGORIES_TABLE.'
169  WHERE id = '.$id.'
170;';
171  $cat = pwg_db_fetch_assoc(pwg_query($query));
172  if (empty($cat))
173    return null;
174
175  foreach ($cat as $k => $v)
176  {
177    // If the field is true or false, the variable is transformed into a
178    // boolean value.
179    if ($cat[$k] == 'true' or $cat[$k] == 'false')
180    {
181      $cat[$k] = get_boolean( $cat[$k] );
182    }
183  }
184
185  $upper_ids = explode(',', $cat['uppercats']);
186  if ( count($upper_ids)==1 )
187  {// no need to make a query for level 1
188    $cat['upper_names'] = array(
189        array(
190          'id' => $cat['id'],
191          'name' => $cat['name'],
192          'permalink' => $cat['permalink'],
193          )
194      );
195  }
196  else
197  {
198    $query = '
199  SELECT id, name, permalink
200    FROM '.CATEGORIES_TABLE.'
201    WHERE id IN ('.$cat['uppercats'].')
202  ;';
203    $names = hash_from_query($query, 'id');
204
205    // category names must be in the same order than uppercats list
206    $cat['upper_names'] = array();
207    foreach ($upper_ids as $cat_id)
208    {
209      $cat['upper_names'][] = $names[$cat_id];
210    }
211  }
212  return $cat;
213}
214
215
216
217// returns an array of image orders available for users/visitors
218function get_category_preferred_image_orders()
219{
220  global $conf, $page;
221
222  return trigger_event('get_category_preferred_image_orders', array(
223    array(l10n('Default'),                        '',                     true),
224    array(l10n('Photo title, A &rarr; Z'),        'name ASC',             true),
225    array(l10n('Photo title, Z &rarr; A'),        'name DESC',            true),
226    array(l10n('Date created, new &rarr; old'),   'date_creation DESC',   true),
227    array(l10n('Date created, old &rarr; new'),   'date_creation ASC',    true),
228    array(l10n('Date posted, new &rarr; old'),    'date_available DESC',  true),
229    array(l10n('Date posted, old &rarr; new'),    'date_available ASC',   true),
230    array(l10n('Rating score, high &rarr; low'),  'rating_score DESC',    $conf['rate']),
231    array(l10n('Rating score, low &rarr; high'),  'rating_score ASC',     $conf['rate']),
232    array(l10n('Visits, high &rarr; low'),        'hit DESC',             true),
233    array(l10n('Visits, low &rarr; high'),        'hit ASC',              true),
234    array(l10n('Permissions'),                    'level DESC',           is_admin()),
235    ));
236}
237
238function display_select_categories($categories,
239                                   $selecteds,
240                                   $blockname,
241                                   $fullname = true)
242{
243  global $template;
244
245  $tpl_cats = array();
246  foreach ($categories as $category)
247  {
248    if ($fullname)
249    {
250      $option = strip_tags(
251        get_cat_display_name_cache(
252          $category['uppercats'],
253          null,
254          false
255          )
256        );
257    }
258    else
259    {
260      $option = str_repeat('&nbsp;',
261                           (3 * substr_count($category['global_rank'], '.')));
262      $option.= '- ';
263      $option.= strip_tags(
264        trigger_event(
265          'render_category_name',
266          $category['name'],
267          'display_select_categories'
268          )
269        );
270    }
271    $tpl_cats[ $category['id'] ] = $option;
272  }
273
274  $template->assign( $blockname, $tpl_cats);
275  $template->assign( $blockname.'_selected', $selecteds);
276}
277
278function display_select_cat_wrapper($query, $selecteds, $blockname,
279                                    $fullname = true)
280{
281  $categories = array_from_query($query);
282  usort($categories, 'global_rank_compare');
283  display_select_categories($categories, $selecteds, $blockname, $fullname);
284}
285
286/**
287 * returns all subcategory identifiers of given category ids
288 *
289 * @param array ids
290 * @return array
291 */
292function get_subcat_ids($ids)
293{
294  $query = '
295SELECT DISTINCT(id)
296  FROM '.CATEGORIES_TABLE.'
297  WHERE ';
298  foreach ($ids as $num => $category_id)
299  {
300    is_numeric($category_id)
301      or trigger_error(
302        'get_subcat_ids expecting numeric, not '.gettype($category_id),
303        E_USER_WARNING
304      );
305    if ($num > 0)
306    {
307      $query.= '
308    OR ';
309    }
310    $query.= 'uppercats '.DB_REGEX_OPERATOR.' \'(^|,)'.$category_id.'(,|$)\'';
311  }
312  $query.= '
313;';
314  return array_from_query($query, 'id');
315}
316
317/** finds a matching category id from a potential list of permalinks
318 * @param array permalinks example: holiday holiday/france holiday/france/paris
319 * @param int idx - output of the index in $permalinks that matches
320 * return category id or null if no match
321 */
322function get_cat_id_from_permalinks( $permalinks, &$idx )
323{
324  $in = '';
325  foreach($permalinks as $permalink)
326  {
327    if ( !empty($in) ) $in.=', ';
328    $in .= '\''.$permalink.'\'';
329  }
330  $query ='
331SELECT cat_id AS id, permalink, 1 AS is_old
332  FROM '.OLD_PERMALINKS_TABLE.'
333  WHERE permalink IN ('.$in.')
334UNION
335SELECT id, permalink, 0 AS is_old
336  FROM '.CATEGORIES_TABLE.'
337  WHERE permalink IN ('.$in.')
338;';
339  $perma_hash = hash_from_query($query, 'permalink');
340
341  if ( empty($perma_hash) )
342    return null;
343  for ($i=count($permalinks)-1; $i>=0; $i--)
344  {
345    if ( isset( $perma_hash[ $permalinks[$i] ] ) )
346    {
347      $idx = $i;
348      $cat_id = $perma_hash[ $permalinks[$i] ]['id'];
349      if ($perma_hash[ $permalinks[$i] ]['is_old'])
350      {
351        $query='
352UPDATE '.OLD_PERMALINKS_TABLE.' SET last_hit=NOW(), hit=hit+1
353  WHERE permalink=\''.$permalinks[$i].'\' AND cat_id='.$cat_id.'
354  LIMIT 1';
355        pwg_query($query);
356      }
357      return $cat_id;
358    }
359  }
360  return null;
361}
362
363function global_rank_compare($a, $b)
364{
365  return strnatcasecmp($a['global_rank'], $b['global_rank']);
366}
367
368function rank_compare($a, $b)
369{
370  return $a['rank'] - $b['rank'];
371}
372
373/**
374 * returns display text for information images of category
375 *
376 * @param array categories
377 * @return string
378 */
379function get_display_images_count($cat_nb_images, $cat_count_images, $cat_count_categories, $short_message = true, $Separator = '\n')
380{
381  $display_text = '';
382
383  if ($cat_count_images > 0)
384  {
385    if ($cat_nb_images > 0 and $cat_nb_images < $cat_count_images)
386    {
387      $display_text.= get_display_images_count($cat_nb_images, $cat_nb_images, 0, $short_message, $Separator).$Separator;
388      $cat_count_images-= $cat_nb_images;
389      $cat_nb_images = 0;
390    }
391
392    //at least one image direct or indirect
393    $display_text.= l10n_dec('%d photo', '%d photos', $cat_count_images);
394
395    if ($cat_count_categories == 0 or $cat_nb_images == $cat_count_images)
396    {
397      //no descendant categories or descendants do not contain images
398      if (! $short_message)
399      {
400        $display_text.= ' '.l10n('in this album');
401      }
402    }
403    else
404    {
405      $display_text.= ' '.l10n_dec('in %d sub-album', 'in %d sub-albums', $cat_count_categories);
406    }
407  }
408
409  return $display_text;
410}
411
412/**
413 * Find a random photo among all photos below a given album in the tree (not
414 * only photo directly associated to the album but also to sub-albums)
415 *
416 * we need $category['uppercats'], $category['id'], $category['count_images']
417 */
418function get_random_image_in_category($category, $recursive=true)
419{
420  $image_id = null;
421  if ($category['count_images']>0)
422  {
423    $query = '
424SELECT image_id
425  FROM '.CATEGORIES_TABLE.' AS c
426    INNER JOIN '.IMAGE_CATEGORY_TABLE.' AS ic ON ic.category_id = c.id
427  WHERE ';
428    if ($recursive)
429    {
430      $query.= '
431    (c.id='.$category['id'].' OR uppercats LIKE \''.$category['uppercats'].',%\')';
432    }
433    else
434    {
435      $query.= '
436    c.id='.$category['id'];
437    }
438    $query.= '
439    '.get_sql_condition_FandF
440    (
441      array
442        (
443          'forbidden_categories' => 'c.id',
444          'visible_categories' => 'c.id',
445          'visible_images' => 'image_id',
446        ),
447      "\n  AND"
448    ).'
449  ORDER BY '.DB_RANDOM_FUNCTION.'()
450  LIMIT 1
451;';
452    $result = pwg_query($query);
453    if (pwg_db_num_rows($result) > 0)
454    {
455      list($image_id) = pwg_db_fetch_row($result);
456    }
457  }
458
459  return $image_id;
460}
461
462
463?>
Note: See TracBrowser for help on using the repository browser.