Цена товара в зависимости от выбранного ТВ [решено]
        Доброго дня, нужна помощь.
Ни разу не писал плагины, но полагаю без этого здесь не обойтись.
Есть ТВ с возможными значениями:
Задача сделать так, чтобы в родное поле price (minishop2) в админке подставлялось значение товара с наименьшей ценой.
во фронтенде пока вывожу костылём:
    
    
                                                        Ни разу не писал плагины, но полагаю без этого здесь не обойтись.
Есть ТВ с возможными значениями:
@EVAL $output = $modx->runSnippet('pdoResources',array( 
'parents'=> $modx->resource->parent,
'resources'=> -$modx->resource->id,
'tpl'=>'@CODE:[[+pagetitle]]==[[+id]]', 
'showUnpublished'=>'1',
'limit'=>'0',
'depth'=>'0',
'hideContainers'=>'1', 
'outputSeparator'=>'||')); 
return '' . $output;В админке я чекбоксами выбираю подходящие товары.Задача сделать так, чтобы в родное поле price (minishop2) в админке подставлялось значение товара с наименьшей ценой.
во фронтенде пока вывожу костылём:
{if $template == 5}
{set $my}
{$clothes | replace :'||':','}
{/set}    
{$_modx->runSnippet('!msProducts', [      
'parents'=> $parent,
'resources'=> $my,
'tpl'=>'@INLINE: {$price} руб.', 
'showUnpublished'=> 1,
'limit'=> 1,
'depth'=> 0,
'sortby' => '{"price":"ASC"}',
'hideContainers'=> 1,
'toPlaceholder'=> 'res',
 ])}
 [[+res:empty=`<small>нет в наличии</small>`]]
 {else}
 {$price} {'ms2_frontend_currency' | lexicon}
{/if}    
            
                Поблагодарить автора            
            
                 Отправить деньги            
        
        
            Комментарии: 8
                Начну мыслить вслух, если вы не против.
Пытаюсь понять как пишутся плагины, для этого делаю что-то простое, например, при сохранении документа с шаблоном 5 нужно прибавить к цене 100 р. делаю вот таким образом:
Наверное стоит ещё сказать зачем такой костыль, когда есть дополнения типа msoptionsprice2 и другие.
Дело в том, что я делаю загрузку каталога с помощью msync. Так как в каталоге 1с размеры и цвета товаров — это отдельные товары, а на сайт я такое вываливать не хочу — я создаю товар с шаблоном 5 и через TV, с возможными значениям (описан в начале) назначаю ему нужные товары. В целом всё работает, но цену приходится назначать руками и следить за её изменениями.
Решение вижу в том, чтобы через плагин подставить значение товара из той самой ТВ с наименьшей ценой, при сохранении документа.
Если у кого будет минутка, направьте пожалуйста, а пока ковыряю дальше.
                    Пытаюсь понять как пишутся плагины, для этого делаю что-то простое, например, при сохранении документа с шаблоном 5 нужно прибавить к цене 100 р. делаю вот таким образом:
