MODX_API_MODE и процессоры

В рамках выполнения одной хитрой задачи, потребовалось написать скрипт, который будет запускаться по cron и что-то делать с MODX.

Проблемы, в общем то нет, вопрос изучен, но выплыл интересный глюк.
А именно: не работали процессоры для создания/обновления ресурсов.

То есть, процессор для логина — нормально, контекст mgr — нормально, а при попытке создать ресурс — просто пустая error.
Выложил вопрос на официальном форуме и никто мне не ответил. Пришлось разбираться самостоятельно, глубоко копая исходники.

И вот, что выяснилось: при запуске MODX из консоли, в режиме MODX_API_MODE, переменная $modx->error->message является массивом, тогда как должна быть строкой. Через это процессор при проверке ошибок, в ходе создания ресурсов, считает, что есть сообщение об ошибке — и выводит его мне. А я ничего не могу понять, ибо там пусто.

Таким образом, вот верный способ работы в MODX_API_MODE:
<?php
// Подключаем
define('MODX_API_MODE', true);
require dirname(dirname(__FILE__)).'/index.php';

// Включаем обработку ошибок
$modx->getService('error','error.modError');
$modx->setLogLevel(modX::LOG_LEVEL_FATAL);
$modx->setLogTarget(XPDO_CLI_MODE ? 'ECHO' : 'HTML');
$modx->error->message = null; // Обнуляем переменную

// Логинимся в админку
$response = $modx->runProcessor('security/login', array('username' => 'admin', 'password' => '123456'));
if ($response->isError()) {
    $modx->log(modX::LOG_LEVEL_ERROR, $response->getMessage());
    return;
}
$modx->initialize('mgr');

// Создаем ресурс
$response = $modx->runProcessor('resource/create', array(
    'pagetitle' => 'Имяресурса'
    ,'parent' => 1
    ,'content' => 'Текстресурса'
    ,'template' => 1
    ,'isfolder' => 1
    ,'published' => 1
));
if ($response->isError()) {
    $modx->log(modX::LOG_LEVEL_ERROR, $response->getMessage());
    return;
}
else {
    print_r($response->response);
}
Вот теперь можно делать что хотите с MODX, из своих скриптов от лица авторизованного админа.
Василий Наумкин
08 сентября 2012, 04:23
24
5 993
0
Поблагодарить автора Отправить деньги

Комментарии: 22

Иван Брежнев
08 сентября 2012, 12:24
0
Отличное решение, я давно пытался переделать ваш скрипт import_export.php на процессоры и столкнулся с той же проблемой, но не разобравшись бросил эту затею.
kochurkov
10 сентября 2012, 16:25
0
Нет слов, один сплошной восторг!
Роман Харин
12 сентября 2012, 13:34
0
Вот где «собака зарыта»!!!
Антон ХайЭксель
21 ноября 2012, 00:13
0
Вообщем снова я. помучался с процессорами. Добавление товаров в minishop получилось только под админом.
как ни мучался с правами user — НОЛЬ.

