Бренд в превью товара

Правила раздела: faq.php?mode=okay
Модератор: Модераторы

makki M
makki M
Репутация: 199
Сообщения: 697
Зарегистрирован: 12.08.2016
С нами: 7 лет 7 месяцев
Откуда: Киев
Сайт

Сообщение #1 makki » 26.01.2018, 10:51

Для того, чтобы в превью товара показать бредн (со ссылкой на страницу бренда), нужно сделать следующее:

1) Файл api/Products.php
1.1) в конце тела функции get_products в sql запросе после строки 180

Код: Выделить всё

p.brand_id,

добавьте

Код: Выделить всё

b.name as brand,
b.url as brand_url,

1.2) И ниже после строки

Код: Выделить всё

$feed_filter

добавьте

Код: Выделить всё

LEFT JOIN __brands b ON p.brand_id = b.id


2) Файл design/ваш_шаблон/html/product_list.tpl
Выводим бренд в нужном месте
Например после строки

Код: Выделить всё

<a class="product_name" data-product="{$product->id}" href="{$lang_link}products/{$product->url}">{$product->name|escape}</a>

добавим

Код: Выделить всё

{if $product->brand}
   <a href="brands/{$product->brand_url}" class="product_brand_link">{$product->brand|escape}</a>
{/if}
Cоздание и расширение функционала интернет-магазина на платформе OkayCMS 2 (с 3-й и 4-й версией не работаю)

korshunov
korshunov
Репутация: 146
Сообщения: 1854
Зарегистрирован: 03.12.2015
С нами: 8 лет 3 месяца
Skype

Сообщение #2 korshunov » 26.01.2018, 13:31

Работать оно будет, но уж больно метод топорный, грубый и нарушающий стандартную идеологию CMS...

makki M
makki M
Репутация: 199
Сообщения: 697
Зарегистрирован: 12.08.2016
С нами: 7 лет 7 месяцев
Откуда: Киев
Сайт

Сообщение #3 makki » 26.01.2018, 15:10

Обоснуйте свои слова. Привык к вашим замечаниям, но в этот раз вас вообще не понимаю.
Последний раз редактировалось makki 26.01.2018, 20:49, всего редактировалось 1 раз.
Cоздание и расширение функционала интернет-магазина на платформе OkayCMS 2 (с 3-й и 4-й версией не работаю)

korshunov
korshunov
Репутация: 146
Сообщения: 1854
Зарегистрирован: 03.12.2015
С нами: 8 лет 3 месяца
Skype

Сообщение #4 korshunov » 26.01.2018, 16:23

Ваша цель - вывести бренд для страниц списков товара (ProductsView).
Для этого надо это бренды получать из базы. Вы это делаете усложнением запроса - вполне естественно.
Но запрос при этом усложняете для ВСЕХ вызовов get_products(). А надо бы только для тех вызовов, которые реально этого требуют.

Функция get_products() - универсальный инструмент, обрабатывающий разные вызовы в зависимости от заданных параметров, и в ней не должно быть ничего лишнего. Запрос, который она делает, стандартно полностью управляется параметрами вызова. А Вы просто прописываете навсегда добавочные элементы, которые нужны в довольно малом числе случаев. Это примерно как носить шубу не только зимой, а круглый год.

makki M
makki M
Репутация: 199
Сообщения: 697
Зарегистрирован: 12.08.2016
С нами: 7 лет 7 месяцев
Откуда: Киев
Сайт

Сообщение #5 makki » 26.01.2018, 22:17

korshunov писал(а):Функция get_products() - универсальный инструмент, обрабатывающий разные вызовы в зависимости от заданных параметров, и в ней не должно быть ничего лишнего. Запрос, который она делает, стандартно полностью управляется параметрами вызова. А Вы просто прописываете навсегда добавочные элементы, которые нужны в довольно малом числе случаев. Это примерно как носить шубу не только зимой, а круглый год.
Вот решение, которое не затрагивает API функции, а использует уже имеющиеся.

1) Файл view/ProductsView.php
в цикле foreach($products as $product) { ...}
после кода (строки 512-514)

