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. |
|
(Beispiel Datei-Icons)
|
Auf das Icon klicken um den Quellcode anzuzeigen |
user.php
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 .= '&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&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