Developer notes
Overview · Installation · Configuration · Usage · FAQ
The add-on never modifies core files. It uses PHP hooks, its own controllers, a template hook at checkout, .post schemas and three e-mail templates.
Data model
Section titled “Data model”| Table | Content |
|---|---|
?:kv_rre_requests |
One row per request: order, company (vendor in MV, storefront company in Ultimate), storefront, customer, language, status (Q scheduled, S sent, R reminded, D reviewed, C cancelled, U unsubscribed, F failed, X skipped) and reason, 40-character random token, test flag, send/sent/reminded/opened/clicked/reviewed times and counters, reward state (P waiting, A active, U used, E expired), coupon code, promotion, expiry, last error |
?:kv_rre_items |
Products of a request: product, vendor, name, review source (P product_reviews, D discussion, X another add-on), review id, rating, moderation state (D pending, A approved, X deleted), reviewed and clicked times |
?:kv_rre_contacts |
Consent per e-mail address: N unsubscribed / unticked at checkout, Y opted in |
?:kv_rre_exclusions |
Excluded categories (C), products (P), user groups (G) and vendors (V) per storefront company (0 = all) |
Run marks (last run, lock, last purge, last errors) use the add-on’s StorageData class: ?:storage_data, or files in var/kv_storage/kv_review_request_emails/ while the full page cache is active.
| Hook | Where (4.21.2 / 4.17.2) | What the add-on does |
|---|---|---|
change_order_status_post |
fn.cart.php 3038 / 2911 | Queues the request of an order that reached a trigger status (child orders only in MV). One INSERT, errors are caught. |
place_order |
fn.cart.php 1678 / 1585 | Stores the checkout checkbox for the order’s e-mail. |
place_order_post |
fn.cart.php 1725 / 1632 | Marks reward codes used in the order and withdraws them from the promotion. |
product_reviews_create_post |
product_reviews Repository.php 410 / 410 | Counts reviews written elsewhere (product page, other add-ons) for a matching request. |
add_discussion_post_post |
discussion func.php 706 / 706 | The same for Comments and reviews. |
mailer_send_pre |
Mailer.php 240 / 240 | Adds the open-tracking pixel after the core built the message (the core downloads and embeds every image of a message; a pixel in the template would be fetched by the server and counted as an open). |
delete_order, delete_user |
Remove the requests of deleted orders and customers. | |
before_dispatch |
Admin fallback run (shutdown, at most every 10 minutes). | |
init_templater_post |
Only while an upgrade synchronization is pending. |
All arguments are identical in 4.17.2 and 4.21.2.
Controllers and URLs
Section titled “Controllers and URLs”| Dispatch | Area | Purpose |
|---|---|---|
kv_review_request_emails.review?t=TOKEN[&p=PRODUCT&r=1-5] |
storefront | Review page; POST (CSRF-validated) saves one review |
kv_review_request_emails.go?t=TOKEN&p=PRODUCT |
storefront | Counts the click and redirects to the product’s reviews tab (“product page” mode) |
kv_review_request_emails.open?t=TOKEN |
storefront | 1×1 GIF, counts the open |
kv_review_request_emails.unsubscribe?t=TOKEN&h=SIGNATURE |
storefront | Confirmation page; POST (CSRF-validated) unsubscribes or subscribes again |
kv_review_request_emails.cron?key=KEY |
storefront | Cron URL (JSON summary) |
kv_review_request_emails.dashboard / manage / view / preview / exclusions |
admin, vendor | Admin pages (vendors: dashboard, manage, view, preview of their own requests) |
admin.php --dispatch=kv_review_request_emails.cron |
console | Cron command |
admin.php --dispatch=kv_review_request_emails_license.check |
console | License check |
The token is 20 random bytes (hex). It is the credential of the review page: whoever has the e-mail can review the products of that order, nothing else. The unsubscribe link carries an additional HMAC signature.
Reviews
Section titled “Reviews”Reviews are created through the store’s own review system:
- Product reviews:
Service::prepareReviewData()→Repository::create()(firesproduct_reviews_create_postfor other add-ons) →actualizeProductPreparedData()→ the coreproduct_reviews.new_postnotification.is_buyerisY(the signed request proves the purchase, also for guests); the status follows the core Review approval setting. - Comments and reviews:
fn_add_discussion_post()for product threads of type Rating or Communication and rating.
The moderation state of pending reviews is re-read by every queue run, so approving a review in Products → Product reviews releases a waiting reward without any hook.
Integration with other review add-ons
Section titled “Integration with other review add-ons”Other add-ons (for example Kavio Labs Photo & Video Reviews) can plug in without changing this add-on:
- Template hooks on the review page:
kv_review_request_emails:review_iteminside each product form (the form ismultipart/form-data; variables$kv_rre_itemwithproduct_id,name,selected,preset, and$kv_page.token) andkv_review_request_emails:review_pageafter the cards. Fields added there are posted with the review; since the review is created through the core repository, a handler ofproduct_reviews_create_postsees them in$_REQUEST/$_FILES. - PHP hook
kv_review_request_emails_review_url($request, $item, $rating, &$url): change the link of each star (and of the product name) in the e-mails, for example to an add-on’s own review form. Keep the token in the URL. - Reviews stored in an add-on’s own tables: call
It finds the customer’s latest sent request for that product and counts the review (statistics, reminder stop, reward). Reviews stored in coreif (function_exists('fn_kv_review_request_emails_register_review')) {fn_kv_review_request_emails_register_review($product_id, $user_id, $email, $review_id, $rating, $approved);}
?:product_reviewsneed no call.
Full page cache (4.21)
Section titled “Full page cache (4.21)”The add-on prints nothing on cacheable pages (home, categories, products, pages). Its storefront output is limited to its own dispatches and the checkout, which the full page cache never stores. Opens and clicks write only to the add-on’s tables, which schemas/full_page_cache/varnish.post.php adds to ignore_cache_tags, so they never purge cached pages; run marks use StorageData (no ?:storage_data writes from storefront requests). Saving a review writes ?:product_reviews like the core form, which refreshes the product’s cached page as intended.
License check
Section titled “License check”Tygh\Addons\KvReviewRequestEmails\License\Client (generated) verifies the license. Gate points (fn_kv_review_request_emails_is_licensed() / …_is_licensed_for_storefront(), wrapped by Gate in class code):
- queueing in
change_order_status_post(per storefront host in Ultimate), - sending requests and reminders in
Sender::run()andsendNow(), test e-mails and “queue past orders”, - the checkout checkbox.
Not gated (they complete what an e-mail already sent asked for): the review page and saving reviews, the click redirect and open pixel, unsubscribe, reward e-mails customers already earned, the admin pages and data.
E-mail delivery in development
Section titled “E-mail delivery in development”A development store can capture the e-mails as files instead of sending them: define KV_REVIEW_REQUEST_EMAILS_MAIL_CAPTURE_DIR (an existing directory) in local_conf.php. The add-on then passes its own file transport to the core mailer for its e-mails only. Never define it on a live store.
File map
Section titled “File map”| Path | Purpose |
|---|---|
app/addons/kv_review_request_emails/addon.xml |
Settings, tables, e-mail templates |
init.php, func.php |
Hook registration and handlers, install/uninstall, settings info handlers, public API |
Tygh/Addons/KvReviewRequestEmails/Config.php |
Settings (per storefront in Ultimate) and constants |
Queue.php |
Queueing, eligibility, “queue past orders”, test requests |
Sender.php |
Queue runner: requests, reminders, approvals, rewards, purge |
Emails.php, MailCapture.php |
Template variables, sending, previews, pixel, development capture |
Reviews.php, Flow.php, ReviewPage.php |
Review backends, opens/clicks/reviews/attribution, review page data |
Coupons.php |
Reward codes in auto-coupon promotions |
Stats.php, Repository.php, Links.php, Gate.php, Logger.php, StorageData.php |
Statistics, data access, signed links, license gate, error log, run marks |
License/Client.php, License/Ed25519.php, controllers/backend/kv_review_request_emails_license.php |
License check (generated) |
Upgrade/Synchronizer.php |
Self-healing upgrades (generated) |
controllers/backend/kv_review_request_emails.php |
Admin and vendor pages |
controllers/frontend/kv_review_request_emails.php, checkout.pre.php, checkout.post.php |
Storefront pages, checkout checkbox |
schemas/ |
Menu, permissions (admin, vendor), CSRF, GDPR, full page cache, settings variants |
design/backend/templates/addons/kv_review_request_emails/ |
Admin templates, license card/bar/badge (license/info.tpl for the License tab) |
var/themes_repository/responsive/templates/addons/kv_review_request_emails/ |
Review page, unsubscribe page, checkout checkbox |