Verzeichnisstruktur phpBB-3.3.15


Veröffentlicht
28.08.2024

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