Developer notes
Data model
Section titled “Data model”| Table | Contents |
|---|---|
?:kv_prs_templates |
template_id, company_id (MV vendor / ULT storefront, 0 = marketplace / all), name, status, approval, position, timestamps |
?:kv_prs_links |
object_type (P product / C category / V vendor), object_id, company_id, template_id. A product link with template 0 means “No personalization” |
?:kv_prs_views |
view_id, template_id, image_source (P main image / A additional image / C own image), image_index |
?:kv_prs_areas |
area_id, view_id, x, y, w, h (percent of the image), rotation (degrees, clockwise) |
?:kv_prs_fields |
field_id, template_id, area_id, type (T text / I image / C choice), code, required, settings (JSON), price_mode, price, free_chars, formula |
?:kv_prs_variants |
variant_id, field_id, surcharge, value |
?:kv_prs_descriptions |
object_type (F field / V variant / W view), object_id, lang_code, name, help |
?:kv_prs_uploads |
token (32 hex), file (sha1), mime, ext, width, height, size, original_name, user_id, owner (hash of the session id), product_id, field_id, status (T temporary / O ordered), created_at |
?:kv_prs_items |
order_id, item_id, product_id, company_id, template_id, data (JSON: values, display lines, proofs), unit_surcharge, approval (‘’ / P / A / C), approval_note, anonymized |
Own view images are core image pairs with the object type kv_prs_view.
Cart data
Section titled “Cart data”?:order_details.extra and the cart line carry extra.kv_prs:
v, template_id, version, hash (sha1 of the normalised values), values {field_id: {type, text, font, color | token, file, ext, mime, width, height, name | variant_id}},approved, unit (surcharge per item), lines (price breakdown), display (label/value lines), proofs {view_id: {name, file, thumb, width, height}}Only CartBridge writes it. A value posted as product_data[..][extra][kv_prs] is always discarded: the personalization comes from product_data[..][kv_prs] (f, font, color, approve), is validated against the template and stored by the server.
Files and security
Section titled “Files and security”- Files live in
var/kv_product_personalizer/as<sha1>.bin:tmp/<2>/for uploads and cart proofs,orders/<order_id>/for ordered items. The folder gets a deny-all.htaccessand anindex.php. Paths are built only from 40-hex hashes and integer ids. - Uploads: allow-list JPG/PNG/WebP; the extension, the magic bytes, finfo and the image header must agree; markup (
<svg,<?xml,<html,<script,<?php) in the first KB is refused; size limits; at most 10,000 px per side and 25 megapixels, checked before decoding; GD decodes, applies the EXIF orientation and encodes again (no metadata, nothing appended). 30 uploads per visitor and hour. - An upload token is usable only by the session or account that uploaded it, for the same product and field.
- Downloads: storefront
kv_product_personalizer.filechecksfn_is_order_allowed()and that the item references the requested hash; cart proofs (kv_product_personalizer.proof) only for lines of the visitor’s own cart. Responses sendX-Content-Type-Options: nosniffand a restrictive Content-Security-Policy. - The storefront upload and preview requests require the form security hash.
Proofs
Section titled “Proofs”Renderer::render() draws the view image (scaled to the proof width) and every field of the view into its area: text with imagettftext() in the bundled font, fitted by a binary search on the font size; images with imagecopyresampled() (contain or cover); rotated areas with imagerotate(). The PNG contains no timestamp, so the same input always gives the same bytes; the file name is the sha1 of the bytes. Proofs are rendered when the item is added to the cart and copied into the order folder when the order is placed (rendered again from the stored values if a copy is missing).
| Hook | Use |
|---|---|
pre_add_to_cart |
Validation and storage of the personalization of new lines |
generate_cart_id |
The personalization hash makes separate cart lines |
apply_option_modifiers_post |
The surcharge per item joins the unit price (cart, checkout, orders, order editing) |
exclude_products_from_calculation |
Storefront carts: expired uploads, changed or removed templates, changed surcharges |
gather_additional_products_data_post |
Product page data (static per product); “Select options” in lists |
place_order, get_order_info, delete_order |
Ordered items and files, option lines and links in orders |
update_product_post, clone_product, delete_product_post, delete_category_post, delete_company |
Assignments |
before_dispatch |
Hourly cleanup on back-end GET requests |
The add-on fires kv_product_personalizer_notify_pre($data) before the proof review e-mail.
GDPR: schemas/gdpr/user_data.post.php exports the personalization of a customer’s orders and, on anonymization, deletes the texts, uploads and proofs (the order lines keep their prices).
Integrations
Section titled “Integrations”- Advanced Product Options & Price Formulas (
kv_product_options_pricing): when active and licensed, the price mode Formula evaluates with itsExpressionengine. Nothing is required: without it the mode is hidden. - Booking & Reservations (
kv_booking_reservations) and Auctions (kv_auction_bidding): their products never get the personalizer (checked through their tables/classes while those add-ons are active). - Core product options keep working next to the personalizer.
File map
Section titled “File map”app/addons/kv_product_personalizer/ addon.xml init.php func.php controllers/backend/kv_product_personalizer.php, products.post.php, kv_product_personalizer_license.php controllers/frontend/kv_product_personalizer.php, checkout.post.php schemas/block_manager/blocks.post.php product page cache keys schemas/gdpr/user_data.post.php schemas/menu/menu.post.php, menu_vendor.post.php, actions.post.php schemas/notifications/events.post.php schemas/permissions/admin.post.php, vendor_multivendor.post.php schemas/security/csrf_validation.post.php Tygh/Addons/KvProductPersonalizer/ CartBridge.php cart lines, surcharge, product page data Cleanup.php abandoned uploads Compat.php options pricing formulas, booking/auction exclusion Config.php settings, licence gate, constants Files.php private file store Fonts.php bundled fonts Gdpr.php export and anonymization ImageTools.php upload validation and re-encoding Notifier.php, ProofDataProvider.php proof review e-mail Orders.php ordered items, files, approval, production data Personalization.php validation, prices, hashes, display lines Renderer.php proofs (GD) StorageData.php run marks (full page cache safe) Templates.php templates, resolution, editor save Uploads.php upload records and ownership License/ Upgrade/ license client, self-healing upgradesdesign/backend/templates/addons/kv_product_personalizer/ template editor, lists, production sheet, hooksvar/themes_repository/responsive/templates/addons/kv_product_personalizer/ personalizer panel, cart and order hooksjs/addons/kv_product_personalizer/func.js, backend.jsjs/addons/kv_product_personalizer/fonts/ six OFL fonts + license textsvar/langs/en/addons/kv_product_personalizer.po