Developer notes
Overview · Installation · Configuration · Usage · FAQ
Data model
Section titled “Data model”All tables are InnoDB, created with CREATE TABLE IF NOT EXISTS and dropped on uninstall.
| Table | Contents |
|---|---|
?:kv_pqa_questions |
question_id, product_id, company_id (Multi-Vendor: owner of the product; Ultimate: storefront), user_id, name, email, question, status (P waiting, A published, D declined, S spam), notify, is_buyer, answers_count (published), helpful_total, lang_code, ip_hash (HMAC), flag (spam guard reason), ext_ref (imported rows), created_at, updated_at, answered_at |
?:kv_pqa_answers |
answer_id, question_id, product_id, user_id, author_type (A store, V seller, C customer), company_id (seller), name, answer, is_buyer, status (P/A/D), helpful_count, ip_hash, flag, ext_ref, timestamps |
?:kv_pqa_votes |
answer_id + voter (HMAC of the customer id, or of a random browser id and the IP address) |
?:kv_pqa_rate |
rate limit buckets (HMAC key, hits, window start) |
IP addresses are never stored in clear. The product tab is a core product tab (blocks/product_tabs/kv_pqa.tpl, html id kv_pqa); privileges view_kv_pqa / manage_kv_pqa (group kv_pqa).
Storefront endpoints (kv_product_questions_answers.*, never cached by the full page cache)
Section titled “Storefront endpoints (kv_product_questions_answers.*, never cached by the full page cache)”| Dispatch | Method | Purpose |
|---|---|---|
ask_form |
GET (AJAX) | Ask dialog with a signed time stamp, honeypot and the captcha template |
ask |
POST | Validates, runs the spam guard and the captcha (fn_image_verification('kv_product_questions', …)), stores, e-mails |
answer_form / answer |
GET (AJAX) / POST | Customer answers (verified buyers or registered customers) |
vote |
POST | Helpful vote; returns kv_pqa_vote {ok, count, already, error} |
list |
GET (AJAX) | Q&A list fragment (result_ids=kv_pqa_list_<product_id>) for search, sorting, pages; without AJAX it redirects to the product page with the same parameters |
state |
GET (AJAX) | Per-visitor state {active, logged_in, can_answer, voted[]}, Cache-Control: no-store |
unsubscribe |
GET | Signed link from the answer e-mail (t = HMAC of question id + e-mail) |
Full page cache and caching
Section titled “Full page cache and caching”- The product page output depends only on the product, the storefront, the language and the list parameters (
kv_pqa_page,kv_pqa_sort,kv_pqa_q). Per-visitor parts (votes given, “Answer” links, forms) come from the endpoints above after the page is shown; no session data is printed and nothing is written to the session or?:storage_dataon GET requests. - Data is read through
Registry::getOrSetCache()withkv_pqa_questionsandkv_pqa_answersas conditions. On 4.21 these tables become cache tags of the page, so a new, edited, moderated or voted question purges the cached product pages; the block cache of the product page (mainblock onproducts.view) and of our block is refreshed the same way and carries the licence state (callable_handlers). - The visitor id cookie
kv_pqa_vidis set by the script only when a guest votes.
| Hook | Use |
|---|---|
dispatch_before_display |
FAQPage structured data on products.view: merged into Kavio SEO Pro Suite’s kv_faq_page item when present, otherwise added to the core SEO markup list (schema_org_markup_items), otherwise printed by hooks/index/meta.post.tpl. Priority 3200 (after SEO 1800 and SEO Pro Suite 2900). |
delete_product_post |
Deletes the product’s questions, answers and votes |
post_delete_user |
Keeps the user’s questions and answers without personal data |
settings_variants_image_verification_use_for |
Adds the captcha scenario kv_product_questions |
Template hooks: products:main_info_title (post, “N answered questions”), index:meta (post), index:styles, index:scripts.
Spam guard order
Section titled “Spam guard order”honeypot (silently dropped) → signed time stamp (minimum seconds, 2 hours lifetime) → rate limit per IP and per guest e-mail (hourly) → duplicate (questions, 24 hours) → blocked words (spam) → links (held) → captcha → auto-publishing rule.
Classes (Tygh\Addons\KvProductQuestionsAnswers)
Section titled “Classes (Tygh\Addons\KvProductQuestionsAnswers)”Config (settings, licence gate storefrontActive()), Access (ask/answer/moderate rules, verified buyer), SpamGuard, Questions, Answers, Votes, Captcha (antibot service, Captcha Pro state), Notifier (e-mails), Storefront (cached view data), Markup (FAQPage), Importer (Photo & Video Reviews), Admin (back office lists and scoping), License\Client, Upgrade\Synchronizer.
File map
Section titled “File map”app/addons/kv_product_questions_answers/ addon.xml init.php func.php controllers/frontend/kv_product_questions_answers.php storefront endpoints controllers/frontend/products.post.php product page data controllers/backend/kv_product_questions_answers.php queue, question page, bulk actions controllers/backend/kv_product_questions_answers_license.php schemas/block_manager/blocks.post.php schemas/menu/{menu,menu_vendor,actions}.post.php schemas/permissions/{admin,vendor_multivendor}.post.php Tygh/Addons/KvProductQuestionsAnswers/*.phpdesign/backend/templates/addons/kv_product_questions_answers/{views,components,settings,license,hooks}/design/backend/css/addons/kv_product_questions_answers/{styles,license}.lessvar/themes_repository/responsive/templates/addons/kv_product_questions_answers/ blocks/product_tabs/kv_pqa.tpl blocks/{latest_questions,product_questions}.tpl components/{qa,list}.tpl views/kv_product_questions_answers/{ask_form,answer_form,list}.tpl hooks/products/main_info_title.post.tpl hooks/index/{meta,styles,scripts}.post.tplvar/themes_repository/responsive/css/addons/kv_product_questions_answers/styles.lessjs/addons/kv_product_questions_answers/func.jsvar/langs/en/addons/kv_product_questions_answers.poStorefront CSS is scoped under .kv-pqa*; templates and styles ship for the Responsive theme and reach Bright, Nova and other child themes by inheritance.