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

Last change on this file since 5560 was 5272, checked in by rub, 14 years ago

Add function is_webmaster (like is_admin function)
Add on ignore list the directory local/personal

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