== Changelog ==

= 1.7.9 =
* Compliance: prepared the plugin for the WordPress.org directory — removed the self-referencing Plugin URI from the main file header, moved textdomain loading to init, converted inline admin script/style blocks to enqueued assets, and added the translation template (languages/fluentor.pot). The readme now documents the AI services, provider terms of use, and the plugin’s privacy behavior, and lists the wp.org contributor.

= 1.7.8 =
* Maintenance: WordPress Plugin Check clean-up — added the missing translators comments for all placeholder strings, replaced mt_rand() with wp_rand(), and documented the intended SQL/meta-query and display-only request reads with phpcs annotations.

= 1.7.7 =
* UX: a collapsed “Separate-domain setup guide” now appears under the URL-mode options in the setup wizard and Multilingual Settings when separate-domain mode is relevant — it explains the DNS and web-server mapping the mode requires, with a concrete international example.

= 1.7.6 =
* Tuned: the default AI provider is now DeepL (a quality-first default).

= 1.7.5 =
* New: 11 additional AI providers — OpenRouter, DeepSeek, Groq, Mistral, Together AI, Fireworks AI, Cerebras, xAI (Grok), NVIDIA NIM, SambaNova, and Anthropic (Claude) — powered by a new OpenAI Chat Completions adapter and a native Anthropic Messages adapter. Every provider is configurable in Multilingual Settings, verifiable with the Test connection button, and usable through the fluentor_translation_providers filter.
* New: provider registry entries now support a base_url, so any OpenAI-compatible endpoint can be pointed at a custom base URL.

= 1.7.4 =
* Bug fix: ACF choice/enum/asset field values (select, checkbox, radio, link, images, ...) are no longer treated as translatable free text — their stored values are always preserved, and every ACF field is excluded from the generic meta translator and tracked in the source signature.
* New: ACF fields attached to taxonomy terms now follow translations — a per-term Translate action on taxonomy list tables creates/links the translated term, translates its name and description, and applies translated ACF field values (including reference fields) onto the sibling.
* New: ACF options pages can now be translated per language from Multilingual Settings; translated values are stored per language and swapped in automatically on the front end (ACF Pro options pages included).

= 1.7.3 =
* New: ACF reference fields now follow the translation — relationship, post object, page link, and taxonomy fields on a translated copy are remapped to the translated posts/terms in the target language (including references nested inside groups, repeaters, and flexible content); references without a translation keep the source value.

= 1.7.2 =
* New: Pods relationship fields now follow the translation — on a translated copy, "pick" fields that reference posts or terms (e.g. parent/child session links on a translated Pods "Program" item) are remapped to the translated siblings in the target language; references without a translation keep the source value.

= 1.7.1 =
* New: translation providers are now pluggable through a provider registry — themes and plugins can register their own AI providers (including OpenAI-compatible services such as DeepSeek or OpenRouter) via the `fluentor_translation_providers` filter, with no core edits. Dispatch, key sanitization, default settings, chunk limits, model selection, and all provider labels now read from the registry.
* New: a "Test connection" button on the Multilingual Settings page checks the saved provider API key on demand and reports the result, so you can confirm your provider (built-in or custom) works before translating.

= 1.7.0 =
* Maintenance: removed the unused legacy Search & Replace Elementor-JSON engine and search-history storage, and the related search-batch-size setting; the genuinely-used helpers it hosted now live in the logging and translation render modules.
* Maintenance: rebranded remaining "ElementorTextReplacer" package docblocks and "ETP" fallback log prefixes to Fluentor.

= 1.6.9 =
* UX: the AI Translation page's Content type filter now shows Elementor templates under a clear "Elementor Templates" label instead of the raw "Template"/"elementor_library" name.

= 1.6.8 =
* New: Elementor Loop Grid / Loop Carousel support — translating a page now points its loop widgets at the translated Loop Item template (when one exists), and loop queries on the frontend are scoped to the current language so a translated page lists translated custom post type entries.

= 1.6.7 =
* New: the source language of a post/page can now be changed directly from the edit screen — the Translations meta box includes an inline language selector that saves immediately.
* Bug fix: languages whose display name was stored as a bare code (e.g. "bg" instead of "Bulgarian") now show their full name in list tables and language selectors, and the stored name is repaired automatically on upgrade.

= 1.6.6 =
* New: a Language filter dropdown in the list-table toolbar of every enabled post type (next to All dates / Filter) lets you view posts by language — posts without an explicit language resolve to the site default and show under it.
* New: an inline Language selector on every row of enabled post-type and taxonomy list tables lets you set or change an item's language (or restore the default) in one click.
* New: "Translate" is now a reliable WordPress bulk action on enabled post-type list tables — it works for posts that only resolve to the default language, not just posts with an explicitly assigned language.

= 1.6.5 =
* Bug fix: the "select all" checkbox on the AI Translation page now actually selects every candidate — previously it only toggled itself and never checked the rows (and it stays in sync with individual selections, including a partial-selection state).

