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

Last change on this file since 12922 was 12922, checked in by mistic100, 12 years ago

update Piwigo headers to 2012, last change before the expected (or not) apocalypse

  • Property svn:eol-style set to LF
File size: 15.3 KB
Line 
1<?php
2// +-----------------------------------------------------------------------+
3// | Piwigo - a PHP based photo gallery                                    |
4// +-----------------------------------------------------------------------+
5// | Copyright(C) 2008-2012 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    array_push($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    $names = array();
199    $query = '
200  SELECT id, name, permalink
201    FROM '.CATEGORIES_TABLE.'
202    WHERE id IN ('.$cat['uppercats'].')
203  ;';
204    $names = hash_from_query($query, 'id');
205
206    // category names must be in the same order than uppercats list
207    $cat['upper_names'] = array();
208    foreach ($upper_ids as $cat_id)
209    {
210      array_push( $cat['upper_names'], $names[$cat_id]);
211    }
212  }
213  return $cat;
214}
215
216// get_complete_dir returns the concatenation of get_site_url and
217// get_local_dir
218// Example : "pets > rex > 1_year_old" is on the the same site as the
219// Piwigo files and this category has 22 for identifier
220// get_complete_dir(22) returns "./galleries/pets/rex/1_year_old/"
221function get_complete_dir( $category_id )
222{
223  return get_site_url($category_id).get_local_dir($category_id);
224}
225
226// get_local_dir returns an array with complete path without the site url
227// Example : "pets > rex > 1_year_old" is on the the same site as the
228// Piwigo files and this category has 22 for identifier
229// get_local_dir(22) returns "pets/rex/1_year_old/"
230function get_local_dir( $category_id )
231{
232  global $page;
233
234  $uppercats = '';
235  $local_dir = '';
236
237  if ( isset( $page['plain_structure'][$category_id]['uppercats'] ) )
238  {
239    $uppercats = $page['plain_structure'][$category_id]['uppercats'];
240  }
241  else
242  {
243    $query = 'SELECT uppercats';
244    $query.= ' FROM '.CATEGORIES_TABLE.' WHERE id = '.$category_id;
245    $query.= ';';
246    $row = pwg_db_fetch_assoc( pwg_query( $query ) );
247    $uppercats = $row['uppercats'];
248  }
249
250  $upper_array = explode( ',', $uppercats );
251
252  $database_dirs = array();
253  $query = 'SELECT id,dir';
254  $query.= ' FROM '.CATEGORIES_TABLE.' WHERE id IN ('.$uppercats.')';
255  $query.= ';';
256  $result = pwg_query( $query );
257  while( $row = pwg_db_fetch_assoc( $result ) )
258  {
259    $database_dirs[$row['id']] = $row['dir'];
260  }
261  foreach ($upper_array as $id)
262  {
263    $local_dir.= $database_dirs[$id].'/';
264  }
265
266  return $local_dir;
267}
268
269// retrieving the site url : "http://domain.com/gallery/" or
270// simply "./galleries/"
271function get_site_url($category_id)
272{
273  global $page;
274
275  $query = '
276SELECT galleries_url
277  FROM '.SITES_TABLE.' AS s,'.CATEGORIES_TABLE.' AS c
278  WHERE s.id = c.site_id
279    AND c.id = '.$category_id.'
280;';
281  $row = pwg_db_fetch_assoc(pwg_query($query));
282  return $row['galleries_url'];
283}
284
285// returns an array of image orders available for users/visitors
286function get_category_preferred_image_orders()
287{
288  global $conf, $page;
289
290  return trigger_event('get_category_preferred_image_orders',
291    array(
292    array(l10n('Default'), '', true),
293    array(l10n('Rating score'), 'rating_score DESC', $conf['rate']),
294    array(l10n('Most visited'), 'hit DESC', true),
295    array(l10n('Creation date'), 'date_creation DESC', true),
296    array(l10n('Post date'), 'date_available DESC', true),
297    array(l10n('File name'), 'file ASC', true),
298    array(
299      l10n('Rank'),
300      'rank ASC',
301      ('categories' == @$page['section'] and !isset($page['flat']) and !isset($page['chronology_field']) )
302      ),
303    array( l10n('Permissions'), 'level DESC', is_admin() )
304    ));
305}
306
307function display_select_categories($categories,
308                                   $selecteds,
309                                   $blockname,
310                                   $fullname = true)
311{
312  global $template;
313
314  $tpl_cats = array();
315  foreach ($categories as $category)
316  {
317    if (!empty($category['permalink']))
318    {
319      $category['name'] .= ' &radic;';
320    }
321    if ($fullname)
322    {
323      $option = strip_tags(
324        get_cat_display_name_cache(
325          $category['uppercats'],
326          null,
327          false
328          )
329        );
330    }
331    else
332    {
333      $option = str_repeat('&nbsp;',
334                           (3 * substr_count($category['global_rank'], '.')));
335      $option.= '- ';
336      $option.= strip_tags(
337        trigger_event(
338          'render_category_name',
339          $category['name'],
340          'display_select_categories'
341          )
342        );
343    }
344    $tpl_cats[ $category['id'] ] = $option;
345  }
346
347  $template->assign( $blockname, $tpl_cats);
348  $template->assign( $blockname.'_selected', $selecteds);
349}
350
351function display_select_cat_wrapper($query, $selecteds, $blockname,
352                                    $fullname = true)
353{
354  $result = pwg_query($query);
355  $categories = array();
356  if (!empty($result))
357  {
358    while ($row = pwg_db_fetch_assoc($result))
359    {
360      array_push($categories, $row);
361    }
362  }
363  usort($categories, 'global_rank_compare');
364  display_select_categories($categories, $selecteds, $blockname, $fullname);
365}
366
367/**
368 * returns all subcategory identifiers of given category ids
369 *
370 * @param array ids
371 * @return array
372 */
373function get_subcat_ids($ids)
374{
375  $query = '
376SELECT DISTINCT(id)
377  FROM '.CATEGORIES_TABLE.'
378  WHERE ';
379  foreach ($ids as $num => $category_id)
380  {
381    is_numeric($category_id)
382      or trigger_error(
383        'get_subcat_ids expecting numeric, not '.gettype($category_id),
384        E_USER_WARNING
385      );
386    if ($num > 0)
387    {
388      $query.= '
389    OR ';
390    }
391    $query.= 'uppercats '.DB_REGEX_OPERATOR.' \'(^|,)'.$category_id.'(,|$)\'';
392  }
393  $query.= '
394;';
395  $result = pwg_query($query);
396
397  $subcats = array();
398  while ($row = pwg_db_fetch_assoc($result))
399  {
400    array_push($subcats, $row['id']);
401  }
402  return $subcats;
403}
404
405/** finds a matching category id from a potential list of permalinks
406 * @param array permalinks example: holiday holiday/france holiday/france/paris
407 * @param int idx - output of the index in $permalinks that matches
408 * return category id or null if no match
409 */
410function get_cat_id_from_permalinks( $permalinks, &$idx )
411{
412  $in = '';
413  foreach($permalinks as $permalink)
414  {
415    if ( !empty($in) ) $in.=', ';
416    $in .= '\''.$permalink.'\'';
417  }
418  $query ='
419SELECT cat_id AS id, permalink, 1 AS is_old
420  FROM '.OLD_PERMALINKS_TABLE.'
421  WHERE permalink IN ('.$in.')
422UNION
423SELECT id, permalink, 0 AS is_old
424  FROM '.CATEGORIES_TABLE.'
425  WHERE permalink IN ('.$in.')
426;';
427  $perma_hash = hash_from_query($query, 'permalink');
428
429  if ( empty($perma_hash) )
430    return null;
431  for ($i=count($permalinks)-1; $i>=0; $i--)
432  {
433    if ( isset( $perma_hash[ $permalinks[$i] ] ) )
434    {
435      $idx = $i;
436      $cat_id = $perma_hash[ $permalinks[$i] ]['id'];
437      if ($perma_hash[ $permalinks[$i] ]['is_old'])
438      {
439        $query='
440UPDATE '.OLD_PERMALINKS_TABLE.' SET last_hit=NOW(), hit=hit+1
441  WHERE permalink=\''.$permalinks[$i].'\' AND cat_id='.$cat_id.'
442  LIMIT 1';
443        pwg_query($query);
444      }
445      return $cat_id;
446    }
447  }
448  return null;
449}
450
451function global_rank_compare($a, $b)
452{
453  return strnatcasecmp($a['global_rank'], $b['global_rank']);
454}
455
456function rank_compare($a, $b)
457{
458  if ($a['rank'] == $b['rank'])
459  {
460    return 0;
461  }
462
463  return ($a['rank'] < $b['rank']) ? -1 : 1;
464}
465
466/**
467 * returns display text for information images of category
468 *
469 * @param array categories
470 * @return string
471 */
472function get_display_images_count($cat_nb_images, $cat_count_images, $cat_count_categories, $short_message = true, $Separator = '\n')
473{
474  $display_text = '';
475
476  if ($cat_count_images > 0)
477  {
478    if ($cat_nb_images > 0 and $cat_nb_images < $cat_count_images)
479    {
480      $display_text.= get_display_images_count($cat_nb_images, $cat_nb_images, 0, $short_message, $Separator).$Separator;
481      $cat_count_images-= $cat_nb_images;
482      $cat_nb_images = 0;
483    }
484
485    //at least one image direct or indirect
486    $display_text.= l10n_dec('%d photo', '%d photos', $cat_count_images);
487
488    if ($cat_count_categories == 0 or $cat_nb_images == $cat_count_images)
489    {
490      //no descendant categories or descendants do not contain images
491      if (! $short_message)
492      {
493        $display_text.= ' '.l10n('in this album');
494      }
495    }
496    else
497    {
498      $display_text.= ' '.l10n_dec('in %d sub-album', 'in %d sub-albums', $cat_count_categories);
499    }
500  }
501
502  return $display_text;
503}
504
505/**
506 * Find a random photo among all photos below a given album in the tree (not
507 * only photo directly associated to the album but also to sub-albums)
508 *
509 * we need $category['uppercats'], $category['id'], $category['count_images']
510 */
511function get_random_image_in_category($category, $recursive=true)
512{
513  $image_id = null;
514  if ($category['count_images']>0)
515  {
516    $query = '
517SELECT image_id
518  FROM '.CATEGORIES_TABLE.' AS c
519    INNER JOIN '.IMAGE_CATEGORY_TABLE.' AS ic ON ic.category_id = c.id
520  WHERE ';
521    if ($recursive)
522    {
523      $query.= '
524    (c.id='.$category['id'].' OR uppercats LIKE \''.$category['uppercats'].',%\')';
525    }
526    else
527    {
528      $query.= '
529    c.id='.$category['id'];
530    }
531    $query.= '
532    '.get_sql_condition_FandF
533    (
534      array
535        (
536          'forbidden_categories' => 'c.id',
537          'visible_categories' => 'c.id',
538          'visible_images' => 'image_id',
539        ),
540      "\n  AND"
541    ).'
542  ORDER BY '.DB_RANDOM_FUNCTION.'()
543  LIMIT 1
544;';
545    $result = pwg_query($query);
546    if (pwg_db_num_rows($result) > 0)
547    {
548      list($image_id) = pwg_db_fetch_row($result);
549    }
550  }
551
552  return $image_id;
553}
554
555/**
556 * create a tree from a flat list of categories, no recursivity for high speed
557 */
558function categories_flatlist_to_tree($categories)
559{
560  $tree = array();
561  $key_of_cat = array();
562
563  foreach ($categories as $key => &$node)
564  {
565    $key_of_cat[$node['id']] = $key;
566
567    if (!isset($node['id_uppercat']))
568    {
569      $tree[$key] = &$node;
570    }
571    else
572    {
573      if (!isset($categories[ $key_of_cat[ $node['id_uppercat'] ] ]['sub_categories']))
574      {
575        $categories[ $key_of_cat[ $node['id_uppercat'] ] ]['sub_categories'] = array();
576      }
577
578      $categories[ $key_of_cat[ $node['id_uppercat'] ] ]['sub_categories'][$key] = &$node;
579    }
580  }
581
582  return $tree;
583}
584?>
Note: See TracBrowser for help on using the repository browser.