Important
There are a few differences between CS-Cart 4.18.1 Beta and the final release. See the differences below.
// Old:
function fn_filter_uploaded_data($name, array $filter_by_ext = [], $show_default_error_notifications = true, $sanitaze_filename = true)
// New:
function fn_filter_uploaded_data($name, array $filter_by_ext = [], $show_default_error_notifications = true, $sanitaze_filename = true, $filter_by_file_size_bytes = false)
// Old:
function fn_check_uploaded_data(array $uploaded_data, array $filter_by_ext)
// New:
function fn_check_uploaded_data(array $uploaded_data, array $filter_by_ext, $filter_by_file_size_bytes = false)
Gets language direction:
\Tygh\Template\IContext::getLanguageDirection()
Gets language direction:
\Tygh\Template\Snippet\Table\ItemContext::getLanguageDirection()
Gets language direction:
\Tygh\Template\Mail\Context::getLanguageDirection()
Gets language direction:
\Tygh\Template\Internal\Context::getLanguageDirection()
Gets language direction:
\Tygh\Template\Document\Order\Context::getLanguageDirection()
The dynamic actions $navigation.dynamic.actions
display is updated. They are now shown in the right upper corner of the page. From now on, dynamic actions are the preferred interface elements for displaying actions and subpages. Dynamic actions appear as buttons. When there are multiple dynamic actions, some of them are displayed in a drop-down menu.
Dynamic actions requirements:
app/addons/my_changes/controllers/backend/products.post.php
<?php
use Tygh\ Registry;
defined('BOOTSTRAP') or die('Access denied');
if ($mode === 'manage') {
Registry::set('navigation.dynamic.actions', [
'my_changes.test_button' => [
'href' => 'categories.manage',
'text' => __('my_changes.view_my_changes'),
]
]);
}
Full list of available options is in the Dynamic actions in the header of the site section.
The dynamic sections $navigation.dynamic.sections
have been deprecated. Use dynamic actions instead.
Gear buttons in the right upper corner of the page have been deprecated. Use dynamic actions instead. Please note that dynamic actions can appear both as standalone buttons and as items in the dropdown menu.
Search filters on the product list page (?dispatch=products.manage) are now set using an array. Use the products:search_data
hook to extend it. For example, to add a text field, use hook:
design/backend/templates/addons/my_changes/hooks/products/search_data.post.tpl
{$search_filters.data.my_changes_filter = [
id => "my_changes_filter",
type => "input",
category => "secondary",
label => __("my_changes_filter"),
value => $search.my_changes_filter_value,
placeholder => __("my_changes_filter_placeholder")
]}
{* Export *}
{$search_filters = $search_filters scope=parent}
Hooks products:simple_search
, companies:products_advanced_search
, products:search_form
, products:search_in_orders
and products:advanced_search
for extending the products list page have been deprecated. The products:select_search
hook have been deprecated, use the products:sort_by_content
hook instead.
The example of connecting search filters can be found in the Search filters on the product list page section.
To display saved searches, use the saved_search
parameter. An example of saved searches for a product list page:
design/backend/templates/views/products/manage.tpl
{$search_form_dispatch = $dispatch|default:"products.manage"}
{$saved_search = [
dispatch => $search_form_dispatch,
view_type => "products"
]}
{include file="common/mainbox.tpl"
...
saved_search=$saved_search
}
Now extending Dashboard analytics blocks should be done through a schema.
app/addons/my_changes/schemas/dashboard/blocks.post.php
<?php
use Tygh\Enum\DashboardSections;
defined('BOOTSTRAP') or die('Access denied');
$schema[DashboardSections::TERTIARY]['my_changes'] = [
'id' => 'my_changes',
'title' => __('my_changes.dashboard.my_changes'),
'position' => 100,
'dispatch' => 'products.manage',
'content_data_function' => 'fn_my_changes_get_dashboard_block_data'
];
return $schema;
app/addons/my_changes/func.php
<?php
if (!defined('BOOTSTRAP')) { die('Access denied'); }
function fn_my_changes_get_dashboard_block_data()
{
$content_data = [
'id' => 'my_changes',
'title' => __('my_changes.dashboard.title'),
'title_button' => [
'href' => 'products.manage',
'name' => __('my_changes.dashboard.title_button'),
],
'number' => 1234,
];
return $content_data;
}
See the full list of available parameters in the Analytics card for Dashboard section.
You can expand the content of existing blocks using the get_dashboard_XXX
hooks. Refer to the New Hooks section for a list of all hooks and their descriptions.
The Setup wizard has been deprecated. Use the Settings tab of your add-on instead. Learn more about scheme 3.0 structure.
Icons must now be connected through the component common/icon.tpl
. Other methods are considered deprecated and will no longer work. The Font Awesome icon library has been replaced with CS-Cart’s custom icons. Now, instead of an icon font, vector SVG icons are used. Connection parameters for icons have changed. Connecting icons using the class
parameter (e.g., class="icon-warning-sign"
) is deprecated. It is necessary to use the source
parameter (e.g., source="warning_sign"
) with a value in snake_case and without the icon-
prefix. See the example of connecting an icon in SVG icons section.
Top and central menu are now displayed on the left. Consequently, the available width for displaying page content has decreased. Please check the display of your pages on small screens.
The width restriction for page display has been removed. Now, the site is displayed across the entire available width of the window. Please check the appearance of interface elements on large screens.
Some Less style variables (colors, sizes, etc.) have been modified or removed. Now, CS-Cart’s Less-variables align with Bootstrap 2’s.
Instead of hardcoding values in styles, use Less variables and CSS custom properties from css/config.less
for styles in your add-ons. For obtaining other values, utilize Less functions. For example, functions like spin(desaturate(lighten(@textColor, 30%), 25%), -15%)
create the Text muted color. For more information about lessphp and Less, refer to their documentation. For details on removed Less variables, see Deleted style variables section.
fn_master_products_generate_navigation_sections
Executes after getting dashboard block data, allows editing it:
fn_set_hook('get_dashboard_block_data', $content_data, $this);
Executes after filling content information for block with sales statistics, allows editing it:
fn_set_hook('get_dashboard_sales_block_data', $content_data, $this);
Executes after filling content information for block with products statistics, allows editing it:
fn_set_hook('get_dashboard_products_block_data', $content_data, $this);
Executes after filling content information for block with orders statistics, allows editing it:
fn_set_hook('get_dashboard_orders_block_data', $content_data, $this);
Executes after filling content information for block with orders by statuses statistics, allows editing it:
fn_set_hook('get_dashboard_orders_by_statuses_block_data', $content_data, $this);
Executes after filling content information for block with vendor balance, allows editing it:
fn_set_hook('get_dashboard_vendor_balance_block_data', $content_data, $this);
Executes after filling content information for block with vendor activity statistics, allows editing it:
fn_set_hook('get_dashboard_vendor_with_sales_block_data', $content_data, $this);
Executes after filling content information for block with companies or vendors statistics, allows editing it:
fn_set_hook('get_dashboard_stores_block_data', $content_data, $this);
Executes after filling content information for block with users statistics, allows editing it:
fn_set_hook('get_dashboard_customers_block_data', $content_data, $this);
Executes after filling content information for block with last logs, allows editing it:
fn_set_hook('get_dashboard_logs_block_data', $content_data, $this);
Executes when changing order status before products are recalculated:
fn_set_hook('change_order_status_pre', $order_id, $status_to, $status_from, $force_notification, $place_order, $order_info, $allow_status_update);
Executes after updating data about the availability of products in warehouses:
fn_set_hook('warehouses_recalculate_destination_products_stocks', $this, $params, $product_condition);
Executes after deleting product stocks:
fn_set_hook('warehouses_remove_product_stocks_post', $this, $product_id);
Executes before updating/creating a banner:
fn_set_hook('banners_update_banner_pre', $data, $banner_id, $lang_code);
// Old:
fn_set_hook('create_order_details', $order_id, $cart, $order_details, $extra);
// New:
fn_set_hook('create_order_details', $order_id, $cart, $order_details, $extra, $k, $v);
// Old:
fn_set_hook('add_to_cart', $cart, $product_id, $_id);
// New:
fn_set_hook('add_to_cart', $cart, $product_id, $_id, $_data);
// Old:
fn_set_hook('filter_uploaded_data_post', $name, $filter_by_ext, $filtered, $udata_local, $udata_other, $utype);
// New:
fn_set_hook('filter_uploaded_data_post', $name, $filter_by_ext, $filtered, $udata_local, $udata_other, $utype, $filter_by_file_size_bytes);
// Old:
fn_set_hook('check_uploaded_data_pre', $uploaded_data, $filter_by_ext, $result, $processed);
// New:
fn_set_hook('check_uploaded_data_pre', $uploaded_data, $filter_by_ext, $result, $processed, $filter_by_file_size_bytes);
// Old:
fn_set_hook('check_uploaded_data_post', $uploaded_data, $filter_by_ext, $result, $processed);
// New:
fn_set_hook('check_uploaded_data_post', $uploaded_data, $filter_by_ext, $result, $processed, $filter_by_file_size_bytes);
Template: design/backend/templates/components/menu/actions_menu.tpl
Dynamic actions are displayed as buttons. If there are many buttons, some of them are displayed as a dropdown menu. The properties correspond to the {btn}
helper from buttons/helpers.tpl
, plus an additional parameter wrapper_class
. The default type used is text
. The usage of dynamic actions is described in The display of dynamic actions is updated section.
Example usage:
app/addons/my_changes/schemas/menu/actions.post.php
<?php
defined('BOOTSTRAP') or die('Access denied');
/** @var array $schema */
$schema['my_changes.manage']['my_changes.test_button'] = [
'href' => 'categories.manage',
'text' => __('my_changes.actions.view_my_changes'),
'text_mobile' => __('my_changes.actions.view_my_changes_mobile'),
'id' => 'my_changes_id',
'class' => 'my-changes-class',
'data' => [
'data-ca-my-changes-param-1' => 'my_value_1',
'data-ca-my-changes-param-2' => 'my_value_2',
],
'wrapper_class' => 'my-changes-wrapper-class',
'position' => 100
];
return $schema;
Available parameters:
type
href
text
. If the parameter is unavailable, the language variable of the array key is used (up to 30 characters).text_mobile
. If the parameter is unavailable, the text
is used (up to 20 characters).title
id
class
meta
dispatch
form
method
target
target_id
process
onclick
icon
data
wrapper_class
Template: views/products/components/search_filters/get_product_search_filters.tpl
Usage
design/backend/templates/addons/my_changes/hooks/products/search_data.post.tpl
{$search_filters.data.my_changes_filter = [
id => "my_changes_filter",
type => "input",
category => "secondary",
label => __("my_changes_filter"),
value => $search.my_changes_filter_value,
placeholder => __("my_changes_filter_placeholder"),
is_enabled => true,
is_hidden => false,
content => "HTML content",
data => [
name_from => "my_changes_filter_from",
value_from => $search.my_changes_filter_from,
label_from => __("my_changes_filter_from"),
name_to => "my_changes_filter_to",
value_to => $search.my_changes_filter_to,
label_to => __("my_changes_filter_to")
],
nested_data => [
my_changes_filter_param => [
key => "my_changes_filter_param",
label => __("my_changes_filter_param"),
value => true,
is_checked => ($search.my_changes_filter_param === "YesNo::YES"|enum)
]
]
]}
{* Export *}
{$search_filters = $search_filters scope=parent}
where:
Parameter | Type | Description or values |
---|---|---|
id | String | Search filter ID. |
type | Enum | Optional. Search filter type.
input (default)range radio checkbox dropdown popup |
category | Enum | Optional. Display the search filter in the Add filter menu or display it always.
secondary (default)primary |
priority | Number | Optional. It is necessary for context search only. Set the priority for contextual search. |
label | String | Search filter label. |
value | String | Optional. Search filter value. |
placeholder | String | Optional. Search filter placeholder. |
is_enabled | Boolean | A boolean value to determine whether the search filter should be render or not. |
is_hidden | Boolean | Optional. A boolean value to determine whether the search filter should be display or not. In this case, the render will be executed. |
content | String | Optional. HTML content for dropdown and popup types, or hidden props. |
data | String | Optional. Required for the range type. Use name_from , value_from , label_from , name_to , value_to , or label_to props for name attribute, value, and label for “From” and “To” fields. |
nested_data | String | Optional. Required for the checkbox and radio types. Use key , label , value , and is_checked props for ID, label, value and checked attribute. |
Examples of extensions
addons/tags/hooks/products/search_data.post.tpl
addons/bestsellers/hooks/products/search_data.post.tpl
addons/ebay/hooks/products/search_data.post.tpl
addons/product_variations/hooks/products/search_data.post.tpl
Example of an array of product search filters: views/products/components/search_filters/get_product_search_filters.tpl
.
The contextual search text field situated next to the saved search can be changed on the products list page.
Usage
addons/my_changes/hooks/products/search_data.post.tpl
For example:
{$search_filters.my_changes_query = [
id => "my_changes_query",
type => "input",
category => "primary",
label => __("search_my_changes"),
value => $search.my_changes_query,
priority => 1000
]}
{* Export *}
{$search_filters = $search_filters scope=parent}
For contextual search, a type
equal to input
is required. The field with the largest priority will be displayed in the context search. The rest of the search fields will be displayed in the search filter. The standard field Search products has 100 priority.
Template: views/index/components/analytics_section/analytics_card/analytics_card.tpl
Usage
The usage of the analytics card for the Dashboard is described in Extending Dashboard analytics blocks through template hooks has been deprecated section.
Example usage:
app/addons/my_changes/schemas/dashboard/blocks.post.php
<?php
use Tygh\Enum\DashboardSections;
defined('BOOTSTRAP') or die('Access denied');
$schema[DashboardSections::TERTIARY]['my_changes'] = [
'id' => 'my_changes',
'title' => __('my_changes.dashboard.my_changes'),
'position' => 100,
'dispatch' => 'products.manage',
'content_data_function' => 'fn_my_changes_get_dashboard_block_data'
];
return $schema;
app/addons/my_changes/func.php
<?php
if (!defined('BOOTSTRAP')) { die('Access denied'); }
function fn_my_changes_get_dashboard_block_data()
{
$content_data = [
'id' => 'my_changes',
'preheader' => __('my_changes.dashboard.preheader'),
'is_selected_date' => false,
'title' => __('my_changes.dashboard.title'),
'title_button' => [
'href' => 'products.manage',
'name' => __('my_changes.dashboard.title_button'),
],
'number' => 1234,
'number_dynamics' => 15,
'use_price_for_number' => false,
'content' => [
'<strong>Hello</strong>',
'<em>world!</em>',
],
'content_tpl' => [
'addons/my_changes/views/my_changes/components/my_changes_component.tpl'
],
'buttons' => [
'button_1' => [
'name' => __('my_changes.dashboard.button_1'),
'href' => 'products.manage',
'class' => 'my-changes-button-1',
],
],
'graph' => [
'content' => [
[
'date' => '2024, (0-0), 30',
'prev' => 150,
'cur' => 200
],
[
'date' => '2024, (0-0), 31',
'prev' => 160,
'cur' => 300,
],
]
],
'bar_chart' => [
'id' => 'bar_chart',
'title' => __('my_changes.dashboard.bar_chart'),
'content' => [
[
'id' => 'bar_1',
'name' => __('products'),
'href' => 'products.manage',
'type' => 'primary',
'value' => 10,
'is_price' => false,
'total' => 100,
'ratio' => 10,
],
[
'id' => 'bar_1',
'name' => __('categories'),
'href' => 'categories.manage',
'value' => 70,
'is_price' => false,
'total' => 100,
'ratio' => 70,
],
]
],
'resource_list' => [
'title' => __('my_changes.dashboard.resource_list'),
'content' => [
[
'id' => 'resource_list',
'href' => 'products.manage',
'name' => __("my_changes.dashboard.resource_list_name"),
'label_text' => __("my_changes.dashboard.resource_list_label_text"),
'label_class' => 'my-changes-resource-list',
'value_href' => 'products.manage',
'value' => '100',
'use_price_for_value' => false,
'description' => __("my_changes.dashboard.resource_list_description"),
'description_href' => 'products.manage',
'small_text' => __("my_changes.dashboard.resource_list_small_text"),
// 'image' => [],
]
]
],
'resource_list_tabs' => [
'id' => 'resource_list_tabs',
'content' => [
'resource_list_tabs_1' => [
'id' => 'resource_list_tabs_1',
'title' => __('resource_list_tabs_1'),
'content' => [
// Same thing as $content_data['resource_list']['content']
]
],
]
],
'scripts' => [
'js/addons/my_changes/func.js'
],
];
return $content_data;
}
design/backend/templates/addons/my_changes/views/my_changes/components/my_changes_component.tpl
<h3>My changes test</h3>
js/addons/my_changes/func.js
Template: common/icon.tpl
Usage
{include_ext file="common/icon.tpl"
source="warning_sign"
tone="warning"
color="#f00"
accessibility_label="No user"
show_icon=$is_show_user_require_warning_icon
class="user-require-warning"
id="user_warning_icon"
render="inline"
data=[
"data-ca-param-1" => "value_1",
"data-ca-param-2" => "value_2"
]
}
where:
Parameter | Type | Description or values |
---|---|---|
source | String | The SVG contents (icon name (warning_sign ), icon path (addons/my_changes/icons/my_icon.svg) or <svg>...</svg> source) to display in the icon (icons should fit in a 20 × 20 pixel viewBox). Use snake_case without the icon- prefix. The available icons can be viewed in the design/backend/template/icons/ directory. You can connect custom icons by specifying the icon path. |
tone | Enum | Optional
base muted error interactive info success primary text_warning text_error text_info text_success |
accessibility_label | String | Optional. Descriptive text to be read to screenreaders. |
color | String | Optional. The fill attribute of the <svg> tag for setting a custom icon color. |
show_icon | Boolean | Optional. A boolean value that determines whether the icon should be displayed. |
class | String | Optional. CSS class of an icon. |
id | String | A unique icon ID. |
data | Array | An array of HTML attributes of the icon. |
render | Enum | Render the icon as an inline
<svg> tag or connect as an external <img src="..."> image.inline (default)img_data |
Deprecated parameters
Parameter | Type | Description or values |
---|---|---|
title | String | Deprecated. Optional. A hint for the icon. Now it is recommended to set the hints at a higher level. For example, to set suggestions for buttons containing such icons. For accessibility, use accessibility_label . |
icon_text | String | Deprecated. Optional. The text for the icon. Use accessibility_label for accessibility. |
Using custom icons
To display a custom icon, pass the path of the SVG icon to the source
parameter. For example:
{include_ext file="common/icon.tpl" source="addons/my_changes/icons/my_icon.svg"}
where:
design/backend/templates/addons/my_changes/icons/my_icon.svg
<svg viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path d="m0 0h20v20h-20z"/></svg>
SVG icons should fit in a 20x20 pixel viewBox.
Template: common/select_object.tpl
The value of the style
parameter for accordion
has been removed. Please use one of the following parameters: dropdown
, graphic
, or field
.
Template: common/tabsbox.tpl
Now you have the option to display tabs navigation in the top navigation. To achieve this, add the parameter show_tabs_navigation=false
when including the common/tabsbox.tpl
template. Also, pass the parameter tabs_navigation=$tabs_navigation
when including the common/mainbox.tpl
template. Example of a tabs navigation in the top navigation: views/products/update.tpl
.
index:head
menu:top_bar_right
banners:status
index:analytics_data
: use dashboard/blocks
schema instead.products:action_buttons
: use dynamic actions instead.products:simple_search
on the product list: use products:search_data
instead.companies:products_advanced_search
on the product list: use products:search_data
instead.products:search_form
on the product list: use products:search_data
instead.products:search_in_orders
on the product list: use products:search_data
instead.products:advanced_search
on the product list: use products:search_data
instead.products:select_search
on the product list: use products:sort_by_content
instead.enable_sticky_scroll
navigation_accordion
vendor_data_premoderation
: vendor_data_premoderation
vendor_plans
: plan_usage
and plan_data
@wide-width
: use var(--content-width)
instead.@mainSidebarWidth
: use var(--sidebar-width)
instead.@mainSidebarThinWidth
: use 50px
instead.@headerOffset
: use 89px
instead.@textMutedColor
: use spin(desaturate(lighten(@textColor, 30%), 25%), -15%)
instead.@mainSidebarBackgroundColor
: use #333940
instead.@topPanelBackground
: use #f9f9f9
instead.@topPanelTextColorLight
: use #daedf7
instead.@topPanelDropdownBackgroundColor
: use #4c6b8a
instead.@topPanelDropdownTextColor
: use #272b31
instead.@brandFontColor
: use #fff
instead.@brandFontWeight
: use 500
instead.@topPanelMenuBackgroundStart
: use @mainColor
instead.@topPanelMenuBackgroundEnd
: use @mainColor
instead.@topPanelMenuBackgroundHoverStart
: use @mainColor
instead.@topPanelMenuBackgroundHoverEnd
: use @mainColor
instead.@topPanelMenuBackgroundActiveStart
: use @mainColor
instead.@topPanelMenuBackgroundActiveEnd
: use @mainColor
instead.@topPanelMenuBackgroundDisabled
: use @gray
instead.@topPanelMenuCaret
: use #fff
instead.@topPanelMenuDividerLeft
: use transparent
instead.@topPanelMenuDividerRight
: use transparent
instead.@topPanelBoxShadow
: use 0 1px 4px rgba(0,0,0,0.1)
instead.@successColor
: use @btnSuccessBackground
instead.@mutedBackground
: use #f7f7f9
instead.@mutedBorder
use #e1e1e8
instead.@btnPrimaryText
: use #daedf7
instead.@btnPrimaryBackgroundBorder
: use @btnPrimaryBackground
instead.@successButton
: use @btnSuccessBackground
instead.@textButtonColor
: use @btnPrimaryBackground
instead.@textButtonCaretColor
: use #1010107b
instead.@tabsBackgroundColor
: use #f4f3f3
instead.@tabsActiveBackgroundColor
: use @mainColor
instead.@extraIconsSprite
: use url(../media/images/exicons.png)
instead.@extraIconsSpriteWhite
: use url(../media/images/exicons_white.png)
instead.@zIndexPopup
: use 1500
instead.btn-text
: use btn-link
instead.Since the release of the Beta, we’ve made some changes to CS-Cart 4.18.1. The document above has already been updated accordingly. This section is for those who used an older version of the document; it covers what has changed.
This part of the Gear buttons have been deprecated section has been changed completely and is not relevant:
Gear buttons on the list of objects have been deprecated (for example, on the product list page). To perform the actions, use the Context menu. The appearance of gear buttons on the list of products and orders has changed (hooksproducts:list_extra_links
andorders:list_extra_links
).
This part of the Search filter extension through product list page template deprecated has been changed and is not relevant:
Search filters on the product list are now set using an array. Use the
products:search_data
hook to extend it.
Instead, a new search filter is now only on the products list page (?dispatch=products.manage). For example, it is not used when you add a product while creating an order.
my_changes_filter
now needs to be placed in $search_filters.data
instead of $search_filters
. You should use the parameter category => "secondary"
.The following changes in the Dynamic actions in the header of the site section have been made:
text
.schemas
, not controllers
.text
parameter up to 30 characters in length.text_mobile
parameter up to 20 characters in length.raw
parameter is not available anymore.The following changes in the Search filters on the product list page section have been made:
get_product_search_filters.tpl
is used instead of products_search_form.tpl
.$search_filters
, now use the sub-array $search_filters.data
.The following changes in the Context search section have been made:
Now there is no need to include context_search.tpl
in your template and pass the parameter to common/mainbox.tpl
. It is enough to hook into addons/my_changes/hooks/products/search_data.post.tpl
, create an array {$search_filters.my_changes_query = [ ... ]}
and export $search_filters
.
Questions & Feedback
Have any questions that weren't answered here? Need help with solving a problem in your online store? Want to report a bug in our software? Find out how to contact us.