Страница 1 из 2

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

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

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}

Добавлено: 26.01.2018, 13:31
korshunov
Работать оно будет, но уж больно метод топорный, грубый и нарушающий стандартную идеологию CMS...

Добавлено: 26.01.2018, 15:10
makki
Обоснуйте свои слова. Привык к вашим замечаниям, но в этот раз вас вообще не понимаю.

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

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

Добавлено: 26.01.2018, 22:17
makki
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, чтобы вывести бренд в превью товаров в хитах, новинках и акционных товарах, в сравнении товаров, избранных и рекомендуемых товарах. Так что склоняюсь к тому, что мое изначальное решение было ничем не хуже а то и лучше.

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

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

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}

Добавлено: 27.01.2018, 08:43
korshunov
Способ 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 кое-где даже по одному в циклах делаются...

Добавлено: 27.01.2018, 09:43
makki
korshunov писал(а):Способ 3.
Похоже пока вы набирали свой метод, я уже выложил похожее и как по мне менее ресурсозатратное решение.
P.S. пользуйтесь пожалуйста форматированием текста. Тяжело читается код.

Добавлено: 27.01.2018, 09:48
IvanovMARK
korshunov писал(а):Способ 3.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Добавлено: 27.01.2018, 11:16
IvanovMARK
makki писал(а):... Из-за одного left join? .. join тут и там. потом ещё

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

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

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

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

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

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

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