Артем

Артем

Был в сети 23 марта 2022, 14:24
Заказы не принимаю
должно быть вот так

{$_modx->lexicon->load('minishop2:product')}

{foreach $options as $name => $values}
    <div class="sm-text"><b>{('ms2_product_' ~ $name) | lexicon}</b></div>
    <div
        {if $constraints[$name]}
            data-constraints="{$constraints[$name]| json_encode: 256 | htmlentities}"
        {/if}
        >
        {foreach $values as $value index=$index}
         
        <label class="input-parent">
        <input type="radio" value="{$values[$index]}" name="options[{$name}]" 
            {if $index == 0}checked="checked"{/if}
            
            {if $constraints[$name]}
                data-relations="{$relations[$name][$value]| json_encode: 256 | htmlentities}"
            {/if}
                    
            />
            {$values[$index]}
        </label>
    
        {/foreach}
    </div>
{/foreach}
Лексиконы подгружает сам минишоп, если вызываются его сниппеты. В вашем случае, видимо, они не вызываются, поэтому и лексиконы не работают. Соответственно, вам нужно подгрузить их самостоятельно, как посоветовали в том топике.

{$_modx->lexicon->load('minishop2:product')}
вот это нужно вставить в тот же чанк, где у вас не работают лексиконы, в самое начало
потому что эта строка
$parent = $resource->get('parent');
возвращает id родителя, а не объект, поэтому в следующей строке вообще должен быть fatal error
$parentTpl = $parent->get('template');

сначала нужно получить объект родителя на основе его id
$parentObj = $modx->getObject(modResource::class, ['id' => $parent]);
а затем уже работать с этим объектом
В плагине локализатора на OnDocFormPrerender напрямую дергается шаблон из ресурса в строке
localizator.config.resource_template = "' . $resource->get('template') . '";
из этого следует, что если открыть несуществующий ресурс в админке, то получим 500 ошибку

было бы неплохо добавить проверку в следующем обновлении
if ($mode == 'upd' && $resource instanceof modResource) {
выводишь справа нужные категории, у каждой из них должен быть прописан id, при отправке формы поиска ловишь выбранный id и добавляешь его в where при формировании поиска
естественно, нужно обязательно фильтровать id, которые будешь отдавать в where
Согласен, бывает и такое, но лично я считаю, что это проблема исключительно клиента и его нежелания обновляться на современное ПО.
Почему разработчик должен тратить свое время и решать эти проблемы? Если клиент хочет поддержку IE, то пусть изволит оплатить это отдельно. А как только клиент поймет, что гораздо проще обновить ПО, чем каждый раз оплачивать доработку под IE, то вдруг у него внезапно появятся и Windows 7/10, и последний хром.
О кроссбраузерности в 2020 году стоит думать только в том случае, если по какой-то странной причине есть надобность поддерживать бородатый IE, в чем я очень сильно сомневаюсь. В остальном никакой головной боли уже нет, а писать на современном JS одно удовольствие, чего не скажешь о jQuery лапше с всевозможным подавлением ошибок и зоопарком долларов.
pagetitle и price не самый удачный пример, способом с IN их не очень удобно доставать)
я бы тут из-за удобства выбрал join, хоть он действительно будет немного медленнее

Вариант с IN:
$data = [];
$c = $modx->newQuery('msProduct', ['class_key' => 'msProduct', 'published' => 1]);
$c->select(['id', 'pagetitle']);
if ($c->prepare() && $c->stmt->execute()) {
    $data = $c->stmt->fetchAll(PDO::FETCH_KEY_PAIR);
}


$c = $modx->newQuery('msProductData', ['id:IN' => array_keys($data)]);
$c->select(['id', 'price']);
if ($c->prepare() && $c->stmt->execute()) {
    while ($item = $c->stmt->fetch(PDO::FETCH_ASSOC)) {
        $data[$item['id']] = ['pagetitle' => $data[$item['id']], 'price' => $item['price']];
    }
}
print_r($data);
return; 
Total time: 0.4112 s
Memory: 22 MB
Можно было еще сделать через ASSOC и array_column, но это медленнее, как мне показалось

Вариант с join:
$c = $modx->newQuery('msProduct', ['msProduct.class_key' => 'msProduct', 'msProduct.published' => 1]);
$c->select(['msProduct.pagetitle', 'Data.price']);
$c->innerJoin('msProductData', 'Data', 'msProduct.id = Data.id');
if ($c->prepare() && $c->stmt->execute()) {
    print_r($c->stmt->fetchAll(PDO::FETCH_ASSOC));
}
return;
Total time: 0.4927 s
Memory: 18 MB
Да я прям копипастнул, только getCollection на getCount заменил

Вариант с IN:
$ids = [];
$q = $modx->newQuery('modResource');
$q->select('id');
$q->where(array(
    'published' => 1,
    'class_key' => 'msProduct',
));
if ($q->prepare() && $q->stmt->execute()){
    while ($row = $q->stmt->fetch(PDO::FETCH_ASSOC)) {
        $ids[] = $row['id'];
    }
}


/* @var msProductData $object*/
$q = $modx->newQuery('msProductData');
$q->where(array(
    'id:IN' => $ids
));
if($objectCount = $modx->getCount('msProductData', $q)) {
    return $objectCount;
}
Total time: 0.4705 s
Вариант с join:
/* @var msProduct $object*/
$q = $modx->newQuery('msProductData');
$q->where(array(
    'Product.published' => 1,
    'Product.class_key' => 'msProduct',
));
$q->innerJoin('msProduct','Product','Product.id = msProductData.id');
if($objectCount = $modx->getCount('msProductData', $q)) {
    return $objectCount;
}
Total time: 0.4096 s
Сейчас разница уже не такая большая, но она все еще в пользу join'а.