Интеграция MODX Revolution и форума phpBB Версия phpBB: 3.0.11 Версия MODX: 2.2.5-pl Папка сайта: / Папка форума: /forum Базы данных у меня разные, но можно и одну использовать, вроде все должно быть Путем. Авторизация происходит почти полностью на стороне MODX. На форуме создаются копии пользователей MODX, но их данные автоматически обновляются из MODX. Плагин авторизации phpBB Для авторизации на форуме используется система «плагинов авторизации», вкратце об них. Чтобы использовать плагин авторизации, надо: 1. Придумать имя плагину авторизации, например: modx 2. Создать файл /forum/includes/auth/auth_modx.php (суффикс имени файла (modx) == имя плагина) 3. В файле /forum/includes/auth/auth_modx.php, должна быть минимум одна функция login_modx (суффикс == имя плагина) 4. Отключить регистрацию на форуме: ОБЩИЕ -> Регистрация пользователей -> Отключить регистрацию 5. В админ панели форума: ОБЩИЕ -> Аутентификация -> выбрать из списка Modx Код файла /forum/includes/auth/auth_modx.php: Код: <?php # /forum/includes/auth/auth_modx.php if (!defined('IN_PHPBB')){ exit; } /** * возвращает информацию о текущем пользователе */ function get_user_data(){ // Подключаем define('MODX_API_MODE', true); require dirname(dirname(dirname(dirname(__FILE__)))) . '/index.php'; // у меня форум лежит в /forum // MODX переназначает на свой обработкчик ошибок, и сообщения форума выводятся криво, // поэтому надо обратно назначить обработчик ошибок на форумный: set_error_handler(defined('PHPBB_MSG_HANDLER') ? PHPBB_MSG_HANDLER : 'msg_handler'); // берем пользователя if($modx->user->get('id') != 0){ // Если не anonimous $result['username'] = $modx->user->get('username'); $profile = $modx->user->getOne('Profile'); $result['user_email'] = $profile->get('email'); $fields = $profile->get('extended'); $result['user_from'] = $fields['region']; // Сюда можно добавить другие поля профиля, например: // $result['имя_столбца_в_БД_форума_в_таблице_users'] = Значение_поля_из_БД_modx; // Все поля перечисленные здесь проверяются, и если изменились в MODX, меняются и на форуме, // например: Поменялся у пользователя в MODX extended поле region, автоматически меняется в БД форума поле user_from // автообновление происходит в функции validate_session_modx (ниже) } return $result; } /** * Функция, отвечающая за авторизацию. */ function login_modx(){ $auth = get_user_data(); // если авторизация невозможна if (!is_array($auth) || empty($auth)) { return array( 'status' => LOGIN_ERROR_USERNAME, 'error_msg' => 'ACCESS_DIRECTLY_DENIDED', 'user_row' => array('user_id' => ANONYMOUS), ); } global $db; $sql = 'SELECT user_id, username, user_password, user_email, user_from, user_type FROM ' . USERS_TABLE . " WHERE username_clean = '" . $db->sql_escape($auth['username']) . "'"; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); if ($row){ $res = array( 'status' => LOGIN_SUCCESS, 'error_msg' => false, 'user_row' => array( 'user_id' => $row['user_id'], 'username' => $row['username'], // Отображаемое имя пользователя 'user_email' => $row['user_email'], // E-mail пользователя, если существует 'user_from' => $row['user_from'], 'user_type' => 0, 'group_id' => 2 ) ); return $res; } // Сообщаем, что авторизация прошла успешно. $res = array( 'status' => LOGIN_SUCCESS_CREATE_PROFILE, 'error_msg' => false, 'user_row' => array( "username" => $auth['username'], // Отображаемое имя пользователя "user_email" => $auth['user_email'], // E-mail пользователя, если существует "user_from" => $auth['user_from'], "user_type" => 0, "group_id" => 2 ), ); return $res; } /** * Функция, отвечающая за регистрацию и авторизацию пользователя при первом посещении. */ function autologin_modx(){ $user_row = login_modx(); // если пользователь еще не зарегистрирован if ($user_row['status'] == LOGIN_SUCCESS_CREATE_PROFILE) { global $phpbb_root_path, $phpEx; if (!function_exists('user_add')) { include($phpbb_root_path . 'includes/functions_user.' . $phpEx); } $user_row['user_row']['user_id'] = user_add($user_row['user_row']); } // возвращаем данные пользователя global $db; $sql = 'SELECT * FROM ' . USERS_TABLE . " WHERE user_id = '" . $db->sql_escape($user_row['user_row']['user_id']) . "'"; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); return $row; } /** * Функция сравнивает поля пользователя modx и поля пользователя форума, если в modx значение поля изменилось, то обновляет это поле и в форуме */ function validate_session_modx() { if($auth = get_user_data()){ // Данные прользователя modx лежат в $auth // Взять данные пользователя phpbb global $db; // Добавить в запрос поля, которые должны обновляться из modx (user_id - не в счет) $sql = 'SELECT user_id, user_email, user_from FROM ' . USERS_TABLE . " WHERE username_clean = '" . $db->sql_escape($auth['username']) . "'"; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); if ($row){ foreach($auth as $auK => $auV){ if($row[$auK] != $auV){ // Если поле пользователя форма не равно полю из modx (хоть одно) // Сделать UPDATE unset($auth['username']); $sql = "UPDATE " . USERS_TABLE . " SET " . $db->sql_build_array('UPDATE', $auth) . " WHERE user_id = '" . $db->sql_escape($row['user_id']) . "'"; $db->sql_query($sql); break; } } } } } Админ форума Так как авторизация почти полностью происходит на стороне MODX, то админ форума (имя пользователя, например admin), должен быть зарегистрирован в MODX. Теперь, допустим, у нас есть пользователь admin в MODX, и у форума админ с тем же именем admin. Проблема в том, что администратор форума должен подтвердить свой пароль, который не может свериться, т.к. авторизация у нас в MODX, а не через БД форума. Поэтому отключаем дополнительную сверку пароля админа форума: В файле: /forum/adm/index.php Код: // Have they authenticated (again) as an admin for this session? if (!isset($user->data['session_admin']) || !$user->data['session_admin']) { login_box('', $user->lang['LOGIN_ADMIN_CONFIRM'], $user->lang['LOGIN_ADMIN_SUCCESS'], true, false); } Меняем на: Код: // Have they authenticated (again) as an admin for this session? //if (!isset($user->data['session_admin']) || !$user->data['session_admin']) //{ // login_box('', $user->lang['LOGIN_ADMIN_CONFIRM'], $user->lang['LOGIN_ADMIN_SUCCESS'], true, false); //} После: Код: if (!$auth->acl_get('a_')) { trigger_error('NO_ADMIN'); } Добавить строку: Код: $user->data['session_admin'] = 1; Вход, выход, восстановление пароля Чтобы можно было выйти с форума и одновременно с сайта по нажатию «Выход [имя_пользователя]»: В файле /forum/ucp.php, между case 'logout': и break; (включительно) получилось следующее: Код: case 'logout': // Подключение modx API define('MODX_API_MODE', true); require dirname(dirname(__FILE__)) . '/index.php'; $modx->getService('error','error.modError'); // Вернуть форумный обработчик ошибок set_error_handler(defined('PHPBB_MSG_HANDLER') ? PHPBB_MSG_HANDLER : 'msg_handler'); // Короче: если есть сессия в $_GET['sid'] и она норм, то это... if ($user->data['user_id'] != ANONYMOUS && isset($_GET['sid']) && !is_array($_GET['sid']) && $_GET['sid'] === $user->session_id) { $user->session_kill(); $user->session_begin(); } $modx->runProcessor('/security/logout'); $message = $user->lang['LOGOUT_REDIRECT']; meta_refresh(3, append_sid("{$phpbb_root_path}index.$phpEx")); $message = $message . '<br /><br />' . sprintf($user->lang['RETURN_INDEX'], '<a href="' . append_sid("{$phpbb_root_path}index.$phpEx") . '">', '</a> '); trigger_error($message); break; А также залогиниться одновременно на сайте и форуме, через форму авторизации на форуме: Между case 'login': и break; (включительно), все тот же файл /forum/ucp.php: Код: case 'login': define('MODX_API_MODE', true); require dirname(dirname(__FILE__)) . '/index.php'; $modx->getService('error','error.modError'); set_error_handler(defined('PHPBB_MSG_HANDLER') ? PHPBB_MSG_HANDLER : 'msg_handler'); if($_REQUEST["username"] and $_REQUEST["password"]){ $data = array( 'username' => $_REQUEST["username"], 'password' => $_REQUEST["password"], 'rememberme' => 1, 'login_context' => 'web', ); $response = $modx->runProcessor('/security/login', $data); if ($response->isError()) { trigger_error($response->getMessage()); } } if ($user->data['is_registered']) { redirect(append_sid("{$phpbb_root_path}index.$phpEx")); } login_box(request_var('redirect', "index.$phpEx")); break; Даже если пользователя небыло в БД форума, он автоматически создается. Чтобы по ссылке «Забыли пароль?» на форуме, попадали на страницу восстановления пароля MODX (/forum/ucp.php): Код: case 'sendpassword': define('MODX_API_MODE', true); require dirname(dirname(__FILE__)) . '/index.php'; $modx->getService('error','error.modError'); set_error_handler(defined('PHPBB_MSG_HANDLER') ? PHPBB_MSG_HANDLER : 'msg_handler'); $modx->sendRedirect($modx->makeUrl(865,'','','full')); // где 865 - это ID ресурса MODX с формой сброса пароля break; взято с http://habrahabr.ru/post/157055/