Перейти до вмісту
Пошук в
  • Детальніше...
Шукати результати, які ...
Шукати результати в ...

Получение опции на странице категорий


Recommended Posts

Обратились с такой задачей:
У товара изначально цена 0 и она формируется от выбора опций. Нужно вывести в товаре минимальную сумму опции на странице категорий

 

Порывшись ради интереса в сети набрел на вот такую дич,

рекомендуют вставить в цикл

                $options= array();

                foreach ($this->model_catalog_product->getProductOptions($result['product_id']) as $option) {
                    $product_option_value_data = array();

                    foreach ($option['product_option_value'] as $option_value) {
                        if (!$option_value['subtract'] || ($option_value['quantity'] > 0)) {
                            if ((($this->config->get('config_customer_price') && $this->customer->isLogged()) || !$this->config->get('config_customer_price')) && (float)$option_value['price']) {
                                $oprice = $this->currency->format($this->tax->calculate($option_value['price'], $result['tax_class_id'], $this->config->get('config_tax') ? 'P' : false));
                            } else {
                                $oprice = false;
                            }

                            $product_option_value_data[] = array(
                                'product_option_value_id' => $option_value['product_option_value_id'],
                                'option_value_id'         => $option_value['option_value_id'],
                                'name'                    => $option_value['name'],
                                'image'                   => $this->model_tool_image->resize($option_value['image'], 50, 50),
                                'price'                   => $oprice,
                                'price_prefix'            => $option_value['price_prefix']
                            );
                        }
                    }

                    $options[] = array(
                        'product_option_id'    => $option['product_option_id'],
                        'product_option_value' => $product_option_value_data,
                        'option_id'            => $option['option_id'],
                        'name'                 => $option['name'],
                        'type'                 => $option['type'],
                        'value'                => $option['value'],
                        'required'             => $option['required']
                    );
                }

 

причем много где так советуют.
Я считаю что запросы SELECT в цикле это зло, но вот опенкарт прямо пестрит ими. Допустим для вывода товаров на стр категорий в запросе и так есть цикл с запросом внутри, а тут еще добавляют вот такую шляпу.

 

В общем вот решение:

 

1. Идем в модель model/catalog/product. php, находим метод getProducts. Нужно добавить в запрос данные
в первых строках видим вот такое

