Сниппет вывода TV параметров при условии их наличия

пригодился для вывода списка параметров товара из TV
наименование TV берется из description
UPD: после долгих раздумий добавил в фильтр id категории

<?php
/**
 * {'pars_part_tv' | snippet : [
        'templates' => $_modx->resource.template,
        'ids'       => $_modx->resource.id,
        'inTv'       => 'weight,lenght,-1sId',
        'category'  => '14,15',
    ]}
 * @param templates - id шаблона (обязательно)
 * @param ids - id ресурса (обязательно)
 * @param inTv - TV параметры через запятую, если нужно исключить какой-то параметр то пишем со знаком "-"
 * @param category - id каталога TVшек для дополнительной фильтрации
 * @param outerClass - класс обвертки по умолчанию ms2_product__tvs
 * 
*/

if (empty($templates) || empty($ids)) {
	return;
}

$inTv = ($inTv != '') ? array_map('trim', explode(',', $inTv)) : false;
$exTv = []; // tv исключения
$exTv_temp = []; // tv исключения временный
if ($inTv) {
	foreach ($inTv as $ikey => $IT) {
		if ($IT['0'] == '-') {
			$exTv[] = substr($IT,1);
			$exTv_temp[] = $IT;
		}
	}
	if (count($exTv)) {
		$inTv = array_diff($inTv, $exTv_temp);
	}
}

$res = $modx->getObject('modResource', ['id' => $ids]);
if ($res == null) {
	return;
}

if (empty($outerClass)) {
	$outerClass = 'ms2_product__tvs';
}

if ($inTv || $exTv) {
	$tvq = $modx->newQuery('modTemplateVar');
	$tvq->where(['id:<>' => 0]);
	if ($inTv) {
		$tvq->where(['AND:name:IN' => $inTv]);
	}
	if ($exTv) {
		$tvq->where(['AND:name:NOT IN' => $exTv]);
	}
	if ( !empty($category) ) {
		$tvq->where(['AND:category:IN' => array_map('trim', explode(',', $category) )]);
	}

	$tvs = $modx->getIterator('modTemplateVar', $tvq);
} else {
	$tvq = $modx->newQuery('modTemplateVarTemplate');
	$tvq->leftJoin('modTemplateVar', 'tvs', 'tvs.id = modTemplateVarTemplate.tmplvarid');
	$tvq->where(['templateid' => $templates]);
	if (!empty($category)) {
		$tvq->where(['tvs.category:IN' => array_map('trim', explode(',', $category))]);
	}
	$tvq->select($modx->getSelectColumns('modTemplateVar', 'tvs'));
	$tvs = $modx->getIterator('modTemplateVarTemplate', $tvq);
	$tvq->prepare();
}

if ($tvs == null) {
	return;
}

$html = '<div class="'.$outerClass.'">';
foreach ($tvs as $tkey => $T) {
	if ($res->getTVValue($T->get('name')) != '') {
		if ($inTv) {
			if (in_array($T->get('name'), $inTv)) {
				$html .= '<div class="'.$outerClass.'_inner">
					<div class="'.$outerClass.'_title">'.$T->get('description').'</div>
					<div class="'.$outerClass.'_body">'.$res->getTVValue($T->get('name')).'</div>
				</div>';
			}
		} else {
			$html .= '<div class="'.$outerClass.'_inner">
				<div class="'.$outerClass.'_title">'.$T->get('description').'</div>
				<div class="'.$outerClass.'_body">'.$res->getTVValue($T->get('name')).'</div>
			</div>';
		}
	}
}
$html .= '</div>';

return $html;
Stepan
25 июля 2022, 13:57
modx.pro
1 421
+1

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