Код: Выделить всё

                if(isset($product->images[0])) {
                    $product->image = $product->images[0];
                }

добавим

Код: Выделить всё

                if($product->brand_id != 0) {
                    $brand = $this->brands->get_brand(intval($product->brand_id));
                    $product->brand = $brand->name;
                    $product->brand_url = $brand->url;
                }

2) Файл design/ваш_шаблон/html/product_list.tpl
Выводим бренд в нужном месте
Например после строки

Код: Выделить всё

<a class="product_name" data-product="{$product->id}" href="{$lang_link}products/{$product->url}">{$product->name|escape}</a>

добавим

Код: Выделить всё

{if $product->brand}
   <a href="brands/{$product->brand_url}" class="product_brand_link">{$product->brand|escape}</a>
{/if}


P.S. Не так уж мало мест, где теперь еще надо обращаться к тому же get_brand, чтобы вывести бренд в превью товаров в хитах, новинках и акционных товарах, в сравнении товаров, избранных и рекомендуемых товарах. Так что склоняюсь к тому, что мое изначальное решение было ничем не хуже а то и лучше.
Cоздание и расширение функционала интернет-магазина на платформе OkayCMS 2 (с 3-й и 4-й версией не работаю)

korshunov
korshunov
Репутация: 146
Сообщения: 1854
Зарегистрирован: 03.12.2015
С нами: 8 лет 3 месяца
Skype

Сообщение #6 korshunov » 27.01.2018, 06:49

Ваше второе решение по нерациональности еще хуже первого.
Придуманная Вами вставка
$brand = $this->brands->get_brand(intval($product->brand_id));
выполняется в цикле по товарам, порождая в каждом шаге цикла однотипные и часто дублирующиеся запросы к базе.
Если на странице категории показывается, например, 40 товаров, то в процессе формирования страницы добавляется 40 запросов к базе. А кнопка Показать все может уже и тормоза создать...
Тихий ужас...

makki M
makki M
Репутация: 199
Сообщения: 697
Зарегистрирован: 12.08.2016
С нами: 7 лет 7 месяцев
Откуда: Киев
Сайт

Сообщение #7 makki » 27.01.2018, 07:32

Предложу еще один вариант, как вывести бренды. Но опять же, в отличие от самого первого решения, это показывает бренд только при показе категории товаров. А в хитах, новинках, акционных товарах, в сравнении товаров, избранных и рекомендуемых товарах надо отдельно программировать.

1) Файл view/ProductsView.php
В внутри блока условия с комментарием // Выбираем бренды, они нужны нам в шаблоне
после строки

Код: Выделить всё

$category->brands = $this->category_brands;

добавим

Код: Выделить всё

            foreach ($category->brands as $brand) {
                $brands[$brand->id] = new StdClass;
                $brands[$brand->id]->name = $brand->name;
                $brands[$brand->id]->url = $brand->url;
            }
            $this->design->assign('brands', $brands);


2) Файл design/ваш_шаблон/html/product_list.tpl
Выводим бренд в нужном месте
Например после строки

Код: Выделить всё

<a class="product_name" data-product="{$product->id}" href="{$lang_link}products/{$product->url}">{$product->name|escape}</a>

добавим

Код: Выделить всё

        {if $product->brand_id}
            <a href="brands/{$brands[$product->brand_id]->url}" class="product_brand_link">{$brands[$product->brand_id]->name|escape}</a>
        {/if}
Последний раз редактировалось makki 27.01.2018, 09:58, всего редактировалось 1 раз.
Cоздание и расширение функционала интернет-магазина на платформе OkayCMS 2 (с 3-й и 4-й версией не работаю)

korshunov
korshunov
Репутация: 146
Сообщения: 1854
Зарегистрирован: 03.12.2015
С нами: 8 лет 3 месяца
Skype

Сообщение #8 korshunov » 27.01.2018, 08:43

Способ 3.

