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

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