Pull to refresh

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

Reading time4 min
Views2.8K
Что же я хотел сказать таким страшным заголовком?

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

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

В этой статье я расскажу о том, как реализовать это на примере движка 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 штук в день. :)
Tags:
Hubs:
+21
Comments14

Articles