попробовал описанным методом, но тогда теряется авторизация пользователя…
как сохранить её?
    Василий Наумкин
    21 ноября 2012, 04:47
    0
    Этот метод вообще придуман для запуска из консоли, по расписанию через cron.

    А чтобы юзер смог добавлять товары, ему надо назначить кучу прав, типа «edit_document»,«publish_document» и т.д.
    Я так даже не заморачивался ни разу.
      Антон ХайЭксель
      21 ноября 2012, 08:27
      0
      Пробовал давать user права вплоть до администраторских (обе группы имели одинаковые настройки) — под админом создается, под user — нет =(
Rimas Kudelis
26 февраля 2014, 14:02
0
Делаю вроде всё по инструкций:
$response = $modx->runProcessor('security/login', array('username' => $username, 'password' => $password, 'login_context' => 'mgr'));
if ($response->isError()) {
	$modx->log(modX::LOG_LEVEL_ERROR, 'Could not log in, will exit now: '.$response->getMessage());
	exit;
}
$user_data = $modx->user->toArray();
if ($user_data['id'] == 0) {
	$modx->log(modX::LOG_LEVEL_ERROR, 'Failed to log in, will exit now: '.$response->getMessage());
	exit;		
}
Первый блок срабатывает, второй – нет. Включив дебаг, при попытке авторизации выводится вот что:

There was an error retrieving or creating session id: jkrdurgorih6im1m9pa0r1ol42
и дальнейший скрипт не срабатывает, так как юзер, оказывается, аноним… пробовал гуглить, но ничего полезного не нашёл. Может подскажите, в чем может быть дело?

Кстати, при обращении к скрипту, сессия в БД создаётся, нот с другим ИД.
    A
    A
    26 февраля 2014, 22:02
    0
    Закрой сессию перед тем как открывать новую.
      Rimas Kudelis
      27 февраля 2014, 11:12
      0
      А это как делается? Я сессию вообще в своём скрипте не трогаю.
      Rimas Kudelis
      27 февраля 2014, 14:48
      0
      Вот уж как интересно…
      Ошибки с сессией избавился. Похоже, контекст не совпадал.
      Но другая штука вылезла: авторизация проходит успешно, а вот $modx->user остаётся тот самый, как и был (т.е. там и дальше хранятся данные, что наш юзер – аноним). Вообще-то это мне не мешает (правда, жаль что в БД не записывается информация о том, какой юзер создал импортированные товары), но странно всё-таки… Или всё так и должно быть?
Дмитрий
01 августа 2015, 00:21
0
Подскажите, пожалуйста, как правильно передать дату создания документа. Т.е. если нужно именно указать НЕ текущую дату. Прописываю

,'publishedon' => $next_date

где $next_date вида 21.07.15
Не получается, вставляется текущая дата и всё. Думал надо в UNIX формате указывать. Сделал, стали прописываться какие-то совершенно левые даты… Не пойму в чём дело.
Дмитрий
03 августа 2015, 11:19
0
Парни, спасибо большое! Василий, действительно в том формате, что вы указали надо выставлять дату. При этом настройки системы на это не влияют. Они только для вывода даты в админке нужны по всей видимости.
Евгений
24 июля 2017, 16:49
0
Что за ошибка?


Fatal error: require(): Failed opening required '/home/mesial1/www/test.mymilena.ru/core/cache/includes/elements/index.php' (include_path='.:/opt/php54/pear') in /home/mesial1/www/test.mymilena.ru/core/cache/includes/elements/modsnippet/92.include.cache.php on line 3

Вот код
<?php
define('MODX_API_MODE', true);
require dirname(dirname(__FILE__)).'/index.php';

$response = $modx->runProcessor('security/login', array('username' => $username, 'password' => $password));
if ($response->isError()) {
    $modx->log(modX::LOG_LEVEL_ERROR, $response->getMessage());
    return;
}
$modx->initialize('mgr');
    Воеводский Михаил
    24 июля 2017, 17:24
    1
    +1
    В сниппете объявлять MODX_API_MODE и подключать основной index.php — давно я подобного не встречал.

    Указанный код необходимо размещать в каком-либо подкаталоге корня сайта, тогда и подключение корректно произойдет, и от MODX_API_MODE будет толк.
    Сергей Шлоков
    25 июля 2017, 07:16
    +1
    Вы сами пишете код или откуда-то просто копируете? Вы понимаете, что эта конструкция значит?
    require dirname(dirname(__FILE__)).'/index.php';
    Она значит — подняться на одну директорию выше текущего файла и там найти файл index.php. PHP ищет этот файл в директории elements и не находит. Об этом и сообщается в ошибке. Файл index.php находится в корне. Поэтому, чтобы его подключить, нужно ещё 4 раза вызвать функцию dirname().
Евгений
24 июля 2017, 17:44
0
С этим понятно, спасибо.
define('MODX_API_MODE', true);
require dirname(dirname(__FILE__)).'/index.php';
Как быть с остальным кодом, при добавлении товара через процессор, в кроне получаю:
Array
(
    [success] => 
    [message] => permission_denied
    [total] => 0
    [errors] => Array
        (
        )
    [object] => Array
        (
        )
)
    Воеводский Михаил
    24 июля 2017, 18:06
    0
    Необходимо добавить получение пользователя и его авторизацию, чтобы исключить такую ошибку.
    В сообществе уже обсуждалось, поищите.
Евгений
25 июля 2017, 00:21
0
Нашел ответ.
В этой статье afres.ru/blog/working-with-modx-revolution-api
Нужно перед авторизацией включить сессии!
// Включаем сессии MODX и инициализируем контекст web
require_once 'config.core.php';
require_once MODX_CORE_PATH.'model/modx/modx.class.php';
$modx = new modX();
$modx->initialize('web');

$response = $modx->runProcessor('security/login', ['username' => 'admin', 'password' => '123456']);
            if ($response->isError()) {
                $modx->log(modX::LOG_LEVEL_ERROR, $response->getMessage());
                return;
            }
            $modx->initialize('mgr');
Как то так у меня получилось…
    Сергей Шлоков
    25 июля 2017, 07:17
    +1
    Сессии здесь совершенно не причем. Читайте мой комментарий выше.
Евгений
25 июля 2017, 11:33
0
С конструкцией
require dirname(dirname(__FILE__)).'/index.php';
я разобрался. Но при этом получал ошибку
Array
(
    [success] => 
    [message] => permission_denied
    [total] => 0
    [errors] => Array
        (
        )
    [object] => Array
        (
        )
)
И вот тут то меня выручили сессии…
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.