== Changelog ==

= 1.8.9 =
* **New – Plugin admin language:** pick the language the plugin's own admin screens are shown in — English, Български, Deutsch, Ελληνικά or Español — from a dropdown on the General Functions page. It is independent of your site language, so you can run a Bulgarian store and keep the plugin's admin in English, or the other way round. The storefront always follows the site language.
* **New – Full translations:** the whole plugin is now translated into Bulgarian, German, Greek and Spanish, admin and customer-facing alike. WordPress still loads the matching translation automatically for your site language; the picker above is only for overriding the admin.

= 1.8.8 =
* **Performance – the plugin loads only the code a page actually needs:** feature files are now pulled in on demand rather than all at once, so a typical front-end request loads far fewer of them and the site stays lighter. No setting or behaviour changes.
* **Maintenance – cleaner internal structure:** Minimum Order, Direct Checkout Links and URL Transliteration each moved into their own self-contained module, and unused transliteration code was removed. This is groundwork for faster, safer updates and changes nothing you can see.
* **Fix – the "Coming soon" feature cards showed a broken icon:** the placeholder icon was stored with a character-encoding glitch and rendered as stray symbols; it now shows correctly.

= 1.8.7 =
* **New – Right of withdrawal ("Withdrawal from contract"):** A compliant way for a customer to exercise the 14-day EU/Bulgarian distance-selling right of withdrawal. They look an order up by its number and the email used at checkout (so it works for guests with no account), choose which items and quantities they are returning, and confirm in a separate step. The declaration is recorded on the order (a red banner, a per-line "withdrawn" column and an orders-list badge), both sides are emailed, and nothing is refunded automatically — returning money stays a deliberate action in WooCommerce. The public lookup is deliberately unhelpful to strangers: one identical message for every failure and per-IP rate limiting, so no one can probe which orders exist. Shown via the `[flexmior_withdrawal]` shortcode, an optional My Account button and a link in order emails; each entry point has its own toggle.
* **New – Product Photo Upload:** Let customers attach a photo to a product — for printing, engraving or photo gifts. Turn it on per product (optionally required); the image is validated, saved with the order with a download link for you, and shown in the order email. Pick the accepted formats (JPG, PNG, GIF, WebP), the size limit and an accent colour, reword every customer-facing text, and set different wording per language. Uploads are handled through WordPress's own upload API, stored under a random name in a folder that refuses script execution, size-capped and rate-limited.
* **Change – Advent Calendar is now available as Beta:** the daily-surprise calendar (the `[flexmior_advent_calendar]` shortcode) is unlocked and can be switched on; it is off by default while it settles in.
* **Change – General Functions page:** features now save the moment you flip a switch — the Save button is gone — and a search box and All / Enabled / Disabled / Coming soon filters make the growing feature list easy to scan. Long descriptions collapse behind "Show more" so two wordy features no longer stretch the grid.
* **New – Email Capture quick links:** each mailing-list service (Mailchimp, Brevo, MailerLite, Klaviyo) now links straight to the screen where its API key and list ID live, so setup is one click away.
* **Fix – A stray arrow and notch appeared beside the Advent Calendar status:** the plugin's generic `arrow` class collided with WordPress's own admin-pointer styling, which positioned it absolutely and drew a decorative triangle. The class was renamed so it no longer inherits those styles.

= 1.8.6 =
* **Fix – Health & Load Guard measured WP-CLI commands as front-end requests:** WP-CLI runs with no memory limit and is meant to run long, so an import, a `wp cron` batch or a backup was logged as a multi-second, thousands-of-query "front request". That skewed the dashboard averages and could raise slow/query warnings against a plugin — in automatic mode a nightly batch job could have disabled one. WP-CLI consumes no PHP-FPM worker, which is what the feature protects, so it is no longer measured at all.
* **Fix – Deactivating the plugin left the recovery guard running:** the must-use recovery plugin and the quarantine list survived deactivation, so a quarantined plugin could stay disabled with no interface left to release it. Deactivation now removes the recovery guard, releases the quarantine (anything it disabled simply stays normally deactivated and visible on the Plugins screen) and clears every scheduled job the plugin created.
* **New – Proper uninstall handling:** deleting the plugin now always stops its scheduled jobs, removes the recovery guard and clears its transients. A new "Delete all ShopBoost data when the plugin is deleted" option in General Functions — **off by default** — additionally removes every table, setting and stored record, so deleting and reinstalling no longer risks your redirects, checkout fields, size charts, quick orders or collected addresses unless you ask for it.

