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

Last change on this file since 6322 was 6322, checked in by plg, 14 years ago

merge r6321 from branch 2.1 to trunk

bug 1682: r6312 was producing a MySQL error (depending on the MySQL server
version) because a count() implies a group by.

This code change was checked against MySQL 5.0.75, MySQL 5.0.51 (where the
error occured) and SQLite 3.6.22.

File size: 14.5 KB
Line 
1<?php
2// +-----------------------------------------------------------------------+
3// | Piwigo - a PHP based picture gallery                                  |
4// +-----------------------------------------------------------------------+
5// | Copyright(C) 2008-2010 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;
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        'icon_ts' => get_icon($row['max_date_last'], $child_date_last),
124        'SELECTED' => $selected_category['id'] == $row['id'] ? true : false,
125        'IS_UPPERCAT' => $selected_category['id_uppercat'] == $row['id'] ? true : false,
126      )
127    );
128    array_push($cats, $row);
129    if ($row['id']==@$page['category']['id']) //save the number of subcats for later optim
130      $page['category']['count_categories'] = $row['count_categories'];
131  }
132  usort($cats, 'global_rank_compare');
133
134  // Update filtered data
135  if (function_exists('update_cats_with_filtered_data'))
136  {
137    update_cats_with_filtered_data($cats);
138  }
139
140  return $cats;
141}
142
143
144/**
145 * Retrieve informations about a category in the database
146 *
147 * Returns an array with following keys :
148 *
149 *  - comment
150 *  - dir : directory, might be empty for virtual categories
151 *  - name : an array with indexes from 0 (lowest cat name) to n (most
152 *           uppercat name findable)
153 *  - nb_images
154 *  - id_uppercat
155 *  - site_id
156 *  -
157 *
158 * @param int category id
159 * @return array
160 */
161function get_cat_info( $id )
162{
163  $query = '
164SELECT *
165  FROM '.CATEGORIES_TABLE.'
166  WHERE id = '.$id.'
167;';
168  $cat = pwg_db_fetch_assoc(pwg_query($query));
169  if (empty($cat))
170    return null;
171
172  foreach ($cat as $k => $v)
173  {
174    // If the field is true or false, the variable is transformed into a
175    // boolean value.
176    if ($cat[$k] == 'true' or $cat[$k] == 'false')
177    {
178      $cat[$k] = get_boolean( $cat[$k] );
179    }
180  }
181
182  $upper_ids = explode(',', $cat['uppercats']);
183  if ( count($upper_ids)==1 )
184  {// no need to make a query for level 1
185    $cat['upper_names'] = array(
186        array(
187          'id' => $cat['id'],
188          'name' => $cat['name'],
189          'permalink' => $cat['permalink'],
190          )
191      );
192  }
193  else
194  {
195    $names = array();
196    $query = '
197  SELECT id, name, permalink
198    FROM '.CATEGORIES_TABLE.'
199    WHERE id IN ('.$cat['uppercats'].')
200  ;';
201    $names = hash_from_query($query, 'id');
202
203    // category names must be in the same order than uppercats list
204    $cat['upper_names'] = array();
205    foreach ($upper_ids as $cat_id)
206    {
207      array_push( $cat['upper_names'], $names[$cat_id]);
208    }
209  }
210  return $cat;
211}
212
213// get_complete_dir returns the concatenation of get_site_url and
214// get_local_dir
215// Example : "pets > rex > 1_year_old" is on the the same site as the
216// Piwigo files and this category has 22 for identifier
217// get_complete_dir(22) returns "./galleries/pets/rex/1_year_old/"
218function get_complete_dir( $category_id )
219{
220  return get_site_url($category_id).get_local_dir($category_id);
221}
222
223// get_local_dir returns an array with complete path without the site url
224// Example : "pets > rex > 1_year_old" is on the the same site as the
225// Piwigo files and this category has 22 for identifier
226// get_local_dir(22) returns "pets/rex/1_year_old/"
227function get_local_dir( $category_id )
228{
229  global $page;
230
231  $uppercats = '';
232  $local_dir = '';
233
234  if ( isset( $page['plain_structure'][$category_id]['uppercats'] ) )
235  {
236    $uppercats = $page['plain_structure'][$category_id]['uppercats'];
237  }
238  else
239  {
240    $query = 'SELECT uppercats';
241    $query.= ' FROM '.CATEGORIES_TABLE.' WHERE id = '.$category_id;
242    $query.= ';';
243    $row = pwg_db_fetch_assoc( pwg_query( $query ) );
244    $uppercats = $row['uppercats'];
245  }
246
247  $upper_array = explode( ',', $uppercats );
248
249  $database_dirs = array();
250  $query = 'SELECT id,dir';
251  $query.= ' FROM '.CATEGORIES_TABLE.' WHERE id IN ('.$uppercats.')';
252  $query.= ';';
253  $result = pwg_query( $query );
254  while( $row = pwg_db_fetch_assoc( $result ) )
255  {
256    $database_dirs[$row['id']] = $row['dir'];
257  }
258  foreach ($upper_array as $id)
259  {
260    $local_dir.= $database_dirs[$id].'/';
261  }
262
263  return $local_dir;
264}
265
266// retrieving the site url : "http://domain.com/gallery/" or
267// simply "./galleries/"
268function get_site_url($category_id)
269{
270  global $page;
271
272  $query = '
273SELECT galleries_url
274  FROM '.SITES_TABLE.' AS s,'.CATEGORIES_TABLE.' AS c
275  WHERE s.id = c.site_id
276    AND c.id = '.$category_id.'
277;';
278  $row = pwg_db_fetch_assoc(pwg_query($query));
279  return $row['galleries_url'];
280}
281
282// returns an array of image orders available for users/visitors
283function get_category_preferred_image_orders()
284{
285  global $conf, $page;
286
287  return trigger_event('get_category_preferred_image_orders',
288    array(
289    array(l10n('Default'), '', true),
290    array(l10n('Average rate'), 'average_rate DESC', $conf['rate']),
291    array(l10n('Most visited'), 'hit DESC', true),
292    array(l10n('Creation date'), 'date_creation DESC', true),
293    array(l10n('Post date'), 'date_available DESC', true),
294    array(l10n('File name'), 'file ASC', true),
295    array(
296      l10n('Rank'),
297      'rank ASC',
298      ('categories' == @$page['section'] and !isset($page['flat']) and !isset($page['chronology_field']) )
299      ),
300    array( l10n('Permissions'), 'level DESC', is_admin() )
301    ));
302}
303
304function display_select_categories($categories,
305                                   $selecteds,
306                                   $blockname,
307                                   $fullname = true)
308{
309  global $template;
310
311  $tpl_cats = array();
312  foreach ($categories as $category)
313  {
314    if (!empty($category['permalink']))
315    {
316      $category['name'] .= ' &radic;';
317    }
318    if ($fullname)
319    {
320      $option = get_cat_display_name_cache($category['uppercats'],
321                                           null,
322                                           false);
323    }
324    else
325    {
326      $option = str_repeat('&nbsp;',
327                           (3 * substr_count($category['global_rank'], '.')));
328      $option.= '- ';
329      $option.= strip_tags(
330        trigger_event(
331          'render_category_name',
332          $category['name'],
333          'display_select_categories'
334          )
335        );
336    }
337    $tpl_cats[ $category['id'] ] = $option;
338  }
339
340  $template->assign( $blockname, $tpl_cats);
341  $template->assign( $blockname.'_selected', $selecteds);
342}
343
344function display_select_cat_wrapper($query, $selecteds, $blockname,
345                                    $fullname = true)
346{
347  $result = pwg_query($query);
348  $categories = array();
349  if (!empty($result))
350  {
351    while ($row = pwg_db_fetch_assoc($result))
352    {
353      array_push($categories, $row);
354    }
355  }
356  usort($categories, 'global_rank_compare');
357  display_select_categories($categories, $selecteds, $blockname, $fullname);
358}
359
360/**
361 * returns all subcategory identifiers of given category ids
362 *
363 * @param array ids
364 * @return array
365 */
366function get_subcat_ids($ids)
367{
368  $query = '
369SELECT DISTINCT(id)
370  FROM '.CATEGORIES_TABLE.'
371  WHERE ';
372  foreach ($ids as $num => $category_id)
373  {
374    is_numeric($category_id)
375      or trigger_error(
376        'get_subcat_ids expecting numeric, not '.gettype($category_id),
377        E_USER_WARNING
378      );
379    if ($num > 0)
380    {
381      $query.= '
382    OR ';
383    }
384    $query.= 'uppercats '.DB_REGEX_OPERATOR.' \'(^|,)'.$category_id.'(,|$)\'';
385  }
386  $query.= '
387;';
388  $result = pwg_query($query);
389
390  $subcats = array();
391  while ($row = pwg_db_fetch_assoc($result))
392  {
393    array_push($subcats, $row['id']);
394  }
395  return $subcats;
396}
397
398/** finds a matching category id from a potential list of permalinks
399 * @param array permalinks example: holiday holiday/france holiday/france/paris
400 * @param int idx - output of the index in $permalinks that matches
401 * return category id or null if no match
402 */
403function get_cat_id_from_permalinks( $permalinks, &$idx )
404{
405  $in = '';
406  foreach($permalinks as $permalink)
407  {
408    if ( !empty($in) ) $in.=', ';
409    $in .= '"'.$permalink.'"';
410  }
411  $query ='
412SELECT cat_id AS id, permalink, 1 AS is_old
413  FROM '.OLD_PERMALINKS_TABLE.'
414  WHERE permalink IN ('.$in.')
415UNION
416SELECT id, permalink, 0 AS is_old
417  FROM '.CATEGORIES_TABLE.'
418  WHERE permalink IN ('.$in.')
419;';
420  $perma_hash = hash_from_query($query, 'permalink');
421
422  if ( empty($perma_hash) )
423    return null;
424  for ($i=count($permalinks)-1; $i>=0; $i--)
425  {
426    if ( isset( $perma_hash[ $permalinks[$i] ] ) )
427    {
428      $idx = $i;
429      $cat_id = $perma_hash[ $permalinks[$i] ]['id'];
430      if ($perma_hash[ $permalinks[$i] ]['is_old'])
431      {
432        $query='
433UPDATE '.OLD_PERMALINKS_TABLE.' SET last_hit=NOW(), hit=hit+1
434  WHERE permalink="'.$permalinks[$i].'" AND cat_id='.$cat_id.'
435  LIMIT 1';
436        pwg_query($query);
437      }
438      return $cat_id;
439    }
440  }
441  return null;
442}
443
444function global_rank_compare($a, $b)
445{
446  return strnatcasecmp($a['global_rank'], $b['global_rank']);
447}
448
449function rank_compare($a, $b)
450{
451  if ($a['rank'] == $b['rank'])
452  {
453    return 0;
454  }
455
456  return ($a['rank'] < $b['rank']) ? -1 : 1;
457}
458
459/**
460 * returns display text for information images of category
461 *
462 * @param array categories
463 * @return string
464 */
465function get_display_images_count($cat_nb_images, $cat_count_images, $cat_count_categories, $short_message = true, $Separator = '\n')
466{
467  $display_text = '';
468
469  if ($cat_count_images > 0)
470  {
471    if ($cat_nb_images > 0 and $cat_nb_images < $cat_count_images)
472    {
473      $display_text.= get_display_images_count($cat_nb_images, $cat_nb_images, 0, $short_message, $Separator).$Separator;
474      $cat_count_images-= $cat_nb_images;
475      $cat_nb_images = 0;
476    }
477
478    //at least one image direct or indirect
479    $display_text.= l10n_dec('%d image', '%d images', $cat_count_images);
480
481    if ($cat_count_categories == 0 or $cat_nb_images == $cat_count_images)
482    {
483      //no descendant categories or descendants do not contain images
484      if (! $short_message)
485      {
486        $display_text.= ' '.l10n('in this category');
487      }
488    }
489    else
490    {
491      $display_text.= ' '.l10n_dec('in %d sub-category', 'in %d sub-categories', $cat_count_categories);
492    }
493  }
494
495  return $display_text;
496}
497
498/**
499 * returns the link of upload menu
500 *
501 * @param null
502 * @return string or null
503 */
504function get_upload_menu_link()
505{
506  global $conf, $page, $user;
507
508  $show_link = false;
509  $arg_link = null;
510
511  if (is_autorize_status($conf['upload_user_access']))
512  {
513    if (isset($page['category']) and $page['category']['uploadable'] )
514    {
515      // upload a picture in the category
516      $show_link = true;
517      $arg_link = 'cat='.$page['category']['id'];
518    }
519    else
520    if ($conf['upload_link_everytime'])
521    {
522      // upload a picture in the category
523      $query = '
524SELECT
525  1
526FROM '.CATEGORIES_TABLE.' INNER JOIN '.USER_CACHE_CATEGORIES_TABLE.'
527  ON id = cat_id and user_id = '.$user['id'].'
528WHERE
529  uploadable = \'true\'
530  '.get_sql_condition_FandF
531    (
532      array
533        (
534          'visible_categories' => 'id',
535        ),
536      'AND'
537    ).'
538LIMIT 1';
539
540      $show_link = pwg_db_num_rows(pwg_query($query)) <> 0;
541    }
542  }
543  if ($show_link)
544  {
545    return get_root_url().'upload.php'.(empty($arg_link) ? '' : '?'.$arg_link);
546  }
547  else
548  {
549    return;
550  }
551}
552
553?>
Note: See TracBrowser for help on using the repository browser.