cyberm 05 сентября 2013 3 19
Пытаюсь сделать импорт товаров. Создаю товар $object = $modx->newObject('modResource');. Прописываю свойства. Но не могу указать цену и валюту. Кто-нибудь может показать пример кода, как это делают профессионалы?
19 комментариев
c
cyberm 05 сентября 2013г в 18:11 #
Может кому пригодится…
<?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
Fi1osof1
Fi1osof 05 сентября 2013г в 19:28 #
Сорри, не видел топика…

Полезный материал есть здесь.

По поводу приведенного примера: в целом да, он работоспособный. Но не оптимальный. Здесь есть серьезная хитрость: у тебя указан вызов конкретного 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.
c
cyberm 07 сентября 2013г в 21:47 #
Спасибо.
Я так и думал, что ты сможешь оптимизировать этот код. :)
Кстати, если кому понадобится, то TV задаются в том же массиве, что и остальные параметры в виде:
'tvN' =>$value, где N — идентификатор TV-параметра.
Fi1osof1
Fi1osof 07 сентября 2013г в 22:00 #
Пожалуйста.

Кстати, если кому понадобится, то 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-поля на обновления, то он эти два поля обновит, а остальные тупо удалит.
c
cyberm 07 сентября 2013г в 23:33 #
Спасибо за важное замечание.
Интересно, а где-нибудь есть документация по modx, где можно прочесть о подобных вещах?
Fi1osof1
Fi1osof 08 сентября 2013г в 00:29 #
Есть только официальная rtfm.modx.com/
Но дам далеко не все есть. Я вообще сам мало там смотрю, так как там многого нет. Особой документации по ядру тоже не видел. Практически все, что знаю — сам копал.
c
cyberm 27 ноября 2013г в 17:20 #
Пытаюсь в консоли обновить некоторые товары.
Делаю поиск по 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';
Fi1osof1
Fi1osof 27 ноября 2013г в 17:33 #
Выложите полный листинг кода, в котором возникает ошибка, и полный текст ошибки.
c
cyberm 27 ноября 2013г в 17:45 #
Так это и есть весь код. Процессор '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.
Fi1osof1
Fi1osof 27 ноября 2013г в 17:54 #
DEBUG — это вообще не серьезно. Это просто отладка. Поменяйте $modx->setLogLevel(3); на $modx->setLogLevel(1); или $modx->setLogLevel(xPDO::LOG_LEVEL_ERROR); и все.
Это просто информационные сообщения.
c
cyberm 27 ноября 2013г в 18:01 #
Если LogLevel(1), то просто модальное окно с сообщение «syntax error:». И все. Данные при этом не сохраняются.
Fi1osof1
Fi1osof 27 ноября 2013г в 18:23 #
Значит вы не все ошибки нам показали. Шлите в личку доступы в админку.
c
cyberm 08 сентября 2013г в 00:26 #
Только еще не указан sm_price.

Без sm_price работает. А вот без sm_currency документ сохраняется, но в каталоге не отображается. А при сохранении через админку не сохраняет, а требует заполнения поля «Валюта».
Fi1osof1
Fi1osof 08 сентября 2013г в 00:33 #
Да, требовать будет. В новой версии включу системную настройку Обязательное поле или нет. Сам я придерживаюсь того, что оно должно быть обязательным, но кому-то это может реально не нравиться.
А вот без sm_currency документ сохраняется, но в каталоге не отображается.
А вот это кажется очень сомнительным. Оба поля принадлежат одному объекту. Просто валюта — обязательное поле, а сумма — нет. Но при сохранении через процессор даже не должен объект сохраняться, так как ошибку возвращает именно процессор, и по сути не важно, через редактор идет сохранение или через консоль.
c
cyberm 08 сентября 2013г в 00:45 #
В данном случае я использую только каталог, без цен, корзины и т.д. Поэтому валюта мне и не требуется.
Через процессор без sm_currency не пробовал. Это через
$object = $modx->newObject('modResource');.
$object->Save();
Fi1osof1
Fi1osof 08 сентября 2013г в 00:54 #
Так поэтому и получается лажа. Ты же создаешь только объекты документа (ShopmodxResourceProduct) (что является расширенным modResource). А надо еще и ShopmodxProduct (именно у него поля sm_price, sm_currency и т.п.). К слову, именно ShopmodxProduct — и является основным объектом товара. Он может существовать и без документа, и расчет на то, что если магазин будет действительно большим (миллионы и более товаров), тогда скорее всего будут только объекты товаров с индивидуальными полями, роутером и т.п.

Но в штатном режиме лучше так не создавать такие объекты через newObject. Через процессоры гораздо правильней и надежней, так как в процессорах много логики может быть прописано, которой может не быть в самом классе объекта.
Fi1osof1
Fi1osof 08 сентября 2013г в 00:56 #
А не выводятся товары в каталог по одной простой причине: как я и сказал, у тебя есть только записи документа, но нет записей товара. А shopModx-овый product/getdata-процессор формирует запрос в жесткой связке с записями товаров. Это делается еще и для того, чтобы без учета вложенности и т.п. получать документы именно товаров, а не всех прочих страниц тоже.
c
cyberm 08 сентября 2013г в 01:49 #
Спасибо за разъяснение. С твоей подачи уже стал пользоваться процессорами.
У меня очень мало опыта. До этого сделал сайт с использованием чанков и снипетов, а сейчас делаю на Smarty и процессорах. Естественно выросла скорость работы сайта. А на сколько удобнее стало работать с modx'ом сложно переоценить.
NetBeans 7.4 + Foundation + SCSS + Modx + Smarty.
Проект на флешке занимает 0,5-2 Мб, синхронизируется по sftp.
Fi1osof1
Fi1osof 08 сентября 2013г в 02:49 #
Ничего, скоро и мы облачные технологии свои запустим, тоже в плане синхронизации dev- и production- сайтов поработаем.
Авторизуйтесь или зарегистрируйтесь (можно через соцсети ), чтобы оставлять комментарии.