Форум пользователей Impera CMS
Impera CMS - отличный движок для лёгкого создания интернет магазина.
Обладает невероятным количеством функций, необходимых в онлайн торговле.

Следить
Главная
00:17
20 фев
#
?
написал:

Добрый день, коллеги! Мне очень нужно 2 полезные функции:

1. Сортировка по наличию

Поисковики, да и посетители, очень не любят когда им вместо карточки товара показывают 404 страницу.

Поэтому товары, которых нет в наличии, я все равно показываю в каталогах (другими словами не пользуюсь галочкой enabled). В карточке товара, в этом случае пишу: "Товара временно нет в наличии, зайдите позже". Последняя цена при этом показывается, но скрывается кнопка в корзину. Наличие товара на складе, я прописываю в вариантах товара. И вопрос в следующем, мне нужно не зависимо от того какую сортировку и направление выбрал посетитель в фильтре поиска, что бы товары, которых нет в наличии всегда были в конце списка (на последних страницах).

2. Галочка в фильтре "Показывать только в наличии"

В фильтре поиска, в блоке где указывается по какому критерию сортировать, направление сортировки и фильтр по цене, я бы хотел сделать галочку Показывать только в наличии, которая по умолчанию отмечена. Если она стоит, то показываются товары у который значение stock > 0. Если галочку снять, показываются все товары, но товары, которых нет в наличии показываются последними. (Как указано в пунтке 1)

Как это можно сделать?

17:12
26 фев
#
написал:

Ответ на вопрос 1 Подобное поведение сортировки уже на уровне ядра движка давно выполняется для товаров, отмеченных флагом не продаём. То есть такие товары всегда располагаются в конце списка, какой бы способ сортировки не использовался в этот момент на сайте.

Кстати, указанный флаг и связанную с ним функциональность, условно называемую "экспонаты", редко кто использует. И если у вас на сайте такая функциональность тоже отброшена, тогда задача решалась бы простым образом и состояла в том, чтобы связать наличие/отсутствие на складе с немедленной простановкой флага не продаём.

Простановка флага могла бы выполняться менеджером вручную, когда редактирует наличие товара. А можно автоматизировать, возложив контроль на некий метод хелпера шаблона, например checkStockFlag, который с паузой 1Час-секунд выполняет запрос к базе данных на установку соответствующего флаг-поля non_usable согласно состояния складского поля stock (файл-таймер контроллер с помощью метода checkFileTimer - лишь один из способов выполнения периодических действий в многопоточном трафике).

<?php
    class TemplateEmulator {
        protected $cms;

        {* <!-- ===================================================================
        |                                                                         |
        |  Конструктор хелпера.                                                   |
        |                                                                         |
        ==================================================================== --> *}

        public function __construct ( & $cms ) {
            $this->cms = & $cms;
            $this->checkStockFlag();
            ...
            ...
        }

        {* <!-- ===================================================================
        |                                                                         |
        |  Еще какие-то методы хелпера.                                           |
        |                                                                         |
        ==================================================================== --> *}

        ...
        ...

        {* <!-- ===================================================================
        |                                                                         |
        |  Установка флага "Не продаем" согласно состоянию склада.                |
        |                                                                         |
        ==================================================================== --> *}

        private function checkStockFlag () {
            $file = dirname(__FILE__) . '/../../../cache/checkStockFlag.FileTimer.tmp';
            if ($this->checkFileTimer($file, 60 * 60)) {
                $this->cms->db->query(
                    'UPDATE `products`, ' .
                           '`products_variants` ' .
                    'SET `products`.`non_usable` = CASE WHEN `products_variants`.`stock` > 0 ' .
                                                       'THEN 0 ' .
                                                       'ELSE 1 ' .
                                                       'END ' .
                    'WHERE `products`.`product_id` = `products_variants`.`product_id`'
                );
            }
        }

        private function checkFileTimer ( $file, $lifetime ) {
            $handle = @ fopen($file, 'rb');
            if ($handle !== FALSE) {
                @ fclose($handle);
                $date = @ filemtime($file);
                if ($date === FALSE) return FALSE;
                $now = time();
                if ($now >= $date && $now <= $date + $lifetime) return FALSE;
            }
            return @ touch($file);
        }
    }
?>


Кстати, для вывода кнопки "В корзину" подойдёт следующая шаблонизационная функция, используемая здесь в упрощённом виде.

{if $helper->maybeSale($product)}
    В корзину
{else}
    Нет в наличии
{/if}


А вот полный вид, который учитывает ситуации, что товар:

  • имеется в наличии
  • отсутствует, но разрешена продажа под заказ
  • отсутствует и запрещена продажа под заказ
  • является экспонатом
{$state = $helper->maybeSale($product)}
{if $state === TRUE}
    В корзину
{elseif $state}
    Под заказ
{elseif $state === FALSE}
    Нет в наличии
{else}
    Экспонат
{/if}
23:28
26 фев
#
написал:

