Возможен ли реврайт любого урла из плагина?

Сабж. Хотел сделать возможность динамического переопределения урлов администратором. Но обращение к каким-либо классам в конфиге невозможно (надо получить список урлов), а в методе Init() плагина что-либо делать с config.uri уже поздно. Возможно ли это реализовать?

Похожие статьи


19 комментариев

+1
Возможно. Воспользуйтесь методом Config::WriteCustomConfig($aData);
Посмотрите примеры работы с данным методом в коде.
0
Вижу ReadPluginConfig/WritePluginConfig. Спасибо, посмотрю.
0
Если честно, результаты выглядят для меня странно. Я записываю в конфиг массив, ожидаю прочитать тот же массив, однако, получаю старый массив + новые только что записанные данные. WTF? Так и должно быть? Я смотрю с БД storage, там сериализованнные данные корректно сохраняются. Видимо, старый мусор добавляется в кеш и читается оттуда.
Отредактирован:
0
Что вообще делаю:
1. Config::WritePluginConfig($sPluginName, ['webpaths' => ['foo']]);
2. Config::ReadPluginConfig($sPluginName, 'webpaths'); // [0 => foo]
3. Config::WritePluginConfig($sPluginName, ['webpaths' => ['bar']]);
4. Config::ReadPluginConfig($sPluginName, 'webpaths'); // [0 => foo, 1 => bar]
Отредактирован:
0
Окей, допустим это поведение нормальное. Тогда используя Config::ResetPluginConfig($sPluginName, 'webpaths'); можно очистить ['webpaths' => ['foo']] и записать ['webpaths' => ['bar']].
Но тогда сбрасываются вообще все (!) настройки, сделанные в админке. При этом, опять же, в `storage` всё на месте.
Отредактирован:
0
Так, до сего момента я делал на 1.1.10, смержил 1.1.12, и словил фатальную ошибку при попытке вызвать Config::ReadPluginConfig из конфига плагина:
Fatal error: Class 'E' not found in /var/www/altocms/engine/classes/core/Config.class.php on line 991
Видимо, теперь этот способ не подходит.
Отредактирован:
0
Вызывать эти методы до того, как загрузится ядро движка (класс Engine), нельзя, т.к. там идет обращение к базе данных, а это идет уже через модуль БД, а он вызывается через ядро.
0
Ну ок, с этим понятно. Но проблема с полной очисткой конфига при очистке ключа (Config::ResetPluginConfig($sPluginName, 'webpaths')) это всё же проблема или нет? Я так понимаю, что там удаляется весь общий файл кеша, но почему-то не генерируется новый.
Отредактирован:
0
А что значит «динамическое переопределение»? Это нужно заново переопределять при каждом запуске?
0
Ну да. Админ на специальной странице назначил в нашем плагине веб-путь для сущности. Он где-то сохраняется. Затем, при загрузке модуля, в конфиге, подгружается список этих веб-путей, по ним гененируются регулярки для router.uri вида ['[~^foo/bar$~]' => 'myaction/42', …], где в myaction есть ивент, который работает уже с идентификаторами урлов (42). Вот так это должно было работать по задумке.
Отредактирован:
0
На гитхабе обновлена работа с конфигом. Погонял, потестил у себя — работает все так, как ожидается. Допустим, есть плагин 'test' и у него такой конфиг-файл:
$config['zero'] = 0;
И мы можем получить значение конфига плагина обычным путем:
// Получить значение конфига плагина
Config::Get('plugin.test'); // ['zero => 0]
Но можем так же прочитать те значения конфига плагина, которые сохранялись через Config::WritePluginConfig():
// Получить значение сохраненного конфига плагина
Config::ReadPluginConfig('test'); // null
Изначально это — null.

Теперь сохраняем программно новые значения и смотрим, что имеем на выходе:
Config::WritePluginConfig('test', ['one' => 1, 'two' => 2]);
Config::Get('plugin.test'); // ['zero => 0, 'one' => 1, 'two' => 2]
Config::ReadPluginConfig('test'); // ['one' => 1, 'two' => 2]
Т.е. обычный Config::Get() возвращает все ключи конфига, как из конфиг-файла, так и сохраненные программно, а Config::ReadPluginConfig() возвращает только программно сохраненные ключи конфига.