= 1.6.4 =
* Bug fix: batch translation from the AI Translation page is fixed — the AJAX handler was registered under a legacy action name the page's JavaScript no longer uses, so every batch request silently failed with a generic error and nothing was logged. The handler is now registered under the current action name (plus a legacy alias).

= 1.6.3 =
* Bug fix: DeepL requests now retry once with backoff on transient rate-limit (429) and server (5xx) errors, which previously caused batch translations from the AI Translation page to fail while single-post translations succeeded.
* Bug fix: bare ampersands in content (e.g. "Tom & Jerry") are now protected through translation, so DeepL's HTML tag handling no longer rejects them as invalid XML.
* UX: enabling a new content type in Multilingual Settings now auto-assigns the default language to its existing posts, so they immediately appear as translatable candidates (covers custom post types created via Pods).

= 1.6.2 =
* UX: the setup wizard's first step now starts with the site's own WordPress language (Settings → General → Site Language) instead of hard-coded English — applied to fresh installs and to existing installs that still have the untouched English default.

= 1.6.1 =
* Bug fix: legacy etp_* options are now deleted the moment their values are migrated (and purged again on upgrade), so a leftover row can never resurrect your saved provider keys or languages after a fresh install.
* UX: the setup wizard's AI Translation step now offers a "Remove saved key" control, so a stored provider key can be cleared directly from the wizard without opening Multilingual Settings.

= 1.6.0 =
* Bug fix: uninstall now also removes the legacy (pre-rename) options, tables, and meta so a fresh install can never resurrect previous languages or saved provider keys.
* Bug fix: provider API keys that were accidentally stored double-encrypted are auto-repaired — previously such keys decrypted to another encrypted marker, which was sent to providers verbatim and rejected (e.g. DeepL). The stored key is re-encrypted once so translation works again without re-entering the key.
* Bug fix: the settings sanitizer now refuses to re-encrypt an already-encrypted key, preventing future double-encryption.

= 1.5.9 =
* New: Fluentor Dashboard — a plugin home page showing your multilingual status at a glance (languages, translatable/translated posts, translation provider), an ordered “what’s next” guide, and quick cards linking to AI Translation, Translation Files, and Multilingual Settings. The setup wizard now finishes on the Dashboard.

= 1.5.8 =
* UX: removed the duplicate top-level "Fluentor" menu item — the plugin’s main page is now the single "AI Translation" item.
* UX: the wizard now states clearly that it only sets up the multilingual foundation and that you translate your content yourself afterwards; finishing leads to the AI Translation page, and the completion notice also points to the Translation Files editor.
* UX: clearer plain-language explanation on the wizard’s Existing Content step.
* UX: Multilingual Settings sections (except Languages) are now collapsed by default for a less overwhelming page.

= 1.5.7 =
* UX: setup wizard — merged Slug Settings into the URL Modifications step (the wizard is now 6 steps) and removed the redundant "Practical effect" note from the Post Types & Taxonomies step.

= 1.5.6 =
* Bug fix: uninstall now truly removes all Fluentor data — languages, settings, encrypted provider keys, Polylang bridge state, meta, tables, and transients — so a clean reinstall starts empty.

= 1.5.5 =
* UX: Polylang bridge — Actions moved into the main page area as the primary action instead of the sidebar.
* UX: Polylang bridge — the one-way migration reports its status inline (progress, success with stats, or error) through an AJAX notification instead of a WordPress admin notice.
* UX: Polylang bridge — a guided Next Steps flow appears after migration (review posts, verify Elementor templates, deactivate Polylang) plus a one-click switch to the native runtime.
* UX: setup wizard AI provider step — restructured into a clear provider card with compact, full-width dropdowns, per-provider descriptions, and a cleaner test-connection row.

= 1.5.4 =
* UX: resume incomplete translation jobs after a tab close or reload; retry failed jobs from the Recent Jobs list with error details.
* UX: staged progress feedback for single-post AI translation.
* UX: AI provider step in the setup wizard with a live connection test.
* Accessibility: aria-current on the active switcher language and reduced-motion support.
* Maintainability: split the Translation Files editor page into per-section render files and moved its inline JavaScript to a dedicated asset.

= 1.5.3 =
* Performance: per-request settings cache; cached translation-group lookups with invalidation; conditional rewrite-rule flushing; filterable AI retry limit and backoff; pre-filtered PO sync fuzzy matching; output buffering and switcher assets loaded only when used; daily cron plus opportunistic pruning of the translation-jobs table.
* Security: provider API keys encrypted at rest and masked in settings; Gemini key sent via request header instead of a URL parameter; per-user daily AI usage limit; translation backup path containment checks; path-traversal rejection in locale normalization.

= 1.5.2 =
* Multilingual structure, AI translation, language switcher, and translation-file editor releases.

