Вывод сгруппированных опций товара


Всем привет. Часто необходимо вывести опции товара разбив их по группам. msProductOptions к сожалению таким функционалом не обладает. Но теперь, благодаря замечательному человеку Евгению Дурягину, такая возможность у нас есть!



Сниппет msProductOptionsEx

<?php
/** @var modX $modx */
/** @var array $scriptProperties */

$tpl = $modx->getOption('tpl', $scriptProperties, 'tpl.msProductOptions');
if (!empty($input) && empty($product)) {
    $product = $input;
}

$emptyGroupName = $modx->getOption('emptyGroupName', $scriptProperties, 'Empty');
$groupSortBy = $modx->getOption('groupSortBy', $scriptProperties, 'rank');

$product = !empty($product) && $product != $modx->resource->id
    ? $modx->getObject('msProduct', $product)
    : $modx->resource;
if (!($product instanceof msProduct)) {
    return "[msProductOptions] The resource with id = {$product->id} is not instance of msProduct.";
}

$ignoreOptions = array_map('trim', explode(',', $modx->getOption('ignoreOptions', $scriptProperties, '')));
$onlyOptions = array_map('trim', explode(',', $modx->getOption('onlyOptions', $scriptProperties, '')));
$groups = !empty($groups)
    ? array_map('trim', explode(',', $groups))
    : array();
/** @var msProductData $data */
if ($data = $product->getOne('Data')) {
    $optionKeys = $data->getOptionKeys();
}
if (empty($optionKeys)) {
    return '';
}
$productData = $product->loadOptions();

$optionCategories = array();
$categoryIds = array();
foreach ($optionKeys as $key) {
    // Filter by key
    if (!empty($onlyOptions) && $onlyOptions[0] != '' && !in_array($key, $onlyOptions)) {
        continue;
    } elseif (in_array($key, $ignoreOptions)) {
        continue;
    }
    $option = array();
    foreach ($productData as $dataKey => $dataValue) {
        $dataKey = explode('.', $dataKey);
        if ($dataKey[0] == $key && (count($dataKey) > 1)) {
            $option[$dataKey[1]] = $dataValue;
        }
    }
    $option['value'] = $product->get($key);

    // Filter by groups
    $skip = !empty($groups) && !in_array($option['category'], $groups) && !in_array($option['category_name'], $groups);
    if ($skip || empty($option['value'])) {
        continue;
    }

    $categoryId = $option['category'];
    if (empty($categoryId)) {
        $categoryId = 0;
    }

    if (!isset($optionCategories[$categoryId])) {
        $optionCategories[$categoryId] = array(
            'name' => $categoryId ? $option['category_name'] : $emptyGroupName,
            'id' => $option['category'],
            'rank' => $categoryId ? $option['category'] : PHP_INT_MAX,
            'idx' => count($optionCategories),
            'options' => array()
        );
        $categoryIds[] = $categoryId;
    }
    $optionCategories[$categoryId]['options'][$key] = $option;
}

/** @var pdoFetch $pdoFetch */
$pdoFetch = $modx->getService('pdoFetch');
$categories = $pdoFetch->getCollection('modCategory', array('id:IN' => $categoryIds));

switch ($groupSortBy) {
    case 'rank':
        foreach ($categories as $category) {
            $categoryId = $category['id'];
            if (!isset($optionCategories[$categoryId])) {
                continue;
            }

            $optionCategories[$categoryId]['rank'] = intval($category['rank']);
        }

        uasort($optionCategories, function($a, $b) {
            if ($a['rank'] == $b['rank']) {
                return 0;
            }

            return ($a['rank'] < $b['rank']) ? -1 : 1;
        });
        break;
    case 'name':
        uasort($optionCategories, function($a, $b) {
            return strcmp($a['name'], $b['name']);
        });
        break;
    case 'idx':
        uasort($optionCategories, function($a, $b) {
            if ($a['idx'] == $b['idx']) {
                return 0;
            }

            return ($a['idx'] < $b['idx']) ? -1 : 1;
        });
        break;
}

return $pdoFetch->getChunk($tpl, array(
    'groups' => $optionCategories,
));

Вызов

[[msProductOptionsEx?
  &tpl=`tpl.msProductOptionsEx`
  &groupEmptyName=`Без группы`
  &groupSortBy=`rank`
]]

Шаблон tpl.msProductOptionsEx

{foreach $groups as $group}
    <div class="group">
        <h4>{$group.name}</h4>
        <div class="group-options">
            {foreach $group.options as $option}
                <div class="form-group">
                    <label class="col-md-2 control-label">{$option.caption}:</label>
                    <div class="col-md-10 form-control-static">
                        {if $option.value is array}
                            {$option.value | join : ', '}
                        {else}
                            {$option.value}
                        {/if}
                    </div>
                </div>
            {/foreach}
        </div>
    </div>
{/foreach}

В groupSortBy можно указать rank (сортировка по тому, что указывается в поле «Сортировка» при создании категории), name (алфавиту), idx (по тому порядку, как встречается).
15 октября 2016, 22:11    Александр Котлов   G+  
24    708 +15

Комментарии (2)

  1. Антон Левиц 18 октября 2016, 11:49 # 0
    Спасибо! пригодилось
    1. Максим 10 апреля 2017, 21:31 # 0
      Спасибо большое.
      Вы должны авторизоваться, чтобы оставлять комментарии.