= 1.8.5 =
* **New – Health & Load Guard:** A built-in server-load monitor. See what every request costs — time, peak memory, database queries and external calls — and, where it can be measured safely, which plugin is responsible. A live indicator sits in the toolbar and a full dashboard covers the last 24 hours. Set thresholds and get warned before a slow-down becomes a "503 – maximum processes reached" outage; optionally let a sustained, non-protected culprit be disabled and quarantined automatically, with a recovery must-use plugin that keeps a crashing plugin from loading on the next request. Includes a tracked checklist of performance recommendations, several checked live (object cache, PHP version, OPcache, autoloaded options, the Action Scheduler backlog, and more).
* **New – Email Capture:** Collect email addresses from the `[flexmior_subscribe]` form, price-drop alerts and Quick Order, and forward them to Mailchimp, Brevo, MailerLite or Klaviyo. Every address is stored locally first and synced on a schedule, so a slow or failing provider never delays the customer and nothing is lost during an outage. Each source has its own opt-in.
* **Change – Advent Calendar is marked "Coming soon"** while it is being finished; it registers nothing and is not yet available.
* **Fix – Signup form source toggle had no effect:** turning off the "Signup form" source now actually stops the form from collecting, and the form is hidden while that source is off.
* **Code quality – WordPress Plugin Check pass:** added `translators:` comments to internationalised strings with placeholders, replaced `unlink()` with `wp_delete_file()`, tightened output escaping, ordered multi-placeholder strings, refreshed the "Tested up to" header, and cleaned up bundled file names.

= 1.8.1 =
* **Fix – Admin screens ran 40px off the right edge of the window:** The plugin's admin wrapper applied `box-sizing: border-box` to its children but not to itself, so its own side padding was added on top of `width: 100%`. Every ShopBoost screen overflowed horizontally, clipping content against the right edge. Affected all admin pages; fixed in one place.
* **Change – Promotions now live only in Mass Discount:** "Sale: X% off", "Add sale" and "Remove sale" have been removed from Bulk Edit's bulk actions, which now covers permanent catalogue changes only (set / increase / decrease the regular price, set stock). Bulk Edit no longer marks a plain price cut as an "active promotion". Promotional actions moved to Mass Discount, which gained **Sale price tools** for setting one fixed sale price across the selection or clearing sale prices. This removes the trap where "Decrease price by %" (a silent price change, no sale badge) sat next to "Sale: X% off" (a real promotion) in the same dropdown.
* **Fix – Creating a promotion could overwrite the previous one:** The apply panel kept the last used promotion in a hidden field, so entering a new promotion name silently reused that promotion — renaming it, changing its percentage, and absorbing its products. A promotion is now identified by its name, so a different name always creates a separate promotion.
* **New – Protection against a product landing in two promotions:** Applying a promotion now skips products that already belong to a different one and reports how many were skipped, so an intended 10% discount can no longer be quietly replaced by a later 5% one. A "Replace existing promotions" checkbox opts in to moving them; the original pre-promotion price is preserved either way, so Restore always returns the genuine price.
* **New – Remove a whole promotion or category in one click:** A "Remove whole set" button restores original prices for every product matching the current filter, instead of requiring each product to be ticked page by page. The button, its hint and its confirmation name the exact scope (a promotion, a category, or every discounted product). Work is processed in batches of 200 per request, reporting how many remain, so large catalogues cannot hit a PHP timeout mid-operation.
* **Fix – Percentage actions stored unrounded prices:** Applying a percentage produced values such as 39.096, which WooCommerce displayed rounded but stored raw, causing cent-level drift between the shown and stored price. Results are now rounded to the store's decimal setting.
* **Fix – "Remove sale" left stale promotion data:** Clearing a sale price kept the product flagged as having an active promotion, so it stayed listed as promoted and Restore could revert prices the admin had already cleared. All promotion data and sale dates are now cleared with it.
* **Fix – Price Tracking recorded timestamps in the site timezone** while the 30/90/365-day windows were calculated in UTC, shifting the window — including the legally significant Omnibus 30-day period — by the store's UTC offset. History is now recorded in UTC.
* **Fix – Price Tracking currency symbol in emails and the Omnibus badge:** `wc_price()` returns an entity-encoded symbol, so the Bulgarian "лв." appeared as `&#1083;&#1074;.` in the price-drop email subject and in the badge. Both now decode it.
* **Fix – Price-drop notification cron was never unscheduled** when the feature or its alerts were switched off, or when the plugin was deactivated.
* **Fix – Price-drop subscriptions accepted any product**, even ones the feature was not configured to display on.

