source: trunk/include/functions_user.inc.php @ 9339

Last change on this file since 9339 was 9074, checked in by plg, 13 years ago

bug 1684 fixed: the fix for bug:1683 was an "automatic repair" but it adds
useless code. We couldn't create a migration task on the stable branch, but
on trunk this is possible.

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