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

Last change on this file since 10198 was 10198, checked in by mistic100, 13 years ago

bug:2224 one parameter for change thumnails number (needs some translations)

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