<?php
if ($modx->event->name = 'OnBeforeDocFormSave') {
	    if ($resource->get('template') == 5) {
        $price = $product->get('price');
        return $price + 100;
	    }
        break;
}но при сохранении страницы бесконечная загрузка и в журнале ошибок ничего. на каком шаге ошибка, пока не пойму.Наверное стоит ещё сказать зачем такой костыль, когда есть дополнения типа msoptionsprice2 и другие.
Дело в том, что я делаю загрузку каталога с помощью msync. Так как в каталоге 1с размеры и цвета товаров — это отдельные товары, а на сайт я такое вываливать не хочу — я создаю товар с шаблоном 5 и через TV, с возможными значениям (описан в начале) назначаю ему нужные товары. В целом всё работает, но цену приходится назначать руками и следить за её изменениями.
Решение вижу в том, чтобы через плагин подставить значение товара из той самой ТВ с наименьшей ценой, при сохранении документа.
Если у кого будет минутка, направьте пожалуйста, а пока ковыряю дальше.
                Примерно так должно работать
                    if ($modx->event->name == 'OnDocFormSave') {
	if ($resource->template != 5) { // id шаблона с товаром
		return;
	}
	// получаем id выбранных в TV продуктов
	$tv = $resource->getTVValue('имя_tv_с_чекбоксами');
	if (empty($tv)) {
		return;
	}
	$ids = explode($tv, ',');
	// получаем сами продукты
	$products = $modx->getCollection('msProduct', [
		'id:IN' => $ids
	]);
	if ($products) {
		$prices = [];
		
		// получаем цены для выбранных продуктов
		foreach ($products as $product) {
			$prices[] = $product->get('price');
		}
		// получаем минимальную цену
		$min_price = min($prices);
		if ($min_price) {
			// сохраняем цену для товара
			$resource->set('price', $min_price);
			$resource->save();
		}
	}
}            
                Для тв с чекбокасми возможно нужно поставить «тип вывода» — «разделитель» запятая.            
                    
                тв с таким типом стоит, но что интересно если в чанке просто вывести {$clothes} значения всё равно — 1 || 2 || 3 
Пробую ваш код:
                    Пробую ваш код:
<?php
if ($modx->event->name == 'OnDocFormSave') {
	if ($resource->template != 5) { // id шаблона с товаром
		return;
	}
	// получаем id выбранных в TV продуктов
	$tv = $resource->getTVValue('clothes');
	if (empty($tv)) {
		return;
	}
	$ids = explode($tv, ',');
	// получаем сами продукты
	$products = $modx->getCollection('msProduct', [
		'id:IN' => $ids
	]);
	if ($products) {
		$prices = [];
		
		// получаем цены для выбранных продуктов
		foreach ($products as $product) {
			$prices[] = $product->get('price');
		}
		// получаем минимальную цену
		$min_price = min($prices);
		if ($min_price) {
			// сохраняем цену для товара
			$product->set('price', $min_price);
			$resource->save();
		}
	}
}системное событие поменял на OnDocFormSave. Ресурс сохраняется нормально, но никаких изменений и в журнале ошибок пусто. Существует ли какой-то способ поиска ошибок в таком случае? как в сниппетах showLog например            
                Попробуйте разделитель в плагине поменять тогда на  ||
Ошибки можно записывать в журнал ошибок Управление — Отчеты — Журнал ошибок
                    Ошибки можно записывать в журнал ошибок Управление — Отчеты — Журнал ошибок
$modx->log(1, print_r($ids, 1)); // распечатает массив с ids            
                полезная вещь!
                    $modx->log(1, print_r($ids, 1)); // распечатает массив с idsмассив пустой — Array
(
    [0] => ,
)хотя $modx->log(1, print_r($tv, 1));выдаёт правильные id причём с разделителем запятая: 2689,2690,2691,2692,2693,2951,2952            
                Ну да, я explode не правильно написал, наоборот надо, сначала разделитель
                    $ids = explode(',', $tv);            
                Огромное спасибо! Теперь работает.
Рабочий плаин:
                    Рабочий плаин:
<?php
if ($modx->event->name == 'OnDocFormSave') {
	if ($resource->template != 5) { // id шаблона с товаром
		return;
	}
	// получаем id выбранных в TV продуктов
	$tv = $resource->getTVValue('clothes');
	if (empty($tv)) {
		return;
	}
	$ids = explode(',', $tv);
	// получаем сами продукты
	$products = $modx->getCollection('msProduct', [
		'id:IN' => $ids
	]);
	if ($products) {
		$prices = [];
		
		// получаем цены для выбранных продуктов
		foreach ($products as $product) {
			$prices[] = $product->get('price');
		}
		// получаем минимальную цену
		$min_price = min($prices);
		if ($min_price) {
			// сохраняем цену для товара
			$resource->set('price', $min_price);
			$resource->save();
		}
	}
}Благодарен вам! И научили как и за меня написали.            
                            Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.