Роман
25 июля 2022, 14:52
0
Очень странная логика: если нет параметра templates, тогда вот это как будет выполнятся: $tvq->where(['templateid' => $templates]);
или вот это $res = $modx->getObject('modResource', ['id' => $ids]); если нет ids, то тогда все товары выведет.
    Stepan
    25 июля 2022, 15:08
    0
    там выше
    if (empty($templates) || empty($ids)) {
    	return;
    }
    но в принципе сильно переписал
    теперь можно списки TV передавать какие выводить или какие не выводить
    ну или все выводить
    Илья Уткин
    25 июля 2022, 16:13
    0
    Что ж вы HTML-то напрямую в сниппет суете? Есть же такой классный механизм чанков у MODX, и феном, благодаря pdoTools можно использовать… Эх…
      Stepan
      25 июля 2022, 17:48
      0
      честно говоря тогда это был бы уже не снипет… (ну в смысле заголовок статьи пришлось бы менять)
      хотя можно было-бы типа parsChunk и все дела, но — это уже, я думаю, пользователи под себя подстроят если захотят
        Илья Уткин
        25 июля 2022, 18:23
        0
        Я не просто так придираюсь. HTML внутри PHP выглядит очень плохо, модифицируется в будущем ещё хуже и абсолютно не читается. Если как вариант «сделать и забыть» — ну ок. Но мой опыт подсказывает — вы сами еще столкнетесь с необходимостью что-то поменять, и будет неудобно.
          Stepan
          25 июля 2022, 18:42
          0
          согласен
          что все стоит делать как следует
          вообще бы добавить в тот-же минишоп
          тогда можно и параметры дать нормально сниппету
          и шаблоны…
          а то параметры товара есть вывод, а ТВ таким-же макаром нет
          добавить еще обработчики для TV и так далее…
          Кто там минишопом заведует
      Stepan
      25 июля 2022, 18:47
      0
      а еще можно опираться не только на список TV но и категорию где лежат TV тогда оформлять код будет проще!
        Stepan
        25 июля 2022, 19:29
        0
        Добавил категори)))
          Алексей Смирнов
          25 июля 2022, 23:14
          0
          Все бы хорошо, но из описания не понятно для чего это готовое решение.
          Ведь для товара, например, всегда выводятся доступные параметры…
            Stepan
            26 июля 2022, 13:07
            0
            так это TV а не параметры — просто я на своем проекте столкнулся с тем что у товара 20(+ овер) TV и не все и не всегда нужны
            а вывести их нужно
            т.е. в принципе то IF ELSE в шаблоне выручило бы, но это много букоф
            данный снипет поможет с выводом…
            HTML шаблон примерно решит 80% хотелок.
            Получится 1 TV: 2 строки/столбца — в зависимости от верстки.

            ЗЫ
            Описание)))
            чукча не писатель — чукча как верстальщик)))
            Роман
            26 июля 2022, 09:53
            0
            Что-то снипет с каждым днем, все больше и больше становится. =)
            $tvq->where(['AND:name:IN' => $inTv]);
            , AND не нужен, идет по умолчанию.
            Не нужные переменные: $where = [];
            Ну и дублировать код не хорошая практика. Про HTML уже писали.
            Ждем от вас красивого кода. =)
              Stepan
              26 июля 2022, 12:56
              0
              да по хорошему чтобы не дублироваться нужно добавить еще методов
              и вообще все в класс вывести иначе портянка будет еще больше
              у нас 4-е условия не линейно исполняемых и потому произошло копирование(((
              Подумаю, но честно особо не горело сделать убер пушку

              ЗЫ
              вообще суть поста — рассчитывал что разрабы минишоп заберут себе с переработкой, им проще будет
              а иначе тут будет километровая инструкция как и что настраивать(если по уму)
              ЗЫЗЫ
              может переделаю в дополнение
                Николай Савин
                26 июля 2022, 16:08
                -1
                Нет. В минишоп это не заберут. Можешь удалять
                  Stepan
                  26 июля 2022, 17:09
                  0
                  Спасибо дорогой!)))
                Stepan
                26 июля 2022, 12:59
                0
                $where = [];

                артефакт остался — убрал
                Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
                15