aboutsummaryrefslogtreecommitdiffstats
path: root/phpBB/phpbb
diff options
context:
space:
mode:
Diffstat (limited to 'phpBB/phpbb')
-rw-r--r--phpBB/phpbb/auth/auth.php12
-rw-r--r--phpBB/phpbb/auth/provider/base.php40
-rw-r--r--phpBB/phpbb/auth/provider/interface.php92
-rw-r--r--phpBB/phpbb/auth/provider/oauth/oauth.php618
-rw-r--r--phpBB/phpbb/auth/provider/oauth/service/base.php55
-rw-r--r--phpBB/phpbb/auth/provider/oauth/service/bitly.php98
-rw-r--r--phpBB/phpbb/auth/provider/oauth/service/exception.php25
-rw-r--r--phpBB/phpbb/auth/provider/oauth/service/facebook.php98
-rw-r--r--phpBB/phpbb/auth/provider/oauth/service/google.php109
-rw-r--r--phpBB/phpbb/auth/provider/oauth/service/interface.php77
-rw-r--r--phpBB/phpbb/auth/provider/oauth/token_storage.php366
-rw-r--r--phpBB/phpbb/controller/helper.php33
-rw-r--r--phpBB/phpbb/db/migration/data/310/auth_provider_oauth.php71
-rw-r--r--phpBB/phpbb/db/tools.php494
-rw-r--r--phpBB/phpbb/log/null.php78
-rw-r--r--phpBB/phpbb/notification/manager.php15
-rw-r--r--phpBB/phpbb/notification/type/group_request.php163
-rw-r--r--phpBB/phpbb/notification/type/group_request_approved.php118
-rw-r--r--phpBB/phpbb/request/interface.php10
-rw-r--r--phpBB/phpbb/request/request.php8
-rw-r--r--phpBB/phpbb/template/twig/environment.php35
-rw-r--r--phpBB/phpbb/template/twig/lexer.php22
-rw-r--r--phpBB/phpbb/template/twig/node/includeasset.php4
23 files changed, 2364 insertions, 277 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/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) ? '&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/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/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/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 97833710c0..acfc984ddc 100644
--- a/phpBB/phpbb/notification/manager.php
+++ b/phpBB/phpbb/notification/manager.php
@@ -59,7 +59,7 @@ class phpbb_notification_manager
/**
* Notification Constructor
- *
+ *
* @param array $notification_types
* @param array $notification_methods
* @param ContainerBuilder $phpbb_container
@@ -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);
}
@@ -834,12 +835,12 @@ class phpbb_notification_manager
protected function load_object($object_name)
{
$object = $this->phpbb_container->get($object_name);
-
+
if (method_exists($object, 'set_notification_manager'))
{
$object->set_notification_manager($this);
}
-
+
return $object;
}
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/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 a33de70d69..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 -->
@@ -205,9 +208,6 @@ class phpbb_template_twig_lexer extends Twig_Lexer
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);
}
@@ -229,18 +229,18 @@ class phpbb_template_twig_lexer extends Twig_Lexer
{
$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\.])#', ' loops.$1|length$2', $inner);
+ $inner = preg_replace('#(\s\(?!?)\.([a-zA-Z_0-9]+)([^a-zA-Z_0-9\.])#', '$1loops.$2|length$3', $inner);
// Replace .foo.bar with foo.bar|length
- $inner = preg_replace('#\s\.([a-zA-Z_0-9\.]+)([^a-zA-Z_0-9\.])#', ' $1|length$2', $inner);
+ $inner = preg_replace('#(\s\(?!?)\.([a-zA-Z_0-9\.]+)([^a-zA-Z_0-9\.])#', '$1$2|length$3', $inner);
return "<!-- {$matches[1]}IF{$inner}-->";
};
- return preg_replace_callback('#<!-- (ELSE)?IF((.*)[\s][\$|\.|!]([^\s]+)(.*))-->#', $callback, $code);
+ return preg_replace_callback('#<!-- (ELSE)?IF((.*?) \(?!?[\$|\.]([^\s]+)(.*?))-->#', $callback, $code);
}
/**
@@ -264,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/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()