Ломается mfilter2 :number при двух и четырёхзначных значениях TV

Всем привет

Исправно работал mfilter2 с фильтрацией по TV ten-long («Длина») в формате number. Вот вывод:
&filters=`
                .....,
                tv|ten-long:number,
                .....
&tplFilter.outer.ten-long=`tpl.mFilter2.filter.slider`
&tplFilter.row.ten-long=`tpl.mFilter2.filter.number`

Само TV стоило сделать иначе (авто-меткой, например), но уже сделано было давно и проставлено большому количеству товаров — переделывать сложно и пока не понятно нужно ли. Работало…


И как только в TV добавили значения до 100мм и свыше 999мм (двухзначные и четырёхзначные) и проставили их товарам, фильтрация по данному TV в категориях, где есть товары с новыми значениями, сломалась (фильтр Длина):



Ползунок не работает, input'ы значения не принимают, в консоли ошибка.
В другой категории, где нет товаров со значением меньше 100 или больше 999 всё работает исправно, ошибок никаких нет.
Если отключить товары с вышеуказанными значениями, фильтрация работает и ошибки пропадают… Не пойму в чем дело
steve.kon
27 марта 2023, 13:18
modx.pro
655
0

Комментарии: 4

Александр Туниеков
28 марта 2023, 22:27
+1
Странно, что вообще с мм работает. Как мфильтер вообще число получает???
попробуйте для теста в core\components\msearch2\model\msearch2\filters.class.php после 74 строки дописать
if($name == 'ten-long') $v=(int)$v;
https://disk.yandex.ru/i/eU3jzbcssEOc8w
    Александр Туниеков
    28 марта 2023, 22:40
    +1
    или лучше
    if($name == 'ten-long') $v=(int)str_replace('мм','',$v);
      steve.kon
      29 марта 2023, 09:10
      0
      Большущее спасибо! Всё заработало!
        Александр Туниеков
        29 марта 2023, 14:04
        +2
        Править исходники лучше только для теста. Если кто-то вздумает обновить mSearch2, то правка пропадет. Лучше расширить класс фильтрации
        Расширяем класс фильтрации
        Все стандартные фильтры mSearch2 находятся в файле /core/components/msearch2/model/msearch2/filters.class.php. Нам нужно унаследовать его, расширить и указать новый класс в системных настройках.

        Создаём новый файл в /core/components/msearch2/custom/filters/custom.class.php и пишем в него:

        <?php
        class myCustomFilter extends mse2FiltersHandler {}

        Указывем его в системной настройке mse2_filters_handler_class.

        С этого момента mSearch2 использует для работы ваш класс фильтрации, в котором вы можете писать новые методы, или переопределять стандартные.

        Для получения данных используются методы getИмяМетодаValues(), для подготовки фильтра — buildИмяМетодаFilter(), а для фильтрации filterИмяМетода. Можно посмотреть, как работают эти 3 типа методов в filters.class.php.
        И прописать исправленный метод getTvValues в классе myCustomFilter.
        <?php
        class myCustomFilter extends mse2FiltersHandler {
        /**
        	 * Retrieves values from Template Variables table
        	 *
        	 * @param array $tvs Names of tvs
        	 * @param array $ids Ids of needed resources
        	 *
        	 * @return array Array with tvs values as keys and resources ids as values
        	 */
        	public function getTvValues(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 (empty($row['id'])) {
        					continue;
        				}
        				elseif (is_null($row['value']) || trim($row['value']) == '') {
        					$row['value'] = $row['default_text'];
        				}
        				if ($row['type'] == 'tag' || $row['type'] == 'autotag') {
        					$row['value'] = str_replace(',', '||', $row['value']);
        				}
        				$tmp = strpos($row['value'], '||') !== false
        					? explode('||', $row['value'])
        					: array($row['value']);
        				foreach ($tmp as $v) {
        					$v = str_replace('"', '"', trim($v));
        					if ($v == '') {
        						continue;
        					}
        					$name = strtolower($row['name']);
        					if($name == 'ten-long') $v=(int)$v;
        					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;
        	}
        }
      Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
      4