=== Treasured Fries — Barcode, QR & Product Verifier ===
Plugin slug:  plantain-verify
Version:      4.0.0
Requires WP:  5.0+
Requires PHP: 8.0+

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  UPGRADING FROM v3 (or earlier)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

DO NOT delete the old plugin first.

1. Go to Plugins → Add New → Upload Plugin
2. Upload plantain-verify-v4.zip
3. WordPress will say "A newer version of this plugin is available"
   → Click "Replace current with uploaded"
4. Done. All your products, scans, labels and settings are untouched.

The upgrade system detects what DB version you're on and applies
ONLY the new changes needed (a new rate_limits table for v4).
It never drops or recreates any existing tables.

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  FRESH INSTALLATION
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

1. Upload `plantain-verify-v4` folder to /wp-content/plugins/
   OR upload the zip via Plugins → Add New → Upload Plugin
2. Activate the plugin
3. Go to Pages → Add New → title it "Verify Product"
4. Add the shortcode: [product_verify]  → Publish
5. Copy the page URL
6. Go to Product Verifier → Dashboard → paste URL → Save

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  WHAT'S NEW IN v4
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

✅ Rate limiting on the public verify endpoint
   30 scans per IP per 60 seconds (customisable via filter).
   Stops bots, scrapers, and denial-of-service flooding.
   Rate limit table auto-purges old windows to stay lean.

✅ Proper IP resolution
   Correctly resolves the real visitor IP behind Cloudflare,
   Nginx, or any reverse proxy. Enable proxy trust via:
     add_filter('pv_trust_proxy_headers', '__return_true');

✅ Base64 payload size validation
   PNG payloads are capped at 2 MB each and must be valid
   data URIs — no unbounded POST bodies.

✅ PHP 8.3 compatibility
   All functions declare return types. Strict comparisons
   throughout. No deprecated function calls.

✅ WordPress 7.0 compatibility
   - wp_date() used instead of date() for timezone safety
   - wp_json_encode() used for inline JS variables
   - wp_unslash() applied to all $_POST/$_GET reads
   - Text domain registered (i18n-ready strings)
   - No $GLOBALS access at define() time

✅ Performance optimisations
   - Dashboard: 6 COUNT queries → 1 combined query
   - All Products: correlated subquery → LEFT JOIN + GROUP BY
   - Label History: LONGTEXT PNG columns no longer loaded for
     the list view. Thumbnails replaced with on-demand download
     (lazy PNG fetch via AJAX, only triggered on button click)
   - Scan History: full pagination (was a hard LIMIT 300)
   - New DB indexes: status, exp_date, scanned_at, generated_at

✅ CDN supply-chain security (Subresource Integrity)
   JsBarcode CDN tag now includes integrity= hash.
   qrcodejs replaced with the maintained qr-creator library.

✅ Caching plugin compatibility
   DONOTCACHEPAGE constant set on the verify shortcode page
   — compatible with WP Rocket, W3 Total Cache, LiteSpeed Cache.

✅ New "rate_limited" state on the verify page
   Clean user-facing message when rate limit is hit.

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  DEVELOPER FILTERS
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

// Trust Cloudflare / Nginx proxy headers for real IP
add_filter('pv_trust_proxy_headers', '__return_true');

// Change rate limit (hits per window)
add_filter('pv_rate_limit_hits', fn() => 60);

// Change rate limit window in seconds
add_filter('pv_rate_limit_window', fn() => 120);

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  ADMIN PAGES OVERVIEW
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Dashboard          Stats overview (single optimised query),
                   quick actions, verify page URL setup, version log

All Products       Full product list with status badges, scan count
                   via JOIN (not subquery), one-click Label button

Add Product        Register a product with barcode, batch, weight,
                   dates (admin only) and notes

Barcode & QR       Generator: EAN-13 / UPC-A, auto check digit,
Labels             3 separate PNG downloads, auto-saves to history

Label History      Metadata-only list (fast). Click Download to
                   lazy-fetch the actual PNG on demand.

Scan History       Full paginated history (50 per page)

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  SHORTCODE
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

[product_verify]

Place on any WordPress page. The page URL must be set in
Product Verifier → Dashboard → Verify page setup.

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  DATABASE TABLES
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

wp_pv_products     Product registry
wp_pv_scans        QR scan log
wp_pv_labels       Label history (PNG data + metadata)
wp_pv_rate_limits  Verify endpoint rate limiting (auto-purging)

Tables are NEVER deleted on deactivation — your data is safe.
To fully remove: delete tables manually via phpMyAdmin.

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  SUPPORT
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
treasuredfriesandbites.com
09130405984 / 08111298868