Ответ на вопрос 2 Согласно поставленной задаче, кроме добавления галочки в вёрстку фильтра в шаблоне клиентской стороны сайта, нам также требуется слегка изменить модуль товаров в части приёма параметров фильтра. Точная последовательность действий выглядит так:

  • 1. добавить галочку в фильтре
  • 2. отключить прежний модуль Список товаров (класс: Products)
  • 3. зарегистрировать новый модуль, например ProductsMy
  • 4. породить ProductsMy от модуля Products и дополнить код приёмом галочки
  • 5. прописать редирект теневых адресов прежнего модуля на новый, то есть заменить GET-параметр module=Products на module=ProductsMy

Причём пункты 2 и 5 служат цели навсегда скрыть прежний модуль, а на его адресах разместить новый.

1 Начнём выполнять по шагам. Галочку добавляем в форму фильтра так, например она станет параметром InStockOnly:

<form ...>
    ...
    ...

    {$checked = (!isset($InStockOnly) || $InStockOnly) ? 'checked' : ''}
    <input name="InStockOnly" type="checkbox" {$checked} value="1" /> Показывать только в наличии
</form>

2 Теперь отключим прежний модуль товаров: на странице админпанели страницы » Зарегистрированные модули выключаем лампочку у модуля класса Products.

3 На той же странице теперь жмём ссылку добавить и добавляем модуль класса ProductsMy.

4 Теперь породим новый модуль от прежнего и допишем его код. Для этого:

  • создаём папку objects/productsmy, здесь будет храниться файл модуля
  • помещаем в эту папку файл ProductsMy.php
  • в файле пишем следующий код
<?php
    require_once(dirname(__FILE__) . '/../products/Products.php');

    class ClientProductsMy extends ClientProducts {

        protected function complementFilter ( & $filter ) {
            if (!parent::complementFilter($filter)) return FALSE;

            // обрабатываем свою галочку фильтра
            $flag = $this->request->getRequestAsBoolean('InStockOnly');
            if ($flag) $filter->non_usable = 0;
            $this->smarty->assignByRef('InStockOnly', $flag);

            return TRUE;
        }
    }
?>

Здесь мы подгрузили код прежнего модуля, породили от него наш модуль, перекрыли метод complementFilter (дополнение фильтра записей), дав сначала отработать родительскому методу, а затем выполнили свою проверку параметра InStockOnly.

5 Осталось в корневом файле .htaccess прописать редирект теневых адресов прежнего модуля.

RewriteCond  %{QUERY_STRING}  ^(.*&)?module=Products(&.*?)?$
RewriteRule  ^index\.php$     index.php?%1module=ProductsMy%2  [L]
10:07
28 фев
#
?
написал:

Огромное спасибо за полезную информацию! Все получилось!!!

5й пункт я так понял в .htaccess ?

23:05
28 фев
#
написал:

Извиняюсь, отсутствие текста 5-ого пункта не заметил, когда публиковал ответ. Уже добавил.

13:13
29 фев
#
?
написал:

Добрый день! Спасибо за ответ! Но есть проблема...

Если я в .htaccess все перенаправления с module=Products переделываю на module=ProductsMy, то все работает.

А если вернуть как было, и использовать ваши 2 строчки, то почему то не работает... Есть разница в какой именно строке размещать это преобразование? Я вставлял в конец...

13:36
01 мар
#
?
burov1ik написал:

Нафиг эти 2 строки? Старый модуль ведь экранируют.

Так зачем размазывать запрос? Имеем редир ЧПУ адреса категории в теневой module=Products старого модуля, из него редир в теневой module=ProductsMy нового.

Почему бы не заменить имя модуля в htaccess сразу?

17:17
01 мар
#
?
написал:

У меня 2 строки заработали вверху htacess после строки RewriteEngine on. Как пробник редирект написал с Product на Login вот так.

RewriteCond  %{QUERY_STRING}  ^(.*&)?module=Product(&.*?)?$
RewriteRule  ^index\.php$     index.php?%1module=Login%2     [NC,L]

Захожу в любой товар, локалхост страницу логина выводит. Убираю строки, работает как обычно.

09:35
02 мар
#
?
написал:

Поиде сверху не должно работать, так как как минимум выше должно быть исходное перенаправление:

RewriteRule  ^(products|items)/?$  index.php?module=Products  [NC,L,QSA]

На которое должны сработать приведенные выше две строчки.

16:19
03 мар
#
?
написал:

Там же все RewriteRule правила содержат флаг L (last), который как описано в документации прерывает текущий цикл реврайта и начинает последующий с начала файла. В такой обработке директив какое-то одно правило срабатывает на каждый проход. Тогда порядок инструкций не имеет значения, на первом цикле может быть обработана нижняя, на втором - верхняя.

Написание ответа

Перед публикацией рекомендуется использовать Предпросмотр, чтобы увидеть конечный вид сообщения.


Обратите внимание! Для противодействия спаму новые посты форума проявляются с задержкой от нескольких минут, пока не пройдут модерацию.