Несколько недель назад по некой нужде было необходимо добавить форум в только что написанный сайт. Сайт на этапе завершения, пользователей раз-два и обчелся. Сайт был написан на Codeigniter. В качестве форума был выбран phpBB, как один из распространенных free форум версии 3.1.1. После несложных манипуляций форум без проблем был установлен. Стало интереснее, когда дело дошло до пользователей.
Первым делом я решил поискать готовые решение дабы не тратить ни свое время, ни время клиента. Была найдена уже не рабочая ссылка на библиотеку phpBB3_library, были найдены плагины для WP, и др. движков, но мне хотелось сделать интеграцию безболезненно для себя и моего детища (сайта) и форума.
Недолго погуглив, нашел вот эту статью, с которой и началось мое погружение в глубины пользовательской функциональности phpBB.
Постановка задачи
- Сделать безболезненную интеграцию. Должен быть один реализующий класс. Без изменений в движке форума, дабы при обновлении форума ничего не слетело.
- Максимальное использование функций форума в нашем классе. Городить велосипед не хочется.
- Реализовать совместную регистрацию, смену пароля, авторизацию, конец сеанса, блокировку и отмену блокировки пользователя на основе уже существующего функционала форума.
Анализ
После чтения доков, стало понятно, что функции управления пользователями размещаются в <корень форума>/includes/functions_user.php, а авторизация в <корень форума>/phpbb/auth/provider. В этой папке размещены функции для нескольких вариантов авторизации. Тип авторизации задается в панели администрирования форума, раздел «Общие -> Аутентификация». Я по оставил значение по умолчанию — Db.
В принципе, необходимый функционал я нашел в этих двух файла, кроме обновления данных пользователя. Далее приступаем к реализации.
Начальные данные
- Сайт, реализованный с помощью codeigniter.
- Форум phpBB.
- Таблица с пользователями сайта — USERS.
- Таблица с пользователями форума — phpbb_USERS.
- Регистрация/авторизация пользователей на сайте — переделанная под свои нужды библиотека Codeigniter Auth.
Решение
Задача поставлена, надо делать.
Перед началом — несколько нюансов.
- Необходимо отключить регистрацию пользователей на сайте. Это делается в панели администратора (Общие -> регистрация пользователей -> Разрешить смену имени пользователя -> Нет). Разрешаем пользователю регистрацию только на сайте.
- Запрещаем смену имени пользователя (Общие -> Регистрация пользователей -> Активация аккаунта -> Отключено).
- Запрещаем авторизацию с форума. Авторизацию и выход делаем только с сайта. Сделал «в лоб» — в файле <корень форума>/ucp.php сделал редиректы на соответствующие страницы на сайте. (см. строки «case 'login':», «case 'login_link':», «case 'logout':». Редирект «header('Location: /auth/login');» и «header('Location: /auth/logout');»).
- На сайте (если есть функция redirect()) заменить функцию redirect(), например на ciredirect(), дабы избежать конфликта имен — в phpBB есть функция с аналогичным названием.
Для codeigniter создаю библиотеку my_phplib.php (библиотека в codeigniter — это некий вспомогательный, подключаемый класс, располагающийся в папке application/libraries. В нем нет ничего необычного, так что пользователи других движков/фрейморков — не унывайте).
Итак, содержимое библиотеки:
<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
class My_phpbblib
{
public $phpBB_user;
public $phpBB_auth;
public $phpBB_db;
public $table_prefix;
public function __construct(){
// определяем видимые переменные.
global $phpbb_root_path,
$phpEx,
$user,
$auth,
$cache,
$db,
$config,
$template,
$table_prefix,
$request,
$phpbb_container,
$symfony_request,
$phpbb_filesystem,
$phpbb_log,
$phpbb_path_helper,
$phpbb_dispatcher;
// Без константы никуда...
define('IN_PHPBB', TRUE);
// корневая папка форума.
$phpbb_root_path = './forum/';
// расширение подключаемых файлов. В нашем случае - php
$phpEx = substr(strrchr(__FILE__, '.'), 1);
// подключаем файлы
// конфигурационные файлы
include($phpbb_root_path . 'common.' . $phpEx);
include($phpbb_root_path . 'config.php.' . $phpEx);
// Функции для работы с пользователями
include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
// разрешим супер глобальные массивы...
$request->enable_super_globals();
// запускаем сессию пользователя
$user->session_begin();
$auth->acl($user->data);
$this->phpBB_user = $user;
$this->phpBB_auth = $auth;
$this->phpBB_db = $db;
$this->table_prefix = $table_prefix;
}
// регистрация
public function registration($data = array()) {
// если данные есть, можно попробовать поработать с ними
if(count($data) < 3){
// нам надо как минимум 3 элемента - логин, пароль и email
return false;
}
$new_phphBB_user = array();
// логин пользователя.
if(isset($data['username'])) return false;
$new_phphBB_user['username'] = $data['username'];
// пароль пользователя
if(isset($data['user_password'])) return false;
$new_phphBB_user['user_password'] = phpbb_hash($data['user_password']);
// email пользователя
if(isset($data['user_email'])) return false;
$new_phphBB_user['user_email'] = $data['user_email'];
// группа пользователя.
// по умолчанию в phpBB3 следующие группы
// - 1 - GUESTS - гость (незарегистрированный пользователь)
// - 2 - REGISTERED - Зарегистрированный пользователь
// - 3 - REGISTERED_COPPA - Зарегистрированный пользователь COPPA
// - 4 - GLOBAL_MODERATORS - Супер-модераторы
// - 5 - ADMINISTRATORS - Администраторы
// - 6 - BOTS - Боты
// - 7 - NEWLY_REGISTERED - Новые пользователи.
// по умолчанию регистрируем NEWLY_REGISTERED
$new_phphBB_user['group_id'] = isset($data['group_id']) ? $data['group_id'] : 7;
// тип пользователя.
// есть 4 типа
// - 0 - Обычный пользователь
// - 1 - Неативный пользователь. Ждет активации.
// - 2 - Игнор пользователя (боты)
// - 3 - Суперадмин
// по умолчанию новый пользователь не активный.
$new_phphBB_user['user_type'] = isset($data['user_type']) ? $data['user_type'] : 1;
// сохраняем пользователя в таблицах форума.
$phphBB_user_id = user_add($user_row, false);
// возвращаем id пользователя в таблицах phpBB
return $phphBB_user_id;
}
// авторизация
public function login($data = array()){
$this->phpBB_user->setup('ucp');
// имя пользователя
$username = $data['username'];
// пароль пользователя
$password = $data['user_password'];
// Запомнить пользователя
$autologin = $data['autologin'];
// Показывать пользователя в онлайне
$viewonline = true;
// авторизация средствами phpBB
$result = $this->phpBB_auth->login($username, $password, $autologin, $viewonline);
// result возвращает массив
// array(
// 'status' => status-code(int),
// 'error_msg'=> status-message-id(text),
// 'user_row'=> user-row(array),
// );
// Статусы
// 1 - Не указан пароль
// 3 - успешный вход
// 10 - Неверный логин
// 11 - Неверный пароль
// 12 - Пользователь неактивен
// 13 - Превышен лимит попыток входа
return $result;
}
// выход
public function logout(){
$this->phpBB_user->session_kill();
$this->phpBB_user->session_begin();
}
// удалить пользователя
public function delete_user($mode = 'remove', $user_name = '') {
// $mode = remove/retain - удалить или оставить в базе
// по имени пользователя получить id, так как мы считаем, что id пользователя в форуме - на сайте нам не известен.
$sql = 'SELECT user_id, username
FROM phpbb_users
WHERE username_clean = "'.utf8_clean_string($user_name).'"';
$result = $this->phpBB_db->sql_query($sql);
if (!($row = $this->phpBB_db->sql_fetchrow($result)))
{
$db->sql_freeresult($result);
} do
{
$user_id_ary[] = $row['user_id'];
}
// освобождаем память.
$this->phpBB_db->sql_freeresult($result);
if($user_id_ary){
// если нашли пользователя - удаляем
return user_delete($mode, $user_id_ary, $retain_username = true);
}
return false;
}
// бан пользователю.
public function ban_user($user_name = '', $ban_minutes = 432000, $ban_reason = ''){
// тип бана - устанавливаем по имени пользователя
// бывает - по имени (user), по ип (ip), по email (email)
return user_ban('user', $user_name, $ban_minutes, $ban_len_other = '', $ban_exclude = false, $ban_reason, $ban_give_reason = '');
}
// разбанить пользователя.
public function unban_user($user_name = ''){
// тип бана - устанавливаем по имени пользователя
// бывает - по имени (user), по ип (ip), по email (email)
// по имени пользователя получить id банов
$sql = 'SELECT b.ban_id, u.user_id
FROM phpbb_users u, phpbb_banlist b
WHERE u.username_clean = "'.utf8_clean_string($user_name).'" AND u.user_id = b.ban_userid';
$result = $this->phpBB_db->sql_query($sql);
if (!($row = $this->phpBB_db->sql_fetchrow($result)))
{
$this->phpBB_db->sql_freeresult($result);
}
do
{
$user_ban_id_ary[] = $row['ban_id'];
}
$this->phpBB_db->sql_freeresult($result);
return user_unban('user', $user_ban_id_ary);
}
// обновить данные пользователя.
public function edit_user_pass($user_name ='', $user_pass) {
if (empty($user_name) || empty($user_pass)){
return false;
}
$sql = 'UPDATE ' . $this->table_prefix . 'users
SET user_password="' . md5($user_pass) . '"
WHERE username_clean = "'.utf8_clean_string($user_name).'"';
$this->phpBB_db->sql_query($sql);
return true;
}
}
Использование в codeigniter — стандартно — подключаем библиотеку в контроллере, отвечающем за авторизацию.
function __construct(){
parent::__construct();
$this->load->library('my_phpbblib');
}
// авторизация
public function login(){
/*
Ваш код
*/
$data = array();
$data['username'] = $this->input->post('login');
$data['user_password'] = $this->input->post('pass');
$data['autologin'] = $remember;
// Пробуем авторизироваться и получаем ответ.
$registration_result = $this->my_phpbblib->login($data);
/*
Ваш код
*/
}
// регистрация
public function registration(){
/*
Ваш код
*/
$user_row['username'] = $user_login;
$user_row['user_password'] = phpbb_hash($user_pass);
$user_row['user_email'] = $user_email;
$user_row['group_id'] = 2;
$user_row['user_type'] = 0;
// регистрация пользователя на форуме
$forum_id = $this->my_phpbblib->registration($user_row);
/*
Ваш код
*/
}
// выход
public function logout() {
/*
Ваш код
*/
$this->my_phpbblib->logout($data);
/*
Ваш код
*/
}
// Удалить пользователя.
public function delete($id = 0){
/*
Ваш код
*/
$this->my_phpbblib->delete_user('remove', $user_login);
/*
Ваш код
*/
}
// Сменить пароль пользователю
public function change_pass(){
/*
Ваш код
*/
// изменение пароля на форуме
$this->my_phpbblib->edit_user_pass($user_login, $user_pass);
/*
Ваш код
*/
}
// Заблокировать пользователя.
public function ban(){
/*
Ваш код
*/
// забаним пользователя и на форме.
$b = $this->my_phpbblib->ban_user($user_login, 432000, $ban_reason);
/*
Ваш код
*/
}
// разблокировать пользователя.
public function unban(){
/*
Ваш код
*/
$ub = $this->my_phpbblib->unban_user($user_login);
/*
Ваш код
*/
}
Данный способ был проделан с phpBB 3.1.1 и phpBB 3.1.3 (после обновления никакого вмешательства не потребовалось).
Спасибо за внимание.
Буду рад, если статья кому-нибудь поможет.
Автор: Romanche