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

Last change on this file since 5195 was 5195, checked in by plg, 14 years ago

bug 1328: backport the pwg_token on trunk

bug 1329: backport the check_input_parameter on trunk

feature 1026: add pwg_token feature for edit/delete comment. Heavy refactoring
on this feature to make the code simpler and easier to maintain (I hope).

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