Developer guide
Back to overview · Previous: Usage · Next: FAQ
app/addons/kv_product_labels_stickers/ addon.xml, init.php, func.php Tygh/Addons/KvProductLabelsStickers/Badge.php options, normalization, CSS classes, placeholders Tygh/Addons/KvProductLabelsStickers/RuleEngine.php cached badge loading and batch rule evaluation Tygh/Addons/KvProductLabelsStickers/Presets.php the preset gallery and the demo set controllers/backend/kv_product_labels_stickers.php list, editor, presets, bulk tools (admin + vendor panel) controllers/backend/products.post.php the "Labels" product tab controllers/backend/kv_product_labels_stickers_license.php "Check now" / cron license check Tygh/Addons/KvProductLabelsStickers/License/Client.php license check client (generated from the shared Kavio Labs template) Tygh/Addons/KvProductLabelsStickers/Upgrade/Synchronizer.php self-healing in-place upgrades schemas/menu/menu.post.php, menu_vendor.post.php schemas/permissions/admin.post.php (view_catalog / manage_catalog), vendor_multivendor.post.php schemas/exim/products.post.php + products.functions.php the "Product labels" column schemas/block_manager/block_cache_properties.post.php block cache invalidation, license state in the cache keyvar/themes_repository/responsive/templates/addons/kv_product_labels_stickers/ hooks/products/product_data.post.tpl injects the overlay into the theme's label capture hooks/index/styles.post.tpl, scripts.post.tpl components/badges.tpl, badge.tpl, icon.tplvar/themes_repository/responsive/css/addons/kv_product_labels_stickers/styles.lessjs/addons/kv_product_labels_stickers/func.js storefront: fits the product page overlay to the main imagejs/addons/kv_product_labels_stickers/backend.js admin: live preview, rule blocks, feature variantsdesign/backend/... admin templates and styles (license/info.tpl: License tab)Data model
Section titled “Data model”| Table | Columns |
|---|---|
cscart_kv_pls_badges |
badge_id, company_id (0 = admin badge, otherwise the Multi-Vendor vendor), status, position, badge_type (text/image), shape, placement, size, color_mode, bg_color, text_color, effect, font, text_style, icon, image_width, show_in (B/L/P), date_from, date_to, rule_match (A = all, O = any), conditions (JSON), preset, timestamps |
cscart_kv_pls_badge_descriptions |
badge_id, lang_code, name, text |
cscart_kv_pls_badge_products |
badge_id, product_id (manual assignment; indexed by product) |
Graphic badges are stored as CS-Cart image pairs with the object type kv_pls_badge.
Example conditions:
{"discount":{"min":20,"max":0},"categories":{"ids":[166,170],"subcats":true},"feature":{"feature_id":18,"variant_ids":[29]}}The keys are discount, new, stock, price, free_shipping, bestseller, categories, feature and vendors. Category IDs are expanded with their subcategories when badges are loaded.
How badges reach the storefront
Section titled “How badges reach the storefront”- PHP hook
gather_additional_products_data_post. For storefront requests,RuleEngine::apply()addskv_pls_badges(a ready-to-render list) to every product of the list. Discounts are already calculated at that point. - Template hook
products:product_data(post). This is the last hook incommon/product_data.tpl. Core builds theproduct_labels_<obj_prefix><obj_id>capture there, and every core list, the product page and quick view print it inside the image container. The hook prepends our overlay to that capture. No core template is overridden. - The theme labels setting. Hide the discount label adds a marker class. The CSS rule
.kv-pls--hide-theme-discount ~ .ty-product-labels .ty-product-labels__item--discounthides the theme’s discount label. Hide all theme labels drops the theme’s labels from the capture.
The product page is detected by products.view / products.quick_view with the requested product_id. There the overlay gets kv-pls--detail, and func.js fits it to .cm-preview-wrapper.
Performance and caching
Section titled “Performance and caching”- Active badges, with their texts, images, product counts and expanded categories, are cached per language in the Registry cache (
kv_pls_badges_<lang>). The cache is invalidated automatically whenkv_pls_*,images,images_linksorcategorieschange. - Per product list,
RuleEngine::collectFacts()runs at most these batch queries, and only when an active badge needs them:products(by primary key): for new, stock, vendor, free shipping and vendor badges;products_categories: for category rules;product_features_values: for feature rules;kv_pls_badge_products: only for badges that have manual products.
- Bestseller counts come from one aggregate query over paid orders per period, cached for the configured time (
Registry::cacheLevel('time')). - Block cache: our tables are added to the global
update_handlers. A callable handler (fn_kv_product_labels_stickers_get_schedule_cache_key) changes the cache key when a scheduled badge starts or ends, and another one (fn_kv_product_labels_stickers_is_licensed) when the license state changes.
License check
Section titled “License check”Tygh\Addons\KvProductLabelsStickers\License\Client verifies the license against the Kavio Labs license server.
fn_kv_product_labels_stickers_is_licensed()is the storefront gate. When it returnsfalse,fn_kv_product_labels_stickers_is_enabled()returnsfalse, sogather_additional_products_data_postadds neitherkv_pls_badgesnor thekv_pls_onflag, andhooks/products/product_data.post.tpl(which reads only that flag, never an add-on function) leaves the theme’s label capture untouched (no overlay, Theme’s own product labels not applied). It reads the stored state only (one storage read per request) and never contacts the server.- The admin and vendor badge editor, the product tab, import/export and the data are not gated.
- Product lists and product pages are printed inside blocks that CS-Cart may cache. The license state is part of every block cache key (
block_cache_properties.post.php,callable_handlerskv_pls_license), so badges appear or disappear at once. Client::boot()(init.php) registers abefore_dispatchhandler for the admin area and the console only. On admin page views and console requests it runs the check when it is due (key changed, or 24 hours after the last check; 1 hour after a failure) and shows the admin notice once per session.- Admin license UI (generated): the License card at the top of the add-on page (
license/card.tplthrough theaddons:tabs_contentpre hook), the badge in Add-ons > Manage (license/badge.tpl,addons:managepost hook), the status bar (license/status_bar.tpl, first line inside the mainbox capture ofviews/kv_product_labels_stickers/{manage,update,presets}.tpl; nothing for vendors) andcss/addons/kv_product_labels_stickers/license.less(index:stylespost hook). The off-effect sentence is the language variablekv_product_labels_stickers.license_off_effect. - Request:
POST https://cs-cart.kaviolabs.com/index.php?dispatch=kv_licenses.checkwith JSON{"v":1, "license", "addon", "version", "hosts":[…], "platform":{"version", "edition"}, "nonce"}, sent throughTygh\Http(3 s connect, 5 s total; kept out of the CS-Cart request log). The answer is accepted only when its Ed25519 signature matches a public key embedded in the client and it echoes the nonce. - State: storage key
kv_license_kv_product_labels_stickers(?:storage_data), orvar/kv_storage/kv_product_labels_stickers/license.jsonwhile the full page cache is active, protected by an HMAC with the store’s crypt key. - Cron:
php admin.php --dispatch=kv_product_labels_stickers_license.check. - Development stores only (
http_hostandhttps_hostare development hosts): the constantsKV_LICENSE_SERVER_URL,KV_LICENSE_TEST_HOST(act as if the development storefronts ran on that host) andKV_LICENSE_TEST_TIME_OFFSET(seconds). They are ignored on production hosts.
The license check endpoint (kv_product_labels_stickers_license.check) accepts only CSRF-protected POST requests of administrators, and console requests. Vendors cannot use it.
PHP hooks used
Section titled “PHP hooks used”gather_additional_products_data_post, update_product_post, delete_product_post, clone_product (copies manual badges to the clone) and delete_company (removes a vendor’s badges). The license client adds a static before_dispatch handler (License\Client::onBeforeDispatch) for the admin area and the console only: it runs the due license check and shows the license notices.
Hooks provided
Section titled “Hooks provided”| Hook | Arguments |
|---|---|
kv_product_labels_stickers_update_badge_pre |
&$data, &$badge_id, &$lang_code |
kv_product_labels_stickers_update_badge_post |
$data, $badge_id, $lang_code, $record |
kv_product_labels_stickers_delete_badge_pre |
$badge_id |
Useful functions
Section titled “Useful functions”fn_kv_product_labels_stickers_update_badge(array $data, $badge_id = 0, $lang_code = DESCR_SL); // returns badge_idfn_kv_product_labels_stickers_delete_badge($badge_id);fn_kv_product_labels_stickers_get_badge($badge_id, $lang_code = DESCR_SL);fn_kv_product_labels_stickers_set_badge_products($badge_id, $product_ids);fn_kv_product_labels_stickers_create_from_preset($preset_key, $status = 'A', $position = 0);\Tygh\Addons\KvProductLabelsStickers\RuleEngine::apply($products, $lang_code); // adds kv_pls_badgesMarkup and CSS classes
Section titled “Markup and CSS classes”<div class="kv-product-labels-stickers kv-pls kv-pls--list|kv-pls--detail" style="--kv-pls-scale: 0.9;"> <div class="kv-pls__pos kv-pls__pos--top-left"> <span class="kv-pls-badge kv-pls-badge--ribbon kv-pls-badge--size-m kv-pls-badge--custom kv-pls-badge--effect-gradient kv-pls-badge--font-inherit kv-pls-badge--text-bold-upper" style="--kv-pls-bg: #e03131; --kv-pls-soft: #fbe0e0; --kv-pls-fg: #ffffff;" data-kv-pls-badge="1"> <span class="kv-pls-badge__inner"><span class="kv-pls-badge__text">Sale -25%</span></span> </span> </div></div>You can override the look in your theme’s CSS through these custom properties:
- on
.kv-product-labels-stickers:--kv-pls-inset(distance from the edge),--kv-pls-gap(space between stacked badges) and--kv-pls-scale; - on
.kv-pls-badge:--kv-pls-fs(base font size).
Theme colors come from the Responsive LESS variables @discount_label, @product_label, @primary_button, @shipping_label and @headings_font.
Custom themes
Section titled “Custom themes”A theme that is based on Responsive and keeps common/product_data.tpl and the product_labels_* capture needs no changes. If your theme prints product images without that capture, print it inside the image container:
{$product_labels = "product_labels_`$obj_prefix``$obj_id`"}{$smarty.capture.$product_labels nofilter}The container must be positioned (position: relative).
Third-party code
Section titled “Third-party code”Tygh/Addons/KvProductLabelsStickers/License/Ed25519.php (checks the signature of the license server’s answers on servers whose PHP has no sodium extension) is derived from paragonie/sodium_compat, ISC License, Copyright (c) 2016-2023 Paragon Initiative Enterprises and Copyright (c) 2013-2019 Frank Denis. The full license notice is in the file header.