Мультидоменность контекстами



В сообществе часто проскакивают вопросы про мультидоменность на одной копии MODX. А у меня, как раз, сайты демо версий компонентов реализованы таким образом. Думаю, информация будет полезной!

На самом деле, сделать это контекстами достаточно просто. Буквально в три шага.

Шаг 1

Создаем плагин switchContextDomain на событие OnMODXInit:
if ($modx->event->name != 'OnMODXInit' || $modx->context->key == 'mgr') {
    return;
}
if ($host = str_replace('www.', '', $_SERVER['HTTP_HOST'] ?: $_SERVER['SERVER_NAME'])) {
    // Выбираем контексты с настройкой http_host
    $q = $modx->newQuery('modContextSetting', array('key' => 'http_host', 'value:!=' => ''));
    $q->select('context_key as ctx, value as host');
    
    $tstart = microtime(true);
    if ($q->prepare() && $q->stmt->execute()) {
        // Учитываем наш запрос в БД
        $modx->queryTime += microtime(true) - $tstart;
        $modx->executedQueries++;
        
        while ($row = $q->stmt->fetch(PDO::FETCH_ASSOC)) {
            // Если нашли нужный контекст - переключаем на него
            if ($row['host'] == $host) {
                $modx->switchContext($row['ctx']);
                break;
            }
        }
    }
}
 

Шаг 2

Назначаем контексту web настройки:
http_host = domain1.ru
site_start = ID главного ресурса в текущем контексте
site_url = http://domain1.ru/
 

Шаг 3

Назначаем контексту domain2 настройки:
http_host = domain2.ru
site_name = Название второго сайта
site_start = ID главного ресурса в текущем контексте
site_url = http://domain2.ru/
 

Итого

Как видите, все довольно просто, что называется, до безобразия!
10 августа 2017, 19:01    Павел Гвоздь   
29    668 +29

Комментарии (22)

  1. Илья Уткин 11 августа 2017, 08:43 # +15
    Есть один нюанс из-за которого я не назначаю контексту web настройку site_url:

    При мультидоменности в админку можно зайти по любому из доменов. И вот, если мы открыли сайт domain2.ru, зашли в его админку, что-то отредактировали и хотим перейти на сам сайт, выбираем «Содержимое» -> «Перейти на сайт».

    В этом случае, если у контекста web есть настройка site_url, открывается сайт domain1.ru. Если же у контекста web настройки site_url нет, то мы перейдём на тот домен, по которому мы открыли админку.
    1. Павел Гвоздь 11 августа 2017, 09:38 # +5
      Сорри, это я минуснул. Пальцами на мобиле не попал, а, к сожалению, не исправить. Вот бы в течение 10 минут была возможность переголосовать…
      Спасибо за информацию!
      1. Василий Наумкин 11 августа 2017, 10:06 # +6
        Я плюсанул, не переживай.
    2. Андрей Шевяков 11 августа 2017, 10:56 # 0
      Добрый день!
      Раз уж тема про мультидоменность контекстами, можно вопрос задам.

      Если у нас поддомены отвечают за города, типа:
      moscow.site.ru, spb.site.ru,…

      С помощью какого дополнения или скрипта можно реализовать автоматическое перенаправление на поддомен с нужным городом, с основного сайта site.ru.

      Кто как реализовывал определение геолокации из браузера и перенаправление? Поделитесь опытом.
      1. Павел Гвоздь 11 августа 2017, 11:06 # +1
        У Володи есть компонент геоип, я им пользовался для определения города.
        1. Андрей Шевяков 11 августа 2017, 11:54 # 0
          Спасибо!
        2. Илья Уткин 11 августа 2017, 11:20 # +2
          1. Андрей Шевяков 11 августа 2017, 11:54 # 0
            Спасибо!
        3. Alexander V 11 августа 2017, 15:14 # 0
          Про алиасы www забыли?
          1. Павел Гвоздь 11 августа 2017, 15:38 # 0
            Не понял.
          2. Alexander V 11 августа 2017, 15:45 # 0
            www никуда не делся. Переадресовываем мы его.
            1. Павел Гвоздь 11 августа 2017, 15:57 # 0
              Можно подробнее, что вас именно смущает?
              1. Alexander V 11 августа 2017, 16:00 # 0
                Не вижу куда алиас добавить. Порядок переадресаций оставим пока на серверной стороне.
                1. Павел Гвоздь 11 августа 2017, 16:03 # +1
                  Вот эта строчка:
                  str_replace('www.', '', $_SERVER['HTTP_HOST'] ?: $_SERVER['SERVER_NAME'])
                  отвечает за то, чтобы вырезать из домена www и никаких алиасов вписывать не нужно.
                  1. Alexander V 11 августа 2017, 16:26 # 0
                    А если переход с www?
                    1. Павел Гвоздь 11 августа 2017, 16:28 # 0
                      Ну перепишите под себя, в чем проблема? Тем более, что правок в плагине ровно в одну строчку. :)
                      1. Alexander V 11 августа 2017, 16:35 # -7
                        Не годится. ИМХО
            2. Андрей 12 августа 2017, 12:37 # 0
              Добрый день. Реализация отличная. Но у меня возник такой вопрос:
              1. Физически поддомен создавать не нужно?
              2. Как быть с https, ведь бесплатные сертификаты типа LEt's Encrypt не обеспечивают безопастность поддомена, а значит, нужно создавать поддомен и к нему делать сертификат. А при наличии физически созщданного поддомена у меня просто отображает страницу поддомена, без работы плагина. Как тут выкрутиться?
              1. Павел Гвоздь 12 августа 2017, 12:53 # +1
                Физически — это как? Я пользуюсь pdd.yandex.ru и там очень просто добавить поддомен и сослаться с него на нужный IP. Собственно, этого достаточно для работы метода. Хотя, если на сервере NGINX + PHP-FPM, то в конфиге NGINX необходимо прописать и поддомен.
                1. Андрей 12 августа 2017, 13:00 # 0
                  Я тоже делаю через pdd.yandex.ru и там я добавляю просто A записи поддомена. Но вот сертификат я ему не могу присвоить, правильно? Без создания поддомена в панели хостинга.
                  1. Павел Гвоздь 12 августа 2017, 13:05 # +1
                    А вот тут я вам уже не помогу. Хостинги бывают разные. На modhost, насколько я помню, вполне возможно привязать к одному сайту несколько доменов и даже создать для них сертификаты автоматически.
              2. SEQUEL.ONE 19 августа 2017, 16:56 # 0
                А кто-нибудь с правами заморачивался, чтобы при открытии админки открывались не все контексты, а только тот, на домене которого открывается админка?
                Вы должны авторизоваться, чтобы оставлять комментарии.