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

Last change on this file since 3622 was 3622, checked in by rvelices, 15 years ago

feature 1053: hide categories that contain no photo due to privacy level

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