Предисловие. Все, кто пользуются Битриксом, знают, до чего сложно порой бывает полностью настроить свой сайт так, как нужно. Одна часть настроек делается в административной части, другая часть в компонентах в публичной части. Тут не было бы проблем, если бы это были совершенно разные настройки, но они могут пересекаться. Самый яркий пример, с которым постоянно сталкиваются разработчики и покупатели интернет-магазинов, — необходимость настраивать адрес детальной страницы товара и в инфоблоке, и в компоненте каталога. Далее возникает необходимость указывать одни и те же параметры в нескольких компонентах на вашем сайте. Путь к странице с корзиной и путь к странице с оформлением заказа нужно задавать в компонентах большой и малой корзины, в компонентах каталога. Настройки инфоблока с товарами, правила добавления в корзину, покупку с характеристикой, свойства для отбора торговых предложений и многие другие настройки нужно задавать отдельно для различных компонентов каталога. Комплексный компонент bitrix:catalog частично избавляет от этой необходимости, но часть компонентов может быть размещена на отдельных страницах (блок спецпредложений на главной странице, дополнительный блок с товарами в разделе новостей и т.п.) и требует дополнительной идентичной настройки. С точки зрения самих компонентов это совершенно нормально, так как каждый из них должен быть полностью самостоятельным, независимым и работоспособным при размещении на любой странице сайта. Также это позволяет добиться универсальности: на разных страницах одни и те же компоненты можно настроить по-разному, например, выводить товары из разных каталогов с разными настройками. Но в рамках большого цельного сайта и особенно типовых решений такой подход к настройкам добавляет головной боли. Вам приходится постоянно помнить, в каких местах находятся одни и те же настройки, чтобы при необходимости их изменения ни о чем не забыть. А если вы купили и установили типовое решение, то о наличии некоторых страниц и/или настроек в компонентах поначалу можно даже и не подозревать. Будучи разработчиками типовых решений мы можем упростить и облегчить процесс настройки сайта и всех его компонентов в публичной части. Именно об этом пойдет в речь в этой статье.
Часть 1. Всё вертится вокруг каталога. Жизнь каждого интернет-магазина начинается с формирования и настройки каталога. После установки 1С-Битрикс и понравившегося шаблона интернет-магазина нам нужно выгрузить товары на сайт и отобразить их в каталоге. Каталог — это ядро нашего магазина, поэтому все настройки в первую очередь вносятся в комплексный компонент bitrix:catalog. И только после этого, имея основной каталог в качестве эталона, мы начинаем настраивать остальные компоненты аналогичным образом. И чем больше настроек нужно сделать для отображения товаров, тем больше их придется дублировать.
Рассмотрим следующий пример: в дизайне и верстке предусмотрен вывод артикула товара на страницах каталога в собственной области отдельно от всех остальных характеристик товара. Для реализации такой возможности в каталог нужно добавить новый параметр, позволяющий выбрать, какое из свойств инфоблока должно выводиться отдельно в качестве артикула.
Далее возникает необходимость также выводить артикул товара в малой и большой корзине.Стандартный подход Битрикса подразумевает, что мы должны добавить аналогичные параметры в шаблоны малой и большой корзины. А это значит, что в итоге мы будем задавать один и тот же параметр в трех компонентах. А если захотим вывести артикул еще в каких-либо компонентах, то потом и там нужно будет настраивать отдельно. К тому же набор свойств для выбора берется из инфоблока, который выбран в параметрах компонента каталога. В компонентах корзины такого выбора нет, так как корзине не нужно указывать какой-то конкретный инфоблок для работы, она работает одинаково для любых инфоблоков, из которых добавляются товары. Чтобы задавать такие параметры в компонентах корзины, понадобится еще и самостоятельно делать дополнительную выборку этих свойств/инфоблоков. При таком подходе, даже настроив отображение артикула в каталоге, мы не сразу узнаем, что можем вывести артикул товара и в других компонентах.
Можно ли выполнить настройку как-то по другому? У нас уже есть параметры, заданные для всего каталога. Нам нужно лишь как-то их получить и использовать в других компонентах решения. Один из способов для достижения этой цели — записывать параметры компонента в кеш в шаблоне каталога, а потом читать их из кеша в шаблонах всех остальных компонентов, где понадобится обработка и вывод какой-либо информации по аналогии с каталогом. Давайте рассмотрим по шагам, как реализуется такой механизм.
$ob = new \CPHPCache();
if ($ob->InitCache($_cacheTime, $_cacheId, $_cachePath, $_cacheDir)) {
// if cache is valid check params equality
if ($arParams != $ob->GetVars()) {
// if not - clean cache
$ob->Clean($_cacheId, $_cachePath, $_cacheDir);
}
}
// write down params if there is no cache
if ($ob->StartDataCache($_cacheTime, $_cacheId, $_cachePath, array(), $_cacheDir)) {
$ob->EndDataCache($arParams);
}
unset($ob);
В result_modifier.php шаблона комплексного компонента bitrix:catalog проверяем наличие кеша с параметрами компонента.
Если он существует, сверяем с текущим набором параметров. При несовпадении удаляем кеш.
Записываем текущие параметры каталога в кеш с уникальным идентификатором.
В другом компоненте читаем параметры каталога из кеша с этим же уникальным идентификатором. Если кеш еще не создан, используем значения по умолчанию.
Пользуемся.
Можно подумать, что реализация такого механизма всего лишь для отображения какого-то артикула в корзине совершенно избыточна, ведь можно просто добавить артикул в корзину как свойство товара, а потом вывести его там. Но лучше не класть разные сущности в одну корзину, ведь может понадобиться и обычный функционал покупки с характеристикой, и тогда в заказах в админке будет каша из купленных свойств товара вперемешку со служебными. А еще больше радует использование такого подхода, когда нужно в корзине вывести наличие товара на отдельных складах, а этот блок задается сразу несколькими параметрами в компоненте каталога и уж точно никак не может существовать в виде свойств товара в корзине.
При хранении параметров в кеше необходимо учитывать две особенности.
Кеш имеет свойство удаляться различными способами. Наш кеш с параметрами чистить нет смысла, он и так будет автоматически обновляться при изменении параметров компонента. А вот если в тот небольшой промежуток, пока нового кеша каталога нет, кто-то откроет другую страницу с компонентом, использующим этот кеш, то он получит не совсем тот вид страницы, как обычно.
Для того, чтобы этот кеш не удалялся даже при сбросе всего кеша в административной части сайта, необходимо разместить его в другой базовой директории. Базовая директория задается третьим аргументом метода CPHPCache::Clean(), четвертым аргументом метода CPHPCache::InitCache() и пятым аргументом метода CPHPCache::StartDataCache(). По умолчанию значение этих аргументов "cache", поэтому весь кеш хранится в директории /bitrix/cache.
В своем решении для хранения этого кеша мы указываем базовую директорию "cache_romza", и кеш параметров каталога попадает в папку /bitrix/cache_romza, и как следствие не удаляется при очистке всего кеша сайта в административной части.
Никакие данные нельзя прочитать из кеша, если на странице была выполнена команда "Сбросить кеш" в административной панели (?clear_cache=Y), или если пользователь отключил кеширование для всего сеанса (?clear_cache_session=Y).
Есть способ обойти и это затруднение. Перед чтением параметров из кеша необходимо отключить режим работы без кеша, а после чтения параметров включить его обратно, если он был активен.
// =========== TURN OFF CLEAR_CACHE ===========
$clearCache = Bitrix\Main\Data\Cache::setClearCache(false);
$clearCacheSession = (isset($_SESSION["SESS_CLEAR_CACHE"]) && $_SESSION["SESS_CLEAR_CACHE"] === "Y");
Bitrix\Main\Data\Cache::setClearCacheSession(false);
if ($clearCacheSession) unset($_SESSION["SESS_CLEAR_CACHE"]);
// ============================================
… Читаем параметры из кеша …
// ============ TURN ON CLEAR_CACHE BACK IF NEEDED ===============
if ($clearCache) Bitrix\Main\Data\Cache::setClearCache(true);
if ($clearCacheSession) {
Bitrix\Main\Data\Cache::setClearCacheSession(true);
$_SESSION["SESS_CLEAR_CACHE"] = "Y";
}
// ===============================================================
Есть и другой подход, при котором с помощью стандартных классов Битрикса можно парсить файл /catalog/index.php и выдирать нужные параметры прямо оттуда. Но в этом случае нужно быть однозначно уверенным, что вызов компонента каталога находится именно поэтому адресу. Такой подход может быть использован только в частной разработке под конкретного клиента. При разработке типового решения мы не можем быть уверены, что конечный клиент не захочет переименовать папку с каталогом в /c/index.php или еще как-нибудь. Способ с записью параметров в кеш из шаблона компонента позволяет абстрагироваться от места вызова компонента. Вдобавок мы получаем нормально сформированный массив параметров, который прошел через предварительную обработку компонентом и наши собственные манипуляции с параметрами в result_modifier.php до момента записи в кеш. Если какие-либо параметры каталога зависят от переменных, которые могут регулярно изменяться, то их лучше изменять после проверки и записи в кеш. Этот же кеш с параметрами можно использовать для подгрузки частей каталога через AJAX, чтобы не гонять параметры в открытом или зашифрованном виде от сервера клиенту и от клиента обратно на сервер.
Часть 2. Панель настройки сайта. Еще один подход к быстрой и простой настройке сайта состоит в том, чтобы создать отдельную панель для единой настройки всех визуальных составляющих. В первую очередь это касается параметров отображения шаблона сайта, то есть того, что не относится ни к одному из компонентов (фон страницы, расположение блоков в шапке и т.п.).
Но также можно вынести ряд одинаковых параметров из разных компонентов в панель для удобства настройки, если они не требуют выборки дополнительных данных на основе других параметров компонента. Такие параметры можно было бы организовать в виде настроек модуля в административной части сайта, но их расположение в публичке позволяет быстрее увидеть результат или даже мгновенно у тех параметров, которые поддерживают "живое" переключение с помощью JS; автоматически определять и разделять настройки для разных сайтов в многосайтовой конфигурации; давать возможность индивидуальной настройки для разных пользователей. Хранение таких настроек тоже весьма интересная задача.
Изначально компонент панели настроек записывал настройки авторизованных пользователей и настройки по умолчанию для всех в COption — по одной записи на каждый параметр, а настройки для неавторизованных пользователей сохранялись в куки — по одной куки на каждый параметр. Такой подход неплохо справлялся со своей задачей, пока количество параметров в панели настроек во всех наших прошлых типовых решениях было небольшим. В типовом решении Битроник 2 общее количество параметров в панели настроек достигло порядка 150. Привело это к тому, что в таблице b_option на демо-сайте решения накопилось свыше 3500 записей c настройками посетителей. Но еще хуже тот факт, что далеко не все браузеры могут сохранить такое количество кук. В браузерах IE и Edge от Microsoft даже последних версий позволяется хранить только 50 кук с одного сайта. Из-за этого настройки решения у неавторизованных пользователей в этих браузерах не сохранялись в принципе. Да и в других браузерах куки начинали периодически пропадать. Для того, чтобы избежать всех этих проблем, решено было также сохранять массив параметров в изолированный кеш с теми же двумя мерами защиты от сброса, как и в первой части статьи. В качестве ID кеша используется хеш массива, который уже записывается в COption или в куку для каждого отдельного пользователя. Таким образом, мы теперь делаем не по 150 записей на каждого пользователя, а всего по одной с ключем от кеша с массивом параметров. Общие настройки сайта, установленные администратором, помимо кеша по-прежнему дублируются отдельными записями в COption для лучшей стабильности работы.
Послесловие. В этой статье был рассмотрен способ хранения каких-либо параметров в изолированном кеше с защитой от сброса для его распределенного использования на вашем сайте и два примера использования такого подхода для получения параметров комплексного компонента каталога в других компонентах и скриптах, а также хранения огромного массива настроек типового решения. Надеемся, что эта информация была интересной и полезной. Будем рады услышать любую конструктивную критику и обсудить другие возможные альтернативные способы решения проблем, затронутых в этой статье.
ОБНОВЛЕНИЕ. Ответы на вопросы из комментариев.
Задойный Алексей написал: Я к тому, что насмерть кешировать что-то - это очень опасная затея, если всё хорошенько не обдумать. И есть риск, что такое мощное оружие попадёт не в те руки.Безусловно. Любое оружие накладывает ответственность за его использование. А испортить можно что угодно и чем угодно, если не включать голову. Чего нам нужно бояться при вечном кешировании, которое нельзя очистить стандартными инструментами?
Бесконечное размножение файлов с кешем и заполнение всего доступного дискового пространства. В первом примере это кеш с параметрами одного компонента. По сути сериализованная копия файла /catalog/index.php (по умолчанию) для чтения в любом другом скрипте независимо от того, по какому пути расположен наш файл с вызовом комплексного каталога. То есть независимо от настроек каталога, независимо от пользователя это всегда только один файл. Изменили настройки каталога в режиме правки, изменилось содержимое нашего файла с кешем настроек. Если понадобится хранить настройки еще одного компонента таким образом, появится еще один файл. По одному файлу на один компонент, чьи настройки нужно хранить. Таким образом за переполнение диска в этом случае волноваться не стоит. Во втором примере уже посложнее, так как на каждую комбинацию настроек создается отдельный файл с кешем. Но тут мы опираемся на многочисленные примеры реального использования клиентами панели настроек. Изначально после установки решения панель настроек закрыта от всех пользователей, кроме администраторов. Администратор настраивает один раз, как сайт должен выглядеть для его посетителей, и может еще отдельно задать настройки лично для себя. На этом всё и заканчивается. Никто не открывает к панели настроек доступ для посетителей, чтобы они могли менять внешний вид под себя. Реально такой функционал используется только на демо-сайте решения, чтобы любой человек мог изучить возможности панели настроек без получения администраторских прав доступа. Но тут несложно написать агент, который будет удалять те файлы кеша, которые не принадлежат авторизованным пользователям и были созданы давно.
Невозможность обновить вид страниц стандартным сбросом кеша. Такая проблема может возникнуть при кешировании $arResult или конечного HTML. Но мы записываем в кеш не конечный результат, а исходный набор параметров компонента, от которого уже зависит всё остальное. И этот набор параметров является актуальной копией того, что мы имеем в файле /catalog/index.php за счет постоянной синхронизации. Так что об этом тоже можно не беспокоиться.
Если существуют еще проблемы, которые возникают при несбрасываемом кеше, прошу их перечислить, чтобы можно было также обсудить.
==========================================
Забродин Роман написал: Возникает вопрос, а если пользователь начинает просмотр сайта не со страницы где расположен комплексный компонент каталога, а с какой-то другой, как тогда получить параметры, ведь получается что кэш с ними еще не создан?
Если быть точнее, то и не вопрос возникает, а серьезная проблема. На протяжении нескольких лет мы записываем параметры каталога в кеш для обновления самого каталога через AJAX, а во втором Битронике мы уже начали использовать его и в других компонентах тоже. Но даже при использовании только для AJAX регулярно происходили ситуации, когда мы загрузили в браузер страницу, в этот момент кеш сбросился по какой-либо причине, и никакие AJAX-запросы на нашей странице работать не будут: мы не сможем положить товар в корзину, перейти на другую страницу раздела, поменять сортировку, отфильтровать товары и т.д., пока не перезагрузим страницу, или пока кто-то другой не откроет страницу этого же каталога, создав кеш заново.
Таким образом, вышеобозначенная ситуация, что мы открываем какую-то страницу без комплексного компонента каталога, но на ней используются настройки этого компонента (берутся из кеша), возникает ВСЕГО ОДИН РАЗ. В тот момент, когда мы только что развернули типовое решение с помощью мастера установки. На последнем шаге мастера находится кнопка "Перейти на сайт". Мы нажимаем её и попадаем на главную страницу. Вот она загрузилась, но кеша с параметрами каталога еще нет. Что нам нужно делать в этом случае? Да ничего не нужно делать, так как каталог еще никто не настраивал, и в нем сейчас стандартные настройки, которые лежат в нашем дистрибутиве. Поэтому, не получив из кеша массив с настройками, мы смело используем параметры по умолчанию. Как долго не будет кеша с параметрами каталога? До первого захода на любую страницу каталога. Что произойдет моментально, так как после установки мы сразу идем и проверяем, всё ли работает. И вот мы открыли любую страницу каталога, наш кеш создан, ВСЁ. Он един для всех пользователей, так же как едины и параметры каталога. С этого момента для любого посетителя при посещении любой страницы сайта этот кеш будет существовать. Если мы зашли и поменяли настройки каталога, они сразу же поменялись и в нашем кеше.
Исключения:
Настройки каталога изменили руками в PHP-коде файла с вызовом компонента. Этот момент мы никак не можем отследить, но такое во-первых делается нечасто, а во-вторых настройки в кеше обновятся сразу же после загрузки любой страницы каталога. Вы же не меняете параметры руками в PHP-коде просто так от нечего делать каждый день по 100 раз? Такое делается очень редко и явно не просто так. После смены параметров через код, мы в любом случае обновим страницу, чтобы проверить, был ли достигнут желаемый результат. И, как следствие, кеш с настройками опять обновился.
Файлы кеша были удалены вручную из папки. Еще более вырожденный случай. Не каждый рядовой администратор сайта будет ходить по жесткому диску с метлой и удалять все файлы без разбора. А от стандартной очистки кеша мы защитились размещением в отдельной директории. НО! Даже в этом случае чтение параметров из кеша производится не просто так в каждом шаблоне по отдельности. Для этого создан специальный метод в нашем ядре (yenisite.core), который делает следующее: - проверяем наличие кеша с нужными параметрами, - если кеш отсутствует, делаем однократный запрос через HttpClient на страницу компонента с двумя специальными параметрами в URL, чтобы не выполнялась шапка сайта и не рендерился шаблон компонента и всё, что после него — только сохранение параметров в кеш и возвращение сообщения об успехе. Страница компонента передается через аргумент метода. По умолчанию "/catalog/index.php", где и расположен файл после установки. На большинстве сайтов путь к каталогу не меняется. И это значит, что… кеш будет доступен всегда. - Даже если это самый первый хит на сайт сразу после установки. - Даже если какой-то злодей руками стер кеш с параметрами компонента. А для случая, когда компонент каталога переносится в другую директорию, можно доработать конструкцию до еще большей стабильности: добавить возможность указывать директорию к каталогу в настройках модуля. И это может быть полезно не только для такого исключительно редкого случая, но и для того, чтобы избежать ряда других проблем. В некоторых типовых решениях приходится кастомизировать шаблон сайта для корректной работы, если компонент каталога размещен в другой директории. Еще несколько нюансов касательно ручного удаления файлов кеша с диска будут в ответе на последующие вопросы.
Забродин Роман написал: И еще вопрос, почему они записываются именно в кэш, а не например в таблицу БД b_option?
Для ответа на этот вопрос обратимся к документации.
Максимальная сохраняемая длина значения - 2000 символов.
Если открыть дистрибутив решения и посчитать количество символов в массиве с параметрами компонента каталога, то их окажется больше 6000. В сериализованном виде массив занимает еще чуть больше. - Имеются ли такие ограничения у файлового кеша? - Нет.
- Можно ли хранить каждый параметр каталога в отдельном COption? - Можно, но зачем? Во-первых, их будет дофига. Во-вторых, получить все настройки каталога одной строчкой кода не получится, API Битрикса предоставляет возможность получать только один COption с помощью одного вызова GetOptionInt() или GetOptionString(). Значит нужно писать свой метод, который будет или дергать их по очереди один за другим и записывать в массив (а для этого еще нужно знать имя каждого параметра, и потом постоянно дублировать при добавлении новых параметров), или делать запрос напрямую в БД, чтобы самостоятельно выбрать все нужные записи. В любом случае это громоздко и жутко. В-третьих, читаем комментарий Антона Долганина:
Категорически не рекомендуется использовать данный метод для хранения объемной информации (максимум - обычные переменные, фразы, маленькие массивы). Дело в том, что все значения переменных, всех модулей наполняют массив GLOBALS на каждом хите.
Злоупотребление данным методом может сказаться в конечном счете на производительности всей системы.
Комментарий датируется 2013 годом. К счастью, сейчас дело обстоит уже не совсем так, но тем не менее при попытке чтения хотя бы одного COption в память загружаются все COption модуля для текущего сайта. Поэтому COption всё равно не стоит злоупотреблять. И мне даже страшно думать о том, что творилось на нашем демо-сайте всё это время, пока на каждом хите в память загружались почти 4000 записей настроек ВСЕХ пользователей для панели настроек.
Забродин Роман написал: Знаю, что многие разработчики, уже воспринимают директорию /cache/ как хранилище всяческого "мусора", которую можно чистить как "корзину" прямо удаляя все ее содержимое (F8 в FAR ) не станет ли для них описанный механизм хранения параметров неприятным сюрпризом?
1) В том числе и поэтому мы не записываем теперь этот кеш в папку /cache/, а записываем в папку /cache_romza/. 2) Если действительно многие разработчики накидываются с клавишей Delete на любую папку, в названии которой содержится слово "cache" в любом виде, тогда возможно стоит переименовать папку в /romza_settings/ или /romza/settings/, или любое другое название, которое не будет вызывать у прожженых разработчиков позывов отправить содержимое каталога в корзину, и вообще к нему прикасаться.
Здесь важно понять, что по своей сути это вообще не кеш. Это хранилище настроек, для реализации которого почти идеально подходит иеющийся в Битриксе класс CPHPCache.
Забродин Роман написал: Так все таки в куку или в COption? Потому, что если в куку, то авторизовавшись на сайте в другом браузере или с другого компьютера (где нет той куки) пользователь получается, что не получит своих настроек?
Как работала панель настроек раньше? Все настройки неавторизованных пользователей записывались в виде отдельных куки в браузер. Все настройки авторизованных пользователей записывались в COption отдельными записями, чтобы могли применяться при авторизации с любого устройства. Это было указано в статье.
Как работает панель настроек сейчас? Все настройки неавторизованных пользователей записываются в кеш. Ключ от кеша записывается в браузер одной кукой. Все настройки авторизованных пользователей записываются в кеш. Ключ от кеша записывается в COption одной записью. Ключ от кеша сохраняется в куки или COption по такому же принципу, как и раньше. Без авторизации настройки не сохраняются при переходе на другое устройство. Авторизованный пользователь получает свои настройки при заходе с любого устройства.
Забродин Роман написал: А в каком конкретно файле компонентов происходит чтение этих параметров? На сколько я понимаю, исполнение этого файла никогда не должно кэшироваться?
В данный момент в Битронике 2 такое чтение параметров используется в шаблонах малой и большой корзин, которые никогда не кешируются, а также в шаблоне комплексного компонента новостей, который тоже не кешируется. Да, всё верно. Получается, что чтение кеша должно быть в некешируемой части. Пока что еще не было необходимости заниматься этим в кешируемых областях. Но даже в этом случае можно накинуть сверху тегирование кеша, чтобы это не было проблемой. Чуть больше труда разработчика = значительно легче жизнь администратора сайта.
Микулич Евгений написал: Ещё никогда я не был так согласен с Забродиным Романом.
А наш отдел разработки не согласен
По каждому из вопросов и замечаний был дан ответ. Надеюсь, что они были достаточно подробны и понятны.
Как всегда с нетерпением ждем следующей порции конструктивной критики, чтобы постараться развеять ваши сомнения, либо обнаружить что-то еще, что мы могли упустить из виду, и пролить в конечном счете свет на истину.
Морозов Артем написал: P.S. А почему я не могу удалить или отредактировать свой коммент ? О_О
владелец блога может сделать это за вас.
Морозов Артем написал: Ну я пока не вижу проблем, там в коде все достаточно логично просматривается. все разложено пополочкам.
Это не говорит ничего о том смогут ли ваш код понять потребители и/или другие разработчики. Это говорит лишь о том, что конкретно вы понимаете ваш код. Я вот тоже пару лет назад понял, что очень сильно оторвался от обычных редакторов контента и они зачастую меня просто не понимают.
В общем, моё дело - высказать опасения. Ваше дело их выслушать. =)
Задойный Алексей написал: Это не говорит ничего о том смогут ли ваш код понять потребители и/или другие разработчики. Это говорит лишь о том, что конкретно вы понимаете ваш код. Я вот тоже пару лет назад понял, что очень сильно оторвался от обычных редакторов контента и они зачастую меня просто не понимают.
Как сказал выше Роман Забродин нужно писать документацию, соответствующие таски уже поставлены и выполняются
Задойный Алексей написал: В общем, моё дело - высказать опасения. Ваше дело их выслушать. =)
Хм. А я тупо вынес параметры каталога в переменную, в отдельном файлике commonParams.php. Из минусов - редактирование параметров через визуальный редактор работает вероятно неожиданным образом. А остальное - как обычно. Нужна часть параметров - инклуд и по ключу массива. Ну а редактировать пхп код в редакторе изначально такая себе идея, тем более я часто использую константы для ид инфоблоков, из-за чего редактирование и так ломается.
В этой статье я собираюсь подробно обсудить с вами существующие в Битриксе статусы наличия товара; какие параметры торгового каталога, SKU, компонентов влияют на определение этих статусов, а также возможность покупки тех или иных товаров; и есть ли какие-нибудь недоработки в стандартных шаблонах и компонентах Битрикса, связанных с наличием товаров.
1. Статусы наличия товара Я думаю, ни для кого не секрет, что в Битриксе всего два статуса наличия товара: "Есть в наличии" и "Нет в наличии". И зависят эти статусы от трёх параметров торгового каталога:
Наличие на складе:
НЕТ
Выполнены ВСЕ три условия: Доступное количество <= 0 Количественный учёт — ДА Разрешена покупка при отсутствии товара — НЕТ
ДА
Все остальные случаи
Каждый администратор интернет-магазина и программист 1С-Битрикс должен знать эту простую формулу как 2х2. Мы можем положить товар в корзину и оформить вместе с ним заказ, только если его статус "В наличии". Отсутствующие товары купить нельзя. Но очень часто в интернет-магазинах можно встретить и другие статусы наличия, и сценарии покупки. Товар может отсутствовать в магазине в данный момент, но его уже заказали у поставщиков и везут в магазин. Обычно у таких товаров указывается примерная дата поступления в магазин, и его уже можно купить. Так же очень распространена покупка товаров "Под заказ". Обычно такие товары никогда не хранятся в магазине из-за больших габаритов, низкого спроса/оборота конкретной модели или ряда других причин, но при этом товар есть в наличии у поставщиков, с которыми работает торговая площадка. Такие товары доступны для покупки под заказ. Покупатель размещает заказ и оплачивает покупку, магазин заказывает товар у поставщика, после чего сразу пересылает его конечному покупателю. Поскольку два последних сценария не поддерживаются Битриксом из коробки, для их реализации нужны какие-либо дополнительные модули и модификация шаблонов. В Битриксе есть возможность подписки на отсутствующие товары: вы можете положить отсутствующий товар в корзину, где он попадёт в отдельную вкладку, а после появления этого товара на складе, пользователю будет отправлено уведомление на почту о том, что товар появился в магазине, и его можно купить. Это тоже довольно удобная и полезная вещь, но выполняет она несколько другую функцию.
В своей работе при разработке типовых решений часто сталкиваемся с клиентами, которым нужен сценарий покупки товаров "Под заказ". В типовом решении "Битроник" такой функционал был реализован с помощью создания в инфоблоке с каталогом отдельного свойства FOR_ORDER (Под заказ) в виде галочки. Если у товара отметить эту галочку, то его плашка со статусом наличия окрашивается в жёлтый цвет, а текст меняется на "под заказ". При добавлении поддержки такого статуса в типовое решение "Битроник 2" было решено отказаться от создания дополнительных сущностей и использовать уже имеющиеся в Битриксе стандартные параметры торгового каталога. Наиболее логичным нам представляется отображение статуса "Под заказ" в том случае, когда у товара включен количественный учет, доступное количество равно или меньше нулю, и разрешена покупка при отсутствии товара. Таким образом, у нас уже три статуса, которые зависят от параметров торгового каталога:
Статус товара:
Нет в наличии
Выполнены ВСЕ три условия: Доступное количество <= 0 Количественный учёт — ДА Разрешена покупка при отсутствии товара — НЕТ
Под заказ
Выполнены ВСЕ три условия: Доступное количество <= 0 Количественный учёт — ДА Разрешена покупка при отсутствии товара — ДА
В наличии
Все остальные случаи
Поскольку с точки зрения платформы такие товары имеют обычный статус СATALOG_AVAILABLE, они всегда отображаются в каталоге, их можно добавить в корзину и оформить заказ. Отличается статус только визуальной индикацией в шаблонах каталога. Также в обновлении 2.8.5 планируется добавить текст, который будет появляться при наведении курсора мыши на плашки со статусом "под заказ". Администратор сайта сможет редактировать этот текст и указать в нём сроки доставки или иную информацию о таких товарах.
Уважаемые коллеги, пожалуйста, напишите в комментариях, сталкивались ли вы в своей работе с необходимостью отображения дополнительных статусов товаров в интернет-магазинах на Битриксе, и как вы решали такие задачи. И нужно ли добавлять новые статусы наличия в стандартный функционал Битрикса, или эти задачи должны остаться на плечах разработчиков для Маркетплейса и решаться на уровне конкретных внедрений? Нам очень интересно узнать ваше мнение.
2. Зависимость статуса наличия от количества товара на отдельных складах. Начиная с версии 12.5 в Битриксе стало возможным создавать склады и заполнять имеющееся количество товара на каждом отдельном складе. При этом везде пишется, что количество товара на складах носит лишь информационный характер и не влияет на расчёт остатков товара и определения его наличия в магазине. Это действительно так, но только если не включен Складской учет. В отличие от обычного количественного учета складской учет нельзя включить или выключить для какого-либо отдельного товара. Этот функционал включается только для всего сайта целиком в настройках модуля Интернет-магазин. После включения функционала поля для редактирования как общего количества товара, так и количества товара на отдельных складах будут везде заблокированы. Изменять количество товара на складах можно будет только с помощью создания и проведения документов. Вместе с этим будет меняться и основное поле с общим количеством товара, которое и влияет на статус наличия товара. То есть, общее количество товара (СATALOG_QUANTITY) будет всегда равно сумме остатков по всем складам при постоянной работе складского учёта. Более подробно с этим функционалом можно познакомиться в учебных курсах: Количественный учет, Складской учет.
3. Когда в бой вступают торговые предложения (SKU). Появление в каталоге магазина товаров с торговыми предложениями несколько усложняет архитектуру каталога и понимание того, как, где и какие статусы наличия должны выводиться. Связано это с тем, что остаток товара и параметры количественного учёта в Битриксе можно задавать как у самого товара, так и у его отдельных торговых предложений. И даже если вы не видите вкладку "Торговый каталог" у основного товара, а лишь вкладку "Торговые предложения", эти значения всё равно будут вычисляться для основного товара отдельно. В последней заключительной третьей части этой статьи я постараюсь распутать этот клубок и вывести на чистую воду самые тёмные уголки стандартного шаблона Eshop для интернет-магазинов, который многие берут за основу при создании своих шаблонов.
Для начала рассмотрим небольшой пример, как отображались отсутствующие торговые предложения в предпоследней версии Eshop:
Как видим, отсутствующие товары имеют отличную индикацию. Но что делать, если мы не хотим отображать в списке отсутствующие товары? Для этого в комплексном компоненте bitrix:catalog имеется замечательный параметр "Не отображать товары, которых нет на складах" (HIDE_NOT_AVAILABLE).
После включения этой опции наблюдаем весьма странный и неожиданный результат:
Корректно отобразился только костюм "Огонь в ночи". У него исчезли те торговые предложения, которые мы не сможем купить, а сам товар остался в списке, потому что в его настройках мы отключили количественный учет. Остальные товары с торговыми предложениями исчезли из списка, хотя у них и имеются торговые предложения в наличии, потому что для самих товаров не заданы никакие параметры для определения их наличия. Так же мы отключили предварительно количественный учет для основного товара "Вечерний спорт", чтобы он остался в списке. Но у него нет в наличии ни одного из торговых предложений, поэтому шаблон начал считать, что это просто обычный товар и предлагает нам купить его, что по сути своей бессмысленно. Ещё больше нестыковок появляется, если сюда добавить использование фильтра:
По проблеме с фильтром и отсутствующими SKU 29.04.15 создали обращение в техподдержку 1С-Битрикс №623234, нам ответили, что опция HIDE_NOT_AVAILABLE пока что не работает с торговыми предложениями. На основе обращения была создана заявка в отдел разработки №47001. Больше никаких сообщений от отдела разработки с тех пор не приходило.
К счастью, хотя бы одну из этих проблем в Битрикс исправили в новом Eshop 15.5. Когда мы захотим скрыть отсутствующие товары, у товаров, чьих торговых предложений нет в наличии, не будет кнопки покупки.
Чтобы скрыть такой товар из списка нужно дополнительно зайти в настройки торгового каталога для этого отдельного товара, включить количественный учет, запретить покупку при отсутствии товара и выставить количество в 0. Но когда его торговые предложения снова появятся на складе, нужно заходить в настройки основного товара и снова отключать для него количественный учет, чтобы он появился в списке. Битрикс пока что не хочет брать на себя обязательства по автоматическому отслеживанию и синхронизации состояния наличия основного товара и его торговых предложений.
В некоторых случаях владельцы магазинов не хотят давать возможность покупки товара с торговыми предложениями в списке, а только с детальной страницы. Например, потому что этих характеристик очень много. Или же просто используется принципиально иной подход: торговые предложения выводятся в виде таблицы только на детальной странице товара. В таких случаях нужно скрыть кнопку покупки в списке, вывести минимальную цену из имеющихся у товара торговых предложений с пометкой "от …" и добавить пометку, что для покупки нужно перейти на детальную страницу. Как быть со статусом наличия товара в этом случае? При разработке своих шаблонов руководствуемся следующим принципом:
Если у товара есть хотя бы одно торговое предложение в наличии, ставим статус "В наличии". Если таких нет, но есть хотя бы одно торговое предложение со статусом "Под заказ", ставим аналогичный статус. Если все торговые предложения отсутствуют на складе, ставим статус "Нет в наличии".
Для того, чтобы обобщить всё вышесказанное про торговые предложения, я составил вот такую таблицу:
На данный момент самой большой проблемой остаётся тот факт, что товары с торговыми предложениями исчезают из списка, даже если торговые предложения есть в наличии, но главному товару мы задали отсутствие в настройках торгового каталога. На уровне шаблона с этим тяжело бороться, так как исчезают товары из $arResult ещё на этапе работы стандартных компонентов Битрикса.
Сколько времени понадобится Битриксу, чтобы исправить эту ситуацию, а так же починить работу фильтра для торговых предложений с одновременным скрытием отсутствующих товаров, нам неизвестно. Но мы как всегда верим, надеемся, ждём…
Жуков Евгений, Добрый день. Подскажите, не решена ли проблема с НЕ выводом товаров которых нет в наличии? Я что то не могу понять как это победить. Имеем товары с торговыми предложениями, и доступность у товаров НЕТ, и при наличии на складе товарных предложений и без их наличия... При настройке каталога ставим HIDE_NOT_AVAILABLE и конечно же пропадают все товары даже если есть в наличии торговые предложения))) не знаю понятно ли написал.... Всю голову сломал уже...
Симбирцев Игорь, нет такой проблемы. У вас настройка "Показывать вкладку Торговый каталог для товаров, имеющих торговые предложения" в модуле catalog (Торговый каталог) случаем не включена? Если да - это причина. Выясните, зачем. Если не нужна - выключите, переиндексируйте каталог (там же, в настройках модуля) и все должно работать. Если нужна - ну, тогда самим решать вопрос пересчета доступности (через обработчики событий)
Группы на сайте создаются не только сотрудниками «1С-Битрикс», но и партнерами компании. Поэтому мнения участников групп могут не совпадать с позицией компании «1С-Битрикс».