aboutsummaryrefslogtreecommitdiffstats
path: root/phpBB/includes
diff options
context:
space:
mode:
Diffstat (limited to 'phpBB/includes')
-rw-r--r--phpBB/includes/acp/acp_board.php127
-rw-r--r--phpBB/includes/acp/acp_captcha.php2
-rw-r--r--phpBB/includes/acp/acp_groups.php14
-rw-r--r--phpBB/includes/acp/acp_permission_roles.php25
-rw-r--r--phpBB/includes/auth/auth.php9
-rw-r--r--phpBB/includes/auth/auth_apache.php247
-rw-r--r--phpBB/includes/auth/auth_db.php289
-rw-r--r--phpBB/includes/auth/auth_ldap.php350
-rw-r--r--phpBB/includes/auth/provider_apache.php275
-rw-r--r--phpBB/includes/auth/provider_db.php337
-rw-r--r--phpBB/includes/auth/provider_interface.php93
-rw-r--r--phpBB/includes/auth/provider_ldap.php386
-rw-r--r--phpBB/includes/constants.php1
-rw-r--r--phpBB/includes/db/driver/mssql_odbc.php2
-rw-r--r--phpBB/includes/db/driver/mssqlnative.php10
-rw-r--r--phpBB/includes/db/migration/tool/module.php5
-rw-r--r--phpBB/includes/feed/base.php259
-rw-r--r--phpBB/includes/feed/factory.php129
-rw-r--r--phpBB/includes/feed/forum.php147
-rw-r--r--phpBB/includes/feed/forums.php72
-rw-r--r--phpBB/includes/feed/helper.php159
-rw-r--r--phpBB/includes/feed/news.php112
-rw-r--r--phpBB/includes/feed/overall.php97
-rw-r--r--phpBB/includes/feed/post_base.php57
-rw-r--r--phpBB/includes/feed/topic.php116
-rw-r--r--phpBB/includes/feed/topic_base.php59
-rw-r--r--phpBB/includes/feed/topics.php91
-rw-r--r--phpBB/includes/feed/topics_active.php136
-rw-r--r--phpBB/includes/functions.php5
-rw-r--r--phpBB/includes/functions_download.php33
-rw-r--r--phpBB/includes/functions_posting.php57
-rw-r--r--phpBB/includes/functions_user.php2
-rw-r--r--phpBB/includes/search/fulltext_mysql.php11
-rw-r--r--phpBB/includes/search/fulltext_sphinx.php2
-rw-r--r--phpBB/includes/session.php41
-rw-r--r--phpBB/includes/template/filter.php1
-rw-r--r--phpBB/includes/ucp/ucp_groups.php19
37 files changed, 2700 insertions, 1077 deletions
diff --git a/phpBB/includes/acp/acp_board.php b/phpBB/includes/acp/acp_board.php
index 6881e03fdb..24b913260b 100644
--- a/phpBB/includes/acp/acp_board.php
+++ b/phpBB/includes/acp/acp_board.php
@@ -522,84 +522,54 @@ class acp_board
if ($mode == 'auth')
{
// Retrieve a list of auth plugins and check their config values
- $auth_plugins = array();
+ $auth_providers = $phpbb_container->get('auth.provider_collection');
- $dp = @opendir($phpbb_root_path . 'includes/auth');
-
- if ($dp)
+ $updated_auth_settings = false;
+ $old_auth_config = array();
+ foreach ($auth_providers as $provider)
{
- while (($file = readdir($dp)) !== false)
+ if ($fields = $provider->acp($this->new_config))
{
- if (preg_match('#^auth_(.*?)\.' . $phpEx . '$#', $file))
+ // Check if we need to create config fields for this plugin and save config when submit was pressed
+ foreach ($fields['config'] as $field)
{
- $auth_plugins[] = basename(preg_replace('#^auth_(.*?)\.' . $phpEx . '$#', '\1', $file));
- }
- }
- closedir($dp);
+ if (!isset($config[$field]))
+ {
+ set_config($field, '');
+ }
- sort($auth_plugins);
- }
+ if (!isset($cfg_array[$field]) || strpos($field, 'legend') !== false)
+ {
+ continue;
+ }
- $updated_auth_settings = false;
- $old_auth_config = array();
- foreach ($auth_plugins as $method)
- {
- if ($method && file_exists($phpbb_root_path . 'includes/auth/auth_' . $method . '.' . $phpEx))
- {
- include_once($phpbb_root_path . 'includes/auth/auth_' . $method . '.' . $phpEx);
+ $old_auth_config[$field] = $this->new_config[$field];
+ $config_value = $cfg_array[$field];
+ $this->new_config[$field] = $config_value;
- $method = 'acp_' . $method;
- if (function_exists($method))
- {
- if ($fields = $method($this->new_config))
+ if ($submit)
{
- // Check if we need to create config fields for this plugin and save config when submit was pressed
- foreach ($fields['config'] as $field)
- {
- if (!isset($config[$field]))
- {
- set_config($field, '');
- }
-
- if (!isset($cfg_array[$field]) || strpos($field, 'legend') !== false)
- {
- continue;
- }
-
- $old_auth_config[$field] = $this->new_config[$field];
- $config_value = $cfg_array[$field];
- $this->new_config[$field] = $config_value;
-
- if ($submit)
- {
- $updated_auth_settings = true;
- set_config($field, $config_value);
- }
- }
+ $updated_auth_settings = true;
+ set_config($field, $config_value);
}
- unset($fields);
}
}
+ unset($fields);
}
if ($submit && (($cfg_array['auth_method'] != $this->new_config['auth_method']) || $updated_auth_settings))
{
$method = basename($cfg_array['auth_method']);
- if ($method && in_array($method, $auth_plugins))
+ if (array_key_exists('auth.provider.' . $method, $auth_providers))
{
- include_once($phpbb_root_path . 'includes/auth/auth_' . $method . '.' . $phpEx);
-
- $method = 'init_' . $method;
- if (function_exists($method))
+ $provider = $auth_providers['auth.provider.' . $method];
+ if ($error = $provider->init())
{
- if ($error = $method())
+ foreach ($old_auth_config as $config_name => $config_value)
{
- foreach ($old_auth_config as $config_name => $config_value)
- {
- set_config($config_name, $config_value);
- }
- trigger_error($error . adm_back_link($this->u_action), E_USER_WARNING);
+ set_config($config_name, $config_value);
}
+ trigger_error($error . adm_back_link($this->u_action), E_USER_WARNING);
}
set_config('auth_method', basename($cfg_array['auth_method']));
}
@@ -683,24 +653,17 @@ class acp_board
{
$template->assign_var('S_AUTH', true);
- foreach ($auth_plugins as $method)
+ foreach ($auth_providers as $provider)
{
- if ($method && file_exists($phpbb_root_path . 'includes/auth/auth_' . $method . '.' . $phpEx))
- {
- $method = 'acp_' . $method;
- if (function_exists($method))
- {
- $fields = $method($this->new_config);
+ $fields = $provider->acp($this->new_config);
- if ($fields['tpl'])
- {
- $template->assign_block_vars('auth_tpl', array(
- 'TPL' => $fields['tpl'])
- );
- }
- unset($fields);
- }
+ if ($fields['tpl'])
+ {
+ $template->assign_block_vars('auth_tpl', array(
+ 'TPL' => $fields['tpl'],
+ ));
}
+ unset($fields);
}
}
}
@@ -710,25 +673,15 @@ class acp_board
*/
function select_auth_method($selected_method, $key = '')
{
- global $phpbb_root_path, $phpEx;
+ global $phpbb_root_path, $phpEx, $phpbb_container;
$auth_plugins = array();
+ $auth_providers = $phpbb_container->get('auth.provider_collection');
- $dp = @opendir($phpbb_root_path . 'includes/auth');
-
- if (!$dp)
+ foreach($auth_providers as $key => $value)
{
- return '';
- }
-
- while (($file = readdir($dp)) !== false)
- {
- if (preg_match('#^auth_(.*?)\.' . $phpEx . '$#', $file))
- {
- $auth_plugins[] = preg_replace('#^auth_(.*?)\.' . $phpEx . '$#', '\1', $file);
- }
+ $auth_plugins[] = str_replace('auth.provider.', '', $key);
}
- closedir($dp);
sort($auth_plugins);
diff --git a/phpBB/includes/acp/acp_captcha.php b/phpBB/includes/acp/acp_captcha.php
index c7c64ae56b..1a083c20ac 100644
--- a/phpBB/includes/acp/acp_captcha.php
+++ b/phpBB/includes/acp/acp_captcha.php
@@ -124,6 +124,8 @@ class acp_captcha
'CAPTCHA_PREVIEW_TPL' => $demo_captcha->get_demo_template($id),
'S_CAPTCHA_HAS_CONFIG' => $demo_captcha->has_config(),
'CAPTCHA_SELECT' => $captcha_select,
+
+ 'U_ACTION' => $this->u_action,
));
}
}
diff --git a/phpBB/includes/acp/acp_groups.php b/phpBB/includes/acp/acp_groups.php
index c740ff7ddc..c79699d465 100644
--- a/phpBB/includes/acp/acp_groups.php
+++ b/phpBB/includes/acp/acp_groups.php
@@ -87,6 +87,11 @@ class acp_groups
case 'approve':
case 'demote':
case 'promote':
+ if (!check_form_key($form_key))
+ {
+ trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING);
+ }
+
if (!$group_id)
{
trigger_error($user->lang['NO_GROUP'] . adm_back_link($this->u_action), E_USER_WARNING);
@@ -259,6 +264,11 @@ class acp_groups
break;
case 'addusers':
+ if (!check_form_key($form_key))
+ {
+ trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING);
+ }
+
if (!$group_id)
{
trigger_error($user->lang['NO_GROUP'] . adm_back_link($this->u_action), E_USER_WARNING);
@@ -581,7 +591,7 @@ class acp_groups
$avatar = phpbb_get_group_avatar($group_row, 'GROUP_AVATAR', true);
- if (!$update)
+ if (isset($phpbb_avatar_manager) && !$update)
{
// Merge any avatar errors into the primary error array
$error = array_merge($error, $phpbb_avatar_manager->localize_errors($user, $avatar_error));
@@ -920,10 +930,12 @@ class acp_groups
case 'set_config_teampage':
$config->set('teampage_forums', $request->variable('teampage_forums', 0));
$config->set('teampage_memberships', $request->variable('teampage_memberships', 0));
+ trigger_error($user->lang['CONFIG_UPDATED'] . adm_back_link($this->u_action));
break;
case 'set_config_legend':
$config->set('legend_sort_groupname', $request->variable('legend_sort_groupname', 0));
+ trigger_error($user->lang['CONFIG_UPDATED'] . adm_back_link($this->u_action));
break;
}
}
diff --git a/phpBB/includes/acp/acp_permission_roles.php b/phpBB/includes/acp/acp_permission_roles.php
index 004187af84..e830479389 100644
--- a/phpBB/includes/acp/acp_permission_roles.php
+++ b/phpBB/includes/acp/acp_permission_roles.php
@@ -21,6 +21,7 @@ if (!defined('IN_PHPBB'))
class acp_permission_roles
{
var $u_action;
+ protected $auth_admin;
function main($id, $mode)
{
@@ -30,7 +31,7 @@ class acp_permission_roles
include_once($phpbb_root_path . 'includes/functions_user.' . $phpEx);
include_once($phpbb_root_path . 'includes/acp/auth.' . $phpEx);
- $auth_admin = new auth_admin();
+ $this->auth_admin = new auth_admin();
$user->add_lang('acp/permissions');
add_permission_language();
@@ -210,7 +211,7 @@ class acp_permission_roles
}
// Now add the auth settings
- $auth_admin->acl_set_role($role_id, $auth_settings);
+ $this->auth_admin->acl_set_role($role_id, $auth_settings);
$role_name = (!empty($user->lang[$role_name])) ? $user->lang[$role_name] : $role_name;
add_log('admin', 'LOG_' . strtoupper($permission_type) . 'ROLE_' . strtoupper($action), $role_name);
@@ -343,7 +344,7 @@ class acp_permission_roles
// Get users/groups/forums using this preset...
if ($action == 'edit')
{
- $hold_ary = $auth_admin->get_role_mask($role_id);
+ $hold_ary = $this->auth_admin->get_role_mask($role_id);
if (sizeof($hold_ary))
{
@@ -354,7 +355,7 @@ class acp_permission_roles
'L_ROLE_ASSIGNED_TO' => sprintf($user->lang['ROLE_ASSIGNED_TO'], $role_name))
);
- $auth_admin->display_role_mask($hold_ary);
+ $this->auth_admin->display_role_mask($hold_ary);
}
}
@@ -445,8 +446,8 @@ class acp_permission_roles
'S_DISPLAY_ROLE_MASK' => true)
);
- $hold_ary = $auth_admin->get_role_mask($display_item);
- $auth_admin->display_role_mask($hold_ary);
+ $hold_ary = $this->auth_admin->get_role_mask($display_item);
+ $this->auth_admin->display_role_mask($hold_ary);
}
}
@@ -462,7 +463,7 @@ class acp_permission_roles
$auth_options = array(0 => $auth_options);
// Making use of auth_admin method here (we do not really want to change two similar code fragments)
- auth_admin::build_permission_array($auth_options, $content_array, $categories, $key_sort_array);
+ $this->auth_admin->build_permission_array($auth_options, $content_array, $categories, $key_sort_array);
$content_array = $content_array[0];
@@ -500,8 +501,6 @@ class acp_permission_roles
{
global $db;
- $auth_admin = new auth_admin();
-
// Get complete auth array
$sql = 'SELECT auth_option, auth_option_id
FROM ' . ACL_OPTIONS_TABLE . "
@@ -529,19 +528,19 @@ class acp_permission_roles
$db->sql_freeresult($result);
// Get role assignments
- $hold_ary = $auth_admin->get_role_mask($role_id);
+ $hold_ary = $this->auth_admin->get_role_mask($role_id);
// Re-assign permissions
foreach ($hold_ary as $forum_id => $forum_ary)
{
if (isset($forum_ary['users']))
{
- $auth_admin->acl_set('user', $forum_id, $forum_ary['users'], $auth_settings, 0, false);
+ $this->auth_admin->acl_set('user', $forum_id, $forum_ary['users'], $auth_settings, 0, false);
}
if (isset($forum_ary['groups']))
{
- $auth_admin->acl_set('group', $forum_id, $forum_ary['groups'], $auth_settings, 0, false);
+ $this->auth_admin->acl_set('group', $forum_id, $forum_ary['groups'], $auth_settings, 0, false);
}
}
@@ -563,6 +562,6 @@ class acp_permission_roles
WHERE role_id = ' . $role_id;
$db->sql_query($sql);
- $auth_admin->acl_clear_prefetch();
+ $this->auth_admin->acl_clear_prefetch();
}
}
diff --git a/phpBB/includes/auth/auth.php b/phpBB/includes/auth/auth.php
index 2535247571..279959974d 100644
--- a/phpBB/includes/auth/auth.php
+++ b/phpBB/includes/auth/auth.php
@@ -927,15 +927,14 @@ class phpbb_auth
*/
function login($username, $password, $autologin = false, $viewonline = 1, $admin = 0)
{
- global $config, $db, $user, $phpbb_root_path, $phpEx;
+ global $config, $db, $user, $phpbb_root_path, $phpEx, $phpbb_container;
$method = trim(basename($config['auth_method']));
- include_once($phpbb_root_path . 'includes/auth/auth_' . $method . '.' . $phpEx);
- $method = 'login_' . $method;
- if (function_exists($method))
+ $provider = $phpbb_container->get('auth.provider.' . $method);
+ if ($provider)
{
- $login = $method($username, $password, $user->ip, $user->browser, $user->forwarded_for);
+ $login = $provider->login($username, $password);
// If the auth module wants us to create an empty profile do so and then treat the status as LOGIN_SUCCESS
if ($login['status'] == LOGIN_SUCCESS_CREATE_PROFILE)
diff --git a/phpBB/includes/auth/auth_apache.php b/phpBB/includes/auth/auth_apache.php
deleted file mode 100644
index 10b288aa09..0000000000
--- a/phpBB/includes/auth/auth_apache.php
+++ /dev/null
@@ -1,247 +0,0 @@
-<?php
-/**
-* Apache auth plug-in for phpBB3
-*
-* Authentication plug-ins is largely down to Sergey Kanareykin, our thanks to him.
-*
-* @package login
-* @copyright (c) 2005 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
-*
-*/
-
-/**
-* @ignore
-*/
-if (!defined('IN_PHPBB'))
-{
- exit;
-}
-
-/**
-* Checks whether the user is identified to apache
-* Only allow changing authentication to apache if the user is identified
-* Called in acp_board while setting authentication plugins
-*
-* @return boolean|string false if the user is identified and else an error message
-*/
-function init_apache()
-{
- global $user, $request;
-
- if (!$request->is_set('PHP_AUTH_USER', phpbb_request_interface::SERVER) || $user->data['username'] !== htmlspecialchars_decode($request->server('PHP_AUTH_USER')))
- {
- return $user->lang['APACHE_SETUP_BEFORE_USE'];
- }
- return false;
-}
-
-/**
-* Login function
-*/
-function login_apache(&$username, &$password)
-{
- global $db, $request;
-
- // do not allow empty password
- if (!$password)
- {
- return array(
- 'status' => LOGIN_ERROR_PASSWORD,
- 'error_msg' => 'NO_PASSWORD_SUPPLIED',
- 'user_row' => array('user_id' => ANONYMOUS),
- );
- }
-
- if (!$username)
- {
- return array(
- 'status' => LOGIN_ERROR_USERNAME,
- 'error_msg' => 'LOGIN_ERROR_USERNAME',
- 'user_row' => array('user_id' => ANONYMOUS),
- );
- }
-
- if (!$request->is_set('PHP_AUTH_USER', phpbb_request_interface::SERVER))
- {
- return array(
- 'status' => LOGIN_ERROR_EXTERNAL_AUTH,
- 'error_msg' => 'LOGIN_ERROR_EXTERNAL_AUTH_APACHE',
- 'user_row' => array('user_id' => ANONYMOUS),
- );
- }
-
- $php_auth_user = htmlspecialchars_decode($request->server('PHP_AUTH_USER'));
- $php_auth_pw = htmlspecialchars_decode($request->server('PHP_AUTH_PW'));
-
- if (!empty($php_auth_user) && !empty($php_auth_pw))
- {
- if ($php_auth_user !== $username)
- {
- return array(
- 'status' => LOGIN_ERROR_USERNAME,
- 'error_msg' => 'LOGIN_ERROR_USERNAME',
- 'user_row' => array('user_id' => ANONYMOUS),
- );
- }
-
- $sql = 'SELECT user_id, username, user_password, user_passchg, user_email, user_type
- FROM ' . USERS_TABLE . "
- WHERE username = '" . $db->sql_escape($php_auth_user) . "'";
- $result = $db->sql_query($sql);
- $row = $db->sql_fetchrow($result);
- $db->sql_freeresult($result);
-
- if ($row)
- {
- // User inactive...
- if ($row['user_type'] == USER_INACTIVE || $row['user_type'] == USER_IGNORE)
- {
- return array(
- 'status' => LOGIN_ERROR_ACTIVE,
- 'error_msg' => 'ACTIVE_ERROR',
- 'user_row' => $row,
- );
- }
-
- // Successful login...
- return array(
- 'status' => LOGIN_SUCCESS,
- 'error_msg' => false,
- 'user_row' => $row,
- );
- }
-
- // this is the user's first login so create an empty profile
- return array(
- 'status' => LOGIN_SUCCESS_CREATE_PROFILE,
- 'error_msg' => false,
- 'user_row' => user_row_apache($php_auth_user, $php_auth_pw),
- );
- }
-
- // Not logged into apache
- return array(
- 'status' => LOGIN_ERROR_EXTERNAL_AUTH,
- 'error_msg' => 'LOGIN_ERROR_EXTERNAL_AUTH_APACHE',
- 'user_row' => array('user_id' => ANONYMOUS),
- );
-}
-
-/**
-* Autologin function
-*
-* @return array containing the user row or empty if no auto login should take place
-*/
-function autologin_apache()
-{
- global $db, $request;
-
- if (!$request->is_set('PHP_AUTH_USER', phpbb_request_interface::SERVER))
- {
- return array();
- }
-
- $php_auth_user = htmlspecialchars_decode($request->server('PHP_AUTH_USER'));
- $php_auth_pw = htmlspecialchars_decode($request->server('PHP_AUTH_PW'));
-
- if (!empty($php_auth_user) && !empty($php_auth_pw))
- {
- set_var($php_auth_user, $php_auth_user, 'string', true);
- set_var($php_auth_pw, $php_auth_pw, 'string', true);
-
- $sql = 'SELECT *
- FROM ' . USERS_TABLE . "
- WHERE username = '" . $db->sql_escape($php_auth_user) . "'";
- $result = $db->sql_query($sql);
- $row = $db->sql_fetchrow($result);
- $db->sql_freeresult($result);
-
- if ($row)
- {
- return ($row['user_type'] == USER_INACTIVE || $row['user_type'] == USER_IGNORE) ? array() : $row;
- }
-
- if (!function_exists('user_add'))
- {
- global $phpbb_root_path, $phpEx;
-
- include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
- }
-
- // create the user if he does not exist yet
- user_add(user_row_apache($php_auth_user, $php_auth_pw));
-
- $sql = 'SELECT *
- FROM ' . USERS_TABLE . "
- WHERE username_clean = '" . $db->sql_escape(utf8_clean_string($php_auth_user)) . "'";
- $result = $db->sql_query($sql);
- $row = $db->sql_fetchrow($result);
- $db->sql_freeresult($result);
-
- if ($row)
- {
- return $row;
- }
- }
-
- return array();
-}
-
-/**
-* This function generates an array which can be passed to the user_add function in order to create a user
-*/
-function user_row_apache($username, $password)
-{
- global $db, $config, $user;
- // first retrieve default group id
- $sql = 'SELECT group_id
- FROM ' . GROUPS_TABLE . "
- WHERE group_name = '" . $db->sql_escape('REGISTERED') . "'
- AND group_type = " . GROUP_SPECIAL;
- $result = $db->sql_query($sql);
- $row = $db->sql_fetchrow($result);
- $db->sql_freeresult($result);
-
- if (!$row)
- {
- trigger_error('NO_GROUP');
- }
-
- // generate user account data
- return array(
- 'username' => $username,
- 'user_password' => phpbb_hash($password),
- 'user_email' => '',
- 'group_id' => (int) $row['group_id'],
- 'user_type' => USER_NORMAL,
- 'user_ip' => $user->ip,
- 'user_new' => ($config['new_member_post_limit']) ? 1 : 0,
- );
-}
-
-/**
-* The session validation function checks whether the user is still logged in
-*
-* @return boolean true if the given user is authenticated or false if the session should be closed
-*/
-function validate_session_apache(&$user)
-{
- global $request;
-
- // Check if PHP_AUTH_USER is set and handle this case
- if ($request->is_set('PHP_AUTH_USER', phpbb_request_interface::SERVER))
- {
- $php_auth_user = $request->server('PHP_AUTH_USER');
-
- return ($php_auth_user === $user['username']) ? true : false;
- }
-
- // PHP_AUTH_USER is not set. A valid session is now determined by the user type (anonymous/bot or not)
- if ($user['user_type'] == USER_IGNORE)
- {
- return true;
- }
-
- return false;
-}
diff --git a/phpBB/includes/auth/auth_db.php b/phpBB/includes/auth/auth_db.php
deleted file mode 100644
index ac944532a5..0000000000
--- a/phpBB/includes/auth/auth_db.php
+++ /dev/null
@@ -1,289 +0,0 @@
-<?php
-/**
-* Database auth plug-in for phpBB3
-*
-* Authentication plug-ins is largely down to Sergey Kanareykin, our thanks to him.
-*
-* This is for authentication via the integrated user table
-*
-* @package login
-* @copyright (c) 2005 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
-*
-*/
-
-/**
-* @ignore
-*/
-if (!defined('IN_PHPBB'))
-{
- exit;
-}
-
-/**
-* Login function
-*
-* @param string $username
-* @param string $password
-* @param string $ip IP address the login is taking place from. Used to
-* limit the number of login attempts per IP address.
-* @param string $browser The user agent used to login
-* @param string $forwarded_for X_FORWARDED_FOR header sent with login request
-* @return array A associative array of the format
-* array(
-* 'status' => status constant
-* 'error_msg' => string
-* 'user_row' => array
-* )
-*/
-function login_db($username, $password, $ip = '', $browser = '', $forwarded_for = '')
-{
- global $db, $config;
- global $request;
-
- // Auth plugins get the password untrimmed.
- // For compatibility we trim() here.
- $password = trim($password);
-
- // do not allow empty password
- if (!$password)
- {
- return array(
- 'status' => LOGIN_ERROR_PASSWORD,
- 'error_msg' => 'NO_PASSWORD_SUPPLIED',
- 'user_row' => array('user_id' => ANONYMOUS),
- );
- }
-
- if (!$username)
- {
- return array(
- 'status' => LOGIN_ERROR_USERNAME,
- 'error_msg' => 'LOGIN_ERROR_USERNAME',
- 'user_row' => array('user_id' => ANONYMOUS),
- );
- }
-
- $username_clean = utf8_clean_string($username);
-
- $sql = 'SELECT user_id, username, user_password, user_passchg, user_pass_convert, user_email, user_type, user_login_attempts
- FROM ' . USERS_TABLE . "
- WHERE username_clean = '" . $db->sql_escape($username_clean) . "'";
- $result = $db->sql_query($sql);
- $row = $db->sql_fetchrow($result);
- $db->sql_freeresult($result);
-
- if (($ip && !$config['ip_login_limit_use_forwarded']) ||
- ($forwarded_for && $config['ip_login_limit_use_forwarded']))
- {
- $sql = 'SELECT COUNT(*) AS attempts
- FROM ' . LOGIN_ATTEMPT_TABLE . '
- WHERE attempt_time > ' . (time() - (int) $config['ip_login_limit_time']);
- if ($config['ip_login_limit_use_forwarded'])
- {
- $sql .= " AND attempt_forwarded_for = '" . $db->sql_escape($forwarded_for) . "'";
- }
- else
- {
- $sql .= " AND attempt_ip = '" . $db->sql_escape($ip) . "' ";
- }
-
- $result = $db->sql_query($sql);
- $attempts = (int) $db->sql_fetchfield('attempts');
- $db->sql_freeresult($result);
-
- $attempt_data = array(
- 'attempt_ip' => $ip,
- 'attempt_browser' => trim(substr($browser, 0, 149)),
- 'attempt_forwarded_for' => $forwarded_for,
- 'attempt_time' => time(),
- 'user_id' => ($row) ? (int) $row['user_id'] : 0,
- 'username' => $username,
- 'username_clean' => $username_clean,
- );
- $sql = 'INSERT INTO ' . LOGIN_ATTEMPT_TABLE . $db->sql_build_array('INSERT', $attempt_data);
- $result = $db->sql_query($sql);
- }
- else
- {
- $attempts = 0;
- }
-
- if (!$row)
- {
- if ($config['ip_login_limit_max'] && $attempts >= $config['ip_login_limit_max'])
- {
- return array(
- 'status' => LOGIN_ERROR_ATTEMPTS,
- 'error_msg' => 'LOGIN_ERROR_ATTEMPTS',
- 'user_row' => array('user_id' => ANONYMOUS),
- );
- }
-
- return array(
- 'status' => LOGIN_ERROR_USERNAME,
- 'error_msg' => 'LOGIN_ERROR_USERNAME',
- 'user_row' => array('user_id' => ANONYMOUS),
- );
- }
-
- $show_captcha = ($config['max_login_attempts'] && $row['user_login_attempts'] >= $config['max_login_attempts']) ||
- ($config['ip_login_limit_max'] && $attempts >= $config['ip_login_limit_max']);
-
- // If there are too much login attempts, we need to check for an confirm image
- // Every auth module is able to define what to do by itself...
- if ($show_captcha)
- {
- // Visual Confirmation handling
- if (!class_exists('phpbb_captcha_factory', false))
- {
- global $phpbb_root_path, $phpEx;
- include ($phpbb_root_path . 'includes/captcha/captcha_factory.' . $phpEx);
- }
-
- $captcha = phpbb_captcha_factory::get_instance($config['captcha_plugin']);
- $captcha->init(CONFIRM_LOGIN);
- $vc_response = $captcha->validate($row);
- if ($vc_response)
- {
- return array(
- 'status' => LOGIN_ERROR_ATTEMPTS,
- 'error_msg' => 'LOGIN_ERROR_ATTEMPTS',
- 'user_row' => $row,
- );
- }
- else
- {
- $captcha->reset();
- }
-
- }
-
- // If the password convert flag is set we need to convert it
- if ($row['user_pass_convert'])
- {
- // enable super globals to get literal value
- // this is needed to prevent unicode normalization
- $super_globals_disabled = $request->super_globals_disabled();
- if ($super_globals_disabled)
- {
- $request->enable_super_globals();
- }
-
- // in phpBB2 passwords were used exactly as they were sent, with addslashes applied
- $password_old_format = isset($_REQUEST['password']) ? (string) $_REQUEST['password'] : '';
- $password_old_format = (!STRIP) ? addslashes($password_old_format) : $password_old_format;
- $password_new_format = $request->variable('password', '', true);
-
- if ($super_globals_disabled)
- {
- $request->disable_super_globals();
- }
-
- if ($password == $password_new_format)
- {
- if (!function_exists('utf8_to_cp1252'))
- {
- global $phpbb_root_path, $phpEx;
- include($phpbb_root_path . 'includes/utf/data/recode_basic.' . $phpEx);
- }
-
- // cp1252 is phpBB2's default encoding, characters outside ASCII range might work when converted into that encoding
- // plain md5 support left in for conversions from other systems.
- if ((strlen($row['user_password']) == 34 && (phpbb_check_hash(md5($password_old_format), $row['user_password']) || phpbb_check_hash(md5(utf8_to_cp1252($password_old_format)), $row['user_password'])))
- || (strlen($row['user_password']) == 32 && (md5($password_old_format) == $row['user_password'] || md5(utf8_to_cp1252($password_old_format)) == $row['user_password'])))
- {
- $hash = phpbb_hash($password_new_format);
-
- // Update the password in the users table to the new format and remove user_pass_convert flag
- $sql = 'UPDATE ' . USERS_TABLE . '
- SET user_password = \'' . $db->sql_escape($hash) . '\',
- user_pass_convert = 0
- WHERE user_id = ' . $row['user_id'];
- $db->sql_query($sql);
-
- $row['user_pass_convert'] = 0;
- $row['user_password'] = $hash;
- }
- else
- {
- // Although we weren't able to convert this password we have to
- // increase login attempt count to make sure this cannot be exploited
- $sql = 'UPDATE ' . USERS_TABLE . '
- SET user_login_attempts = user_login_attempts + 1
- WHERE user_id = ' . (int) $row['user_id'] . '
- AND user_login_attempts < ' . LOGIN_ATTEMPTS_MAX;
- $db->sql_query($sql);
-
- return array(
- 'status' => LOGIN_ERROR_PASSWORD_CONVERT,
- 'error_msg' => 'LOGIN_ERROR_PASSWORD_CONVERT',
- 'user_row' => $row,
- );
- }
- }
- }
-
- // Check password ...
- if (!$row['user_pass_convert'] && phpbb_check_hash($password, $row['user_password']))
- {
- // Check for old password hash...
- if (strlen($row['user_password']) == 32)
- {
- $hash = phpbb_hash($password);
-
- // Update the password in the users table to the new format
- $sql = 'UPDATE ' . USERS_TABLE . "
- SET user_password = '" . $db->sql_escape($hash) . "',
- user_pass_convert = 0
- WHERE user_id = {$row['user_id']}";
- $db->sql_query($sql);
-
- $row['user_password'] = $hash;
- }
-
- $sql = 'DELETE FROM ' . LOGIN_ATTEMPT_TABLE . '
- WHERE user_id = ' . $row['user_id'];
- $db->sql_query($sql);
-
- if ($row['user_login_attempts'] != 0)
- {
- // Successful, reset login attempts (the user passed all stages)
- $sql = 'UPDATE ' . USERS_TABLE . '
- SET user_login_attempts = 0
- WHERE user_id = ' . $row['user_id'];
- $db->sql_query($sql);
- }
-
- // User inactive...
- if ($row['user_type'] == USER_INACTIVE || $row['user_type'] == USER_IGNORE)
- {
- return array(
- 'status' => LOGIN_ERROR_ACTIVE,
- 'error_msg' => 'ACTIVE_ERROR',
- 'user_row' => $row,
- );
- }
-
- // Successful login... set user_login_attempts to zero...
- return array(
- 'status' => LOGIN_SUCCESS,
- 'error_msg' => false,
- 'user_row' => $row,
- );
- }
-
- // Password incorrect - increase login attempts
- $sql = 'UPDATE ' . USERS_TABLE . '
- SET user_login_attempts = user_login_attempts + 1
- WHERE user_id = ' . (int) $row['user_id'] . '
- AND user_login_attempts < ' . LOGIN_ATTEMPTS_MAX;
- $db->sql_query($sql);
-
- // Give status about wrong password...
- return array(
- 'status' => ($show_captcha) ? LOGIN_ERROR_ATTEMPTS : LOGIN_ERROR_PASSWORD,
- 'error_msg' => ($show_captcha) ? 'LOGIN_ERROR_ATTEMPTS' : 'LOGIN_ERROR_PASSWORD',
- 'user_row' => $row,
- );
-}
diff --git a/phpBB/includes/auth/auth_ldap.php b/phpBB/includes/auth/auth_ldap.php
deleted file mode 100644
index 98355dd044..0000000000
--- a/phpBB/includes/auth/auth_ldap.php
+++ /dev/null
@@ -1,350 +0,0 @@
-<?php
-/**
-*
-* LDAP auth plug-in for phpBB3
-*
-* Authentication plug-ins is largely down to Sergey Kanareykin, our thanks to him.
-*
-* @package login
-* @copyright (c) 2005 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
-*
-*/
-
-/**
-* @ignore
-*/
-if (!defined('IN_PHPBB'))
-{
- exit;
-}
-
-/**
-* Connect to ldap server
-* Only allow changing authentication to ldap if we can connect to the ldap server
-* Called in acp_board while setting authentication plugins
-*/
-function init_ldap()
-{
- global $config, $user;
-
- if (!@extension_loaded('ldap'))
- {
- return $user->lang['LDAP_NO_LDAP_EXTENSION'];
- }
-
- $config['ldap_port'] = (int) $config['ldap_port'];
- if ($config['ldap_port'])
- {
- $ldap = @ldap_connect($config['ldap_server'], $config['ldap_port']);
- }
- else
- {
- $ldap = @ldap_connect($config['ldap_server']);
- }
-
- if (!$ldap)
- {
- return $user->lang['LDAP_NO_SERVER_CONNECTION'];
- }
-
- @ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
- @ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
-
- if ($config['ldap_user'] || $config['ldap_password'])
- {
- if (!@ldap_bind($ldap, htmlspecialchars_decode($config['ldap_user']), htmlspecialchars_decode($config['ldap_password'])))
- {
- return $user->lang['LDAP_INCORRECT_USER_PASSWORD'];
- }
- }
-
- // ldap_connect only checks whether the specified server is valid, so the connection might still fail
- $search = @ldap_search(
- $ldap,
- htmlspecialchars_decode($config['ldap_base_dn']),
- ldap_user_filter($user->data['username']),
- (empty($config['ldap_email'])) ?
- array(htmlspecialchars_decode($config['ldap_uid'])) :
- array(htmlspecialchars_decode($config['ldap_uid']), htmlspecialchars_decode($config['ldap_email'])),
- 0,
- 1
- );
-
- if ($search === false)
- {
- return $user->lang['LDAP_SEARCH_FAILED'];
- }
-
- $result = @ldap_get_entries($ldap, $search);
-
- @ldap_close($ldap);
-
-
- if (!is_array($result) || sizeof($result) < 2)
- {
- return sprintf($user->lang['LDAP_NO_IDENTITY'], $user->data['username']);
- }
-
- if (!empty($config['ldap_email']) && !isset($result[0][htmlspecialchars_decode($config['ldap_email'])]))
- {
- return $user->lang['LDAP_NO_EMAIL'];
- }
-
- return false;
-}
-
-/**
-* Login function
-*/
-function login_ldap(&$username, &$password)
-{
- global $db, $config, $user;
-
- // do not allow empty password
- if (!$password)
- {
- return array(
- 'status' => LOGIN_ERROR_PASSWORD,
- 'error_msg' => 'NO_PASSWORD_SUPPLIED',
- 'user_row' => array('user_id' => ANONYMOUS),
- );
- }
-
- if (!$username)
- {
- return array(
- 'status' => LOGIN_ERROR_USERNAME,
- 'error_msg' => 'LOGIN_ERROR_USERNAME',
- 'user_row' => array('user_id' => ANONYMOUS),
- );
- }
-
- if (!@extension_loaded('ldap'))
- {
- return array(
- 'status' => LOGIN_ERROR_EXTERNAL_AUTH,
- 'error_msg' => 'LDAP_NO_LDAP_EXTENSION',
- 'user_row' => array('user_id' => ANONYMOUS),
- );
- }
-
- $config['ldap_port'] = (int) $config['ldap_port'];
- if ($config['ldap_port'])
- {
- $ldap = @ldap_connect($config['ldap_server'], $config['ldap_port']);
- }
- else
- {
- $ldap = @ldap_connect($config['ldap_server']);
- }
-
- if (!$ldap)
- {
- return array(
- 'status' => LOGIN_ERROR_EXTERNAL_AUTH,
- 'error_msg' => 'LDAP_NO_SERVER_CONNECTION',
- 'user_row' => array('user_id' => ANONYMOUS),
- );
- }
-
- @ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
- @ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
-
- if ($config['ldap_user'] || $config['ldap_password'])
- {
- if (!@ldap_bind($ldap, htmlspecialchars_decode($config['ldap_user']), htmlspecialchars_decode($config['ldap_password'])))
- {
- return array(
- 'status' => LOGIN_ERROR_EXTERNAL_AUTH,
- 'error_msg' => 'LDAP_NO_SERVER_CONNECTION',
- 'user_row' => array('user_id' => ANONYMOUS),
- );
- }
- }
-
- $search = @ldap_search(
- $ldap,
- htmlspecialchars_decode($config['ldap_base_dn']),
- ldap_user_filter($username),
- (empty($config['ldap_email'])) ?
- array(htmlspecialchars_decode($config['ldap_uid'])) :
- array(htmlspecialchars_decode($config['ldap_uid']), htmlspecialchars_decode($config['ldap_email'])),
- 0,
- 1
- );
-
- $ldap_result = @ldap_get_entries($ldap, $search);
-
- if (is_array($ldap_result) && sizeof($ldap_result) > 1)
- {
- if (@ldap_bind($ldap, $ldap_result[0]['dn'], htmlspecialchars_decode($password)))
- {
- @ldap_close($ldap);
-
- $sql ='SELECT user_id, username, user_password, user_passchg, user_email, user_type
- FROM ' . USERS_TABLE . "
- WHERE username_clean = '" . $db->sql_escape(utf8_clean_string($username)) . "'";
- $result = $db->sql_query($sql);
- $row = $db->sql_fetchrow($result);
- $db->sql_freeresult($result);
-
- if ($row)
- {
- unset($ldap_result);
-
- // User inactive...
- if ($row['user_type'] == USER_INACTIVE || $row['user_type'] == USER_IGNORE)
- {
- return array(
- 'status' => LOGIN_ERROR_ACTIVE,
- 'error_msg' => 'ACTIVE_ERROR',
- 'user_row' => $row,
- );
- }
-
- // Successful login... set user_login_attempts to zero...
- return array(
- 'status' => LOGIN_SUCCESS,
- 'error_msg' => false,
- 'user_row' => $row,
- );
- }
- else
- {
- // retrieve default group id
- $sql = 'SELECT group_id
- FROM ' . GROUPS_TABLE . "
- WHERE group_name = '" . $db->sql_escape('REGISTERED') . "'
- AND group_type = " . GROUP_SPECIAL;
- $result = $db->sql_query($sql);
- $row = $db->sql_fetchrow($result);
- $db->sql_freeresult($result);
-
- if (!$row)
- {
- trigger_error('NO_GROUP');
- }
-
- // generate user account data
- $ldap_user_row = array(
- 'username' => $username,
- 'user_password' => phpbb_hash($password),
- 'user_email' => (!empty($config['ldap_email'])) ? utf8_htmlspecialchars($ldap_result[0][htmlspecialchars_decode($config['ldap_email'])][0]) : '',
- 'group_id' => (int) $row['group_id'],
- 'user_type' => USER_NORMAL,
- 'user_ip' => $user->ip,
- 'user_new' => ($config['new_member_post_limit']) ? 1 : 0,
- );
-
- unset($ldap_result);
-
- // this is the user's first login so create an empty profile
- return array(
- 'status' => LOGIN_SUCCESS_CREATE_PROFILE,
- 'error_msg' => false,
- 'user_row' => $ldap_user_row,
- );
- }
- }
- else
- {
- unset($ldap_result);
- @ldap_close($ldap);
-
- // Give status about wrong password...
- return array(
- 'status' => LOGIN_ERROR_PASSWORD,
- 'error_msg' => 'LOGIN_ERROR_PASSWORD',
- 'user_row' => array('user_id' => ANONYMOUS),
- );
- }
- }
-
- @ldap_close($ldap);
-
- return array(
- 'status' => LOGIN_ERROR_USERNAME,
- 'error_msg' => 'LOGIN_ERROR_USERNAME',
- 'user_row' => array('user_id' => ANONYMOUS),
- );
-}
-
-/**
-* Generates a filter string for ldap_search to find a user
-*
-* @param $username string Username identifying the searched user
-*
-* @return string A filter string for ldap_search
-*/
-function ldap_user_filter($username)
-{
- global $config;
-
- $filter = '(' . $config['ldap_uid'] . '=' . ldap_escape(htmlspecialchars_decode($username)) . ')';
- if ($config['ldap_user_filter'])
- {
- $_filter = ($config['ldap_user_filter'][0] == '(' && substr($config['ldap_user_filter'], -1) == ')') ? $config['ldap_user_filter'] : "({$config['ldap_user_filter']})";
- $filter = "(&{$filter}{$_filter})";
- }
- return $filter;
-}
-
-/**
-* Escapes an LDAP AttributeValue
-*/
-function ldap_escape($string)
-{
- return str_replace(array('*', '\\', '(', ')'), array('\\*', '\\\\', '\\(', '\\)'), $string);
-}
-
-/**
-* This function is used to output any required fields in the authentication
-* admin panel. It also defines any required configuration table fields.
-*/
-function acp_ldap(&$new)
-{
- global $user;
-
- $tpl = '
-
- <dl>
- <dt><label for="ldap_server">' . $user->lang['LDAP_SERVER'] . $user->lang['COLON'] . '</label><br /><span>' . $user->lang['LDAP_SERVER_EXPLAIN'] . '</span></dt>
- <dd><input type="text" id="ldap_server" size="40" name="config[ldap_server]" value="' . $new['ldap_server'] . '" /></dd>
- </dl>
- <dl>
- <dt><label for="ldap_port">' . $user->lang['LDAP_PORT'] . $user->lang['COLON'] . '</label><br /><span>' . $user->lang['LDAP_PORT_EXPLAIN'] . '</span></dt>
- <dd><input type="text" id="ldap_port" size="40" name="config[ldap_port]" value="' . $new['ldap_port'] . '" /></dd>
- </dl>
- <dl>
- <dt><label for="ldap_dn">' . $user->lang['LDAP_DN'] . $user->lang['COLON'] . '</label><br /><span>' . $user->lang['LDAP_DN_EXPLAIN'] . '</span></dt>
- <dd><input type="text" id="ldap_dn" size="40" name="config[ldap_base_dn]" value="' . $new['ldap_base_dn'] . '" /></dd>
- </dl>
- <dl>
- <dt><label for="ldap_uid">' . $user->lang['LDAP_UID'] . $user->lang['COLON'] . '</label><br /><span>' . $user->lang['LDAP_UID_EXPLAIN'] . '</span></dt>
- <dd><input type="text" id="ldap_uid" size="40" name="config[ldap_uid]" value="' . $new['ldap_uid'] . '" /></dd>
- </dl>
- <dl>
- <dt><label for="ldap_user_filter">' . $user->lang['LDAP_USER_FILTER'] . $user->lang['COLON'] . '</label><br /><span>' . $user->lang['LDAP_USER_FILTER_EXPLAIN'] . '</span></dt>
- <dd><input type="text" id="ldap_user_filter" size="40" name="config[ldap_user_filter]" value="' . $new['ldap_user_filter'] . '" /></dd>
- </dl>
- <dl>
- <dt><label for="ldap_email">' . $user->lang['LDAP_EMAIL'] . $user->lang['COLON'] . '</label><br /><span>' . $user->lang['LDAP_EMAIL_EXPLAIN'] . '</span></dt>
- <dd><input type="email" id="ldap_email" size="40" name="config[ldap_email]" value="' . $new['ldap_email'] . '" /></dd>
- </dl>
- <dl>
- <dt><label for="ldap_user">' . $user->lang['LDAP_USER'] . $user->lang['COLON'] . '</label><br /><span>' . $user->lang['LDAP_USER_EXPLAIN'] . '</span></dt>
- <dd><input type="text" id="ldap_user" size="40" name="config[ldap_user]" value="' . $new['ldap_user'] . '" /></dd>
- </dl>
- <dl>
- <dt><label for="ldap_password">' . $user->lang['LDAP_PASSWORD'] . $user->lang['COLON'] . '</label><br /><span>' . $user->lang['LDAP_PASSWORD_EXPLAIN'] . '</span></dt>
- <dd><input type="password" id="ldap_password" size="40" name="config[ldap_password]" value="' . $new['ldap_password'] . '" autocomplete="off" /></dd>
- </dl>
- ';
-
- // These are fields required in the config table
- return array(
- 'tpl' => $tpl,
- 'config' => array('ldap_server', 'ldap_port', 'ldap_base_dn', 'ldap_uid', 'ldap_user_filter', 'ldap_email', 'ldap_user', 'ldap_password')
- );
-}
diff --git a/phpBB/includes/auth/provider_apache.php b/phpBB/includes/auth/provider_apache.php
new file mode 100644
index 0000000000..5f6f2862b6
--- /dev/null
+++ b/phpBB/includes/auth/provider_apache.php
@@ -0,0 +1,275 @@
+<?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;
+}
+
+/**
+ * Apache authentication provider for phpBB3
+ *
+ * @package auth
+ */
+class phpbb_auth_provider_apache implements phpbb_auth_provider_interface
+{
+ /**
+ * Apache Authentication Constructor
+ *
+ * @param phpbb_db_driver $db
+ * @param phpbb_config $config
+ * @param phpbb_request $request
+ * @param phpbb_user $user
+ * @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, $phpbb_root_path, $php_ext)
+ {
+ $this->db = $db;
+ $this->config = $config;
+ $this->request = $request;
+ $this->user = $user;
+ $this->phpbb_root_path = $phpbb_root_path;
+ $this->php_ext = $php_ext;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function init()
+ {
+ if (!$this->request->is_set('PHP_AUTH_USER', phpbb_request_interface::SERVER) || $this->user->data['username'] !== htmlspecialchars_decode($this->request->server('PHP_AUTH_USER')))
+ {
+ return $this->user->lang['APACHE_SETUP_BEFORE_USE'];
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function login($username, $password)
+ {
+ // do not allow empty password
+ if (!$password)
+ {
+ return array(
+ 'status' => LOGIN_ERROR_PASSWORD,
+ 'error_msg' => 'NO_PASSWORD_SUPPLIED',
+ 'user_row' => array('user_id' => ANONYMOUS),
+ );
+ }
+
+ if (!$username)
+ {
+ return array(
+ 'status' => LOGIN_ERROR_USERNAME,
+ 'error_msg' => 'LOGIN_ERROR_USERNAME',
+ 'user_row' => array('user_id' => ANONYMOUS),
+ );
+ }
+
+ if (!$this->request->is_set('PHP_AUTH_USER', phpbb_request_interface::SERVER))
+ {
+ return array(
+ 'status' => LOGIN_ERROR_EXTERNAL_AUTH,
+ 'error_msg' => 'LOGIN_ERROR_EXTERNAL_AUTH_APACHE',
+ 'user_row' => array('user_id' => ANONYMOUS),
+ );
+ }
+
+ $php_auth_user = htmlspecialchars_decode($this->request->server('PHP_AUTH_USER'));
+ $php_auth_pw = htmlspecialchars_decode($this->request->server('PHP_AUTH_PW'));
+
+ if (!empty($php_auth_user) && !empty($php_auth_pw))
+ {
+ if ($php_auth_user !== $username)
+ {
+ return array(
+ 'status' => LOGIN_ERROR_USERNAME,
+ 'error_msg' => 'LOGIN_ERROR_USERNAME',
+ 'user_row' => array('user_id' => ANONYMOUS),
+ );
+ }
+
+ $sql = 'SELECT user_id, username, user_password, user_passchg, user_email, user_type
+ FROM ' . USERS_TABLE . "
+ WHERE username = '" . $this->db->sql_escape($php_auth_user) . "'";
+ $result = $this->db->sql_query($sql);
+ $row = $this->db->sql_fetchrow($result);
+ $this->db->sql_freeresult($result);
+
+ if ($row)
+ {
+ // User inactive...
+ if ($row['user_type'] == USER_INACTIVE || $row['user_type'] == USER_IGNORE)
+ {
+ return array(
+ 'status' => LOGIN_ERROR_ACTIVE,
+ 'error_msg' => 'ACTIVE_ERROR',
+ 'user_row' => $row,
+ );
+ }
+
+ // Successful login...
+ return array(
+ 'status' => LOGIN_SUCCESS,
+ 'error_msg' => false,
+ 'user_row' => $row,
+ );
+ }
+
+ // this is the user's first login so create an empty profile
+ return array(
+ 'status' => LOGIN_SUCCESS_CREATE_PROFILE,
+ 'error_msg' => false,
+ 'user_row' => user_row_apache($php_auth_user, $php_auth_pw),
+ );
+ }
+
+ // Not logged into apache
+ return array(
+ 'status' => LOGIN_ERROR_EXTERNAL_AUTH,
+ 'error_msg' => 'LOGIN_ERROR_EXTERNAL_AUTH_APACHE',
+ 'user_row' => array('user_id' => ANONYMOUS),
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function autologin()
+ {
+ if (!$this->request->is_set('PHP_AUTH_USER', phpbb_request_interface::SERVER))
+ {
+ return array();
+ }
+
+ $php_auth_user = htmlspecialchars_decode($this->request->server('PHP_AUTH_USER'));
+ $php_auth_pw = htmlspecialchars_decode($this->request->server('PHP_AUTH_PW'));
+
+ if (!empty($php_auth_user) && !empty($php_auth_pw))
+ {
+ set_var($php_auth_user, $php_auth_user, 'string', true);
+ set_var($php_auth_pw, $php_auth_pw, 'string', true);
+
+ $sql = 'SELECT *
+ FROM ' . USERS_TABLE . "
+ WHERE username = '" . $this->db->sql_escape($php_auth_user) . "'";
+ $result = $this->db->sql_query($sql);
+ $row = $this->db->sql_fetchrow($result);
+ $this->db->sql_freeresult($result);
+
+ if ($row)
+ {
+ return ($row['user_type'] == USER_INACTIVE || $row['user_type'] == USER_IGNORE) ? array() : $row;
+ }
+
+ if (!function_exists('user_add'))
+ {
+ include($this->phpbb_root_path . 'includes/functions_user.' . $this->php_ext);
+ }
+
+ // create the user if he does not exist yet
+ user_add(user_row_apache($php_auth_user, $php_auth_pw));
+
+ $sql = 'SELECT *
+ FROM ' . USERS_TABLE . "
+ WHERE username_clean = '" . $this->db->sql_escape(utf8_clean_string($php_auth_user)) . "'";
+ $result = $this->db->sql_query($sql);
+ $row = $this->db->sql_fetchrow($result);
+ $this->db->sql_freeresult($result);
+
+ if ($row)
+ {
+ return $row;
+ }
+ }
+
+ return array();
+ }
+
+ /**
+ * This function generates an array which can be passed to the user_add
+ * function in order to create a user
+ *
+ * @param string $username The username of the new user.
+ * @param string $password The password of the new user.
+ * @return array Contains data that can be passed directly to
+ * the user_add function.
+ */
+ private function user_row($username, $password)
+ {
+ // first retrieve default group id
+ $sql = 'SELECT group_id
+ FROM ' . GROUPS_TABLE . "
+ WHERE group_name = '" . $this->db->sql_escape('REGISTERED') . "'
+ AND group_type = " . GROUP_SPECIAL;
+ $result = $this->db->sql_query($sql);
+ $row = $this->db->sql_fetchrow($result);
+ $this->db->sql_freeresult($result);
+
+ if (!$row)
+ {
+ trigger_error('NO_GROUP');
+ }
+
+ // generate user account data
+ return array(
+ 'username' => $username,
+ 'user_password' => phpbb_hash($password),
+ 'user_email' => '',
+ 'group_id' => (int) $row['group_id'],
+ 'user_type' => USER_NORMAL,
+ 'user_ip' => $this->user->ip,
+ 'user_new' => ($this->config['new_member_post_limit']) ? 1 : 0,
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function validate_session($user)
+ {
+ // Check if PHP_AUTH_USER is set and handle this case
+ if ($this->request->is_set('PHP_AUTH_USER', phpbb_request_interface::SERVER))
+ {
+ $php_auth_user = $this->request->server('PHP_AUTH_USER');
+
+ return ($php_auth_user === $user['username']) ? true : false;
+ }
+
+ // PHP_AUTH_USER is not set. A valid session is now determined by the user type (anonymous/bot or not)
+ if ($user['user_type'] == USER_IGNORE)
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function acp($new)
+ {
+ return;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function logout($data, $new_session)
+ {
+ return;
+ }
+}
diff --git a/phpBB/includes/auth/provider_db.php b/phpBB/includes/auth/provider_db.php
new file mode 100644
index 0000000000..894041c9cf
--- /dev/null
+++ b/phpBB/includes/auth/provider_db.php
@@ -0,0 +1,337 @@
+<?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;
+}
+
+/**
+ * Database authentication provider for phpBB3
+ *
+ * This is for authentication via the integrated user table
+ *
+ * @package auth
+ */
+class phpbb_auth_provider_db implements phpbb_auth_provider_interface
+{
+
+ /**
+ * Database Authentication Constructor
+ *
+ * @param phpbb_db_driver $db
+ * @param phpbb_config $config
+ * @param phpbb_request $request
+ * @param phpbb_user $user
+ * @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, $phpbb_root_path, $php_ext)
+ {
+ $this->db = $db;
+ $this->config = $config;
+ $this->request = $request;
+ $this->user = $user;
+ $this->phpbb_root_path = $phpbb_root_path;
+ $this->php_ext = $php_ext;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function init()
+ {
+ return;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function login($username, $password)
+ {
+ // Auth plugins get the password untrimmed.
+ // For compatibility we trim() here.
+ $password = trim($password);
+
+ // do not allow empty password
+ if (!$password)
+ {
+ return array(
+ 'status' => LOGIN_ERROR_PASSWORD,
+ 'error_msg' => 'NO_PASSWORD_SUPPLIED',
+ 'user_row' => array('user_id' => ANONYMOUS),
+ );
+ }
+
+ if (!$username)
+ {
+ return array(
+ 'status' => LOGIN_ERROR_USERNAME,
+ 'error_msg' => 'LOGIN_ERROR_USERNAME',
+ 'user_row' => array('user_id' => ANONYMOUS),
+ );
+ }
+
+ $username_clean = utf8_clean_string($username);
+
+ $sql = 'SELECT user_id, username, user_password, user_passchg, user_pass_convert, user_email, user_type, user_login_attempts
+ FROM ' . USERS_TABLE . "
+ WHERE username_clean = '" . $this->db->sql_escape($username_clean) . "'";
+ $result = $this->db->sql_query($sql);
+ $row = $this->db->sql_fetchrow($result);
+ $this->db->sql_freeresult($result);
+
+ if (($this->user->ip && !$this->config['ip_login_limit_use_forwarded']) ||
+ ($this->user->forwarded_for && $this->config['ip_login_limit_use_forwarded']))
+ {
+ $sql = 'SELECT COUNT(*) AS attempts
+ FROM ' . LOGIN_ATTEMPT_TABLE . '
+ WHERE attempt_time > ' . (time() - (int) $this->config['ip_login_limit_time']);
+ if ($this->config['ip_login_limit_use_forwarded'])
+ {
+ $sql .= " AND attempt_forwarded_for = '" . $this->db->sql_escape($this->user->forwarded_for) . "'";
+ }
+ else
+ {
+ $sql .= " AND attempt_ip = '" . $this->db->sql_escape($this->user->ip) . "' ";
+ }
+
+ $result = $this->db->sql_query($sql);
+ $attempts = (int) $this->db->sql_fetchfield('attempts');
+ $this->db->sql_freeresult($result);
+
+ $attempt_data = array(
+ 'attempt_ip' => $this->user->ip,
+ 'attempt_browser' => trim(substr($this->user->browser, 0, 149)),
+ 'attempt_forwarded_for' => $this->user->forwarded_for,
+ 'attempt_time' => time(),
+ 'user_id' => ($row) ? (int) $row['user_id'] : 0,
+ 'username' => $username,
+ 'username_clean' => $username_clean,
+ );
+ $sql = 'INSERT INTO ' . LOGIN_ATTEMPT_TABLE . $this->db->sql_build_array('INSERT', $attempt_data);
+ $result = $this->db->sql_query($sql);
+ }
+ else
+ {
+ $attempts = 0;
+ }
+
+ if (!$row)
+ {
+ if ($this->config['ip_login_limit_max'] && $attempts >= $this->config['ip_login_limit_max'])
+ {
+ return array(
+ 'status' => LOGIN_ERROR_ATTEMPTS,
+ 'error_msg' => 'LOGIN_ERROR_ATTEMPTS',
+ 'user_row' => array('user_id' => ANONYMOUS),
+ );
+ }
+
+ return array(
+ 'status' => LOGIN_ERROR_USERNAME,
+ 'error_msg' => 'LOGIN_ERROR_USERNAME',
+ 'user_row' => array('user_id' => ANONYMOUS),
+ );
+ }
+
+ $show_captcha = ($this->config['max_login_attempts'] && $row['user_login_attempts'] >= $this->config['max_login_attempts']) ||
+ ($this->config['ip_login_limit_max'] && $attempts >= $this->config['ip_login_limit_max']);
+
+ // If there are too many login attempts, we need to check for a confirm image
+ // Every auth module is able to define what to do by itself...
+ if ($show_captcha)
+ {
+ // Visual Confirmation handling
+ if (!class_exists('phpbb_captcha_factory', false))
+ {
+ include ($this->phpbb_root_path . 'includes/captcha/captcha_factory.' . $this->php_ext);
+ }
+
+ $captcha = phpbb_captcha_factory::get_instance($this->config['captcha_plugin']);
+ $captcha->init(CONFIRM_LOGIN);
+ $vc_response = $captcha->validate($row);
+ if ($vc_response)
+ {
+ return array(
+ 'status' => LOGIN_ERROR_ATTEMPTS,
+ 'error_msg' => 'LOGIN_ERROR_ATTEMPTS',
+ 'user_row' => $row,
+ );
+ }
+ else
+ {
+ $captcha->reset();
+ }
+
+ }
+
+ // If the password convert flag is set we need to convert it
+ if ($row['user_pass_convert'])
+ {
+ // enable super globals to get literal value
+ // this is needed to prevent unicode normalization
+ $super_globals_disabled = $this->request->super_globals_disabled();
+ if ($super_globals_disabled)
+ {
+ $this->request->enable_super_globals();
+ }
+
+ // in phpBB2 passwords were used exactly as they were sent, with addslashes applied
+ $password_old_format = isset($_REQUEST['password']) ? (string) $_REQUEST['password'] : '';
+ $password_old_format = (!STRIP) ? addslashes($password_old_format) : $password_old_format;
+ $password_new_format = $this->request->variable('password', '', true);
+
+ if ($super_globals_disabled)
+ {
+ $this->request->disable_super_globals();
+ }
+
+ if ($password == $password_new_format)
+ {
+ if (!function_exists('utf8_to_cp1252'))
+ {
+ include($this->phpbb_root_path . 'includes/utf/data/recode_basic.' . $this->php_ext);
+ }
+
+ // cp1252 is phpBB2's default encoding, characters outside ASCII range might work when converted into that encoding
+ // plain md5 support left in for conversions from other systems.
+ if ((strlen($row['user_password']) == 34 && (phpbb_check_hash(md5($password_old_format), $row['user_password']) || phpbb_check_hash(md5(utf8_to_cp1252($password_old_format)), $row['user_password'])))
+ || (strlen($row['user_password']) == 32 && (md5($password_old_format) == $row['user_password'] || md5(utf8_to_cp1252($password_old_format)) == $row['user_password'])))
+ {
+ $hash = phpbb_hash($password_new_format);
+
+ // Update the password in the users table to the new format and remove user_pass_convert flag
+ $sql = 'UPDATE ' . USERS_TABLE . '
+ SET user_password = \'' . $this->db->sql_escape($hash) . '\',
+ user_pass_convert = 0
+ WHERE user_id = ' . $row['user_id'];
+ $this->db->sql_query($sql);
+
+ $row['user_pass_convert'] = 0;
+ $row['user_password'] = $hash;
+ }
+ else
+ {
+ // Although we weren't able to convert this password we have to
+ // increase login attempt count to make sure this cannot be exploited
+ $sql = 'UPDATE ' . USERS_TABLE . '
+ SET user_login_attempts = user_login_attempts + 1
+ WHERE user_id = ' . (int) $row['user_id'] . '
+ AND user_login_attempts < ' . LOGIN_ATTEMPTS_MAX;
+ $this->db->sql_query($sql);
+
+ return array(
+ 'status' => LOGIN_ERROR_PASSWORD_CONVERT,
+ 'error_msg' => 'LOGIN_ERROR_PASSWORD_CONVERT',
+ 'user_row' => $row,
+ );
+ }
+ }
+ }
+
+ // Check password ...
+ if (!$row['user_pass_convert'] && phpbb_check_hash($password, $row['user_password']))
+ {
+ // Check for old password hash...
+ if (strlen($row['user_password']) == 32)
+ {
+ $hash = phpbb_hash($password);
+
+ // Update the password in the users table to the new format
+ $sql = 'UPDATE ' . USERS_TABLE . "
+ SET user_password = '" . $this->db->sql_escape($hash) . "',
+ user_pass_convert = 0
+ WHERE user_id = {$row['user_id']}";
+ $this->db->sql_query($sql);
+
+ $row['user_password'] = $hash;
+ }
+
+ $sql = 'DELETE FROM ' . LOGIN_ATTEMPT_TABLE . '
+ WHERE user_id = ' . $row['user_id'];
+ $this->db->sql_query($sql);
+
+ if ($row['user_login_attempts'] != 0)
+ {
+ // Successful, reset login attempts (the user passed all stages)
+ $sql = 'UPDATE ' . USERS_TABLE . '
+ SET user_login_attempts = 0
+ WHERE user_id = ' . $row['user_id'];
+ $this->db->sql_query($sql);
+ }
+
+ // User inactive...
+ if ($row['user_type'] == USER_INACTIVE || $row['user_type'] == USER_IGNORE)
+ {
+ return array(
+ 'status' => LOGIN_ERROR_ACTIVE,
+ 'error_msg' => 'ACTIVE_ERROR',
+ 'user_row' => $row,
+ );
+ }
+
+ // Successful login... set user_login_attempts to zero...
+ return array(
+ 'status' => LOGIN_SUCCESS,
+ 'error_msg' => false,
+ 'user_row' => $row,
+ );
+ }
+
+ // Password incorrect - increase login attempts
+ $sql = 'UPDATE ' . USERS_TABLE . '
+ SET user_login_attempts = user_login_attempts + 1
+ WHERE user_id = ' . (int) $row['user_id'] . '
+ AND user_login_attempts < ' . LOGIN_ATTEMPTS_MAX;
+ $this->db->sql_query($sql);
+
+ // Give status about wrong password...
+ return array(
+ 'status' => ($show_captcha) ? LOGIN_ERROR_ATTEMPTS : LOGIN_ERROR_PASSWORD,
+ 'error_msg' => ($show_captcha) ? 'LOGIN_ERROR_ATTEMPTS' : 'LOGIN_ERROR_PASSWORD',
+ 'user_row' => $row,
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function autologin()
+ {
+ return;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function acp($new)
+ {
+ return;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function logout($data, $new_session)
+ {
+ return;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function validate_session($user)
+ {
+ return;
+ }
+}
diff --git a/phpBB/includes/auth/provider_interface.php b/phpBB/includes/auth/provider_interface.php
new file mode 100644
index 0000000000..2d1935f8f0
--- /dev/null
+++ b/phpBB/includes/auth/provider_interface.php
@@ -0,0 +1,93 @@
+<?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;
+}
+
+/**
+ * The interface authentication provider classes have to implement.
+ *
+ * @package auth
+ */
+interface phpbb_auth_provider_interface
+{
+ /**
+ * Checks whether the user is currently identified to the authentication
+ * provider.
+ * Called in acp_board while setting authentication plugins.
+ * Changing to an authentication provider will not be permitted in acp_board
+ * if there is an error.
+ *
+ * @return boolean|string False if the user is identified, otherwise an
+ * error message, or null if not implemented.
+ */
+ public function init();
+
+ /**
+ * Performs login.
+ *
+ * @param string $username The name of the user being authenticated.
+ * @param string $password The password of the user.
+ * @return array An associative array of the format:
+ * array(
+ * 'status' => status constant
+ * 'error_msg' => string
+ * 'user_row' => array
+ * )
+ */
+ public function login($username, $password);
+
+ /**
+ * Autologin function
+ *
+ * @return array|null containing the user row, empty if no auto login
+ * should take place, or null if not impletmented.
+ */
+ public function autologin();
+
+ /**
+ * This function is used to output any required fields in the authentication
+ * admin panel. It also defines any required configuration table fields.
+ *
+ * @param array $new Contains the new configuration values that have
+ * been set in acp_board.
+ * @return array|null Returns null if not implemented or an array of the
+ * form:
+ * array(
+ * 'tpl' => string
+ * 'config' => array
+ * )
+ */
+ public function acp($new);
+
+ /**
+ * Performs additional actions during logout.
+ *
+ * @param array $data An array corresponding to
+ * phpbb_session::data
+ * @param boolean $new_session True for a new session, false for no new
+ * session.
+ */
+ public function logout($data, $new_session);
+
+ /**
+ * The session validation function checks whether the user is still logged
+ * into phpBB.
+ *
+ * @param array $user
+ * @return boolean true if the given user is authenticated, false if the
+ * session should be closed, or null if not implemented.
+ */
+ public function validate_session($user);
+}
diff --git a/phpBB/includes/auth/provider_ldap.php b/phpBB/includes/auth/provider_ldap.php
new file mode 100644
index 0000000000..f67c1e9247
--- /dev/null
+++ b/phpBB/includes/auth/provider_ldap.php
@@ -0,0 +1,386 @@
+<?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;
+}
+
+/**
+ * Database authentication provider for phpBB3
+ *
+ * This is for authentication via the integrated user table
+ *
+ * @package auth
+ */
+class phpbb_auth_provider_ldap implements phpbb_auth_provider_interface
+{
+ /**
+ * LDAP Authentication Constructor
+ *
+ * @param phpbb_db_driver $db
+ * @param phpbb_config $config
+ * @param phpbb_user $user
+ */
+ public function __construct(phpbb_db_driver $db, phpbb_config $config, phpbb_user $user)
+ {
+ $this->db = $db;
+ $this->config = $config;
+ $this->user = $user;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function init()
+ {
+ if (!@extension_loaded('ldap'))
+ {
+ return $this->user->lang['LDAP_NO_LDAP_EXTENSION'];
+ }
+
+ $this->config['ldap_port'] = (int) $this->config['ldap_port'];
+ if ($this->config['ldap_port'])
+ {
+ $ldap = @ldap_connect($this->config['ldap_server'], $this->config['ldap_port']);
+ }
+ else
+ {
+ $ldap = @ldap_connect($this->config['ldap_server']);
+ }
+
+ if (!$ldap)
+ {
+ return $this->user->lang['LDAP_NO_SERVER_CONNECTION'];
+ }
+
+ @ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
+ @ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
+
+ if ($this->config['ldap_user'] || $this->config['ldap_password'])
+ {
+ if (!@ldap_bind($ldap, htmlspecialchars_decode($this->config['ldap_user']), htmlspecialchars_decode($this->config['ldap_password'])))
+ {
+ return $this->user->lang['LDAP_INCORRECT_USER_PASSWORD'];
+ }
+ }
+
+ // ldap_connect only checks whether the specified server is valid, so the connection might still fail
+ $search = @ldap_search(
+ $ldap,
+ htmlspecialchars_decode($this->config['ldap_base_dn']),
+ $this->ldap_user_filter($this->user->data['username']),
+ (empty($this->config['ldap_email'])) ?
+ array(htmlspecialchars_decode($this->config['ldap_uid'])) :
+ array(htmlspecialchars_decode($this->config['ldap_uid']), htmlspecialchars_decode($this->config['ldap_email'])),
+ 0,
+ 1
+ );
+
+ if ($search === false)
+ {
+ return $this->user->lang['LDAP_SEARCH_FAILED'];
+ }
+
+ $result = @ldap_get_entries($ldap, $search);
+
+ @ldap_close($ldap);
+
+
+ if (!is_array($result) || sizeof($result) < 2)
+ {
+ return sprintf($this->user->lang['LDAP_NO_IDENTITY'], $this->user->data['username']);
+ }
+
+ if (!empty($this->config['ldap_email']) && !isset($result[0][htmlspecialchars_decode($this->config['ldap_email'])]))
+ {
+ return $this->user->lang['LDAP_NO_EMAIL'];
+ }
+
+ return false;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function login($username, $password)
+ {
+ // do not allow empty password
+ if (!$password)
+ {
+ return array(
+ 'status' => LOGIN_ERROR_PASSWORD,
+ 'error_msg' => 'NO_PASSWORD_SUPPLIED',
+ 'user_row' => array('user_id' => ANONYMOUS),
+ );
+ }
+
+ if (!$username)
+ {
+ return array(
+ 'status' => LOGIN_ERROR_USERNAME,
+ 'error_msg' => 'LOGIN_ERROR_USERNAME',
+ 'user_row' => array('user_id' => ANONYMOUS),
+ );
+ }
+
+ if (!@extension_loaded('ldap'))
+ {
+ return array(
+ 'status' => LOGIN_ERROR_EXTERNAL_AUTH,
+ 'error_msg' => 'LDAP_NO_LDAP_EXTENSION',
+ 'user_row' => array('user_id' => ANONYMOUS),
+ );
+ }
+
+ $this->config['ldap_port'] = (int) $this->config['ldap_port'];
+ if ($this->config['ldap_port'])
+ {
+ $ldap = @ldap_connect($this->config['ldap_server'], $this->config['ldap_port']);
+ }
+ else
+ {
+ $ldap = @ldap_connect($this->config['ldap_server']);
+ }
+
+ if (!$ldap)
+ {
+ return array(
+ 'status' => LOGIN_ERROR_EXTERNAL_AUTH,
+ 'error_msg' => 'LDAP_NO_SERVER_CONNECTION',
+ 'user_row' => array('user_id' => ANONYMOUS),
+ );
+ }
+
+ @ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
+ @ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
+
+ if ($this->config['ldap_user'] || $this->config['ldap_password'])
+ {
+ if (!@ldap_bind($ldap, htmlspecialchars_decode($this->config['ldap_user']), htmlspecialchars_decode($this->config['ldap_password'])))
+ {
+ return array(
+ 'status' => LOGIN_ERROR_EXTERNAL_AUTH,
+ 'error_msg' => 'LDAP_NO_SERVER_CONNECTION',
+ 'user_row' => array('user_id' => ANONYMOUS),
+ );
+ }
+ }
+
+ $search = @ldap_search(
+ $ldap,
+ htmlspecialchars_decode($this->config['ldap_base_dn']),
+ $this->ldap_user_filter($username),
+ (empty($this->config['ldap_email'])) ?
+ array(htmlspecialchars_decode($this->config['ldap_uid'])) :
+ array(htmlspecialchars_decode($this->config['ldap_uid']), htmlspecialchars_decode($this->config['ldap_email'])),
+ 0,
+ 1
+ );
+
+ $ldap_result = @ldap_get_entries($ldap, $search);
+
+ if (is_array($ldap_result) && sizeof($ldap_result) > 1)
+ {
+ if (@ldap_bind($ldap, $ldap_result[0]['dn'], htmlspecialchars_decode($password)))
+ {
+ @ldap_close($ldap);
+
+ $sql ='SELECT user_id, username, user_password, user_passchg, user_email, user_type
+ FROM ' . USERS_TABLE . "
+ WHERE username_clean = '" . $this->db->sql_escape(utf8_clean_string($username)) . "'";
+ $result = $this->db->sql_query($sql);
+ $row = $this->db->sql_fetchrow($result);
+ $this->db->sql_freeresult($result);
+
+ if ($row)
+ {
+ unset($ldap_result);
+
+ // User inactive...
+ if ($row['user_type'] == USER_INACTIVE || $row['user_type'] == USER_IGNORE)
+ {
+ return array(
+ 'status' => LOGIN_ERROR_ACTIVE,
+ 'error_msg' => 'ACTIVE_ERROR',
+ 'user_row' => $row,
+ );
+ }
+
+ // Successful login... set user_login_attempts to zero...
+ return array(
+ 'status' => LOGIN_SUCCESS,
+ 'error_msg' => false,
+ 'user_row' => $row,
+ );
+ }
+ else
+ {
+ // retrieve default group id
+ $sql = 'SELECT group_id
+ FROM ' . GROUPS_TABLE . "
+ WHERE group_name = '" . $this->db->sql_escape('REGISTERED') . "'
+ AND group_type = " . GROUP_SPECIAL;
+ $result = $this->db->sql_query($sql);
+ $row = $this->db->sql_fetchrow($result);
+ $this->db->sql_freeresult($result);
+
+ if (!$row)
+ {
+ trigger_error('NO_GROUP');
+ }
+
+ // generate user account data
+ $ldap_user_row = array(
+ 'username' => $username,
+ 'user_password' => phpbb_hash($password),
+ 'user_email' => (!empty($this->config['ldap_email'])) ? utf8_htmlspecialchars($ldap_result[0][htmlspecialchars_decode($this->config['ldap_email'])][0]) : '',
+ 'group_id' => (int) $row['group_id'],
+ 'user_type' => USER_NORMAL,
+ 'user_ip' => $this->user->ip,
+ 'user_new' => ($this->config['new_member_post_limit']) ? 1 : 0,
+ );
+
+ unset($ldap_result);
+
+ // this is the user's first login so create an empty profile
+ return array(
+ 'status' => LOGIN_SUCCESS_CREATE_PROFILE,
+ 'error_msg' => false,
+ 'user_row' => $ldap_user_row,
+ );
+ }
+ }
+ else
+ {
+ unset($ldap_result);
+ @ldap_close($ldap);
+
+ // Give status about wrong password...
+ return array(
+ 'status' => LOGIN_ERROR_PASSWORD,
+ 'error_msg' => 'LOGIN_ERROR_PASSWORD',
+ 'user_row' => array('user_id' => ANONYMOUS),
+ );
+ }
+ }
+
+ @ldap_close($ldap);
+
+ return array(
+ 'status' => LOGIN_ERROR_USERNAME,
+ 'error_msg' => 'LOGIN_ERROR_USERNAME',
+ 'user_row' => array('user_id' => ANONYMOUS),
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function autologin()
+ {
+ return;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function acp($new)
+ {
+ $tpl = '
+
+ <dl>
+ <dt><label for="ldap_server">' . $this->user->lang['LDAP_SERVER'] . $this->user->lang['COLON'] . '</label><br /><span>' . $this->user->lang['LDAP_SERVER_EXPLAIN'] . '</span></dt>
+ <dd><input type="text" id="ldap_server" size="40" name="config[ldap_server]" value="' . $new['ldap_server'] . '" /></dd>
+ </dl>
+ <dl>
+ <dt><label for="ldap_port">' . $this->user->lang['LDAP_PORT'] . $this->user->lang['COLON'] . '</label><br /><span>' . $this->user->lang['LDAP_PORT_EXPLAIN'] . '</span></dt>
+ <dd><input type="text" id="ldap_port" size="40" name="config[ldap_port]" value="' . $new['ldap_port'] . '" /></dd>
+ </dl>
+ <dl>
+ <dt><label for="ldap_dn">' . $this->user->lang['LDAP_DN'] . $this->user->lang['COLON'] . '</label><br /><span>' . $this->user->lang['LDAP_DN_EXPLAIN'] . '</span></dt>
+ <dd><input type="text" id="ldap_dn" size="40" name="config[ldap_base_dn]" value="' . $new['ldap_base_dn'] . '" /></dd>
+ </dl>
+ <dl>
+ <dt><label for="ldap_uid">' . $this->user->lang['LDAP_UID'] . $this->user->lang['COLON'] . '</label><br /><span>' . $this->user->lang['LDAP_UID_EXPLAIN'] . '</span></dt>
+ <dd><input type="text" id="ldap_uid" size="40" name="config[ldap_uid]" value="' . $new['ldap_uid'] . '" /></dd>
+ </dl>
+ <dl>
+ <dt><label for="ldap_user_filter">' . $this->user->lang['LDAP_USER_FILTER'] . $this->user->lang['COLON'] . '</label><br /><span>' . $this->user->lang['LDAP_USER_FILTER_EXPLAIN'] . '</span></dt>
+ <dd><input type="text" id="ldap_user_filter" size="40" name="config[ldap_user_filter]" value="' . $new['ldap_user_filter'] . '" /></dd>
+ </dl>
+ <dl>
+ <dt><label for="ldap_email">' . $this->user->lang['LDAP_EMAIL'] . $this->user->lang['COLON'] . '</label><br /><span>' . $this->user->lang['LDAP_EMAIL_EXPLAIN'] . '</span></dt>
+ <dd><input type="email" id="ldap_email" size="40" name="config[ldap_email]" value="' . $new['ldap_email'] . '" /></dd>
+ </dl>
+ <dl>
+ <dt><label for="ldap_user">' . $this->user->lang['LDAP_USER'] . $this->user->lang['COLON'] . '</label><br /><span>' . $this->user->lang['LDAP_USER_EXPLAIN'] . '</span></dt>
+ <dd><input type="text" id="ldap_user" size="40" name="config[ldap_user]" value="' . $new['ldap_user'] . '" /></dd>
+ </dl>
+ <dl>
+ <dt><label for="ldap_password">' . $this->user->lang['LDAP_PASSWORD'] . $this->user->lang['COLON'] . '</label><br /><span>' . $this->user->lang['LDAP_PASSWORD_EXPLAIN'] . '</span></dt>
+ <dd><input type="password" id="ldap_password" size="40" name="config[ldap_password]" value="' . $new['ldap_password'] . '" autocomplete="off" /></dd>
+ </dl>
+ ';
+
+ // These are fields required in the config table
+ return array(
+ 'tpl' => $tpl,
+ 'config' => array('ldap_server', 'ldap_port', 'ldap_base_dn', 'ldap_uid', 'ldap_user_filter', 'ldap_email', 'ldap_user', 'ldap_password')
+ );
+ }
+
+ /**
+ * Generates a filter string for ldap_search to find a user
+ *
+ * @param $username string Username identifying the searched user
+ *
+ * @return string A filter string for ldap_search
+ */
+ private function ldap_user_filter($username)
+ {
+ $filter = '(' . $this->config['ldap_uid'] . '=' . $this->ldap_escape(htmlspecialchars_decode($username)) . ')';
+ if ($this->config['ldap_user_filter'])
+ {
+ $_filter = ($this->config['ldap_user_filter'][0] == '(' && substr($this->config['ldap_user_filter'], -1) == ')') ? $this->config['ldap_user_filter'] : "({$this->config['ldap_user_filter']})";
+ $filter = "(&{$filter}{$_filter})";
+ }
+ return $filter;
+ }
+
+ /**
+ * Escapes an LDAP AttributeValue
+ *
+ * @param string $string The string to be escaped
+ * @return string The escaped string
+ */
+ private function ldap_escape($string)
+ {
+ return str_replace(array('*', '\\', '(', ')'), array('\\*', '\\\\', '\\(', '\\)'), $string);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function logout($data, $new_session)
+ {
+ return;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function validate_session($user)
+ {
+ return;
+ }
+}
diff --git a/phpBB/includes/constants.php b/phpBB/includes/constants.php
index 8c27d3fd0c..96011f4ec5 100644
--- a/phpBB/includes/constants.php
+++ b/phpBB/includes/constants.php
@@ -156,6 +156,7 @@ define('PHYSICAL_LINK', 2);
define('CONFIRM_REG', 1);
define('CONFIRM_LOGIN', 2);
define('CONFIRM_POST', 3);
+define('CONFIRM_REPORT', 4);
// Categories - Attachments
define('ATTACHMENT_CATEGORY_NONE', 0);
diff --git a/phpBB/includes/db/driver/mssql_odbc.php b/phpBB/includes/db/driver/mssql_odbc.php
index cde9d332ba..a1d1a5d5dd 100644
--- a/phpBB/includes/db/driver/mssql_odbc.php
+++ b/phpBB/includes/db/driver/mssql_odbc.php
@@ -253,7 +253,7 @@ class phpbb_db_driver_mssql_odbc extends phpbb_db_driver_mssql_base
* Fetch current row
* @note number of bytes returned depends on odbc.defaultlrl php.ini setting. If it is limited to 4K for example only 4K of data is returned max.
*/
- function sql_fetchrow($query_id = false, $debug = false)
+ function sql_fetchrow($query_id = false)
{
global $cache;
diff --git a/phpBB/includes/db/driver/mssqlnative.php b/phpBB/includes/db/driver/mssqlnative.php
index 6f433e10cf..28fc88298a 100644
--- a/phpBB/includes/db/driver/mssqlnative.php
+++ b/phpBB/includes/db/driver/mssqlnative.php
@@ -326,7 +326,7 @@ class phpbb_db_driver_mssqlnative extends phpbb_db_driver_mssql_base
$this->sql_report('stop', $query);
}
- if ($cache_ttl)
+ if ($cache && $cache_ttl)
{
$this->open_queries[(int) $this->query_result] = $this->query_result;
$this->query_result = $cache->sql_save($this, $query, $this->query_result, $cache_ttl);
@@ -394,7 +394,7 @@ class phpbb_db_driver_mssqlnative extends phpbb_db_driver_mssql_base
*/
function sql_affectedrows()
{
- return (!empty($this->query_result)) ? @sqlsrv_rows_affected($this->query_result) : false;
+ return ($this->db_connect_id) ? @sqlsrv_rows_affected($this->query_result) : false;
}
/**
@@ -409,7 +409,7 @@ class phpbb_db_driver_mssqlnative extends phpbb_db_driver_mssql_base
$query_id = $this->query_result;
}
- if ($cache->sql_exists($query_id))
+ if ($cache && $cache->sql_exists($query_id))
{
return $cache->sql_fetchrow($query_id);
}
@@ -474,9 +474,9 @@ class phpbb_db_driver_mssqlnative extends phpbb_db_driver_mssql_base
return $cache->sql_freeresult($query_id);
}
- if (isset($this->open_queries[$query_id]))
+ if (isset($this->open_queries[(int) $query_id]))
{
- unset($this->open_queries[$query_id]);
+ unset($this->open_queries[(int) $query_id]);
return @sqlsrv_free_stmt($query_id);
}
return false;
diff --git a/phpBB/includes/db/migration/tool/module.php b/phpBB/includes/db/migration/tool/module.php
index ec683d36af..ac4d2c9bd7 100644
--- a/phpBB/includes/db/migration/tool/module.php
+++ b/phpBB/includes/db/migration/tool/module.php
@@ -209,9 +209,6 @@ class phpbb_db_migration_tool_module implements phpbb_db_migration_tool_interfac
}
// The "manual" way
- $module_log_name = ((isset($this->user->lang[$data['module_langname']])) ? $this->user->lang[$data['module_langname']] : $data['module_langname']);
- add_log('admin', 'LOG_MODULE_ADD', $module_log_name);
-
if (!is_numeric($parent))
{
$sql = 'SELECT module_id
@@ -267,6 +264,8 @@ class phpbb_db_migration_tool_module implements phpbb_db_migration_tool_interfac
else
{
// Success
+ $module_log_name = ((isset($this->user->lang[$data['module_langname']])) ? $this->user->lang[$data['module_langname']] : $data['module_langname']);
+ add_log('admin', 'LOG_MODULE_ADD', $module_log_name);
// Move the module if requested above/below an existing one
if (isset($data['before']) && $data['before'])
diff --git a/phpBB/includes/feed/base.php b/phpBB/includes/feed/base.php
new file mode 100644
index 0000000000..af28ee8dc8
--- /dev/null
+++ b/phpBB/includes/feed/base.php
@@ -0,0 +1,259 @@
+<?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;
+}
+
+/**
+* Base class with some generic functions and settings.
+*
+* @package phpBB3
+*/
+abstract class phpbb_feed_base
+{
+ /**
+ * Feed helper object
+ * @var phpbb_feed_helper
+ */
+ protected $helper;
+
+ /** @var phpbb_config */
+ protected $config;
+
+ /** @var phpbb_db_driver */
+ protected $db;
+
+ /** @var phpbb_cache_driver_interface */
+ protected $cache;
+
+ /** @var phpbb_user */
+ protected $user;
+
+ /** @var phpbb_auth */
+ protected $auth;
+
+ /** @var string */
+ protected $phpEx;
+
+ /**
+ * SQL Query to be executed to get feed items
+ */
+ var $sql = array();
+
+ /**
+ * Keys specified for retrieval of title, content, etc.
+ */
+ var $keys = array();
+
+ /**
+ * Number of items to fetch. Usually overwritten by $config['feed_something']
+ */
+ var $num_items = 15;
+
+ /**
+ * Separator for title elements to separate items (for example forum / topic)
+ */
+ var $separator = "\xE2\x80\xA2"; // &bull;
+
+ /**
+ * Separator for the statistics row (Posted by, post date, replies, etc.)
+ */
+ var $separator_stats = "\xE2\x80\x94"; // &mdash;
+
+ /**
+ * Constructor
+ *
+ * @param phpbb_feed_helper $helper Feed helper
+ * @param phpbb_config $config Config object
+ * @param phpbb_db_driver $db Database connection
+ * @param phpbb_cache_driver_interface $cache Cache object
+ * @param phpbb_user $user User object
+ * @param phpbb_auth $auth Auth object
+ * @param string $phpEx php file extension
+ * @return null
+ */
+ function __construct(phpbb_feed_helper $helper, phpbb_config $config, phpbb_db_driver $db, phpbb_cache_driver_interface $cache, phpbb_user $user, phpbb_auth $auth, $phpEx)
+ {
+ $this->config = $config;
+ $this->helper = $helper;
+ $this->db = $db;
+ $this->cache = $cache;
+ $this->user = $user;
+ $this->auth = $auth;
+ $this->phpEx = $phpEx;
+
+ $this->set_keys();
+
+ // Allow num_items to be string
+ if (is_string($this->num_items))
+ {
+ $this->num_items = (int) $this->config[$this->num_items];
+
+ // A precaution
+ if (!$this->num_items)
+ {
+ $this->num_items = 10;
+ }
+ }
+ }
+
+ /**
+ * Set keys.
+ */
+ function set_keys()
+ {
+ }
+
+ /**
+ * Open feed
+ */
+ function open()
+ {
+ }
+
+ /**
+ * Close feed
+ */
+ function close()
+ {
+ if (!empty($this->result))
+ {
+ $this->db->sql_freeresult($this->result);
+ }
+ }
+
+ /**
+ * Set key
+ */
+ function set($key, $value)
+ {
+ $this->keys[$key] = $value;
+ }
+
+ /**
+ * Get key
+ */
+ function get($key)
+ {
+ return (isset($this->keys[$key])) ? $this->keys[$key] : NULL;
+ }
+
+ function get_readable_forums()
+ {
+ static $forum_ids;
+
+ if (!isset($forum_ids))
+ {
+ $forum_ids = array_keys($this->auth->acl_getf('f_read', true));
+ }
+
+ return $forum_ids;
+ }
+
+ function get_moderator_approve_forums()
+ {
+ static $forum_ids;
+
+ if (!isset($forum_ids))
+ {
+ $forum_ids = array_keys($this->auth->acl_getf('m_approve', true));
+ }
+
+ return $forum_ids;
+ }
+
+ function is_moderator_approve_forum($forum_id)
+ {
+ static $forum_ids;
+
+ if (!isset($forum_ids))
+ {
+ $forum_ids = array_flip($this->get_moderator_approve_forums());
+ }
+
+ return (isset($forum_ids[$forum_id])) ? true : false;
+ }
+
+ function get_excluded_forums()
+ {
+ static $forum_ids;
+
+ // Matches acp/acp_board.php
+ $cache_name = 'feed_excluded_forum_ids';
+
+ if (!isset($forum_ids) && ($forum_ids = $this->cache->get('_' . $cache_name)) === false)
+ {
+ $sql = 'SELECT forum_id
+ FROM ' . FORUMS_TABLE . '
+ WHERE ' . $this->db->sql_bit_and('forum_options', FORUM_OPTION_FEED_EXCLUDE, '<> 0');
+ $result = $this->db->sql_query($sql);
+
+ $forum_ids = array();
+ while ($forum_id = (int) $this->db->sql_fetchfield('forum_id'))
+ {
+ $forum_ids[$forum_id] = $forum_id;
+ }
+ $this->db->sql_freeresult($result);
+
+ $this->cache->put('_' . $cache_name, $forum_ids);
+ }
+
+ return $forum_ids;
+ }
+
+ function is_excluded_forum($forum_id)
+ {
+ $forum_ids = $this->get_excluded_forums();
+
+ return isset($forum_ids[$forum_id]) ? true : false;
+ }
+
+ function get_passworded_forums()
+ {
+ return $this->user->get_passworded_forums();
+ }
+
+ function get_item()
+ {
+ static $result;
+
+ if (!isset($result))
+ {
+ if (!$this->get_sql())
+ {
+ return false;
+ }
+
+ // Query database
+ $sql = $this->db->sql_build_query('SELECT', $this->sql);
+ $result = $this->db->sql_query_limit($sql, $this->num_items);
+ }
+
+ return $this->db->sql_fetchrow($result);
+ }
+
+ function user_viewprofile($row)
+ {
+ $author_id = (int) $row[$this->get('author_id')];
+
+ if ($author_id == ANONYMOUS)
+ {
+ // Since we cannot link to a profile, we just return GUEST
+ // instead of $row['username']
+ return $this->user->lang['GUEST'];
+ }
+
+ return '<a href="' . $this->helper->append_sid('memberlist.' . $this->phpEx, 'mode=viewprofile&amp;u=' . $author_id) . '">' . $row[$this->get('creator')] . '</a>';
+ }
+}
diff --git a/phpBB/includes/feed/factory.php b/phpBB/includes/feed/factory.php
new file mode 100644
index 0000000000..63a1eb8ef0
--- /dev/null
+++ b/phpBB/includes/feed/factory.php
@@ -0,0 +1,129 @@
+<?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;
+}
+
+/**
+* Factory class to return correct object
+* @package phpBB3
+*/
+class phpbb_feed_factory
+{
+ /**
+ * Service container object
+ * @var object
+ */
+ protected $container;
+
+ /** @var phpbb_config */
+ protected $config;
+
+ /** @var phpbb_db_driver */
+ protected $db;
+
+ /**
+ * Constructor
+ *
+ * @param objec $container Container object
+ * @param phpbb_config $config Config object
+ * @param phpbb_db_driver $db Database connection
+ * @return null
+ */
+ public function __construct($container, phpbb_config $config, phpbb_db_driver $db)
+ {
+ $this->container = $container;
+ $this->config = $config;
+ $this->db = $db;
+ }
+
+ /**
+ * Return correct object for specified mode
+ *
+ * @param string $mode The feeds mode.
+ * @param int $forum_id Forum id specified by the script if forum feed provided.
+ * @param int $topic_id Topic id specified by the script if topic feed provided.
+ *
+ * @return object Returns correct feeds object for specified mode.
+ */
+ function get_feed($mode, $forum_id, $topic_id)
+ {
+ switch ($mode)
+ {
+ case 'forums':
+ if (!$this->config['feed_overall_forums'])
+ {
+ return false;
+ }
+
+ return $this->container->get('feed.forums');
+ break;
+
+ case 'topics':
+ case 'topics_new':
+ if (!$this->config['feed_topics_new'])
+ {
+ return false;
+ }
+
+ return $this->container->get('feed.topics');
+ break;
+
+ case 'topics_active':
+ if (!$this->config['feed_topics_active'])
+ {
+ return false;
+ }
+
+ return $this->container->get('feed.topics_active');
+ break;
+
+ case 'news':
+ // Get at least one news forum
+ $sql = 'SELECT forum_id
+ FROM ' . FORUMS_TABLE . '
+ WHERE ' . $this->db->sql_bit_and('forum_options', FORUM_OPTION_FEED_NEWS, '<> 0');
+ $result = $this->db->sql_query_limit($sql, 1, 0, 600);
+ $s_feed_news = (int) $this->db->sql_fetchfield('forum_id');
+ $this->db->sql_freeresult($result);
+
+ if (!$s_feed_news)
+ {
+ return false;
+ }
+
+ return $this->container->get('feed.news');
+ break;
+
+ default:
+ if ($topic_id && $this->config['feed_topic'])
+ {
+ return $this->container->get('feed.topic')
+ ->set_topic_id($topic_id);
+ }
+ else if ($forum_id && $this->config['feed_forum'])
+ {
+ return $this->container->get('feed.forum')
+ ->set_forum_id($forum_id);
+ }
+ else if ($this->config['feed_overall'])
+ {
+ return $this->container->get('feed.overall');
+ }
+
+ return false;
+ break;
+ }
+ }
+}
diff --git a/phpBB/includes/feed/forum.php b/phpBB/includes/feed/forum.php
new file mode 100644
index 0000000000..7670fbeaaa
--- /dev/null
+++ b/phpBB/includes/feed/forum.php
@@ -0,0 +1,147 @@
+<?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;
+}
+
+/**
+* Forum feed
+*
+* This will give you the last {$this->num_items} posts made
+* within a specific forum.
+*
+* @package phpBB3
+*/
+class phpbb_feed_forum extends phpbb_feed_post_base
+{
+ var $forum_id = 0;
+ var $forum_data = array();
+
+ /**
+ * Set the Forum ID
+ *
+ * @param int $forum_id Forum ID
+ * @return phpbb_feed_forum
+ */
+ public function set_forum_id($topic_id)
+ {
+ $this->forum_id = (int) $forum_id;
+
+ return $this;
+ }
+
+ function open()
+ {
+ // Check if forum exists
+ $sql = 'SELECT forum_id, forum_name, forum_password, forum_type, forum_options
+ FROM ' . FORUMS_TABLE . '
+ WHERE forum_id = ' . $this->forum_id;
+ $result = $this->db->sql_query($sql);
+ $this->forum_data = $this->db->sql_fetchrow($result);
+ $this->db->sql_freeresult($result);
+
+ if (empty($this->forum_data))
+ {
+ trigger_error('NO_FORUM');
+ }
+
+ // Forum needs to be postable
+ if ($this->forum_data['forum_type'] != FORUM_POST)
+ {
+ trigger_error('NO_FEED');
+ }
+
+ // Make sure forum is not excluded from feed
+ if (phpbb_optionget(FORUM_OPTION_FEED_EXCLUDE, $this->forum_data['forum_options']))
+ {
+ trigger_error('NO_FEED');
+ }
+
+ // Make sure we can read this forum
+ if (!$this->auth->acl_get('f_read', $this->forum_id))
+ {
+ trigger_error('SORRY_AUTH_READ');
+ }
+
+ // Make sure forum is not passworded or user is authed
+ if ($this->forum_data['forum_password'])
+ {
+ $forum_ids_passworded = $this->get_passworded_forums();
+
+ if (isset($forum_ids_passworded[$this->forum_id]))
+ {
+ trigger_error('SORRY_AUTH_READ');
+ }
+
+ unset($forum_ids_passworded);
+ }
+ }
+
+ function get_sql()
+ {
+ $m_approve = ($this->auth->acl_get('m_approve', $this->forum_id)) ? true : false;
+
+ // Determine topics with recent activity
+ $sql = 'SELECT topic_id, topic_last_post_time
+ FROM ' . TOPICS_TABLE . '
+ WHERE forum_id = ' . $this->forum_id . '
+ AND topic_moved_id = 0
+ ' . ((!$m_approve) ? 'AND topic_approved = 1' : '') . '
+ ORDER BY topic_last_post_time DESC';
+ $result = $this->db->sql_query_limit($sql, $this->num_items);
+
+ $topic_ids = array();
+ $min_post_time = 0;
+ while ($row = $this->db->sql_fetchrow())
+ {
+ $topic_ids[] = (int) $row['topic_id'];
+
+ $min_post_time = (int) $row['topic_last_post_time'];
+ }
+ $this->db->sql_freeresult($result);
+
+ if (empty($topic_ids))
+ {
+ return false;
+ }
+
+ $this->sql = array(
+ 'SELECT' => 'p.post_id, p.topic_id, p.post_time, p.post_edit_time, p.post_approved, p.post_subject, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url, ' .
+ 'u.username, u.user_id',
+ 'FROM' => array(
+ POSTS_TABLE => 'p',
+ USERS_TABLE => 'u',
+ ),
+ 'WHERE' => $this->db->sql_in_set('p.topic_id', $topic_ids) . '
+ ' . ((!$m_approve) ? 'AND p.post_approved = 1' : '') . '
+ AND p.post_time >= ' . $min_post_time . '
+ AND p.poster_id = u.user_id',
+ 'ORDER_BY' => 'p.post_time DESC',
+ );
+
+ return true;
+ }
+
+ function adjust_item(&$item_row, &$row)
+ {
+ parent::adjust_item($item_row, $row);
+
+ $item_row['title'] = (isset($row['forum_name']) && $row['forum_name'] !== '') ? $row['forum_name'] . ' ' . $this->separator . ' ' . $item_row['title'] : $item_row['title'];
+ }
+
+ function get_item()
+ {
+ return ($row = parent::get_item()) ? array_merge($this->forum_data, $row) : $row;
+ }
+}
diff --git a/phpBB/includes/feed/forums.php b/phpBB/includes/feed/forums.php
new file mode 100644
index 0000000000..72f786aa6a
--- /dev/null
+++ b/phpBB/includes/feed/forums.php
@@ -0,0 +1,72 @@
+<?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;
+}
+
+/**
+* 'All Forums' feed
+*
+* This will give you a list of all postable forums where feeds are enabled
+* including forum description, topic stats and post stats
+*
+* @package phpBB3
+*/
+class phpbb_feed_forums extends phpbb_feed_base
+{
+ var $num_items = 0;
+
+ function set_keys()
+ {
+ $this->set('title', 'forum_name');
+ $this->set('text', 'forum_desc');
+ $this->set('bitfield', 'forum_desc_bitfield');
+ $this->set('bbcode_uid','forum_desc_uid');
+ $this->set('updated', 'forum_last_post_time');
+ $this->set('options', 'forum_desc_options');
+ }
+
+ function get_sql()
+ {
+ $in_fid_ary = array_diff($this->get_readable_forums(), $this->get_excluded_forums());
+ if (empty($in_fid_ary))
+ {
+ return false;
+ }
+
+ // Build SQL Query
+ $this->sql = array(
+ 'SELECT' => 'f.forum_id, f.left_id, f.forum_name, f.forum_last_post_time,
+ f.forum_desc, f.forum_desc_bitfield, f.forum_desc_uid, f.forum_desc_options,
+ f.forum_topics, f.forum_posts',
+ 'FROM' => array(FORUMS_TABLE => 'f'),
+ 'WHERE' => 'f.forum_type = ' . FORUM_POST . '
+ AND ' . $this->db->sql_in_set('f.forum_id', $in_fid_ary),
+ 'ORDER_BY' => 'f.left_id ASC',
+ );
+
+ return true;
+ }
+
+ function adjust_item(&$item_row, &$row)
+ {
+ $item_row['link'] = $this->helper->append_sid('viewforum.' . $this->phpEx, 'f=' . $row['forum_id']);
+
+ if ($this->config['feed_item_statistics'])
+ {
+ $item_row['statistics'] = $this->user->lang('TOTAL_TOPICS', (int) $row['forum_topics'])
+ . ' ' . $this->separator_stats . ' ' . $this->user->lang('TOTAL_POSTS_COUNT', (int) $row['forum_posts']);
+ }
+ }
+}
diff --git a/phpBB/includes/feed/helper.php b/phpBB/includes/feed/helper.php
new file mode 100644
index 0000000000..93330aa2ad
--- /dev/null
+++ b/phpBB/includes/feed/helper.php
@@ -0,0 +1,159 @@
+<?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;
+}
+
+/**
+* Class with some helpful functions used in feeds
+* @package phpBB3
+*/
+class phpbb_feed_helper
+{
+ /** @var phpbb_config */
+ protected $config;
+
+ /** @var phpbb_user */
+ protected $user;
+
+ /** @var string */
+ protected $phpbb_root_path;
+
+ /**
+ * Constructor
+ *
+ * @param phpbb_config $config Config object
+ * @param phpbb_user $user User object
+ * @param string $phpbb_root_path Root path
+ * @return null
+ */
+ public function __construct(phpbb_config $config, phpbb_user $user, $phpbb_root_path)
+ {
+ $this->config = $config;
+ $this->user = $user;
+ $this->phpbb_root_path = $phpbb_root_path;
+ }
+
+ /**
+ * Run links through append_sid(), prepend generate_board_url() and remove session id
+ */
+ public function get_board_url()
+ {
+ static $board_url;
+
+ if (empty($board_url))
+ {
+ $board_url = generate_board_url();
+ }
+
+ return $board_url;
+ }
+
+ /**
+ * Run links through append_sid(), prepend generate_board_url() and remove session id
+ */
+ public function append_sid($url, $params)
+ {
+ return append_sid($this->get_board_url() . '/' . $url, $params, true, '');
+ }
+
+ /**
+ * Generate ISO 8601 date string (RFC 3339)
+ */
+ public function format_date($time)
+ {
+ static $zone_offset;
+ static $offset_string;
+
+ if (empty($offset_string))
+ {
+ $zone_offset = $this->user->create_datetime()->getOffset();
+ $offset_string = phpbb_format_timezone_offset($zone_offset);
+ }
+
+ return gmdate("Y-m-d\TH:i:s", $time + $zone_offset) . $offset_string;
+ }
+
+ /**
+ * Generate text content
+ */
+ public function generate_content($content, $uid, $bitfield, $options)
+ {
+ if (empty($content))
+ {
+ return '';
+ }
+
+ // Prepare some bbcodes for better parsing
+ $content = preg_replace("#\[quote(=&quot;.*?&quot;)?:$uid\]\s*(.*?)\s*\[/quote:$uid\]#si", "[quote$1:$uid]<br />$2<br />[/quote:$uid]", $content);
+
+ $content = generate_text_for_display($content, $uid, $bitfield, $options);
+
+ // Add newlines
+ $content = str_replace('<br />', '<br />' . "\n", $content);
+
+ // Convert smiley Relative paths to Absolute path, Windows style
+ $content = str_replace($this->phpbb_root_path . $this->config['smilies_path'], $this->get_board_url() . '/' . $this->config['smilies_path'], $content);
+
+ // Remove "Select all" link and mouse events
+ $content = str_replace('<a href="#" onclick="selectCode(this); return false;">' . $this->user->lang['SELECT_ALL_CODE'] . '</a>', '', $content);
+ $content = preg_replace('#(onkeypress|onclick)="(.*?)"#si', '', $content);
+
+ // Firefox does not support CSS for feeds, though
+
+ // Remove font sizes
+ // $content = preg_replace('#<span style="font-size: [0-9]+%; line-height: [0-9]+%;">([^>]+)</span>#iU', '\1', $content);
+
+ // Make text strong :P
+ // $content = preg_replace('#<span style="font-weight: bold?">(.*?)</span>#iU', '<strong>\1</strong>', $content);
+
+ // Italic
+ // $content = preg_replace('#<span style="font-style: italic?">([^<]+)</span>#iU', '<em>\1</em>', $content);
+
+ // Underline
+ // $content = preg_replace('#<span style="text-decoration: underline?">([^<]+)</span>#iU', '<u>\1</u>', $content);
+
+ // Remove embed Windows Media Streams
+ $content = preg_replace( '#<\!--\[if \!IE\]>-->([^[]+)<\!--<!\[endif\]-->#si', '', $content);
+
+ // Do not use &lt; and &gt;, because we want to retain code contained in [code][/code]
+
+ // Remove embed and objects
+ $content = preg_replace( '#<(object|embed)(.*?) (value|src)=(.*?) ([^[]+)(object|embed)>#si',' <a href=$4 target="_blank"><strong>$1</strong></a> ',$content);
+
+ // Remove some specials html tag, because somewhere there are a mod to allow html tags ;)
+ $content = preg_replace( '#<(script|iframe)([^[]+)\1>#siU', ' <strong>$1</strong> ', $content);
+
+ // Remove Comments from inline attachments [ia]
+ $content = preg_replace('#<div class="(inline-attachment|attachtitle)">(.*?)<!-- ia(.*?) -->(.*?)<!-- ia(.*?) -->(.*?)</div>#si','$4',$content);
+
+ // Replace some entities with their unicode counterpart
+ $entities = array(
+ '&nbsp;' => "\xC2\xA0",
+ '&bull;' => "\xE2\x80\xA2",
+ '&middot;' => "\xC2\xB7",
+ '&copy;' => "\xC2\xA9",
+ );
+
+ $content = str_replace(array_keys($entities), array_values($entities), $content);
+
+ // Remove CDATA blocks. ;)
+ $content = preg_replace('#\<\!\[CDATA\[(.*?)\]\]\>#s', '', $content);
+
+ // Other control characters
+ $content = preg_replace('#(?:[\x00-\x1F\x7F]+|(?:\xC2[\x80-\x9F])+)#', '', $content);
+
+ return $content;
+ }
+}
diff --git a/phpBB/includes/feed/news.php b/phpBB/includes/feed/news.php
new file mode 100644
index 0000000000..92cc18a3ab
--- /dev/null
+++ b/phpBB/includes/feed/news.php
@@ -0,0 +1,112 @@
+<?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;
+}
+
+/**
+* News feed
+*
+* This will give you {$this->num_items} first posts
+* of all topics in the selected news forums.
+*
+* @package phpBB3
+*/
+class phpbb_feed_news extends phpbb_feed_topic_base
+{
+ function get_news_forums()
+ {
+ static $forum_ids;
+
+ // Matches acp/acp_board.php
+ $cache_name = 'feed_news_forum_ids';
+
+ if (!isset($forum_ids) && ($forum_ids = $this->cache->get('_' . $cache_name)) === false)
+ {
+ $sql = 'SELECT forum_id
+ FROM ' . FORUMS_TABLE . '
+ WHERE ' . $this->db->sql_bit_and('forum_options', FORUM_OPTION_FEED_NEWS, '<> 0');
+ $result = $this->db->sql_query($sql);
+
+ $forum_ids = array();
+ while ($forum_id = (int) $this->db->sql_fetchfield('forum_id'))
+ {
+ $forum_ids[$forum_id] = $forum_id;
+ }
+ $this->db->sql_freeresult($result);
+
+ $this->cache->put('_' . $cache_name, $forum_ids);
+ }
+
+ return $forum_ids;
+ }
+
+ function get_sql()
+ {
+ // Determine forum ids
+ $in_fid_ary = array_intersect($this->get_news_forums(), $this->get_readable_forums());
+ if (empty($in_fid_ary))
+ {
+ return false;
+ }
+
+ $in_fid_ary = array_diff($in_fid_ary, $this->get_passworded_forums());
+ if (empty($in_fid_ary))
+ {
+ return false;
+ }
+
+ // We really have to get the post ids first!
+ $sql = 'SELECT topic_first_post_id, topic_time
+ FROM ' . TOPICS_TABLE . '
+ WHERE ' . $this->db->sql_in_set('forum_id', $in_fid_ary) . '
+ AND topic_moved_id = 0
+ AND topic_approved = 1
+ ORDER BY topic_time DESC';
+ $result = $this->db->sql_query_limit($sql, $this->num_items);
+
+ $post_ids = array();
+ while ($row = $this->db->sql_fetchrow($result))
+ {
+ $post_ids[] = (int) $row['topic_first_post_id'];
+ }
+ $this->db->sql_freeresult($result);
+
+ if (empty($post_ids))
+ {
+ return false;
+ }
+
+ $this->sql = array(
+ 'SELECT' => 'f.forum_id, f.forum_name,
+ t.topic_id, t.topic_title, t.topic_poster, t.topic_first_poster_name, t.topic_replies, t.topic_replies_real, t.topic_views, t.topic_time, t.topic_last_post_time,
+ p.post_id, p.post_time, p.post_edit_time, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url',
+ 'FROM' => array(
+ TOPICS_TABLE => 't',
+ POSTS_TABLE => 'p',
+ ),
+ 'LEFT_JOIN' => array(
+ array(
+ 'FROM' => array(FORUMS_TABLE => 'f'),
+ 'ON' => 'p.forum_id = f.forum_id',
+ ),
+ ),
+ 'WHERE' => 'p.topic_id = t.topic_id
+ AND ' . $this->db->sql_in_set('p.post_id', $post_ids),
+ 'ORDER_BY' => 'p.post_time DESC',
+ );
+
+ return true;
+ }
+}
diff --git a/phpBB/includes/feed/overall.php b/phpBB/includes/feed/overall.php
new file mode 100644
index 0000000000..5fb922f6bb
--- /dev/null
+++ b/phpBB/includes/feed/overall.php
@@ -0,0 +1,97 @@
+<?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;
+}
+
+/**
+* Board wide feed (aka overall feed)
+*
+* This will give you the newest {$this->num_items} posts
+* from the whole board.
+*
+* @package phpBB3
+*/
+class phpbb_feed_overall extends phpbb_feed_post_base
+{
+ function get_sql()
+ {
+ $forum_ids = array_diff($this->get_readable_forums(), $this->get_excluded_forums(), $this->get_passworded_forums());
+ if (empty($forum_ids))
+ {
+ return false;
+ }
+
+ // m_approve forums
+ $fid_m_approve = $this->get_moderator_approve_forums();
+ $sql_m_approve = (!empty($fid_m_approve)) ? 'OR ' . $this->db->sql_in_set('forum_id', $fid_m_approve) : '';
+
+ // Determine topics with recent activity
+ $sql = 'SELECT topic_id, topic_last_post_time
+ FROM ' . TOPICS_TABLE . '
+ WHERE ' . $this->db->sql_in_set('forum_id', $forum_ids) . '
+ AND topic_moved_id = 0
+ AND (topic_approved = 1
+ ' . $sql_m_approve . ')
+ ORDER BY topic_last_post_time DESC';
+ $result = $this->db->sql_query_limit($sql, $this->num_items);
+
+ $topic_ids = array();
+ $min_post_time = 0;
+ while ($row = $this->db->sql_fetchrow())
+ {
+ $topic_ids[] = (int) $row['topic_id'];
+
+ $min_post_time = (int) $row['topic_last_post_time'];
+ }
+ $this->db->sql_freeresult($result);
+
+ if (empty($topic_ids))
+ {
+ return false;
+ }
+
+ // Get the actual data
+ $this->sql = array(
+ 'SELECT' => 'f.forum_id, f.forum_name, ' .
+ 'p.post_id, p.topic_id, p.post_time, p.post_edit_time, p.post_approved, p.post_subject, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url, ' .
+ 'u.username, u.user_id',
+ 'FROM' => array(
+ USERS_TABLE => 'u',
+ POSTS_TABLE => 'p',
+ ),
+ 'LEFT_JOIN' => array(
+ array(
+ 'FROM' => array(FORUMS_TABLE => 'f'),
+ 'ON' => 'f.forum_id = p.forum_id',
+ ),
+ ),
+ 'WHERE' => $this->db->sql_in_set('p.topic_id', $topic_ids) . '
+ AND (p.post_approved = 1
+ ' . str_replace('forum_id', 'p.forum_id', $sql_m_approve) . ')
+ AND p.post_time >= ' . $min_post_time . '
+ AND u.user_id = p.poster_id',
+ 'ORDER_BY' => 'p.post_time DESC',
+ );
+
+ return true;
+ }
+
+ function adjust_item(&$item_row, &$row)
+ {
+ parent::adjust_item($item_row, $row);
+
+ $item_row['title'] = (isset($row['forum_name']) && $row['forum_name'] !== '') ? $row['forum_name'] . ' ' . $this->separator . ' ' . $item_row['title'] : $item_row['title'];
+ }
+}
diff --git a/phpBB/includes/feed/post_base.php b/phpBB/includes/feed/post_base.php
new file mode 100644
index 0000000000..a25ed50263
--- /dev/null
+++ b/phpBB/includes/feed/post_base.php
@@ -0,0 +1,57 @@
+<?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 for post based feeds
+*
+* @package phpBB3
+*/
+abstract class phpbb_feed_post_base extends phpbb_feed_base
+{
+ var $num_items = 'feed_limit_post';
+
+ function set_keys()
+ {
+ $this->set('title', 'post_subject');
+ $this->set('title2', 'topic_title');
+
+ $this->set('author_id', 'user_id');
+ $this->set('creator', 'username');
+ $this->set('published', 'post_time');
+ $this->set('updated', 'post_edit_time');
+ $this->set('text', 'post_text');
+
+ $this->set('bitfield', 'bbcode_bitfield');
+ $this->set('bbcode_uid','bbcode_uid');
+
+ $this->set('enable_bbcode', 'enable_bbcode');
+ $this->set('enable_smilies', 'enable_smilies');
+ $this->set('enable_magic_url', 'enable_magic_url');
+ }
+
+ function adjust_item(&$item_row, &$row)
+ {
+ $item_row['link'] = $this->helper->append_sid('viewtopic.' . $this->phpEx, "t={$row['topic_id']}&amp;p={$row['post_id']}#p{$row['post_id']}");
+
+ if ($this->config['feed_item_statistics'])
+ {
+ $item_row['statistics'] = $this->user->lang['POSTED'] . ' ' . $this->user->lang['POST_BY_AUTHOR'] . ' ' . $this->user_viewprofile($row)
+ . ' ' . $this->separator_stats . ' ' . $this->user->format_date($row[$this->get('published')])
+ . (($this->is_moderator_approve_forum($row['forum_id']) && !$row['post_approved']) ? ' ' . $this->separator_stats . ' ' . $this->user->lang['POST_UNAPPROVED'] : '');
+ }
+ }
+}
diff --git a/phpBB/includes/feed/topic.php b/phpBB/includes/feed/topic.php
new file mode 100644
index 0000000000..7d9a344982
--- /dev/null
+++ b/phpBB/includes/feed/topic.php
@@ -0,0 +1,116 @@
+<?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;
+}
+
+/**
+* Topic feed for a specific topic
+*
+* This will give you the last {$this->num_items} posts made within this topic.
+*
+* @package phpBB3
+*/
+class phpbb_feed_topic extends phpbb_feed_post_base
+{
+ var $topic_id = 0;
+ var $forum_id = 0;
+ var $topic_data = array();
+
+ /**
+ * Set the Topic ID
+ *
+ * @param int $topic_id Topic ID
+ * @return phpbb_feed_topic
+ */
+ public function set_topic_id($topic_id)
+ {
+ $this->topic_id = (int) $topic_id;
+
+ return $this;
+ }
+
+ function open()
+ {
+ $sql = 'SELECT f.forum_options, f.forum_password, t.topic_id, t.forum_id, t.topic_approved, t.topic_title, t.topic_time, t.topic_views, t.topic_replies, t.topic_type
+ FROM ' . TOPICS_TABLE . ' t
+ LEFT JOIN ' . FORUMS_TABLE . ' f
+ ON (f.forum_id = t.forum_id)
+ WHERE t.topic_id = ' . $this->topic_id;
+ $result = $this->db->sql_query($sql);
+ $this->topic_data = $this->db->sql_fetchrow($result);
+ $this->db->sql_freeresult($result);
+
+ if (empty($this->topic_data))
+ {
+ trigger_error('NO_TOPIC');
+ }
+
+ $this->forum_id = (int) $this->topic_data['forum_id'];
+
+ // Make sure topic is either approved or user authed
+ if (!$this->topic_data['topic_approved'] && !$this->auth->acl_get('m_approve', $this->forum_id))
+ {
+ trigger_error('SORRY_AUTH_READ');
+ }
+
+ // Make sure forum is not excluded from feed
+ if (phpbb_optionget(FORUM_OPTION_FEED_EXCLUDE, $this->topic_data['forum_options']))
+ {
+ trigger_error('NO_FEED');
+ }
+
+ // Make sure we can read this forum
+ if (!$this->auth->acl_get('f_read', $this->forum_id))
+ {
+ trigger_error('SORRY_AUTH_READ');
+ }
+
+ // Make sure forum is not passworded or user is authed
+ if ($this->topic_data['forum_password'])
+ {
+ $forum_ids_passworded = $this->get_passworded_forums();
+
+ if (isset($forum_ids_passworded[$this->forum_id]))
+ {
+ trigger_error('SORRY_AUTH_READ');
+ }
+
+ unset($forum_ids_passworded);
+ }
+ }
+
+ function get_sql()
+ {
+ $this->sql = array(
+ 'SELECT' => 'p.post_id, p.post_time, p.post_edit_time, p.post_approved, p.post_subject, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url, ' .
+ 'u.username, u.user_id',
+ 'FROM' => array(
+ POSTS_TABLE => 'p',
+ USERS_TABLE => 'u',
+ ),
+ 'WHERE' => 'p.topic_id = ' . $this->topic_id . '
+ ' . ($this->forum_id && !$this->auth->acl_get('m_approve', $this->forum_id) ? 'AND p.post_approved = 1' : '') . '
+ AND p.poster_id = u.user_id',
+ 'ORDER_BY' => 'p.post_time DESC',
+ );
+
+ return true;
+ }
+
+ function get_item()
+ {
+ return ($row = parent::get_item()) ? array_merge($this->topic_data, $row) : $row;
+ }
+}
diff --git a/phpBB/includes/feed/topic_base.php b/phpBB/includes/feed/topic_base.php
new file mode 100644
index 0000000000..e6a47b4c86
--- /dev/null
+++ b/phpBB/includes/feed/topic_base.php
@@ -0,0 +1,59 @@
+<?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 for topic based feeds
+*
+* @package phpBB3
+*/
+abstract class phpbb_feed_topic_base extends phpbb_feed_base
+{
+ var $num_items = 'feed_limit_topic';
+
+ function set_keys()
+ {
+ $this->set('title', 'topic_title');
+ $this->set('title2', 'forum_name');
+
+ $this->set('author_id', 'topic_poster');
+ $this->set('creator', 'topic_first_poster_name');
+ $this->set('published', 'post_time');
+ $this->set('updated', 'post_edit_time');
+ $this->set('text', 'post_text');
+
+ $this->set('bitfield', 'bbcode_bitfield');
+ $this->set('bbcode_uid','bbcode_uid');
+
+ $this->set('enable_bbcode', 'enable_bbcode');
+ $this->set('enable_smilies', 'enable_smilies');
+ $this->set('enable_magic_url', 'enable_magic_url');
+ }
+
+ function adjust_item(&$item_row, &$row)
+ {
+ $item_row['link'] = $this->helper->append_sid('viewtopic.' . $this->phpEx, 't=' . $row['topic_id'] . '&amp;p=' . $row['post_id'] . '#p' . $row['post_id']);
+
+ if ($this->config['feed_item_statistics'])
+ {
+ $item_row['statistics'] = $this->user->lang['POSTED'] . ' ' . $this->user->lang['POST_BY_AUTHOR'] . ' ' . $this->user_viewprofile($row)
+ . ' ' . $this->separator_stats . ' ' . $this->user->format_date($row[$this->get('published')])
+ . ' ' . $this->separator_stats . ' ' . $this->user->lang['REPLIES'] . ' ' . (($this->is_moderator_approve_forum($row['forum_id'])) ? $row['topic_replies_real'] : $row['topic_replies'])
+ . ' ' . $this->separator_stats . ' ' . $this->user->lang['VIEWS'] . ' ' . $row['topic_views']
+ . (($this->is_moderator_approve_forum($row['forum_id']) && ($row['topic_replies_real'] != $row['topic_replies'])) ? ' ' . $this->separator_stats . ' ' . $this->user->lang['POSTS_UNAPPROVED'] : '');
+ }
+ }
+}
diff --git a/phpBB/includes/feed/topics.php b/phpBB/includes/feed/topics.php
new file mode 100644
index 0000000000..c8761d7176
--- /dev/null
+++ b/phpBB/includes/feed/topics.php
@@ -0,0 +1,91 @@
+<?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;
+}
+
+/**
+* New Topics feed
+*
+* This will give you the last {$this->num_items} created topics
+* including the first post.
+*
+* @package phpBB3
+*/
+class phpbb_feed_topics extends phpbb_feed_topic_base
+{
+ function get_sql()
+ {
+ $forum_ids_read = $this->get_readable_forums();
+ if (empty($forum_ids_read))
+ {
+ return false;
+ }
+
+ $in_fid_ary = array_diff($forum_ids_read, $this->get_excluded_forums(), $this->get_passworded_forums());
+ if (empty($in_fid_ary))
+ {
+ return false;
+ }
+
+ // We really have to get the post ids first!
+ $sql = 'SELECT topic_first_post_id, topic_time
+ FROM ' . TOPICS_TABLE . '
+ WHERE ' . $this->db->sql_in_set('forum_id', $in_fid_ary) . '
+ AND topic_moved_id = 0
+ AND topic_approved = 1
+ ORDER BY topic_time DESC';
+ $result = $this->db->sql_query_limit($sql, $this->num_items);
+
+ $post_ids = array();
+ while ($row = $this->db->sql_fetchrow($result))
+ {
+ $post_ids[] = (int) $row['topic_first_post_id'];
+ }
+ $this->db->sql_freeresult($result);
+
+ if (empty($post_ids))
+ {
+ return false;
+ }
+
+ $this->sql = array(
+ 'SELECT' => 'f.forum_id, f.forum_name,
+ t.topic_id, t.topic_title, t.topic_poster, t.topic_first_poster_name, t.topic_replies, t.topic_replies_real, t.topic_views, t.topic_time, t.topic_last_post_time,
+ p.post_id, p.post_time, p.post_edit_time, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url',
+ 'FROM' => array(
+ TOPICS_TABLE => 't',
+ POSTS_TABLE => 'p',
+ ),
+ 'LEFT_JOIN' => array(
+ array(
+ 'FROM' => array(FORUMS_TABLE => 'f'),
+ 'ON' => 'p.forum_id = f.forum_id',
+ ),
+ ),
+ 'WHERE' => 'p.topic_id = t.topic_id
+ AND ' . $this->db->sql_in_set('p.post_id', $post_ids),
+ 'ORDER_BY' => 'p.post_time DESC',
+ );
+
+ return true;
+ }
+
+ function adjust_item(&$item_row, &$row)
+ {
+ parent::adjust_item($item_row, $row);
+
+ $item_row['title'] = (isset($row['forum_name']) && $row['forum_name'] !== '') ? $row['forum_name'] . ' ' . $this->separator . ' ' . $item_row['title'] : $item_row['title'];
+ }
+}
diff --git a/phpBB/includes/feed/topics_active.php b/phpBB/includes/feed/topics_active.php
new file mode 100644
index 0000000000..d1c920c136
--- /dev/null
+++ b/phpBB/includes/feed/topics_active.php
@@ -0,0 +1,136 @@
+<?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;
+}
+
+/**
+* Active Topics feed
+*
+* This will give you the last {$this->num_items} topics
+* with replies made withing the last {$this->sort_days} days
+* including the last post.
+*
+* @package phpBB3
+*/
+class phpbb_feed_topics_active extends phpbb_feed_topic_base
+{
+ var $sort_days = 7;
+
+ function set_keys()
+ {
+ parent::set_keys();
+
+ $this->set('author_id', 'topic_last_poster_id');
+ $this->set('creator', 'topic_last_poster_name');
+ }
+
+ function get_sql()
+ {
+ $forum_ids_read = $this->get_readable_forums();
+ if (empty($forum_ids_read))
+ {
+ return false;
+ }
+
+ $in_fid_ary = array_intersect($forum_ids_read, $this->get_forum_ids());
+ $in_fid_ary = array_diff($in_fid_ary, $this->get_passworded_forums());
+ if (empty($in_fid_ary))
+ {
+ return false;
+ }
+
+ // Search for topics in last X days
+ $last_post_time_sql = ($this->sort_days) ? ' AND topic_last_post_time > ' . (time() - ($this->sort_days * 24 * 3600)) : '';
+
+ // We really have to get the post ids first!
+ $sql = 'SELECT topic_last_post_id, topic_last_post_time
+ FROM ' . TOPICS_TABLE . '
+ WHERE ' . $this->db->sql_in_set('forum_id', $in_fid_ary) . '
+ AND topic_moved_id = 0
+ AND topic_approved = 1
+ ' . $last_post_time_sql . '
+ ORDER BY topic_last_post_time DESC';
+ $result = $this->db->sql_query_limit($sql, $this->num_items);
+
+ $post_ids = array();
+ while ($row = $this->db->sql_fetchrow($result))
+ {
+ $post_ids[] = (int) $row['topic_last_post_id'];
+ }
+ $this->db->sql_freeresult($result);
+
+ if (empty($post_ids))
+ {
+ return false;
+ }
+
+ $this->sql = array(
+ 'SELECT' => 'f.forum_id, f.forum_name,
+ t.topic_id, t.topic_title, t.topic_replies, t.topic_replies_real, t.topic_views,
+ t.topic_last_poster_id, t.topic_last_poster_name, t.topic_last_post_time,
+ p.post_id, p.post_time, p.post_edit_time, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url',
+ 'FROM' => array(
+ TOPICS_TABLE => 't',
+ POSTS_TABLE => 'p',
+ ),
+ 'LEFT_JOIN' => array(
+ array(
+ 'FROM' => array(FORUMS_TABLE => 'f'),
+ 'ON' => 'p.forum_id = f.forum_id',
+ ),
+ ),
+ 'WHERE' => 'p.topic_id = t.topic_id
+ AND ' . $this->db->sql_in_set('p.post_id', $post_ids),
+ 'ORDER_BY' => 'p.post_time DESC',
+ );
+
+ return true;
+ }
+
+ function get_forum_ids()
+ {
+ static $forum_ids;
+
+ $cache_name = 'feed_topic_active_forum_ids';
+
+ if (!isset($forum_ids) && ($forum_ids = $this->cache->get('_' . $cache_name)) === false)
+ {
+ $sql = 'SELECT forum_id
+ FROM ' . FORUMS_TABLE . '
+ WHERE forum_type = ' . FORUM_POST . '
+ AND ' . $this->db->sql_bit_and('forum_options', FORUM_OPTION_FEED_EXCLUDE, '= 0') . '
+ AND ' . $this->db->sql_bit_and('forum_flags', log(FORUM_FLAG_ACTIVE_TOPICS, 2), '<> 0');
+ $result = $this->db->sql_query($sql);
+
+ $forum_ids = array();
+ while ($forum_id = (int) $this->db->sql_fetchfield('forum_id'))
+ {
+ $forum_ids[$forum_id] = $forum_id;
+ }
+ $this->db->sql_freeresult($result);
+
+ $this->cache->put('_' . $cache_name, $forum_ids, 180);
+ }
+
+ return $forum_ids;
+ }
+
+ function adjust_item(&$item_row, &$row)
+ {
+ parent::adjust_item($item_row, $row);
+
+ $item_row['title'] = (isset($row['forum_name']) && $row['forum_name'] !== '') ? $row['forum_name'] . ' ' . $this->separator . ' ' . $item_row['title'] : $item_row['title'];
+ }
+}
diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php
index b087e1298b..6a1b3fd4f8 100644
--- a/phpBB/includes/functions.php
+++ b/phpBB/includes/functions.php
@@ -2345,9 +2345,8 @@ function phpbb_generate_template_pagination($template, $base_url, $block_var_nam
$tpl_prefix . 'BASE_URL' => $base_url,
'A_' . $tpl_prefix . 'BASE_URL' => addslashes($base_url),
$tpl_prefix . 'PER_PAGE' => $per_page,
- $tpl_prefix . 'PREVIOUS_PAGE' => $previous_page,
- $tpl_prefix . 'PREV_PAGE' => $previous_page,
- $tpl_prefix . 'NEXT_PAGE' => ($on_page != $total_pages) ? $base_url . $url_delim . $start_name . '=' . ($on_page * $per_page) : '',
+ 'U_' . $tpl_prefix . 'PREVIOUS_PAGE' => $previous_page,
+ 'U_' . $tpl_prefix . 'NEXT_PAGE' => ($on_page != $total_pages) ? $base_url . $url_delim . $start_name . '=' . ($on_page * $per_page) : '',
$tpl_prefix . 'TOTAL_PAGES' => $total_pages,
$tpl_prefix . 'CURRENT_PAGE' => $on_page,
);
diff --git a/phpBB/includes/functions_download.php b/phpBB/includes/functions_download.php
index ee4e2f5135..0a8000ea3d 100644
--- a/phpBB/includes/functions_download.php
+++ b/phpBB/includes/functions_download.php
@@ -46,7 +46,7 @@ function send_avatar_to_browser($file, $browser)
$image_data = @getimagesize($file_path);
header('Content-Type: ' . image_type_to_mime_type($image_data[2]));
- if (strpos(strtolower($browser), 'msie') !== false && strpos(strtolower($browser), 'msie 8.0') === false)
+ if ((strpos(strtolower($user->browser), 'msie') !== false) && !phpbb_is_greater_ie_version($browser, 7))
{
header('Content-Disposition: attachment; ' . header_filename($file));
@@ -174,10 +174,9 @@ function send_file_to_browser($attachment, $upload_dir, $category)
header('Pragma: public');
// Send out the Headers. Do not set Content-Disposition to inline please, it is a security measure for users using the Internet Explorer.
- $is_ie8 = (strpos(strtolower($user->browser), 'msie 8.0') !== false);
header('Content-Type: ' . $attachment['mimetype']);
- if ($is_ie8)
+ if (phpbb_is_greater_ie_version($user->browser, 7))
{
header('X-Content-Type-Options: nosniff');
}
@@ -189,7 +188,7 @@ function send_file_to_browser($attachment, $upload_dir, $category)
}
else
{
- if (empty($user->browser) || (!$is_ie8 && (strpos(strtolower($user->browser), 'msie') !== false)))
+ if (empty($user->browser) || ((strpos(strtolower($user->browser), 'msie') !== false) && !phpbb_is_greater_ie_version($user->browser, 7)))
{
header('Content-Disposition: attachment; ' . header_filename(htmlspecialchars_decode($attachment['real_filename'])));
if (empty($user->browser) || (strpos(strtolower($user->browser), 'msie 6.0') !== false))
@@ -200,7 +199,7 @@ function send_file_to_browser($attachment, $upload_dir, $category)
else
{
header('Content-Disposition: ' . ((strpos($attachment['mimetype'], 'image') === 0) ? 'inline' : 'attachment') . '; ' . header_filename(htmlspecialchars_decode($attachment['real_filename'])));
- if ($is_ie8 && (strpos($attachment['mimetype'], 'image') !== 0))
+ if (phpbb_is_greater_ie_version($user->browser, 7) && (strpos($attachment['mimetype'], 'image') !== 0))
{
header('X-Download-Options: noopen');
}
@@ -410,7 +409,8 @@ function set_modified_headers($stamp, $browser)
// let's see if we have to send the file at all
$last_load = $request->header('Modified-Since') ? strtotime(trim($request->header('Modified-Since'))) : false;
- if ((strpos(strtolower($browser), 'msie 6.0') === false) && (strpos(strtolower($browser), 'msie 8.0') === false))
+
+ if (strpos(strtolower($browser), 'msie 6.0') === false && !phpbb_is_greater_ie_version($browser, 7))
{
if ($last_load !== false && $last_load >= $stamp)
{
@@ -721,3 +721,24 @@ function phpbb_download_clean_filename($filename)
return $filename;
}
+
+/**
+* Check if the browser is internet explorer version 7+
+*
+* @param string $user_agent User agent HTTP header
+* @param int $version IE version to check against
+*
+* @return bool true if internet explorer version is greater than $version
+*/
+function phpbb_is_greater_ie_version($user_agent, $version)
+{
+ if (preg_match('/msie (\d+)/', strtolower($user_agent), $matches))
+ {
+ $ie_version = (int) $matches[1];
+ return ($ie_version > $version);
+ }
+ else
+ {
+ return false;
+ }
+}
diff --git a/phpBB/includes/functions_posting.php b/phpBB/includes/functions_posting.php
index baef7bcda5..b9b518ad32 100644
--- a/phpBB/includes/functions_posting.php
+++ b/phpBB/includes/functions_posting.php
@@ -403,14 +403,7 @@ function upload_attachment($form_name, $forum_id, $local = false, $local_storage
$upload->set_disallowed_content(explode('|', $config['mime_triggers']));
}
- if (!$local)
- {
- $filedata['post_attach'] = ($upload->is_valid($form_name)) ? true : false;
- }
- else
- {
- $filedata['post_attach'] = true;
- }
+ $filedata['post_attach'] = $local || $upload->is_valid($form_name);
if (!$filedata['post_attach'])
{
@@ -429,30 +422,18 @@ function upload_attachment($form_name, $forum_id, $local = false, $local_storage
return $filedata;
}
- $cat_id = (isset($extensions[$file->get('extension')]['display_cat'])) ? $extensions[$file->get('extension')]['display_cat'] : ATTACHMENT_CATEGORY_NONE;
-
- // Make sure the image category only holds valid images...
- if ($cat_id == ATTACHMENT_CATEGORY_IMAGE && !$file->is_image())
- {
- $file->remove();
-
- // If this error occurs a user tried to exploit an IE Bug by renaming extensions
- // Since the image category is displaying content inline we need to catch this.
- trigger_error($user->lang['ATTACHED_IMAGE_NOT_IMAGE']);
- }
-
- // Do we have to create a thumbnail?
- $filedata['thumbnail'] = ($cat_id == ATTACHMENT_CATEGORY_IMAGE && $config['img_create_thumbnail']) ? 1 : 0;
-
- // Check Image Size, if it is an image
- if (!$auth->acl_get('a_') && !$auth->acl_get('m_', $forum_id) && $cat_id == ATTACHMENT_CATEGORY_IMAGE)
- {
- $file->upload->set_allowed_dimensions(0, 0, $config['img_max_width'], $config['img_max_height']);
- }
+ // Whether the uploaded file is in the image category
+ $is_image = (isset($extensions[$file->get('extension')]['display_cat'])) ? $extensions[$file->get('extension')]['display_cat'] == ATTACHMENT_CATEGORY_IMAGE : false;
- // Admins and mods are allowed to exceed the allowed filesize
if (!$auth->acl_get('a_') && !$auth->acl_get('m_', $forum_id))
{
+ // Check Image Size, if it is an image
+ if ($is_image)
+ {
+ $file->upload->set_allowed_dimensions(0, 0, $config['img_max_width'], $config['img_max_height']);
+ }
+
+ // Admins and mods are allowed to exceed the allowed filesize
if (!empty($extensions[$file->get('extension')]['max_filesize']))
{
$allowed_filesize = $extensions[$file->get('extension')]['max_filesize'];
@@ -467,10 +448,12 @@ function upload_attachment($form_name, $forum_id, $local = false, $local_storage
$file->clean_filename('unique', $user->data['user_id'] . '_');
- // Are we uploading an image *and* this image being within the image category? Only then perform additional image checks.
- $no_image = ($cat_id == ATTACHMENT_CATEGORY_IMAGE) ? false : true;
+ // Are we uploading an image *and* this image being within the image category?
+ // Only then perform additional image checks.
+ $file->move_file($config['upload_path'], false, !$is_image);
- $file->move_file($config['upload_path'], false, $no_image);
+ // Do we have to create a thumbnail?
+ $filedata['thumbnail'] = ($is_image && $config['img_create_thumbnail']) ? 1 : 0;
if (sizeof($file->error))
{
@@ -481,6 +464,16 @@ function upload_attachment($form_name, $forum_id, $local = false, $local_storage
return $filedata;
}
+ // Make sure the image category only holds valid images...
+ if ($is_image && !$file->is_image())
+ {
+ $file->remove();
+
+ // If this error occurs a user tried to exploit an IE Bug by renaming extensions
+ // Since the image category is displaying content inline we need to catch this.
+ trigger_error($user->lang['ATTACHED_IMAGE_NOT_IMAGE']);
+ }
+
$filedata['filesize'] = $file->get('filesize');
$filedata['mimetype'] = $file->get('mimetype');
$filedata['extension'] = $file->get('extension');
diff --git a/phpBB/includes/functions_user.php b/phpBB/includes/functions_user.php
index 7b11e4f01b..1b598f7bf7 100644
--- a/phpBB/includes/functions_user.php
+++ b/phpBB/includes/functions_user.php
@@ -1653,7 +1653,7 @@ function validate_username($username, $allowed_username = false)
*/
function validate_password($password)
{
- global $config, $db, $user;
+ global $config;
if ($password === '' || $config['pass_complex'] === 'PASS_TYPE_ANY')
{
diff --git a/phpBB/includes/search/fulltext_mysql.php b/phpBB/includes/search/fulltext_mysql.php
index adaf025730..aa493c3281 100644
--- a/phpBB/includes/search/fulltext_mysql.php
+++ b/phpBB/includes/search/fulltext_mysql.php
@@ -163,9 +163,16 @@ class phpbb_search_fulltext_mysql extends phpbb_search_base
$engine = $info['Type'];
}
- if ($engine != 'MyISAM')
+ $fulltext_supported =
+ $engine === 'MyISAM' ||
+ // FULLTEXT is supported on InnoDB since MySQL 5.6.4 according to
+ // http://dev.mysql.com/doc/refman/5.6/en/innodb-storage-engine.html
+ $engine === 'InnoDB' &&
+ phpbb_version_compare($this->db->sql_server_info(true), '5.6.4', '>=');
+
+ if (!$fulltext_supported)
{
- return $this->user->lang['FULLTEXT_MYSQL_NOT_MYISAM'];
+ return $this->user->lang['FULLTEXT_MYSQL_NOT_SUPPORTED'];
}
$sql = 'SHOW VARIABLES
diff --git a/phpBB/includes/search/fulltext_sphinx.php b/phpBB/includes/search/fulltext_sphinx.php
index 63e35eb4af..889324bbda 100644
--- a/phpBB/includes/search/fulltext_sphinx.php
+++ b/phpBB/includes/search/fulltext_sphinx.php
@@ -611,7 +611,7 @@ class phpbb_search_fulltext_sphinx
$result_count = $result['total_found'];
- if ($start >= $result_count)
+ if ($result_count && $start >= $result_count)
{
$start = floor(($result_count - 1) / $per_page) * $per_page;
diff --git a/phpBB/includes/session.php b/phpBB/includes/session.php
index 6bc71da0c1..66bf053f7d 100644
--- a/phpBB/includes/session.php
+++ b/phpBB/includes/session.php
@@ -207,7 +207,7 @@ class phpbb_session
function session_begin($update_session_page = true)
{
global $phpEx, $SID, $_SID, $_EXTRA_URL, $db, $config, $phpbb_root_path;
- global $request;
+ global $request, $phpbb_container;
// Give us some basic information
$this->time_now = time();
@@ -402,15 +402,12 @@ class phpbb_session
// Check whether the session is still valid if we have one
$method = basename(trim($config['auth_method']));
- include_once($phpbb_root_path . 'includes/auth/auth_' . $method . '.' . $phpEx);
- $method = 'validate_session_' . $method;
- if (function_exists($method))
+ $provider = $phpbb_container->get('auth.provider.' . $method);
+ $ret = $provider->validate_session($this->data);
+ if ($ret !== null && !$ret)
{
- if (!$method($this->data))
- {
- $session_expired = true;
- }
+ $session_expired = true;
}
if (!$session_expired)
@@ -504,7 +501,7 @@ class phpbb_session
*/
function session_create($user_id = false, $set_admin = false, $persist_login = false, $viewonline = true)
{
- global $SID, $_SID, $db, $config, $cache, $phpbb_root_path, $phpEx;
+ global $SID, $_SID, $db, $config, $cache, $phpbb_root_path, $phpEx, $phpbb_container;
$this->data = array();
@@ -568,18 +565,14 @@ class phpbb_session
}
$method = basename(trim($config['auth_method']));
- include_once($phpbb_root_path . 'includes/auth/auth_' . $method . '.' . $phpEx);
- $method = 'autologin_' . $method;
- if (function_exists($method))
- {
- $this->data = $method();
+ $provider = $phpbb_container->get('auth.provider.' . $method);
+ $this->data = $provider->autologin();
- if (sizeof($this->data))
- {
- $this->cookie_data['k'] = '';
- $this->cookie_data['u'] = $this->data['user_id'];
- }
+ if (sizeof($this->data))
+ {
+ $this->cookie_data['k'] = '';
+ $this->cookie_data['u'] = $this->data['user_id'];
}
// If we're presented with an autologin key we'll join against it.
@@ -884,7 +877,7 @@ class phpbb_session
*/
function session_kill($new_session = true)
{
- global $SID, $_SID, $db, $config, $phpbb_root_path, $phpEx;
+ global $SID, $_SID, $db, $config, $phpbb_root_path, $phpEx, $phpbb_container;
$sql = 'DELETE FROM ' . SESSIONS_TABLE . "
WHERE session_id = '" . $db->sql_escape($this->session_id) . "'
@@ -893,13 +886,9 @@ class phpbb_session
// Allow connecting logout with external auth method logout
$method = basename(trim($config['auth_method']));
- include_once($phpbb_root_path . 'includes/auth/auth_' . $method . '.' . $phpEx);
- $method = 'logout_' . $method;
- if (function_exists($method))
- {
- $method($this->data, $new_session);
- }
+ $provider = $phpbb_container->get('auth.provider.' . $method);
+ $provider->logout($this->data, $new_session);
if ($this->data['user_id'] != ANONYMOUS)
{
diff --git a/phpBB/includes/template/filter.php b/phpBB/includes/template/filter.php
index f2bd442010..1c0a56c9f5 100644
--- a/phpBB/includes/template/filter.php
+++ b/phpBB/includes/template/filter.php
@@ -475,6 +475,7 @@ class phpbb_template_filter extends php_user_filter
*/
private function compile_var_tags(&$text_blocks)
{
+ $is_expr = null;
$text_blocks = $this->get_varref($text_blocks, $is_expr);
$lang_replaced = $this->compile_language_tags($text_blocks);
diff --git a/phpBB/includes/ucp/ucp_groups.php b/phpBB/includes/ucp/ucp_groups.php
index efc88e6e37..aada0525a8 100644
--- a/phpBB/includes/ucp/ucp_groups.php
+++ b/phpBB/includes/ucp/ucp_groups.php
@@ -416,9 +416,11 @@ class ucp_groups
if ($group_id)
{
- $sql = 'SELECT *
- FROM ' . GROUPS_TABLE . "
- WHERE group_id = $group_id";
+ $sql = 'SELECT g.*, t.teampage_position AS group_teampage
+ FROM ' . GROUPS_TABLE . ' g
+ LEFT JOIN ' . TEAMPAGE_TABLE . ' t
+ ON (t.group_id = g.group_id)
+ WHERE g.group_id = ' . $group_id;
$result = $db->sql_query($sql);
$group_row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
@@ -514,6 +516,8 @@ class ucp_groups
'receive_pm' => isset($_REQUEST['group_receive_pm']) ? 1 : 0,
'message_limit' => request_var('group_message_limit', 0),
'max_recipients'=> request_var('group_max_recipients', 0),
+ 'legend' => $group_row['group_legend'],
+ 'teampage' => $group_row['group_teampage'],
);
if ($config['allow_avatar'])
@@ -569,6 +573,9 @@ class ucp_groups
// Only set the rank, colour, etc. if it's changed or if we're adding a new
// group. This prevents existing group members being updated if no changes
// were made.
+ // However there are some attributes that need to be set everytime,
+ // otherwise the group gets removed from the feature.
+ $set_attributes = array('legend', 'teampage');
$group_attributes = array();
$test_variables = array(
@@ -580,13 +587,14 @@ class ucp_groups
'avatar_height' => 'int',
'receive_pm' => 'int',
'legend' => 'int',
+ 'teampage' => 'int',
'message_limit' => 'int',
'max_recipients'=> 'int',
);
foreach ($test_variables as $test => $type)
{
- if (isset($submit_ary[$test]) && ($action == 'add' || $group_row['group_' . $test] != $submit_ary[$test] || isset($group_attributes['group_avatar']) && strpos($test, 'avatar') === 0))
+ if (isset($submit_ary[$test]) && ($action == 'add' || $group_row['group_' . $test] != $submit_ary[$test] || isset($group_attributes['group_avatar']) && strpos($test, 'avatar') === 0 || in_array($test, $set_attributes)))
{
settype($submit_ary[$test], $type);
$group_attributes['group_' . $test] = $group_row['group_' . $test] = $submit_ary[$test];
@@ -596,6 +604,7 @@ class ucp_groups
if (!($error = group_create($group_id, $group_type, $group_name, $group_desc, $group_attributes, $allow_desc_bbcode, $allow_desc_urls, $allow_desc_smilies)))
{
$cache->destroy('sql', GROUPS_TABLE);
+ $cache->destroy('sql', TEAMPAGE_TABLE);
$message = ($action == 'edit') ? 'GROUP_UPDATED' : 'GROUP_CREATED';
trigger_error($user->lang[$message] . $return_page);
@@ -682,7 +691,7 @@ class ucp_groups
}
}
- if (!$update)
+ if (isset($phpbb_avatar_manager) && !$update)
{
// Merge any avatars errors into the primary error array
$error = array_merge($error, $phpbb_avatar_manager->localize_errors($user, $avatar_error));