= 1.8.0 =
* **New Feature – Price Tracking:** Records every price change and shows the history on the product page as a "Price history" tab and via the `[flexmior_price_history]` shortcode. Includes an inline SVG chart, current/lowest/highest/average stat tiles, and a 30/90/365-day range switch. No external chart libraries — fully self-contained.
* **New Feature – Price Tracking: EU Omnibus badge:** When a product is on sale, a "lowest price in the last 30 days" badge is shown next to the price — the disclosure required by the EU Omnibus Directive. The reference price correctly excludes the current reduced price.
* **New Feature – Price Tracking: price-drop email alerts:** Customers can subscribe to be notified when a product gets cheaper. A daily check emails them a professionally designed HTML notification (product image, old vs. new price, savings, call-to-action) with a one-click unsubscribe link. Built-in per-IP rate limiting on sign-up.
* **New Feature – Price Tracking: targeting & styling:** Show it on all products, selected categories, or individual products (additive). Configurable tab title, default range, chart accent color, Omnibus badge text, and alert toggle.

= 1.7.6 =
* **Improvement – Buy X Get Y Free: target individual products:** The promotion is no longer limited to whole categories. Products can now be selected individually, by category, or both — a product qualifies if it is picked on its own **or** it belongs to a selected category. Existing category-only setups keep working exactly as before.
* **Improvement – Buy X Get Y Free settings screen:** New "Eligible Products" card with a filterable product list and a selected-count, plus a filter and count for the category list. Products already selected but outside the displayed list are always rendered, so saving the form can never silently drop them.

= 1.7.5 =
* **New Feature – Buy X Get Y Free:** Quantity-based reward for products in selected categories. For every N units of the same product in the cart, M free units are added automatically as a separate 0.00 line (e.g. buy 4 → the 5th is free; buy 8 → two free). The ratio (buy N / get M) and the eligible categories are configurable. Free items are recalculated on every cart change, locked from manual editing, and shown with a gift badge.
* **Improvement – Secondary Currency (formerly "BGN → EUR"):** The dual-currency display is no longer limited to Bulgaria. It now works for any store currency and can show **multiple** secondary currencies at once (e.g. EUR + USD), each with its own manual conversion rate. The BGN ↔ EUR pair remains automatically locked to the fixed legal rate (1 EUR = 1.95583 BGN). Existing BGN/EUR stores are unaffected — the previous behaviour is preserved automatically when nothing new is configured.
* **Architecture – Per-feature modules:** The monolithic main class has been split so each feature (Secondary Currency, Conditional Free Shipping, Redirect, Checkout Fields, Price Variation, Size Chart, Auto-Add Product, Buy X Get Y Free) lives in its own class under `includes/features/` and registers its hooks only when enabled. The core file shrank from ~5,000 to ~1,800 lines. No user-facing behaviour changes; every feature toggle and option key is unchanged.
* **Fix – Bulk Edit Products: stale prices after edits:** Prices changed via Bulk Edit could linger on the storefront (object cache / price-lookup table / page cache) until the scheduled-sales cron ran or a hard refresh. Product (and variation) caches are now flushed explicitly after each change, so the displayed price stays in sync with checkout immediately.

