source: branches/2.2/include/functions_user.inc.php @ 28741

Last change on this file since 28741 was 11736, checked in by plg, 13 years ago

bug 2338 fixed: force purge on sessions table (each time a user gets connected)

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