diff options
Diffstat (limited to 'phpBB/phpbb')
77 files changed, 2842 insertions, 1584 deletions
diff --git a/phpBB/phpbb/auth/auth.php b/phpBB/phpbb/auth/auth.php index 279959974d..81f8c76fc8 100644 --- a/phpBB/phpbb/auth/auth.php +++ b/phpBB/phpbb/auth/auth.php @@ -970,6 +970,18 @@ class phpbb_auth ); } + // If the auth provider wants us to link an empty account do so and redirect + if ($login['status'] == LOGIN_SUCCESS_LINK_PROFILE) + { + // If this status exists a fourth field is in the $login array called 'redirect_data' + // This data is passed along as GET data to the next page allow the account to be linked + + $params = array('mode' => 'login_link'); + $url = append_sid($phpbb_root_path . 'ucp.' . $phpEx, array_merge($params, $login['redirect_data'])); + + redirect($url); + } + // If login succeeded, we will log the user in... else we pass the login array through... if ($login['status'] == LOGIN_SUCCESS) { diff --git a/phpBB/phpbb/auth/provider/base.php b/phpBB/phpbb/auth/provider/base.php index 7eaf8bb2d3..09e918cee4 100644 --- a/phpBB/phpbb/auth/provider/base.php +++ b/phpBB/phpbb/auth/provider/base.php @@ -57,6 +57,22 @@ abstract class phpbb_auth_provider_base implements phpbb_auth_provider_interface /** * {@inheritdoc} */ + public function get_login_data() + { + return; + } + + /** + * {@inheritdoc} + */ + public function get_auth_link_data() + { + return; + } + + /** + * {@inheritdoc} + */ public function logout($data, $new_session) { return; @@ -69,4 +85,28 @@ abstract class phpbb_auth_provider_base implements phpbb_auth_provider_interface { return; } + + /** + * {@inheritdoc} + */ + public function login_link_has_necessary_data($login_link_data) + { + return; + } + + /** + * {@inheritdoc} + */ + public function link_account(array $link_data) + { + return; + } + + /** + * {@inheritdoc} + */ + public function unlink_account(array $link_data) + { + return; + } } diff --git a/phpBB/phpbb/auth/provider/interface.php b/phpBB/phpbb/auth/provider/interface.php index 47043bc107..eadd5f01d1 100644 --- a/phpBB/phpbb/auth/provider/interface.php +++ b/phpBB/phpbb/auth/provider/interface.php @@ -45,6 +45,11 @@ interface phpbb_auth_provider_interface * 'error_msg' => string * 'user_row' => array * ) + * A fourth key of the array may be present: + * 'redirect_data' This key is only used when 'status' is + * equal to LOGIN_SUCCESS_LINK_PROFILE and its value is an + * associative array that is turned into GET variables on + * the redirect url. */ public function login($username, $password); @@ -80,10 +85,49 @@ interface phpbb_auth_provider_interface * 'TEMPLATE_FILE' => string, * 'TEMPLATE_VARS' => array(...), * ) + * An optional third element may be added to this + * array: 'BLOCK_VAR_NAME'. If this is present, + * then its value should be a string that is used + * to designate the name of the loop used in the + * ACP template file. When this is present, an + * additional key named 'BLOCK_VARS' is required. + * This must be an array containing at least one + * array of variables that will be assigned during + * the loop in the template. An example of this is + * presented below: + * array( + * 'BLOCK_VAR_NAME' => string, + * 'BLOCK_VARS' => array( + * 'KEY IS UNIMPORTANT' => array(...), + * ), + * 'TEMPLATE_FILE' => string, + * 'TEMPLATE_VARS' => array(...), + * ) */ public function get_acp_template($new_config); /** + * Returns an array of data necessary to build custom elements on the login + * form. + * + * @return array|null If this function is not implemented on an auth + * provider then it returns null. If it is implemented + * it will return an array of up to four elements of + * which only 'TEMPLATE_FILE'. If 'BLOCK_VAR_NAME' is + * present then 'BLOCK_VARS' must also be present in + * the array. The fourth element 'VARS' is also + * optional. The array, with all four elements present + * looks like the following: + * array( + * 'TEMPLATE_FILE' => string, + * 'BLOCK_VAR_NAME' => string, + * 'BLOCK_VARS' => array(...), + * 'VARS' => array(...), + * ) + */ + public function get_login_data(); + + /** * Performs additional actions during logout. * * @param array $data An array corresponding to @@ -102,4 +146,52 @@ interface phpbb_auth_provider_interface * session should be closed, or null if not implemented. */ public function validate_session($user); + + /** + * Checks to see if $login_link_data contains all information except for the + * user_id of an account needed to successfully link an external account to + * a forum account. + * + * @param array $link_data Any data needed to link a phpBB account to + * an external account. + * @return string|null Returns a string with a language constant if there + * is data missing or null if there is no error. + */ + public function login_link_has_necessary_data($login_link_data); + + /** + * Links an external account to a phpBB account. + * + * @param array $link_data Any data needed to link a phpBB account to + * an external account. + */ + public function link_account(array $link_data); + + /** + * Returns an array of data necessary to build the ucp_auth_link page + * + * @return array|null If this function is not implemented on an auth + * provider then it returns null. If it is implemented + * it will return an array of up to four elements of + * which only 'TEMPLATE_FILE'. If 'BLOCK_VAR_NAME' is + * present then 'BLOCK_VARS' must also be present in + * the array. The fourth element 'VARS' is also + * optional. The array, with all four elements present + * looks like the following: + * array( + * 'TEMPLATE_FILE' => string, + * 'BLOCK_VAR_NAME' => string, + * 'BLOCK_VARS' => array(...), + * 'VARS' => array(...), + * ) + */ + public function get_auth_link_data(); + + /** + * Unlinks an external account from a phpBB account. + * + * @param array $link_data Any data needed to unlink a phpBB account + * from a phpbb account. + */ + public function unlink_account(array $link_data); } diff --git a/phpBB/phpbb/auth/provider/oauth/oauth.php b/phpBB/phpbb/auth/provider/oauth/oauth.php new file mode 100644 index 0000000000..be0b8bb7d6 --- /dev/null +++ b/phpBB/phpbb/auth/provider/oauth/oauth.php @@ -0,0 +1,618 @@ +<?php +/** +* +* @package auth +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +use OAuth\Common\Consumer\Credentials; +use OAuth\Common\Http\Uri\Uri; + +/** +* OAuth authentication provider for phpBB3 +* +* @package auth +*/ +class phpbb_auth_provider_oauth extends phpbb_auth_provider_base +{ + /** + * Database driver + * + * @var phpbb_db_driver + */ + protected $db; + + /** + * phpBB config + * + * @var phpbb_config + */ + protected $config; + + /** + * phpBB request object + * + * @var phpbb_request + */ + protected $request; + + /** + * phpBB user + * + * @var phpbb_user + */ + protected $user; + + /** + * OAuth token table + * + * @var string + */ + protected $auth_provider_oauth_token_storage_table; + + /** + * OAuth account association table + * + * @var string + */ + protected $auth_provider_oauth_token_account_assoc; + + /** + * All OAuth service providers + * + * @var phpbb_di_service_collection Contains phpbb_auth_provider_oauth_service_interface + */ + protected $service_providers; + + /** + * Users table + * + * @var string + */ + protected $users_table; + + /** + * Cached current uri object + * + * @var \OAuth\Common\Http\Uri\UriInterface|null + */ + protected $current_uri; + + /** + * phpBB root path + * + * @var string + */ + protected $phpbb_root_path; + + /** + * PHP extenstion + * + * @var string + */ + protected $php_ext; + + /** + * OAuth Authentication Constructor + * + * @param phpbb_db_driver $db + * @param phpbb_config $config + * @param phpbb_request $request + * @param phpbb_user $user + * @param string $auth_provider_oauth_token_storage_table + * @param string $auth_provider_oauth_token_account_assoc + * @param phpbb_di_service_collection $service_providers Contains phpbb_auth_provider_oauth_service_interface + * @param string $users_table + * @param string $phpbb_root_path + * @param string $php_ext + */ + public function __construct(phpbb_db_driver $db, phpbb_config $config, phpbb_request $request, phpbb_user $user, $auth_provider_oauth_token_storage_table, $auth_provider_oauth_token_account_assoc, phpbb_di_service_collection $service_providers, $users_table, $phpbb_root_path, $php_ext) + { + $this->db = $db; + $this->config = $config; + $this->request = $request; + $this->user = $user; + $this->auth_provider_oauth_token_storage_table = $auth_provider_oauth_token_storage_table; + $this->auth_provider_oauth_token_account_assoc = $auth_provider_oauth_token_account_assoc; + $this->service_providers = $service_providers; + $this->users_table = $users_table; + $this->phpbb_root_path = $phpbb_root_path; + $this->php_ext = $php_ext; + } + + /** + * {@inheritdoc} + */ + public function init() + { + // This does not test whether or not the key and secret provided are valid. + foreach ($this->service_providers as $service_provider) + { + $credentials = $service_provider->get_service_credentials(); + + if (($credentials['key'] && !$credentials['secret']) || (!$credentials['key'] && $credentials['secret'])) + { + return $this->user->lang['AUTH_PROVIDER_OAUTH_ERROR_ELEMENT_MISSING']; + } + } + return false; + } + + /** + * {@inheritdoc} + */ + public function login($username, $password) + { + // Temporary workaround for only having one authentication provider available + if (!$this->request->is_set('oauth_service')) + { + $provider = new phpbb_auth_provider_db($this->db, $this->config, $this->request, $this->user, $this->phpbb_root_path, $this->php_ext); + return $provider->login($username, $password); + } + + // Requst the name of the OAuth service + $service_name_original = $this->request->variable('oauth_service', '', false); + $service_name = 'auth.provider.oauth.service.' . strtolower($service_name_original); + if ($service_name_original === '' || !array_key_exists($service_name, $this->service_providers)) + { + return array( + 'status' => LOGIN_ERROR_EXTERNAL_AUTH, + 'error_msg' => 'LOGIN_ERROR_OAUTH_SERVICE_DOES_NOT_EXIST', + 'user_row' => array('user_id' => ANONYMOUS), + ); + } + + // Get the service credentials for the given service + $service_credentials = $this->service_providers[$service_name]->get_service_credentials(); + + $storage = new phpbb_auth_provider_oauth_token_storage($this->db, $this->user, $this->auth_provider_oauth_token_storage_table); + $query = 'mode=login&login=external&oauth_service=' . $service_name_original; + $service = $this->get_service($service_name_original, $storage, $service_credentials, $this->service_providers[$service_name]->get_auth_scope(), $query); + + if ($this->request->is_set('code', phpbb_request_interface::GET)) + { + $this->service_providers[$service_name]->set_external_service_provider($service); + $unique_id = $this->service_providers[$service_name]->perform_auth_login(); + + // Check to see if this provider is already assosciated with an account + $data = array( + 'provider' => $service_name_original, + 'oauth_provider_id' => $unique_id + ); + $sql = 'SELECT user_id FROM ' . $this->auth_provider_oauth_token_account_assoc . ' + WHERE ' . $this->db->sql_build_array('SELECT', $data); + $result = $this->db->sql_query($sql); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + if (!$row) + { + // The user does not yet exist, ask to link or create profile + return array( + 'status' => LOGIN_SUCCESS_LINK_PROFILE, + 'error_msg' => 'LOGIN_OAUTH_ACCOUNT_NOT_LINKED', + 'user_row' => array(), + 'redirect_data' => array( + 'auth_provider' => 'oauth', + 'login_link_oauth_service' => $service_name_original, + ), + ); + } + + // Retrieve the user's account + $sql = 'SELECT user_id, username, user_password, user_passchg, user_pass_convert, user_email, user_type, user_login_attempts + FROM ' . $this->users_table . ' + WHERE user_id = ' . (int) $row['user_id']; + $result = $this->db->sql_query($sql); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + if (!$row) + { + throw new Exception('AUTH_PROVIDER_OAUTH_ERROR_INVALID_ENTRY'); + } + + // Update token storage to store the user_id + $storage->set_user_id($row['user_id']); + + // The user is now authenticated and can be logged in + return array( + 'status' => LOGIN_SUCCESS, + 'error_msg' => false, + 'user_row' => $row, + ); + } + else + { + $url = $service->getAuthorizationUri(); + header('Location: ' . $url); + } + } + + /** + * Returns the cached current_uri object or creates and caches it if it is + * not already created. In each case the query string is updated based on + * the $query parameter. + * + * @param string $service_name The name of the service + * @param string $query The query string of the current_uri + * used in redirects + * @return \OAuth\Common\Http\Uri\UriInterface + */ + protected function get_current_uri($service_name, $query) + { + if ($this->current_uri) + { + $this->current_uri->setQuery($query); + return $this->current_uri; + } + + $uri_factory = new \OAuth\Common\Http\Uri\UriFactory(); + $current_uri = $uri_factory->createFromSuperGlobalArray($this->request->get_super_global(phpbb_request_interface::SERVER)); + $current_uri->setQuery($query); + + $this->current_uri = $current_uri; + return $current_uri; + } + + /** + * Returns a new service object + * + * @param string $service_name The name of the service + * @param phpbb_auth_oauth_token_storage $storage + * @param array $service_credentials {@see phpbb_auth_provider_oauth::get_service_credentials} + * @param array $scope The scope of the request against + * the api. + * @param string $query The query string of the + * current_uri used in redirection + * @return \OAuth\Common\Service\ServiceInterface + */ + protected function get_service($service_name, phpbb_auth_provider_oauth_token_storage $storage, array $service_credentials, array $scopes = array(), $query) + { + $current_uri = $this->get_current_uri($service_name, $query); + + // Setup the credentials for the requests + $credentials = new Credentials( + $service_credentials['key'], + $service_credentials['secret'], + $current_uri->getAbsoluteUri() + ); + + $service_factory = new \OAuth\ServiceFactory(); + $service = $service_factory->createService($service_name, $credentials, $storage, $scopes); + + if (!$service) + { + throw new Exception('AUTH_PROVIDER_OAUTH_ERROR_SERVICE_NOT_CREATED'); + } + + return $service; + } + + /** + * {@inheritdoc} + */ + public function get_login_data() + { + $login_data = array( + 'TEMPLATE_FILE' => 'login_body_oauth.html', + 'BLOCK_VAR_NAME' => 'oauth', + 'BLOCK_VARS' => array(), + ); + + foreach ($this->service_providers as $service_name => $service_provider) + { + // Only include data if the credentials are set + $credentials = $service_provider->get_service_credentials(); + if ($credentials['key'] && $credentials['secret']) + { + $actual_name = str_replace('auth.provider.oauth.service.', '', $service_name); + $redirect_url = build_url(false) . '&login=external&oauth_service=' . $actual_name; + $login_data['BLOCK_VARS'][$service_name] = array( + 'REDIRECT_URL' => redirect($redirect_url, true), + 'SERVICE_NAME' => $this->user->lang['AUTH_PROVIDER_OAUTH_SERVICE_' . strtoupper($actual_name)], + ); + } + } + + return $login_data; + } + + /** + * {@inheritdoc} + */ + public function acp() + { + $ret = array(); + + foreach ($this->service_providers as $service_name => $service_provider) + { + $actual_name = str_replace('auth.provider.oauth.service.', '', $service_name); + $ret[] = 'auth_oauth_' . $actual_name . '_key'; + $ret[] = 'auth_oauth_' . $actual_name . '_secret'; + } + + return $ret; + } + + /** + * {@inheritdoc} + */ + public function get_acp_template($new_config) + { + $ret = array( + 'BLOCK_VAR_NAME' => 'oauth_services', + 'BLOCK_VARS' => array(), + 'TEMPLATE_FILE' => 'auth_provider_oauth.html', + 'TEMPLATE_VARS' => array(), + ); + + foreach ($this->service_providers as $service_name => $service_provider) + { + $actual_name = str_replace('auth.provider.oauth.service.', '', $service_name); + $ret['BLOCK_VARS'][$actual_name] = array( + 'ACTUAL_NAME' => $this->user->lang['AUTH_PROVIDER_OAUTH_SERVICE_' . strtoupper($actual_name)], + 'KEY' => $new_config['auth_oauth_' . $actual_name . '_key'], + 'NAME' => $actual_name, + 'SECRET' => $new_config['auth_oauth_' . $actual_name . '_secret'], + ); + } + + return $ret; + } + + /** + * {@inheritdoc} + */ + public function login_link_has_necessary_data($login_link_data) + { + if (empty($login_link_data)) + { + return 'LOGIN_LINK_NO_DATA_PROVIDED'; + } + + if (!array_key_exists('oauth_service', $login_link_data) || !$login_link_data['oauth_service'] || + !array_key_exists('link_method', $login_link_data) || !$login_link_data['link_method']) + { + return 'LOGIN_LINK_MISSING_DATA'; + } + + return null; + } + + /** + * {@inheritdoc} + */ + public function link_account(array $link_data) + { + // Check for a valid link method (auth_link or login_link) + if (!array_key_exists('link_method', $link_data) || + !in_array($link_data['link_method'], array( + 'auth_link', + 'login_link', + ))) + { + return 'LOGIN_LINK_MISSING_DATA'; + } + + // We must have an oauth_service listed, check for it two ways + if (!array_key_exists('oauth_service', $link_data) || !$link_data['oauth_service']) + { + $link_data['oauth_service'] = $this->request->variable('oauth_service', ''); + + if (!$link_data['oauth_service']) + { + return 'LOGIN_LINK_MISSING_DATA'; + } + } + + $service_name = 'auth.provider.oauth.service.' . strtolower($link_data['oauth_service']); + if (!array_key_exists($service_name, $this->service_providers)) + { + return 'LOGIN_ERROR_OAUTH_SERVICE_DOES_NOT_EXIST'; + } + + switch ($link_data['link_method']) + { + case 'auth_link': + return $this->link_account_auth_link($link_data, $service_name); + case 'login_link': + return $this->link_account_login_link($link_data, $service_name); + } + } + + /** + * Performs the account linking for login_link + * + * @param array $link_data The same variable given to {@see phpbb_auth_provider_interface::link_account} + * @param string $service_name The name of the service being used in + * linking. + * @return string|null Returns a language constant (string) if an error is + * encountered, or null on success. + */ + protected function link_account_login_link(array $link_data, $service_name) + { + $storage = new phpbb_auth_provider_oauth_token_storage($this->db, $this->user, $this->auth_provider_oauth_token_storage_table); + + // Check for an access token, they should have one + if (!$storage->has_access_token_by_session($service_name)) + { + return 'LOGIN_LINK_ERROR_OAUTH_NO_ACCESS_TOKEN'; + } + + // Prepare the query string + $query = 'mode=login_link&login_link_oauth_service=' . strtolower($link_data['oauth_service']); + + // Prepare for an authentication request + $service_credentials = $this->service_providers[$service_name]->get_service_credentials(); + $scopes = $this->service_providers[$service_name]->get_auth_scope(); + $service = $this->get_service(strtolower($link_data['oauth_service']), $storage, $service_credentials, $scopes, $query); + $this->service_providers[$service_name]->set_external_service_provider($service); + + // The user has already authenticated successfully, request to authenticate again + $unique_id = $this->service_providers[$service_name]->perform_token_auth(); + + // Insert into table, they will be able to log in after this + $data = array( + 'user_id' => $link_data['user_id'], + 'provider' => strtolower($link_data['oauth_service']), + 'oauth_provider_id' => $unique_id, + ); + + $this->link_account_perform_link($data); + // Update token storage to store the user_id + $storage->set_user_id($link_data['user_id']); + } + + /** + * Performs the account linking for auth_link + * + * @param array $link_data The same variable given to {@see phpbb_auth_provider_interface::link_account} + * @param string $service_name The name of the service being used in + * linking. + * @return string|null Returns a language constant (string) if an error is + * encountered, or null on success. + */ + protected function link_account_auth_link(array $link_data, $service_name) + { + $storage = new phpbb_auth_provider_oauth_token_storage($this->db, $this->user, $this->auth_provider_oauth_token_storage_table); + $query = 'i=ucp_auth_link&mode=auth_link&link=1&oauth_service=' . strtolower($link_data['oauth_service']); + $service_credentials = $this->service_providers[$service_name]->get_service_credentials(); + $scopes = $this->service_providers[$service_name]->get_auth_scope(); + $service = $this->get_service(strtolower($link_data['oauth_service']), $storage, $service_credentials, $scopes, $query); + + if ($this->request->is_set('code', phpbb_request_interface::GET)) + { + $this->service_providers[$service_name]->set_external_service_provider($service); + $unique_id = $this->service_providers[$service_name]->perform_auth_login(); + + // Insert into table, they will be able to log in after this + $data = array( + 'user_id' => $this->user->data['user_id'], + 'provider' => strtolower($link_data['oauth_service']), + 'oauth_provider_id' => $unique_id, + ); + + $this->link_account_perform_link($data); + } + else + { + $url = $service->getAuthorizationUri(); + header('Location: ' . $url); + } + } + + /** + * Performs the query that inserts an account link + * + * @param array $data This array is passed to db->sql_build_array + */ + protected function link_account_perform_link(array $data) + { + $sql = 'INSERT INTO ' . $this->auth_provider_oauth_token_account_assoc . ' + ' . $this->db->sql_build_array('INSERT', $data); + $this->db->sql_query($sql); + } + + /** + * {@inheritdoc} + */ + public function logout($data, $new_session) + { + // Clear all tokens belonging to the user + $storage = new phpbb_auth_provider_oauth_token_storage($this->db, $this->user, $this->auth_provider_oauth_token_storage_table); + $storage->clearAllTokens(); + + return; + } + + /** + * {@inheritdoc} + */ + public function get_auth_link_data() + { + $block_vars = array(); + + // Get all external accounts tied to the current user + $data = array( + 'user_id' => (int) $this->user->data['user_id'], + ); + $sql = 'SELECT oauth_provider_id, provider FROM ' . $this->auth_provider_oauth_token_account_assoc . ' + WHERE ' . $this->db->sql_build_array('SELECT', $data); + $result = $this->db->sql_query($sql); + $rows = $this->db->sql_fetchrowset($result); + $this->db->sql_freeresult($result); + + $oauth_user_ids = array(); + + if ($rows !== false && sizeof($rows)) + { + foreach ($rows as $row) + { + $oauth_user_ids[$row['provider']] = $row['oauth_provider_id']; + } + } + unset($rows); + + foreach ($this->service_providers as $service_name => $service_provider) + { + // Only include data if the credentials are set + $credentials = $service_provider->get_service_credentials(); + if ($credentials['key'] && $credentials['secret']) + { + $actual_name = str_replace('auth.provider.oauth.service.', '', $service_name); + + $block_vars[$service_name] = array( + 'HIDDEN_FIELDS' => array( + 'link' => (!isset($oauth_user_ids[$actual_name])), + 'oauth_service' => $actual_name, + ), + + 'SERVICE_NAME' => $this->user->lang['AUTH_PROVIDER_OAUTH_SERVICE_' . strtoupper($actual_name)], + 'UNIQUE_ID' => (isset($oauth_user_ids[$actual_name])) ? $oauth_user_ids[$actual_name] : null, + ); + } + } + + return array( + 'BLOCK_VAR_NAME' => 'oauth', + 'BLOCK_VARS' => $block_vars, + + 'TEMPLATE_FILE' => 'ucp_auth_link_oauth.html', + ); + } + + /** + * {@inheritdoc} + */ + public function unlink_account(array $link_data) + { + if (!array_key_exists('oauth_service', $link_data) || !$link_data['oauth_service']) + { + return 'LOGIN_LINK_MISSING_DATA'; + } + + // Remove the link + $sql = 'DELETE FROM ' . $this->auth_provider_oauth_token_account_assoc . " + WHERE provider = '" . $this->db->sql_escape($link_data['oauth_service']) . "' + AND user_id = " . (int) $this->user->data['user_id']; + $this->db->sql_query($sql); + + // Clear all tokens belonging to the user on this servce + $service_name = 'auth.provider.oauth.service.' . strtolower($link_data['oauth_service']); + $storage = new phpbb_auth_provider_oauth_token_storage($this->db, $this->user, $this->auth_provider_oauth_token_storage_table); + $storage->clearToken($service_name); + + return; + } +} diff --git a/phpBB/phpbb/auth/provider/oauth/service/base.php b/phpBB/phpbb/auth/provider/oauth/service/base.php new file mode 100644 index 0000000000..1eb49b4265 --- /dev/null +++ b/phpBB/phpbb/auth/provider/oauth/service/base.php @@ -0,0 +1,55 @@ +<?php +/** +* +* @package auth +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** +* Base OAuth abstract class that all OAuth services should implement +* +* @package auth +*/ +abstract class phpbb_auth_provider_oauth_service_base implements phpbb_auth_provider_oauth_service_interface +{ + /** + * External OAuth service provider + * + * @var \OAuth\Common\Service\ServiceInterface + */ + protected $service_provider; + + /** + * {@inheritdoc} + */ + public function get_external_service_provider() + { + return $this->service_provider; + } + + /** + * {@inheritdoc} + */ + public function get_auth_scope() + { + return array(); + } + + /** + * {@inheritdoc} + */ + public function set_external_service_provider(\OAuth\Common\Service\ServiceInterface $service_provider) + { + $this->service_provider = $service_provider; + } +} diff --git a/phpBB/phpbb/auth/provider/oauth/service/bitly.php b/phpBB/phpbb/auth/provider/oauth/service/bitly.php new file mode 100644 index 0000000000..3bafdd59ce --- /dev/null +++ b/phpBB/phpbb/auth/provider/oauth/service/bitly.php @@ -0,0 +1,98 @@ +<?php +/** +* +* @package auth +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** +* Bitly OAuth service +* +* @package auth +*/ +class phpbb_auth_provider_oauth_service_bitly extends phpbb_auth_provider_oauth_service_base +{ + /** + * phpBB config + * + * @var phpbb_config + */ + protected $config; + + /** + * phpBB request + * + * @var phpbb_request + */ + protected $request; + + /** + * Constructor + * + * @param phpbb_config $config + * @param phpbb_request $request + */ + public function __construct(phpbb_config $config, phpbb_request $request) + { + $this->config = $config; + $this->request = $request; + } + + /** + * {@inheritdoc} + */ + public function get_service_credentials() + { + return array( + 'key' => $this->config['auth_oauth_bitly_key'], + 'secret' => $this->config['auth_oauth_bitly_secret'], + ); + } + + /** + * {@inheritdoc} + */ + public function perform_auth_login() + { + if (!($this->service_provider instanceof \OAuth\OAuth2\Service\Bitly)) + { + throw new phpbb_auth_provider_oauth_service_exception('AUTH_PROVIDER_OAUTH_ERROR_INVALID_SERVICE_TYPE'); + } + + // This was a callback request from bitly, get the token + $this->service_provider->requestAccessToken($this->request->variable('code', '')); + + // Send a request with it + $result = json_decode($this->service_provider->request('user/info'), true); + + // Return the unique identifier returned from bitly + return $result['data']['login']; + } + + /** + * {@inheritdoc} + */ + public function perform_token_auth() + { + if (!($this->service_provider instanceof \OAuth\OAuth2\Service\Bitly)) + { + throw new phpbb_auth_provider_oauth_service_exception('AUTH_PROVIDER_OAUTH_ERROR_INVALID_SERVICE_TYPE'); + } + + // Send a request with it + $result = json_decode($this->service_provider->request('user/info'), true); + + // Return the unique identifier returned from bitly + return $result['data']['login']; + } +} diff --git a/phpBB/phpbb/auth/provider/oauth/service/exception.php b/phpBB/phpbb/auth/provider/oauth/service/exception.php new file mode 100644 index 0000000000..23d3387951 --- /dev/null +++ b/phpBB/phpbb/auth/provider/oauth/service/exception.php @@ -0,0 +1,25 @@ +<?php +/** +* +* @package auth +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** +* OAuth service exception class +* +* @package auth +*/ +class phpbb_auth_provider_oauth_service_exception extends RuntimeException +{ +} diff --git a/phpBB/phpbb/auth/provider/oauth/service/facebook.php b/phpBB/phpbb/auth/provider/oauth/service/facebook.php new file mode 100644 index 0000000000..49206b7654 --- /dev/null +++ b/phpBB/phpbb/auth/provider/oauth/service/facebook.php @@ -0,0 +1,98 @@ +<?php +/** +* +* @package auth +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** +* Facebook OAuth service +* +* @package auth +*/ +class phpbb_auth_provider_oauth_service_facebook extends phpbb_auth_provider_oauth_service_base +{ + /** + * phpBB config + * + * @var phpbb_config + */ + protected $config; + + /** + * phpBB request + * + * @var phpbb_request + */ + protected $request; + + /** + * Constructor + * + * @param phpbb_config $config + * @param phpbb_request $request + */ + public function __construct(phpbb_config $config, phpbb_request $request) + { + $this->config = $config; + $this->request = $request; + } + + /** + * {@inheritdoc} + */ + public function get_service_credentials() + { + return array( + 'key' => $this->config['auth_oauth_facebook_key'], + 'secret' => $this->config['auth_oauth_facebook_secret'], + ); + } + + /** + * {@inheritdoc} + */ + public function perform_auth_login() + { + if (!($this->service_provider instanceof \OAuth\OAuth2\Service\Facebook)) + { + throw new phpbb_auth_provider_oauth_service_exception('AUTH_PROVIDER_OAUTH_ERROR_INVALID_SERVICE_TYPE'); + } + + // This was a callback request, get the token + $this->service_provider->requestAccessToken($this->request->variable('code', '')); + + // Send a request with it + $result = json_decode($this->service_provider->request('/me'), true); + + // Return the unique identifier + return $result['id']; + } + + /** + * {@inheritdoc} + */ + public function perform_token_auth() + { + if (!($this->service_provider instanceof \OAuth\OAuth2\Service\Facebook)) + { + throw new phpbb_auth_provider_oauth_service_exception('AUTH_PROVIDER_OAUTH_ERROR_INVALID_SERVICE_TYPE'); + } + + // Send a request with it + $result = json_decode($this->service_provider->request('/me'), true); + + // Return the unique identifier + return $result['id']; + } +} diff --git a/phpBB/phpbb/auth/provider/oauth/service/google.php b/phpBB/phpbb/auth/provider/oauth/service/google.php new file mode 100644 index 0000000000..d4ef6e1d42 --- /dev/null +++ b/phpBB/phpbb/auth/provider/oauth/service/google.php @@ -0,0 +1,109 @@ +<?php +/** +* +* @package auth +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** +* Google OAuth service +* +* @package auth +*/ +class phpbb_auth_provider_oauth_service_google extends phpbb_auth_provider_oauth_service_base +{ + /** + * phpBB config + * + * @var phpbb_config + */ + protected $config; + + /** + * phpBB request + * + * @var phpbb_request + */ + protected $request; + + /** + * Constructor + * + * @param phpbb_config $config + * @param phpbb_request $request + */ + public function __construct(phpbb_config $config, phpbb_request $request) + { + $this->config = $config; + $this->request = $request; + } + + /** + * {@inheritdoc} + */ + public function get_auth_scope() + { + return array( + 'userinfo_email', + 'userinfo_profile', + ); + } + + /** + * {@inheritdoc} + */ + public function get_service_credentials() + { + return array( + 'key' => $this->config['auth_oauth_google_key'], + 'secret' => $this->config['auth_oauth_google_secret'], + ); + } + + /** + * {@inheritdoc} + */ + public function perform_auth_login() + { + if (!($this->service_provider instanceof \OAuth\OAuth2\Service\Google)) + { + throw new phpbb_auth_provider_oauth_service_exception('AUTH_PROVIDER_OAUTH_ERROR_INVALID_SERVICE_TYPE'); + } + + // This was a callback request, get the token + $this->service_provider->requestAccessToken($this->request->variable('code', '')); + + // Send a request with it + $result = json_decode($this->service_provider->request('https://www.googleapis.com/oauth2/v1/userinfo'), true); + + // Return the unique identifier + return $result['id']; + } + + /** + * {@inheritdoc} + */ + public function perform_token_auth() + { + if (!($this->service_provider instanceof \OAuth\OAuth2\Service\Google)) + { + throw new phpbb_auth_provider_oauth_service_exception('AUTH_PROVIDER_OAUTH_ERROR_INVALID_SERVICE_TYPE'); + } + + // Send a request with it + $result = json_decode($this->service_provider->request('https://www.googleapis.com/oauth2/v1/userinfo'), true); + + // Return the unique identifier + return $result['id']; + } +} diff --git a/phpBB/phpbb/auth/provider/oauth/service/interface.php b/phpBB/phpbb/auth/provider/oauth/service/interface.php new file mode 100644 index 0000000000..3bba7c0e2c --- /dev/null +++ b/phpBB/phpbb/auth/provider/oauth/service/interface.php @@ -0,0 +1,77 @@ +<?php +/** +* +* @package auth +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** +* OAuth service interface +* +* @package auth +*/ +interface phpbb_auth_provider_oauth_service_interface +{ + /** + * Returns an array of the scopes necessary for auth + * + * @return array An array of the required scopes + */ + public function get_auth_scope(); + + /** + * Returns the external library service provider once it has been set + * + * @param \OAuth\Common\Service\ServiceInterface|null + */ + public function get_external_service_provider(); + + /** + * Returns an array containing the service credentials belonging to requested + * service. + * + * @return array An array containing the 'key' and the 'secret' of the + * service in the form: + * array( + * 'key' => string + * 'secret' => string + * ) + */ + public function get_service_credentials(); + + /** + * Returns the results of the authentication in json format + * + * @throws phpbb_auth_provider_oauth_service_exception + * @return string The unique identifier returned by the service provider + * that is used to authenticate the user with phpBB. + */ + public function perform_auth_login(); + + /** + * Returns the results of the authentication in json format + * Use this function when the user already has an access token + * + * @throws phpbb_auth_provider_oauth_service_exception + * @return string The unique identifier returned by the service provider + * that is used to authenticate the user with phpBB. + */ + public function perform_token_auth(); + + /** + * Sets the external library service provider + * + * @param \OAuth\Common\Service\ServiceInterface $service + */ + public function set_external_service_provider(\OAuth\Common\Service\ServiceInterface $service_provider); +} diff --git a/phpBB/phpbb/auth/provider/oauth/token_storage.php b/phpBB/phpbb/auth/provider/oauth/token_storage.php new file mode 100644 index 0000000000..d21deb8999 --- /dev/null +++ b/phpBB/phpbb/auth/provider/oauth/token_storage.php @@ -0,0 +1,366 @@ +<?php +/** +* +* @package auth +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + + +use OAuth\OAuth1\Token\StdOAuth1Token; +use OAuth\Common\Token\TokenInterface; +use OAuth\Common\Storage\TokenStorageInterface; +use OAuth\Common\Storage\Exception\StorageException; +use OAuth\Common\Storage\Exception\TokenNotFoundException; + +/** +* OAuth storage wrapper for phpbb's cache +* +* @package auth +*/ +class phpbb_auth_provider_oauth_token_storage implements TokenStorageInterface +{ + /** + * Cache driver. + * + * @var phpbb_db_driver + */ + protected $db; + + /** + * phpBB user + * + * @var phpbb_user + */ + protected $user; + + /** + * OAuth token table + * + * @var string + */ + protected $auth_provider_oauth_table; + + /** + * @var object|TokenInterface + */ + protected $cachedToken; + + /** + * Creates token storage for phpBB. + * + * @param phpbb_db_driver $db + * @param phpbb_user $user + * @param string $auth_provider_oauth_table + */ + public function __construct(phpbb_db_driver $db, phpbb_user $user, $auth_provider_oauth_table) + { + $this->db = $db; + $this->user = $user; + $this->auth_provider_oauth_table = $auth_provider_oauth_table; + } + + /** + * {@inheritdoc} + */ + public function retrieveAccessToken($service) + { + $service = $this->get_service_name_for_db($service); + + if ($this->cachedToken instanceOf TokenInterface) + { + return $this->cachedToken; + } + + $data = array( + 'user_id' => (int) $this->user->data['user_id'], + 'provider' => $service, + ); + + if ((int) $this->user->data['user_id'] === ANONYMOUS) + { + $data['session_id'] = $this->user->data['session_id']; + } + + return $this->_retrieve_access_token($data); + } + + /** + * {@inheritdoc} + */ + public function storeAccessToken($service, TokenInterface $token) + { + $service = $this->get_service_name_for_db($service); + + $this->cachedToken = $token; + + $data = array( + 'user_id' => (int) $this->user->data['user_id'], + 'provider' => $service, + 'oauth_token' => $this->json_encode_token($token), + 'session_id' => $this->user->data['session_id'], + ); + + $sql = 'INSERT INTO ' . $this->auth_provider_oauth_table . ' + ' . $this->db->sql_build_array('INSERT', $data); + $this->db->sql_query($sql); + } + + /** + * {@inheritdoc} + */ + public function hasAccessToken($service) + { + $service = $this->get_service_name_for_db($service); + + if ($this->cachedToken) { + return true; + } + + $data = array( + 'user_id' => (int) $this->user->data['user_id'], + 'provider' => $service, + ); + + if ((int) $this->user->data['user_id'] === ANONYMOUS) + { + $data['session_id'] = $this->user->data['session_id']; + } + + return $this->_has_acess_token($data); + } + + /** + * {@inheritdoc} + */ + public function clearToken($service) + { + $service = $this->get_service_name_for_db($service); + + $this->cachedToken = null; + + $sql = 'DELETE FROM ' . $this->auth_provider_oauth_table . ' + WHERE user_id = ' . (int) $this->user->data['user_id'] . " + AND provider = '" . $this->db->sql_escape($service) . "'"; + + if ((int) $this->user->data['user_id'] === ANONYMOUS) + { + $sql .= " AND session_id = '" . $this->db->sql_escape($this->user->data['session_id']) . "'"; + } + + $this->db->sql_query($sql); + } + + /** + * {@inheritdoc} + */ + public function clearAllTokens() + { + $this->cachedToken = null; + + $sql = 'DELETE FROM ' . $this->auth_provider_oauth_table . ' + WHERE user_id = ' . (int) $this->user->data['user_id']; + + if ((int) $this->user->data['user_id'] === ANONYMOUS) + { + $sql .= " AND session_id = '" . $this->db->sql_escape($this->user->data['session_id']) . "'"; + } + + $this->db->sql_query($sql); + } + + /** + * Updates the user_id field in the database assosciated with the token + * + * @param int $user_id + */ + public function set_user_id($user_id) + { + if (!$this->cachedToken) + { + return; + } + + $sql = 'UPDATE ' . $this->auth_provider_oauth_table . ' + SET ' . $this->db->sql_build_array('UPDATE', array( + 'user_id' => (int) $user_id + )) . ' + WHERE user_id = ' . (int) $this->user->data['user_id'] . " + AND session_id = '" . $this->db->sql_escape($this->user->data['session_id']) . "'"; + $this->db->sql_query($sql); + } + + /** + * Checks to see if an access token exists solely by the session_id of the user + * + * @return bool true if they have token, false if they don't + */ + public function has_access_token_by_session($service) + { + $service = $this->get_service_name_for_db($service); + + if ($this->cachedToken) + { + return true; + } + + $data = array( + 'session_id' => $this->user->data['session_id'], + 'provider' => $service, + ); + + return $this->_has_acess_token($data); + } + + /** + * A helper function that performs the query for has access token functions + * + * @param array $data + * @return bool + */ + protected function _has_acess_token($data) + { + return (bool) $this->get_access_token_row($data); + } + + public function retrieve_access_token_by_session($service) + { + $service = $this->get_service_name_for_db($service); + + if ($this->cachedToken instanceOf TokenInterface) { + return $this->cachedToken; + } + + $data = array( + 'session_id' => $this->user->data['session_id'], + 'provider' => $service, + ); + + return $this->_retrieve_access_token($data); + } + + /** + * A helper function that performs the query for retrieve access token functions + * Also checks if the token is a valid token + * + * @param array $data + * @return mixed + */ + protected function _retrieve_access_token($data) + { + $row = $this->get_access_token_row($data); + + if (!$row) + { + throw new TokenNotFoundException('AUTH_PROVIDER_OAUTH_TOKEN_ERROR_NOT_STORED'); + } + + $token = $this->json_decode_token($row['oauth_token']); + + // Ensure that the token was serialized/unserialized correctly + if (!($token instanceof TokenInterface)) + { + $this->clearToken(); + throw new TokenNotFoundException('AUTH_PROVIDER_OAUTH_TOKEN_ERROR_INCORRECTLY_STORED'); + } + + $this->cachedToken = $token; + return $token; + } + + /** + * A helper function that performs the query for retrieving an access token + * + * @param array $data + * @return mixed + */ + protected function get_access_token_row($data) + { + $sql = 'SELECT oauth_token FROM ' . $this->auth_provider_oauth_table . ' + WHERE ' . $this->db->sql_build_array('SELECT', $data); + $result = $this->db->sql_query($sql); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + return $row; + } + + public function json_encode_token(TokenInterface $token) + { + $members = array( + 'accessToken' => $token->getAccessToken(), + 'endOfLife' => $token->getEndOfLife(), + 'extraParams' => $token->getExtraParams(), + 'refreshToken' => $token->getRefreshToken(), + + 'token_class' => get_class($token), + ); + + // Handle additional data needed for OAuth1 tokens + if ($token instanceof StdOAuth1Token) + { + $members['requestToken'] = $token->getRequestToken(); + $members['requestTokenSecret'] = $token->getRequestTokenSecret(); + $members['accessTokenSecret'] = $token->getAccessTokenSecret(); + } + + return json_encode($members); + } + + public function json_decode_token($json) + { + $token_data = json_decode($json, true); + + if ($token_data === null) + { + throw new TokenNotFoundException('AUTH_PROVIDER_OAUTH_TOKEN_ERROR_INCORRECTLY_STORED'); + } + + $token_class = $token_data['token_class']; + $access_token = $token_data['accessToken']; + $refresh_token = $token_data['refreshToken']; + $endOfLife = $token_data['endOfLife']; + $extra_params = $token_data['extraParams']; + + // Create the token + $token = new $token_class($access_token, $refresh_token, TokenInterface::EOL_NEVER_EXPIRES, $extra_params); + $token->setEndOfLife($endOfLife); + + // Handle OAuth 1.0 specific elements + if ($token instanceof StdOAuth1Token) + { + $token->setRequestToken($token_data['requestToken']); + $token->setRequestTokenSecret($token_data['requestTokenSecret']); + $token->setAccessTokenSecret($token_data['accessTokenSecret']); + } + + return $token; + } + + /** + * Returns the name of the service as it must be stored in the database. + * + * @param string $service The name of the OAuth service + * @return string The name of the OAuth service as it needs to be stored + * in the database. + */ + protected function get_service_name_for_db($service) + { + // Enforce the naming convention for oauth services + if (strpos($service, 'auth.provider.oauth.service.') !== 0) + { + $service = 'auth.provider.oauth.service.' . strtolower($service); + } + + return $service; + } +} diff --git a/phpBB/phpbb/cache/driver/file.php b/phpBB/phpbb/cache/driver/file.php index 85decbe3e8..944dfd6541 100644 --- a/phpBB/phpbb/cache/driver/file.php +++ b/phpBB/phpbb/cache/driver/file.php @@ -205,28 +205,34 @@ class phpbb_cache_driver_file extends phpbb_cache_driver_base function purge() { // Purge all phpbb cache files - $dir = @opendir($this->cache_dir); - - if (!$dir) + try + { + $iterator = new DirectoryIterator($this->cache_dir); + } + catch (Exception $e) { return; } - while (($entry = readdir($dir)) !== false) + foreach ($iterator as $fileInfo) { - if (strpos($entry, 'container_') !== 0 && - strpos($entry, 'url_matcher') !== 0 && - strpos($entry, 'sql_') !== 0 && - strpos($entry, 'data_') !== 0 && - strpos($entry, 'ctpl_') !== 0 && - strpos($entry, 'tpl_') !== 0) + if ($fileInfo->isDot()) { continue; } - - $this->remove_file($this->cache_dir . $entry); + $filename = $fileInfo->getFilename(); + if ($fileInfo->isDir()) + { + $this->remove_dir($fileInfo->getPathname()); + } + elseif (strpos($filename, 'container_') === 0 || + strpos($filename, 'url_matcher') === 0 || + strpos($filename, 'sql_') === 0 || + strpos($filename, 'data_') === 0) + { + $this->remove_file($fileInfo->getPathname()); + } } - closedir($dir); unset($this->vars); unset($this->var_expires); @@ -242,6 +248,44 @@ class phpbb_cache_driver_file extends phpbb_cache_driver_base } /** + * Remove directory + * + * @param string $dir Directory to remove + * + * @return null + */ + protected function remove_dir($dir) + { + try + { + $iterator = new DirectoryIterator($dir); + } + catch (Exception $e) + { + return; + } + + foreach ($iterator as $fileInfo) + { + if ($fileInfo->isDot()) + { + continue; + } + + if ($fileInfo->isDir()) + { + $this->remove_dir($fileInfo->getPathname()); + } + else + { + $this->remove_file($fileInfo->getPathname()); + } + } + + @rmdir($dir); + } + + /** * Destroy cache data */ function destroy($var_name, $table = '') diff --git a/phpBB/phpbb/content_visibility.php b/phpBB/phpbb/content_visibility.php index 4ad5f6793e..fb8ece0e8c 100644 --- a/phpBB/phpbb/content_visibility.php +++ b/phpBB/phpbb/content_visibility.php @@ -360,6 +360,11 @@ class phpbb_content_visibility // Sync the first/last topic information if needed if (!$is_starter && $is_latest) { + if (!function_exists('update_post_information')) + { + include($this->phpbb_root_path . 'includes/functions_posting.' . $this->php_ext); + } + // update_post_information can only update the last post info ... if ($topic_id) { diff --git a/phpBB/phpbb/controller/helper.php b/phpBB/phpbb/controller/helper.php index 74410ddfd1..4d240f9380 100644 --- a/phpBB/phpbb/controller/helper.php +++ b/phpBB/phpbb/controller/helper.php @@ -36,6 +36,12 @@ class phpbb_controller_helper protected $user; /** + * Request object + * @var phpbb_request + */ + protected $request; + + /** * phpBB root path * @var string */ @@ -55,10 +61,11 @@ class phpbb_controller_helper * @param string $phpbb_root_path phpBB root path * @param string $php_ext PHP extension */ - public function __construct(phpbb_template $template, phpbb_user $user, $phpbb_root_path, $php_ext) + public function __construct(phpbb_template $template, phpbb_user $user, phpbb_request_interface $request, $phpbb_root_path, $php_ext) { $this->template = $template; $this->user = $user; + $this->request = $request; $this->phpbb_root_path = $phpbb_root_path; $this->php_ext = $php_ext; } @@ -102,22 +109,16 @@ class phpbb_controller_helper $route = substr($route, 0, $route_delim); } - if (is_array($params) && !empty($params)) - { - $params = array_merge(array( - 'controller' => $route, - ), $params); - } - else if (is_string($params) && $params) - { - $params = 'controller=' . $route . (($is_amp) ? '&' : '&') . $params; - } - else - { - $params = array('controller' => $route); - } + $request_uri = $this->request->variable('REQUEST_URI', '', false, phpbb_request::SERVER); + $script_name = $this->request->variable('SCRIPT_NAME', '', false, phpbb_request::SERVER); + + // If the app.php file is being used (no rewrite) keep it in the URL. + // Otherwise, don't include it. + $route_prefix = $this->phpbb_root_path; + $parts = explode('/', $script_name); + $route_prefix .= strpos($request_uri, $script_name) === 0 ? array_pop($parts) . '/' : ''; - return append_sid($this->phpbb_root_path . 'app.' . $this->php_ext . $route_params, $params, $is_amp, $session_id); + return append_sid($route_prefix . "$route" . $route_params, $params, $is_amp, $session_id); } /** diff --git a/phpBB/phpbb/controller/resolver.php b/phpBB/phpbb/controller/resolver.php index 95dfc8da8e..d772507261 100644 --- a/phpBB/phpbb/controller/resolver.php +++ b/phpBB/phpbb/controller/resolver.php @@ -38,23 +38,23 @@ class phpbb_controller_resolver implements ControllerResolverInterface protected $container; /** - * phpbb_style object - * @var phpbb_style + * phpbb_template object + * @var phpbb_template */ - protected $style; + protected $template; /** * Construct method * * @param phpbb_user $user User Object * @param ContainerInterface $container ContainerInterface object - * @param phpbb_style $style + * @param phpbb_template $template */ - public function __construct(phpbb_user $user, ContainerInterface $container, phpbb_style $style = null) + public function __construct(phpbb_user $user, ContainerInterface $container, phpbb_template $template = null) { $this->user = $user; $this->container = $container; - $this->style = $style; + $this->template = $template; } /** @@ -96,13 +96,13 @@ class phpbb_controller_resolver implements ControllerResolverInterface $controller_dir = explode('_', get_class($controller_object)); // 0 phpbb, 1 ext, 2 vendor, 3 extension name, ... - if (!is_null($this->style) && isset($controller_dir[3]) && $controller_dir[1] === 'ext') + if (!is_null($this->template) && isset($controller_dir[3]) && $controller_dir[1] === 'ext') { $controller_style_dir = 'ext/' . $controller_dir[2] . '/' . $controller_dir[3] . '/styles'; if (is_dir($controller_style_dir)) { - $this->style->set_style(array($controller_style_dir, 'styles')); + $this->template->set_style(array($controller_style_dir, 'styles')); } } diff --git a/phpBB/phpbb/db/migration/data/30x/3_0_1.php b/phpBB/phpbb/db/migration/data/30x/3_0_1.php index c996a0138a..c5b1681d96 100644 --- a/phpBB/phpbb/db/migration/data/30x/3_0_1.php +++ b/phpBB/phpbb/db/migration/data/30x/3_0_1.php @@ -11,7 +11,7 @@ class phpbb_db_migration_data_30x_3_0_1 extends phpbb_db_migration { public function effectively_installed() { - return version_compare($this->config['version'], '3.0.1', '>='); + return phpbb_version_compare($this->config['version'], '3.0.1', '>='); } static public function depends_on() diff --git a/phpBB/phpbb/db/migration/data/30x/3_0_10.php b/phpBB/phpbb/db/migration/data/30x/3_0_10.php index 122f93d6b4..640fcbc16f 100644 --- a/phpBB/phpbb/db/migration/data/30x/3_0_10.php +++ b/phpBB/phpbb/db/migration/data/30x/3_0_10.php @@ -11,7 +11,7 @@ class phpbb_db_migration_data_30x_3_0_10 extends phpbb_db_migration { public function effectively_installed() { - return version_compare($this->config['version'], '3.0.10', '>='); + return phpbb_version_compare($this->config['version'], '3.0.10', '>='); } static public function depends_on() diff --git a/phpBB/phpbb/db/migration/data/30x/3_0_10_rc1.php b/phpBB/phpbb/db/migration/data/30x/3_0_10_rc1.php index 0ed05812dc..e0aca09c3a 100644 --- a/phpBB/phpbb/db/migration/data/30x/3_0_10_rc1.php +++ b/phpBB/phpbb/db/migration/data/30x/3_0_10_rc1.php @@ -11,7 +11,7 @@ class phpbb_db_migration_data_30x_3_0_10_rc1 extends phpbb_db_migration { public function effectively_installed() { - return version_compare($this->config['version'], '3.0.10-rc1', '>='); + return phpbb_version_compare($this->config['version'], '3.0.10-RC1', '>='); } static public function depends_on() @@ -24,7 +24,7 @@ class phpbb_db_migration_data_30x_3_0_10_rc1 extends phpbb_db_migration return array( array('config.add', array('email_max_chunk_size', 50)), - array('config.update', array('version', '3.0.10-rc1')), + array('config.update', array('version', '3.0.10-RC1')), ); } } diff --git a/phpBB/phpbb/db/migration/data/30x/3_0_10_rc2.php b/phpBB/phpbb/db/migration/data/30x/3_0_10_rc2.php index b14b3b00aa..394e030acf 100644 --- a/phpBB/phpbb/db/migration/data/30x/3_0_10_rc2.php +++ b/phpBB/phpbb/db/migration/data/30x/3_0_10_rc2.php @@ -11,7 +11,7 @@ class phpbb_db_migration_data_30x_3_0_10_rc2 extends phpbb_db_migration { public function effectively_installed() { - return version_compare($this->config['version'], '3.0.10-rc2', '>='); + return phpbb_version_compare($this->config['version'], '3.0.10-RC2', '>='); } static public function depends_on() @@ -22,7 +22,7 @@ class phpbb_db_migration_data_30x_3_0_10_rc2 extends phpbb_db_migration public function update_data() { return array( - array('config.update', array('version', '3.0.10-rc2')), + array('config.update', array('version', '3.0.10-RC2')), ); } } diff --git a/phpBB/phpbb/db/migration/data/30x/3_0_10_rc3.php b/phpBB/phpbb/db/migration/data/30x/3_0_10_rc3.php index 473057d65d..92900e3aed 100644 --- a/phpBB/phpbb/db/migration/data/30x/3_0_10_rc3.php +++ b/phpBB/phpbb/db/migration/data/30x/3_0_10_rc3.php @@ -11,7 +11,7 @@ class phpbb_db_migration_data_30x_3_0_10_rc3 extends phpbb_db_migration { public function effectively_installed() { - return version_compare($this->config['version'], '3.0.10-rc3', '>='); + return phpbb_version_compare($this->config['version'], '3.0.10-RC3', '>='); } static public function depends_on() @@ -22,7 +22,7 @@ class phpbb_db_migration_data_30x_3_0_10_rc3 extends phpbb_db_migration public function update_data() { return array( - array('config.update', array('version', '3.0.10-rc3')), + array('config.update', array('version', '3.0.10-RC3')), ); } } diff --git a/phpBB/phpbb/db/migration/data/30x/3_0_11.php b/phpBB/phpbb/db/migration/data/30x/3_0_11.php index e063c699cc..3be03cec40 100644 --- a/phpBB/phpbb/db/migration/data/30x/3_0_11.php +++ b/phpBB/phpbb/db/migration/data/30x/3_0_11.php @@ -11,7 +11,7 @@ class phpbb_db_migration_data_30x_3_0_11 extends phpbb_db_migration { public function effectively_installed() { - return version_compare($this->config['version'], '3.0.11', '>='); + return phpbb_version_compare($this->config['version'], '3.0.11', '>='); } static public function depends_on() diff --git a/phpBB/phpbb/db/migration/data/30x/3_0_11_rc1.php b/phpBB/phpbb/db/migration/data/30x/3_0_11_rc1.php index dddfc0e0e7..f7b0247fdb 100644 --- a/phpBB/phpbb/db/migration/data/30x/3_0_11_rc1.php +++ b/phpBB/phpbb/db/migration/data/30x/3_0_11_rc1.php @@ -11,7 +11,7 @@ class phpbb_db_migration_data_30x_3_0_11_rc1 extends phpbb_db_migration { public function effectively_installed() { - return version_compare($this->config['version'], '3.0.11-rc1', '>='); + return phpbb_version_compare($this->config['version'], '3.0.11-RC1', '>='); } static public function depends_on() @@ -25,7 +25,7 @@ class phpbb_db_migration_data_30x_3_0_11_rc1 extends phpbb_db_migration array('custom', array(array(&$this, 'cleanup_deactivated_styles'))), array('custom', array(array(&$this, 'delete_orphan_private_messages'))), - array('config.update', array('version', '3.0.11-rc1')), + array('config.update', array('version', '3.0.11-RC1')), ); } diff --git a/phpBB/phpbb/db/migration/data/30x/3_0_11_rc2.php b/phpBB/phpbb/db/migration/data/30x/3_0_11_rc2.php index fac8523e8c..204aa314ac 100644 --- a/phpBB/phpbb/db/migration/data/30x/3_0_11_rc2.php +++ b/phpBB/phpbb/db/migration/data/30x/3_0_11_rc2.php @@ -11,7 +11,7 @@ class phpbb_db_migration_data_30x_3_0_11_rc2 extends phpbb_db_migration { public function effectively_installed() { - return version_compare($this->config['version'], '3.0.11-rc2', '>='); + return phpbb_version_compare($this->config['version'], '3.0.11-RC2', '>='); } static public function depends_on() @@ -44,7 +44,7 @@ class phpbb_db_migration_data_30x_3_0_11_rc2 extends phpbb_db_migration public function update_data() { return array( - array('config.update', array('version', '3.0.11-rc2')), + array('config.update', array('version', '3.0.11-RC2')), ); } } diff --git a/phpBB/phpbb/db/migration/data/30x/3_0_12_rc1.php b/phpBB/phpbb/db/migration/data/30x/3_0_12_rc1.php index 6a31a51201..31d37afa48 100644 --- a/phpBB/phpbb/db/migration/data/30x/3_0_12_rc1.php +++ b/phpBB/phpbb/db/migration/data/30x/3_0_12_rc1.php @@ -13,7 +13,7 @@ class phpbb_db_migration_data_30x_3_0_12_rc1 extends phpbb_db_migration { public function effectively_installed() { - return version_compare($this->config['version'], '3.0.12-rc1', '>='); + return phpbb_version_compare($this->config['version'], '3.0.12-RC1', '>='); } static public function depends_on() @@ -28,7 +28,7 @@ class phpbb_db_migration_data_30x_3_0_12_rc1 extends phpbb_db_migration array('custom', array(array(&$this, 'update_bots'))), array('custom', array(array(&$this, 'disable_bots_from_receiving_pms'))), - array('config.update', array('version', '3.0.12-rc1')), + array('config.update', array('version', '3.0.12-RC1')), ); } @@ -108,7 +108,7 @@ class phpbb_db_migration_data_30x_3_0_12_rc1 extends phpbb_db_migration WHERE user_id = $bot_user_id"; $this->sql_query($sql); - user_delete('remove', $bot_user_id); + user_delete('retain', $bot_user_id); } else { diff --git a/phpBB/phpbb/db/migration/data/30x/3_0_1_rc1.php b/phpBB/phpbb/db/migration/data/30x/3_0_1_rc1.php index 562ccf077c..984b8fb37e 100644 --- a/phpBB/phpbb/db/migration/data/30x/3_0_1_rc1.php +++ b/phpBB/phpbb/db/migration/data/30x/3_0_1_rc1.php @@ -11,7 +11,7 @@ class phpbb_db_migration_data_30x_3_0_1_rc1 extends phpbb_db_migration { public function effectively_installed() { - return version_compare($this->config['version'], '3.0.1-rc1', '>='); + return phpbb_version_compare($this->config['version'], '3.0.1-RC1', '>='); } public function update_schema() @@ -74,7 +74,7 @@ class phpbb_db_migration_data_30x_3_0_1_rc1 extends phpbb_db_migration array('custom', array(array(&$this, 'fix_unset_last_view_time'))), array('custom', array(array(&$this, 'reset_smiley_size'))), - array('config.update', array('version', '3.0.1-rc1')), + array('config.update', array('version', '3.0.1-RC1')), ); } diff --git a/phpBB/phpbb/db/migration/data/30x/3_0_2.php b/phpBB/phpbb/db/migration/data/30x/3_0_2.php index eed5acef82..6e11e5a145 100644 --- a/phpBB/phpbb/db/migration/data/30x/3_0_2.php +++ b/phpBB/phpbb/db/migration/data/30x/3_0_2.php @@ -11,7 +11,7 @@ class phpbb_db_migration_data_30x_3_0_2 extends phpbb_db_migration { public function effectively_installed() { - return version_compare($this->config['version'], '3.0.2', '>='); + return phpbb_version_compare($this->config['version'], '3.0.2', '>='); } static public function depends_on() diff --git a/phpBB/phpbb/db/migration/data/30x/3_0_2_rc1.php b/phpBB/phpbb/db/migration/data/30x/3_0_2_rc1.php index a960e90765..9a25628f25 100644 --- a/phpBB/phpbb/db/migration/data/30x/3_0_2_rc1.php +++ b/phpBB/phpbb/db/migration/data/30x/3_0_2_rc1.php @@ -11,7 +11,7 @@ class phpbb_db_migration_data_30x_3_0_2_rc1 extends phpbb_db_migration { public function effectively_installed() { - return version_compare($this->config['version'], '3.0.2-rc1', '>='); + return phpbb_version_compare($this->config['version'], '3.0.2-RC1', '>='); } static public function depends_on() @@ -26,7 +26,7 @@ class phpbb_db_migration_data_30x_3_0_2_rc1 extends phpbb_db_migration array('config.add', array('check_attachment_content', '1')), array('config.add', array('mime_triggers', 'body|head|html|img|plaintext|a href|pre|script|table|title')), - array('config.update', array('version', '3.0.2-rc1')), + array('config.update', array('version', '3.0.2-RC1')), ); } } diff --git a/phpBB/phpbb/db/migration/data/30x/3_0_2_rc2.php b/phpBB/phpbb/db/migration/data/30x/3_0_2_rc2.php index 8917dfea77..6c37d6701b 100644 --- a/phpBB/phpbb/db/migration/data/30x/3_0_2_rc2.php +++ b/phpBB/phpbb/db/migration/data/30x/3_0_2_rc2.php @@ -11,7 +11,7 @@ class phpbb_db_migration_data_30x_3_0_2_rc2 extends phpbb_db_migration { public function effectively_installed() { - return version_compare($this->config['version'], '3.0.2-rc2', '>='); + return phpbb_version_compare($this->config['version'], '3.0.2-RC2', '>='); } static public function depends_on() @@ -74,7 +74,7 @@ class phpbb_db_migration_data_30x_3_0_2_rc2 extends phpbb_db_migration public function update_data() { return array( - array('config.update', array('version', '3.0.2-rc2')), + array('config.update', array('version', '3.0.2-RC2')), ); } } diff --git a/phpBB/phpbb/db/migration/data/30x/3_0_3.php b/phpBB/phpbb/db/migration/data/30x/3_0_3.php index 8984cf7b76..11fd2a2e80 100644 --- a/phpBB/phpbb/db/migration/data/30x/3_0_3.php +++ b/phpBB/phpbb/db/migration/data/30x/3_0_3.php @@ -11,7 +11,7 @@ class phpbb_db_migration_data_30x_3_0_3 extends phpbb_db_migration { public function effectively_installed() { - return version_compare($this->config['version'], '3.0.3', '>='); + return phpbb_version_compare($this->config['version'], '3.0.3', '>='); } static public function depends_on() diff --git a/phpBB/phpbb/db/migration/data/30x/3_0_3_rc1.php b/phpBB/phpbb/db/migration/data/30x/3_0_3_rc1.php index 4b102e1a2e..cbeb00499a 100644 --- a/phpBB/phpbb/db/migration/data/30x/3_0_3_rc1.php +++ b/phpBB/phpbb/db/migration/data/30x/3_0_3_rc1.php @@ -11,7 +11,7 @@ class phpbb_db_migration_data_30x_3_0_3_rc1 extends phpbb_db_migration { public function effectively_installed() { - return version_compare($this->config['version'], '3.0.3-rc1', '>='); + return phpbb_version_compare($this->config['version'], '3.0.3-RC1', '>='); } static public function depends_on() @@ -60,7 +60,7 @@ class phpbb_db_migration_data_30x_3_0_3_rc1 extends phpbb_db_migration array('permission.add', array('u_masspm_group', true, 'u_masspm')), array('custom', array(array(&$this, 'correct_acp_email_permissions'))), - array('config.update', array('version', '3.0.3-rc1')), + array('config.update', array('version', '3.0.3-RC1')), ); } diff --git a/phpBB/phpbb/db/migration/data/30x/3_0_4.php b/phpBB/phpbb/db/migration/data/30x/3_0_4.php index 9a0c132e78..4375a96dac 100644 --- a/phpBB/phpbb/db/migration/data/30x/3_0_4.php +++ b/phpBB/phpbb/db/migration/data/30x/3_0_4.php @@ -11,7 +11,7 @@ class phpbb_db_migration_data_30x_3_0_4 extends phpbb_db_migration { public function effectively_installed() { - return version_compare($this->config['version'], '3.0.4', '>='); + return phpbb_version_compare($this->config['version'], '3.0.4', '>='); } static public function depends_on() diff --git a/phpBB/phpbb/db/migration/data/30x/3_0_4_rc1.php b/phpBB/phpbb/db/migration/data/30x/3_0_4_rc1.php index 8ad75a557b..73334dcc6f 100644 --- a/phpBB/phpbb/db/migration/data/30x/3_0_4_rc1.php +++ b/phpBB/phpbb/db/migration/data/30x/3_0_4_rc1.php @@ -11,7 +11,7 @@ class phpbb_db_migration_data_30x_3_0_4_rc1 extends phpbb_db_migration { public function effectively_installed() { - return version_compare($this->config['version'], '3.0.4-rc1', '>='); + return phpbb_version_compare($this->config['version'], '3.0.4-RC1', '>='); } static public function depends_on() @@ -76,7 +76,7 @@ class phpbb_db_migration_data_30x_3_0_4_rc1 extends phpbb_db_migration return array( array('custom', array(array(&$this, 'update_custom_profile_fields'))), - array('config.update', array('version', '3.0.4-rc1')), + array('config.update', array('version', '3.0.4-RC1')), ); } diff --git a/phpBB/phpbb/db/migration/data/30x/3_0_5.php b/phpBB/phpbb/db/migration/data/30x/3_0_5.php index 16d2dee457..2700274f35 100644 --- a/phpBB/phpbb/db/migration/data/30x/3_0_5.php +++ b/phpBB/phpbb/db/migration/data/30x/3_0_5.php @@ -11,7 +11,7 @@ class phpbb_db_migration_data_30x_3_0_5 extends phpbb_db_migration { public function effectively_installed() { - return version_compare($this->config['version'], '3.0.5', '>='); + return phpbb_version_compare($this->config['version'], '3.0.5', '>='); } static public function depends_on() diff --git a/phpBB/phpbb/db/migration/data/30x/3_0_5_rc1.php b/phpBB/phpbb/db/migration/data/30x/3_0_5_rc1.php index ea17cc1e31..90c6b3b46a 100644 --- a/phpBB/phpbb/db/migration/data/30x/3_0_5_rc1.php +++ b/phpBB/phpbb/db/migration/data/30x/3_0_5_rc1.php @@ -11,7 +11,7 @@ class phpbb_db_migration_data_30x_3_0_5_rc1 extends phpbb_db_migration { public function effectively_installed() { - return version_compare($this->config['version'], '3.0.5-rc1', '>='); + return phpbb_version_compare($this->config['version'], '3.0.5-RC1', '>='); } static public function depends_on() diff --git a/phpBB/phpbb/db/migration/data/30x/3_0_5_rc1part2.php b/phpBB/phpbb/db/migration/data/30x/3_0_5_rc1part2.php index 8538347b1a..2d1e5cfed8 100644 --- a/phpBB/phpbb/db/migration/data/30x/3_0_5_rc1part2.php +++ b/phpBB/phpbb/db/migration/data/30x/3_0_5_rc1part2.php @@ -11,7 +11,7 @@ class phpbb_db_migration_data_30x_3_0_5_rc1part2 extends phpbb_db_migration { public function effectively_installed() { - return version_compare($this->config['version'], '3.0.5-rc1', '>='); + return phpbb_version_compare($this->config['version'], '3.0.5-RC1', '>='); } static public function depends_on() @@ -36,7 +36,7 @@ class phpbb_db_migration_data_30x_3_0_5_rc1part2 extends phpbb_db_migration public function update_data() { return array( - array('config.update', array('version', '3.0.5-rc1')), + array('config.update', array('version', '3.0.5-RC1')), ); } } diff --git a/phpBB/phpbb/db/migration/data/30x/3_0_6.php b/phpBB/phpbb/db/migration/data/30x/3_0_6.php index bb651dc7cd..1877b0c5a1 100644 --- a/phpBB/phpbb/db/migration/data/30x/3_0_6.php +++ b/phpBB/phpbb/db/migration/data/30x/3_0_6.php @@ -11,7 +11,7 @@ class phpbb_db_migration_data_30x_3_0_6 extends phpbb_db_migration { public function effectively_installed() { - return version_compare($this->config['version'], '3.0.6', '>='); + return phpbb_version_compare($this->config['version'], '3.0.6', '>='); } static public function depends_on() diff --git a/phpBB/phpbb/db/migration/data/30x/3_0_6_rc1.php b/phpBB/phpbb/db/migration/data/30x/3_0_6_rc1.php index 38c282ebf0..3e2a9544c7 100644 --- a/phpBB/phpbb/db/migration/data/30x/3_0_6_rc1.php +++ b/phpBB/phpbb/db/migration/data/30x/3_0_6_rc1.php @@ -11,7 +11,7 @@ class phpbb_db_migration_data_30x_3_0_6_rc1 extends phpbb_db_migration { public function effectively_installed() { - return version_compare($this->config['version'], '3.0.6-rc1', '>='); + return phpbb_version_compare($this->config['version'], '3.0.6-RC1', '>='); } static public function depends_on() @@ -185,7 +185,7 @@ class phpbb_db_migration_data_30x_3_0_6_rc1 extends phpbb_db_migration array('custom', array(array(&$this, 'add_newly_registered_group'))), array('custom', array(array(&$this, 'set_user_options_default'))), - array('config.update', array('version', '3.0.6-rc1')), + array('config.update', array('version', '3.0.6-RC1')), ); } diff --git a/phpBB/phpbb/db/migration/data/30x/3_0_6_rc2.php b/phpBB/phpbb/db/migration/data/30x/3_0_6_rc2.php index a939dbd489..439e25b100 100644 --- a/phpBB/phpbb/db/migration/data/30x/3_0_6_rc2.php +++ b/phpBB/phpbb/db/migration/data/30x/3_0_6_rc2.php @@ -11,7 +11,7 @@ class phpbb_db_migration_data_30x_3_0_6_rc2 extends phpbb_db_migration { public function effectively_installed() { - return version_compare($this->config['version'], '3.0.6-rc2', '>='); + return phpbb_version_compare($this->config['version'], '3.0.6-RC2', '>='); } static public function depends_on() @@ -22,7 +22,7 @@ class phpbb_db_migration_data_30x_3_0_6_rc2 extends phpbb_db_migration public function update_data() { return array( - array('config.update', array('version', '3.0.6-rc2')), + array('config.update', array('version', '3.0.6-RC2')), ); } } diff --git a/phpBB/phpbb/db/migration/data/30x/3_0_6_rc3.php b/phpBB/phpbb/db/migration/data/30x/3_0_6_rc3.php index b3f09d8ab8..77b62d7fc7 100644 --- a/phpBB/phpbb/db/migration/data/30x/3_0_6_rc3.php +++ b/phpBB/phpbb/db/migration/data/30x/3_0_6_rc3.php @@ -11,7 +11,7 @@ class phpbb_db_migration_data_30x_3_0_6_rc3 extends phpbb_db_migration { public function effectively_installed() { - return version_compare($this->config['version'], '3.0.6-rc3', '>='); + return phpbb_version_compare($this->config['version'], '3.0.6-RC3', '>='); } static public function depends_on() @@ -24,7 +24,7 @@ class phpbb_db_migration_data_30x_3_0_6_rc3 extends phpbb_db_migration return array( array('custom', array(array(&$this, 'update_cp_fields'))), - array('config.update', array('version', '3.0.6-rc3')), + array('config.update', array('version', '3.0.6-RC3')), ); } diff --git a/phpBB/phpbb/db/migration/data/30x/3_0_6_rc4.php b/phpBB/phpbb/db/migration/data/30x/3_0_6_rc4.php index fc2923f99b..61a31d09e6 100644 --- a/phpBB/phpbb/db/migration/data/30x/3_0_6_rc4.php +++ b/phpBB/phpbb/db/migration/data/30x/3_0_6_rc4.php @@ -11,7 +11,7 @@ class phpbb_db_migration_data_30x_3_0_6_rc4 extends phpbb_db_migration { public function effectively_installed() { - return version_compare($this->config['version'], '3.0.6-rc4', '>='); + return phpbb_version_compare($this->config['version'], '3.0.6-RC4', '>='); } static public function depends_on() @@ -22,7 +22,7 @@ class phpbb_db_migration_data_30x_3_0_6_rc4 extends phpbb_db_migration public function update_data() { return array( - array('config.update', array('version', '3.0.6-rc4')), + array('config.update', array('version', '3.0.6-RC4')), ); } } diff --git a/phpBB/phpbb/db/migration/data/30x/3_0_7.php b/phpBB/phpbb/db/migration/data/30x/3_0_7.php index 9ff2e9e4ab..3eb1caddbc 100644 --- a/phpBB/phpbb/db/migration/data/30x/3_0_7.php +++ b/phpBB/phpbb/db/migration/data/30x/3_0_7.php @@ -11,7 +11,7 @@ class phpbb_db_migration_data_30x_3_0_7 extends phpbb_db_migration { public function effectively_installed() { - return version_compare($this->config['version'], '3.0.7', '>='); + return phpbb_version_compare($this->config['version'], '3.0.7', '>='); } static public function depends_on() diff --git a/phpBB/phpbb/db/migration/data/30x/3_0_7_pl1.php b/phpBB/phpbb/db/migration/data/30x/3_0_7_pl1.php index c9cc9d19ac..c7b5c584ac 100644 --- a/phpBB/phpbb/db/migration/data/30x/3_0_7_pl1.php +++ b/phpBB/phpbb/db/migration/data/30x/3_0_7_pl1.php @@ -11,7 +11,7 @@ class phpbb_db_migration_data_30x_3_0_7_pl1 extends phpbb_db_migration { public function effectively_installed() { - return version_compare($this->config['version'], '3.0.7-pl1', '>='); + return phpbb_version_compare($this->config['version'], '3.0.7-pl1', '>='); } static public function depends_on() diff --git a/phpBB/phpbb/db/migration/data/30x/3_0_7_rc1.php b/phpBB/phpbb/db/migration/data/30x/3_0_7_rc1.php index ffebf66f2d..e0fd313834 100644 --- a/phpBB/phpbb/db/migration/data/30x/3_0_7_rc1.php +++ b/phpBB/phpbb/db/migration/data/30x/3_0_7_rc1.php @@ -11,7 +11,7 @@ class phpbb_db_migration_data_30x_3_0_7_rc1 extends phpbb_db_migration { public function effectively_installed() { - return version_compare($this->config['version'], '3.0.7-rc1', '>='); + return phpbb_version_compare($this->config['version'], '3.0.7-RC1', '>='); } static public function depends_on() @@ -62,7 +62,7 @@ class phpbb_db_migration_data_30x_3_0_7_rc1 extends phpbb_db_migration array('config.add', array('feed_topics_active', $this->config['feed_overall_topics'])), array('custom', array(array(&$this, 'delete_text_templates'))), - array('config.update', array('version', '3.0.7-rc1')), + array('config.update', array('version', '3.0.7-RC1')), ); } diff --git a/phpBB/phpbb/db/migration/data/30x/3_0_7_rc2.php b/phpBB/phpbb/db/migration/data/30x/3_0_7_rc2.php index 55bc2bc679..f4f3327385 100644 --- a/phpBB/phpbb/db/migration/data/30x/3_0_7_rc2.php +++ b/phpBB/phpbb/db/migration/data/30x/3_0_7_rc2.php @@ -11,7 +11,7 @@ class phpbb_db_migration_data_30x_3_0_7_rc2 extends phpbb_db_migration { public function effectively_installed() { - return version_compare($this->config['version'], '3.0.7-rc2', '>='); + return phpbb_version_compare($this->config['version'], '3.0.7-RC2', '>='); } static public function depends_on() @@ -24,7 +24,7 @@ class phpbb_db_migration_data_30x_3_0_7_rc2 extends phpbb_db_migration return array( array('custom', array(array(&$this, 'update_email_hash'))), - array('config.update', array('version', '3.0.7-rc2')), + array('config.update', array('version', '3.0.7-RC2')), ); } diff --git a/phpBB/phpbb/db/migration/data/30x/3_0_8.php b/phpBB/phpbb/db/migration/data/30x/3_0_8.php index 8998ef9627..77771a9acd 100644 --- a/phpBB/phpbb/db/migration/data/30x/3_0_8.php +++ b/phpBB/phpbb/db/migration/data/30x/3_0_8.php @@ -11,7 +11,7 @@ class phpbb_db_migration_data_30x_3_0_8 extends phpbb_db_migration { public function effectively_installed() { - return version_compare($this->config['version'], '3.0.8', '>='); + return phpbb_version_compare($this->config['version'], '3.0.8', '>='); } static public function depends_on() diff --git a/phpBB/phpbb/db/migration/data/30x/3_0_8_rc1.php b/phpBB/phpbb/db/migration/data/30x/3_0_8_rc1.php index aeff35333e..c534cabb6c 100644 --- a/phpBB/phpbb/db/migration/data/30x/3_0_8_rc1.php +++ b/phpBB/phpbb/db/migration/data/30x/3_0_8_rc1.php @@ -11,7 +11,7 @@ class phpbb_db_migration_data_30x_3_0_8_rc1 extends phpbb_db_migration { public function effectively_installed() { - return version_compare($this->config['version'], '3.0.8-rc1', '>='); + return phpbb_version_compare($this->config['version'], '3.0.8-RC1', '>='); } static public function depends_on() @@ -38,7 +38,7 @@ class phpbb_db_migration_data_30x_3_0_8_rc1 extends phpbb_db_migration array('config.update_if_equals', array(600, 'queue_interval', 60)), array('config.update_if_equals', array(50, 'email_package_size', 20)), - array('config.update', array('version', '3.0.8-rc1')), + array('config.update', array('version', '3.0.8-RC1')), ); } diff --git a/phpBB/phpbb/db/migration/data/30x/3_0_9.php b/phpBB/phpbb/db/migration/data/30x/3_0_9.php index d5269ea6f0..6a38793269 100644 --- a/phpBB/phpbb/db/migration/data/30x/3_0_9.php +++ b/phpBB/phpbb/db/migration/data/30x/3_0_9.php @@ -11,7 +11,7 @@ class phpbb_db_migration_data_30x_3_0_9 extends phpbb_db_migration { public function effectively_installed() { - return version_compare($this->config['version'], '3.0.9', '>='); + return phpbb_version_compare($this->config['version'], '3.0.9', '>='); } static public function depends_on() diff --git a/phpBB/phpbb/db/migration/data/30x/3_0_9_rc1.php b/phpBB/phpbb/db/migration/data/30x/3_0_9_rc1.php index 4c345b429b..81c67550bd 100644 --- a/phpBB/phpbb/db/migration/data/30x/3_0_9_rc1.php +++ b/phpBB/phpbb/db/migration/data/30x/3_0_9_rc1.php @@ -11,7 +11,7 @@ class phpbb_db_migration_data_30x_3_0_9_rc1 extends phpbb_db_migration { public function effectively_installed() { - return version_compare($this->config['version'], '3.0.9-rc1', '>='); + return phpbb_version_compare($this->config['version'], '3.0.9-RC1', '>='); } static public function depends_on() @@ -74,7 +74,7 @@ class phpbb_db_migration_data_30x_3_0_9_rc1 extends phpbb_db_migration array('custom', array(array(&$this, 'update_file_extension_group_names'))), array('custom', array(array(&$this, 'fix_firebird_qa_captcha'))), - array('config.update', array('version', '3.0.9-rc1')), + array('config.update', array('version', '3.0.9-RC1')), ); } diff --git a/phpBB/phpbb/db/migration/data/30x/3_0_9_rc2.php b/phpBB/phpbb/db/migration/data/30x/3_0_9_rc2.php index c0e662aa45..1531f408b7 100644 --- a/phpBB/phpbb/db/migration/data/30x/3_0_9_rc2.php +++ b/phpBB/phpbb/db/migration/data/30x/3_0_9_rc2.php @@ -11,7 +11,7 @@ class phpbb_db_migration_data_30x_3_0_9_rc2 extends phpbb_db_migration { public function effectively_installed() { - return version_compare($this->config['version'], '3.0.9-rc2', '>='); + return phpbb_version_compare($this->config['version'], '3.0.9-RC2', '>='); } static public function depends_on() @@ -22,7 +22,7 @@ class phpbb_db_migration_data_30x_3_0_9_rc2 extends phpbb_db_migration public function update_data() { return array( - array('config.update', array('version', '3.0.9-rc2')), + array('config.update', array('version', '3.0.9-RC2')), ); } } diff --git a/phpBB/phpbb/db/migration/data/30x/3_0_9_rc3.php b/phpBB/phpbb/db/migration/data/30x/3_0_9_rc3.php index d6d1f14b2e..851680b093 100644 --- a/phpBB/phpbb/db/migration/data/30x/3_0_9_rc3.php +++ b/phpBB/phpbb/db/migration/data/30x/3_0_9_rc3.php @@ -11,7 +11,7 @@ class phpbb_db_migration_data_30x_3_0_9_rc3 extends phpbb_db_migration { public function effectively_installed() { - return version_compare($this->config['version'], '3.0.9-rc3', '>='); + return phpbb_version_compare($this->config['version'], '3.0.9-RC3', '>='); } static public function depends_on() @@ -22,7 +22,7 @@ class phpbb_db_migration_data_30x_3_0_9_rc3 extends phpbb_db_migration public function update_data() { return array( - array('config.update', array('version', '3.0.9-rc3')), + array('config.update', array('version', '3.0.9-RC3')), ); } } diff --git a/phpBB/phpbb/db/migration/data/30x/3_0_9_rc4.php b/phpBB/phpbb/db/migration/data/30x/3_0_9_rc4.php index e673249343..879538c341 100644 --- a/phpBB/phpbb/db/migration/data/30x/3_0_9_rc4.php +++ b/phpBB/phpbb/db/migration/data/30x/3_0_9_rc4.php @@ -11,7 +11,7 @@ class phpbb_db_migration_data_30x_3_0_9_rc4 extends phpbb_db_migration { public function effectively_installed() { - return version_compare($this->config['version'], '3.0.9-rc4', '>='); + return phpbb_version_compare($this->config['version'], '3.0.9-RC4', '>='); } static public function depends_on() @@ -22,7 +22,7 @@ class phpbb_db_migration_data_30x_3_0_9_rc4 extends phpbb_db_migration public function update_data() { return array( - array('config.update', array('version', '3.0.9-rc4')), + array('config.update', array('version', '3.0.9-RC4')), ); } } diff --git a/phpBB/phpbb/db/migration/data/310/auth_provider_oauth.php b/phpBB/phpbb/db/migration/data/310/auth_provider_oauth.php new file mode 100644 index 0000000000..cad1c16bb2 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/310/auth_provider_oauth.php @@ -0,0 +1,71 @@ +<?php +/** +* +* @package migration +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* +*/ + +class phpbb_db_migration_data_310_auth_provider_oauth extends phpbb_db_migration +{ + public function effectively_installed() + { + return $this->db_tools->sql_table_exists($this->table_prefix . 'auth_provider_oauth'); + } + + public function update_schema() + { + return array( + 'add_tables' => array( + $this->table_prefix . 'oauth_tokens' => array( + 'COLUMNS' => array( + 'user_id' => array('UINT', 0), // phpbb_users.user_id + 'session_id' => array('CHAR:32', ''), // phpbb_sessions.session_id used only when user_id not set + 'provider' => array('VCHAR', ''), // Name of the OAuth provider + 'oauth_token' => array('MTEXT', ''), // Serialized token + ), + 'KEYS' => array( + 'user_id' => array('INDEX', 'user_id'), + 'provider' => array('INDEX', 'provider'), + ), + ), + $this->table_prefix . 'oauth_accounts' => array( + 'COLUMNS' => array( + 'user_id' => array('UINT', 0), + 'provider' => array('VCHAR', ''), + 'oauth_provider_id' => array('TEXT_UNI', ''), + ), + 'PRIMARY_KEY' => array( + 'user_id', + 'provider', + ), + ), + ), + ); + } + + public function revert_schema() + { + return array( + 'drop_tables' => array( + $this->table_prefix . 'oauth_tokens', + $this->table_prefix . 'oauth_accounts', + ), + ); + } + + public function update_data() + { + return array( + array('module.add', array( + 'ucp', + 'UCP_PROFILE', + array( + 'module_basename' => 'ucp_auth_link', + 'modes' => array('auth_link'), + ), + )), + ); + } +} diff --git a/phpBB/phpbb/db/migration/data/310/signature_module_auth.php b/phpBB/phpbb/db/migration/data/310/signature_module_auth.php index e4fbb27bcb..02cd70059a 100644 --- a/phpBB/phpbb/db/migration/data/310/signature_module_auth.php +++ b/phpBB/phpbb/db/migration/data/310/signature_module_auth.php @@ -17,7 +17,7 @@ class phpbb_db_migration_data_310_signature_module_auth extends phpbb_db_migrati AND module_basename = 'ucp_profile' AND module_mode = 'signature'"; $result = $this->db->sql_query($sql); - $module_auth = $this->db_sql_fetchfield('module_auth'); + $module_auth = $this->db->sql_fetchfield('module_auth'); $this->db->sql_freeresult($result); return $module_auth === 'acl_u_sig' || $module_auth === false; diff --git a/phpBB/phpbb/db/migration/data/310/softdelete_mcp_modules.php b/phpBB/phpbb/db/migration/data/310/softdelete_mcp_modules.php new file mode 100644 index 0000000000..f80f55d19a --- /dev/null +++ b/phpBB/phpbb/db/migration/data/310/softdelete_mcp_modules.php @@ -0,0 +1,55 @@ +<?php +/** +* +* @package migration +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* +*/ + +class phpbb_db_migration_data_310_softdelete_mcp_modules extends phpbb_db_migration +{ + public function effectively_installed() + { + $sql = 'SELECT module_id + FROM ' . MODULES_TABLE . " + WHERE module_class = 'mcp' + AND module_basename = 'mcp_queue' + AND module_mode = 'deleted_topics'"; + $result = $this->db->sql_query($sql); + $module_id = $this->db->sql_fetchfield('module_id'); + $this->db->sql_freeresult($result); + + return $module_id !== false; + } + + static public function depends_on() + { + return array( + 'phpbb_db_migration_data_310_dev', + 'phpbb_db_migration_data_310_softdelete_p2', + ); + } + + public function update_data() + { + return array( + array('module.add', array( + 'mcp', + 'MCP_QUEUE', + array( + 'module_basename' => 'mcp_queue', + 'modes' => array('deleted_topics'), + ), + )), + array('module.add', array( + 'mcp', + 'MCP_QUEUE', + array( + 'module_basename' => 'mcp_queue', + 'modes' => array('deleted_posts'), + ), + )), + ); + } +} diff --git a/phpBB/phpbb/db/tools.php b/phpBB/phpbb/db/tools.php index 492284ffcd..dbe00f6be2 100644 --- a/phpBB/phpbb/db/tools.php +++ b/phpBB/phpbb/db/tools.php @@ -37,247 +37,257 @@ class phpbb_db_tools * The Column types for every database we support * @var array */ - var $dbms_type_map = array( - 'mysql_41' => array( - 'INT:' => 'int(%d)', - 'BINT' => 'bigint(20)', - 'UINT' => 'mediumint(8) UNSIGNED', - 'UINT:' => 'int(%d) UNSIGNED', - 'TINT:' => 'tinyint(%d)', - 'USINT' => 'smallint(4) UNSIGNED', - 'BOOL' => 'tinyint(1) UNSIGNED', - 'VCHAR' => 'varchar(255)', - 'VCHAR:' => 'varchar(%d)', - 'CHAR:' => 'char(%d)', - 'XSTEXT' => 'text', - 'XSTEXT_UNI'=> 'varchar(100)', - 'STEXT' => 'text', - 'STEXT_UNI' => 'varchar(255)', - 'TEXT' => 'text', - 'TEXT_UNI' => 'text', - 'MTEXT' => 'mediumtext', - 'MTEXT_UNI' => 'mediumtext', - 'TIMESTAMP' => 'int(11) UNSIGNED', - 'DECIMAL' => 'decimal(5,2)', - 'DECIMAL:' => 'decimal(%d,2)', - 'PDECIMAL' => 'decimal(6,3)', - 'PDECIMAL:' => 'decimal(%d,3)', - 'VCHAR_UNI' => 'varchar(255)', - 'VCHAR_UNI:'=> 'varchar(%d)', - 'VCHAR_CI' => 'varchar(255)', - 'VARBINARY' => 'varbinary(255)', - ), - - 'mysql_40' => array( - 'INT:' => 'int(%d)', - 'BINT' => 'bigint(20)', - 'UINT' => 'mediumint(8) UNSIGNED', - 'UINT:' => 'int(%d) UNSIGNED', - 'TINT:' => 'tinyint(%d)', - 'USINT' => 'smallint(4) UNSIGNED', - 'BOOL' => 'tinyint(1) UNSIGNED', - 'VCHAR' => 'varbinary(255)', - 'VCHAR:' => 'varbinary(%d)', - 'CHAR:' => 'binary(%d)', - 'XSTEXT' => 'blob', - 'XSTEXT_UNI'=> 'blob', - 'STEXT' => 'blob', - 'STEXT_UNI' => 'blob', - 'TEXT' => 'blob', - 'TEXT_UNI' => 'blob', - 'MTEXT' => 'mediumblob', - 'MTEXT_UNI' => 'mediumblob', - 'TIMESTAMP' => 'int(11) UNSIGNED', - 'DECIMAL' => 'decimal(5,2)', - 'DECIMAL:' => 'decimal(%d,2)', - 'PDECIMAL' => 'decimal(6,3)', - 'PDECIMAL:' => 'decimal(%d,3)', - 'VCHAR_UNI' => 'blob', - 'VCHAR_UNI:'=> array('varbinary(%d)', 'limit' => array('mult', 3, 255, 'blob')), - 'VCHAR_CI' => 'blob', - 'VARBINARY' => 'varbinary(255)', - ), - - 'firebird' => array( - 'INT:' => 'INTEGER', - 'BINT' => 'DOUBLE PRECISION', - 'UINT' => 'INTEGER', - 'UINT:' => 'INTEGER', - 'TINT:' => 'INTEGER', - 'USINT' => 'INTEGER', - 'BOOL' => 'INTEGER', - 'VCHAR' => 'VARCHAR(255) CHARACTER SET NONE', - 'VCHAR:' => 'VARCHAR(%d) CHARACTER SET NONE', - 'CHAR:' => 'CHAR(%d) CHARACTER SET NONE', - 'XSTEXT' => 'BLOB SUB_TYPE TEXT CHARACTER SET NONE', - 'STEXT' => 'BLOB SUB_TYPE TEXT CHARACTER SET NONE', - 'TEXT' => 'BLOB SUB_TYPE TEXT CHARACTER SET NONE', - 'MTEXT' => 'BLOB SUB_TYPE TEXT CHARACTER SET NONE', - 'XSTEXT_UNI'=> 'VARCHAR(100) CHARACTER SET UTF8', - 'STEXT_UNI' => 'VARCHAR(255) CHARACTER SET UTF8', - 'TEXT_UNI' => 'BLOB SUB_TYPE TEXT CHARACTER SET UTF8', - 'MTEXT_UNI' => 'BLOB SUB_TYPE TEXT CHARACTER SET UTF8', - 'TIMESTAMP' => 'INTEGER', - 'DECIMAL' => 'DOUBLE PRECISION', - 'DECIMAL:' => 'DOUBLE PRECISION', - 'PDECIMAL' => 'DOUBLE PRECISION', - 'PDECIMAL:' => 'DOUBLE PRECISION', - 'VCHAR_UNI' => 'VARCHAR(255) CHARACTER SET UTF8', - 'VCHAR_UNI:'=> 'VARCHAR(%d) CHARACTER SET UTF8', - 'VCHAR_CI' => 'VARCHAR(255) CHARACTER SET UTF8', - 'VARBINARY' => 'CHAR(255) CHARACTER SET NONE', - ), - - 'mssql' => array( - 'INT:' => '[int]', - 'BINT' => '[float]', - 'UINT' => '[int]', - 'UINT:' => '[int]', - 'TINT:' => '[int]', - 'USINT' => '[int]', - 'BOOL' => '[int]', - 'VCHAR' => '[varchar] (255)', - 'VCHAR:' => '[varchar] (%d)', - 'CHAR:' => '[char] (%d)', - 'XSTEXT' => '[varchar] (1000)', - 'STEXT' => '[varchar] (3000)', - 'TEXT' => '[varchar] (8000)', - 'MTEXT' => '[text]', - 'XSTEXT_UNI'=> '[varchar] (100)', - 'STEXT_UNI' => '[varchar] (255)', - 'TEXT_UNI' => '[varchar] (4000)', - 'MTEXT_UNI' => '[text]', - 'TIMESTAMP' => '[int]', - 'DECIMAL' => '[float]', - 'DECIMAL:' => '[float]', - 'PDECIMAL' => '[float]', - 'PDECIMAL:' => '[float]', - 'VCHAR_UNI' => '[varchar] (255)', - 'VCHAR_UNI:'=> '[varchar] (%d)', - 'VCHAR_CI' => '[varchar] (255)', - 'VARBINARY' => '[varchar] (255)', - ), - - 'mssqlnative' => array( - 'INT:' => '[int]', - 'BINT' => '[float]', - 'UINT' => '[int]', - 'UINT:' => '[int]', - 'TINT:' => '[int]', - 'USINT' => '[int]', - 'BOOL' => '[int]', - 'VCHAR' => '[varchar] (255)', - 'VCHAR:' => '[varchar] (%d)', - 'CHAR:' => '[char] (%d)', - 'XSTEXT' => '[varchar] (1000)', - 'STEXT' => '[varchar] (3000)', - 'TEXT' => '[varchar] (8000)', - 'MTEXT' => '[text]', - 'XSTEXT_UNI'=> '[varchar] (100)', - 'STEXT_UNI' => '[varchar] (255)', - 'TEXT_UNI' => '[varchar] (4000)', - 'MTEXT_UNI' => '[text]', - 'TIMESTAMP' => '[int]', - 'DECIMAL' => '[float]', - 'DECIMAL:' => '[float]', - 'PDECIMAL' => '[float]', - 'PDECIMAL:' => '[float]', - 'VCHAR_UNI' => '[varchar] (255)', - 'VCHAR_UNI:'=> '[varchar] (%d)', - 'VCHAR_CI' => '[varchar] (255)', - 'VARBINARY' => '[varchar] (255)', - ), - - 'oracle' => array( - 'INT:' => 'number(%d)', - 'BINT' => 'number(20)', - 'UINT' => 'number(8)', - 'UINT:' => 'number(%d)', - 'TINT:' => 'number(%d)', - 'USINT' => 'number(4)', - 'BOOL' => 'number(1)', - 'VCHAR' => 'varchar2(255)', - 'VCHAR:' => 'varchar2(%d)', - 'CHAR:' => 'char(%d)', - 'XSTEXT' => 'varchar2(1000)', - 'STEXT' => 'varchar2(3000)', - 'TEXT' => 'clob', - 'MTEXT' => 'clob', - 'XSTEXT_UNI'=> 'varchar2(300)', - 'STEXT_UNI' => 'varchar2(765)', - 'TEXT_UNI' => 'clob', - 'MTEXT_UNI' => 'clob', - 'TIMESTAMP' => 'number(11)', - 'DECIMAL' => 'number(5, 2)', - 'DECIMAL:' => 'number(%d, 2)', - 'PDECIMAL' => 'number(6, 3)', - 'PDECIMAL:' => 'number(%d, 3)', - 'VCHAR_UNI' => 'varchar2(765)', - 'VCHAR_UNI:'=> array('varchar2(%d)', 'limit' => array('mult', 3, 765, 'clob')), - 'VCHAR_CI' => 'varchar2(255)', - 'VARBINARY' => 'raw(255)', - ), - - 'sqlite' => array( - 'INT:' => 'int(%d)', - 'BINT' => 'bigint(20)', - 'UINT' => 'INTEGER UNSIGNED', //'mediumint(8) UNSIGNED', - 'UINT:' => 'INTEGER UNSIGNED', // 'int(%d) UNSIGNED', - 'TINT:' => 'tinyint(%d)', - 'USINT' => 'INTEGER UNSIGNED', //'mediumint(4) UNSIGNED', - 'BOOL' => 'INTEGER UNSIGNED', //'tinyint(1) UNSIGNED', - 'VCHAR' => 'varchar(255)', - 'VCHAR:' => 'varchar(%d)', - 'CHAR:' => 'char(%d)', - 'XSTEXT' => 'text(65535)', - 'STEXT' => 'text(65535)', - 'TEXT' => 'text(65535)', - 'MTEXT' => 'mediumtext(16777215)', - 'XSTEXT_UNI'=> 'text(65535)', - 'STEXT_UNI' => 'text(65535)', - 'TEXT_UNI' => 'text(65535)', - 'MTEXT_UNI' => 'mediumtext(16777215)', - 'TIMESTAMP' => 'INTEGER UNSIGNED', //'int(11) UNSIGNED', - 'DECIMAL' => 'decimal(5,2)', - 'DECIMAL:' => 'decimal(%d,2)', - 'PDECIMAL' => 'decimal(6,3)', - 'PDECIMAL:' => 'decimal(%d,3)', - 'VCHAR_UNI' => 'varchar(255)', - 'VCHAR_UNI:'=> 'varchar(%d)', - 'VCHAR_CI' => 'varchar(255)', - 'VARBINARY' => 'blob', - ), - - 'postgres' => array( - 'INT:' => 'INT4', - 'BINT' => 'INT8', - 'UINT' => 'INT4', // unsigned - 'UINT:' => 'INT4', // unsigned - 'USINT' => 'INT2', // unsigned - 'BOOL' => 'INT2', // unsigned - 'TINT:' => 'INT2', - 'VCHAR' => 'varchar(255)', - 'VCHAR:' => 'varchar(%d)', - 'CHAR:' => 'char(%d)', - 'XSTEXT' => 'varchar(1000)', - 'STEXT' => 'varchar(3000)', - 'TEXT' => 'varchar(8000)', - 'MTEXT' => 'TEXT', - 'XSTEXT_UNI'=> 'varchar(100)', - 'STEXT_UNI' => 'varchar(255)', - 'TEXT_UNI' => 'varchar(4000)', - 'MTEXT_UNI' => 'TEXT', - 'TIMESTAMP' => 'INT4', // unsigned - 'DECIMAL' => 'decimal(5,2)', - 'DECIMAL:' => 'decimal(%d,2)', - 'PDECIMAL' => 'decimal(6,3)', - 'PDECIMAL:' => 'decimal(%d,3)', - 'VCHAR_UNI' => 'varchar(255)', - 'VCHAR_UNI:'=> 'varchar(%d)', - 'VCHAR_CI' => 'varchar_ci', - 'VARBINARY' => 'bytea', - ), - ); + var $dbms_type_map = array(); + + /** + * Get the column types for every database we support + * + * @return array + */ + public static function get_dbms_type_map() + { + return array( + 'mysql_41' => array( + 'INT:' => 'int(%d)', + 'BINT' => 'bigint(20)', + 'UINT' => 'mediumint(8) UNSIGNED', + 'UINT:' => 'int(%d) UNSIGNED', + 'TINT:' => 'tinyint(%d)', + 'USINT' => 'smallint(4) UNSIGNED', + 'BOOL' => 'tinyint(1) UNSIGNED', + 'VCHAR' => 'varchar(255)', + 'VCHAR:' => 'varchar(%d)', + 'CHAR:' => 'char(%d)', + 'XSTEXT' => 'text', + 'XSTEXT_UNI'=> 'varchar(100)', + 'STEXT' => 'text', + 'STEXT_UNI' => 'varchar(255)', + 'TEXT' => 'text', + 'TEXT_UNI' => 'text', + 'MTEXT' => 'mediumtext', + 'MTEXT_UNI' => 'mediumtext', + 'TIMESTAMP' => 'int(11) UNSIGNED', + 'DECIMAL' => 'decimal(5,2)', + 'DECIMAL:' => 'decimal(%d,2)', + 'PDECIMAL' => 'decimal(6,3)', + 'PDECIMAL:' => 'decimal(%d,3)', + 'VCHAR_UNI' => 'varchar(255)', + 'VCHAR_UNI:'=> 'varchar(%d)', + 'VCHAR_CI' => 'varchar(255)', + 'VARBINARY' => 'varbinary(255)', + ), + + 'mysql_40' => array( + 'INT:' => 'int(%d)', + 'BINT' => 'bigint(20)', + 'UINT' => 'mediumint(8) UNSIGNED', + 'UINT:' => 'int(%d) UNSIGNED', + 'TINT:' => 'tinyint(%d)', + 'USINT' => 'smallint(4) UNSIGNED', + 'BOOL' => 'tinyint(1) UNSIGNED', + 'VCHAR' => 'varbinary(255)', + 'VCHAR:' => 'varbinary(%d)', + 'CHAR:' => 'binary(%d)', + 'XSTEXT' => 'blob', + 'XSTEXT_UNI'=> 'blob', + 'STEXT' => 'blob', + 'STEXT_UNI' => 'blob', + 'TEXT' => 'blob', + 'TEXT_UNI' => 'blob', + 'MTEXT' => 'mediumblob', + 'MTEXT_UNI' => 'mediumblob', + 'TIMESTAMP' => 'int(11) UNSIGNED', + 'DECIMAL' => 'decimal(5,2)', + 'DECIMAL:' => 'decimal(%d,2)', + 'PDECIMAL' => 'decimal(6,3)', + 'PDECIMAL:' => 'decimal(%d,3)', + 'VCHAR_UNI' => 'blob', + 'VCHAR_UNI:'=> array('varbinary(%d)', 'limit' => array('mult', 3, 255, 'blob')), + 'VCHAR_CI' => 'blob', + 'VARBINARY' => 'varbinary(255)', + ), + + 'firebird' => array( + 'INT:' => 'INTEGER', + 'BINT' => 'DOUBLE PRECISION', + 'UINT' => 'INTEGER', + 'UINT:' => 'INTEGER', + 'TINT:' => 'INTEGER', + 'USINT' => 'INTEGER', + 'BOOL' => 'INTEGER', + 'VCHAR' => 'VARCHAR(255) CHARACTER SET NONE', + 'VCHAR:' => 'VARCHAR(%d) CHARACTER SET NONE', + 'CHAR:' => 'CHAR(%d) CHARACTER SET NONE', + 'XSTEXT' => 'BLOB SUB_TYPE TEXT CHARACTER SET NONE', + 'STEXT' => 'BLOB SUB_TYPE TEXT CHARACTER SET NONE', + 'TEXT' => 'BLOB SUB_TYPE TEXT CHARACTER SET NONE', + 'MTEXT' => 'BLOB SUB_TYPE TEXT CHARACTER SET NONE', + 'XSTEXT_UNI'=> 'VARCHAR(100) CHARACTER SET UTF8', + 'STEXT_UNI' => 'VARCHAR(255) CHARACTER SET UTF8', + 'TEXT_UNI' => 'BLOB SUB_TYPE TEXT CHARACTER SET UTF8', + 'MTEXT_UNI' => 'BLOB SUB_TYPE TEXT CHARACTER SET UTF8', + 'TIMESTAMP' => 'INTEGER', + 'DECIMAL' => 'DOUBLE PRECISION', + 'DECIMAL:' => 'DOUBLE PRECISION', + 'PDECIMAL' => 'DOUBLE PRECISION', + 'PDECIMAL:' => 'DOUBLE PRECISION', + 'VCHAR_UNI' => 'VARCHAR(255) CHARACTER SET UTF8', + 'VCHAR_UNI:'=> 'VARCHAR(%d) CHARACTER SET UTF8', + 'VCHAR_CI' => 'VARCHAR(255) CHARACTER SET UTF8', + 'VARBINARY' => 'CHAR(255) CHARACTER SET NONE', + ), + + 'mssql' => array( + 'INT:' => '[int]', + 'BINT' => '[float]', + 'UINT' => '[int]', + 'UINT:' => '[int]', + 'TINT:' => '[int]', + 'USINT' => '[int]', + 'BOOL' => '[int]', + 'VCHAR' => '[varchar] (255)', + 'VCHAR:' => '[varchar] (%d)', + 'CHAR:' => '[char] (%d)', + 'XSTEXT' => '[varchar] (1000)', + 'STEXT' => '[varchar] (3000)', + 'TEXT' => '[varchar] (8000)', + 'MTEXT' => '[text]', + 'XSTEXT_UNI'=> '[varchar] (100)', + 'STEXT_UNI' => '[varchar] (255)', + 'TEXT_UNI' => '[varchar] (4000)', + 'MTEXT_UNI' => '[text]', + 'TIMESTAMP' => '[int]', + 'DECIMAL' => '[float]', + 'DECIMAL:' => '[float]', + 'PDECIMAL' => '[float]', + 'PDECIMAL:' => '[float]', + 'VCHAR_UNI' => '[varchar] (255)', + 'VCHAR_UNI:'=> '[varchar] (%d)', + 'VCHAR_CI' => '[varchar] (255)', + 'VARBINARY' => '[varchar] (255)', + ), + + 'mssqlnative' => array( + 'INT:' => '[int]', + 'BINT' => '[float]', + 'UINT' => '[int]', + 'UINT:' => '[int]', + 'TINT:' => '[int]', + 'USINT' => '[int]', + 'BOOL' => '[int]', + 'VCHAR' => '[varchar] (255)', + 'VCHAR:' => '[varchar] (%d)', + 'CHAR:' => '[char] (%d)', + 'XSTEXT' => '[varchar] (1000)', + 'STEXT' => '[varchar] (3000)', + 'TEXT' => '[varchar] (8000)', + 'MTEXT' => '[text]', + 'XSTEXT_UNI'=> '[varchar] (100)', + 'STEXT_UNI' => '[varchar] (255)', + 'TEXT_UNI' => '[varchar] (4000)', + 'MTEXT_UNI' => '[text]', + 'TIMESTAMP' => '[int]', + 'DECIMAL' => '[float]', + 'DECIMAL:' => '[float]', + 'PDECIMAL' => '[float]', + 'PDECIMAL:' => '[float]', + 'VCHAR_UNI' => '[varchar] (255)', + 'VCHAR_UNI:'=> '[varchar] (%d)', + 'VCHAR_CI' => '[varchar] (255)', + 'VARBINARY' => '[varchar] (255)', + ), + + 'oracle' => array( + 'INT:' => 'number(%d)', + 'BINT' => 'number(20)', + 'UINT' => 'number(8)', + 'UINT:' => 'number(%d)', + 'TINT:' => 'number(%d)', + 'USINT' => 'number(4)', + 'BOOL' => 'number(1)', + 'VCHAR' => 'varchar2(255)', + 'VCHAR:' => 'varchar2(%d)', + 'CHAR:' => 'char(%d)', + 'XSTEXT' => 'varchar2(1000)', + 'STEXT' => 'varchar2(3000)', + 'TEXT' => 'clob', + 'MTEXT' => 'clob', + 'XSTEXT_UNI'=> 'varchar2(300)', + 'STEXT_UNI' => 'varchar2(765)', + 'TEXT_UNI' => 'clob', + 'MTEXT_UNI' => 'clob', + 'TIMESTAMP' => 'number(11)', + 'DECIMAL' => 'number(5, 2)', + 'DECIMAL:' => 'number(%d, 2)', + 'PDECIMAL' => 'number(6, 3)', + 'PDECIMAL:' => 'number(%d, 3)', + 'VCHAR_UNI' => 'varchar2(765)', + 'VCHAR_UNI:'=> array('varchar2(%d)', 'limit' => array('mult', 3, 765, 'clob')), + 'VCHAR_CI' => 'varchar2(255)', + 'VARBINARY' => 'raw(255)', + ), + + 'sqlite' => array( + 'INT:' => 'int(%d)', + 'BINT' => 'bigint(20)', + 'UINT' => 'INTEGER UNSIGNED', //'mediumint(8) UNSIGNED', + 'UINT:' => 'INTEGER UNSIGNED', // 'int(%d) UNSIGNED', + 'TINT:' => 'tinyint(%d)', + 'USINT' => 'INTEGER UNSIGNED', //'mediumint(4) UNSIGNED', + 'BOOL' => 'INTEGER UNSIGNED', //'tinyint(1) UNSIGNED', + 'VCHAR' => 'varchar(255)', + 'VCHAR:' => 'varchar(%d)', + 'CHAR:' => 'char(%d)', + 'XSTEXT' => 'text(65535)', + 'STEXT' => 'text(65535)', + 'TEXT' => 'text(65535)', + 'MTEXT' => 'mediumtext(16777215)', + 'XSTEXT_UNI'=> 'text(65535)', + 'STEXT_UNI' => 'text(65535)', + 'TEXT_UNI' => 'text(65535)', + 'MTEXT_UNI' => 'mediumtext(16777215)', + 'TIMESTAMP' => 'INTEGER UNSIGNED', //'int(11) UNSIGNED', + 'DECIMAL' => 'decimal(5,2)', + 'DECIMAL:' => 'decimal(%d,2)', + 'PDECIMAL' => 'decimal(6,3)', + 'PDECIMAL:' => 'decimal(%d,3)', + 'VCHAR_UNI' => 'varchar(255)', + 'VCHAR_UNI:'=> 'varchar(%d)', + 'VCHAR_CI' => 'varchar(255)', + 'VARBINARY' => 'blob', + ), + + 'postgres' => array( + 'INT:' => 'INT4', + 'BINT' => 'INT8', + 'UINT' => 'INT4', // unsigned + 'UINT:' => 'INT4', // unsigned + 'USINT' => 'INT2', // unsigned + 'BOOL' => 'INT2', // unsigned + 'TINT:' => 'INT2', + 'VCHAR' => 'varchar(255)', + 'VCHAR:' => 'varchar(%d)', + 'CHAR:' => 'char(%d)', + 'XSTEXT' => 'varchar(1000)', + 'STEXT' => 'varchar(3000)', + 'TEXT' => 'varchar(8000)', + 'MTEXT' => 'TEXT', + 'XSTEXT_UNI'=> 'varchar(100)', + 'STEXT_UNI' => 'varchar(255)', + 'TEXT_UNI' => 'varchar(4000)', + 'MTEXT_UNI' => 'TEXT', + 'TIMESTAMP' => 'INT4', // unsigned + 'DECIMAL' => 'decimal(5,2)', + 'DECIMAL:' => 'decimal(%d,2)', + 'PDECIMAL' => 'decimal(6,3)', + 'PDECIMAL:' => 'decimal(%d,3)', + 'VCHAR_UNI' => 'varchar(255)', + 'VCHAR_UNI:'=> 'varchar(%d)', + 'VCHAR_CI' => 'varchar_ci', + 'VARBINARY' => 'bytea', + ), + ); + } /** * A list of types being unsigned for better reference in some db's @@ -308,6 +318,8 @@ class phpbb_db_tools $this->db = $db; $this->return_statements = $return_statements; + $this->dbms_type_map = self::get_dbms_type_map(); + // Determine mapping database type switch ($this->db->sql_layer) { diff --git a/phpBB/phpbb/di/extension/core.php b/phpBB/phpbb/di/extension/core.php index 9c36ba2fc4..9d59a24b7e 100644 --- a/phpBB/phpbb/di/extension/core.php +++ b/phpBB/phpbb/di/extension/core.php @@ -26,19 +26,19 @@ use Symfony\Component\Config\FileLocator; class phpbb_di_extension_core extends Extension { /** - * phpBB Root path + * Config path * @var string */ - protected $root_path; + protected $config_path; /** * Constructor * - * @param string $root_path Root path + * @param string $config_path Config path */ - public function __construct($root_path) + public function __construct($config_path) { - $this->root_path = $root_path; + $this->config_path = $config_path; } /** @@ -51,7 +51,7 @@ class phpbb_di_extension_core extends Extension */ public function load(array $config, ContainerBuilder $container) { - $loader = new YamlFileLoader($container, new FileLocator(phpbb_realpath($this->root_path . 'config'))); + $loader = new YamlFileLoader($container, new FileLocator(phpbb_realpath($this->config_path))); $loader->load('services.yml'); } diff --git a/phpBB/phpbb/event/extension_subscriber_loader.php b/phpBB/phpbb/event/extension_subscriber_loader.php index d933b943d7..d6284a52fb 100644 --- a/phpBB/phpbb/event/extension_subscriber_loader.php +++ b/phpBB/phpbb/event/extension_subscriber_loader.php @@ -33,7 +33,6 @@ class phpbb_event_extension_subscriber_loader $finder = $this->extension_manager->get_finder(); $subscriber_classes = $finder ->extension_directory('/event') - ->suffix('listener') ->core_path('event/') ->get_classes(); diff --git a/phpBB/phpbb/log/null.php b/phpBB/phpbb/log/null.php new file mode 100644 index 0000000000..14b5f65eec --- /dev/null +++ b/phpBB/phpbb/log/null.php @@ -0,0 +1,78 @@ +<?php +/** +* +* @package phpbb_log +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** +* Null logger +* +* @package phpbb_log +*/ +class phpbb_log_null implements phpbb_log_interface +{ + /** + * {@inheritdoc} + */ + public function is_enabled($type = '') + { + return false; + } + + /** + * {@inheritdoc} + */ + public function disable($type = '') + { + } + + /** + * {@inheritdoc} + */ + public function enable($type = '') + { + } + + /** + * {@inheritdoc} + */ + public function add($mode, $user_id, $log_ip, $log_operation, $log_time = false, $additional_data = array()) + { + return false; + } + + /** + * {@inheritdoc} + */ + public function get_logs($mode, $count_logs = true, $limit = 0, $offset = 0, $forum_id = 0, $topic_id = 0, $user_id = 0, $log_time = 0, $sort_by = 'l.log_time DESC', $keywords = '') + { + return array(); + } + + /** + * {@inheritdoc} + */ + public function get_log_count() + { + return 0; + } + + /** + * {@inheritdoc} + */ + public function get_valid_offset() + { + return 0; + } +} diff --git a/phpBB/phpbb/notification/manager.php b/phpBB/phpbb/notification/manager.php index dab69bcff9..a962a61e6e 100644 --- a/phpBB/phpbb/notification/manager.php +++ b/phpBB/phpbb/notification/manager.php @@ -490,15 +490,15 @@ class phpbb_notification_manager * * @param string|array $notification_type_name Type identifier or array of item types (only acceptable if the $item_id is identical for the specified types) * @param int|array $item_id Identifier within the type (or array of ids) - * @param array $data Data specific for this type that will be updated + * @param mixed $parent_id Parent identifier within the type (or array of ids), used in combination with item_id if specified (Default: false; not checked) */ - public function delete_notifications($notification_type_name, $item_id) + public function delete_notifications($notification_type_name, $item_id, $parent_id = false) { if (is_array($notification_type_name)) { foreach ($notification_type_name as $type) { - $this->delete_notifications($type, $item_id); + $this->delete_notifications($type, $item_id, $parent_id); } return; @@ -508,7 +508,8 @@ class phpbb_notification_manager $sql = 'DELETE FROM ' . $this->notifications_table . ' WHERE notification_type_id = ' . (int) $notification_type_id . ' - AND ' . (is_array($item_id) ? $this->db->sql_in_set('item_id', $item_id) : 'item_id = ' . (int) $item_id); + AND ' . (is_array($item_id) ? $this->db->sql_in_set('item_id', $item_id) : 'item_id = ' . (int) $item_id) . + (($parent_id !== false) ? ' AND ' . ((is_array($parent_id) ? $this->db->sql_in_set('item_parent_id', $parent_id) : 'item_parent_id = ' . (int) $parent_id)) : ''); $this->db->sql_query($sql); } diff --git a/phpBB/phpbb/notification/type/group_request.php b/phpBB/phpbb/notification/type/group_request.php new file mode 100644 index 0000000000..1a3b5b6992 --- /dev/null +++ b/phpBB/phpbb/notification/type/group_request.php @@ -0,0 +1,163 @@ +<?php +/** +* +* @package notifications +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +class phpbb_notification_type_group_request extends phpbb_notification_type_base +{ + /** + * {@inheritdoc} + */ + public function get_type() + { + return 'group_request'; + } + + /** + * {@inheritdoc} + */ + public static $notification_option = array( + 'lang' => 'NOTIFICATION_TYPE_GROUP_REQUEST', + ); + + /** + * {@inheritdoc} + */ + public function is_available() + { + // Leader of any groups? + $sql = 'SELECT group_id + FROM ' . USER_GROUP_TABLE . ' + WHERE user_id = ' . (int) $this->user->data['user_id'] . ' + AND group_leader = 1'; + $result = $this->db->sql_query_limit($sql, 1); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + return (!empty($row)) ? true : false; + } + + /** + * {@inheritdoc} + */ + public static function get_item_id($group) + { + return (int) $group['user_id']; + } + + /** + * {@inheritdoc} + */ + public static function get_item_parent_id($group) + { + // Group id is the parent + return (int) $group['group_id']; + } + + /** + * {@inheritdoc} + */ + public function find_users_for_notification($group, $options = array()) + { + $options = array_merge(array( + 'ignore_users' => array(), + ), $options); + + $sql = 'SELECT user_id + FROM ' . USER_GROUP_TABLE . ' + WHERE group_leader = 1 + AND group_id = ' . (int) $group['group_id']; + $result = $this->db->sql_query($sql); + + $user_ids = array(); + while ($row = $this->db->sql_fetchrow($result)) + { + $user_ids[] = (int) $row['user_id']; + } + $this->db->sql_freeresult($result); + + $this->user_loader->load_users($user_ids); + + return $this->check_user_notification_options($user_ids, $options); + } + + /** + * {@inheritdoc} + */ + public function get_avatar() + { + return $this->user_loader->get_avatar($this->item_id); + } + + /** + * {@inheritdoc} + */ + public function get_title() + { + $username = $this->user_loader->get_username($this->item_id, 'no_profile'); + + return $this->user->lang('NOTIFICATION_GROUP_REQUEST', $username, $this->get_data('group_name')); + } + + /** + * {@inheritdoc} + */ + public function get_email_template() + { + return 'group_request'; + } + + /** + * {@inheritdoc} + */ + public function get_email_template_variables() + { + $user_data = $this->user_loader->get_user($this->item_id); + + return array( + 'GROUP_NAME' => htmlspecialchars_decode($this->get_data('group_name')), + 'REQUEST_USERNAME' => htmlspecialchars_decode($user_data['username']), + + 'U_PENDING' => generate_board_url() . "/ucp.{$this->php_ext}?i=groups&mode=manage&action=list&g={$this->item_parent_id}", + 'U_GROUP' => generate_board_url() . "/memberlist.{$this->php_ext}?mode=group&g={$this->item_parent_id}", + ); + } + + /** + * {@inheritdoc} + */ + public function get_url() + { + return append_sid($this->phpbb_root_path . 'ucp.' . $this->php_ext, "i=groups&mode=manage&action=list&g={$this->item_parent_id}"); + } + + /** + * {@inheritdoc} + */ + public function users_to_query() + { + return array($this->item_id); + } + + /** + * {@inheritdoc} + */ + public function create_insert_array($group, $pre_create_data = array()) + { + $this->set_data('group_name', $group['group_name']); + + return parent::create_insert_array($group, $pre_create_data); + } +} diff --git a/phpBB/phpbb/notification/type/group_request_approved.php b/phpBB/phpbb/notification/type/group_request_approved.php new file mode 100644 index 0000000000..ce83329ff3 --- /dev/null +++ b/phpBB/phpbb/notification/type/group_request_approved.php @@ -0,0 +1,118 @@ +<?php +/** +* +* @package notifications +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +class phpbb_notification_type_group_request_approved extends phpbb_notification_type_base +{ + /** + * {@inheritdoc} + */ + public function get_type() + { + return 'group_request_approved'; + } + + /** + * {@inheritdoc} + */ + public function is_available() + { + return false; + } + + /** + * {@inheritdoc} + */ + public static function get_item_id($group) + { + return (int) $group['group_id']; + } + + /** + * {@inheritdoc} + */ + public static function get_item_parent_id($group) + { + return 0; + } + + /** + * {@inheritdoc} + */ + public function find_users_for_notification($group, $options = array()) + { + $users = array(); + + $group['user_ids'] = (!is_array($group['user_ids'])) ? array($group['user_ids']) : $group['user_ids']; + + foreach ($group['user_ids'] as $user_id) + { + $users[$user_id] = array(''); + } + + return $users; + } + + /** + * {@inheritdoc} + */ + public function get_title() + { + return $this->user->lang('NOTIFICATION_GROUP_REQUEST_APPROVED', $this->get_data('group_name')); + } + + /** + * {@inheritdoc} + */ + public function get_url() + { + return append_sid($this->phpbb_root_path . 'memberlist.' . $this->php_ext, "mode=group&g={$this->item_id}"); + } + + /** + * {@inheritdoc} + */ + public function create_insert_array($group, $pre_create_data = array()) + { + $this->set_data('group_name', $group['group_name']); + + return parent::create_insert_array($group, $pre_create_data); + } + + /** + * {@inheritdoc} + */ + public function users_to_query() + { + return array(); + } + + /** + * {@inheritdoc} + */ + public function get_email_template() + { + return false; + } + + /** + * {@inheritdoc} + */ + public function get_email_template_variables() + { + return array(); + } +} diff --git a/phpBB/phpbb/request/interface.php b/phpBB/phpbb/request/interface.php index 741db35917..05f6c54d3f 100644 --- a/phpBB/phpbb/request/interface.php +++ b/phpBB/phpbb/request/interface.php @@ -136,4 +136,14 @@ interface phpbb_request_interface * Pay attention when using these, they are unsanitised! */ public function variable_names($super_global = phpbb_request_interface::REQUEST); + + /** + * Returns the original array of the requested super global + * + * @param phpbb_request_interface::POST|GET|REQUEST|COOKIE $super_global + * The super global which will be returned + * + * @return array The original array of the requested super global. + */ + public function get_super_global($super_global = phpbb_request_interface::REQUEST); } diff --git a/phpBB/phpbb/request/request.php b/phpBB/phpbb/request/request.php index ae3c526d89..ed2e8e2200 100644 --- a/phpBB/phpbb/request/request.php +++ b/phpBB/phpbb/request/request.php @@ -412,4 +412,12 @@ class phpbb_request implements phpbb_request_interface return $var; } + + /** + * {@inheritdoc} + */ + public function get_super_global($super_global = phpbb_request_interface::REQUEST) + { + return $this->input[$super_global]; + } } diff --git a/phpBB/phpbb/style/extension_path_provider.php b/phpBB/phpbb/style/extension_path_provider.php deleted file mode 100644 index ec1d85f821..0000000000 --- a/phpBB/phpbb/style/extension_path_provider.php +++ /dev/null @@ -1,137 +0,0 @@ -<?php -/** -* -* @package phpBB3 -* @copyright (c) 2011 phpBB Group -* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 -* -*/ - -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** -* Provides a style resource locator with core style paths and extension style paths -* -* Finds installed style paths and makes them available to the resource locator. -* -* @package phpBB3 -*/ -class phpbb_style_extension_path_provider extends phpbb_extension_provider implements phpbb_style_path_provider_interface -{ - /** - * Optional prefix for style paths searched within extensions. - * - * Empty by default. Relative to the extension directory. As an example, it - * could be adm/ for admin style. - * - * @var string - */ - protected $ext_dir_prefix = ''; - - /** - * A provider of paths to be searched for styles - * @var phpbb_style_path_provider - */ - protected $base_path_provider; - - /** @var string */ - protected $phpbb_root_path; - - /** - * Constructor stores extension manager - * - * @param phpbb_extension_manager $extension_manager phpBB extension manager - * @param phpbb_style_path_provider $base_path_provider A simple path provider - * to provide paths to be located in extensions - * @param string $phpbb_root_path phpBB root path - */ - public function __construct(phpbb_extension_manager $extension_manager, phpbb_style_path_provider $base_path_provider, $phpbb_root_path) - { - parent::__construct($extension_manager); - $this->base_path_provider = $base_path_provider; - $this->phpbb_root_path = $phpbb_root_path; - } - - /** - * Sets a prefix for style paths searched within extensions. - * - * The prefix is inserted between the extension's path e.g. ext/foo/ and - * the looked up style path, e.g. styles/bar/. So it should not have a - * leading slash, but should have a trailing slash. - * - * @param string $ext_dir_prefix The prefix including trailing slash - * @return null - */ - public function set_ext_dir_prefix($ext_dir_prefix) - { - $this->ext_dir_prefix = $ext_dir_prefix; - } - - /** - * Finds style paths using the extension manager - * - * Locates a path (e.g. styles/prosilver/) in all active extensions. - * Then appends the core style paths based in the current working - * directory. - * - * @return array List of style paths - */ - public function find() - { - $directories = array(); - - $finder = $this->extension_manager->get_finder(); - foreach ($this->base_path_provider as $key => $paths) - { - if ($key == 'style') - { - foreach ($paths as $path) - { - $directories['style'][] = $path; - if ($path && !phpbb_is_absolute($path)) - { - // Remove phpBB root path from the style path, - // so the finder is able to find extension styles, - // when the root path is not ./ - if (strpos($path, $this->phpbb_root_path) === 0) - { - $path = substr($path, strlen($this->phpbb_root_path)); - } - - $result = $finder->directory('/' . $this->ext_dir_prefix . $path) - ->get_directories(true, false, true); - foreach ($result as $ext => $ext_path) - { - // Make sure $ext_path has no ending slash - if (substr($ext_path, -1) === '/') - { - $ext_path = substr($ext_path, 0, -1); - } - $directories[$ext][] = $ext_path; - } - } - } - } - } - - return $directories; - } - - /** - * Overwrites the current style paths - * - * @param array $styles An array of style paths. The first element is the main style. - * @return null - */ - public function set_styles(array $styles) - { - $this->base_path_provider->set_styles($styles); - $this->items = null; - } -} diff --git a/phpBB/phpbb/style/path_provider.php b/phpBB/phpbb/style/path_provider.php deleted file mode 100644 index 731d682e88..0000000000 --- a/phpBB/phpbb/style/path_provider.php +++ /dev/null @@ -1,62 +0,0 @@ -<?php -/** -* -* @package phpBB3 -* @copyright (c) 2011 phpBB Group -* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 -* -*/ - -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** -* Provides a style resource locator with paths -* -* Finds installed style paths and makes them available to the resource locator. -* -* @package phpBB3 -*/ -class phpbb_style_path_provider implements IteratorAggregate, phpbb_style_path_provider_interface -{ - protected $paths = array(); - - /** - * Ignores the extension dir prefix - * - * @param string $ext_dir_prefix The prefix including trailing slash - * @return null - */ - public function set_ext_dir_prefix($ext_dir_prefix) - { - } - - /** - * Overwrites the current style paths - * - * The first element of the passed styles map, is considered the main - * style. - * - * @param array $styles An array of style paths. The first element is the main style. - * @return null - */ - public function set_styles(array $styles) - { - $this->paths = array('style' => $styles); - } - - /** - * Retrieve an iterator over all style paths - * - * @return ArrayIterator An iterator for the array of style paths - */ - public function getIterator() - { - return new ArrayIterator($this->paths); - } -} diff --git a/phpBB/phpbb/style/path_provider_interface.php b/phpBB/phpbb/style/path_provider_interface.php deleted file mode 100644 index 1a6153a4d3..0000000000 --- a/phpBB/phpbb/style/path_provider_interface.php +++ /dev/null @@ -1,42 +0,0 @@ -<?php -/** -* -* @package phpBB3 -* @copyright (c) 2011 phpBB Group -* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 -* -*/ - -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** -* Provides a style resource locator with paths -* -* Finds installed style paths and makes them available to the resource locator. -* -* @package phpBB3 -*/ -interface phpbb_style_path_provider_interface extends Traversable -{ - /** - * Defines a prefix to use for style paths in extensions - * - * @param string $ext_dir_prefix The prefix including trailing slash - * @return null - */ - public function set_ext_dir_prefix($ext_dir_prefix); - - /** - * Overwrites the current style paths - * - * @param array $styles An array of style paths. The first element is the main style. - * @return null - */ - public function set_styles(array $styles); -} diff --git a/phpBB/phpbb/style/resource_locator.php b/phpBB/phpbb/style/resource_locator.php deleted file mode 100644 index 4cf767c062..0000000000 --- a/phpBB/phpbb/style/resource_locator.php +++ /dev/null @@ -1,348 +0,0 @@ -<?php -/** -* -* @package phpBB3 -* @copyright (c) 2011 phpBB Group -* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 -* -*/ - -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - - -/** -* Style resource locator. -* Maintains mapping from template handles to source template file paths. -* Locates style files: resources (such as .js and .css files) and templates. -* -* Style resource locator is aware of styles tree, and can return actual -* filesystem paths (i.e., the "child" style or the "parent" styles) -* depending on what files exist. -* -* Root paths stored in locator are paths to style directories. Templates are -* stored in subdirectory that $template_path points to. -* -* @package phpBB3 -*/ -class phpbb_style_resource_locator implements phpbb_template_locator -{ - /** - * Paths to style directories. - * @var array - */ - private $roots = array(); - - /** - * Location of templates directory within style directories. - * Must have trailing slash. Empty if templates are stored in root - * style directory, such as admin control panel templates. - * @var string - */ - private $template_path; - - /** - * Map from root index to handles to source template file paths. - * Normally it only contains paths for handles that are used - * (or are likely to be used) by the page being rendered and not - * all templates that exist on the filesystem. - * @var array - */ - private $files = array(); - - /** - * Map from handles to source template file names. - * Covers the same data as $files property but maps to basenames - * instead of paths. - * @var array - */ - private $filenames = array(); - - /** - * Constructor. - * - * Sets default template path to template/. - */ - public function __construct() - { - $this->set_default_template_path(); - } - - /** - * Sets the list of style paths - * - * These paths will be searched for style files in the provided order. - * Paths may be outside of phpBB, but templates loaded from these paths - * will still be cached. - * - * @param array $style_paths An array of paths to style directories - * @return null - */ - public function set_paths($style_paths) - { - $this->roots = array(); - $this->files = array(); - $this->filenames = array(); - - foreach ($style_paths as $key => $paths) - { - foreach ($paths as $path) - { - // Make sure $path has no ending slash - if (substr($path, -1) === '/') - { - $path = substr($path, 0, -1); - } - $this->roots[$key][] = $path; - } - } - } - - /** - * Sets the location of templates directory within style directories. - * - * The location must be a relative path, with a trailing slash. - * Typically it is one directory level deep, e.g. "template/". - * - * @param string $template_path Relative path to templates directory within style directories - * @return null - */ - public function set_template_path($template_path) - { - $this->template_path = $template_path; - } - - /** - * Sets the location of templates directory within style directories - * to the default, which is "template/". - * - * @return null - */ - public function set_default_template_path() - { - $this->template_path = 'template/'; - } - - /** - * {@inheritDoc} - */ - public function set_filenames(array $filename_array) - { - foreach ($filename_array as $handle => $filename) - { - if (empty($filename)) - { - trigger_error("style resource locator: set_filenames: Empty filename specified for $handle", E_USER_ERROR); - } - - $this->filename[$handle] = $filename; - - foreach ($this->roots as $root_key => $root_paths) - { - foreach ($root_paths as $root_index => $root) - { - $this->files[$root_key][$root_index][$handle] = $root . '/' . $this->template_path . $filename; - } - } - } - } - - /** - * {@inheritDoc} - */ - public function get_filename_for_handle($handle) - { - if (!isset($this->filename[$handle])) - { - trigger_error("style resource locator: get_filename_for_handle: No file specified for handle $handle", E_USER_ERROR); - } - return $this->filename[$handle]; - } - - /** - * {@inheritDoc} - */ - public function get_virtual_source_file_for_handle($handle) - { - // If we don't have a file assigned to this handle, die. - if (!isset($this->files['style'][0][$handle])) - { - trigger_error("style resource locator: No file specified for handle $handle", E_USER_ERROR); - } - - $source_file = $this->files['style'][0][$handle]; - return $source_file; - } - - /** - * {@inheritDoc} - */ - public function get_source_file_for_handle($handle, $find_all = false) - { - // If we don't have a file assigned to this handle, die. - if (!isset($this->files['style'][0][$handle])) - { - trigger_error("style resource locator: No file specified for handle $handle", E_USER_ERROR); - } - - // locate a source file that exists - $source_file = $this->files['style'][0][$handle]; - $tried = $source_file; - $found = false; - $found_all = array(); - foreach ($this->roots as $root_key => $root_paths) - { - foreach ($root_paths as $root_index => $root) - { - $source_file = $this->files[$root_key][$root_index][$handle]; - $tried .= ', ' . $source_file; - if (file_exists($source_file)) - { - $found = true; - break; - } - } - if ($found) - { - if ($find_all) - { - $found_all[] = $source_file; - $found = false; - } - else - { - break; - } - } - } - - // search failed - if (!$found && !$find_all) - { - trigger_error("style resource locator: File for handle $handle does not exist. Could not find: $tried", E_USER_ERROR); - } - - return ($find_all) ? $found_all : $source_file; - } - - /** - * {@inheritDoc} - */ - public function get_first_file_location($files, $return_default = false, $return_full_path = true) - { - // set default value - $default_result = false; - - // check all available paths - foreach ($this->roots as $root_paths) - { - foreach ($root_paths as $path) - { - // check all files - foreach ($files as $filename) - { - $source_file = $path . '/' . $filename; - if (file_exists($source_file)) - { - return ($return_full_path) ? $source_file : $filename; - } - - // assign first file as result if $return_default is true - if ($return_default && $default_result === false) - { - $default_result = $source_file; - } - } - } - } - - // search failed - return $default_result; - } - - /** - * Obtains filesystem path for a template file. - * - * The simplest use is specifying a single template file as a string - * in the first argument. This template file should be a basename - * of a template file in the selected style, or its parent styles - * if template inheritance is being utilized. - * - * Note: "selected style" is whatever style the style resource locator - * is configured for. - * - * The return value then will be a path, relative to the current - * directory or absolute, to the template file in the selected style - * or its closest parent. - * - * If the selected style does not have the template file being searched, - * (and if inheritance is involved, none of the parents have it either), - * false will be returned. - * - * Specifying true for $return_default will cause the function to - * return the first path which was checked for existence in the event - * that the template file was not found, instead of false. - * This is the path in the selected style itself, not any of its - * parents. - * - * $files can be given an array of templates instead of a single - * template. When given an array, the function will try to resolve - * each template in the array to a path, and will return the first - * path that exists, or false if none exist. - * - * If $files is an array and template inheritance is involved, first - * each of the files will be checked in the selected style, then each - * of the files will be checked in the immediate parent, and so on. - * - * If $return_full_path is false, then instead of returning a usable - * path (when the template is found) only the template's basename - * will be returned. This can be used to check which of the templates - * specified in $files exists. Naturally more than one template must - * be given in $files. - * - * This function works identically to get_first_file_location except - * it operates on a list of templates, not files. Practically speaking, - * the templates given in the first argument first are prepended with - * the template path (property in this class), then given to - * get_first_file_location for the rest of the processing. - * - * Templates given to this function can be relative paths for templates - * located in subdirectories of the template directories. The paths - * should be relative to the templates directory (template/ by default). - * - * @param string or array $files List of templates to locate. If there is only - * one template, $files can be a string to make code easier to read. - * @param bool $return_default Determines what to return if template does not - * exist. If true, function will return location where template is - * supposed to be. If false, function will return false. - * @param bool $return_full_path If true, function will return full path - * to template. If false, function will return template file name. - * This parameter can be used to check which one of set of template - * files is available. - * @return string or boolean Source template path if template exists or $return_default is - * true. False if template does not exist and $return_default is false - */ - public function get_first_template_location($templates, $return_default = false, $return_full_path = true) - { - // add template path prefix - $files = array(); - if (is_string($templates)) - { - $files[] = $this->template_path . $templates; - } - else - { - foreach ($templates as $template) - { - $files[] = $this->template_path . $template; - } - } - - return $this->get_first_file_location($files, $return_default, $return_full_path); - } -} diff --git a/phpBB/phpbb/style/style.php b/phpBB/phpbb/style/style.php deleted file mode 100644 index 034f518091..0000000000 --- a/phpBB/phpbb/style/style.php +++ /dev/null @@ -1,241 +0,0 @@ -<?php -/** -* -* @package phpBB3 -* @copyright (c) 2005 phpBB Group, sections (c) 2001 ispi of Lincoln Inc -* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 -* -*/ - -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** -* Base Style class. -* @package phpBB3 -*/ -class phpbb_style -{ - /** - * Template class. - * Handles everything related to templates. - * @var phpbb_template - */ - private $template; - - /** - * phpBB root path - * @var string - */ - private $phpbb_root_path; - - /** - * PHP file extension - * @var string - */ - private $php_ext; - - /** - * phpBB config instance - * @var phpbb_config - */ - private $config; - - /** - * Current user - * @var phpbb_user - */ - private $user; - - /** - * Style resource locator - * @var phpbb_style_resource_locator - */ - private $locator; - - /** - * Style path provider - * @var phpbb_style_path_provider - */ - private $provider; - - /** - * Constructor. - * - * @param string $phpbb_root_path phpBB root path - * @param user $user current user - * @param phpbb_style_resource_locator $locator style resource locator - * @param phpbb_style_path_provider $provider style path provider - * @param phpbb_template $template template - */ - public function __construct($phpbb_root_path, $php_ext, $config, $user, phpbb_style_resource_locator $locator, phpbb_style_path_provider_interface $provider, phpbb_template $template) - { - $this->phpbb_root_path = $phpbb_root_path; - $this->php_ext = $php_ext; - $this->config = $config; - $this->user = $user; - $this->locator = $locator; - $this->provider = $provider; - $this->template = $template; - } - - /** - * Get the style tree of the style preferred by the current user - * - * @return array Style tree, most specific first - */ - public function get_user_style() - { - $style_list = array( - $this->user->style['style_path'], - ); - - if ($this->user->style['style_parent_id']) - { - $style_list = array_merge($style_list, array_reverse(explode('/', $this->user->style['style_parent_tree']))); - } - - return $style_list; - } - - /** - * Set style location based on (current) user's chosen style. - * - * @param array $style_directories The directories to add style paths for - * E.g. array('ext/foo/bar/styles', 'styles') - * Default: array('styles') (phpBB's style directory) - * @return bool true - */ - public function set_style($style_directories = array('styles')) - { - $this->names = $this->get_user_style(); - - $paths = array(); - foreach ($style_directories as $directory) - { - foreach ($this->names as $name) - { - $path = $this->get_style_path($name, $directory); - - if (is_dir($path)) - { - $paths[] = $path; - } - } - } - - $this->provider->set_styles($paths); - $this->locator->set_paths($this->provider); - - $new_paths = array(); - foreach ($paths as $path) - { - $new_paths[] = $path . '/template/'; - } - - $this->template->set_style_names($this->names, $new_paths, ($style_directories === array('styles'))); - - return true; - } - - /** - * Set custom style location (able to use directory outside of phpBB). - * - * Note: Templates are still compiled to phpBB's cache directory. - * - * @param string $name Name of style, used for cache prefix. Examples: "admin", "prosilver" - * @param array or string $paths Array of style paths, relative to current root directory - * @param array $names Array of names of templates in inheritance tree order, used by extensions. If empty, $name will be used. - * @param string $template_path Path to templates, relative to style directory. False if path should be set to default (templates/). - * @return bool true - */ - public function set_custom_style($name, $paths, $names = array(), $template_path = false) - { - if (is_string($paths)) - { - $paths = array($paths); - } - - if (empty($names)) - { - $names = array($name); - } - $this->names = $names; - - $this->provider->set_styles($paths); - $this->locator->set_paths($this->provider); - - if ($template_path !== false) - { - $this->locator->set_template_path($template_path); - } - - $new_paths = array(); - foreach ($paths as $path) - { - $new_paths[] = $path . '/' . (($template_path !== false) ? $template_path : 'template/'); - } - - $this->template->set_style_names($names, $new_paths); - - return true; - } - - /** - * Get location of style directory for specific style_path - * - * @param string $path Style path, such as "prosilver" - * @param string $style_base_directory The base directory the style is in - * E.g. 'styles', 'ext/foo/bar/styles' - * Default: 'styles' - * @return string Path to style directory, relative to current path - */ - public function get_style_path($path, $style_base_directory = 'styles') - { - return $this->phpbb_root_path . trim($style_base_directory, '/') . '/' . $path; - } - - /** - * Defines a prefix to use for style paths in extensions - * - * @param string $ext_dir_prefix The prefix including trailing slash - * @return null - */ - public function set_ext_dir_prefix($ext_dir_prefix) - { - $this->provider->set_ext_dir_prefix($ext_dir_prefix); - } - - /** - * Locates source file path, accounting for styles tree and verifying that - * the path exists. - * - * @param string or array $files List of files to locate. If there is only - * one file, $files can be a string to make code easier to read. - * @param bool $return_default Determines what to return if file does not - * exist. If true, function will return location where file is - * supposed to be. If false, function will return false. - * @param bool $return_full_path If true, function will return full path - * to file. If false, function will return file name. This - * parameter can be used to check which one of set of files - * is available. - * @return string or boolean Source file path if file exists or $return_default is - * true. False if file does not exist and $return_default is false - */ - public function locate($files, $return_default = false, $return_full_path = true) - { - // convert string to array - if (is_string($files)) - { - $files = array($files); - } - - // use resource locator to find files - return $this->locator->get_first_file_location($files, $return_default, $return_full_path); - } -} diff --git a/phpBB/phpbb/template/base.php b/phpBB/phpbb/template/base.php new file mode 100644 index 0000000000..3778424a96 --- /dev/null +++ b/phpBB/phpbb/template/base.php @@ -0,0 +1,148 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +abstract class phpbb_template_base implements phpbb_template +{ + /** + * Template context. + * Stores template data used during template rendering. + * + * @var phpbb_template_context + */ + protected $context; + + /** + * Array of filenames assigned to set_filenames + * + * @var array + */ + protected $filenames = array(); + + /** + * {@inheritdoc} + */ + public function set_filenames(array $filename_array) + { + $this->filenames = array_merge($this->filenames, $filename_array); + + return $this; + } + + /** + * Get a filename from the handle + * + * @param string $handle + * @return string + */ + protected function get_filename_from_handle($handle) + { + return (isset($this->filenames[$handle])) ? $this->filenames[$handle] : $handle; + } + + /** + * {@inheritdoc} + */ + public function destroy() + { + $this->context->clear(); + + return $this; + } + + /** + * {@inheritdoc} + */ + public function destroy_block_vars($blockname) + { + $this->context->destroy_block_vars($blockname); + + return $this; + } + + /** + * {@inheritdoc} + */ + public function assign_vars(array $vararray) + { + foreach ($vararray as $key => $val) + { + $this->assign_var($key, $val); + } + + return $this; + } + + /** + * {@inheritdoc} + */ + public function assign_var($varname, $varval) + { + $this->context->assign_var($varname, $varval); + + return $this; + } + + /** + * {@inheritdoc} + */ + public function append_var($varname, $varval) + { + $this->context->append_var($varname, $varval); + + return $this; + } + + /** + * {@inheritdoc} + */ + public function assign_block_vars($blockname, array $vararray) + { + $this->context->assign_block_vars($blockname, $vararray); + + return $this; + } + + /** + * {@inheritdoc} + */ + public function alter_block_array($blockname, array $vararray, $key = false, $mode = 'insert') + { + return $this->context->alter_block_array($blockname, $vararray, $key, $mode); + } + + /** + * Calls hook if any is defined. + * + * @param string $handle Template handle being displayed. + * @param string $method Method name of the caller. + */ + protected function call_hook($handle, $method) + { + global $phpbb_hook; + + if (!empty($phpbb_hook) && $phpbb_hook->call_hook(array(__CLASS__, $method), $handle, $this)) + { + if ($phpbb_hook->hook_return(array(__CLASS__, $method))) + { + $result = $phpbb_hook->hook_return_result(array(__CLASS__, $method)); + return array($result); + } + } + + return false; + } +} diff --git a/phpBB/phpbb/template/locator.php b/phpBB/phpbb/template/locator.php deleted file mode 100644 index f6fd20bcc2..0000000000 --- a/phpBB/phpbb/template/locator.php +++ /dev/null @@ -1,163 +0,0 @@ -<?php -/** -* -* @package phpBB3 -* @copyright (c) 2011 phpBB Group -* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 -* -*/ - -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - - -/** -* Resource locator interface. -* -* Objects implementing this interface maintain mapping from template handles -* to source template file paths and locate templates. -* -* Locates style files. -* -* Resource locator is aware of styles tree, and can return actual -* filesystem paths (i.e., the "child" style or the "parent" styles) -* depending on what files exist. -* -* Root paths stored in locator are paths to style directories. Templates are -* stored in subdirectory that $template_path points to. -* -* @package phpBB3 -*/ -interface phpbb_template_locator -{ - /** - * Sets the template filenames for handles. $filename_array - * should be a hash of handle => filename pairs. - * - * @param array $filename_array Should be a hash of handle => filename pairs. - */ - public function set_filenames(array $filename_array); - - /** - * Determines the filename for a template handle. - * - * The filename comes from array used in a set_filenames call, - * which should have been performed prior to invoking this function. - * Return value is a file basename (without path). - * - * @param $handle string Template handle - * @return string Filename corresponding to the template handle - */ - public function get_filename_for_handle($handle); - - /** - * Determines the source file path for a template handle without - * regard for styles tree. - * - * This function returns the path in "primary" style directory - * corresponding to the given template handle. That path may or - * may not actually exist on the filesystem. Because this function - * does not perform stat calls to determine whether the path it - * returns actually exists, it is faster than get_source_file_for_handle. - * - * Use get_source_file_for_handle to obtain the actual path that is - * guaranteed to exist (which might come from the parent style - * directory if primary style has parent styles). - * - * This function will trigger an error if the handle was never - * associated with a template file via set_filenames. - * - * @param $handle string Template handle - * @return string Path to source file path in primary style directory - */ - public function get_virtual_source_file_for_handle($handle); - - /** - * Determines the source file path for a template handle, accounting - * for styles tree and verifying that the path exists. - * - * This function returns the actual path that may be compiled for - * the specified template handle. It will trigger an error if - * the template handle was never associated with a template path - * via set_filenames or if the template file does not exist on the - * filesystem. - * - * Use get_virtual_source_file_for_handle to just resolve a template - * handle to a path without any filesystem or styles tree checks. - * - * @param string $handle Template handle (i.e. "friendly" template name) - * @param bool $find_all If true, each root path will be checked and function - * will return array of files instead of string and will not - * trigger a error if template does not exist - * @return string Source file path - */ - public function get_source_file_for_handle($handle, $find_all = false); - - /** - * Obtains a complete filesystem path for a file in a style. - * - * This function traverses the style tree (selected style and - * its parents in order, if inheritance is being used) and finds - * the first file on the filesystem matching specified relative path, - * or the first of the specified paths if more than one path is given. - * - * This function can be used to determine filesystem path of any - * file under any style, with the consequence being that complete - * relative to the style directory path must be provided as an argument. - * - * In particular, this function can be used to locate templates - * and javascript files. - * - * For locating templates get_first_template_location should be used - * as it prepends the configured template path to the template basename. - * - * Note: "selected style" is whatever style the style resource locator - * is configured for. - * - * The return value then will be a path, relative to the current - * directory or absolute, to the first existing file in the selected - * style or its closest parent. - * - * If the selected style does not have the file being searched, - * (and if inheritance is involved, none of the parents have it either), - * false will be returned. - * - * Multiple files can be specified, in which case the first file in - * the list that can be found on the filesystem is returned. - * - * If multiple files are specified and inheritance is involved, - * first each of the specified files is checked in the selected style, - * then each of the specified files is checked in the immediate parent, - * etc. - * - * Specifying true for $return_default will cause the function to - * return the first path which was checked for existence in the event - * that the template file was not found, instead of false. - * This is always a path in the selected style itself, not any of its - * parents. - * - * If $return_full_path is false, then instead of returning a usable - * path (when the file is found) the file's path relative to the style - * directory will be returned. This is the same path as was given to - * the function as a parameter. This can be used to check which of the - * files specified in $files exists. Naturally this requires passing - * more than one file in $files. - * - * @param array $files List of files to locate. - * @param bool $return_default Determines what to return if file does not - * exist. If true, function will return location where file is - * supposed to be. If false, function will return false. - * @param bool $return_full_path If true, function will return full path - * to file. If false, function will return file name. This - * parameter can be used to check which one of set of files - * is available. - * @return string or boolean Source file path if file exists or $return_default is - * true. False if file does not exist and $return_default is false - */ - public function get_first_file_location($files, $return_default = false, $return_full_path = true); -} diff --git a/phpBB/phpbb/template/template.php b/phpBB/phpbb/template/template.php index 89a01e924d..6b9c331a3e 100644 --- a/phpBB/phpbb/template/template.php +++ b/phpBB/phpbb/template/template.php @@ -34,14 +34,32 @@ interface phpbb_template public function set_filenames(array $filename_array); /** - * Sets the style names/paths corresponding to style hierarchy being compiled - * and/or rendered. + * Get the style tree of the style preferred by the current user * - * @param array $style_names List of style names in inheritance tree order - * @param array $style_paths List of style paths in inheritance tree order + * @return array Style tree, most specific first + */ + public function get_user_style(); + + /** + * Set style location based on (current) user's chosen style. + * + * @param array $style_directories The directories to add style paths for + * E.g. array('ext/foo/bar/styles', 'styles') + * Default: array('styles') (phpBB's style directory) + * @return phpbb_template $this + */ + public function set_style($style_directories = array('styles')); + + /** + * Set custom style location (able to use directory outside of phpBB). + * + * Note: Templates are still compiled to phpBB's cache directory. + * + * @param string|array $names Array of names or string of name of template(s) in inheritance tree order, used by extensions. + * @param string|array or string $paths Array of style paths, relative to current root directory * @return phpbb_template $this */ - public function set_style_names(array $style_names, array $style_paths); + public function set_custom_style($names, $paths); /** * Clears all variables and blocks assigned to this template. diff --git a/phpBB/phpbb/template/twig/environment.php b/phpBB/phpbb/template/twig/environment.php index b60cd72325..9a40dc2b15 100644 --- a/phpBB/phpbb/template/twig/environment.php +++ b/phpBB/phpbb/template/twig/environment.php @@ -137,4 +137,39 @@ class phpbb_template_twig_environment extends Twig_Environment return parent::loadTemplate($name, $index); } } + + /** + * Finds a template by name. + * + * @param string $name The template name + * @return string + */ + public function findTemplate($name) + { + if (strpos($name, '@') === false) + { + foreach ($this->getNamespaceLookUpOrder() as $namespace) + { + try + { + if ($namespace === '__main__') + { + return parent::getLoader()->getCacheKey($name); + } + + return parent::getLoader()->getCacheKey('@' . $namespace . '/' . $name); + } + catch (Twig_Error_Loader $e) + { + } + } + + // We were unable to load any templates + throw $e; + } + else + { + return parent::getLoader()->getCacheKey($name); + } + } } diff --git a/phpBB/phpbb/template/twig/lexer.php b/phpBB/phpbb/template/twig/lexer.php index 4f88147542..8b72a06642 100644 --- a/phpBB/phpbb/template/twig/lexer.php +++ b/phpBB/phpbb/template/twig/lexer.php @@ -75,7 +75,7 @@ class phpbb_template_twig_lexer extends Twig_Lexer // Fix tokens that may have inline variables (e.g. <!-- DEFINE $TEST = '{FOO}') $code = $this->fix_inline_variable_tokens(array( - 'DEFINE.+=', + 'DEFINE \$[a-zA-Z0-9]+ =', 'INCLUDE', 'INCLUDEPHP', 'INCLUDEJS', @@ -130,7 +130,7 @@ class phpbb_template_twig_lexer extends Twig_Lexer // E.g. 'asdf'"' -> asdf'" // E.g. "asdf'"" -> asdf'" // E.g. 'asdf'" -> 'asdf'" - $matches[2] = preg_replace('#^([\'"])?(.+?)\1$#', '$2', $matches[2]); + $matches[2] = preg_replace('#^([\'"])?(.*?)\1$#', '$2', $matches[2]); // Replace template variables with start/end to parse variables (' ~ TEST ~ '.html) $matches[2] = preg_replace('#{([a-zA-Z0-9_\.$]+)}#', "'~ \$1 ~'", $matches[2]); @@ -161,6 +161,9 @@ class phpbb_template_twig_lexer extends Twig_Lexer $subset = trim(substr($matches[2], 1, -1)); // Remove parenthesis $body = $matches[3]; + // Replace <!-- BEGINELSE --> + $body = str_replace('<!-- BEGINELSE -->', '{% else %}', $body); + // Is the designer wanting to call another loop in a loop? // <!-- BEGIN loop --> // <!-- BEGIN !loop2 --> @@ -191,25 +194,20 @@ class phpbb_template_twig_lexer extends Twig_Lexer // Recursive...fix any child nodes $body = $parent_class->fix_begin_tokens($body, $parent_nodes); - // Rename loopname vars (to prevent collisions, loop children are named (loop name)_loop_element) - $body = str_replace($name . '.', $name . '_loop_element.', $body); - // Need the parent variable name array_pop($parent_nodes); - $parent = (!empty($parent_nodes)) ? end($parent_nodes) . '_loop_element.' : ''; + $parent = (!empty($parent_nodes)) ? end($parent_nodes) . '.' : ''; if ($subset !== '') { $subset = '|subset(' . $subset . ')'; } - // Turn into a Twig for loop, using (loop name)_loop_element for each child - return "{% for {$name}_loop_element in {$parent}{$name}{$subset} %}{$body}{% endfor %}"; + $parent = ($parent) ?: 'loops.'; + // Turn into a Twig for loop + return "{% for {$name} in {$parent}{$name}{$subset} %}{$body}{% endfor %}"; }; - // Replace <!-- BEGINELSE --> correctly, only needs to be done once - $code = str_replace('<!-- BEGINELSE -->', '{% else %}', $code); - return preg_replace_callback('#<!-- BEGIN ([!a-zA-Z0-9_]+)(\([0-9,\-]+\))? -->(.+?)<!-- END \1 -->#s', $callback, $code); } @@ -221,22 +219,28 @@ class phpbb_template_twig_lexer extends Twig_Lexer */ protected function fix_if_tokens($code) { + // Replace ELSE IF with ELSEIF + $code = preg_replace('#<!-- ELSE IF (.+?) -->#', '<!-- ELSEIF $1 -->', $code); + + // Replace our "div by" with Twig's divisibleby (Twig does not like test names with spaces) + $code = preg_replace('# div by ([0-9]+)#', ' divisibleby($1)', $code); + $callback = function($matches) { $inner = $matches[2]; // Replace $TEST with definition.TEST - $inner = preg_replace('#\s\$([a-zA-Z_0-9]+)#', ' definition.$1', $inner); + $inner = preg_replace('#(\s\(?!?)\$([a-zA-Z_0-9]+)#', '$1definition.$2', $inner); + + // Replace .foo with loops.foo|length + $inner = preg_replace('#(\s\(?!?)\.([a-zA-Z_0-9]+)([^a-zA-Z_0-9\.])#', '$1loops.$2|length$3', $inner); - // Replace .test with test|length - $inner = preg_replace('#\s\.([a-zA-Z_0-9\.]+)#', ' $1|length', $inner); + // Replace .foo.bar with foo.bar|length + $inner = preg_replace('#(\s\(?!?)\.([a-zA-Z_0-9\.]+)([^a-zA-Z_0-9\.])#', '$1$2|length$3', $inner); return "<!-- {$matches[1]}IF{$inner}-->"; }; - // Replace our "div by" with Twig's divisibleby (Twig does not like test names with spaces) - $code = preg_replace('# div by ([0-9]+)#', ' divisibleby($1)', $code); - - return preg_replace_callback('#<!-- (ELSE)?IF((.*)[\s][\$|\.|!]([^\s]+)(.*))-->#', $callback, $code); + return preg_replace_callback('#<!-- (ELSE)?IF((.*?) \(?!?[\$|\.]([^\s]+)(.*?))-->#', $callback, $code); } /** @@ -260,10 +264,10 @@ class phpbb_template_twig_lexer extends Twig_Lexer */ // Replace <!-- DEFINE $NAME with {% DEFINE definition.NAME - $code = preg_replace('#<!-- DEFINE \$(.*)-->#', '{% DEFINE $1 %}', $code); + $code = preg_replace('#<!-- DEFINE \$(.*?) -->#', '{% DEFINE $1 %}', $code); // Changing UNDEFINE NAME to DEFINE NAME = null to save from creating an extra token parser/node - $code = preg_replace('#<!-- UNDEFINE \$(.*)-->#', '{% DEFINE $1= null %}', $code); + $code = preg_replace('#<!-- UNDEFINE \$(.*?)-->#', '{% DEFINE $1= null %}', $code); // Replace all of our variables, {$VARNAME}, with Twig style, {{ definition.VARNAME }} $code = preg_replace('#{\$([a-zA-Z0-9_\.]+)}#', '{{ definition.$1 }}', $code); diff --git a/phpBB/phpbb/template/twig/node/event.php b/phpBB/phpbb/template/twig/node/event.php index 971dea14fa..c94e5fdf20 100644 --- a/phpBB/phpbb/template/twig/node/event.php +++ b/phpBB/phpbb/template/twig/node/event.php @@ -18,6 +18,12 @@ if (!defined('IN_PHPBB')) class phpbb_template_twig_node_event extends Twig_Node { + /** + * The subdirectory in which all template listener files must be placed + * @var string + */ + protected $listener_directory = 'event/'; + /** @var Twig_Environment */ protected $environment; @@ -37,7 +43,7 @@ class phpbb_template_twig_node_event extends Twig_Node { $compiler->addDebugInfo($this); - $location = $this->getNode('expr')->getAttribute('name'); + $location = $this->listener_directory . $this->getNode('expr')->getAttribute('name'); foreach ($this->environment->get_phpbb_extensions() as $ext_namespace => $ext_path) { diff --git a/phpBB/phpbb/template/twig/node/includeasset.php b/phpBB/phpbb/template/twig/node/includeasset.php index 1cab416c79..0808e2b10e 100644 --- a/phpBB/phpbb/template/twig/node/includeasset.php +++ b/phpBB/phpbb/template/twig/node/includeasset.php @@ -40,10 +40,10 @@ abstract class phpbb_template_twig_node_includeasset extends Twig_Node ->write("\$local_file = \$this->getEnvironment()->get_phpbb_root_path() . \$asset_path;\n") ->write("if (!file_exists(\$local_file)) {\n") ->indent() - ->write("\$local_file = \$this->getEnvironment()->getLoader()->getCacheKey(\$asset_path);\n") + ->write("\$local_file = \$this->getEnvironment()->findTemplate(\$asset_path);\n") ->write("\$asset->set_path(\$local_file, true);\n") ->outdent() - ->write("\$asset->add_assets_version({$config['assets_version']});\n") + ->write("\$asset->add_assets_version('{$config['assets_version']}');\n") ->write("\$asset_file = \$asset->get_url();\n") ->write("}\n") ->outdent() diff --git a/phpBB/phpbb/template/twig/twig.php b/phpBB/phpbb/template/twig/twig.php index 92a37d1634..1ed89d3ccc 100644 --- a/phpBB/phpbb/template/twig/twig.php +++ b/phpBB/phpbb/template/twig/twig.php @@ -19,16 +19,9 @@ if (!defined('IN_PHPBB')) * Twig Template class. * @package phpBB3 */ -class phpbb_template_twig implements phpbb_template +class phpbb_template_twig extends phpbb_template_base { /** - * Template context. - * Stores template data used during template rendering. - * @var phpbb_template_context - */ - protected $context; - - /** * Path of the cache directory for the template * * Cannot be changed during runtime. @@ -44,12 +37,6 @@ class phpbb_template_twig implements phpbb_template protected $phpbb_root_path; /** - * adm relative path - * @var string - */ - protected $adm_relative_path; - - /** * PHP file extension * @var string */ @@ -75,16 +62,6 @@ class phpbb_template_twig implements phpbb_template protected $extension_manager; /** - * Name of the style that the template being compiled and/or rendered - * belongs to, and its parents, in inheritance tree order. - * - * Used to invoke style-specific template events. - * - * @var array - */ - protected $style_names; - - /** * Twig Environment * * @var Twig_Environment @@ -92,13 +69,6 @@ class phpbb_template_twig implements phpbb_template protected $twig; /** - * Array of filenames assigned to set_filenames - * - * @var array - */ - protected $filenames = array(); - - /** * Constructor. * * @param string $phpbb_root_path phpBB root path @@ -112,7 +82,6 @@ class phpbb_template_twig implements phpbb_template public function __construct($phpbb_root_path, $php_ext, $config, $user, phpbb_template_context $context, phpbb_extension_manager $extension_manager = null, $adm_relative_path = null) { $this->phpbb_root_path = $phpbb_root_path; - $this->adm_relative_path = $adm_relative_path; $this->php_ext = $php_ext; $this->config = $config; $this->user = $user; @@ -147,6 +116,12 @@ class phpbb_template_twig implements phpbb_template $lexer = new phpbb_template_twig_lexer($this->twig); $this->twig->setLexer($lexer); + + // Add admin namespace + if ($adm_relative_path !== null && is_dir($this->phpbb_root_path . $adm_relative_path . 'style/')) + { + $this->twig->getLoader()->setPaths($this->phpbb_root_path . $adm_relative_path . 'style/', 'admin'); + } } /** @@ -165,51 +140,90 @@ class phpbb_template_twig implements phpbb_template } /** - * Sets the template filenames for handles. + * Get the style tree of the style preferred by the current user * - * @param array $filename_array Should be a hash of handle => filename pairs. - * @return phpbb_template $this + * @return array Style tree, most specific first */ - public function set_filenames(array $filename_array) + public function get_user_style() { - $this->filenames = array_merge($this->filenames, $filename_array); + $style_list = array( + $this->user->style['style_path'], + ); - return $this; + if ($this->user->style['style_parent_id']) + { + $style_list = array_merge($style_list, array_reverse(explode('/', $this->user->style['style_parent_tree']))); + } + + return $style_list; } /** - * Sets the style names/paths corresponding to style hierarchy being compiled - * and/or rendered. + * Set style location based on (current) user's chosen style. * - * @param array $style_names List of style names in inheritance tree order - * @param array $style_paths List of style paths in inheritance tree order - * @param bool $is_core True if the style names are the "core" styles for this page load - * Core means the main phpBB template files + * @param array $style_directories The directories to add style paths for + * E.g. array('ext/foo/bar/styles', 'styles') + * Default: array('styles') (phpBB's style directory) * @return phpbb_template $this */ - public function set_style_names(array $style_names, array $style_paths, $is_core = false) + public function set_style($style_directories = array('styles')) { - $this->style_names = $style_names; + if ($style_directories !== array('styles') && $this->twig->getLoader()->getPaths('core') === array()) + { + // We should set up the core styles path since not already setup + $this->set_style(); + } - // Set as __main__ namespace - $this->twig->getLoader()->setPaths($style_paths); + $names = $this->get_user_style(); - // Core style namespace from phpbb_style::set_style() - if ($is_core) + $paths = array(); + foreach ($style_directories as $directory) { - $this->twig->getLoader()->setPaths($style_paths, 'core'); + foreach ($names as $name) + { + $path = $this->phpbb_root_path . trim($directory, '/') . "/{$name}/template/"; + + if (is_dir($path)) + { + $paths[] = $path; + } + } } - // Add admin namespace - if (is_dir($this->phpbb_root_path . $this->adm_relative_path . 'style/')) + // If we're setting up the main phpBB styles directory and the core + // namespace isn't setup yet, we will set it up now + if ($style_directories === array('styles') && $this->twig->getLoader()->getPaths('core') === array()) { - $this->twig->getLoader()->setPaths($this->phpbb_root_path . $this->adm_relative_path . 'style/', 'admin'); + // Set up the core style paths namespace + $this->twig->getLoader()->setPaths($paths, 'core'); } + $this->set_custom_style($names, $paths); + + return $this; + } + + /** + * Set custom style location (able to use directory outside of phpBB). + * + * Note: Templates are still compiled to phpBB's cache directory. + * + * @param string|array $names Array of names or string of name of template(s) in inheritance tree order, used by extensions. + * @param string|array or string $paths Array of style paths, relative to current root directory + * @return phpbb_template $this + */ + public function set_custom_style($names, $paths) + { + $paths = (is_string($paths)) ? array($paths) : $paths; + $names = (is_string($names)) ? array($names) : $names; + + // Set as __main__ namespace + $this->twig->getLoader()->setPaths($paths); + // Add all namespaces for all extensions if ($this->extension_manager instanceof phpbb_extension_manager) { - $style_names[] = 'all'; + $names[] = 'all'; foreach ($this->extension_manager->all_enabled() as $ext_namespace => $ext_path) { @@ -217,7 +231,7 @@ class phpbb_template_twig implements phpbb_template $namespace = str_replace('/', '_', $ext_namespace); $paths = array(); - foreach ($style_names as $style_name) + foreach ($names as $style_name) { $ext_style_path = $ext_path . 'styles/' . $style_name . '/template'; @@ -235,31 +249,6 @@ class phpbb_template_twig implements phpbb_template } /** - * Clears all variables and blocks assigned to this template. - * - * @return phpbb_template $this - */ - public function destroy() - { - $this->context = array(); - - return $this; - } - - /** - * Reset/empty complete block - * - * @param string $blockname Name of block to destroy - * @return phpbb_template $this - */ - public function destroy_block_vars($blockname) - { - $this->context->destroy_block_vars($blockname); - - return $this; - } - - /** * Display a template for provided handle. * * The template will be loaded and compiled, if necessary, first. @@ -283,28 +272,6 @@ class phpbb_template_twig implements phpbb_template } /** - * Calls hook if any is defined. - * - * @param string $handle Template handle being displayed. - * @param string $method Method name of the caller. - */ - protected function call_hook($handle, $method) - { - global $phpbb_hook; - - if (!empty($phpbb_hook) && $phpbb_hook->call_hook(array(__CLASS__, $method), $handle, $this)) - { - if ($phpbb_hook->hook_return(array(__CLASS__, $method))) - { - $result = $phpbb_hook->hook_return_result(array(__CLASS__, $method)); - return array($result); - } - } - - return false; - } - - /** * Display the handle and assign the output to a template variable * or return the compiled result. * @@ -326,134 +293,30 @@ class phpbb_template_twig implements phpbb_template } /** - * Assign key variable pairs from an array - * - * @param array $vararray A hash of variable name => value pairs - * @return phpbb_template $this - */ - public function assign_vars(array $vararray) - { - foreach ($vararray as $key => $val) - { - $this->assign_var($key, $val); - } - - return $this; - } - - /** - * Assign a single scalar value to a single key. - * - * Value can be a string, an integer or a boolean. - * - * @param string $varname Variable name - * @param string $varval Value to assign to variable - * @return phpbb_template $this - */ - public function assign_var($varname, $varval) - { - $this->context->assign_var($varname, $varval); - - return $this; - } - - /** - * Append text to the string value stored in a key. - * - * Text is appended using the string concatenation operator (.). - * - * @param string $varname Variable name - * @param string $varval Value to append to variable - * @return phpbb_template $this - */ - public function append_var($varname, $varval) - { - $this->context->append_var($varname, $varval); - - return $this; - } - - /** - * Assign key variable pairs from an array to a specified block - * @param string $blockname Name of block to assign $vararray to - * @param array $vararray A hash of variable name => value pairs - * @return phpbb_template $this - */ - public function assign_block_vars($blockname, array $vararray) - { - $this->context->assign_block_vars($blockname, $vararray); - - return $this; - } - - /** - * Change already assigned key variable pair (one-dimensional - single loop entry) - * - * An example of how to use this function: - * {@example alter_block_array.php} - * - * @param string $blockname the blockname, for example 'loop' - * @param array $vararray the var array to insert/add or merge - * @param mixed $key Key to search for - * - * array: KEY => VALUE [the key/value pair to search for within the loop to determine the correct position] - * - * int: Position [the position to change or insert at directly given] - * - * If key is false the position is set to 0 - * If key is true the position is set to the last entry - * - * @param string $mode Mode to execute (valid modes are 'insert' and 'change') - * - * If insert, the vararray is inserted at the given position (position counting from zero). - * If change, the current block gets merged with the vararray (resulting in new key/value pairs be added and existing keys be replaced by the new value). - * - * Since counting begins by zero, inserting at the last position will result in this array: array(vararray, last positioned array) - * and inserting at position 1 will result in this array: array(first positioned array, vararray, following vars) - * - * @return bool false on error, true on success - */ - public function alter_block_array($blockname, array $vararray, $key = false, $mode = 'insert') - { - return $this->context->alter_block_array($blockname, $vararray, $key, $mode); - } - - /** * Get template vars in a format Twig will use (from the context) * * @return array */ - public function get_template_vars() + protected function get_template_vars() { $context_vars = $this->context->get_data_ref(); $vars = array_merge( $context_vars['.'][0], // To get normal vars - $context_vars, // To get loops array( 'definition' => new phpbb_template_twig_definition(), 'user' => $this->user, + 'loops' => $context_vars, // To get loops ) ); // cleanup - unset($vars['.']); + unset($vars['loops']['.']); return $vars; } /** - * Get a filename from the handle - * - * @param string $handle - * @return string - */ - protected function get_filename_from_handle($handle) - { - return (isset($this->filenames[$handle])) ? $this->filenames[$handle] : $handle; - } - - /** * Get path to template for handle (required for BBCode parser) * * @return string diff --git a/phpBB/phpbb/user.php b/phpBB/phpbb/user.php index 5530fe3f03..36120798e5 100644 --- a/phpBB/phpbb/user.php +++ b/phpBB/phpbb/user.php @@ -75,7 +75,7 @@ class phpbb_user extends phpbb_session */ function setup($lang_set = false, $style_id = false) { - global $db, $phpbb_style, $template, $config, $auth, $phpEx, $phpbb_root_path, $cache; + global $db, $template, $config, $auth, $phpEx, $phpbb_root_path, $cache; global $phpbb_dispatcher; if ($this->data['user_id'] != ANONYMOUS) @@ -128,6 +128,7 @@ class phpbb_user extends phpbb_session } $user_data = $this->data; + $lang_set_ext = array(); /** * Event to load language files and modify user data on every page @@ -139,10 +140,18 @@ class phpbb_user extends phpbb_session * @var string user_timezone User's timezone, should be one of * http://www.php.net/manual/en/timezones.php * @var mixed lang_set String or array of language files + * @var array lang_set_ext Array containing entries of format + * array( + * 'ext_name' => (string) [extension name], + * 'lang_set' => (string|array) [language files], + * ) + * For performance reasons, only load translations + * that are absolutely needed globally using this + * event. Use local events otherwise. * @var mixed style_id Style we are going to display * @since 3.1-A1 */ - $vars = array('user_data', 'user_lang_name', 'user_date_format', 'user_timezone', 'lang_set', 'style_id'); + $vars = array('user_data', 'user_lang_name', 'user_date_format', 'user_timezone', 'lang_set', 'lang_set_ext', 'style_id'); extract($phpbb_dispatcher->trigger_event('core.user_setup', compact($vars))); $this->data = $user_data; @@ -173,6 +182,12 @@ class phpbb_user extends phpbb_session $this->add_lang($lang_set); unset($lang_set); + foreach ($lang_set_ext as $ext_lang_pair) + { + $this->add_lang_ext($ext_lang_pair['ext_name'], $ext_lang_pair['lang_set']); + } + unset($lang_set_ext); + $style_request = request_var('style', 0); if ($style_request && $auth->acl_get('a_styles') && !defined('ADMIN_START')) { @@ -236,7 +251,7 @@ class phpbb_user extends phpbb_session } } - $phpbb_style->set_style(); + $template->set_style(); $this->img_lang = $this->lang_name; @@ -590,6 +605,13 @@ class phpbb_user extends phpbb_session $language_filename = $lang_path . $this->lang_name . '/' . $filename . '.' . $phpEx; } + // If we are in install, try to use the updated version, when available + $install_language_filename = str_replace('language/', 'install/update/new/language/', $language_filename); + if (defined('IN_INSTALL') && file_exists($install_language_filename)) + { + $language_filename = $install_language_filename; + } + if (!file_exists($language_filename)) { global $config; |