[РЕШЕНО] Несколько цен в TV'шках + mFilter2

Есть у меня основная цена и модификатор в виде процента в TV.
Везде всё замечательно работает, кроме mFilter2. Он берет цену напрямую из БД.

Сейчас использую следующий код. Понимаю что «что-то не так». Неправильно.

<?php
switch ($modx->event->name) {
	case 'msOnGetProductPrice':
        $resource = $product->id;

        // Получаю данные с нужной ценой
        $tv_retail = $modx->getObject('modTemplateVarResource', array('contentid'=>$resource, 'tmplvarid' => 5));
        // Получаю данные с уже выставленной ценой для mSearch
        $tv_temp = $modx->getObject('modTemplateVarResource', array('contentid'=>$resource, 'tmplvarid' => 28));
        
        // Если нужная цена не пустая, то записываем в переменную
        if (isset($tv_retail)){
            $need_price = $tv_retail->get('value');
        }
        
    	$values = & $modx->event->returnedValues;
    	$real_price = $product->price;
    	
	    if($need_price && $real_price != '0'){
	        // Ставим нужную нам цену
	        $values['price'] = $real_price + ($real_price * ($need_price / 100));
        
            $page = $modx->getObject('modResource', $resource);
            if($page->get('value') != $values['price']){
                // Ставим цену для mSearch в TV
                $page->setTVValue('price_temp', $values['price']);
                
                $modx->resource->save();
            }
        }
        
        //$modx->log(xPDO::LOG_LEVEL_ERROR, $modx->resource->get('id'));
	break;
}

Если подсовывание цены для minishop'а и прочих корзин проходит отлично, то для фильтра пришлось завести отдельную TV. Плюс еще цена не сразу обновляется, а только после перезагрузки страницы.

Вот думаю, как правильно это всё сделать. Если оставить всё как есть, то придется еще делать 4 модификатора (у продавца их всего 5).

Подскажите пожалуйста: как всё таки лучше реализовать подобное?

UPD 2: скопировал функцию обработки TV из исходников mFilter2. Нашел место где изменяется цена, смог получить ID. Сейчас не могу получить value нужной TV.

UPD 3: Сделал! Теперь я беру цену и умножаю на модификатор в виде нужной TV.
Полностью отказался от идеи с временной TV. Это было глупо :>

<?php

class myCustomFilter extends mse2FiltersHandler {
	public function getMsValues(array $fields, array $ids) {
		$filters = array();
		$q = $this->modx->newQuery('msProductData');
		$q->where(array('id:IN' => $ids));
		$q->select('id,' . implode(',', $fields));
		$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)) {
			    // Получаем ID
				$product_id = $row['id'];
				// Получаем TV
                $tv = $this->modx->getObject('modTemplateVarResource', array('contentid' => $product_id , 'tmplvarid' => 5));
                // Получаем данные из TV
                $tv_value = $tv->get('value');
                // Делаем нужную цену + округляем, убирая дробь
				$row['price'] = round($row['price'] + ($row['price'] * ($tv_value / 100)), 0, PHP_ROUND_HALF_UP);
				foreach ($row as $k => $v) {
					$v = str_replace('"', '"', trim($v));
					if ($k == 'id') {
						continue;
					}
					elseif (isset($filters[$k][$v])) {
						$filters[$k][$v][$row['id']] = $row['id'];
					}
					else {
						$filters[$k][$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;
	}
}
Raimei
02 июля 2018, 15:59
modx.pro
2
1 542
0

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

Евгений Шеронов
03 июля 2018, 06:46
+1
1. Расширить методы фильтрации: docs.modx.pro/components/msearch2/extension/components/msearch2/the-extension/filtering-methods

2. В вызове mFilter2 цену прописать как нибудь-так (типо свою таблицу msmy используем):
msmy|price:number

3. Не забыть создать метод getMsmyValues, который будет почти повторять getMsValues и также собирать цену, но ещё подсоединять значения из ТВшки и перемножать цену на эту тв.
Вернуть такой метод должен массив новых обработанных цен вместе с ресурсами.
$filters = array(
	'price'=>array(	
		'1000'=>array(12,19,125,754,543),
		// и т.д.
	)
);
P.S. и естественно от записи новой цены в плагине на msOnGetProductPrice нужно отказаться.
    Raimei
    03 июля 2018, 13:25
    0
    Спасибо, я вчера пришел к этому. Нужно делать свой метод фильтрации.
    Как думаете, сколько стоит такая работа? Сам не осилю (хотя попробую), придется скорее всего в работу закидывать.
      Raimei
      03 июля 2018, 15:02
      0
      Смог сделать. Спасибо за наводки!
      Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
      3