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

Revision 18164, 35.7 KB checked in by mistic100, 8 years ago (diff)

feature 2754: Add "Email" field for user comments + mandatory "Author"

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