• Блог
  • Загружаем конфиги из файлов

Я думаю, не будет открытием тот факт, что в MODX настройки системы и компонентов хранятся в таблицах. Их аж целых 4 — modx_system_settings, modx_context_setting, modx_user_group_settings и modx_user_settings. Эта особенность, конечно, никак не способствует популярности среди авторитетных программистов. Не так давно в компоненте pdoTools было реализовано решение для работы с файловыми элементами, которые изначально также хранятся в базе данных. Я был одним из его инициаторов. Сейчас я хочу предложить подобную альтернативу для загрузки настроек из файлов. Побудило меня сделать это несколько причин.

Во-первых, я являюсь сторонником файловых элементов. Преимуществ у данного подхода перед хранением в БД больше чем минусов — проще разрабатывать, разворачивать, тестировать и поддерживать в системах контроля версий. Во-вторых, мне не очень нравится реализация в менеджере. Конечно, AdminTools с возможностью запоминания последнего фильтра немного выручает, но всё равно кривишься при мысли, что нужно туда лезть. Ведь есть 4 разных интерфейса (общие настройки, настройки контекста, настройка группы пользователей и настройки пользователя), в которых меняются значения. И нужно помнить где что указано.

Ну и последнее обстоятельство, которое побудило меня использовать данное решение, это обновление HybridAuth. Со страхом решил обновиться до новой мажорной версии. И в этоге у меня перестала работать авторизация через Facebook. Потеряв пару часов, я так и не смог заставить его работать и решил откатиться до старой версии (сейчас последняя версия работает нормально — ошибка была в том, что провайдер Facebook определял протокол как HTTP вместо HTTPS). Ну и при откате мои настройки стёрлись. Так как я предварительно сделал backup, я восстановил утерянные настройки. На эту операцию пришлось затратить время. А если бы настройки хранились в файле, то всё было бы гораздо проще.

Решил я эту задачу достаточно просто. В MODX есть директория для хранения главного файла настроек — core/config/config.inc.php. Я создал там файл hybridauth.php и перенёс все настройки для компонента HybridAuth из БД в него, а в базе их удалил (имеется ввиду не сами настройки, а значения). Но можно и не удалять — они всё равно заменятся данными из файла. Загрузка настроек происходит в плагине по событию OnHandleRequest (можно и OnMODXInit). Зато теперь я могу в файле управлять настройками по желанию — закомментиривать, быстро изменить значения, определить условие и т.д. Ну и конечно все прелести редактирования в любимом IDE.

Ну и ещё один большой плюс — это лёгкий экспорт/импорт настроек. Меня не однократно просили сделать такую возможность в AdminTools. Но это очень непростая задача. А решение с файлами — достаточно лёгкая реализация этой задачи.

Ладно, давайте к делу.

Шаг 1. Создание плагина

switch ($modx->event->name) {
    case 'OnHandleRequest':
        foreach (glob(MODX_CORE_PATH . 'config/*.php') as $file) {
            if (basename($file) == MODX_CONFIG_KEY . '.inc.php') continue;
            $response = require $file;
            if (is_array($response)) {
                $modx->config = array_merge($modx->config, $response);
            }
        }
    break;
}

В принципе папку можно указать любую. Если загрузить конфиг на событие OnMODXInit, то дополнительно будут созданы системные плейсхолдеры (которые с двумя плюсами — [[++setting]]).

Шаг 2. Файлы настроек

Теперь вы можете в папке core/config создавать файлы настроек, которые должны возвращать массив в следующем формате — 'key'=>'value'. Простой пример файла без каких-либо условий:

<?php //mysettings.php

return [
    'setting1' => 'value1',
    'setting2' => 'value2',
];

Название файлам лучше давать осмысленные, чтобы было понятно не только вам, но и другим разработчикам.

Вот и всё. Вы также можете в этом файле переопределять системные настройки. Удобно для отладки и тестирования. Я уже подключил несколько файлов из своих компонентов и не заметил какой-либо дополнительной нагрузки — время загрузки страниц вообще не изменилось. В общем, жду ваших замечаний и предложений.

2   2084

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

  1. Антон 14 мая 2021, 15:42 # 0
    Добрый день, Сергей.
    Создал файлик с настройками, и плагин на событие OnMODXInit.
    Пробую переопределить pdotools_elements_path (путь до папки с файловыми элементами).
    И если вызвать в шаблоне
    {'pdotools_elements_path'|config}
    то выводит то, что я прописал в своем файле, все ок.
    Но fenom берет значение не из моей настройки, а из той, что указана в админке по дефолту.

    Вопрос — как подсунуть свое значение? Нужно как-то реинициализировать fenom?
    1. Сергей Шлоков 14 мая 2021, 21:05 # 0
      У своего плагина для события укажи приоритет -110. Просто плагин pdoTools загружается раньше и запоминает настройки из базы. Нужно его опередить.
      1. Антон 14 мая 2021, 22:13 # 0
        Поставил -110. Не помогает.
        Может, в плагине чего не хватает?
        <?php
        switch ($modx->event->name) {
            //OnHandleRequest
            case 'OnMODXInit':
                $user = $modx->getUser();
                $user_id = $user->get('id');
                switch ($user_id) {
                    case '1':
                        $theme = 'admin_test';
                        break;
                    default:
                        $theme = 'default';
                        break;
                };
                
                $file = MODX_BASE_PATH.'themes/'.$theme.'/theme.config.php';
                $response = require($file);
                if (is_array($response)) $modx->config = array_merge($modx->config, $response);
                //$modx->cacheManager->refresh(array('system_settings' => array()));
            break;
        }
        1. Сергей Шлоков 15 мая 2021, 08:29 # 0
          К сожалению простым путём подменить путь для фенома не получится. Парсер жёстко запоминает путь из базы. Придётся делать финт ушами и говнокодить
          ...
          $response = require $file;
          if (is_array($response)) {
              $modx->parser->pdoTools->setConfig(['elementsPath' => $response['pdotools_elements_path']]);
          }
          
          Или пойти другим путём — у файловых элементов указать специальное свойство elementsPath
          {'@FILE chunks/chunk.tpl' | chunk : ['elementsPath' => 'pdotools_elements_path'|config]}
          1. Антон 15 мая 2021, 17:53 # 0
            Да, так завелось. Спасибо! )

    Вы должны авторизоваться, чтобы оставлять комментарии.

    Выделите опечатку и нажмите Ctrl + Enter, чтобы отправить сообщение об ошибке.