1. view/ProductsView.php
после
$images = $this->products->get_images(array('product_id'=>$products_ids));
foreach($images as $image) {
$products[$image->product_id]->images[] = $image;
}
добавить
$bids = array();
$brands = array();
foreach($products as $product) {
$bids[] = $product->brand_id;
}
if($bids){
$temps = $this->brands->get_brands(array('id'=>$bids));
foreach($temps as $temp) {
$brands[$temp->id]= $temp;
}
$this->design->assign('brands', $brands);
}
2. design/ваш_шаблон/html/product_list.tpl
В нужном месте внутри цикла
{if $product->brand_id}
<a href="brands/{$brands[$product->brand_id]->url}" class="product_brand_link">{$brands[$product->brand_id]->name}</a>
{/if}

По сравнению с предыдущими двумя предложениями
1. Не усложняются бесполезной нагрузкой "чужие" запросы, как в способе 1.
2. Не добавляется чрезмерная нагрузка на базу , как в способе 2. Добавляется лишь один запрос.

IvanovMARK писал(а):P.S. Не так уж мало мест, где теперь еще надо обращаться к тому же get_brand, чтобы вывести бренд в превью товаров в хитах, новинках и акционных товарах, в сравнении товаров, избранных и рекомендуемых товарах. Так что склоняюсь к тому, что мое изначальное решение было ничем не хуже а то и лучше.
vedastudio@gmail.com

