=== AD Pro Price Lists ===
Contributors: altaydagistan, freemius
Tags: price list, pricing table, services, inquiry form, price
Requires at least: 5.0
Tested up to: 6.9
Requires PHP: 7.2
Stable tag: 1.7.7
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Create and display beautiful multi-category service price lists with built-in inquiry forms, password protection, and full styling control.

== Description ==

• Lightweight and fast: frontend assets load only on pages that contain the shortcode
• Multi-category price lists: services grouped by category with custom display order and optional category icons
• Per-service inquiry modal: visitors can request a quote directly from the price list
• Password lock & access block: protect any list behind a two-panel lock card (access request form + direct password entry)
• Lead capture dashboards: full admin inbox for access request submissions and quote requests, with bulk actions and pagination
• Global password management: multiple passwords with per-password expiry dates
• Full CSS custom property control: card backgrounds, borders, price colour, modal, lock card, buttons, backdrop, and more
• Import & export to JSON: full portability of lists, services, categories, settings, and passwords
• Secure: nonce verification, honeypot, rate limiting, and input sanitisation on all forms
• White label ready: remove all plugin branding for client deployments (Business plan)

== Installation ==

1. Upload the folder "ad-pro-price-list" into /wp-content/plugins/
2. Activate the plugin in the WordPress Plugins menu
3. Go to Price Lists > Add New to create your first price list
4. Add services under Price Lists > Services
5. Embed a list anywhere with the shortcode: [comhit_pricelist id="123"]

=========================================
USAGE

BASIC SHORTCODE

[comhit_pricelist id="123"]

Replace 123 with your Price List post ID.

SHORTCODE WITH OVERRIDES

[comhit_pricelist id="123" max_width="900px" button_bg="#81c424" button_text="#ffffff"]

Overrides apply to this embed instance only and do not affect global styling settings.

SHORTCODE ATTRIBUTES

id          (required) — Post ID of the price list to display
max_width   (optional) — Override the maximum width of this list, e.g. "800px" or "100%"
button_bg   (optional) — Override the inquiry button background colour for this embed
button_text (optional) — Override the inquiry button text colour for this embed

=========================================
PRICE LISTS

Go to: Price Lists > Add New

Each price list is a WordPress post of type "price_list". Once published, copy its
post ID from the URL bar and use it in the shortcode.

=========================================
SERVICES

Go to: Price Lists > Services

Each service belongs to one price list (set via the "Price List" meta box) and
optionally to one or more categories. Per-service fields:

• Title
• Description
• Price (numeric)
• Price suffix (HT, TTC, etc. — set globally in Settings)
• Sur devis toggle (replaces price with a "quote on request" label)
• Hover image overlay (Pro — desktop only, smart viewport-aware positioning)

=========================================
CATEGORIES

Go to: Price Lists > Categories

Categories group services within a list. Each category supports:

• Name and slug
• Display order (numeric — lower numbers appear first)
• Category icon (optional image from the media library)

Services are sorted within their category by WordPress menu order (drag-and-drop
in the Services list view).

=========================================
INQUIRY MODAL

Every service row shows a "request a quote" button. Clicking it opens a modal form with:

• Name (required)
• Company (required)
• Email (required)
• Message (optional)

On submission:
• Admin receives an email notification with Reply-To set to the visitor's address
• The request is stored in the Quote Requests dashboard for follow-up

=========================================
PASSWORD LOCK & ACCESS BLOCK (Pro)

Enable per-list from the Price List edit screen.

The lock card has two panels:

PANEL 1 — ACCESS REQUEST FORM
Visitors submit: name, company, SIREN business number, email.
Submissions are stored in the Submissions dashboard and trigger an admin email.
Optional: redirect visitor to a chosen WordPress page after submission.

PANEL 2 — DIRECT PASSWORD ENTRY
Visitors enter a global password to unlock the list immediately via AJAX.
The lock card is replaced with the live price list without a page reload.
A chcpl-list-unlocked JavaScript event is dispatched on success.

Additional lock features:
• Fully customisable copy: surtitle, title, description, button labels, subtext
• noindex / nofollow meta injected on all pages containing a locked list
• Admin auto-unlock with a dismissible frontend notice banner (toggleable)

=========================================
GLOBAL PASSWORD MANAGEMENT (Pro)

Go to: Price Lists > Global Passwords

• Add multiple passwords, each valid for any locked list
• Set per-password expiry: indefinite or a fixed calendar date
• Expired passwords are rejected automatically

=========================================
DASHBOARDS (Pro)