= 1.7.4 =
* **Fix – URL Transliteration broke menu links:** Display-time filters (`wp_nav_menu_items`, `the_content`, `the_excerpt`) were transliterating URLs on output without checking whether the underlying slug had actually been changed — producing links to non-existent pages. Removed all three display-time hooks; transliteration now happens exclusively at save time and via the manual/auto scan, which is the correct approach.
* **Fix – URL Transliteration could not transliterate taxonomy terms:** `apply_manual_transliteration()` called `get_term_by('slug', ..., '')` with an empty taxonomy string. WordPress's `taxonomy_exists('')` returns `false`, so the lookup always failed silently — no category, tag, or product-category slug was ever updated. Now iterates all public taxonomies. Also added `urldecode()` on the slug extracted from the URL path so URL-encoded Cyrillic characters match the database value.
* **Fix – "Run Scan Now" button did nothing when Automatic Scanning was off:** The button called `auto_scan_and_transliterate()`, which checks `flexmior_auto_scan_enabled` and returns early when disabled. Added a dedicated `run_scan_now()` method that always executes regardless of the auto-scan toggle.
* **New – URL Health Status dashboard:** The URL Transliteration settings page now shows a live health-status card at the top that loads automatically on page open. Displays the count of untransliterated URLs grouped by type (Post, Page, Product, Category, Menu Link) with original vs. transliterated URLs side by side. Includes a one-click **Transliterate All** button and a **Fix Selected Menu Links** action for custom-link menu items.
* **New – Menu custom-link scanning:** The health check now also scans WordPress navigation menus for custom-link items containing Cyrillic URLs, which the existing post/term scan did not cover. Detected menu links can be fixed individually or via the Transliterate All action.
* **Fix – Minimum Order feature enabled by default on fresh install:** The `flexmior_feature_minimum_order_enabled` option defaulted to `1` in five places, causing it to appear active immediately after plugin installation. Changed all defaults to `0` — all features now start disabled and must be explicitly enabled by the admin.
* **Fix – Quick Order: variable product variation not recorded:** The form did not capture the selected variation. Added a hidden `variation_id` field, JavaScript listener for WooCommerce `found_variation`/`reset_data` events, server-side validation (variation must belong to the parent product), and variation-aware display in admin list, detail view, email notifications, and Convert to Order.
* **Fix – Quick Order: public submit endpoint worked with feature disabled:** The AJAX handler was registered unconditionally but did not check the feature toggle, allowing submissions even when Quick Order was turned off. Added an early `flexmior_feature_quick_order_enabled` check.
* **Fix – Quick Order: empty text options left buttons unlabelled:** Saving an empty Form Title, Submit Button Text, or Collapsed Button Text resulted in blank labels. Added a `get_text_option()` helper that falls back to the default value when the stored option is an empty string.
* **Fix – Quick Order: WooCommerce HPOS incompatible order links:** Hardcoded `post.php?post=X&action=edit` URLs do not work when High-Performance Order Storage is active. Replaced with `$order->get_edit_order_url()` in the orders list, detail modal, and Convert to Order response.

