source: branches/2.1/include/functions_user.inc.php @ 6322

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

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: 36.1 KB
RevLine 
[2]1<?php
[362]2// +-----------------------------------------------------------------------+
[2297]3// | Piwigo - a PHP based picture gallery                                  |
4// +-----------------------------------------------------------------------+
[5196]5// | Copyright(C) 2008-2010 Piwigo Team                  http://piwigo.org |
[2297]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// +-----------------------------------------------------------------------+
[2]23
[2115]24// validate_mail_address:
25//   o verifies whether the given mail address has the
26//     right format. ie someone@domain.com "someone" can contain ".", "-" or
27//     even "_". Exactly as "domain". The extension doesn't have to be
28//     "com". The mail address can also be empty.
29//   o check if address could be empty
30//   o check if address is not used by a other user
[9]31// If the mail address doesn't correspond, an error message is returned.
[2127]32//
[2124]33function validate_mail_address($user_id, $mail_address)
[2]34{
[2115]35  global $conf;
[2]36
[2032]37  if (empty($mail_address) and
[2127]38      !($conf['obligatory_user_mail_address'] and
[2124]39      in_array(script_basename(), array('register', 'profile'))))
[2]40  {
[9]41    return '';
[2]42  }
[2115]43
[2507]44  $atom   = '[-a-z0-9!#$%&\'*+\\/=?^_`{|}~]';   // before  arobase
[2572]45  $domain = '([a-z0-9]([-a-z0-9]*[a-z0-9]+)?)'; // domain name
[2507]46  $regex = '/^' . $atom . '+' . '(\.' . $atom . '+)*' . '@' . '(' . $domain . '{1,63}\.)+' . $domain . '{2,63}$/i';
47
[9]48  if ( !preg_match( $regex, $mail_address ) )
49  {
[5021]50    return l10n('mail address must be like xxx@yyy.eee (example : jack@altern.org)');
[9]51  }
[2127]52
[2115]53  if (defined("PHPWG_INSTALLED") and !empty($mail_address))
54  {
55    $query = '
56select count(*)
57from '.USERS_TABLE.'
58where upper('.$conf['user_fields']['email'].') = upper(\''.$mail_address.'\')
[2124]59'.(is_numeric($user_id) ? 'and '.$conf['user_fields']['id'].' != \''.$user_id.'\'' : '').'
[2115]60;';
[4325]61    list($count) = pwg_db_fetch_row(pwg_query($query));
[2115]62    if ($count != 0)
63    {
[5021]64      return l10n('a user use already this mail address');
[2115]65    }
66  }
[2]67}
68
[4429]69// validate_login_case:
70//   o check if login is not used by a other user
71// If the login doesn't correspond, an error message is returned.
72//
73function validate_login_case($login)
74{
75  global $conf;
76 
77  if (defined("PHPWG_INSTALLED"))
78  {
79    $query = "
80SELECT ".$conf['user_fields']['username']."
81FROM ".USERS_TABLE."
82WHERE LOWER(".stripslashes($conf['user_fields']['username']).") = '".strtolower($login)."'
83;";
84
85    $count = pwg_db_num_rows(pwg_query($query));
86
87    if ($count > 0)
88    {
[5021]89      return l10n('this login is already used');
[4429]90    }
91  }
92}
93
[2178]94function register_user($login, $password, $mail_address,
95  $with_notification = true, $errors = array())
[2]96{
[2115]97  global $conf;
[2]98
[661]99  if ($login == '')
100  {
[5021]101    array_push($errors, l10n('Please, enter a login'));
[661]102  }
[3747]103  if (preg_match('/^.* $/', $login))
[661]104  {
[5021]105    array_push($errors, l10n('login mustn\'t end with a space character'));
[661]106  }
[3747]107  if (preg_match('/^ .*$/', $login))
[661]108  {
[5021]109    array_push($errors, l10n('login mustn\'t start with a space character'));
[661]110  }
[808]111  if (get_userid($login))
[804]112  {
[5021]113    array_push($errors, l10n('this login is already used'));
[2]114  }
[2124]115  $mail_error = validate_mail_address(null, $mail_address);
[808]116  if ('' != $mail_error)
[661]117  {
[808]118    array_push($errors, $mail_error);
[661]119  }
[2]120
[5060]121  if ($conf['insensitive_case_logon'] == true)
[4429]122  {
123    $login_error = validate_login_case($login);
124    if ($login_error != '')
125    {
126      array_push($errors, $login_error);
127    }
128  }
129
[2237]130  $errors = trigger_event('register_user_check',
131              $errors,
132              array(
[2268]133                'username'=>$login,
[2237]134                'password'=>$password,
135                'email'=>$mail_address,
136              )
137            );
138
[9]139  // if no error until here, registration of the user
[661]140  if (count($errors) == 0)
[2]141  {
[906]142    // what will be the inserted id ?
143    $query = '
144SELECT MAX('.$conf['user_fields']['id'].') + 1
145  FROM '.USERS_TABLE.'
146;';
[4325]147    list($next_id) = pwg_db_fetch_row(pwg_query($query));
[1068]148
[808]149    $insert =
150      array(
[906]151        $conf['user_fields']['id'] => $next_id,
[4325]152        $conf['user_fields']['username'] => pwg_db_real_escape_string($login),
[808]153        $conf['user_fields']['password'] => $conf['pass_convert']($password),
154        $conf['user_fields']['email'] => $mail_address
155        );
[661]156
[808]157    include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
158    mass_inserts(USERS_TABLE, array_keys($insert), array($insert));
[1068]159
[2178]160    // Assign by default groups
161    {
162      $query = '
[1583]163SELECT id
164  FROM '.GROUPS_TABLE.'
165  WHERE is_default = \''.boolean_to_string(true).'\'
166  ORDER BY id ASC
167;';
[2178]168      $result = pwg_query($query);
[1581]169
[2178]170      $inserts = array();
[4325]171      while ($row = pwg_db_fetch_assoc($result))
[2178]172      {
173        array_push
[1583]174        (
[2178]175          $inserts,
176          array
177          (
178            'user_id' => $next_id,
179            'group_id' => $row['id']
180          )
181        );
182      }
[1583]183    }
[1581]184
[1583]185    if (count($inserts) != 0)
186    {
[1581]187      include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
[1583]188      mass_inserts(USER_GROUP_TABLE, array('user_id', 'group_id'), $inserts);
[1581]189    }
190
[2425]191    $override = null;
192    if ($with_notification and $conf['browser_language'])
193    {
194      if ( !get_browser_language($override['language']) )
195        $override=null;
196    }
197    create_user_infos($next_id, $override);
[1605]198
[2178]199    if ($with_notification and $conf['email_admin_on_new_user'])
200    {
201      include_once(PHPWG_ROOT_PATH.'include/functions_mail.inc.php');
202      $admin_url = get_absolute_root_url()
[2268]203                   .'admin.php?page=user_list&username='.$login;
[2178]204
205      $keyargs_content = array
206      (
[4304]207        get_l10n_args('User: %s', stripslashes($login)),
[2178]208        get_l10n_args('Email: %s', $_POST['mail_address']),
209        get_l10n_args('', ''),
210        get_l10n_args('Admin: %s', $admin_url)
211      );
212
213      pwg_mail_notification_admins
214      (
[4304]215        get_l10n_args('Registration of %s', stripslashes($login)),
[2178]216        $keyargs_content
217      );
218    }
219
[1605]220    trigger_action('register_user',
221      array(
222        'id'=>$next_id,
223        'username'=>$login,
224        'email'=>$mail_address,
225       )
226      );
[2]227  }
[906]228
[661]229  return $errors;
[2]230}
231
[1677]232function build_user( $user_id, $use_cache )
[1568]233{
234  global $conf;
[2038]235
[1568]236  $user['id'] = $user_id;
[1677]237  $user = array_merge( $user, getuserdata($user_id, $use_cache) );
[1926]238
[2055]239  if ($user['id'] == $conf['guest_id'] and $user['status'] <> 'guest')
240  {
241    $user['status'] = 'guest';
242    $user['internal_status']['guest_must_be_guest'] = true;
243  }
244
[1568]245  // calculation of the number of picture to display per page
246  $user['nb_image_page'] = $user['nb_image_line'] * $user['nb_line_page'];
247
[5123]248  // Check user theme
[5264]249  if (!isset($user['theme_name']))
[5123]250  {
[5264]251    $user['theme'] = get_default_theme();
[5123]252  }
[2039]253
[1568]254  return $user;
255}
256
[808]257/**
258 * find informations related to the user identifier
259 *
260 * @param int user identifier
261 * @param boolean use_cache
262 * @param array
263 */
[1677]264function getuserdata($user_id, $use_cache)
[393]265{
[808]266  global $conf;
267
268  $userdata = array();
[1068]269
[6312]270  // retrieve basic user data
[808]271  $query = '
272SELECT ';
273  $is_first = true;
274  foreach ($conf['user_fields'] as $pwgfield => $dbfield)
275  {
276    if ($is_first)
277    {
278      $is_first = false;
279    }
280    else
281    {
282      $query.= '
283     , ';
284    }
285    $query.= $dbfield.' AS '.$pwgfield;
286  }
287  $query.= '
288  FROM '.USERS_TABLE.'
[3622]289  WHERE '.$conf['user_fields']['id'].' = \''.$user_id.'\'';
[1068]290
[4325]291  $row = pwg_db_fetch_assoc(pwg_query($query));
[808]292
[6312]293  // retrieve additional user data
294  $query = '
295SELECT
296    COUNT(1) AS counter,
297    ui.*,
298    uc.*,
299    t.name AS theme_name
[5264]300  FROM '.USER_INFOS_TABLE.' AS ui
301    LEFT JOIN '.USER_CACHE_TABLE.' AS uc ON ui.user_id = uc.user_id
302    LEFT JOIN '.THEMES_TABLE.' AS t ON t.id = ui.theme
[6312]303  WHERE ui.user_id = \''.$user_id.'\'
[6321]304  GROUP BY ui.user_id
[6312]305;';
306  $result = pwg_query($query);
307  $user_infos_row = pwg_db_fetch_assoc($result);
[6321]308  if (!isset($user_infos_row['counter']) or 0 == $user_infos_row['counter']) {
[6312]309    create_user_infos($user_id);
310   
[808]311    $result = pwg_query($query);
[6312]312    $user_infos_row = pwg_db_fetch_assoc($result);
[808]313  }
[1068]314
[6312]315  // then merge basic + additional user data
316  $row = array_merge($row, $user_infos_row);
[1068]317
[808]318  foreach ($row as $key => $value)
319  {
320    if (!is_numeric($key))
321    {
322      // If the field is true or false, the variable is transformed into a
323      // boolean value.
324      if ($value == 'true' or $value == 'false')
325      {
326        $userdata[$key] = get_boolean($value);
327      }
328      else
329      {
330        $userdata[$key] = $value;
331      }
332    }
333  }
334
335  if ($use_cache)
336  {
337    if (!isset($userdata['need_update'])
338        or !is_bool($userdata['need_update'])
[1677]339        or $userdata['need_update'] == true)
[808]340    {
[2448]341      $userdata['cache_update_time'] = time();
342
343      // Set need update are done
344      $userdata['need_update'] = false;
345
[808]346      $userdata['forbidden_categories'] =
347        calculate_permissions($userdata['id'], $userdata['status']);
348
[2084]349      /* now we build the list of forbidden images (this list does not contain
350      images that are not in at least an authorized category)*/
351      $query = '
352SELECT DISTINCT(id)
353  FROM '.IMAGES_TABLE.' INNER JOIN '.IMAGE_CATEGORY_TABLE.' ON id=image_id
354  WHERE category_id NOT IN ('.$userdata['forbidden_categories'].')
355    AND level>'.$userdata['level'];
356      $forbidden_ids = array_from_query($query, 'id');
357
358      if ( empty($forbidden_ids) )
359      {
360        array_push( $forbidden_ids, 0 );
361      }
362      $userdata['image_access_type'] = 'NOT IN'; //TODO maybe later
363      $userdata['image_access_list'] = implode(',',$forbidden_ids);
364
[1624]365
[1081]366      $query = '
367SELECT COUNT(DISTINCT(image_id)) as total
368  FROM '.IMAGE_CATEGORY_TABLE.'
369  WHERE category_id NOT IN ('.$userdata['forbidden_categories'].')
[3622]370    AND image_id '.$userdata['image_access_type'].' ('.$userdata['image_access_list'].')';
[4325]371      list($userdata['nb_total_images']) = pwg_db_fetch_row(pwg_query($query));
[1081]372
[3622]373
374      // now we update user cache categories
375      $user_cache_cats = get_computed_categories($userdata, null);
376      if ( !is_admin($userdata['status']) )
377      { // for non admins we forbid categories with no image (feature 1053)
378        $forbidden_ids = array();
[3640]379        foreach ($user_cache_cats as $cat)
[3622]380        {
381          if ($cat['count_images']==0)
382          {
[3640]383            array_push($forbidden_ids, $cat['cat_id']);
384            unset( $user_cache_cats[$cat['cat_id']] );
[3622]385          }
386        }
387        if ( !empty($forbidden_ids) )
388        {
389          if ( empty($userdata['forbidden_categories']) )
390          {
391            $userdata['forbidden_categories'] = implode(',', $forbidden_ids);
392          }
393          else
394          {
395            $userdata['forbidden_categories'] .= ','.implode(',', $forbidden_ids);
396          }
397        }
398      }
399
400      // delete user cache
401      $query = '
402DELETE FROM '.USER_CACHE_CATEGORIES_TABLE.'
403  WHERE user_id = '.$userdata['id'];
404      pwg_query($query);
405
406      include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
407      mass_inserts
408      (
409        USER_CACHE_CATEGORIES_TABLE,
410        array
411        (
412          'user_id', 'cat_id',
413          'date_last', 'max_date_last', 'nb_images', 'count_images', 'count_categories'
414        ),
415        $user_cache_cats
416      );
417
418
[808]419      // update user cache
420      $query = '
421DELETE FROM '.USER_CACHE_TABLE.'
[3622]422  WHERE user_id = '.$userdata['id'];
[808]423      pwg_query($query);
[1068]424
[808]425      $query = '
426INSERT INTO '.USER_CACHE_TABLE.'
[2448]427  (user_id, need_update, cache_update_time, forbidden_categories, nb_total_images,
[2084]428    image_access_type, image_access_list)
[808]429  VALUES
[2448]430  ('.$userdata['id'].',\''.boolean_to_string($userdata['need_update']).'\','
431  .$userdata['cache_update_time'].',\''
[4367]432  .$userdata['forbidden_categories'].'\','.$userdata['nb_total_images'].',\''
433  .$userdata['image_access_type'].'\',\''.$userdata['image_access_list'].'\')';
[808]434      pwg_query($query);
435    }
436  }
437
438  return $userdata;
[393]439}
[647]440
441/*
442 * deletes favorites of the current user if he's not allowed to see them
443 *
444 * @return void
445 */
446function check_user_favorites()
447{
448  global $user;
449
450  if ($user['forbidden_categories'] == '')
451  {
452    return;
453  }
[832]454
[1677]455  // $filter['visible_categories'] and $filter['visible_images']
456  // must be not used because filter <> restriction
[832]457  // retrieving images allowed : belonging to at least one authorized
458  // category
[647]459  $query = '
[832]460SELECT DISTINCT f.image_id
[647]461  FROM '.FAVORITES_TABLE.' AS f INNER JOIN '.IMAGE_CATEGORY_TABLE.' AS ic
462    ON f.image_id = ic.image_id
463  WHERE f.user_id = '.$user['id'].'
[1677]464'.get_sql_condition_FandF
465  (
466    array
467      (
468        'forbidden_categories' => 'ic.category_id',
469      ),
470    'AND'
471  ).'
[647]472;';
473  $result = pwg_query($query);
[832]474  $authorizeds = array();
[4325]475  while ($row = pwg_db_fetch_assoc($result))
[647]476  {
[832]477    array_push($authorizeds, $row['image_id']);
[647]478  }
479
[832]480  $query = '
481SELECT image_id
482  FROM '.FAVORITES_TABLE.'
483  WHERE user_id = '.$user['id'].'
484;';
485  $result = pwg_query($query);
486  $favorites = array();
[4325]487  while ($row = pwg_db_fetch_assoc($result))
[647]488  {
[832]489    array_push($favorites, $row['image_id']);
490  }
491
492  $to_deletes = array_diff($favorites, $authorizeds);
493
494  if (count($to_deletes) > 0)
495  {
[647]496    $query = '
497DELETE FROM '.FAVORITES_TABLE.'
[832]498  WHERE image_id IN ('.implode(',', $to_deletes).')
[647]499    AND user_id = '.$user['id'].'
500;';
501    pwg_query($query);
502  }
503}
[648]504
505/**
[808]506 * calculates the list of forbidden categories for a given user
[648]507 *
[808]508 * Calculation is based on private categories minus categories authorized to
509 * the groups the user belongs to minus the categories directly authorized
510 * to the user. The list contains at least -1 to be compliant with queries
511 * such as "WHERE category_id NOT IN ($forbidden_categories)"
[648]512 *
513 * @param int user_id
[680]514 * @param string user_status
[648]515 * @return string forbidden_categories
516 */
[680]517function calculate_permissions($user_id, $user_status)
[648]518{
519  $private_array = array();
520  $authorized_array = array();
521
522  $query = '
523SELECT id
524  FROM '.CATEGORIES_TABLE.'
525  WHERE status = \'private\'
526;';
527  $result = pwg_query($query);
[4325]528  while ($row = pwg_db_fetch_assoc($result))
[648]529  {
530    array_push($private_array, $row['id']);
531  }
[680]532
[648]533  // retrieve category ids directly authorized to the user
534  $query = '
535SELECT cat_id
536  FROM '.USER_ACCESS_TABLE.'
537  WHERE user_id = '.$user_id.'
538;';
[808]539  $authorized_array = array_from_query($query, 'cat_id');
[648]540
541  // retrieve category ids authorized to the groups the user belongs to
542  $query = '
543SELECT cat_id
544  FROM '.USER_GROUP_TABLE.' AS ug INNER JOIN '.GROUP_ACCESS_TABLE.' AS ga
545    ON ug.group_id = ga.group_id
546  WHERE ug.user_id = '.$user_id.'
547;';
[808]548  $authorized_array =
549    array_merge(
550      $authorized_array,
551      array_from_query($query, 'cat_id')
552      );
[648]553
554  // uniquify ids : some private categories might be authorized for the
555  // groups and for the user
556  $authorized_array = array_unique($authorized_array);
557
558  // only unauthorized private categories are forbidden
559  $forbidden_array = array_diff($private_array, $authorized_array);
560
[1117]561  // if user is not an admin, locked categories are forbidden
[1851]562  if (!is_admin($user_status))
[1117]563  {
564    $query = '
565SELECT id
566  FROM '.CATEGORIES_TABLE.'
567  WHERE visible = \'false\'
568;';
569    $result = pwg_query($query);
[4325]570    while ($row = pwg_db_fetch_assoc($result))
[1117]571    {
572      array_push($forbidden_array, $row['id']);
573    }
574    $forbidden_array = array_unique($forbidden_array);
575  }
[1068]576
[1117]577  if ( empty($forbidden_array) )
[1331]578  {// at least, the list contains 0 value. This category does not exists so
579   // where clauses such as "WHERE category_id NOT IN(0)" will always be
[1117]580   // true.
[1331]581    array_push($forbidden_array, 0);
[1117]582  }
583
[808]584  return implode(',', $forbidden_array);
[648]585}
[708]586
587/**
[1677]588 * compute data of categories branches (one branch only)
[1624]589 */
[1640]590function compute_branch_cat_data(&$cats, &$list_cat_id, &$level, &$ref_level)
[1624]591{
[1640]592  $date = '';
593  $count_images = 0;
594  $count_categories = 0;
595  do
[1624]596  {
[1640]597    $cat_id = array_pop($list_cat_id);
598    if (!is_null($cat_id))
[1624]599    {
[1640]600      // Count images and categories
601      $cats[$cat_id]['count_images'] += $count_images;
602      $cats[$cat_id]['count_categories'] += $count_categories;
603      $count_images = $cats[$cat_id]['count_images'];
604      $count_categories = $cats[$cat_id]['count_categories'] + 1;
605
606      if ((empty($cats[$cat_id]['max_date_last'])) or ($cats[$cat_id]['max_date_last'] < $date))
[1624]607      {
[1640]608        $cats[$cat_id]['max_date_last'] = $date;
[1624]609      }
610      else
611      {
[1640]612        $date = $cats[$cat_id]['max_date_last'];
[1624]613      }
[1640]614      $ref_level = substr_count($cats[$cat_id]['global_rank'], '.') + 1;
615    }
616    else
[1624]617    {
[1640]618      $ref_level = 0;
[1624]619    }
[1640]620  } while ($level <= $ref_level);
621
622  // Last cat updating must be added to list for next branch
623  if ($ref_level <> 0)
624  {
625    array_push($list_cat_id, $cat_id);
[1624]626  }
[1640]627}
[1624]628
[1640]629/**
[1677]630 * compute data of categories branches
[1640]631 */
[1677]632function compute_categories_data(&$cats)
[1640]633{
[1677]634  $ref_level = 0;
635  $level = 0;
636  $list_cat_id = array();
[1624]637
[1677]638  foreach ($cats as $id => $category)
[1624]639  {
[1677]640    // Compute
641    $level = substr_count($category['global_rank'], '.') + 1;
642    if ($level > $ref_level)
643    {
644      array_push($list_cat_id, $id);
645    }
646    else
647    {
648      compute_branch_cat_data($cats, $list_cat_id, $level, $ref_level);
649      array_push($list_cat_id, $id);
650    }
651    $ref_level = $level;
[1624]652  }
[1651]653
[1677]654  $level = 1;
655  compute_branch_cat_data($cats, $list_cat_id, $level, $ref_level);
656}
[1651]657
[1677]658/**
659 * get computed array of categories
660 *
[1860]661 * @param array userdata
662 * @param int filter_days number of recent days to filter on or null
[1677]663 * @return array
664 */
[1860]665function get_computed_categories($userdata, $filter_days=null)
[1677]666{
[1860]667  $query = 'SELECT c.id cat_id, global_rank';
[2084]668  // Count by date_available to avoid count null
669  $query .= ',
[2324]670  MAX(date_available) date_last, COUNT(date_available) nb_images
[2084]671FROM '.CATEGORIES_TABLE.' as c
672  LEFT JOIN '.IMAGE_CATEGORY_TABLE.' AS ic ON ic.category_id = c.id
673  LEFT JOIN '.IMAGES_TABLE.' AS i
674    ON ic.image_id = i.id
675      AND i.level<='.$userdata['level'];
676
677  if ( isset($filter_days) )
[1651]678  {
[4367]679    $query .= ' AND i.date_available > '.pwg_db_get_recent_period_expression($filter_days);
[1651]680  }
681
[1860]682  if ( !empty($userdata['forbidden_categories']) )
[1651]683  {
684    $query.= '
[1860]685  WHERE c.id NOT IN ('.$userdata['forbidden_categories'].')';
[1651]686  }
687
[2324]688  $query.= '
[4385]689  GROUP BY c.id, c.global_rank';
[1624]690
691  $result = pwg_query($query);
692
693  $cats = array();
[4325]694  while ($row = pwg_db_fetch_assoc($result))
[1624]695  {
[1860]696    $row['user_id'] = $userdata['id'];
[1641]697    $row['count_categories'] = 0;
[2324]698    $row['count_images'] = (int)$row['nb_images'];
699    $row['max_date_last'] = $row['date_last'];
[1860]700
[1624]701    $cats += array($row['cat_id'] => $row);
702  }
[3642]703  uasort($cats, 'global_rank_compare');
[1624]704
[1677]705  compute_categories_data($cats);
[1624]706
[1860]707  if ( isset($filter_days) )
[1624]708  {
[1651]709    $cat_tmp = $cats;
710    $cats = array();
[1860]711
[1677]712    foreach ($cat_tmp as $category)
[1651]713    {
[1677]714      if (!empty($category['max_date_last']))
[1651]715      {
[1677]716        // Re-init counters
717        $category['count_categories'] = 0;
[2324]718        $category['count_images'] = (int)$category['nb_images'];
[1677]719        // Keep category
720        $cats[$category['cat_id']] = $category;
[1651]721      }
722    }
[1677]723    // Compute a second time
724    compute_categories_data($cats);
[1651]725  }
[1677]726  return $cats;
727}
728
729/**
[808]730 * returns user identifier thanks to his name, false if not found
731 *
732 * @param string username
733 * @param int user identifier
734 */
735function get_userid($username)
736{
737  global $conf;
738
[4325]739  $username = pwg_db_real_escape_string($username);
[808]740
741  $query = '
742SELECT '.$conf['user_fields']['id'].'
743  FROM '.USERS_TABLE.'
744  WHERE '.$conf['user_fields']['username'].' = \''.$username.'\'
745;';
746  $result = pwg_query($query);
747
[4325]748  if (pwg_db_num_rows($result) == 0)
[808]749  {
750    return false;
751  }
752  else
753  {
[4325]754    list($user_id) = pwg_db_fetch_row($result);
[808]755    return $user_id;
756  }
757}
758
759/**
[801]760 * search an available feed_id
761 *
762 * @return string feed identifier
763 */
764function find_available_feed_id()
765{
766  while (true)
767  {
768    $key = generate_key(50);
769    $query = '
770SELECT COUNT(*)
[833]771  FROM '.USER_FEED_TABLE.'
772  WHERE id = \''.$key.'\'
[801]773;';
[4325]774    list($count) = pwg_db_fetch_row(pwg_query($query));
[801]775    if (0 == $count)
776    {
777      return $key;
778    }
779  }
780}
[808]781
[1926]782/*
783 * Returns a array with default user value
[808]784 *
[1926]785 * @param convert_str allows to convert string value if necessary
[808]786 */
[1926]787function get_default_user_info($convert_str = true)
[808]788{
[3126]789  global $cache, $conf;
[2084]790
[3126]791  if (!isset($cache['default_user']))
[1926]792  {
[3126]793    $query = 'SELECT * FROM '.USER_INFOS_TABLE.
794            ' WHERE user_id = '.$conf['default_user_id'].';';
[1068]795
[1926]796    $result = pwg_query($query);
[4325]797    $cache['default_user'] = pwg_db_fetch_assoc($result);
[2084]798
[3126]799    if ($cache['default_user'] !== false)
[1930]800    {
[3126]801      unset($cache['default_user']['user_id']);
802      unset($cache['default_user']['status']);
803      unset($cache['default_user']['registration_date']);
[6311]804
805      // theme and language fields may be null in the database (see
806      // bug:1683) This is absolutely not nice to have this code in this
807      // very place, but it avoids a complexe upgrade with an "automatic
808      // fix" in the database => this code should be removed after branch
809      // 2.1 if a migration tasks performs the job the same way
810      if (empty($cache['default_user']['theme']))
811      {
812        mass_updates(
813          USER_INFOS_TABLE,
814          array(
815            'primary' => array('user_id'),
816            'update'  => array('theme')
817            ),
818          array(
819            array(
820              'user_id' => $conf['default_user_id'],
821              'theme' => PHPWG_DEFAULT_TEMPLATE
822              )
823            )
824          );
825        $cache['default_user']['theme'] = PHPWG_DEFAULT_TEMPLATE;
826      }
827     
828      if (empty($cache['default_user']['language']))
829      {
830        mass_updates(
831          USER_INFOS_TABLE,
832          array(
833            'primary' => array('user_id'),
834            'update'  => array('language')
835            ),
836          array(
837            array(
838              'user_id' => $conf['default_user_id'],
839              'language' => PHPWG_DEFAULT_LANGUAGE
840              )
841            )
842          );
843        $cache['default_user']['language'] = PHPWG_DEFAULT_LANGUAGE;
844      }
[1930]845    }
[1926]846  }
[808]847
[3126]848  if (is_array($cache['default_user']) and $convert_str)
[1284]849  {
[1926]850    $default_user = array();
[3126]851    foreach ($cache['default_user'] as $name => $value)
[1926]852    {
853      // If the field is true or false, the variable is transformed into a
854      // boolean value.
855      if ($value == 'true' or $value == 'false')
856      {
857        $default_user[$name] = get_boolean($value);
858      }
859      else
860      {
861        $default_user[$name] = $value;
862      }
863    }
864    return $default_user;
[1284]865  }
[1926]866  else
[1284]867  {
[3126]868    return $cache['default_user'];
[1284]869  }
[1926]870}
871
872/*
873 * Returns a default user value
874 *
875 * @param value_name: name of value
876 * @param sos_value: value used if don't exist value
877 */
878function get_default_user_value($value_name, $sos_value)
879{
880  $default_user = get_default_user_info(true);
[5271]881  if ($default_user === false or empty($default_user[$value_name]))
[1926]882  {
883    return $sos_value;
884  }
[1284]885  else
886  {
[1926]887   return $default_user[$value_name];
[1284]888  }
[1926]889}
[1567]890
[1926]891/*
892 * Returns the default template value
893 *
894 */
[5123]895function get_default_theme()
[1926]896{
[5982]897  $theme = get_default_user_value('theme', PHPWG_DEFAULT_TEMPLATE);
898  if (check_theme_installed($theme))
899  {
900    return $theme;
901  }
902 
903  // let's find the first available theme
904  $active_themes = get_pwg_themes();
905  foreach (array_keys(get_pwg_themes()) as $theme_id)
906  {
907    if (check_theme_installed($theme_id))
908    {
909      return $theme_id;
910    }
911  }
[1926]912}
[808]913
[1926]914/*
915 * Returns the default language value
916 *
917 */
918function get_default_language()
919{
[2425]920  return get_default_user_value('language', PHPWG_DEFAULT_LANGUAGE);
[808]921}
[817]922
923/**
[2425]924  * Returns true if the browser language value is set into param $lang
[2411]925  *
926  */
[2425]927function get_browser_language(&$lang)
[2411]928{
[2572]929  $browser_language = substr(@$_SERVER["HTTP_ACCEPT_LANGUAGE"], 0, 2);
[2411]930  foreach (get_languages() as $language_code => $language_name)
931  {
932    if (substr($language_code, 0, 2) == $browser_language)
933    {
[2425]934      $lang = $language_code;
935      return true;
[2411]936    }
937  }
[2425]938  return false;
[2411]939}
940
941/**
[1926]942 * add user informations based on default values
943 *
944 * @param int user_id / array of user_if
[1930]945 * @param array of values used to override default user values
[1926]946 */
[1930]947function create_user_infos($arg_id, $override_values = null)
[1926]948{
949  global $conf;
950
951  if (is_array($arg_id))
952  {
953    $user_ids = $arg_id;
954  }
955  else
956  {
957    $user_ids = array();
[2229]958    if (is_numeric($arg_id))
[1926]959    {
960      $user_ids[] = $arg_id;
961    }
962  }
963
964  if (!empty($user_ids))
965  {
966    $inserts = array();
[4325]967    list($dbnow) = pwg_db_fetch_row(pwg_query('SELECT NOW();'));
[1926]968
969    $default_user = get_default_user_info(false);
970    if ($default_user === false)
971    {
972      // Default on structure are used
973      $default_user = array();
974    }
975
[1930]976    if (!is_null($override_values))
977    {
978      $default_user = array_merge($default_user, $override_values);
979    }
980
[1926]981    foreach ($user_ids as $user_id)
982    {
[2084]983      $level= isset($default_user['level']) ? $default_user['level'] : 0;
[1926]984      if ($user_id == $conf['webmaster_id'])
985      {
986        $status = 'webmaster';
[2084]987        $level = max( $conf['available_permission_levels'] );
[1926]988      }
[2084]989      else if (($user_id == $conf['guest_id']) or
[1926]990               ($user_id == $conf['default_user_id']))
991      {
992        $status = 'guest';
993      }
994      else
995      {
996        $status = 'normal';
997      }
998
[1930]999      $insert = array_merge(
1000        $default_user,
[1926]1001        array(
1002          'user_id' => $user_id,
1003          'status' => $status,
[2084]1004          'registration_date' => $dbnow,
1005          'level' => $level
[1930]1006          ));
[1926]1007
1008      array_push($inserts, $insert);
[2084]1009    }
[1926]1010
1011    include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
1012    mass_inserts(USER_INFOS_TABLE, array_keys($inserts[0]), $inserts);
1013
1014  }
1015}
1016
1017/**
[1622]1018 * returns the auto login key or false on error
1019 * @param int user_id
[2411]1020 * @param time_t time
[1744]1021 * @param string [out] username
[1622]1022*/
[2409]1023function calculate_auto_login_key($user_id, $time, &$username)
[1622]1024{
1025  global $conf;
1026  $query = '
1027SELECT '.$conf['user_fields']['username'].' AS username
1028  , '.$conf['user_fields']['password'].' AS password
1029FROM '.USERS_TABLE.'
1030WHERE '.$conf['user_fields']['id'].' = '.$user_id;
1031  $result = pwg_query($query);
[4325]1032  if (pwg_db_num_rows($result) > 0)
[1622]1033  {
[4325]1034    $row = pwg_db_fetch_assoc($result);
[4304]1035    $username = stripslashes($row['username']);
1036    $data = $time.stripslashes($row['username']).$row['password'];
[1744]1037    $key = base64_encode(
1038      pack('H*', sha1($data))
1039      .hash_hmac('md5', $data, $conf['secret_key'],true)
1040      );
[1622]1041    return $key;
1042  }
1043  return false;
1044}
1045
[1068]1046/*
1047 * Performs all required actions for user login
1048 * @param int user_id
1049 * @param bool remember_me
1050 * @return void
1051*/
1052function log_user($user_id, $remember_me)
1053{
[1511]1054  global $conf, $user;
[1493]1055
[1641]1056  if ($remember_me and $conf['authorize_remembering'])
[1068]1057  {
[2409]1058    $now = time();
1059    $key = calculate_auto_login_key($user_id, $now, $username);
[1622]1060    if ($key!==false)
[1493]1061    {
[2409]1062      $cookie = $user_id.'-'.$now.'-'.$key;
[2757]1063      if (version_compare(PHP_VERSION, '5.2', '>=') )
1064      {
1065        setcookie($conf['remember_me_name'],
[2409]1066            $cookie,
[2029]1067            time()+$conf['remember_me_length'],
[2757]1068            cookie_path(),ini_get('session.cookie_domain'),ini_get('session.cookie_secure'),
1069            ini_get('session.cookie_httponly')
[2029]1070          );
[2757]1071      }
1072      else
1073      {
1074        setcookie($conf['remember_me_name'],
1075            $cookie,
1076            time()+$conf['remember_me_length'],
1077            cookie_path(),ini_get('session.cookie_domain'),ini_get('session.cookie_secure')
1078          );
1079      }
[2029]1080    }
[1068]1081  }
[1568]1082  else
1083  { // make sure we clean any remember me ...
[2757]1084    setcookie($conf['remember_me_name'], '', 0, cookie_path(),ini_get('session.cookie_domain'));
[1568]1085  }
1086  if ( session_id()!="" )
[1622]1087  { // we regenerate the session for security reasons
1088    // see http://www.acros.si/papers/session_fixation.pdf
[1568]1089    session_regenerate_id();
1090  }
1091  else
1092  {
1093    session_start();
1094  }
[1622]1095  $_SESSION['pwg_uid'] = (int)$user_id;
[1511]1096
1097  $user['id'] = $_SESSION['pwg_uid'];
[1068]1098}
1099
[1070]1100/*
[1511]1101 * Performs auto-connexion when cookie remember_me exists
[1568]1102 * @return true/false
[1511]1103*/
[1567]1104function auto_login() {
[1511]1105  global $conf;
1106
[1568]1107  if ( isset( $_COOKIE[$conf['remember_me_name']] ) )
1108  {
[2409]1109    $cookie = explode('-', stripslashes($_COOKIE[$conf['remember_me_name']]));
[2411]1110    if ( count($cookie)===3
[2409]1111        and is_numeric(@$cookie[0]) /*user id*/
1112        and is_numeric(@$cookie[1]) /*time*/
1113        and time()-$conf['remember_me_length']<=@$cookie[1]
1114        and time()>=@$cookie[1] /*cookie generated in the past*/ )
[1568]1115    {
[2409]1116      $key = calculate_auto_login_key( $cookie[0], $cookie[1], $username );
1117      if ($key!==false and $key===$cookie[2])
[1622]1118      {
[2409]1119        log_user($cookie[0], true);
[4304]1120        trigger_action('login_success', stripslashes($username));
[1622]1121        return true;
1122      }
[1568]1123    }
[2757]1124    setcookie($conf['remember_me_name'], '', 0, cookie_path(),ini_get('session.cookie_domain'));
[1511]1125  }
[1568]1126  return false;
[1511]1127}
1128
[1744]1129/**
1130 * Tries to login a user given username and password (must be MySql escaped)
1131 * return true on success
1132 */
1133function try_log_user($username, $password, $remember_me)
1134{
1135  global $conf;
1136  // retrieving the encrypted password of the login submitted
1137  $query = '
1138SELECT '.$conf['user_fields']['id'].' AS id,
1139       '.$conf['user_fields']['password'].' AS password
1140  FROM '.USERS_TABLE.'
[4367]1141  WHERE '.$conf['user_fields']['username'].' = \''.pwg_db_real_escape_string($username).'\'
[1744]1142;';
[4325]1143  $row = pwg_db_fetch_assoc(pwg_query($query));
[1744]1144  if ($row['password'] == $conf['pass_convert']($password))
1145  {
1146    log_user($row['id'], $remember_me);
[4304]1147    trigger_action('login_success', stripslashes($username));
[1744]1148    return true;
1149  }
[4304]1150  trigger_action('login_failure', stripslashes($username));
[1744]1151  return false;
1152}
1153
[2757]1154/** Performs all the cleanup on user logout */
1155function logout_user()
1156{
1157  global $conf;
1158  $_SESSION = array();
1159  session_unset();
1160  session_destroy();
1161  setcookie(session_name(),'',0,
1162      ini_get('session.cookie_path'),
1163      ini_get('session.cookie_domain')
1164    );
1165  setcookie($conf['remember_me_name'], '', 0, cookie_path(),ini_get('session.cookie_domain'));
1166}
1167
[1511]1168/*
[2029]1169 * Return user status used in this library
1170 * @return string
[1070]1171*/
[2029]1172function get_user_status($user_status)
[1070]1173{
[2029]1174  global $user;
[1072]1175
[1854]1176  if (empty($user_status))
[1075]1177  {
[1854]1178    if (isset($user['status']))
1179    {
1180      $user_status = $user['status'];
1181    }
1182    else
1183    {
1184      // swicth to default value
1185      $user_status = '';
1186    }
[1075]1187  }
[2029]1188  return $user_status;
1189}
[1075]1190
[2029]1191/*
[2325]1192 * Return access_type definition of user
[2029]1193 * Test does with user status
1194 * @return bool
1195*/
1196function get_access_type_status($user_status='')
1197{
1198  global $conf;
1199
1200  switch (get_user_status($user_status))
[1072]1201  {
[1075]1202    case 'guest':
[1851]1203    {
[1854]1204      $access_type_status =
[2325]1205        ($conf['guest_access'] ? ACCESS_GUEST : ACCESS_FREE);
[1851]1206      break;
1207    }
[1075]1208    case 'generic':
[1072]1209    {
[1075]1210      $access_type_status = ACCESS_GUEST;
1211      break;
[1072]1212    }
[1075]1213    case 'normal':
1214    {
1215      $access_type_status = ACCESS_CLASSIC;
1216      break;
1217    }
1218    case 'admin':
1219    {
1220      $access_type_status = ACCESS_ADMINISTRATOR;
1221      break;
1222    }
1223    case 'webmaster':
1224    {
1225      $access_type_status = ACCESS_WEBMASTER;
1226      break;
1227    }
[2221]1228    default:
[1854]1229    {
[2325]1230      $access_type_status = ACCESS_FREE;
[2221]1231      break;
[1854]1232    }
[1072]1233  }
1234
[1085]1235  return $access_type_status;
[1070]1236}
1237
[1072]1238/*
[1085]1239 * Return if user have access to access_type definition
1240 * Test does with user status
1241 * @return bool
1242*/
[1851]1243function is_autorize_status($access_type, $user_status = '')
[1085]1244{
[1851]1245  return (get_access_type_status($user_status) >= $access_type);
[1085]1246}
1247
1248/*
1249 * Check if user have access to access_type definition
[1072]1250 * Stop action if there are not access
1251 * Test does with user status
1252 * @return none
1253*/
[1851]1254function check_status($access_type, $user_status = '')
[1072]1255{
[1851]1256  if (!is_autorize_status($access_type, $user_status))
[1072]1257  {
[1113]1258    access_denied();
[1072]1259  }
1260}
1261
1262/*
[2163]1263 * Return if user is generic
[1072]1264 * @return bool
1265*/
[2163]1266 function is_generic($user_status = '')
[2029]1267{
[2163]1268  return get_user_status($user_status) == 'generic';
[2029]1269}
1270
1271/*
[2163]1272 * Return if user is only a guest
[2161]1273 * @return bool
1274*/
[2163]1275 function is_a_guest($user_status = '')
[2161]1276{
[2163]1277  return get_user_status($user_status) == 'guest';
[2161]1278}
[2163]1279
[2161]1280/*
[2029]1281 * Return if user is, at least, a classic user
1282 * @return bool
1283*/
1284 function is_classic_user($user_status = '')
1285{
1286  return is_autorize_status(ACCESS_CLASSIC, $user_status);
1287}
1288
1289/*
1290 * Return if user is, at least, an administrator
1291 * @return bool
1292*/
[1851]1293 function is_admin($user_status = '')
[1072]1294{
[1851]1295  return is_autorize_status(ACCESS_ADMINISTRATOR, $user_status);
[1072]1296}
1297
[1085]1298/*
[5272]1299 * Return if user is, at least, a webmaster
1300 * @return bool
1301*/
1302 function is_webmaster($user_status = '')
1303{
1304  return is_autorize_status(ACCESS_WEBMASTER, $user_status);
1305}
1306
1307/*
[1085]1308 * Return if current user is an adviser
1309 * @return bool
1310*/
1311function is_adviser()
1312{
1313  global $user;
1314
1315  return ($user['adviser'] == 'true');
1316}
[1458]1317
1318/*
[5195]1319 * Return if current user can edit/delete/validate a comment
1320 * @param action edit/delete/validate
[3445]1321 * @return bool
1322 */
[3622]1323function can_manage_comment($action, $comment_author_id)
[3445]1324{
[5195]1325  global $user, $conf;
1326 
1327  if (is_a_guest())
1328  {
[3445]1329    return false;
1330  }
[5195]1331 
1332  if (!in_array($action, array('delete','edit', 'validate')))
1333  {
1334    return false;
1335  }
1336
1337  if (is_admin())
1338  {
1339    return true;
1340  }
1341
1342  if ('edit' == $action and $conf['user_can_edit_comment'])
1343  {
1344    if ($comment_author_id == $user['id']) {
1345      return true;
1346    }
1347  }
1348
1349  if ('delete' == $action and $conf['user_can_delete_comment'])
1350  {
1351    if ($comment_author_id == $user['id']) {
1352      return true;
1353    }
1354  }
1355
1356  return false;
[3445]1357}
1358
1359/*
[1458]1360 * Return mail address as display text
1361 * @return string
1362*/
1363function get_email_address_as_display_text($email_address)
1364{
1365  global $conf;
1366
[1462]1367  if (!isset($email_address) or (trim($email_address) == ''))
[1458]1368  {
[1462]1369    return '';
[1458]1370  }
1371  else
1372  {
[2237]1373    if (defined('IN_ADMIN') and is_adviser())
[1462]1374    {
1375      return 'adviser.mode@'.$_SERVER['SERVER_NAME'];
1376    }
1377    else
1378    {
1379      return $email_address;
1380    }
[1458]1381  }
1382}
1383
[1677]1384/*
[1817]1385 * Compute sql where condition with restrict and filter data. "FandF" means
1386 * Forbidden and Filters.
[1677]1387 *
[1817]1388 * @param array condition_fields: read function body
1389 * @param string prefix_condition: prefixes sql if condition is not empty
1390 * @param boolean force_one_condition: use at least "1 = 1"
[1677]1391 *
1392 * @return string sql where/conditions
1393 */
[1817]1394function get_sql_condition_FandF(
1395  $condition_fields,
1396  $prefix_condition = null,
1397  $force_one_condition = false
1398  )
[1677]1399{
1400  global $user, $filter;
1401
1402  $sql_list = array();
1403
1404  foreach ($condition_fields as $condition => $field_name)
1405  {
1406    switch($condition)
1407    {
1408      case 'forbidden_categories':
[1817]1409      {
[1677]1410        if (!empty($user['forbidden_categories']))
1411        {
[1817]1412          $sql_list[] =
1413            $field_name.' NOT IN ('.$user['forbidden_categories'].')';
[1677]1414        }
1415        break;
[1817]1416      }
[1677]1417      case 'visible_categories':
[1817]1418      {
[1677]1419        if (!empty($filter['visible_categories']))
1420        {
[1817]1421          $sql_list[] =
1422            $field_name.' IN ('.$filter['visible_categories'].')';
[1677]1423        }
1424        break;
[1817]1425      }
[1677]1426      case 'visible_images':
1427        if (!empty($filter['visible_images']))
1428        {
[1817]1429          $sql_list[] =
1430            $field_name.' IN ('.$filter['visible_images'].')';
[1677]1431        }
[2084]1432        // note there is no break - visible include forbidden
1433      case 'forbidden_images':
1434        if (
1435            !empty($user['image_access_list'])
1436            or $user['image_access_type']!='NOT IN'
1437            )
1438        {
1439          $table_prefix=null;
1440          if ($field_name=='id')
1441          {
1442            $table_prefix = '';
1443          }
1444          elseif ($field_name=='i.id')
1445          {
1446            $table_prefix = 'i.';
1447          }
1448          if ( isset($table_prefix) )
1449          {
1450            $sql_list[]=$table_prefix.'level<='.$user['level'];
1451          }
1452          else
1453          {
1454            $sql_list[]=$field_name.' '.$user['image_access_type']
1455                .' ('.$user['image_access_list'].')';
1456          }
1457        }
[1677]1458        break;
1459      default:
[1817]1460      {
[1677]1461        die('Unknow condition');
1462        break;
[1817]1463      }
[1677]1464    }
1465  }
1466
1467  if (count($sql_list) > 0)
1468  {
1469    $sql = '('.implode(' AND ', $sql_list).')';
1470  }
1471  else
1472  {
[2824]1473    $sql = $force_one_condition ? '1 = 1' : '';
[1677]1474  }
1475
1476  if (isset($prefix_condition) and !empty($sql))
1477  {
1478    $sql = $prefix_condition.' '.$sql;
1479  }
1480
1481  return $sql;
1482}
1483
[1860]1484?>
Note: See TracBrowser for help on using the repository browser.