SUBMISSIONS DASHBOARD — Price Lists > Submissions
Inbox for access request form submissions from locked lists.

QUOTE REQUESTS DASHBOARD — Price Lists > Quote Requests
Inbox for inquiry modal submissions from service rows.

Both dashboards include:
• Stat cards (total, unread, read)
• Filter tabs (All / Unread / Read)
• Per-row actions: mark as read, mark as unread, delete
• Bulk actions with select-all checkbox
• Pagination (20 entries per page)
• Unread indicators (red left border + dot)
• Empty state illustration

=========================================
STYLING

Go to: Price Lists > Styling

All visual properties are driven by CSS custom properties. The Styling page is
organised into cards, each with its own Save Changes button:

LAYOUT
• Border radius, gap between services, z-index, button radius

COLOURS
• Category title background and text colour
• Service title colour, description colour, price colour
• Card background, border colour

INQUIRY BUTTON
• Background, text, hover background, hover text

MODAL (Pro)
• Background, max width, border colour
• Title colour, close button colour
• Label colour, input background, input border, input text
• Service name colour inside modal

LOCK CARD (Pro)
• Background, border colour, max width (or full width toggle)
• Title colour, heading colour
• Submit button: background, hover background, text, hover text
• Access panel background, message colour, subtext colour and weight
• Access button: background, hover background, text, hover text

=========================================
IMPORT / EXPORT (Pro)

Go to: Price Lists > Import / Export

EXPORT
Select one list or all lists. Optionally include plugin settings.
Downloads a JSON file containing lists, services, categories, settings, and passwords.

IMPORT
Upload a previously exported JSON file. Options:
• Draft mode — all imported content created as drafts
• Overwrite settings — replace current plugin settings with the file's settings
• Title prefix — prepend a string to all imported list and service titles

File validation: JSON extension required, MIME type verified, 10 MB maximum,
plugin export signature checked before processing.

=========================================
GLOBAL SETTINGS

Go to: Price Lists > Settings

• Price suffix — appended to all service prices (HT, TTC, or custom)
• Auto-unlock for admins — logged-in admins see lists without entering a password
• Access request prompt — call-to-action text above the access request form
• Notification email — address that receives submission emails

=========================================
TOOLS

Go to: Price Lists > Tools

• Reset Settings & Styles — restores all settings and styling to plugin defaults

=========================================
SECURITY FEATURES

• WordPress nonce verification on every form POST and AJAX request
• Rate limiting: 5 attempts per 5 minutes on inquiry and access request forms;
  10 attempts per 10 minutes on password unlock attempts
• Honeypot anti-spam on all public-facing forms
• Full input sanitisation (sanitize_text_field, sanitize_email, intval, custom validators)
• Output escaping throughout (esc_html, esc_attr, esc_url, esc_js)
• SQL parameterisation via $wpdb->prepare on all queries; writes via $wpdb->insert/update/delete with format arrays
• Import meta key whitelist — arbitrary post meta cannot be injected via crafted JSON files
• Uploaded import files validated by extension, MIME type, and content before processing

=========================================
WHITE LABEL (Business)

Go to: Price Lists > Settings > White Label

• Remove all AD Pro Price Lists branding from the WordPress admin
• Set a custom plugin name, author name, and author URL for client-facing installs
• Logo, "What is X?" card, and plugin name are replaced across the admin UI

=========================================
MULTISITE (Business)

Network activation supported with per-site settings.

=========================================
REQUIREMENTS

WordPress 5.0+
PHP 7.2+

== Changelog ==

= 1.7.4 =
* Fixed: Quote Requests dashboard is now accessible to free plan users (limited to last 20 entries, enforced in DB layer) — previously free users saw an upgrade teaser instead of the actual dashboard
* Fixed: Styling page is now accessible to all plans — free and Essential users see core styling cards; Pro-only cards (Modal, Lock Block) remain locked with an upgrade prompt
* Fixed: Freemius /* <fs_premium_only> */ tags now correctly reflect the plan: category icons and display order tagged as Solo+, AJAX unlock/access-request handlers and registrations tagged as Pro+, redirect metabox tagged as Pro+, quote-requests teaser function tagged as Solo+ (now unused for free)
* Added: Free plan notice on Quote Requests dashboard informing users of the 20-entry limit with upgrade CTA

= 1.7.3 =
* Fixed: Freemius PHP Processor markers applied throughout codebase — lock card HTML, hover images, per-shortcode overrides, AJAX handlers, and AJAX action registrations wrapped in fs_premium_only blocks so free version ZIP is stripped of Pro code at build time