SELECT p.product_id, (SELECT AVG

 

можно после p.product_id добавить, допустим вот так чтоб было

SELECT p.product_id, MIN(pov.price) AS sums, pov.product_id AS pid, (SELECT AVG

 

вот это pov.product_id AS pid по сути не обязательно, но может кому надо будет

 

2. Далее идем чуть ниже и находим вот такую строку

 

$sql .= " LEFT JOIN " . DB_PREFIX . "manufacturer m ON (p.manufacturer_id = m.manufacturer_id)";

 

и перед ней или после нее, я ставил перед ней, поставить вот такой доп запрос

 

$sql .= " LEFT JOIN ".DB_PREFIX."product_option_value pov ON (pov.product_id = p.product_id)";

 

3. Далее опять спускаемся еще ниже до самого цикла

 

foreach ($query->rows as $result) {

 

и в цикле вставляем

 

$product_data[$result['product_id']]['min_opt'] = $result['sums'];

 

4. Идем в контроллер категории controller/product/category.php . Примерно 189 строка, нам нужен цикл который формирует данные на вывод

 

$results = $this->model_catalog_product->getProducts($filter_data);

foreach ($results as $result) {

 

и в формирование массива $data['products'] добавить получение наших данных по опции, допустим после

 

'href' => $this->url->link('product/product', 'path=' . $this->request->get['path'] . '&product_id=' . $result['product_id'] . $url),

 

добавить

 

'min_sum' => number_format($result['min_opt'], 2)

 

Всё, теперь min_sum будет доступна в шаблоне в цикле формирования данных


В дальнейшем хочу составить нормальный вариант запроса на получение опций для продукта на страницу категорий и не лепить ту дичь которую советуют как выше пример привел. Еще попытаюсь переделать запрос в методе getProducts без запроса в цикле посмотрим что выйдет.
 

  • +1 1
Надіслати
Поділитися на інших сайтах

И теперь у вас любой getProducts джойнит опции и долбит их поиском минимального value :-(
Ну, если у вас 200 товаров, то сойдёт.
А так я бы рекомендовал не ломать не поломанное, сделать свой собственный getMyMegaProducts. Или вообще отдельный запрос типа getProductsMinOptionValues там, где оно вам надо. С отдельный запросом будет, скорее всего, суммарно быстрее, чем при создании в памяти огромных джойнутых на всю голову таблиц. 

Надіслати
Поділитися на інших сайтах


2 часа назад, Shureg сказал:

И теперь у вас любой getProducts джойнит опции и долбит их поиском минимального value :-(
Ну, если у вас 200 товаров, то сойдёт.

на странице поиска тоже может пригодится, Логично?? я думаю логично

 

Далее, вас почему то не смущает в родном запросе

$sql .= " LEFT JOIN " . DB_PREFIX . "manufacturer m ON (p.manufacturer_id = m.manufacturer_id)";
		

он точно так же не везде используется, но он есть. Так с чего это мое решение поломает не поломанное, а вот с этим всё как надо???

Тогда уж по вашему мнению нужно и с этим джоином что то делать не так ли???

 

Далее, сделать другой запрос и куда его??? в цикл??? Ну так если в цикл, то это решение что намного лучше чем джоины????

Я считаю нет!!!! 

 

Критика критикой, но вроде как находимся в ветке помощи программистам, так выдвинете свой вариант на эту тему, как бы вы решили данную задачу.

Кстати про отдельный запрос, вроде как тестил с отдельным запросом, надо посмотреть остался код или нет или снова протестить и написать

Надіслати
Поділитися на інших сайтах

14 минут назад, Venter сказал:

на странице поиска тоже может пригодится, Логично?? я думаю логично

Плохо думаете. Не логично. Не трогайте без крайней необходимости то, что трогать не требуется. Оставьте стандартные запросы стандартными, если вам нужны свои, создавайте свои модифицированные. Ваши данные все равно могут быть использованы только в модифицированных вами контроллерах, стандартные никакого sums не знают, и нет смысла его для них вычислять. Вот и создавайте-запрашивайте свой метод, не коверкайте существующий

Змінено користувачем Shureg
Надіслати
Поділитися на інших сайтах


15 минут назад, Venter сказал:

Далее, вас почему то не смущает в родном запросе

Не смущает. Я уже писал, что дефолтный запрос далек от совершенства. Но это не повод его еще более уродовать, джойнить ненужные таблицы там, где они не нужны. Да еще с вычислением  min

Надіслати
Поділитися на інших сайтах


Отдельный метод получения мин суммы опции в контроллере категории

 

Сам метод

	public function getMinOption( $category_id ) {
		
		$sql = "SELECT p.product_id, MIN(pov.price) AS min_summ
		        FROM ".DB_PREFIX."product_to_category ptc 
		        LEFT JOIN " . DB_PREFIX . "product p ON (ptc.product_id = p.product_id)
				LEFT JOIN ".DB_PREFIX."product_option_value pov ON (pov.product_id = ptc.product_id)
			    WHERE ptc.category_id = '20' AND p.status = '1' AND p.date_available <= NOW() 
				GROUP BY p.product_id ORDER BY p.sort_order ASC";
				
		$query = $this->db->query($sql);
		
		$opt_data = array();
		
		foreach ($query->rows as $result) {
			$opt_data[$result['product_id']] = $result['min_summ'];
		}
		
		return $opt_data;
	}

 

В контроллере перед циклом

$data_res = $this->model_catalog_product->getMinOption($category_id);

 

3 часа назад, Venter сказал:

и в формирование массива $data['products'] добавить получение наших данных по опции, допустим после

 


'href' => $this->url->link('product/product', 'path=' . $this->request->get['path'] . '&product_id=' . $result['product_id'] . $url),

 

после можно поставить так

 

'min_sum' => number_format( $data_res[$result['product_id']], 2 )

 

Вот вам отдельный запрос

Надіслати
Поділитися на інших сайтах

4 минуты назад, Shureg сказал:

Не смущает. Я уже писал, что дефолтный запрос далек от совершенства. Но это не повод его еще более уродовать, джойнить ненужные таблицы там, где они не нужны. Да еще с вычислением  min

 

тогда этот родной запрос не использовать допустим в контроллере категорий а написать нормальный отдельный запрос. Жаль времени мало, в свободное время потестирую с этим

Надіслати
Поділитися на інших сайтах

Створіть аккаунт або увійдіть для коментування

Ви повинні бути користувачем, щоб залишити коментар

Створити обліковий запис

Зареєструйтеся для отримання облікового запису. Це просто!

Зареєструвати аккаунт

Вхід

Уже зареєстровані? Увійдіть тут.

Вхід зараз
  • Зараз на сторінці   0 користувачів

    • Ні користувачів, які переглядиють цю сторінку
×
×
  • Створити...

Important Information

На нашому сайті використовуються файли cookie і відбувається обробка деяких персональних даних користувачів, щоб поліпшити користувальницький інтерфейс. Щоб дізнатися для чого і які персональні дані ми обробляємо перейдіть за посиланням . Якщо Ви натиснете «Я даю згоду», це означає, що Ви розумієте і приймаєте всі умови, зазначені в цьому Повідомленні про конфіденційність.