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
modx.pro
24
6 846
0
Поблагодарить автора Отправить деньги

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

Иван Брежнев
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().
                      wissem
                      28 мая 2019, 15:16
                      0
                      А как правильно подключить этот код? Я так понимаю, что создавать сниппет с кодом это не правильно. А как тогда?
                    Евгений
                    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
                                (
                                )
                        )
                        И вот тут то меня выручили сессии…
                          Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
                          23