= 1.7.2 =
* Fixed: free version generated by Freemius was incorrectly showing Business Plan features — removed WP_DEBUG bypass from chcpl_is_plan() and chcpl_is_free() which caused all plan checks to return true on any site with WP_DEBUG enabled
* Fixed: Freemius PHP Processor can now correctly strip premium-only files (lock.php, import-export.php, white-label.php) from the free version by wrapping their includes with /* <fs_premium_only> */ markers

= 1.7.1 =
* Security: added sanitize_key( wp_unslash() ) to $_GET['taxonomy'] comparisons in menu filter functions
* Security: added wp_unslash() before category order and icon $_POST reads
* Security: import handler now whitelists allowed meta keys for lists and services — prevents arbitrary post meta injection via crafted JSON
* Performance: chcpl_get_settings() result cached in a static variable — get_option() called at most once per request
* Performance: SHOW TABLES queries for both custom tables now cached in 24-hour transients — cleared on plugin activation
* Performance: frontend CSS and JS now registered unconditionally but only enqueued on pages that contain the [comhit_pricelist] shortcode
* Performance: inline CSS custom properties block only generated when the frontend stylesheet is actually enqueued
* Performance: removed dead admin_init migration hook that ran get_posts() over all services on every admin page load
* Fixed: plan badge (Free / Solo / Pro / Business) not appearing on Services and Categories admin screens — extended page detection to include price_service and price_category screen IDs
* Fixed: "Save Changes" button now appears after each card on the Styling page — users no longer need to scroll to the bottom
* Removed: all scattered per-field and per-card "Pro Features" section dividers — replaced by the global plan badge on all plugin pages
* Removed: debug error_log() call that wrote to the server log on every shortcode render for admin users
* Translated: remaining French strings in security.php validation messages and ajax.php success/error responses

= 1.7.0 =
* Added global plan badge to all plugin admin pages via admin_notices hook — shows Free Plan, Solo Plan, Pro Plan, or Business Plan
* Added "Save Changes" button after each card in Styling page
* Redesigned Global Settings page using plugin design system (stacked labels, max-width 900px)
* Converted "Auto-unlock for Admins" checkbox to a toggle switch
* Added "Reset Settings & Styles" card to Tools page with confirmation dialog
* Reset now deletes per-list lock post meta so lock card copy reverts to defaults
* Added "Our Prices" as default surtitle fallback on lock card
* Removed "Available Price Lists" card from Tools page
* Updated default frontend styles to a clean light theme: green category headers, purple prices, white card backgrounds

= 1.6.0 =
* Translated all French strings to English across all plugin files (shortcodes.php, ajax.php, lock.php, security.php, admin.php)
* Added free-plan attribution footer on frontend (shown only on free plan)
* Added dynamic multi-row password addition — add multiple passwords at once before saving
* Fixed password column overflow in Global Password Management page
* Fixed theme CSS interference with plugin frontend elements via targeted !important resets
* Fixed lock card element row gaps being wiped by broad CSS reset

= 1.5.0 =
* Added Import / Export (Pro): full JSON export and import with draft mode, settings overwrite, title prefix, category and list ID remapping
* Added file validation on import: extension, MIME type, size limit, plugin signature

= 1.4.0 =
* Added two-panel lock card: access request form (name, company, SIREN, email) + direct password panel
* Added Submissions dashboard with stat cards, filter tabs, bulk actions, pagination
* Added Global Password Management with per-password expiry
* Added admin auto-unlock with frontend notice banner
* Added optional post-access-request redirect
* Added noindex / nofollow injection on locked lists

= 1.3.0 =
* Added per-list password lock with fully customisable copy
* Added AJAX unlock with chcpl-list-unlocked JS event
* Added hover image overlay per service (Pro)
* Added per-shortcode instance overrides (max_width, button_bg, button_text)

= 1.2.0 =
* Added Quote Requests dashboard
* Added full CSS custom property styling system
* Added Styling settings page with colour pickers

= 1.1.0 =
* Added category icons (optional image per category)
* Added category display order field with sortable admin column
* Added price suffix global setting

= 1.0.0 =
* Initial release
* Price list shortcode [comhit_pricelist id="123"]
* Services grouped by category
* Per-service inquiry modal with email notification
* Nonce verification, honeypot, rate limiting

== Credits ==

Created by Altay Dagistan
Website: altaydagistan.com

=========================================
LICENSE

GPL v2 or later
