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

Last change on this file since 9923 was 9923, checked in by patdenice, 13 years ago

bug:2234
HTML characters are allowed in username

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