Расширение фильтрации mFilter2 для тегов Tagger
mFilter2 — фильтрация найденных результатов.
Tagger — система управления тегами.
3,1,2 — группы тегов Tagger-а.
Улучшенная версия от Евгения Шеронова:
2. Прописать в системной настройке mse2_filters_handler_class: taggerCustomFilter
Исходная версия для истории и самоистязания:
Tagger — система управления тегами.
[[!mFilter2?
&filters=`
tagger|3:tgroup,
tagger|1:tgroup,
tagger|2:tgroup
`
&aliases=`
tagger|3==cars,
tagger|1==colors
`
]]
3,1,2 — группы тегов Tagger-а.
Улучшенная версия от Евгения Шеронова:
<?php
class taggerCustomFilter extends mse2FiltersHandler {
/**
* Retrieves values from Tagger table
*
* @param array $fields
* @param array $ids
*
* @return array
*/
public function getTaggerValues(array $fields, array $ids) {
$filters = array();
if(!$this->modx->addPackage('tagger',$this->modx->getOption('tagger.core_path',null,$this->modx->getOption('core_path').'components/tagger/').'model/')) {
return $filters;
}
$q = $this->modx->newQuery('TaggerTagResource');
$q->innerJoin('TaggerTag','TaggerTag','TaggerTag.id = TaggerTagResource.tag');
$q->where(array('TaggerTagResource.resource:IN' => $ids,'TaggerTag.group:IN'=>$fields));
$q->select(array('TaggerTagResource.resource,TaggerTag.tag,TaggerTag.group'));
$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)) {
foreach ($row as $k => $v) {
$v = str_replace('"', '"', trim($v));
if($k == 'tag') {
$k = $row['group'];
}
if ($k == 'resource' || $k == 'group') {
continue;
}
elseif (isset($filters[$k][$v])) {
$filters[$k][$v][$row['resource']] = $row['resource'];
}
else {
$filters[$k][$v] = array($row['resource'] => $row['resource']);
}
}
}
}
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;
}
/**
* Prepares values for filter
* Retrieves labels of tagger tags and replaces ids in array keys by it
*
* @param array $values
* @param string $name
*
* @return array Prepared values
*/
public function buildTgroupFilter(array $values,$name = '') {
if(!$this->modx->addPackage('tagger',$this->modx->getOption('tagger.core_path',null,$this->modx->getOption('core_path').'components/tagger/').'model/')) {
return array();
}
$tags = array_keys($values);
if (empty($tags) || (count($tags) < 2 && empty($this->config['showEmptyFilters']))) {
return array();
}
$results = array();
$q = $this->modx->newQuery('TaggerTag', array('tag:IN' => $tags));
$q->select('tag,label');
$tstart = microtime(true);
if ($q->prepare() && $q->stmt->execute()) {
$this->modx->queryTime += microtime(true) - $tstart;
$this->modx->executedQueries++;
$tags = array();
while ($row = $q->stmt->fetch(PDO::FETCH_ASSOC)) {
$tags[$row['tag']] = $row['label'];
}
foreach ($values as $tag => $ids) {
$title = !isset($tags[$tag])
? $this->modx->lexicon('mse2_filter_boolean_no')
: $tags[$tag];
$results[$title] = array(
'title' => $title,
'value' => $tag,
'type' => 'tagger',
'resources' => $ids
);
}
}
ksort($results);
return $results;
}
}
1. Положить файл в директорию core/components/msearch2/custom/filters/2. Прописать в системной настройке mse2_filters_handler_class: taggerCustomFilter
Исходная версия для истории и самоистязания:
<?php
class taggerCustomFilter extends mse2FiltersHandler {
public function getTaggerValues(array $tags, array $ids) {
$tagger = $this->modx->getService('tagger','Tagger',$this->modx->getOption('tagger.core_path',null,$this->modx->getOption('core_path').'components/tagger/').'model/tagger/');
if (!($tagger instanceof Tagger)) return '';
$filters = array();
$q = $this->modx->newQuery('TaggerTagResource');
$q->leftJoin('TaggerTag','TaggerTag','TaggerTagResource.tag = TaggerTag.id AND TaggerTag.group IN ("' . implode('","', $tags).'")');
$q->select('TaggerTag.tag,TaggerTag.group,TaggerTagResource.resource');
$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)) {
foreach ($row as $k => $v) {
$v = trim($v);
if($k == 'tag'){ $k = $row['group'];}
if ($v == '' || $k == 'id' || $k == 'resource' || $k == 'group') {continue;}
else if (isset($filters[$k][$v])) {
$filters[$k][$v][] = $row['resource'];
}
else {
$filters[$k][$v] = array($row['resource']);
}
}
}
}
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 buildTgroupFilter(array $values, $name = '') {
if (count($values) < 2 && empty($this->config['showEmptyFilters'])) {
return array();
}
$results = array();
foreach ($values as $value => $ids) {
$results[$value] = array(
'title' => $value
,'value' => $value
,'type' => 'default'
,'resources' => $ids
);
}
ksort($results);
return $results;
}
public function filterTgroup(array $requested, array $values, array $ids) {
$matched = array();
$tmp = array_flip($ids);
foreach ($requested as $value) {
if (isset($values[$value])) {
$resources = $values[$value];
foreach ($resources as $id) {
if (isset($tmp[$id])) {
$matched[] = $id;
}
}
}
}
return $matched;
}
}
Комментарии: 6
Разработчики Modx принципиально отказываются от тегов? Я понимаю, что это нарушает логику фреймворка. Заказчики одолели с вопросом тегов.
Как минимум из коробки есть тв. В остальном все зависит от задачи. Где-то вполне будет достаточно тех же тв, где-то нужно что-то поудобнее, а где-то теги вообще лишние.
Т.ч. принципиального отказа не вижу, вижу вопрос, решение которого ложится на плечи разработчика проекта.
Т.ч. принципиального отказа не вижу, вижу вопрос, решение которого ложится на плечи разработчика проекта.
Так себе решение. Что касается TV.
Автор, я тут немного подправил код, чтобы из Tagger для отображения вытаскивать Label, а для значения Tag — так более правильно.
gist.github.com/sheronov/a64692ced49a4f120ae87fd9795a0299
Сохранил название методов и класса, если хотите — можете у себя в заметке поправить.
Кстати, метод filterTgroup — немного лишний, так как если его нет, будет filterDefault отрабатывать.
gist.github.com/sheronov/a64692ced49a4f120ae87fd9795a0299
Сохранил название методов и класса, если хотите — можете у себя в заметке поправить.
Кстати, метод filterTgroup — немного лишний, так как если его нет, будет filterDefault отрабатывать.
Спасибо! Дополнил, обновил.
важный момент
в системную настройку
в системную настройку
extension_packages
нужно добавить пакетик «tagger»{"tagger":{"path":"[[++core_path]]components/tagger/model/"}}
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.