Адаптация существующих модулей и тем под CS-Cart 4.21.1¶
Изменения в ядре¶
Предстоящие изменения требований к версии PHP¶
Мы планируем повысить минимальную поддерживаемую версию PHP в ближайших релизах:
- Поддержка PHP 7 будет полностью прекращена. Минимальной поддерживаемой версией вероятнее всего станет PHP 8.0 (именно до этой версии необходимо повысить системные требования).
- Тем не менее, мы рекомендуем уже сейчас перейти на PHP 8.3. Это последняя версия PHP, которая в настоящее время поддерживается CS-Cart (поддержка была добавлена в версии 4.19.1).
- Одновременно с прекращением поддержки PHP 7 будет добавлена поддержка более новых версий PHP, включая PHP 8.5.
- Мы ожидаем, что после выхода версии CS-Cart с поддержкой PHP 8.5 многие владельцы магазинов захотят обновиться до этой версии PHP. Пожалуйста, учитывайте это при планировании разработки и развертывания своих решений.
Новый опциональный интерфейс для shipping-сервисов, предоставляющих возможность выбора ПВЗ¶
Добавлен новый интерфейс TyghShippingsIPickupPointsService. Вы можете реализовать его в своем shipping-сервисе, если хотите привести данные ПВЗ (пунктов выдачи заказов) к единому формату, описанному в классе TyghShippingsPickupPointsDtoPickupPoint.
Раньше shipping-сервисы, которые предоставляют возможность выбора ПВЗ, должны были реализовывать интерфейс TyghShippingsIPickupService. Так как изменение его методов сломало бы уже существующие сервисы, параллельно с ним добавлен новый интерфейс.
Зачем? Возникла необходимость унифицировать данные ПВЗ, что дает возможность:
- Не плодить большое количество шаблонов и контроллеров под каждый сервис доставки.
- Отображать все ПВЗ всех способов доставки в одном списке и на одной карте.
- Хранить полученные ПВЗ в одной таблице кэша, а не в сессии, как было ранее в некоторых сервисах (например, СДЭК и Самовывоз). Это дает большой прирост к производительности страниц, использующих список ПВЗ, в первую очередь - страницы оформления заказа.
По этим причинам создан новый интерфейс TyghShippingsIPickupPointsService, при этом старый остался для сохранения обратной совместимости.
Как работает новый интерфейс?¶
- Он требует реализовать в shipping-сервисе метод getPickupPointsLoader(): IPickupPointsLoaderByLocation, который должен вернуть объект класса-loader вашего shipping-сервиса, реализующего интерфейс TyghShippingsPickupPointsLoaderByLocationIPickupPointsLoaderByLocation.
- Интерфейс IPickupPointsLoaderByLocation, в свою очередь, предполагает, что в классе-loader вашего сервиса будет метод getPickupPointsByLocation(): PickupPoint[], который обязан вернуть список ПВЗ, каждый из которых является объектом класса TyghShippingsPickupPointsDtoPickupPoint.
- Дальше ядро само определяет, реализует ли ваш сервис новый интерфейс и, в зависимости от этого, принимает решение по какой логике получать список ПВЗ (старой или новой).
В целом, на этом все. Вы реализовываете метод, который может вернуть список ПВЗ в унифицированном виде, таким образом далее для работы со списком и его отображения можно использовать глобальные шаблоны. Например, если в будущем будет реализована карта с пунктами выдачи всех доступных способов доставки, ваши ПВЗ также попадут на эту карту. В противном случае - нет.
Из чего состоит объект PickupPoint?¶
Объект класса TyghShippingsPickupPointsDtoPickupPoint состоит из базовых полей ПВЗ, необходимых для отображения (город, адрес, координаты, время работы и т.п.). Также для хранения всей информации о ПВЗ, которую предоставляет API сервиса, предусмотрено отдельное поле $shipping_extra, туда в качестве массива нужно передавать все данные целиком.
Как кэшируется список ПВЗ?¶
Для кэширования предусмотрена таблица shipping_pickup_points. Она содержит столбцы, соответствующие полям в классе PickupPoint. На данный момент реализовано так, что каждый сервис реализует кеширование сам в своем loader-классе.
Функции для работы с таблицами кэширования находятся в TyghShippingsPickupPointsRepository.
- Перед запросом в API сервиса на получение списка ПВЗ из параметров запроса формируется cache_key, который равен hash(‘sha256’, implode(‘,’, $params)). Предварительно params должны быть отсортированы.
- С помощью метода findFreshPickupPointsSyncStates($provider, $cache_key) проверяется, есть ли свежеполученные ПВЗ. Свежими считаются те, что получены в течение текущих суток.
- Если есть, то список ПВЗ получаем методом findPickupPointsByProviderAndCacheKey($provider, $cache_key).
- Если нет, то: * Получаем список ПВЗ из API. * Циклом каждый элемент списка приводим к объекту PickupPoint. То есть создаем объект и записываем в него сеттерами все параметры. * Полученный список объектов PickupPoint записываем в таблицу кэша методом setPickupPointsByCacheKey($pickup_points, $cache_key). * Также в таблицу текущего состояния записываем новые данные с помощью метода setPickupPointSyncState.
Новые функции¶
fn_get_storefront_theme_manifest_features- Раздел “features” файла manifest.json активной темы витрины (кэшируется в рамках запроса).fn_is_storefront_theme_manifest_feature_enabled($feature)- Проверяет, включена ли булева возможность из раздела “features” файла manifest.json темы (значение свойства в JSON должно быть строго true).
Изменения в хуках¶
Новые хуки¶
fn_set_hook('get_pickup_points_for_checkout_pre', $cart, $pickup_points);- Выполняется перед получением списка ПВЗ для оформления заказа. Позволяет предотвратить дальнейшее выполнение кода, задав собственный список ПВЗ.fn_set_hook('get_pickup_points_for_checkout_post', $cart, $pickup_points);- Выполняется после получения списка ПВЗ для оформления заказа. Позволяет изменить данные в списке ПВЗ.fn_set_hook('get_checkout_pickup_points_loader_pre', $cart, $loader);- Выполняется перед получением загрузчика ПВЗ для оформления заказа. Позволяет использовать собственный загрузчик.fn_set_hook('get_checkout_pickup_points_loader_post', $cart, $loader);- Выполняется после получения загрузчика ПВЗ для оформления заказа. Позволяет изменить данные загрузчика.fn_set_hook('get_pickup_points_for_order_management_pre', $cart, $pickup_points);- Выполняется перед получением списка ПВЗ для управления заказом. Позволяет предотвратить дальнейшее выполнение кода, задав собственный список ПВЗ.fn_set_hook('get_pickup_points_for_order_management_post', $cart, $pickup_points);- Выполняется после получения списка ПВЗ для управления заказом. Позволяет изменить данные в списке ПВЗ.fn_set_hook('get_order_management_pickup_points_loader_pre', $cart, $loader);- Выполняется перед получением загрузчика ПВЗ для управления заказом. Позволяет использовать собственный загрузчик.fn_set_hook('get_order_management_pickup_points_loader_post', $cart, $loader);- Выполняется после получения загрузчика ПВЗ для управления заказом. Позволяет изменить данные загрузчика.fn_set_hook('get_pickup_points_for_order_pre', $order_info, $pickup_points);- Выполняется перед получением списка ПВЗ для заказа. Позволяет предотвратить дальнейшее выполнение кода, задав собственный список ПВЗ.fn_set_hook('get_pickup_points_for_order_post', $order_info, $pickup_points);- Выполняется после получения списка ПВЗ для заказа. Позволяет изменить данные в списке ПВЗ.fn_set_hook('get_order_pickup_points_loader_pre', $order_info, $loader);- Выполняется перед получением загрузчика ПВЗ для заказа. Позволяет использовать собственный загрузчик.fn_set_hook('get_order_pickup_points_loader_post', $order_info, $loader);- Выполняется после получения загрузчика ПВЗ для заказа. Позволяет изменить данные загрузчика.fn_set_hook('get_storefront_theme_manifest_features_post', $features);- Выполняется после загрузки раздела features файла manifest.json активной темы витрины.
Измененные хуки¶
- fn_set_hook('get_store_locations_for_shipping_before_select', $destination_id, $fields, $joins, $conditions, \Tygh\Shippings\Services\StoreLocator $this);
+ fn_set_hook('get_store_locations_for_shipping_before_select', $destination_id, $fields, $joins, $conditions, \Tygh\Shippings\PickupPoints\StoreLocatorPickupPointsByLocationLoader $this);
Измененные функции¶
- function fn_set_storage_data($key, $data = '', $allow_empty = false)
+ function fn_set_storage_data($key, $data = '', $allow_empty = false, $expires_at = null)
Изменения в модулях¶
Новые хуки¶
fn_set_hook('seo_get_schema_org_organization_markup_post', $storefront, $extra, $organization);- Выполняется при формировании JSON-LD-разметки Organization Schema.org для главной страницы витрины, до ее фильтрации в вызывающем коде.fn_set_hook('seo_get_schema_org_breadcrumb_list_markup_post', $breadcrumbs, $markup);- Выполняется при формировании JSON-LD-разметки BreadcrumbList Schema.org на основе хлебных крошек витрины, до ее фильтрации и вывода.
Витрина¶
Компонент Image Panel для размещения элементов на изображениях товаров¶
Новый компонент Image Panel предназначен для размещения кнопок и других элементов поверх изображения товара. По умолчанию такие кнопки отображаются в правом верхнем углу изображения товара. Используйте Image Panel, если вам необходимо добавить собственные кнопки или другие элементы управления поверх изображения товара.
Как это работает¶
Image Panel использует API, управляемый данными (data-driven API): вместо того чтобы вручную писать HTML для элементов поверх изображения, вы описываете их в виде элементов массива Smarty. Компонент самостоятельно отвечает за компоновку, позиционирование, сортировку и отрисовку.
common/product_data.tplперехватывает вывод Image Panel, если включен параметрshow_image_panel.views/products/components/image_panel_data.tpl` формирует массив ``$image_panel_itemsи предоставляет шаблонный хукproducts:image_panelдля расширений.views/products/components/image_panel_process.tplсортирует элементы внутри каждого угла.views/products/components/image_panel.tplвыполняет отрисовку панели.
Каждый элемент размещается в одном из четырех углов:
top_lefttop_rightbottom_leftbottom_right
Расширение Image Panel в модуле¶
Добавьте элементы в массив $image_panel_items в шаблонном хуке products:image_panel.
Пример
design/themes/responsive/templates/addons/wishlist/hooks/products/image_panel.post.tpl
{strip}
{if !$hide_wishlist_button && $show_wishlist_button_on_image_panel}
{$image_panel_items.top_right.add_to_wishlist = [
type => "a",
insert_before_id => "add_to_compare",
id => "button_wishlist_`$obj_prefix``$product.product_id`",
class => "ty-btn ty-btn__tertiary ty-btn-icon ty-add-to-wish cm-submit",
title => __("add_to_wishlist"),
icon => "ty-icon-heart",
element_attrs => [
"data-ca-dispatch" => "dispatch[wishlist.add..`$product.product_id`]"
]
]}
{/if}
{$image_panel_items = $image_panel_items scope=parent}
{/strip}
Важно
- После изменения массива обязательно экспортируйте его обратно в родительскую область видимости:
{$image_panel_items = $image_panel_items scope=parent}. - Используйте уникальный ключ элемента (например,
add_to_wishlist). Этот ключ используется для определения порядка отображения элемента и формирования CSS-классов. - Перед добавлением элемента проверяйте флаги видимости, такие как
$show_wishlist_button_on_image_panelи$hide_wishlist_button.
Структура данных элемента¶
Добавляйте элементы в массив $image_panel_items, используя ключи, соответствующие углам. Для каждого угла используется ассоциативный массив элементов.
Общие поля
| Поле | Описание |
|---|---|
type |
Тип элемента: button, a или div. Если поле не указано, используется a при наличии href; иначе - div. |
id |
HTML-атрибут id. |
name |
HTML-атрибут name. |
title |
HTML-атрибут title. |
href |
URL ссылки. Обрабатывается функцией fn_url. |
class |
CSS-классы элемента. |
text |
Текстовое содержимое элемента. |
icon |
Имя иконки, передаваемое в шаблон common/icon.tpl. |
icon_class |
Дополнительные CSS-классы иконки. |
icon_id |
HTML-атрибут id иконки. |
icon_title |
HTML-атрибут title иконки. |
icon_text |
Текстовое содержимое иконки. |
icon_data |
Массив дополнительных данных иконки. |
ajax |
Если значение равно true, элементу добавляется CSS-класс cm-ajax. |
full_render |
Если значение равно true, элементу добавляется CSS-класс cm-ajax-full-render. |
element_attrs |
Ассоциативный массив дополнительных HTML-атрибутов элемента (rel, data-ca-target-id, и т.д.). |
wrapper_attrs |
Ассоциативный массив HTML-атрибутов контейнера элемента. |
content |
HTML-содержимое элемента. |
insert_before_id |
Ключ элемента, перед которым необходимо разместить текущий элемент. |
insert_after_id |
Ключ элемента, после которого необходимо разместить текущий элемент. |
file |
Путь к пользовательскому шаблону. Если указан, компонент подключает этот шаблон вместо автоматической отрисовки элемента. |
Отрисовка с использованием пользовательского шаблона
Если для элемента требуется нестандартная разметка, задайте параметр file и создайте шаблон, которому будут переданы переменные $item и $item_id:
{$image_panel_items.top_left.my_addon_button = [
file => "addons/my_addon/views/products/components/my_image_panel_button.tpl"
]}
design/themes/responsive/templates/addons/my_addon/views/products/components/my_image_panel_button.tpl
{* $item and $item_id are provided by Image Panel *}
<div class="my-addon-image-panel-button">
{* custom markup *}
</div>