*/ if (!defined('DOKU_INC')) { die(); } /** * phpBB 3.x Authentication class. */ class auth_plugin_authphpbb3 extends DokuWiki_Auth_Plugin { // @var object phpBB database connection. protected $_phpbb_db_link = null; // @var array phpBB configuration (cached). protected $_phpbb_conf = array( // @var string phpBB root path. 'root_path' => '', // @var string phpBB URL. 'url' => '', // @var string php extension. 'phpEx' => '', // @var string phpBB database's driver to use. 'dbms' => '', // @var string phpBB database's host. 'dbhost' => '', // @var string phpBB database's port. 'dbport' => '', // @var string phpBB database's name. 'dbname' => '', // @var string phpBB database's user. 'dbuser' => '', // @var string phpBB database's password. 'dbpasswd' => '', // @var string phpBB database's table prefix. 'table_prefix' => '', // @var string phpBB cookie's name. 'cookie_name' => '' ); // @var int phpBB user ID. protected $_phpbb_user_id = 0; // @var int phpBB user session ID. protected $_phpbb_user_session_id = ''; // @var int phpBB user type (0 = normal, 1 = inactive, 2 = bot, 3 = founder). protected $_phpbb_user_type = 0; // @var string phpBB user name. protected $_phpbb_username = ''; // @var string phpBB user mail. protected $_phpbb_user_email = ''; // @var array phpBB user's groups. protected $_phpbb_groups = array(); // @var long phpBB user session time. protected $_phpbb_sessiontime = 0; // @var cache DokuWiki cache object. protected $_cache = null; // @var int Cache duration. protected $_cache_duration = 0; // @var int Cache extension file name. protected $_cache_ext_name = '.phpbb3cache'; // @var int Cache unit constant (in seconds). CONST CACHE_DURATION_UNIT = 86400; /* 60 * 60 * 24 = 1 day */ /** * Constructor. */ public function __construct() { if (method_exists(get_parent_class($this), '__construct')) { parent::__construct(); } // Set capabilities accordingly. $this->cando['addUser'] = false; // Can Users be created? $this->cando['delUser'] = false; // Can Users be deleted? $this->cando['modLogin'] = false; // Can login names be changed? $this->cando['modPass'] = false; // Can passwords be changed? $this->cando['modName'] = false; // Can real names be changed? $this->cando['modMail'] = false; // Can emails be changed? $this->cando['modGroups'] = false; // Can groups be changed? $this->cando['getUsers'] = true; // Can a (filtered) list of users be retrieved? $this->cando['getUserCount']= true; // Can the number of users be retrieved? $this->cando['getGroups'] = true; // Can a list of available groups be retrieved? $this->cando['external'] = true; // Does the module do external auth checking? $this->cando['logout'] = true; // Can the user logout again? // Check database connection requirement. if (!class_exists('PDO')) { $this->dbglog('PDO extension for PHP not found.'); $this->success = false; } else { // Load plugin configuration. $this->success = $this->load_configuration(); } if (!$this->success) { msg($this->getLang('config_error'), -1); } } /** * Destructor. */ public function __destruct() { $this->phpbb_disconnect(); $this->_cache = null; if (method_exists(get_parent_class($this), '__destruct')) { parent::__destruct(); } } /** * Writes debug informations. * * @param string $msg Message to write. */ public function dbglog($msg) { $class_name = @get_class($this); if ($class_name !== false) { $msg = $class_name . ': ' . $msg; } dbglog($msg); } /** * Sanitizes a given username. * * @param string $username Username to clean. * @return string Clean username. */ public function clean_username($username) { $username = preg_replace('#(?:[\x00-\x1F\x7F]+|(?:\xC2[\x80-\x9F])+)#', '', $username); $username = preg_replace('# {2,}#', ' ', $username); $username = trim($username); return strtolower($username); } /** * Gets phpBB URL. * * @return string|false phpBB URL if success, false otherwise. */ public function get_phpbb_url() { if (!empty($this->_phpbb_conf['url'])) { return $this->_phpbb_conf['url']; } if ($this->use_phpbb_cache()) { $result = unserialize($this->_cache->retrieveCache(false)); if (is_array($result) && array_key_exists('url', $result)) { $this->_phpbb_conf['url'] = $result['url']; } } if (!empty($this->_phpbb_conf['url'])) { return $this->_phpbb_conf['url']; } if (!$this->phpbb_connect()) { return false; } $query = "SELECT config_name, config_value FROM {$this->_phpbb_conf['table_prefix']}config WHERE config_name IN ('server_protocol', 'server_name', 'script_path', 'server_port')"; $result = $this->_phpbb_sql_link->prepare($query); if ($result === false) { $this->dbglog('error while preparing query for phpBB URL'); return false; } if ($result->execute() === false) { $this->dbglog('error while executing query for phpBB URL'); return false; } $server_protocol = ''; $server_name = ''; $script_path = ''; $server_port = ''; while ($row = $result->fetch(PDO::FETCH_ASSOC)) { switch ($row['config_name']) { case 'server_protocol': $server_protocol = strtolower(trim($row['config_value'])); break; case 'server_name': $server_name = rtrim(trim($row['config_value']), '/'); break; case 'script_path': $script_path = trim($row['config_value']); break; case 'server_port': $server_port = intval($row['config_value']); break; default: break; } } if (empty($server_port)) { $server_port = '80'; if ($server_protocol === 'https://') { $server_port = '443'; } } $server_name = rtrim($server_protocol . $server_name . ':' . $server_port . $script_path, '/'); $this->_phpbb_conf['url'] = $server_name; $result->closeCursor(); $result = null; return $this->_phpbb_conf['url']; } /** * Authenticates the user. Called on every page loaded. * * @param string $user Case sensitive user name. * @param string $pass Plain text password for the user. * @param boolean $sticky Remember login? * @return boolean True for match, false for everything else. */ public function trustExternal($user, $pass, $sticky = false) { global $USERINFO; $b = false; $this->_phpbb_username = ''; $this->_phpbb_user_email = ''; $this->_phpbb_user_session_id = ''; if (empty($user)) { $b = $this->do_login_cookie(); } if (!$b || empty($this->_phpbb_username) || empty($this->_phpbb_user_email)) { return false; } $USERINFO['name'] = utf8_encode($this->_phpbb_username); $USERINFO['mail'] = $this->_phpbb_user_email; $USERINFO['grps'] = $this->_phpbb_groups; $_SERVER['REMOTE_USER'] = $USERINFO['name']; $_SESSION[DOKU_COOKIE]['auth']['user'] = $USERINFO['name']; $_SESSION[DOKU_COOKIE]['auth']['info'] = $USERINFO; return true; } /** * Fetchs user details from phpBB. * * @param string $user Case sensitive username. * @param boolean $requireGroups Whether or not the returned data must include groups. * @return array/boolean False for error conditions and an array for success. * array['name'] string User's name. * array['username'] string User's name. * array['mail'] string User's email address. * array['phpbb_user_id'] string User's ID. * array['phpbb_profile'] string User's link to profile. * array['grps'] array Group names the user belongs to. */ public function getUserData($user, $requireGroups = true) { if (empty($user)) { return false; } $this->_cache_duration = intval($this->getConf('phpbb_cache')); $depends = array('age' => self::CACHE_DURATION_UNIT * $this->_cache_duration); $cache = new cache('authphpbb3_getUserData_' . $user, $this->_cache_ext_name); $user_data = false; if (($this->_cache_duration > 0) && $cache->useCache($depends)) { $user_data = unserialize($cache->retrieveCache(false)); } else { $cache->removeCache(); if (!$this->phpbb_connect()) { return false; } $query = "SELECT user_id, username, username_clean, user_email, user_type FROM {$this->_phpbb_conf['table_prefix']}users WHERE username_clean = ?"; $result = $this->_phpbb_sql_link->prepare($query); if ($result === false) { $this->dbglog('error while preparing query for user data'); return false; } if (!$result->execute(array($this->clean_username($user)))) { $this->dbglog('error while executing query for user data'); return false; } $row = $result->fetch(PDO::FETCH_ASSOC); $this->_phpbb_user_type = (int)$row['user_type']; $this->_phpbb_user_id = (int)$row['user_id']; $this->_phpbb_username = $row['username']; $this->_phpbb_user_email = $row['user_email']; $result->closeCursor(); $result = null; $this->get_phpbb_user_groups(); $this->get_phpbb_url(); $user_data = array( 'name' => $this->_phpbb_username, 'username' => $this->_phpbb_username, 'mail' => $this->_phpbb_user_email, 'phpbb_user_id' => $this->_phpbb_user_id, 'phpbb_profile' => $this->_phpbb_conf['url'] . '/memberlist.php?mode=viewprofile&u=' . $this->_phpbb_user_id, 'grps' => $this->_phpbb_groups ); $cache->storeCache(serialize($user_data)); } $cache = null; return $user_data; } /** * Bulk retrieval of users' data (does not use cache system). * * @param int $start Index of first user to be returned. * @param int $limit Maximum number of users to be returned. * @param array $filter Array of field/pattern pairs. * @return array/boolean List of arrays returned by getUserData function. */ public function retrieveUsers($start = 0, $limit = 0, $filter = array()) { if (!$this->phpbb_connect()) { return false; } $start = intval($start); if ($start < 0) { $start = 0; } $limit = intval($limit); if ($limit <= 0) { // Arbitrary limit. $limit = 10000; } if (is_null($filter)) { $filter = array(); } if (isset($filter['grps'])) { $filter['group'] = $filter['grps']; } foreach (array('user', 'name', 'mail') as $key) { $tmp = '%'; if (isset($filter[$key])) { $tmp = str_replace('%', '', $filter[$key]); if (!is_string($tmp)) { $tmp = ''; } if (empty($tmp)) { $tmp = '%'; } else { $tmp = '%' . $tmp . '%'; } } $filter[$key] = $tmp; } $filter['start'] = (int)$start; $filter['end'] = (int)($start + $limit); $filter['limit'] = (int)$limit; // Gets users. $query = "SELECT user_id, username, username_clean, user_email FROM {$this->_phpbb_conf['table_prefix']}users WHERE (username like :name OR username like :user OR username_clean like :nameclean OR username_clean like :userclean) AND user_email like :mail LIMIT :limit OFFSET :start"; $result = $this->_phpbb_sql_link->prepare($query); if ($result === false) { $this->dbglog('error while preparing query for users data'); return false; } $result->bindValue(':name', $filter['name'], PDO::PARAM_STR); $result->bindValue(':user', $filter['user'], PDO::PARAM_STR); $result->bindValue(':nameclean', $filter['name'], PDO::PARAM_STR); $result->bindValue(':userclean', $filter['user'], PDO::PARAM_STR); $result->bindValue(':mail', $filter['mail'], PDO::PARAM_STR); $result->bindValue(':limit', (int)$filter['limit'], PDO::PARAM_INT); $result->bindValue(':start', (int)$filter['start'], PDO::PARAM_INT); if (!$result->execute()) { $this->dbglog('error while executing query for users data'); return false; } $users = array(); // Gets users' groups. while ($row = $result->fetch(PDO::FETCH_ASSOC)) { $user_data = array( 'name' => $row['username'], 'username' => $row['username_clean'], 'mail' => $row['user_email'], 'phpbb_user_id' => $row['user_id'], 'phpbb_profile' => $this->_phpbb_conf['url'] . '/memberlist.php?mode=viewprofile&u=' . $row['user_id'], 'grps' => array() ); $query = "SELECT * FROM {$this->_phpbb_conf['table_prefix']}groups g, {$this->_phpbb_conf['table_prefix']}users u, {$this->_phpbb_conf['table_prefix']}user_group ug WHERE u.user_id = ug.user_id AND g.group_id = ug.group_id AND u.user_id = ?"; $resgrp = $this->_phpbb_sql_link->prepare($query); if (($resgrp === false) || !$resgrp->execute(array($row['user_id']))) { $this->dbglog('error while executing query for ' . $row['user_id'] . ' groups'); // If no group filter, we still add the user to the list. if (!isset($filter['group'])) { $users[$user_data['username']] = $user_data; } $resgrp->closeCursor(); $resgrp = null; continue; } $ingroup = false; while ($rowgrp = $resgrp->fetch(PDO::FETCH_ASSOC)) { $user_data['grps'][] = $rowgrp['group_name']; if (!$ingroup && isset($filter['group']) && (strpos($rowgrp['group_name'], $filter['group']) !== false)) { $ingroup = true; } } // Apply group's filter. if (!isset($filter['group']) || (isset($filter['group']) && $ingroup)) { $users[$user_data['username']] = $user_data; } $resgrp->closeCursor(); $resgrp = null; } $result->closeCursor(); $result = null; return $users; } /** * Bulk retrieval of groups (does not use cache system). * * @param int $start Index of first group to be returned. * @param int $limit Maximum number of groups to be returned. * @return array/boolean List of groups. */ public function retrieveGroups($start = 0, $limit = 0) { if (!$this->phpbb_connect()) { return false; } $start = intval($start); if ($start < 0) { $start = 0; } $limit = intval($limit); if ($limit <= 0) { // Arbitrary limit. $limit = 10000; } $query = "SELECT * FROM {$this->_phpbb_conf['table_prefix']}groups LIMIT :limit OFFSET :start"; $result = $this->_phpbb_sql_link->prepare($query); if ($result === false) { $this->dbglog('error while preparing query for groups data'); return false; } $result->bindValue(':limit', (int)$limit, PDO::PARAM_INT); $result->bindValue(':start', (int)$start, PDO::PARAM_INT); if (!$result->execute()) { $this->dbglog('error while executing query for groups data'); return false; } $groups = array(); while ($row = $result->fetch(PDO::FETCH_ASSOC)) { if (isset($row['group_name']) && !empty($row['group_name'])) { $groups[$row['group_name']] = $row; } } $result->closeCursor(); $result = null; ksort($groups); return $groups; } /** * Returns the number of users which meet $filter criteria (does not use cache system). * * @param array $filter Array of field/pattern pairs, empty array for no filter. * @return int Number of users matching criteria. */ public function getUserCount($filter = array()) { $users = $this->retrieveUsers(0, 0, $filter); if ($users === false) { return 0; } return count($users); } /** * Logs off the user. */ public function logOff() { if (method_exists(get_parent_class($this), 'logOff')) { parent::logOff(); } if (empty($this->_phpbb_user_session_id)) { $this->get_phpbb_cookie_name(); if (empty($this->_phpbb_conf['cookie_name'])) { return ; } $phpbb_cookie_sid_name = $this->_phpbb_conf['cookie_name'] . '_sid'; if (array_key_exists($phpbb_cookie_sid_name, $_COOKIE)) { $this->_phpbb_user_session_id = $_COOKIE[$phpbb_cookie_sid_name]; } } if (!empty($this->_phpbb_user_session_id) && ($this->get_phpbb_url() !== false) && $this->_phpbb_user_id) { //global $ID; $url = $this->_phpbb_conf['url'] . '/ucp.php?mode=logout&sid=' . $this->_phpbb_user_session_id; // phpBB doesn't natively support the logout redirection yet. //$url .= '&redirect=' . urlencode(wl($ID, '', true)); send_redirect($url); } } /** * Loads the plugin's configuration. * * @return boolean True on success, false otherwise. */ private function load_configuration() { if ($this->use_phpbb_cache()) { $this->_phpbb_conf = unserialize($this->_cache->retrieveCache(false)); } else { $this->_cache->removeCache(); $this->_phpbb_conf['root_path'] = DOKU_INC . rtrim(trim($this->getConf('phpbb_root_path')), '/') . '/'; $this->_phpbb_conf['phpEx'] = substr(strrchr(__FILE__, '.'), 1); if (!@file_exists($this->_phpbb_conf['root_path'] . 'config.' . $this->_phpbb_conf['phpEx'])) { $this->dbglog('phpBB installation not found'); return false; } include($this->_phpbb_conf['root_path'] . 'config.' . $this->_phpbb_conf['phpEx']); $this->_phpbb_conf['dbms'] = $dbms; $this->_phpbb_conf['dbhost'] = empty($dbhost) ? '127.0.0.1' : $dbhost; $this->_phpbb_conf['dbport'] = $dbport; $this->_phpbb_conf['dbname'] = $dbname; $this->_phpbb_conf['dbuser'] = $dbuser; $this->_phpbb_conf['dbpasswd'] = $dbpasswd; $this->_phpbb_conf['table_prefix'] = $table_prefix; foreach (array('dbms', 'dbhost', 'dbname', 'dbuser') as $member) { if (empty($this->_phpbb_conf[$member])) { $this->dbglog("phpBB config variable {$member} not set"); return false; } } if ($this->get_phpbb_url() === false) { $this->dbglog('cannot get phpBB URL'); return false; } if (!$this->get_phpbb_cookie_name()) { $this->dbglog('cannot get phpBB cookie name'); return false; } $this->_cache->storeCache(serialize($this->_phpbb_conf)); } return (!empty($this->_phpbb_conf['url']) && !empty($this->_phpbb_conf['cookie_name'])); } /** * Gets the phpBB configuration cache. * * @return object Cache of the phpBB configuration. */ private function get_phpbb_cache() { if ($this->_cache === null) { $this->_cache = new cache('authphpbb3', $this->_cache_ext_name); } return $this->_cache; } /** * Can use the phpBB configuration cache. * * @return object Cache of the phpBB configuration. */ private function use_phpbb_cache() { $depends = array(); $this->get_phpbb_cache(); $this->_cache_duration = intval($this->getConf('phpbb_cache')); if ($this->_cache_duration > 0) { $depends['age'] = self::CACHE_DURATION_UNIT * $this->_cache_duration; } else { $depends['purge'] = true; } return $this->_cache->useCache($depends); } /** * Connects to phpBB database. * * @return boolean True on success, false otherwise. */ private function phpbb_connect() { if (!$this->_phpbb_db_link) { $host = strtolower(end(explode('\\', $this->_phpbb_conf['dbms']))); $port = ''; $dsn = ''; if (!empty($this->_phpbb_conf['dbport'])) { $port = ';port=' . intval($this->_phpbb_conf['dbport']); } $dsn = ':host=' . $this->_phpbb_conf['dbhost'] . $port . ';dbname=' . $this->_phpbb_conf['dbname']; try { switch ($host) { case 'mysql': case 'mysqli': $dsn = 'mysql' . $dsn . ';charset=utf8'; $this->_phpbb_sql_link = new PDO( $dsn, $this->_phpbb_conf['dbuser'], $this->_phpbb_conf['dbpasswd']); break; case 'postgres': $dsn = 'pgsql' . $dsn . ';user=' . $this->_phpbb_conf['dbuser'] . ';password=' . $this->_phpbb_conf['dbpasswd']; $this->_phpbb_sql_link = new PDO($dsn); $this->_phpbb_sql_link->exec("SET NAMES 'UTF8'"); break; case 'oracle': $dsn = 'oci' . $dsn . ';charset=utf8'; $this->_phpbb_sql_link = new PDO( $dsn, $this->_phpbb_conf['dbuser'], $this->_phpbb_conf['dbpasswd']); break; case 'sqlite': case 'sqlite3': if ($host === 'sqlite') { // SQLite 2 prefix. $host = 'sqlite2'; } else { // SQLite 3 prefix. $host = 'sqlite'; } $dsn = $host . ':' . $this->_phpbb_conf['root_path'] . $this->_phpbb_conf['dbhost']; $this->_phpbb_sql_link = new PDO($dsn); break; default: msg($this->getLang('database_support'), -1); return false; } } catch (PDOException $e) { $this->dbglog('cannot connect to database server (' . $e->getMessage() .')'); msg($this->getLang('database_error'), -1); $this->_phpbb_db_link = null; return false; } } return true; } /** * Disconnects from phpBB database. */ private function phpbb_disconnect() { if ($this->_phpbb_db_link !== null) { $this->_phpbb_db_link = null; } } /** * Gets phpBB cookie's name. * * @return boolean True for success, false otherwise. */ private function get_phpbb_cookie_name() { if (!empty($this->_phpbb_conf['cookie_name'])) { return true; } if ($this->use_phpbb_cache()) { $result = unserialize($this->_cache->retrieveCache(false)); if (is_array($result) && array_key_exists('cookie_name', $result)) { $this->_phpbb_conf['cookie_name'] = $result['cookie_name']; } } if (!empty($this->_phpbb_conf['cookie_name'])) { return true; } if (!$this->phpbb_connect()) { return false; } // Query for cookie_name. $query = "SELECT config_name, config_value FROM {$this->_phpbb_conf['table_prefix']}config WHERE config_name = 'cookie_name'"; $result = $this->_phpbb_sql_link->prepare($query); if ($result === false) { $this->dbglog('error while preparing query for cookie.'); return false; } if (!$result->execute()) { $this->dbglog('error while executing query for cookie.'); return false; } $row = $result->fetch(PDO::FETCH_ASSOC); $this->_phpbb_conf['cookie_name'] = $row['config_value']; $result->closeCursor(); $result = null; return true; } /** * Gets phpBB user's groups. * * @return boolean True for success, false otherwise. */ private function get_phpbb_user_groups() { $this->_phpbb_groups = array(); $this->_phpbb_user_id = filter_var($this->_phpbb_user_id, FILTER_VALIDATE_INT); if (!$this->_phpbb_user_id) { return false; } if (!$this->phpbb_connect()) { return false; } $query = "SELECT * FROM {$this->_phpbb_conf['table_prefix']}groups g, {$this->_phpbb_conf['table_prefix']}users u, {$this->_phpbb_conf['table_prefix']}user_group ug WHERE u.user_id = ug.user_id AND g.group_id = ug.group_id AND u.user_id = ?"; $result = $this->_phpbb_sql_link->prepare($query); if ($result === false) { $this->dbglog('error while preparing query for user\'s groups'); return false; } if (!$result->execute(array($this->_phpbb_user_id))) { $this->dbglog('error while executing query for user\'s groups'); return false; } while ($row = $result->fetch(PDO::FETCH_ASSOC)) { $this->_phpbb_groups[] = $row['group_name']; } // If the user is a founder. if ($this->_phpbb_user_type === 3) { $this->_phpbb_groups[] = 'admin'; } $result->closeCursor(); $result = null; return true; } /** * Authenticate the user using cookie. Called on every page load. * * @return boolean True for success, false otherwise. */ private function do_login_cookie() { if (!$this->phpbb_connect()) { return false; } if (!$this->get_phpbb_cookie_name()) { return false; } $phpbb_cookie_user_sid = $this->_phpbb_conf['cookie_name'] . '_sid'; $phpbb_cookie_user_id = $this->_phpbb_conf['cookie_name'] . '_u'; $this->_phpbb_user_session_id = array_key_exists($phpbb_cookie_user_sid, $_COOKIE) ? $_COOKIE[$phpbb_cookie_user_sid] : null; $phpbb_cookie_user_id = array_key_exists($phpbb_cookie_user_id, $_COOKIE) ? intval($_COOKIE[$phpbb_cookie_user_id]) : null; if (empty($this->_phpbb_user_session_id) || !ctype_xdigit($this->_phpbb_user_session_id)) { $this->dbglog('invalid SID in user\'s cookie ' . '(SID=' . $phpbb_cookie_user_sid . ', Value=' . $this->_phpbb_user_session_id . ')'); return false; } // Get session data from database. $query = "SELECT session_id, session_user_id FROM {$this->_phpbb_conf['table_prefix']}sessions WHERE session_id = ?"; $result = $this->_phpbb_sql_link->prepare($query); if ($result === false) { $this->dbglog('error while preparing query for session'); return false; } if (!$result->execute(array($this->_phpbb_user_session_id))) { $this->dbglog('error while executing query for session'); return false; } $row = $result->fetch(PDO::FETCH_ASSOC); if ($phpbb_cookie_user_id !== (int)$row['session_user_id']) { $this->dbglog('invalid SID/User ID pair'); $result->closeCursor(); $result = null; return false; } $this->_phpbb_user_id = (int)$row['session_user_id']; $this->_phpbb_sessiontime = $row['session_time']; $result->closeCursor(); $result = null; // Update session time. $current_time = time(); if ($current_time > $this->_phpbb_sessiontime) { $query = "UPDATE {$this->_phpbb_conf['table_prefix']}sessions SET session_time = ? WHERE session_id = ?"; $result = $this->_phpbb_sql_link->prepare($query); if ($result === false) { $this->dbglog('error while preparing query for session update'); return false; } if (!$result->execute(array($current_time, $this->_phpbb_user_session_id))) { $this->dbglog('error while executing query for session update'); } $result = null; } // Check for guest session. if ($this->_phpbb_user_id === 1) { return false; } // Get username from database. $query = "SELECT user_id, username, user_email, user_type FROM {$this->_phpbb_conf['table_prefix']}users WHERE user_id = ?"; $result = $this->_phpbb_sql_link->prepare($query); if ($result === false) { $this->dbglog('error while preparing query for username'); return false; } if (!$result->execute(array($this->_phpbb_user_id))) { $this->dbglog('error while executing query for username'); return false; } $row = $result->fetch(PDO::FETCH_ASSOC); $this->_phpbb_user_type = (int)$row['user_type']; $this->_phpbb_username = $row['username']; $this->_phpbb_user_email = $row['user_email']; $result->closeCursor(); $result = null; // Get user groups from database. $this->get_phpbb_user_groups(); return true; } }