Verzeichnisstruktur phpBB-3.1.0


Veröffentlicht
27.10.2014

So funktioniert es


Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück

Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

(Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

user.php

Zuletzt modifiziert: 09.10.2024, 12:51 - Dateigröße: 26.46 KiB


001  <?php
002  /**
003  *
004  * This file is part of the phpBB Forum Software package.
005  *
006  * @copyright (c) phpBB Limited <https://www.phpbb.com>
007  * @license GNU General Public License, version 2 (GPL-2.0)
008  *
009  * For full copyright and license information, please see
010  * the docs/CREDITS.txt file.
011  *
012  */
013   
014  namespace phpbb;
015   
016  /**
017  * Base user class
018  *
019  * This is the overarching class which contains (through session extend)
020  * all methods utilised for user functionality during a session.
021  */
022  class user extends \phpbb\session
023  {
024      var $lang = array();
025      var $help = array();
026      var $style = array();
027      var $date_format;
028   
029      /**
030      * DateTimeZone object holding the timezone of the user
031      */
032      public $timezone;
033   
034      /**
035      * @var string Class name of datetime object
036      */
037      protected $datetime;
038   
039      var $lang_name = false;
040      var $lang_id = false;
041      var $lang_path;
042      var $img_lang;
043      var $img_array = array();
044   
045      // Able to add new options (up to id 31)
046      var $keyoptions = array('viewimg' => 0, 'viewflash' => 1, 'viewsmilies' => 2, 'viewsigs' => 3, 'viewavatars' => 4, 'viewcensors' => 5, 'attachsig' => 6, 'bbcode' => 8, 'smilies' => 9, 'sig_bbcode' => 15, 'sig_smilies' => 16, 'sig_links' => 17);
047   
048      /**
049      * Constructor to set the lang path
050      * @param string $datetime_class Class name of datetime class
051      */
052      function __construct($datetime_class)
053      {
054          global $phpbb_root_path;
055   
056          $this->lang_path = $phpbb_root_path . 'language/';
057          $this->datetime = $datetime_class;
058      }
059   
060      /**
061      * Function to set custom language path (able to use directory outside of phpBB)
062      *
063      * @param string $lang_path New language path used.
064      * @access public
065      */
066      function set_custom_lang_path($lang_path)
067      {
068          $this->lang_path = $lang_path;
069   
070          if (substr($this->lang_path, -1) != '/')
071          {
072              $this->lang_path .= '/';
073          }
074      }
075   
076      /**
077      * Setup basic user-specific items (style, language, ...)
078      */
079      function setup($lang_set = false, $style_id = false)
080      {
081          global $db, $request, $template, $config, $auth, $phpEx, $phpbb_root_path, $cache;
082          global $phpbb_dispatcher;
083   
084          if ($this->data['user_id'] != ANONYMOUS)
085          {
086              $user_lang_name = (file_exists($this->lang_path . $this->data['user_lang'] . "/common.$phpEx")) ? $this->data['user_lang'] : basename($config['default_lang']);
087              $user_date_format = $this->data['user_dateformat'];
088              $user_timezone = $this->data['user_timezone'];
089          }
090          else
091          {
092              $lang_override = $request->variable('language', '');
093              if ($lang_override)
094              {
095                  $this->set_cookie('lang', $lang_override, 0, false);
096              }
097              else
098              {
099                  $lang_override = $request->variable($config['cookie_name'] . '_lang', '', true, \phpbb\request\request_interface::COOKIE);
100              }
101              if ($lang_override)
102              {
103                  $use_lang = basename($lang_override);
104                  $user_lang_name = (file_exists($this->lang_path . $use_lang . "/common.$phpEx")) ? $use_lang : basename($config['default_lang']);
105                  $this->data['user_lang'] = $user_lang_name;
106              }
107              else
108              {
109                  $user_lang_name = basename($config['default_lang']);
110              }
111              $user_date_format = $config['default_dateformat'];
112              $user_timezone = $config['board_timezone'];
113   
114              /**
115              * If a guest user is surfing, we try to guess his/her language first by obtaining the browser language
116              * If re-enabled we need to make sure only those languages installed are checked
117              * Commented out so we do not loose the code.
118   
119              if ($request->header('Accept-Language'))
120              {
121                  $accept_lang_ary = explode(',', $request->header('Accept-Language'));
122   
123                  foreach ($accept_lang_ary as $accept_lang)
124                  {
125                      // Set correct format ... guess full xx_YY form
126                      $accept_lang = substr($accept_lang, 0, 2) . '_' . strtoupper(substr($accept_lang, 3, 2));
127                      $accept_lang = basename($accept_lang);
128   
129                      if (file_exists($this->lang_path . $accept_lang . "/common.$phpEx"))
130                      {
131                          $user_lang_name = $config['default_lang'] = $accept_lang;
132                          break;
133                      }
134                      else
135                      {
136                          // No match on xx_YY so try xx
137                          $accept_lang = substr($accept_lang, 0, 2);
138                          $accept_lang = basename($accept_lang);
139   
140                          if (file_exists($this->lang_path . $accept_lang . "/common.$phpEx"))
141                          {
142                              $user_lang_name = $config['default_lang'] = $accept_lang;
143                              break;
144                          }
145                      }
146                  }
147              }
148              */
149          }
150   
151          $user_data = $this->data;
152          $lang_set_ext = array();
153   
154          /**
155          * Event to load language files and modify user data on every page
156          *
157          * @event core.user_setup
158          * @var    array    user_data            Array with user's data row
159          * @var    string    user_lang_name        Basename of the user's langauge
160          * @var    string    user_date_format    User's date/time format
161          * @var    string    user_timezone        User's timezone, should be one of
162          *                            http://www.php.net/manual/en/timezones.php
163          * @var    mixed    lang_set            String or array of language files
164          * @var    array    lang_set_ext        Array containing entries of format
165          *                     array(
166          *                         'ext_name' => (string) [extension name],
167          *                         'lang_set' => (string|array) [language files],
168          *                     )
169          *                     For performance reasons, only load translations
170          *                     that are absolutely needed globally using this
171          *                     event. Use local events otherwise.
172          * @var    mixed    style_id            Style we are going to display
173          * @since 3.1.0-a1
174          */
175          $vars = array(
176              'user_data',
177              'user_lang_name',
178              'user_date_format',
179              'user_timezone',
180              'lang_set',
181              'lang_set_ext',
182              'style_id',
183          );
184          extract($phpbb_dispatcher->trigger_event('core.user_setup', compact($vars)));
185   
186          $this->data = $user_data;
187          $this->lang_name = $user_lang_name;
188          $this->date_format = $user_date_format;
189   
190          try
191          {
192              $this->timezone = new \DateTimeZone($user_timezone);
193          }
194          catch (\Exception $e)
195          {
196              // If the timezone the user has selected is invalid, we fall back to UTC.
197              $this->timezone = new \DateTimeZone('UTC');
198          }
199   
200          // We include common language file here to not load it every time a custom language file is included
201          $lang = &$this->lang;
202   
203          // Do not suppress error if in DEBUG mode
204          $include_result = (defined('DEBUG')) ? (include $this->lang_path . $this->lang_name . "/common.$phpEx") : (@include $this->lang_path . $this->lang_name . "/common.$phpEx");
205   
206          if ($include_result === false)
207          {
208              die('Language file ' . $this->lang_path . $this->lang_name . "/common.$phpEx" . " couldn't be opened.");
209          }
210   
211          $this->add_lang($lang_set);
212          unset($lang_set);
213   
214          foreach ($lang_set_ext as $ext_lang_pair)
215          {
216              $this->add_lang_ext($ext_lang_pair['ext_name'], $ext_lang_pair['lang_set']);
217          }
218          unset($lang_set_ext);
219   
220          $style_request = $request->variable('style', 0);
221          if ($style_request && (!$config['override_user_style'] || $auth->acl_get('a_styles')) && !defined('ADMIN_START'))
222          {
223              global $SID, $_EXTRA_URL;
224   
225              $style_id = $style_request;
226              $SID .= '&amp;style=' . $style_id;
227              $_EXTRA_URL = array('style=' . $style_id);
228          }
229          else
230          {
231              // Set up style
232              $style_id = ($style_id) ? $style_id : ((!$config['override_user_style']) ? $this->data['user_style'] : $config['default_style']);
233          }
234   
235          $sql = 'SELECT *
236              FROM ' . STYLES_TABLE . " s
237              WHERE s.style_id = $style_id";
238          $result = $db->sql_query($sql, 3600);
239          $this->style = $db->sql_fetchrow($result);
240          $db->sql_freeresult($result);
241   
242          // Fallback to user's standard style
243          if (!$this->style && $style_id != $this->data['user_style'])
244          {
245              $style_id = $this->data['user_style'];
246   
247              $sql = 'SELECT *
248                  FROM ' . STYLES_TABLE . " s
249                  WHERE s.style_id = $style_id";
250              $result = $db->sql_query($sql, 3600);
251              $this->style = $db->sql_fetchrow($result);
252              $db->sql_freeresult($result);
253          }
254   
255          // User has wrong style
256          if (!$this->style && $style_id == $this->data['user_style'])
257          {
258              $style_id = $this->data['user_style'] = $config['default_style'];
259   
260              $sql = 'UPDATE ' . USERS_TABLE . "
261                  SET user_style = $style_id
262                  WHERE user_id = {$this->data['user_id']}";
263              $db->sql_query($sql);
264   
265              $sql = 'SELECT *
266                  FROM ' . STYLES_TABLE . " s
267                  WHERE s.style_id = $style_id";
268              $result = $db->sql_query($sql, 3600);
269              $this->style = $db->sql_fetchrow($result);
270              $db->sql_freeresult($result);
271          }
272   
273          if (!$this->style)
274          {
275              trigger_error('NO_STYLE_DATA', E_USER_ERROR);
276          }
277   
278          // Now parse the cfg file and cache it
279          $parsed_items = $cache->obtain_cfg_items($this->style);
280   
281          $check_for = array(
282              'pagination_sep'    => (string) ', '
283          );
284   
285          foreach ($check_for as $key => $default_value)
286          {
287              $this->style[$key] = (isset($parsed_items[$key])) ? $parsed_items[$key] : $default_value;
288              settype($this->style[$key], gettype($default_value));
289   
290              if (is_string($default_value))
291              {
292                  $this->style[$key] = htmlspecialchars($this->style[$key]);
293              }
294          }
295   
296          $template->set_style();
297   
298          $this->img_lang = $this->lang_name;
299   
300          // Call phpbb_user_session_handler() in case external application want to "bend" some variables or replace classes...
301          // After calling it we continue script execution...
302          phpbb_user_session_handler();
303   
304          // If this function got called from the error handler we are finished here.
305          if (defined('IN_ERROR_HANDLER'))
306          {
307              return;
308          }
309   
310          // Disable board if the install/ directory is still present
311          // For the brave development army we do not care about this, else we need to comment out this everytime we develop locally
312          if (!defined('DEBUG') && !defined('ADMIN_START') && !defined('IN_INSTALL') && !defined('IN_LOGIN') && file_exists($phpbb_root_path . 'install') && !is_file($phpbb_root_path . 'install'))
313          {
314              // Adjust the message slightly according to the permissions
315              if ($auth->acl_gets('a_', 'm_') || $auth->acl_getf_global('m_'))
316              {
317                  $message = 'REMOVE_INSTALL';
318              }
319              else
320              {
321                  $message = (!empty($config['board_disable_msg'])) ? $config['board_disable_msg'] : 'BOARD_DISABLE';
322              }
323              trigger_error($message);
324          }
325   
326          // Is board disabled and user not an admin or moderator?
327          if ($config['board_disable'] && !defined('IN_LOGIN') && !defined('SKIP_CHECK_DISABLED') && !$auth->acl_gets('a_', 'm_') && !$auth->acl_getf_global('m_'))
328          {
329              if ($this->data['is_bot'])
330              {
331                  send_status_line(503, 'Service Unavailable');
332              }
333   
334              $message = (!empty($config['board_disable_msg'])) ? $config['board_disable_msg'] : 'BOARD_DISABLE';
335              trigger_error($message);
336          }
337   
338          // Is load exceeded?
339          if ($config['limit_load'] && $this->load !== false)
340          {
341              if ($this->load > floatval($config['limit_load']) && !defined('IN_LOGIN') && !defined('IN_ADMIN'))
342              {
343                  // Set board disabled to true to let the admins/mods get the proper notification
344                  $config['board_disable'] = '1';
345   
346                  if (!$auth->acl_gets('a_', 'm_') && !$auth->acl_getf_global('m_'))
347                  {
348                      if ($this->data['is_bot'])
349                      {
350                          send_status_line(503, 'Service Unavailable');
351                      }
352                      trigger_error('BOARD_UNAVAILABLE');
353                  }
354              }
355          }
356   
357          if (isset($this->data['session_viewonline']))
358          {
359              // Make sure the user is able to hide his session
360              if (!$this->data['session_viewonline'])
361              {
362                  // Reset online status if not allowed to hide the session...
363                  if (!$auth->acl_get('u_hideonline'))
364                  {
365                      $sql = 'UPDATE ' . SESSIONS_TABLE . '
366                          SET session_viewonline = 1
367                          WHERE session_user_id = ' . $this->data['user_id'];
368                      $db->sql_query($sql);
369                      $this->data['session_viewonline'] = 1;
370                  }
371              }
372              else if (!$this->data['user_allow_viewonline'])
373              {
374                  // the user wants to hide and is allowed to  -> cloaking device on.
375                  if ($auth->acl_get('u_hideonline'))
376                  {
377                      $sql = 'UPDATE ' . SESSIONS_TABLE . '
378                          SET session_viewonline = 0
379                          WHERE session_user_id = ' . $this->data['user_id'];
380                      $db->sql_query($sql);
381                      $this->data['session_viewonline'] = 0;
382                  }
383              }
384          }
385   
386          // Does the user need to change their password? If so, redirect to the
387          // ucp profile reg_details page ... of course do not redirect if we're already in the ucp
388          if (!defined('IN_ADMIN') && !defined('ADMIN_START') && $config['chg_passforce'] && !empty($this->data['is_registered']) && $auth->acl_get('u_chgpasswd') && $this->data['user_passchg'] < time() - ($config['chg_passforce'] * 86400))
389          {
390              if (strpos($this->page['query_string'], 'mode=reg_details') === false && $this->page['page_name'] != "ucp.$phpEx")
391              {
392                  redirect(append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=profile&amp;mode=reg_details'));
393              }
394          }
395   
396          return;
397      }
398   
399      /**
400      * More advanced language substitution
401      * Function to mimic sprintf() with the possibility of using phpBB's language system to substitute nullar/singular/plural forms.
402      * Params are the language key and the parameters to be substituted.
403      * This function/functionality is inspired by SHS` and Ashe.
404      *
405      * Example call: <samp>$user->lang('NUM_POSTS_IN_QUEUE', 1);</samp>
406      *
407      * If the first parameter is an array, the elements are used as keys and subkeys to get the language entry:
408      * Example: <samp>$user->lang(array('datetime', 'AGO'), 1)</samp> uses $user->lang['datetime']['AGO'] as language entry.
409      */
410      function lang()
411      {
412          $args = func_get_args();
413          $key = $args[0];
414   
415          if (is_array($key))
416          {
417              $lang = &$this->lang[array_shift($key)];
418   
419              foreach ($key as $_key)
420              {
421                  $lang = &$lang[$_key];
422              }
423          }
424          else
425          {
426              $lang = &$this->lang[$key];
427          }
428   
429          // Return if language string does not exist
430          if (!isset($lang) || (!is_string($lang) && !is_array($lang)))
431          {
432              return $key;
433          }
434   
435          // If the language entry is a string, we simply mimic sprintf() behaviour
436          if (is_string($lang))
437          {
438              if (sizeof($args) == 1)
439              {
440                  return $lang;
441              }
442   
443              // Replace key with language entry and simply pass along...
444              $args[0] = $lang;
445              return call_user_func_array('sprintf', $args);
446          }
447          else if (sizeof($lang) == 0)
448          {
449              // If the language entry is an empty array, we just return the language key
450              return $args[0];
451          }
452   
453          // It is an array... now handle different nullar/singular/plural forms
454          $key_found = false;
455   
456          // We now get the first number passed and will select the key based upon this number
457          for ($i = 1, $num_args = sizeof($args); $i < $num_args; $i++)
458          {
459              if (is_int($args[$i]) || is_float($args[$i]))
460              {
461                  if ($args[$i] == 0 && isset($lang[0]))
462                  {
463                      // We allow each translation using plural forms to specify a version for the case of 0 things,
464                      // so that "0 users" may be displayed as "No users".
465                      $key_found = 0;
466                      break;
467                  }
468                  else
469                  {
470                      $use_plural_form = $this->get_plural_form($args[$i]);
471                      if (isset($lang[$use_plural_form]))
472                      {
473                          // The key we should use exists, so we use it.
474                          $key_found = $use_plural_form;
475                      }
476                      else
477                      {
478                          // If the key we need to use does not exist, we fall back to the previous one.
479                          $numbers = array_keys($lang);
480   
481                          foreach ($numbers as $num)
482                          {
483                              if ($num > $use_plural_form)
484                              {
485                                  break;
486                              }
487   
488                              $key_found = $num;
489                          }
490                      }
491                      break;
492                  }
493              }
494          }
495   
496          // Ok, let's check if the key was found, else use the last entry (because it is mostly the plural form)
497          if ($key_found === false)
498          {
499              $numbers = array_keys($lang);
500              $key_found = end($numbers);
501          }
502   
503          // Use the language string we determined and pass it to sprintf()
504          $args[0] = $lang[$key_found];
505          return call_user_func_array('sprintf', $args);
506      }
507   
508      /**
509      * Determine which plural form we should use.
510      * For some languages this is not as simple as for English.
511      *
512      * @param $number        int|float   The number we want to get the plural case for. Float numbers are floored.
513      * @param $force_rule    mixed   False to use the plural rule of the language package
514      *                               or an integer to force a certain plural rule
515      * @return   int     The plural-case we need to use for the number plural-rule combination
516      */
517      function get_plural_form($number, $force_rule = false)
518      {
519          $number = (int) $number;
520   
521          // Default to English system
522          $plural_rule = ($force_rule !== false) ? $force_rule : ((isset($this->lang['PLURAL_RULE'])) ? $this->lang['PLURAL_RULE'] : 1);
523   
524          return phpbb_get_plural_form($plural_rule, $number);
525      }
526   
527      /**
528      * Add Language Items - use_db and use_help are assigned where needed (only use them to force inclusion)
529      *
530      * @param mixed $lang_set specifies the language entries to include
531      * @param bool $use_db internal variable for recursion, do not use
532      * @param bool $use_help internal variable for recursion, do not use
533      * @param string $ext_name The extension to load language from, or empty for core files
534      *
535      * Examples:
536      * <code>
537      * $lang_set = array('posting', 'help' => 'faq');
538      * $lang_set = array('posting', 'viewtopic', 'help' => array('bbcode', 'faq'))
539      * $lang_set = array(array('posting', 'viewtopic'), 'help' => array('bbcode', 'faq'))
540      * $lang_set = 'posting'
541      * $lang_set = array('help' => 'faq', 'db' => array('help:faq', 'posting'))
542      * </code>
543      */
544      function add_lang($lang_set, $use_db = false, $use_help = false, $ext_name = '')
545      {
546          global $phpEx;
547   
548          if (is_array($lang_set))
549          {
550              foreach ($lang_set as $key => $lang_file)
551              {
552                  // Please do not delete this line.
553                  // We have to force the type here, else [array] language inclusion will not work
554                  $key = (string) $key;
555   
556                  if ($key == 'db')
557                  {
558                      $this->add_lang($lang_file, true, $use_help, $ext_name);
559                  }
560                  else if ($key == 'help')
561                  {
562                      $this->add_lang($lang_file, $use_db, true, $ext_name);
563                  }
564                  else if (!is_array($lang_file))
565                  {
566                      $this->set_lang($this->lang, $this->help, $lang_file, $use_db, $use_help, $ext_name);
567                  }
568                  else
569                  {
570                      $this->add_lang($lang_file, $use_db, $use_help, $ext_name);
571                  }
572              }
573              unset($lang_set);
574          }
575          else if ($lang_set)
576          {
577              $this->set_lang($this->lang, $this->help, $lang_set, $use_db, $use_help, $ext_name);
578          }
579      }
580   
581      /**
582      * Add Language Items from an extension - use_db and use_help are assigned where needed (only use them to force inclusion)
583      *
584      * @param string $ext_name The extension to load language from, or empty for core files
585      * @param mixed $lang_set specifies the language entries to include
586      * @param bool $use_db internal variable for recursion, do not use
587      * @param bool $use_help internal variable for recursion, do not use
588      */
589      function add_lang_ext($ext_name, $lang_set, $use_db = false, $use_help = false)
590      {
591          if ($ext_name === '/')
592          {
593              $ext_name = '';
594          }
595   
596          $this->add_lang($lang_set, $use_db, $use_help, $ext_name);
597      }
598   
599      /**
600      * Set language entry (called by add_lang)
601      * @access private
602      */
603      function set_lang(&$lang, &$help, $lang_file, $use_db = false, $use_help = false, $ext_name = '')
604      {
605          global $phpbb_root_path, $phpEx;
606   
607          // Make sure the language name is set (if the user setup did not happen it is not set)
608          if (!$this->lang_name)
609          {
610              global $config;
611              $this->lang_name = basename($config['default_lang']);
612          }
613   
614          // $lang == $this->lang
615          // $help == $this->help
616          // - add appropriate variables here, name them as they are used within the language file...
617          if (!$use_db)
618          {
619              if ($use_help && strpos($lang_file, '/') !== false)
620              {
621                  $filename = dirname($lang_file) . '/help_' . basename($lang_file);
622              }
623              else
624              {
625                  $filename = (($use_help) ? 'help_' : '') . $lang_file;
626              }
627   
628              if ($ext_name)
629              {
630                  global $phpbb_extension_manager;
631                  $ext_path = $phpbb_extension_manager->get_extension_path($ext_name, true);
632   
633                  $lang_path = $ext_path . 'language/';
634              }
635              else
636              {
637                  $lang_path = $this->lang_path;
638              }
639   
640              if (strpos($phpbb_root_path . $filename, $lang_path . $this->lang_name . '/') === 0)
641              {
642                  $language_filename = $phpbb_root_path . $filename;
643              }
644              else
645              {
646                  $language_filename = $lang_path . $this->lang_name . '/' . $filename . '.' . $phpEx;
647              }
648   
649              // If we are in install, try to use the updated version, when available
650              $install_language_filename = str_replace('language/', 'install/update/new/language/', $language_filename);
651              if (defined('IN_INSTALL') && file_exists($install_language_filename))
652              {
653                  $language_filename = $install_language_filename;
654              }
655   
656              if (!file_exists($language_filename))
657              {
658                  global $config;
659   
660                  if ($this->lang_name == 'en')
661                  {
662                      // The user's selected language is missing the file, the board default's language is missing the file, and the file doesn't exist in /en.
663                      $language_filename = str_replace($lang_path . 'en', $lang_path . $this->data['user_lang'], $language_filename);
664                      trigger_error('Language file ' . $language_filename . ' couldn\'t be opened.', E_USER_ERROR);
665                  }
666                  else if ($this->lang_name == basename($config['default_lang']))
667                  {
668                      // Fall back to the English Language
669                      $reset_lang_name = $this->lang_name;
670                      $this->lang_name = 'en';
671                      $this->set_lang($lang, $help, $lang_file, $use_db, $use_help, $ext_name);
672                      $this->lang_name = $reset_lang_name;
673                  }
674                  else if ($this->lang_name == $this->data['user_lang'])
675                  {
676                      // Fall back to the board default language
677                      $reset_lang_name = $this->lang_name;
678                      $this->lang_name = basename($config['default_lang']);
679                      $this->set_lang($lang, $help, $lang_file, $use_db, $use_help, $ext_name);
680                      $this->lang_name = $reset_lang_name;
681                  }
682   
683                  return;
684              }
685   
686              // Do not suppress error if in DEBUG mode
687              $include_result = (defined('DEBUG')) ? (include $language_filename) : (@include $language_filename);
688   
689              if ($include_result === false)
690              {
691                  trigger_error('Language file ' . $language_filename . ' couldn\'t be opened.', E_USER_ERROR);
692              }
693          }
694          else if ($use_db)
695          {
696              // Get Database Language Strings
697              // Put them into $lang if nothing is prefixed, put them into $help if help: is prefixed
698              // For example: help:faq, posting
699          }
700      }
701   
702      /**
703      * Format user date
704      *
705      * @param int $gmepoch unix timestamp
706      * @param string $format date format in date() notation. | used to indicate relative dates, for example |d m Y|, h:i is translated to Today, h:i.
707      * @param bool $forcedate force non-relative date format.
708      *
709      * @return mixed translated date
710      */
711      function format_date($gmepoch, $format = false, $forcedate = false)
712      {
713          static $utc;
714   
715          if (!isset($utc))
716          {
717              $utc = new \DateTimeZone('UTC');
718          }
719   
720          $time = new $this->datetime($this, "@$gmepoch", $utc);
721          $time->setTimezone($this->timezone);
722   
723          return $time->format($format, $forcedate);
724      }
725   
726      /**
727      * Create a \phpbb\datetime object in the context of the current user
728      *
729      * @since 3.1
730      * @param string $time String in a format accepted by strtotime().
731      * @param DateTimeZone $timezone Time zone of the time.
732      * @return \phpbb\datetime Date time object linked to the current users locale
733      */
734      public function create_datetime($time = 'now', \DateTimeZone $timezone = null)
735      {
736          $timezone = $timezone ?: $this->timezone;
737          return new $this->datetime($this, $time, $timezone);
738      }
739   
740      /**
741      * Get the UNIX timestamp for a datetime in the users timezone, so we can store it in the database.
742      *
743      * @param    string            $format        Format of the entered date/time
744      * @param    string            $time        Date/time with the timezone applied
745      * @param    DateTimeZone    $timezone    Timezone of the date/time, falls back to timezone of current user
746      * @return    int            Returns the unix timestamp
747      */
748      public function get_timestamp_from_format($format, $time, \DateTimeZone $timezone = null)
749      {
750          $timezone = $timezone ?: $this->timezone;
751          $date = \DateTime::createFromFormat($format, $time, $timezone);
752          return ($date !== false) ? $date->format('U') : false;
753      }
754   
755      /**
756      * Get language id currently used by the user
757      */
758      function get_iso_lang_id()
759      {
760          global $config, $db;
761   
762          if (!empty($this->lang_id))
763          {
764              return $this->lang_id;
765          }
766   
767          if (!$this->lang_name)
768          {
769              $this->lang_name = $config['default_lang'];
770          }
771   
772          $sql = 'SELECT lang_id
773              FROM ' . LANG_TABLE . "
774              WHERE lang_iso = '" . $db->sql_escape($this->lang_name) . "'";
775          $result = $db->sql_query($sql);
776          $this->lang_id = (int) $db->sql_fetchfield('lang_id');
777          $db->sql_freeresult($result);
778   
779          return $this->lang_id;
780      }
781   
782      /**
783      * Get users profile fields
784      */
785      function get_profile_fields($user_id)
786      {
787          global $db;
788   
789          if (isset($this->profile_fields))
790          {
791              return;
792          }
793   
794          $sql = 'SELECT *
795              FROM ' . PROFILE_FIELDS_DATA_TABLE . "
796              WHERE user_id = $user_id";
797          $result = $db->sql_query_limit($sql, 1);
798          $this->profile_fields = (!($row = $db->sql_fetchrow($result))) ? array() : $row;
799          $db->sql_freeresult($result);
800      }
801   
802      /**
803      * Specify/Get image
804      */
805      function img($img, $alt = '')
806      {
807          $title = '';
808   
809          if ($alt)
810          {
811              $alt = $this->lang($alt);
812              $title = ' title="' . $alt . '"';
813          }
814          return '<span class="imageset ' . $img . '"' . $title . '>' . $alt . '</span>';
815      }
816   
817      /**
818      * Get option bit field from user options.
819      *
820      * @param int $key option key, as defined in $keyoptions property.
821      * @param int $data bit field value to use, or false to use $this->data['user_options']
822      * @return bool true if the option is set in the bit field, false otherwise
823      */
824      function optionget($key, $data = false)
825      {
826          $var = ($data !== false) ? $data : $this->data['user_options'];
827          return phpbb_optionget($this->keyoptions[$key], $var);
828      }
829   
830      /**
831      * Set option bit field for user options.
832      *
833      * @param int $key Option key, as defined in $keyoptions property.
834      * @param bool $value True to set the option, false to clear the option.
835      * @param int $data Current bit field value, or false to use $this->data['user_options']
836      * @return int|bool If $data is false, the bit field is modified and
837      *                  written back to $this->data['user_options'], and
838      *                  return value is true if the bit field changed and
839      *                  false otherwise. If $data is not false, the new
840      *                  bitfield value is returned.
841      */
842      function optionset($key, $value, $data = false)
843      {
844          $var = ($data !== false) ? $data : $this->data['user_options'];
845   
846          $new_var = phpbb_optionset($this->keyoptions[$key], $value, $var);
847   
848          if ($data === false)
849          {
850              if ($new_var != $var)
851              {
852                  $this->data['user_options'] = $new_var;
853                  return true;
854              }
855              else
856              {
857                  return false;
858              }
859          }
860          else
861          {
862              return $new_var;
863          }
864      }
865   
866      /**
867      * Funtion to make the user leave the NEWLY_REGISTERED system group.
868      * @access public
869      */
870      function leave_newly_registered()
871      {
872          global $db;
873   
874          if (empty($this->data['user_new']))
875          {
876              return false;
877          }
878   
879          if (!function_exists('remove_newly_registered'))
880          {
881              global $phpbb_root_path, $phpEx;
882   
883              include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
884          }
885          if ($group = remove_newly_registered($this->data['user_id'], $this->data))
886          {
887              $this->data['group_id'] = $group;
888   
889          }
890          $this->data['user_permissions'] = '';
891          $this->data['user_new'] = 0;
892   
893          return true;
894      }
895   
896      /**
897      * Returns all password protected forum ids the user is currently NOT authenticated for.
898      *
899      * @return array     Array of forum ids
900      * @access public
901      */
902      function get_passworded_forums()
903      {
904          global $db;
905   
906          $sql = 'SELECT f.forum_id, fa.user_id
907              FROM ' . FORUMS_TABLE . ' f
908              LEFT JOIN ' . FORUMS_ACCESS_TABLE . " fa
909                  ON (fa.forum_id = f.forum_id
910                      AND fa.session_id = '" . $db->sql_escape($this->session_id) . "')
911              WHERE f.forum_password <> ''";
912          $result = $db->sql_query($sql);
913   
914          $forum_ids = array();
915          while ($row = $db->sql_fetchrow($result))
916          {
917              $forum_id = (int) $row['forum_id'];
918   
919              if ($row['user_id'] != $this->data['user_id'])
920              {
921                  $forum_ids[$forum_id] = $forum_id;
922              }
923          }
924          $db->sql_freeresult($result);
925   
926          return $forum_ids;
927      }
928  }
929