Несколько недель назад по некой нужде было необходимо добавить форум в только что написанный сайт. Сайт на этапе завершения, пользователей раз-два и обчелся. Сайт был написан на 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. В нем нет ничего необычного, так что пользователи других движков/фрейморков — не унывайте).
Итак, содержимое библиотеки:
Библиотека my_phplib.php
<?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 — стандартно — подключаем библиотеку в контроллере, отвечающем за авторизацию.
Использование my_phplib.php
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 (после обновления никакого вмешательства не потребовалось).
Спасибо за внимание.
Буду рад, если статья кому-нибудь поможет.