= 1.7.3 =
* **New Feature – Quick Order:** Customer-facing quick order form (renders automatically under Add to Cart, or via the `[flexmior_quick_order]` shortcode, or as a modal popup). Three display modes: **Inline** (form shown directly under Add to Cart), **Inline + Collapsible** (form starts hidden behind a single button — click to slide it open), and **Modal** (small trigger button opens a popup). Fully configurable field builder (text, textarea, email, tel, number, select, checkbox, radio — drag to reorder, mark as required, custom placeholders/options). Submissions are stored in a dedicated `wp_flexmior_quick_orders` table and listed under **ShopBoost → Quick Orders** with filters (status, search), detail modal, status updates (new / processing / done / rejected), and a one-click **Convert to Order** action that creates a real WooCommerce order. Email notifications: admin alert + optional customer confirmation. Built-in anti-spam: honeypot field (autofill-safe naming) + per-IP rate limiting (configurable).
* **New Feature – Quick Order: Full button styling:** Dedicated "Button appearance" admin card lets you customise background color, hover color, text color, font family (13 presets + theme inherit), font size, font weight, padding, and border radius — all with a live preview that updates in real time. Styles are injected as inline CSS only when overridden; defaults stay clean.
* **New Feature – Quick Order: Admin bar integration:** "Quick Orders" link added to the ShopBoost dropdown in the WordPress admin bar for one-click access to incoming submissions from anywhere in the admin.
* **Improvement – Bulk Edit Products: Name and Slug inline editing:** Click any product name or slug cell to edit in place; saves on Enter/blur. Slugs are properly decoded from URL-encoded Cyrillic on display and re-sanitised on save. Blur without changes no longer triggers a save.
* **Improvement – Mass Discount: Scheduled date range:** Each promotion can now be assigned a `from` / `to` date — WooCommerce native sale-price scheduling kicks in automatically. Promotion cards show a status badge (Active / Scheduled / Expired) plus the date range.
* **Fix – Quick Order rendered inside the WooCommerce cart form:** Switched the auto-render hook from `woocommerce_after_add_to_cart_button` (inside the cart form) to `woocommerce_after_add_to_cart_form` (after the closing tag). The old placement produced nested forms — on certain themes the Quick Order submit was hijacked by the cart form, adding the product to the cart instead of saving the quick-order submission. Click handlers on the modal trigger and collapsible toggle now also call `preventDefault()` / `stopPropagation()` as a second line of defence.
* **Fix – Quick Order modal showed "Submission failed" instead of the form:** In modal mode no inline form was rendered, so the JS had nothing to clone into the modal. The fallback message used the generic "Submission failed" string, which looked like a server error. The modal now pre-renders the form inside the container at page load — clicking the trigger shows the ready-to-use form instantly.
* **Fix – Quick Order honeypot blocked legitimate submissions:** The hidden anti-spam field was named `flexmior_qo_website` with a label of "Website", which password managers and browser autofill commonly fill in automatically — triggering false-positive rejections. Renamed to a non-semantic name with `autocomplete="new-password"`, `opacity:0`, and `pointer-events:none` so autofill ignores it entirely.
* **Fix – Quick Order button-in-button when modal mode + collapsible were both enabled:** Collapsible is now strictly an inline-mode feature. When Modal display mode is selected the Collapsible options are hidden in the admin UI and ignored on the front end, so the popup no longer contains a nested toggle button.

= 1.7.2 =
* **New Feature – Mass Discount module:** Separated into its own independent module with a dedicated admin page and its own On/Off toggle in General Functions. Supports named promotions — each discount run is saved with a custom label (e.g. "Summer Sale"), percentage, and date. The promotions panel on the left lists all active promotions with live product counts; clicking a promotion filters the product table to show only the products in that promotion. Original prices are backed up automatically and can be restored per-product or in bulk at any time. Products discounted before this feature was introduced continue to work normally under "All with active discount".
* **Improvement – Bulk Edit Products: SKU inline editing:** SKU cells in the Bulk Edit Products table are now inline-editable. Click any SKU cell to edit in place; uniqueness is validated server-side before saving (duplicate SKUs are rejected with an error message). Variable products support SKU editing directly in the table.
* **Fix – Product filter not applied in Mass Discount:** Switching to `WP_Query` directly (replacing `wc_get_products()`) to fix paginated meta-query filtering. `wc_get_products()` silently ignored `meta_query` in paginated requests, causing the promotion filter to return all products instead of the filtered set.

= 1.7.1 =
* **Bug fix – Admin styles and scripts not loading:** All plugin sub-pages (Minimum Order, Product Links, Auto Add Product, URL Transliteration, Redirect, etc.) were loading without any admin styles or JavaScript. Root cause: WordPress generates sub-page screen IDs from the sanitised menu *title* (`sanitize_title('ShopBoost')` → `shopboost`), producing IDs like `shopboost_page_flexmior-*`. The previous detection used `strpos($screen_id, 'flexible-minimum-order')` which never matched these IDs. Fixed by also checking for `flexmior` in both `$screen->id` and the `$hook` parameter — now covers all current and future plugin pages reliably.
* **Bug fix – Auto Add Product product list not injected:** The product list for the Auto Add Product page was gated behind a strict equality check against a hardcoded screen ID (`flexible-minimum-order_page_flexmior-auto-add-product`) that was also affected by the same naming issue above. Replaced with a `strpos()` check so the product data is correctly passed to JavaScript regardless of the screen ID prefix.
* **Improvement – Minimum Order settings page redesign:** Rebuilt with a proper two-column card layout (Basic Settings + Custom Message + Shortcode on the left; Notice Colors + Typography on the right). Fixed a broken form structure where `<form>` opened inside the left column while Visual Settings and the Save button were outside it — meaning visual settings were never actually submitted. Added toggle switches, a live message preview, a live visual preview (colours and typography), and a one-click shortcode copy button.

