Config Mutator - что это и зачем?

Config Mutator это новое понятие которое я предлагаю внедрять при помощи файла config_mutator.php в MODX Evolution старше 1.4.4.

По умолчанию, данного файла в ядре нет и не будет. Его необходимо создать рядом с вашим config.inc.php (на данный момент это /manager/includes/config.inc.php).

Этот файл поможет вам внедрить composer до того, как будет запущено ваше ядро и произойдут срабатывания событий OnWebPageInit/OnManagerPageInit (иногда это может быть полезно, но частный случай мы разберем ниже)

Если вы думаете, что достаточно поправить config.inc.php, то глубоко заблуждаетесь. Этот файл перезаписывается по шаблону после каждого обновления движка. И это самая важная причина, почему Config Mutatorу быть!

Предположим:
— У вас MODX Evolution старше 1.4.4 (или на данный момент вы взяли dev версию из репозитория)
— Вы не боитесь с composer
— Уже слышали про мою версию DBAPI

Активация Config Mutator
Шаг 1
Создаем config_mutator.php рядом с вашим config.inc.php примерно такого содержания
<?php
$aboveRoot = __DIR__ . '/../../../';
include_once $aboveRoot . 'vendor/autoload.php';

global $database_type,
       $database_server,
       $database_user,
       $database_password,
       $database_connection_charset,
       $database_connection_method,
       $dbase,
       $table_prefix;

$envFile = $aboveRoot . '.env';
if (file_exists($envFile)) {
    if (!is_readable($envFile)) {
        throw new Exception("!!! .env file can't readable");
    }

    $config = M1\Env\Parser::parse(file_get_contents($envFile));

    if (!empty($config['DB_TYPE'])) $database_type = $config['DB_TYPE'];
    if (!empty($config['DB_HOST'])) $database_server = $config['DB_HOST'];
    if (!empty($config['DB_USERNAME'])) $database_user = $config['DB_USERNAME'];
    if (!empty($config['DB_PASSWORD'])) $database_password = $config['DB_PASSWORD'];
    if (!empty($config['DB_CHARSET'])) $database_connection_charset = $config['DB_CHARSET'];
    if (!empty($config['DB_METHOD'])) $database_connection_method = $config['DB_METHOD'];
    if (!empty($config['DB_DATABASE'])) $dbase = '`' . trim($config['DB_DATABASE'], '`') . '`';
    if (!empty($config['DB_PREFIX'])) $table_prefix = $config['DB_PREFIX'];
    if (!empty($config['EVO_SERVICES_FILE'])) define('EVO_SERVICES_FILE', $config['EVO_SERVICES_FILE']);
}

Шаг 2
Копируем содержимое файла services.php (а еще лучше через array_merge изменяем) в services2.php (можно положить этот файл куда угодно, главное на 3 шаге указать верный путь для параметра EVO_SERVICES_FILE) и немного изменяем, чтобы получилось примерно так
<?php
global $database_server, $dbase, $database_user, $database_password, $table_prefix, $database_connection_charset, $database_connection_method;

return [
    EvolutionCMS\Interfaces\DatabaseInterface::class => array(
        'class' => AgelxNash\Modx\Evo\Database\LegacyDatabase::class,
        'arguments' => array(
            $database_server,
            $dbase,
            $database_user,
            $database_password,
            $table_prefix,
            $database_connection_charset,
            $database_connection_method,
            'utf8mb4_unicode_ci',
            AgelxNash\Modx\Evo\Database\Drivers\IlluminateDriver::class
        ),
        'calls' => array(
            array(
                'method' => 'query',
                'arguments' => array(
                    "SET SQL_MODE = '';"
                )
            )
        )
    ),
    ..........

Шаг 3
Выше корня вашего сайта создаем .env файл (с синтаксисом .env файла можно ознакомиться тут) по подобию этого
DB_TYPE=mysqli
DB_HOST=localhost
DB_USERNAME=root
DB_PASSWORD=pass
DB_CHARSET=utf8mb4
DB_METHOD="SET NAMES"
DB_DATABASE=modx
DB_PREFIX=modx_
EVO_SERVICES_FILE=/var/www/example.com/public/manager/includes/services2.php

Шаг 4
Так же выше корня сайта создаем composer.json файл следующего вида
{
  "name": "agelxnash/evo-project",
  "license": "MIT",
  "authors": [
    {
      "name": "agel_nash",
      "email": "modx@agel-nash.ru",
      "homepage": "https://agel-nash.ru"
    }
  ],
  "require": {
    "m1/env": "~2.1",
    "agelxnash/modx-evo-database": "~1.4",
    "illuminate/database": "~5.6",
    "illuminate/events": "~5.6"
  },
  "require-dev": {
    "roave/security-advisories": "dev-master"
  },
}

Шаг 5
Теперь открываем консоль и в папке с вашим composer.json выполняем composer install.

Profit
— Подключили composer до загрузки ядра
— Научились подменять значения конфига (внутри config_mutator.php можете заложить свою логику)
— Подменили стандартный DBAPI класс на новую версию и активировали поддержку Eloquent ORM

Пример использования Eloquent
$out = AgelxNash\Modx\Evo\Database\Models\SiteContent::where('parent', '>', 0)
    ->orderBy('pagetitle', 'DESC')
    ->limit(10)
    ->get();
foreach ($out as $item) {
    echo "\t [ DOCUMENT #ID " . $item->id . ' ] ' . $item->pagetitle . PHP_EOL;
    $item->longtitle = $item->pagetitle;
    $item->save();
}

К сожалению, моделей как таковых еще нет. Но вы можете помочь мне прислав PR. За подробностями можете обратиться к документации по Laravel

3 комментария

avatar
Так composer же и так подключается до загрузки ядра, даже до загрузки конфига.
avatar
Раньше подключался. Теперь нет, т.к.
— Место подключения выбрано из корня сайта. Лично мне, да я думаю и многим другим это не нравится. Возня с конфигами nginx или .htaccess это не дело. Сейчас же я могу самостоятельно выбирать место где буде располагаться сие чудо.
— composer.json по умолчанию лежит в корне сайта. Многие обновляются перезаписью файлов и может возникнуть много боли, когда по запарке перезатрутся нужные зависимости (composer.lock? А если в этой же запаре уже успели выполнить composer update?)
— Несмотря на подключение автозагрузчика, зависимостей у проекта нет. Даже PHPMailer, PHPThumb до сих пор в ручную обновляют. Целесообразность подобного внедрения вызывает большие вопросы.
avatar
В том месте где был ранее подключался композер, мы обязаны были следить за всеми index и ajax скриптами, чтобы они тоже не забывали это делать. Помимо этого от туда нет доступа ни к одной переменной. Так что config mutator это не просто место для инклюда кастомного автозагрузчика. Собственно это я и хотел показать в статье.
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.