NameOne: Акция для пользователей MediaWiki.ru - Регистрация доменов по доступным ценам. RU и РФ от 95 рублей! →
Не нашли ответа на свой вопрос? Посетите наш форум, там обязательно помогут.

Субдоменная мульти-установка mediawiki с единой БД юзеров и общим кодом

Что же я хотел сказать таким страшным заголовком?

На самом деле — все просто.

Допустим, у нас есть какой-то домен, на котором мы хотим поднять кучу вики-энциклопедий. Для каждой отдельной вики мы хотим отдельный субдомен. Но при этом мы хотим, чтобы все это работало на едином коде (чтобы в случае обновления мы могли разом поменять все), а также чтобы юзеры имели одну регистрацию во всех наших вики.

В этой статье я расскажу о том, как реализовать это на примере движка mediawiki.

Зачем это надо?

Отвечу на своем примере. У меня есть некоторое количество сайтов по разным играм. И мне всегда хотелось иметь какой-то единый вики-ресурс по разным играм.

Мой сценарий таков:

  • имеем единый домен (в моем случае это playwiki.ru)
  • при заходе на него, мы попадаем на некую главную страницу проекта — описание, что это, зачем, ну и естественно — ссылки на разные вики
  • каждая отдельная вики по игре занимает свой собственный субдомен: wow.playwiki.ru, diablo2.playwiki.ru и т.п.
  • таблицы юзеров, групп — общие для всех суб-вики, равно как и куки (т.е. единожды залогинившись, вы остаетесь залогиненными)
  • используется общий код вики-движка
  • каждая вики имеет свою БД, свою папку хранения картинок, свой скин и логотип

Установка mediawiki.

Пока все просто. Устанавливаете mediawiki как обычно, на свой основной домен. Никаких тонкостей.

Сервер.

В своих проектах я использую nginx. Он гораздо быстрее апача, правда несколько более сложный в настройке.

В нашем случае нам нужно, чтобы переход на любой субдомен нашего основного домена все равно вызывал один и тот же код. Реализуется это просто:

 

server {
server_name playwiki.ru *.playwiki.ru;
root /wwwroot/playwiki.ru ;
index index.php;
}

 

Здесь стоит отметить, что nginx имеет некоторое отличие в поведении от апача. Дело в том, что на какой бы субдомен вы не перешли, server_name заюзается всегда первый.

Следовательно, пэха в нашем случае будет получать всегда «playwiki.ru» в $_SERVER['SERVER_NAME'], что повлечет неверные редиректы в движке mediawiki.

Сразу же поправим этот баг:

В LocalSettings.php в самом начале напишем:
include('My_ExtFunctions.php');
$_SERVER['SERVER_NAME'] = ($pw_subdomain_prefix) ? $pw_subdomain_prefix . ".playwiki.ru" : "playwiki.ru";

В конце сразу подключим наши настройки:

include('My_LocalSettings.php');

Здесь я заодно подключил два файла со своими настройками, т.к. не хочу сильно перегружать LocalSettings.php.

$pw_subdomain_prefix устанавливается внутри My_ExtFunctions.php:
function getMySubDomainPrefix() {

$a = $_SERVER['HTTP_HOST'];
$a = substr($a, 0, strpos($a, ".playwiki"));
if ($a == 'www') $a = '';

// secure it!
$a = str_replace("\t", "", str_replace("\r", "", str_replace("\n", "", $a)));
$a = str_replace("*", "", str_replace("'", "", str_replace("\"", "", $a)));
$a = str_replace(" ", "", str_replace(",", "", str_replace(".", "", $a)));
$a = str_replace("/", "", str_replace("//", "", str_replace("\0", "", $a)));

return $a;

}

$pw_subdomain_prefix = getMySubDomainPrefix();

 

Настройка mediawiki на субдомены.

Итак, мы имеем название нашего субдомена в $pw_subdomain_prefix. Весь код будем писать в My_LocalSettings.php.

Установим скин по умолчанию:

$wgDefaultSkin = 'monobook';

Сделаем так, чтобы скины искались в папках, соответствующих субдомену (например, для wow.playwiki.ru скины должны быть в папке /skins/skin_wow/:

$wgStylePath = "{$wgScriptPath}/skins" . (($pw_subdomain_prefix == '') ? '' : "/skin_$pw_subdomain_prefix");
$wgStyleDirectory = "{$IP}/skins" . (($pw_subdomain_prefix == '') ? '' : "/skin_$pw_subdomain_prefix");

Сделаем, чтобы БД зависила от субдомена. В моем случае вики на www.playwiki.ru будет юзать базу «playwiki» (она же будет основная для хранения юзеров и т.п.), а субдоменные вики будут использовать бд типа playwiki_wow, playwiki_la2 и т.п.

if ($pw_subdomain_prefix) $pw_subdomain_prefix = '_' . $pw_subdomain_prefix;
$wgDBname = 'playwiki' . $pw_subdomain_prefix;

Установка общих таблиц (юзеры, блокировка по ip):

$wgSharedDB = 'playwiki'; // The $wgDBname for the wiki database holding the main user table
$wgSharedPrefix = 'wk_'; // The $wgDBprefix for the database, if not used, this can be omitted
$wgSharedTables = array('user', 'user_properties', 'ipblocks', 'user_groups');

Устанавливаем общий домен для cookies, чтобы юзер, залогиненный на любом субдомене так и оставался залогиненным на любом субдомене:

$wgCookieDomain = '.playwiki.ru';

Делаем, чтобы каждый субдомен вики имел свой собственный логотип:

$wgLogo = "images/logo$pw_subdomain_prefix.png";

Настройка upload'а изображений (в разные папки):

$wgEnableUploads = true;
$wgUploadDirectory = "images";
if ($pw_subdomain_prefix) $wgUploadDirectory .= "/img$pw_subdomain_prefix";
$wgUploadPath = "{$wgScriptPath}$wgUploadDirectory";

$wgUploadDirectory = "{$IP}/$wgUploadDirectory";

 

Заодно запретим правки незалогиненным юзерам:

$wgGroupPermissions['*']['edit'] = false;
$wgGroupPermissions['*']['createpage'] = false;
$wgGroupPermissions['*']['createtalk'] = false;

$wgGroupPermissions['user']['edit'] = true;
$wgGroupPermissions['user']['createpage'] = true;
$wgGroupPermissions['user']['createtalk'] = true;

$wgGroupPermissions['sysop']['edit'] = true;
$wgGroupPermissions['sysop']['createpage'] = true;
$wgGroupPermissions['sysop']['createtalk'] = true;

$wgGroupPermissions['bureaucrat']['edit'] = true;
$wgGroupPermissions['bureaucrat']['createpage'] = true;
$wgGroupPermissions['bureaucrat']['createtalk'] = true;

Размножение wiki-энциклопедий.

Вот здесь все не очень изящно.

После установки вики, я скопировал дамп базы. Теперь, когда мне нужно добавить новую вики, я создаю (ручками) новую БД, прописываю права и разворачиваю туда этот дамп.

В принципе — терпимо. Учитывая, что вики не планируются к подъему по 10 штук в день. :)