= 1.7.0 =
* **New Feature – BGN ↔ EUR Dual Currency:** Shows the secondary currency equivalent next to every price across the store (product listings, variable product ranges, cart item prices and subtotals, cart grand total, mini-cart, order pages, My Account, and transactional emails). Works in both directions — BGN stores show EUR (÷ 1.95583); EUR stores show лв. (BGN) (× 1.95583). Uses the fixed ECB conversion rate (1 EUR = 1.95583 BGN). Configurable display format (brackets or slash), position (after or before), and independent per-location toggles. Settings page adapts automatically to the active store currency.
* **Performance – Feature hooks:** Every feature toggle now truly disables its code path. All Auto Add Product hooks (six in total) are now gated behind the feature toggle — zero callbacks registered when the feature is off.
* **Performance – Admin asset loading:** Replaced 19 redundant page-detection `if` blocks in `admin_scripts()` with a single `strpos()` check on the screen ID. Covers all current and future plugin pages automatically. Product Links admin bundle now loads only when the Product Links feature is enabled.
* **Performance – Color CSS variables:** Notice colour overrides moved from a raw `wp_head` echo to `wp_add_inline_style()`, removing a separate render-blocking `<style>` tag.
* **Performance – BGN/EUR frontend CSS:** `.fmo-eur-price` rule moved permanently into `frontend.css` (already loaded only on WooCommerce pages), removing one inline style block per page load.
* **Redirect – URL matching fixed:** Removed an impossible fourth SQL variation (raw `REQUEST_URI` with query string — source URLs are stored without query strings so it could never match). Query now uses three clean, documented variations.
* **Redirect – DB error logging:** All four AJAX operations (create, update, delete, toggle) now log `$wpdb->last_error` on failure for easier debugging.
* **Price Variation – Two-column layout:** Settings page rebuilt with side-by-side layout matching the rest of the plugin UI.
* **Price Variation – Checkbox template fixed:** "Checkbox – Square" template now renders correctly; previously fell back silently to the Table template.
* **Price Variation – Checkbox Settings card:** Dedicated settings card (size and four colors) appears automatically when the Checkbox template is selected.
* **Price Variation – Highlight Selected:** Toggle now correctly emits or suppresses `.selected` CSS rules for all five templates.
* **Price Variation – UI consistency:** Toggle switches, color fields, number inputs, and save button now use the standard plugin design system.
* **Size Chart editor rewrite:** Fully data-driven. PHP parses saved chart HTML into a JSON model via DOMDocument; JavaScript renders from that model. Removed ~270 lines of legacy DOM-scraping code and all production `console.log()` leaks.
* **Size Chart – Display Settings UX:** Two always-visible multi-select boxes replaced with a segmented "Show on" toggle (All Products / By Category / Specific Products).
* **Safer toggling:** Admin UI, settings link, and shortcodes remain always-on so settings are always accessible regardless of feature state.

= 1.6.4 =
* **Cleanup:** Removed leftover `console.log()` debug statements from the Checkout Field Editor and URL Transliteration screens. Only `console.error()` calls for genuine failures (missing jQuery UI, AJAX errors) remain.

= 1.6.3 =
* **Fix:** Bulk Edit Products page threw `SyntaxError: Expected property name or '}' in JSON` when a category name contained an apostrophe, ampersand, or other character mangled by `esc_js()`. The categories list is now injected with `wp_json_encode()` directly (no `JSON.parse()` / `esc_js()`), which produces a valid JavaScript array literal regardless of the contents.