Если хотите выводить и в других местах, то приведенный способ можно изменить так: в View.php получать и отправлять в Smarty данные по всем брендам, подобно тому, как делается сейчас, например, для всех языков. Это даст возможность в ЛЮБОМ шаблоне без дополнительных ухищрений использовать конструкции вида
{$brands[$product->brand_id]->url, {$brands[$product->brand_id]->name.
Затраты - всего лишь один доп запрос. А может, этим способом еще можно сэкономить на прочих запросах по брендам, например, тем, которые в том же ProductsView.php кое-где даже по одному в циклах делаются...

makki M
makki M
Репутация: 199
Сообщения: 697
Зарегистрирован: 12.08.2016
С нами: 7 лет 7 месяцев
Откуда: Киев
Сайт

Сообщение #9 makki » 27.01.2018, 09:43

korshunov писал(а):Способ 3.
Похоже пока вы набирали свой метод, я уже выложил похожее и как по мне менее ресурсозатратное решение.
P.S. пользуйтесь пожалуйста форматированием текста. Тяжело читается код.
Cоздание и расширение функционала интернет-магазина на платформе OkayCMS 2 (с 3-й и 4-й версией не работаю)

IvanovMARK M
Аватара
IvanovMARK M
Репутация: 2
Сообщения: 58
Зарегистрирован: 05.01.2016
С нами: 8 лет 2 месяца

Сообщение #10 IvanovMARK » 27.01.2018, 09:48

korshunov писал(а):Способ 3.

Ну вот же. Всё просто.
P.S. Общались уже голосом.

makki M
makki M
Репутация: 199
Сообщения: 697
Зарегистрирован: 12.08.2016
С нами: 7 лет 7 месяцев
Откуда: Киев
Сайт

Сообщение #11 makki » 27.01.2018, 10:26

Вернулся к первому варианту. Он самый простой и универсальный. А в том, что мы добавили 2 новых значения в массив, возвращаемый функцией get_products, не вижу ничего криминального.
Cоздание и расширение функционала интернет-магазина на платформе OkayCMS 2 (с 3-й и 4-й версией не работаю)

korshunov
korshunov
Репутация: 146
Сообщения: 1854
Зарегистрирован: 03.12.2015
С нами: 8 лет 3 месяца
Skype

Сообщение #12 korshunov » 27.01.2018, 10:44

makki писал(а):Похоже пока вы набирали свой метод, я уже выложил похожее и как по мне менее ресурсозатратное решение.

Не понял, чем Ваше новое решение менее ресурсозатратное. По сравнению с моим - экономия в один несложный запрос на бренды. Но за это Вам приходится платить уже указанным Вами недостатком - "это показывает бренд только при показе категории товаров".
То есть, например, на странице поиска
http://demookay.com/all-products?keyword=кресло
это не работает, что несколько неестественно.
То же самое касается страницы
http://demookay.com/wishlist
Тем самым Ваше последнее решение не совсем соответствует задаче, поставленной в самом начале в заголовке темы: "Бренд в превью товара".
По сравнению со способом 2 кидаетесь в другую крайность - ради экономии одного простенького запроса даете решение неполное и искусственно ограниченное.

Добавлено спустя 8 минут 4 секунды:
makki писал(а):Вернулся к первому варианту. Он самый простой и универсальный. А в том, что мы добавили 2 новых значения в массив, возвращаемый функцией get_products, не вижу ничего криминального.

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

makki M
makki M
Репутация: 199
Сообщения: 697
Зарегистрирован: 12.08.2016
С нами: 7 лет 7 месяцев
Откуда: Киев
Сайт

Сообщение #13 makki » 27.01.2018, 10:53

korshunov писал(а):По сравнению со способом 2 кидаетесь в другую крайность - ради экономии одного простенького запроса даете решение неполное и искусственно ограниченное.
Именно поэтому, потом я написал, что самым нормальным решением считаю изначальный способ, выложенный в первом посте. Ни ваш вариант, ни мои последующие варианты не дают полного решения задачи.
Cоздание и расширение функционала интернет-магазина на платформе OkayCMS 2 (с 3-й и 4-й версией не работаю)

IvanovMARK M
Аватара
IvanovMARK M
Репутация: 2
Сообщения: 58
Зарегистрирован: 05.01.2016
С нами: 8 лет 2 месяца

Сообщение #14 IvanovMARK » 27.01.2018, 10:54

makki писал(а):
korshunov писал(а):По сравнению со способом 2 кидаетесь в другую крайность - ради экономии одного простенького запроса даете решение неполное и искусственно ограниченное.
Именно поэтому, потом я написал, что самым нормальным решением считаю изначальный способ,

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

Вывод: если работает - не трогай :)

korshunov
korshunov
Репутация: 146
Сообщения: 1854
Зарегистрирован: 03.12.2015
С нами: 8 лет 3 месяца
Skype

Сообщение #15 korshunov » 27.01.2018, 11:09

makki писал(а):Именно поэтому, потом я написал, что самым нормальным решением считаю изначальный способ, выложенный в первом посте. Ни ваш вариант, ни мои последующие варианты не дают полного решения задачи.

Если Вы напишете ТОЧНО, что считаете за "полное решение задачи", а заодно и задачу поставите ТОЧНО, то можно будет говорить предметно, а не общими фразами...

makki M
makki M
Репутация: 199
Сообщения: 697
Зарегистрирован: 12.08.2016
С нами: 7 лет 7 месяцев
Откуда: Киев
Сайт

Сообщение #16 makki » 27.01.2018, 11:13

IvanovMARK писал(а):
makki писал(а):Именно поэтому, потом я написал, что самым нормальным решением считаю изначальный способ,

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

Вывод: если работает - не трогай :)
Из-за чего повесится магазин? Из-за одного left join?

Добавлено спустя 1 минуту 47 секунд:
korshunov писал(а):
makki писал(а):Именно поэтому, потом я написал, что самым нормальным решением считаю изначальный способ, выложенный в первом посте. Ни ваш вариант, ни мои последующие варианты не дают полного решения задачи.

Если Вы напишете ТОЧНО, что считаете за "полное решение задачи", а заодно и задачу поставите ТОЧНО, то можно будет говорить предметно, а не общими фразами...
Я уже писал об этом. Полное решение, это видеть бренд не только в каталоге товаров, а и в хитах, новинках, акционных товарах, в сравнении товаров, избранных и рекомендуемых товарах
Cоздание и расширение функционала интернет-магазина на платформе OkayCMS 2 (с 3-й и 4-й версией не работаю)

IvanovMARK M
Аватара
IvanovMARK M
Репутация: 2
Сообщения: 58
Зарегистрирован: 05.01.2016
С нами: 8 лет 2 месяца

Сообщение #17 IvanovMARK » 27.01.2018, 11:16

