5 сент. 2013 г., 2:39

Как программно создать документ

Пытаюсь сделать импорт товаров. Создаю товар $object = $modx->newObject('modResource');. Прописываю свойства. Но не могу указать цену и валюту. Кто-нибудь может показать пример кода, как это делают профессионалы?
Может кому пригодится…
<?php if(!$path = $modx->getOption('shopmodx.core_path')){ $path = $modx->getOption('core_path').'components/shopmodx/'; } $path .= 'processors/'; $options = array( 'pagetitle' => 'Пример создания', 'template' => 3, 'parent' => 87, 'class_key' => 'ShopmodxResourceProduct', 'sm_currency' => 79, 'published' => true, ); $response = $modx->runProcessor('mgr/resourceproduct/create', $options, array( 'processors_path' => $path, )); if($response->isError()){ print "error"; } print_r($response->getResponse()); print '<br />OK';
На основе комментария Fi1osof'a в этой ветке community.modx-cms.ru/blog/solutions/9448.html
Сорри, не видел топика…
Полезный материал есть здесь.
По поводу приведенного примера: в целом да, он работоспособный. Но не оптимальный. Здесь есть серьезная хитрость: у тебя указан вызов конкретного shopModx-ого процессора, но это не обязательно делать. Почему? Посмотрим на метод системного процессора resource/create modResourceCreateProcessor::getInstance()
public static function getInstance(modX &$modx,$className,$properties = array()) { $classKey = !empty($properties['class_key']) ? $properties['class_key'] : 'modDocument'; $object = $modx->newObject($classKey); if (!in_array($classKey,array('modDocument','modResource',''))) { $className = $classKey.'CreateProcessor'; if (!class_exists($className)) { $className = 'modResourceCreateProcessor'; } } /** @var modProcessor $processor */ $processor = new $className($modx,$properties); return $processor; }
Особенно обратить внимание на:
$className = $classKey.'CreateProcessor'; if (!class_exists($className)) { $className = 'modResourceCreateProcessor'; }
То есть он на лету формирует по маске название класса-процессора для указанного class_key, и если такой объявлен, то выполняется именно этот процессор вместо системного. Итог: можно легко вызывать и системный процессор, при этом выполнится shopModx-овый в соответствии с указанным class_key. Конечный код такой:
$options = array( 'pagetitle' => 'Пример создания', 'template' => 3, 'parent' => 87, 'class_key' => 'ShopmodxResourceProduct', 'sm_currency' => 79, 'published' => true, ); $response = $modx->runProcessor('resource/create', $options); if($response->isError()){ print "error"; } print_r($response->getResponse()); print '<br />OK';
Только еще не указан sm_price.
Спасибо. Я так и думал, что ты сможешь оптимизировать этот код. :) Кстати, если кому понадобится, то TV задаются в том же массиве, что и остальные параметры в виде: 'tvN' =>$value, где N — идентификатор TV-параметра.
Пожалуйста.
Кстати, если кому понадобится, то TV задаются в том же массиве, что и остальные параметры в виде: 'tvN' =>$value, где N — идентификатор TV-параметра.
По этому поводу тоже есть что сказать очень важное. Механизм с TV-шками в resource/create и resource/update очень сильно отличается. resource/create да, просто смотрит параметры вида tv{$tvID}, и если таковые имеются, то создает соответствующие TV-шки для ресурса. А resource/update просто так их не присваивает и не обновляет. Для того, чтобы он обновил TV-шки, надо передать параметр tvs=>true. Но тут есть очень опасный подводный камень. Если передан tvs, то процессор обновит не только переданные в параметре TV-шки, но и вообще все TV-шки этого ресурса. При чем не указанные TV-шки он просто удалит. То есть если у ресурса есть 10 назначенных TV со значениями, а вы передаете а параметрах, допустим, только два TV-поля на обновления, то он эти два поля обновит, а остальные тупо удалит.
Спасибо за важное замечание. Интересно, а где-нибудь есть документация по modx, где можно прочесть о подобных вещах?
Только еще не указан sm_price.
Без sm_price работает. А вот без sm_currency документ сохраняется, но в каталоге не отображается. А при сохранении через админку не сохраняет, а требует заполнения поля «Валюта».
Есть только официальная rtfm.modx.com/ Но дам далеко не все есть. Я вообще сам мало там смотрю, так как там многого нет. Особой документации по ядру тоже не видел. Практически все, что знаю — сам копал.
Да, требовать будет. В новой версии включу системную настройку Обязательное поле или нет. Сам я придерживаюсь того, что оно должно быть обязательным, но кому-то это может реально не нравиться.
А вот без sm_currency документ сохраняется, но в каталоге не отображается.
А вот это кажется очень сомнительным. Оба поля принадлежат одному объекту. Просто валюта — обязательное поле, а сумма — нет. Но при сохранении через процессор даже не должен объект сохраняться, так как ошибку возвращает именно процессор, и по сути не важно, через редактор идет сохранение или через консоль.
В данном случае я использую только каталог, без цен, корзины и т.д. Поэтому валюта мне и не требуется. Через процессор без sm_currency не пробовал. Это через $object = $modx->newObject('modResource');. $object->Save();
Так поэтому и получается лажа. Ты же создаешь только объекты документа (ShopmodxResourceProduct) (что является расширенным modResource). А надо еще и ShopmodxProduct (именно у него поля sm_price, sm_currency и т.п.). К слову, именно ShopmodxProduct — и является основным объектом товара. Он может существовать и без документа, и расчет на то, что если магазин будет действительно большим (миллионы и более товаров), тогда скорее всего будут только объекты товаров с индивидуальными полями, роутером и т.п.
Но в штатном режиме лучше так не создавать такие объекты через newObject. Через процессоры гораздо правильней и надежней, так как в процессорах много логики может быть прописано, которой может не быть в самом классе объекта.
А не выводятся товары в каталог по одной простой причине: как я и сказал, у тебя есть только записи документа, но нет записей товара. А shopModx-овый product/getdata-процессор формирует запрос в жесткой связке с записями товаров. Это делается еще и для того, чтобы без учета вложенности и т.п. получать документы именно товаров, а не всех прочих страниц тоже.
Спасибо за разъяснение. С твоей подачи уже стал пользоваться процессорами. У меня очень мало опыта. До этого сделал сайт с использованием чанков и снипетов, а сейчас делаю на Smarty и процессорах. Естественно выросла скорость работы сайта. А на сколько удобнее стало работать с modx'ом сложно переоценить. NetBeans 7.4 + Foundation + SCSS + Modx + Smarty. Проект на флешке занимает 0,5-2 Мб, синхронизируется по sftp.
Ничего, скоро и мы облачные технологии свои запустим, тоже в плане синхронизации dev- и production- сайтов поработаем.
Пытаюсь в консоли обновить некоторые товары. Делаю поиск по tv и меняю некоторые свойства. Отдельно поиск работает, отдельно обновление тоже работает. А если запускать последовательно поиск и обновление, то при обновлении появляется «syntax error». В чем может быть причина? Может лучше переопределить mgr/resourceproduct/update и там добавить проверку по условию?
<?php print '<pre>'; $modx->setLogLevel(3); $namespace = 'modxsite'; if(!$response = $modx->runProcessor('web/catalog/products/article/getdata', array("article" => "Н001024",), array('processors_path' => $modx->getObject('modNamespace', $namespace)->getCorePath().'processors/',))){ print "Не удалось выполнить процессор"; return; } $result = $response->getResponse(); if ($object = current($result['object'])){ //print_r($object); $params['class_key'] = 'ShopmodxResourceProduct'; $params['context_key'] = 'web'; $params['pagetitle'] = $object['pagetitle']; $params['parent'] = $object['parent']; $params['id'] = $object['object_id']; $params['sm_price'] = 2070; if(!$response = $modx->runProcessor('mgr/resourceproduct/update', $params , array('processors_path' => $modx->getOption('core_path').'components/shopmodx/processors/',))){ print "Не удалось выполнить процессор"; return; } } print '<br />OK';
Выложите полный листинг кода, в котором возникает ошибка, и полный текст ошибки.
Так это и есть весь код. Процессор 'web/catalog/products/article/getdata' сделан по образу и подобию из топика про поиск по tv.
Вот ответ, если поменять loglevel:
print '</pre>'; Loading... syntax error: [2013-11-27 17:40:00] (DEBUG @ /manager/components/console/connectors/console.php) Language string not found: "Имя возвращающей значение функции. getBaseUrl или getBasePath" [2013-11-27 17:40:00] (DEBUG @ /manager/components/console/connectors/console.php) Language string not found: "" [2013-11-27 17:40:00] (DEBUG @ /manager/components/console/connectors/console.php) Language string not found: "id медиасурса. Обязательное"
Плюс еще несколько таких же DEBUG.
DEBUG — это вообще не серьезно. Это просто отладка. Поменяйте $modx->setLogLevel(3); на $modx->setLogLevel(1); или $modx->setLogLevel(xPDO::LOG_LEVEL_ERROR); и все. Это просто информационные сообщения.
Если LogLevel(1), то просто модальное окно с сообщение «syntax error:». И все. Данные при этом не сохраняются.
Значит вы не все ошибки нам показали. Шлите в личку доступы в админку.

Добавить комментарий