= 1.6.2 =
* **Fix:** Drag-and-drop reordering on the Checkout Field Editor now works for both default WooCommerce fields and custom fields. The default fields container was switched from CSS grid to flexbox (jQuery UI sortable cannot compute positions inside a grid container), a dedicated `.fmo-drag-handle` element is now the sortable handle so Edit/Hide/Required buttons stay clickable, and the custom fields table helper now preserves column widths during drag.

= 1.6.1 =
* **View layer extracted:** Every admin page HTML template has been moved out of `class-settings-page.php` into its own file under `includes/views/`. The class shrinks from 5,914 to 556 lines and now contains only routing, menu registration, settings sanitizers, and thin delegators to the view files. No behaviour changes.
* **Maintainability:** Each screen is now reviewable on its own (`view-redirect.php`, `view-bulk-edit.php`, `view-checkout-field-editor.php`, etc.).

= 1.6.0 =
* **Architecture refactor:** The monolithic settings class has been split into dedicated AJAX handlers (Redirects, Checkout Fields, URL Transliteration, Product Generator, Bulk Edit) and a reusable URL transliterator service. No user-facing behaviour changes; AJAX endpoints and nonces are preserved.
* **Security by default:** New `Flexmior_Ajax_Handler` base class enforces `check_ajax_referer()` + `current_user_can()` on every AJAX endpoint — it is no longer possible to add a handler that forgets the check.
* **Smaller core file:** `class-settings-page.php` reduced from 7,918 → 5,914 lines (-25%). Feature code lives in focused files under `includes/ajax/`.
* **Dead code removed:** `upload_image_from_url()` (unused).

= 1.5.3 =
* **HPOS fix:** Custom checkout fields now use the Order CRUD API (`$order->update_meta_data` / `$order->get_meta`) instead of legacy post meta — required for stores running High-Performance Order Storage.
* **Security hardening:** Added explicit `phpcs:ignore` annotations with justifications to direct database queries against plugin tables; strict comparison (`true`) added to all `in_array()` calls.
* **Code quality:** Replaced `gmdate()` with `wp_date()` for analytics date grouping so results respect the site timezone.
* **JS cleanup:** Debug console output is now gated behind a debug flag (enabled automatically when `WP_DEBUG` is true). Production console stays quiet; real errors still log via `console.error`.
* **Cleanup:** Removed dead code blocks, debug HTML comments, and stale `// ПРЕМАХНАТО` markers.
* **Activation:** Explicit defaults when reading options in the activation hook.

= 1.5.2 =
* **New:** Conditional Free Shipping now supports custom checkout text for uncalculated shipping labels (editable from settings)
* **Bug fixes:** Fixed minor bugs and improved overall stability

= 1.5.1 =
* **Bulk Edit:** Added product image column in table
* **Bulk Edit:** Products per page filter (10, 20, 50, 100)
* **Admin bar:** ShopBoost menu for quick access to Settings and Bulk Edit
* **Bulk Edit:** Mass discount with save & restore – original prices saved automatically, restore action to undo
* **Bulk Edit:** Full variation support – backup/restore and all bulk actions apply to variable product variations
* **Bulk Edit:** Variable products show min–max price ranges; Variations badge in table
* File cleanup for WordPress.org compliance – removed development-only docs
* Updated README.md with accurate plugin description

= 1.5.0 =
* **New:** Size Chart feature (Beta) – display size guide tables in product tabs, via shortcode, or as popup
* **New:** Bulk Edit Products – edit prices, stock, and apply bulk promotions in a table view with search and filters
* **Performance:** Frontend CSS loads only on cart, checkout, shop, and product pages (not on blog/archive)
* **Performance:** Color CSS variables injection limited to WooCommerce pages only
* **Performance:** Auto Add Product product list limited to 500 items for faster loading
* **Performance:** Added lightweight frontend.css (~3 KB) with only notice styles
* Size Chart marked as Beta in admin interface
* Plugin optimized for speed and compatibility with latest WordPress

= 1.4.1 =
* Minimum order now uses cart contents only (products) – shipping, taxes and fees are excluded from the minimum order check
* Fixed redirect logic on login/registration pages (replaced undefined is_login/is_registration with proper WordPress/WooCommerce checks)

