Developer notes
Overview · Installation · Configuration · Usage · FAQ
How products are saved
Section titled “How products are saved”Every row goes through core fn_update_product() (one call per product), categories through fn_update_category(), new feature values through fn_add_feature_variant() and images through fn_update_image_pairs(). All core and add-on hooks run as in the admin panel: SEO names, product premoderation, vendor plan limits, variations sync, cache tags and the full page cache BAN. Core notices raised during a save are collected into the row log instead of the admin notifications. Vendor feeds run with the vendor as the runtime company.
Run engine
Section titled “Run engine”- Start (Run now or cron): takes the feed lock (
lock_token = run:<id>with an atomicUPDATE ... WHERE lock_token = ''), so a second run of the same feed cannot start. - Fetch: downloads the source into
var/kv_sfi/runs/<run_id>/, unpacks gzip, parses it once and writes the mapped source fields of every row as one JSON line into a work file. - Rows: imports from the stored cursor (byte offset + row number) until Rows per step or the time budget is reached. Each step takes a short worker lease (
lock_expires); a crashed worker’s lease expires after 5 minutes and the next cron call continues the run. - Missing: applies the missing-items action to products of the feed’s item map that were not seen in this run (with the safety limit).
- Finish: counters and message, work files deleted, lock released, next run scheduled, old runs pruned.
Data model
Section titled “Data model”| Table | Contents |
|---|---|
?:kv_sfi_feeds |
Feed: company, source (password encrypted with the core cipher), format options, mapping, rules, options (JSON), interval, next run, lock, vendor flag |
?:kv_sfi_runs |
Run: trigger, status, phase, cursor, counters, timings, message |
?:kv_sfi_run_errors |
Row log (up to 500 messages per run) |
?:kv_sfi_items |
Item map: feed, product, code, row hash, image hash, last run seen, missing flag |
?:kv_sfi_presets |
Mapping presets per company |
No ?:storage_data writes; the cron key is an add-on setting.
Controllers and endpoints
Section titled “Controllers and endpoints”- Admin and vendor panel
kv_scheduled_feed_import:manage,add,update(GET form / POST save with optional field detection, upload and presets),run(run details),delete,preset_delete, and JSONrun_start,run_step,run_cancel,preview(POST, core CSRF check). - Cron, console:
php admin.php --dispatch=kv_scheduled_feed_import.cron --key=<key>. - Cron, URL:
index.php?dispatch=kv_scheduled_feed_import.cron&key=<key>(JSON summary,Cache-Control: no-store, 403 for a wrong key). - Hooks:
delete_product_post(item map cleanup),delete_company(feeds of a deleted vendor or storefront).
Security
Section titled “Security”- SSRF guard: only http, https, ftp, ftps and sftp; the host is resolved once and every address must be public (loopback, private, link-local, CGNAT, multicast, reserved, IPv4-mapped IPv6 and NAT64 forms are refused) unless Allow feeds from private network addresses is on (never for vendor feeds). cURL connects to the checked address only (
CURLOPT_RESOLVE); redirects are followed by hand (at most 3) and checked again; credentials are not sent to another host. - Limits: maximum feed size (streamed, also for unpacked gzip), download timeout, 10 MB and 30 seconds per image, image MIME check (JPEG, PNG, GIF, WebP).
- XML: streamed with XMLReader,
LIBXML_NONET, no entity substitution, no DTD loading; documents with a DOCTYPE are refused, so no entity can be declared. - Server path sources are limited to
var/files/(realpath check) and to administrators. Uploads are stored undervar/kv_sfi/uploads/(web access denied).
Full page cache (4.21)
Section titled “Full page cache (4.21)”The add-on has no storefront output. The cron URL is a non-cacheable dispatch. Product saves purge the affected pages through core.
License check
Section titled “License check”See License. The gate is at the start of a run (Run now and cron). Feeds, mappings, presets, the preview, the run history and a run that has already started keep working without a license.
Not in 1.0.0
Section titled “Not in 1.0.0”Grouping rows into product variations (rows import as standalone products; CS-Cart’s Variations can group them), product options, Excel .xlsx files (save as CSV), multi-language texts in one feed, deleting products.
File map
Section titled “File map”| Path | Purpose |
|---|---|
app/addons/kv_scheduled_feed_import/addon.xml, init.php, func.php |
Scheme, settings, tables, hooks, settings info |
controllers/backend/kv_scheduled_feed_import.php |
Admin and vendor pages, JSON endpoints, console cron |
controllers/frontend/kv_scheduled_feed_import.php |
Cron URL |
Tygh/Addons/KvScheduledFeedImport/Runner.php |
Run engine (start, step, cancel, cron, preview, field detection) |
.../Fetcher.php, UrlGuard.php, Files.php |
Sources, SSRF guard, working folders |
.../Parser.php |
CSV, XML and JSON readers |
.../Mapper.php |
Mapping, replace, markup, rounding, stock rules |
.../Importer.php, Catalog.php |
Product save, categories, features, images |
.../Repository.php, FeedForm.php, Access.php, Config.php |
Data access, form validation, scoping, settings |
.../License/*, controllers/backend/kv_scheduled_feed_import_license.php |
License client and “Check now” |
.../Upgrade/Synchronizer.php |
Self-healing upgrades |
schemas/permissions/*, schemas/menu/* |
Privileges, vendor access, menu |
design/backend/templates/addons/kv_scheduled_feed_import/ |
Feed list, feed form, run details, preview, license UI |
js/addons/kv_scheduled_feed_import/admin.js, design/backend/css/addons/kv_scheduled_feed_import/ |
Admin script and styles |
var/langs/en/addons/kv_scheduled_feed_import.po |
Language variables |