Еще примеры программных манипуляций конфигом:
// Сброс конкретного ключа
Config::ResetPluginConfig($sPluginName, 'one');
Config::Get('plugin.test'); // ['zero => 0, 'two' => 2]
Config::ReadPluginConfig('test'); // ['two' => 2]

// Сброс всех сохраненных настроек конфига заданного плагина
// Настройки, заданные в конфиг-файле плагина не меняются
Config::ResetPluginConfig($sPluginName);
Config::Get('plugin.test'); // ['zero => 0]
Config::ReadPluginConfig('test'); // null

// Сохранение ключа 'webpaths'
Config::WritePluginConfig($sPluginName, ['webpaths' => ['foo']]);
Config::Get('plugin.test'); // ['zero => 0, 'webpaths' => ['foo']]
Config::ReadPluginConfig('test'); // ['webpaths' => ['foo']]

// Значение ключа 'webpaths' будет заменено на новый массив
Config::WritePluginConfig($sPluginName, ['webpaths' => ['bar']]);
Config::Get('plugin.test'); // ['zero => 0, 'webpaths' => ['bar']]
Config::ReadPluginConfig('test'); // ['webpaths' => ['bar']]

// Действие, аналогичное директиве config['$root$'] в конфиг-файле плагина
Config::WritePluginConfig('test3', ['$root$' => ['router.uri' => ['aaa' => 'bbb']]]);
Config::Get('plugin.test'); // ['zero => 0, 'webpaths' => ['bar']]
Config::ReadPluginConfig('test'); // ['webpaths' => ['bar'], '$root$' => ['router.uri' => ['aaa' => 'bbb']]]
Последний пример примечателен тем, что через конфиг плагина он воздействует на общий конфиг приложения — добавляет значение в секцию 'router.uri'.

В принципе, мы могли бы воздействовать на конфиг приложения напрямую через Config::Set() или через Config::WriteCustomConfig(). Но использование Config::WritePluginConfig() является более предпочтительным и вот почему: если плагин отключается в админке, то все его настройки, которые были сделаны через Config::WritePluginConfig() также будут отключены автоматически.
0
Спасибо, это как раз то, что надо.
Я попробовал сделать так, как в последнем примере:
Config::WritePluginConfig($sPluginName, [Config::KEY_ROOT => [
    "router.uri" => [
        "[~^admin/about$~iu]"] => "feedback/1"
    ]
]);

Затем читаю:

Config::ReadPluginConfig($sPluginName);
/* Возвращает:
array(1) {
  ["$root$"]=>
  array(1) {
    ["router.uri"]=>
    array(1) {
      ["[~^admin/about$~iu]"]=>
      string(10) "feedback/1"
    }
  }
}
*/

Затем вывожу Config::Get('router.uri'), но в нём нет нашего элемента.
0
И ещё перестали сохраняться какие-либо настройки в админке, ошибок в логах нет
Отредактирован:
0
Забыл отметить нюанс: при использовании '$roor$' эффект будет при следующей загрузке страницы
0
В экшне плагина в админке записывается, а в конфиге плагина выводится
$aConfigWebpaths = Config::ReadPluginConfig('feedback');
var_dump(Config::Get('router.uri'), $aConfigWebpaths);

Внутри aConfigWebpaths:
array(1) {
  ["_db_"]=>
  bool(false)
}
Отредактирован:
0
Методы Config::ReadPluginConfig()/Config::WritePluginConfig() работают с базой данных, поэтому смысла нет вызывать их при до загрузки ядра. Не знаю, возможно, стоит выбрасывать исключение, когда они вызываются в неположенном месте, чтоб разработчику было понятно.

Но если в вашем случае вызвать Config::Get('router.uri') в любом экшене, то должно вернуть верные значения. Или, например, можно повесить хук на 'action_before' (он вызывается ДО того, как будет определен класс экшена для обработки URL).
0
Желаемого результата (установка и применение правил $root$ через WritePluginConfig) смог добиться только после отключения плагина «Multiple File Upload». После повторной активации плагина, ничего не сломалось и продолжило нормально работать, хм.
0
Могу предположить, что до этого было что-то некорректно записано в конфиг (либо в базу, либо в кеш), а при отключении/включении плагина конфиг перезаписался корректно и все заработало
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.