= 1.4 =
* Improved Checkout Field Editor with simplified modal design and better user experience
* Enhanced Redirect page with compact layout and improved modal interface
* Fixed drag and drop functionality for reordering checkout fields
* Fixed show/hide functionality for default WooCommerce checkout fields
* Enhanced security with improved SQL injection protection and data sanitization
* Reorganized General Functions page - active features first, then Coming Soon features
* Improved overall admin interface consistency and usability

= 1.3.3 =
* Redesigned General Functions page with modern card-based layout
* Added feature toggle system for enabling/disabling individual features
* Added 6 new "Coming Soon" features: Advent Calendar, Free Shipping Bar, Price Tracking, Abandoned Cart, Price Variation, and Checkout Field Editor
* Improved admin interface with full-width responsive grid layout
* Updated plugin icons (Shopboostar.png and Icondash.ico) for better visual identity
* Removed deprecated icon-128x128.png
* Enhanced product links page with improved product name and price formatting
* Optimized icon sizes for better performance (20x20px for menu icons)
* Improved code organization and preparation for future feature releases

= 1.3.2 =
* Added Woodmart theme integration with full AJAX cart support
* Added mini cart widget message for Woodmart theme
* Added protection against duplicate plugin loading using FLEXIBLE_MINIMUM_ORDER_LOADED constant
* Improved theme detection for Woodmart, Divi, and default themes
* Added dark mode support for Woodmart theme
* Enhanced responsive styles for all integrations

= 1.3.1 =
* Fixed Gutenberg/Blocks integration - HTML tags now display correctly as HTML instead of plain text
* Fixed syntax error in JavaScript code for Blocks integration
* Fixed output escaping issues in all integration files
* Updated "Tested up to" WordPress version to 6.9
* Removed all debug messages (console.log and error_log) for production release
* Improved HTML rendering in Gutenberg Blocks minimum order messages
* Enhanced security with proper output escaping and sanitization

= 1.3.0 =
* Added Auto Add Product feature - Automatically add products to cart when customers reach specified amounts
* Added support for multiple auto-add products with individual configuration per product
* Added discount options for auto-added products (Percentage, Fixed Amount, Set Price)
* Added option to automatically remove products from cart when total falls below threshold
* Added option to hide auto-added products from shop pages (only visible when automatically added)
* Moved "Enable direct checkout links" option to Product Links page for better organization
* Improved admin interface with full-width product configuration table
* Enhanced security with proper input sanitization and validation
* Fixed all security warnings and linter errors
* Improved JavaScript functionality for dynamic product row management

= 1.2.1 =
* Fixed issue where "Enable Minimum Order" checkbox could not be properly disabled
* Improved form submission handling to correctly save checkbox states when unchecked
* Enhanced settings save logic to properly detect Basic Settings form submission

= 1.2 =
* Added Product Links feature - Generate direct checkout links for products
* Added variation selection popup for variable products when copying checkout links
* Added "Copy Checkout Link" action in product list for quick link generation
* Improved admin interface with new "Product Links" submenu page
* Enhanced security with proper input sanitization and validation
* Fixed all linter warnings and security recommendations
* Added phpcs.xml configuration file for code quality
* Improved JavaScript error handling and user feedback
* Added modal popup for variation selection with AJAX support
* Updated menu naming to "Flexible Minimum Order" (restored original name)
* Enhanced copy-to-clipboard functionality with visual feedback
* Added support for variable products in direct checkout links
* Improved code documentation and comments

= 1.0.1 =
* Applied flexmior/fmo_ prefixes across entire codebase for better uniqueness
* Added direct access guards (ABSPATH) to all PHP files
* Implemented robust admin assets enqueue logic for proper page detection
* Fixed all i18n and escaping issues with proper translator comments
* Updated plugin headers with correct URIs and requirements
* Added migration path for old option names to maintain backward compatibility
* Deprecated old shortcode while maintaining backward compatibility
* Removed all debug code and improved code quality
* Enhanced security with proper nonce verification and sanitization
* Updated readme.txt to WordPress.org standards

= 1.0.0 =
* Initial release
* Basic minimum order amount functionality
* Category-based minimum amounts
* Custom message customization
* HPOS compatibility
* Modern admin interface
