Фильтрация по MIGX таблице средствами mFilter2
Делаю проект, где нужно хитро задавать цвет у товаров, решение Володи msOptionsColorв рамках проекта показалось громоздким и немного не подходящим по другим причинам, поэтому решено было оформить все в MIGX и написать свои методы фильтрации. Я такое делал впервые.
Получилось следующее:
Вызывать так:
Получилось следующее:
<?php
class migxFilter extends mse2FiltersHandler {
public function getMigxsValues(array $tvs, array $ids) {
$filters = array();
$q = $this->modx->newQuery('modResource', array('modResource.id:IN' => $ids));
$q->leftJoin('modTemplateVarTemplate', 'TemplateVarTemplate', 'TemplateVarTemplate.tmplvarid IN (SELECT id FROM ' . $this->modx->getTableName('modTemplateVar') . ' WHERE name IN ("' . implode('","', $tvs) . '") )
AND modResource.template = TemplateVarTemplate.templateid'
);
$q->leftJoin('modTemplateVar', 'TemplateVar', 'TemplateVarTemplate.tmplvarid = TemplateVar.id');
$q->leftJoin('modTemplateVarResource', 'TemplateVarResource', 'TemplateVarResource.tmplvarid = TemplateVar.id AND TemplateVarResource.contentid = modResource.id');
$q->select('TemplateVar.name, TemplateVarResource.contentid as id, TemplateVarResource.value, TemplateVar.type, TemplateVar.default_text');
$tstart = microtime(true);
if ($q->prepare() && $q->stmt->execute()) {
$this->modx->queryTime += microtime(true) - $tstart;
$this->modx->executedQueries++;
while ($row = $q->stmt->fetch(PDO::FETCH_ASSOC)) {
if ($row) {
$migxs = (array) json_decode($row['value']);
foreach ($migxs as $migx) {
$v = $migx->title;
$name = strtolower($row['name']);
if (isset($filters[$name][$v])) {
$filters[$name][$v][$row['id']] = $row['id'];
} else {
$filters[$name][$v] = array($row['id'] => $row['id']);
}
}
}
}
} else {
$this->modx->log(modX::LOG_LEVEL_ERROR, "[mSearch2] Error on get filter params.\nQuery: " . $q->toSQL() . "\nResponse: " . print_r($q->stmt->errorInfo(), 1));
}
return $filters;
}
public function buildMigxFilter(array $values, $name = '') {
$keys = array_keys($values);
if (empty($keys) || (count($keys) < 2 && empty($this->config['showEmptyFilters']))) {
return array();
}
$results = $names = array();
$q = $this->modx->newQuery('modTemplateVar', array('name' => $name));
$q->select('elements');
$tstart = microtime(true);
if ($q->prepare() && $q->stmt->execute()) {
$this->modx->queryTime += microtime(true) - $tstart;
$this->modx->executedQueries++;
$tmp = $q->stmt->fetchColumn();
$names = array();
}
foreach ($values as $value => $ids) {
if ($value !== '') {
$migxs = json_decode(str_replace('"', '"', $value));
foreach ($migxs as $migx) {
$title = trim($migx->title);
if (!is_array($results[$title]['resources'])) {
$results[$title]['resources'] = array();
}
$results[$title] = array(
'title' => $title,
'value' => $migx->value,
'type' => 'tv',
'resources' => array_merge($results[$title]['resources'], $ids)
);
}
}
}
return $this->sortFilters($results, 'tv', array('name' => $name));
}
public function filterMigx(array $requested, array $values, array $ids) {
$matched = array();
$tmp = array_flip($ids);
$filteredValues = [];
foreach ($values as $value => $ids) {
$migxs = json_decode(str_replace('"', '"', $value));
foreach ($migxs as $migx) {
$title = trim($migx->value);
if (!is_array($filteredValues[$title])) {
$filteredValues[$title] = array();
}
$filteredValues[$title] = array_merge($filteredValues[$title], $ids);
}
}
foreach ($requested as $value) {
$value = str_replace('"', '"', $value);
if (isset($filteredValues[$value])) {
$resources = $filteredValues[$value];
foreach ($resources as $id) {
if (isset($tmp[$id])) {
$matched[] = $id;
}
}
}
}
return $matched;
}
}Код, возможно, не самый торт, но вроде и не плохой. Единственное условие: у MIGX таблички должны быть объявлены два поля — title и value. Title выводится как заголовок фильтра, а value собственно отображается в адресной строке как параметр поиска. Вызывать так:
'filters' => 'ms|price:number,msoption|size,msoption|color,tv|color:migx',Комментарии по коду приветствуются. Комментарии: 13
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
Это редактор обработал теги. Изначально это выглядит так
Уже битый час вожусь — никак не получается. В migx-tv есть поле числовое. Подскажите пожалуйста, куда копнуть, чтобы вывести именно в виде number (чтобы было min и max значение).
Правильно ли я понимаю, что мне требуется только переписать buildMigxFilter и filterMigx?
Но если коротко — то для вывода цвета в HEX-формате. То есть был фильтр цвет, где текстом (поле title) было название цвета, а value был HEX-код цвета, который выводился в CSS для стилизации.
Типа того