Дмитрий

Дмитрий

Был в сети 30 августа 2024, 20:01
Заказы не принимаю
Сергей, вопрос: а если требуется подтянуть файловые элементы для одного сниппета или плагина из одной папки, а для другого – из другой? У меня на многих сайтах такая необходимость. Особенно это касается собственных компонентов – чтобы не складировать все в одной папке, часть плагинов подключаются из папки с элементами, которая находится в каталоге компонента. Мне кажется, что отключение этого параметра, сильно снизит удобство. Или есть еще способ подключать сниппет или плагин через
$pdoTools->runSnippet('<НАЗВАНИЕ ФАЙЛА>')
из определенного каталога, отличного от того, что задан в системных настройках pdoTools?
Добрый день!

Нужно перезаписать ExtJS-компонент miniShop2.tree.Categories.
По шагам:

  • Создаем файлы:
    1. /core/components/extendedminishop2/elements/plugins/extended.minishop2.php
    2. /assets/components/extendedminishop2/js/mgr/category.tree.js

  • Создаем в админке плагин extendedMinishop2. Назначаем ему событие OnDocFormPrerender
  • Код плагина в админке:
    <?php
    if ($pdoTools = $modx->getService('pdoTools')) {
        $pdoTools->runSnippet('@FILE plugins/extended.minishop2.php', array_merge(
          array(
            'elementsPath' => MODX_CORE_PATH . 'components/extendedminishop2/elements/'
            ),
          $scriptProperties));
    }
  • Код в файле /core/components/extendedminishop2/elements/plugins/extended.minishop2.php
    <?php
    
    switch ($modx->event->name) {
      case 'OnDocFormPrerender':
        $modx->controller->addLastJavaScript(MODX_ASSETS_URL . 'components/extendedminishop2/js/mgr/category.tree.js');
        break;
    }
  • Код в файле /assets/components/extendedminishop2/js/mgr/category.tree.js
    Ext.override(miniShop2.tree.Categories, {
      prepareNodes: function(node) {
        var params = {};
        if (location.search) {
            var parts = location.search.substring(1).split('&');
    
            for (var i = 0; i < parts.length; i++) {
                var nv = parts[i].split('=');
                if (!nv[0]) continue;
                params[nv[0]] = nv[1] || true;
            }
        }
        var activeFile = params.file;
    
        Ext.each(node.childNodes,function (node) {
            if (node.attributes.selected || node.id == activeFile) {
                node.ui.addClass('x-tree-selected');
            }
    
            if (node.attributes.text) {
              node.ui.textNode.innerHTML = node.attributes.text;
            }
    
            this.addNodeButtons(node);
        }, this);
      }
    });
Была проблема с выводом опций в листинге товаров. Они через раз грузились. Набросал свой сниппет:

<?php
$options = $modx->resource->getTVvalue('categoryTplOpitions');
if (!$options && $source) {
  $parent = $modx->getObject('modResource',$source);
  $options = $parent->getTVValue('categoryTplOpitions');
}
if(!$product || !$options) {
  return;
}
$result = '<ul class="category-product-main-list w-list-unstyled">';
$options_arr = explode(',',$options);
if(($key = array_search('vendor',$options_arr)) !== false){
  unset($options_arr[$key]);
  if ($data = $modx->getObject('msProductData', $product)) {
    $productObj = $data->getOne('Product');
    $vendor = $productObj->getOne('Vendor');
    if ($vendor) {
      $result .= '<li class="category-product-main-li">Производитель: <span class="category-product-mail-li-span">'.$vendor->get('name').'</span></li>';
    }
  }
}
$options_str = '"'.implode('","',$options_arr).'"';
if (implode('","',$options_arr)) {
  $query = $modx->newQuery('msProductOption');
  $query->leftJoin('msOption','msOption',array("msOption.key = msProductOption.key"));
  $query->select(array(
    'msProductOption.key as option_key',
    'msProductOption.value as value',
    'msProductOption.product_id as product_id',
    'msOption.id as option_id',
    'msOption.caption as caption',
    'msOption.description as description',
    'msOption.measure_unit as measure_unit'
  ));
  $query->where(array(
    'product_id'=>$product,
    'msProductOption.key:IN' => $options_arr,
  ));
  $query->sortby('FIELD(option_key,'.$options_str.')');
  $items = $modx->getCollection('msProductOption',$query);
  $arr=[];
  
  foreach ($items as $item) {
    $caption = $item->get('description');
    if (!$caption) {
      $caption = $item->get('caption');
    }
    if (array_key_exists ($caption , $arr )) {
      $key = $arr[$caption];
      $key .= ', '.$item->get('value');
      $arr[$caption]=$key;
    } else {
      if ($item->get('measure_unit')) {
        $arr[$caption]=$item->get('value').' '.$item->get('measure_unit');
      } else {
      $arr[$caption]=$item->get('value');
      }
    }
  }
  foreach ($arr as $key=>$value) {
    $result .= '<li class="category-product-main-li">'.$key.': <span class="category-product-mail-li-span">'.$value.'</span></li>';
  }
}
$result .='</ul>';
return $result;
И в чанке товара соответственно:

{$_modx->runSnippet('!productOptions',[
    'product' => $id
    'source' => $_modx->resource.categorySource
  ])}
$_modx->resource.categorySource
– это id категории, откуда опции подтягиваем. В этом проекте так надо было.

Знаю, что html в сниппеты – не кошерно. Тогда не знал)

Можете под себя поднастроить.