Фильтр опций в товаре с переходом по ссылке
Вывод всех параметров опций в товаре и переход на соседний товар в разделе при выборе опции.
Сниппет для получения данных опций из раздела, на основе Настроек опций в самом разделе.
<?php if (empty($parent)){$parent = $modx->resource->get('parent');} if (empty($id)){$id = $modx->resource->get('id');} /* получаем настройки и названия опций от родителя-каталога */ $sql = $modx->query("SELECT catopt.* , mo.* FROM {$modx->getTableName('msCategoryOption')} as catopt inner JOIN {$modx->getTableName('msOption')} as mo on mo.id = catopt.option_id WHERE catopt.category_id = ". $parent." ORDER BY catopt.rank"); $options = $sql->fetchAll(PDO::FETCH_ASSOC); $ids_opt = []; foreach ($options as $option) { $ids_opt[] = $option['id']; } /* получаем все значения id товаров в этом каталоге */ $sql = $modx->query("SELECT res.id, res.uri FROM {$modx->getTableName('modResource')} as res WHERE res.deleted = 0 AND res.published = 1 AND res.parent = ".$parent); $resourses = $sql->fetchAll(PDO::FETCH_ASSOC); $ids_res = []; foreach ($resourses as $idr) { $ids_res[] = $idr['id']; } if ($id > 0){ /* получение всех опций у текущего товара */ $sql = $modx->query("SELECT opt.key, opt.value FROM {$modx->getTableName('msProductOption')} as opt WHERE opt.product_id IN (".$id.") AND opt.value is not NULL AND opt.value not like 'undefined' GROUP BY opt.value ORDER BY opt.key ASC, floor(opt.value) ASC"); $res = $sql->fetchAll(PDO::FETCH_ASSOC); $res_opt = []; foreach ($res as $v){ $res_opt[$v['key']] = $v['value']; } } /* получение списка опций всех товаров в каталоге */ $sql = $modx->query("SELECT opt.key, opt.value FROM {$modx->getTableName('msProductOption')} as opt WHERE opt.product_id IN (".implode($ids_res, ',').") AND opt.value is not NULL GROUP BY opt.value ORDER BY opt.key ASC, floor(opt.value) ASC"); $opt_values = $sql->fetchAll(PDO::FETCH_ASSOC); $opt_value = []; foreach ($opt_values as $opt_v) { if($opt_v['value'] == $res_opt[$opt_v['key']]){ $opt_value[$opt_v['key']][] = ['value' => $opt_v['value'], 'checked' => 'checked']; }else{ $opt_value[$opt_v['key']][] = ['value' => $opt_v['value']]; } } /* получаем зависимость параметров */ if (count($res_opt) > 1){ $subject_res = []; $select = ''; $sql=''; foreach ($res_opt as $res_key => $res_val){ $select = " SELECT {$res_key}.`key`, {$res_key}.`value`"; $from = " FROM {$modx->getTableName('msProductOption')} as {$res_key}"; $join = ''; $and = ''; foreach ($options as $key_opt){ if ($key_opt['key'] !== $res_key){ $join .= " inner join {$modx->getTableName('msProductOption')} as {$key_opt['key']} on {$key_opt['key']}.product_id = {$res_key}.product_id AND {$key_opt['key']}.`key` like '{$key_opt['key']}'"; $and .= " AND {$key_opt['key']}.`value` like '{$res_opt[$key_opt['key']]}' "; } } $where = " WHERE {$res_key}.product_id IN (".implode($ids_res, ',').")"; $sql .= $select . $from . $join . $where. $and .' UNION'; } $sql = rtrim($sql, 'UNION'); $modx->log(1,print_r($sql,1)); $sql = $modx->query($sql); $subject = $sql->fetchAll(PDO::FETCH_ASSOC); //$modx->log(1,print_r($subject,1)); foreach ($subject as $v){ $subject_res[$v['key']][] = $v['value']; $subject_res[$v['key']] = array_unique($subject_res[$v['key']]); } foreach ($opt_value as $opt_k => $opt_p) { foreach($opt_p as $i => $opt_v){ $opt_value[$opt_k][$i]['disabled'] = 'disabled'; foreach($subject_res[$opt_k] as $sub_val){ if ($sub_val == $opt_v['value']){ $opt_value[$opt_k][$i]['disabled'] = ''; } } } } } /* добавляем значения опций в опции */ foreach ($options as $key => $option){ $options[$key]['values'] = $opt_value[$option['key']]; } /** @var pdoTools $pdoTools */ $pdoTools = $modx->getService('pdoTools'); /* выводим массив в чанк */ $output = ''; if ($tpl == ''){ echo '<pre>'; print_r($options); echo '</pre>'; }else{ $output .= $pdoTools->getChunk($tpl, ['options'=>$options, 'res_option'=>$res_opt, 'subject'=>$subject_res ]); } return $output;
Чанк вывода опций с указанием опций самого товара и доступных вариаций, и обработки результатов выбора.
{*$options|print} {$res_option|print*} {*$subject|print*} {if $options|len > 0} {foreach $options as $opt} <fieldset id="{$opt.key}" class="product-filtrs"> <h4 class="pb-1">{$opt.caption}</h4> <div class="row-flex pb-2"> {foreach $opt.values as $k => $param} {if $param['value']?} <input type="radio" value="{$param['value']}" name="{$opt.key}" id="{$opt.key~$k}" {$param['checked']} {$param['disabled']} class="radio-option"> <label for="{$opt.key~$k}" class="radio-label">{$param['value']}</label> {/if} {/foreach} </div> </fieldset> {/foreach} <script> $(document).on('change', '.radio-option', function() { let query = { }; let tvfields = { }; query['parent'] = {$_modx->resource.parent}; $('.radio-option:checked').each(function(index, val){ tvfields[$(val).attr('name')] = $(val).val(); }); query['tvfields'] = tvfields; $.ajax({ type: "POST", url:'/assets/components/ajax/resource.php', data:{ action:'gethref', query: JSON.stringify(query)} }).done(function(response){ if (response) { document.location.href = response; }; }); }); </script> {/if}
Получение ссылки на товар на основе переданных параметров через ajax
<?php define('MODX_API_MODE', true); // Если запрос не AJAX или не передано действие, выходим if (empty($_SERVER['HTTP_X_REQUESTED_WITH']) || $_SERVER['HTTP_X_REQUESTED_WITH'] != 'XMLHttpRequest' || empty($_REQUEST['action'])) {exit('error');} require_once dirname(dirname(dirname(dirname(__FILE__)))) . '/index.php'; $modx->getService('error', 'error.modError'); $modx->setLogLevel(modX::LOG_LEVEL_ERROR); $modx->setLogTarget('FILE'); $modx->error->message = null; $action = $_REQUEST['action']; $data = false; switch ($action) { case 'gethref': $query = json_decode($_REQUEST['query']); $TVfields = $query->tvfields; $parent = $query->parent; $select = "SELECT content.`id`, content.uri FROM {$modx->getTableName('modResource')} as content"; foreach ($TVfields as $key=>$value){ $select .= " inner join {$modx->getTableName('msProductOption')} as $key on $key.product_id = content.id AND $key.`key` = '$key' AND $key.`value` like '%".$value."%'"; } $select .= " WHERE content.parent = " . $parent; $sql = $modx->query($select); if ($rezult = $sql->fetchAll(PDO::FETCH_ASSOC)){ //$modx->log(1, print_r($TVfields,1)); $data = $rezult['0']['uri']; } } @session_write_close(); exit($data);
Комментарии ()