makki писал(а):... Из-за одного left join? .. join тут и там. потом ещё

при НЕ большом кол-ве товаров всё хорошо.
я не спорю. а пиковую нагрузку хостинги прощают.. если не постоянно.
Если у вас работает. пусть будет так.. не розетка и не юлмарт же у вас ;)

Добавлено спустя 8 минут 37 секунд:
makki,
Вы в своём праве делать и 1 способ и 3. ваш выбор. просто... когда /ЕСЛИ у вас будет такое кол-во посетителей.
ОДНОВРЕМЕННО открывающих 54456756756 страниц.
тогда у вас и возникнет вопрос оптимизации запросов. сейчас у вас и так работает. ок.
Последний раз редактировалось IvanovMARK 27.01.2018, 17:31, всего редактировалось 3 раза.

makki M
makki M
Репутация: 199
Сообщения: 697
Зарегистрирован: 12.08.2016
С нами: 7 лет 7 месяцев
Откуда: Киев
Сайт

Сообщение #18 makki » 27.01.2018, 11:53

IvanovMARK писал(а):Будет развитие магазина? тогда и появятся вопросы.
Меня не надо убеждать, что важно, чтобы решение задач было насколько возможно оптимизировано и менее ресурсозатратно. Я с этим полностью согласен. Именно поэтому, я принял изначальное замечание korshunov и начал искать другие варианты. Также сам korshunov предложил свой вариант.
Безусловно, есть еще варианты решения и возможно они будут более оптимизированы. Но из всех предложенных вариантов, я считаю что 1-й вариан наиболее подходящий. Если нет, переубедите меня или предложите лучший вариант.
Для справки: В клиентской части функция get_products задействована 8 раз. Из них, только 3 раза, полученная путем left join информация не задействована, если нам нужно вывести бренд во всех местах, где есть превью товара.
Cоздание и расширение функционала интернет-магазина на платформе OkayCMS 2 (с 3-й и 4-й версией не работаю)

IvanovMARK M
Аватара
IvanovMARK M
Репутация: 2
Сообщения: 58
Зарегистрирован: 05.01.2016
С нами: 8 лет 2 месяца

Сообщение #19 IvanovMARK » 27.01.2018, 11:58

работает? не трогай :)
оптимизация == отдельный вопрос
pps сайт покажите. Здесь - или сам сделаешь.. или может таки верить в update

«Тестирование можно использовать для того, чтобы доказать наличие ошибок в программе, и никогда — для того чтобы доказать их отсутствие!»
Эдсгер Дейкстра
Последний раз редактировалось IvanovMARK 28.01.2018, 05:03, всего редактировалось 3 раза.

makki M
makki M
Репутация: 199
Сообщения: 697
Зарегистрирован: 12.08.2016
С нами: 7 лет 7 месяцев
Откуда: Киев
Сайт

Сообщение #20 makki » 27.01.2018, 12:19

IvanovMARK писал(а):работает? не трогай :)
Для меня это пройденный этап. Теперь хочется, чтобы не только работало, а работало правильно. Поэтому вопрос оптимизации мне тоже интересен.
IvanovMARK писал(а):
makki писал(а):get_products задействована 8 раз

сайт покажите.
это в шаблоне запросы .. в дизайне кто-то делал под общие задачи.
а по факту, тут желания.
Обращение напрямую к функции PHP из шаблона SMARTY не делаются :)
Никто ничего не делал. Я никому не даю вносить изменения в свой магазин.
Функция get_products задействована 8 раз в стандартном коде движка.
Cоздание и расширение функционала интернет-магазина на платформе OkayCMS 2 (с 3-й и 4-й версией не работаю)


Название раздела: Полезные решения для OkayCMS
Правила раздела: faq.php?mode=okay

Быстрый ответ


Введите код в точности так, как вы его видите. Регистр символов не имеет значения.
Код подтверждения

   

Вернуться в «Полезные решения для OkayCMS»

Кто сейчас на форуме (по активности за 5 минут)

Сейчас этот раздел просматривают: 20 гостей