=== 4Linking ===
Contributors: 04codedev
Tags: internal linking, automatic internal linking, pillar pages, link building, seo, interlinking, ai content, semantic linking, knowledge base, content generation
Requires at least: 6.0
Tested up to: 7.0
Requires PHP: 7.4
Stable tag: 4.6.121
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Internal linking for WordPress with pillar pages and rules. AI content and semantic linking available in PRO.

== Description ==

**4Linking** is an internal linking plugin for WordPress built for editors, agencies and content teams. It helps you maintain a clean internal link structure across sites of any size — from a small blog to an editorial site with thousands of posts — without the manual work that internal linking usually requires.

The free version (4Linking Lite) handles rule-based internal linking, pillar pages, exclusions and a link map. The PRO version adds AI content generation, semantic linking based on embeddings, knowledge bases with verified data, image generation, translation and full automation pipelines.

= What 4Linking Lite does (free) =

4Linking Lite automates internal linking on your WordPress site using a clear, controllable system: **rules**. You define explicit relationships between content and pillar pages, and the plugin applies them consistently across the site as new content is published.

Concretely, the free version includes:

* **Rule-based internal linking** — define which keywords should link to which URLs, with custom anchor text, frequency caps and priority. Up to 5 active rules.
* **Pillar pages** — mark up to 2 strategic pages that receive preferential internal links from related content.
* **URL exclusions** — list URLs that should never receive or emit internal links (legal pages, login, checkout, etc.).
* **Basic link map** — total count of internal links created by the plugin.
* **Compatible with the WordPress block editor and classic editor**.
* **No external services required** — the Lite version runs entirely on your server with no calls to third-party APIs.

= Who it's for =

4Linking is designed for three main profiles:

* **Online editors and media sites** that publish multiple pieces per day and need to maintain internal architecture without it becoming a full-time job.
* **SEO agencies** managing multiple client sites that need to replicate configurations, templates and rules reliably.
* **Content and marketing teams** producing SEO blog content systematically, who want to free up execution time to focus on strategy and review.

= What 4Linking PRO adds =

When you upgrade to 4Linking PRO, you unlock the full content production pipeline inside WordPress:

* **AI content generation** — write complete articles with AI: titles, structure, sections, FAQ, conclusion. Three lengths (short, medium and pillar), seven tones, eight structures (guide, listicle, comparison, review, FAQ, etc.) and configurable language.
* **Knowledge bases (KB) with verified data** — store your own information (data, descriptions, FAQs, vocabulary) and have the AI consult it before writing. The system is instructed to ground factual claims in your material. **An automatic editorial audit detects unsupported statements and flags them for your review** before publishing. This doesn't eliminate AI hallucinations entirely — no system can — but it makes them visible so you can verify and fix.
* **Semantic internal linking** — instead of matching keywords literally, the PRO version uses OpenAI embeddings to detect topical relationships between posts. A "soccer tactics" article can link to a "youth training" article without sharing any literal keyword, because their meaning is related.
* **Anti-reciprocal triangular pattern** — semantic links are arranged in triangles (A→B→C→A) instead of pairs (A↔B), which Google interprets more naturally and distributes authority more organically.
* **Orphan post detection** — automatically identifies posts that receive no internal links from other posts and prioritises them for inbound linking.
* **AI image generation** — original featured images for each article, optimised to WebP, with SEO metadata (alt, title, caption) generated automatically.
* **Translation** — translate posts to multiple languages using GPT-4o with native Polylang integration. Each translation is an independent post with its own URL and SEO architecture.
* **Automation pipeline** — schedule the creation, linking, translation and publication of articles in autopilot. Define a list of titles and a frequency: the plugin generates and publishes on its own.
* **Templates** — save your content configuration (length, tone, KB assigned, etc.) for reuse across articles.
* **Email notifications, logs and editorial audit panel** — full operational visibility for production-level use.

= Why 4Linking is different =

There are many internal linking and SEO plugins for WordPress, and they all have their place. 4Linking is built for one specific job: serious internal linking at scale, with optional AI content production on top.

* **Versus general SEO plugins (Yoast, Rank Math)** — those handle analysis and on-page SEO; 4Linking specialises in the actual mechanics of internal linking and content creation. They complement each other well.
* **Versus keyword-match linking plugins (Link Whisper)** — they detect literal keyword matches; 4Linking PRO adds semantic understanding based on embeddings, plus content generation, knowledge bases, translation and automation in one product.
* **Versus standalone AI content generators (Jasper, Surfer SEO)** — those live outside WordPress, requiring copy-paste and separate linking/image workflows. 4Linking integrates content generation, linking and publishing in a single flow inside WordPress.

= Privacy and data =

**4Linking Lite makes no calls to any external service.** It runs entirely on your server using WordPress's standard database and APIs.

**4Linking PRO** uses the OpenAI API for AI content, embeddings, translation and image generation. It works under a **Bring Your Own Key (BYOK)** model: you provide your own OpenAI API key directly in the plugin settings, and the plugin makes calls from your server to OpenAI. **Your content is never routed through 4Linking's servers** — it goes directly from your WordPress to OpenAI and back. You pay OpenAI directly for usage based on their current pricing.

= Requirements =

* WordPress 6.0 or higher
* PHP 7.4 or higher
* For translation (PRO): Polylang installed and active
* For AI features (PRO): an OpenAI account with API access (paid separately to OpenAI based on your usage)

== Installation ==

1. Upload the `04-internal-linking` folder to `/wp-content/plugins/`, or install through the WordPress plugin directory by searching "4Linking".
2. Activate the plugin through the **Plugins** menu in WordPress.
3. The plugin adds a **4Linking** entry to your WordPress admin menu. The welcome screen will guide you through the initial setup.
4. Go to **4Linking → Enlazado** to start creating your first internal linking rules and pillar pages.
5. (Optional) To upgrade to PRO, visit [4linking.com](https://4linking.com) for plans and pricing.

== Frequently Asked Questions ==

= Do I need to pay anything to use the free version? =

No. 4Linking Lite is completely free and makes no calls to any paid service. You can use rule-based internal linking, pillar pages, exclusions and the link map without any cost or signup.

= What's the difference between Lite and PRO? =

Lite handles rule-based internal linking only: up to 5 rules, 2 pillar pages, exclusions and a basic link map. PRO adds AI content generation, knowledge bases with verified data, semantic linking using embeddings, image generation, translation, automation pipelines and unlimited rules and pillar pages. See the description above for a full comparison.

= Does 4Linking work with my SEO plugin (Yoast, Rank Math, etc.)? =

Yes. 4Linking is designed to complement general SEO plugins, not replace them. Yoast and Rank Math handle analysis, meta tags and on-page SEO; 4Linking handles internal linking mechanics and (in PRO) content production. Many users run both together without issues.

= Does the AI really write good content? Won't it sound robotic? =

PRO's content generation includes a system of 19 style rules that the AI must follow, plus automatic post-filters that detect and rewrite common "AI-sounding" patterns (filler phrases, formulaic transitions, empty marketing adjectives). After generation, an editorial audit panel rates the article across five categories (AI smell risk, data to verify, intro naturalness, authorial voice, section openings) and highlights the specific sentences you should review. The result still benefits from human review, but it's significantly above the standard AI-generated baseline.

= How does the knowledge base prevent AI hallucinations? =

When you generate an article with PRO and have a knowledge base assigned, the system selects the most relevant entries from your verified material and injects them into the prompt as authoritative context. The AI is then instructed to ground all factual claims (numbers, dates, citations, study names) in that material — and the post-generation audit specifically flags unsupported statements so you can verify or remove them. No system eliminates AI hallucinations completely, but this combination makes them visible and reduces them substantially in practice.

= What happens to my data if I uninstall the plugin? =

By default, uninstalling 4Linking removes all plugin-related data: rules, pillar pages, exclusions, settings and the link map. There's an option in **Ajustes → Generales** to preserve data on uninstall if you prefer.

= Is 4Linking compatible with WooCommerce? =

Yes. The plugin works alongside WooCommerce without conflicts and respects product pages just like any other content type.

= Where do I get support? =

For the free version, please use the [WordPress.org support forum](https://wordpress.org/support/plugin/04-internal-linking/). For PRO customers, dedicated support is available at [4linking.com/support](https://4linking.com/support) or by email at support@4linking.com.

== Screenshots ==

1. Link map showing internal linking stats across the site.
2. Creating an internal linking rule with anchor text, frequency and priority.
3. Pillar pages configuration: strategic content that receives preferential links.
4. URL exclusions: pages that should never receive or emit internal links.
5. (PRO) AI content generation form with tone, length and structure options.
6. (PRO) Editorial audit panel showing risk categories after content generation.
7. (PRO) Knowledge base management with verified entries.
8. (PRO) Automation pipeline scheduling articles in autopilot.

== Changelog ==

= 4.6.60 =
* Menu order: Enlazado now comes before Crear contenido.

= 4.6.58 =
* The rule link-detail view now uses the same slide-in side panel as the pillar detail, with a stats bar and search filter for a consistent experience.

= 4.6.57 =
* Fixed the pillar link-detail side panel rendering misplaced and unstyled (its element id no longer matched the stylesheet); it now slides in correctly.

= 4.6.56 =
* Fixed the rule link-detail, confirm and CSV import dialogs appearing unstyled and misplaced at the bottom of the page; they now display correctly centered.

= 4.6.55 =
* Minor readme wording cleanup.

= 4.6.54 =
* Database upgrade routine now verifies a table exists before describing or altering it, avoiding database notices in partially-initialised environments.

= 4.6.53 =
* Passed the explicit escape parameter to fputcsv()/str_getcsv() so the CSV import/export no longer raises PHP 8.4 deprecation notices.

= 4.6.52 =
* Removed all remaining license-related code paths and references from the free build, so the plugin contains no license-checking machinery whatsoever.

= 4.6.51 =
* Internal: corrected an outdated code comment that referenced the old text domain.

= 4.6.50 =
* The CSV rule import button is now always enabled; it validates and prompts for a file on click instead of starting disabled. Removes any appearance of a restricted built-in feature.

= 4.6.49 =
* Plugin Check compliance: use gmdate() for export filenames; output stream handling in CSV export; documented dynamic SQL placeholder count; "Tested up to" bumped to 7.0; removed manual textdomain loading (WordPress.org loads translations automatically) and renamed language files to match the plugin slug.

= 4.6.48 =
* Fixed: the "Pillar pages" tab icon was not displaying. The output sanitizer now allows the SVG polygon element used by that icon.

= 4.6.47 =
* Minor: internal version bump.

= 4.6.46 =
* The link map summary and table now show semantic-link columns only when the semantic engine is available, so the free edition presents a clean rules-only view with no references to features it does not include.

= 4.6.45 =
* Renamed internal admin page slugs to use a unique, distinct prefix (flinkil-) instead of the short generic one, to avoid any chance of conflicts with other plugins. The main menu slug is unchanged for update compatibility.

= 4.6.44 =
* Output escaping: admin markup (rule and pillar rows, hub navigation) is now passed through wp_kses() with an explicit allow-list at output time, and several conditional class attributes are escaped with esc_attr(). No visual or functional change; this hardens output following WordPress.org guidelines.

= 4.6.43 =
* Hardened database queries: post-type filters and ID lists in the batch processor and link stats now use prepared statements with placeholders instead of building the SQL by string concatenation.

= 4.6.42 =
* Internationalization: the translatable strings now use a text domain that matches the plugin slug, so the plugin can be translated through the directory's tools.

= 4.6.41 =
* Removed the "Select file" button from the backup restore panel; drag-and-drop is now the single, reliable way to pick a file there.
* Fixed backup restore writing to the wrong database tables and discarding settings on import (an internal table/option prefix mismatch). Restoring a backup now correctly recovers pillar pages, rules, exclusions, templates, knowledge bases, automations and global settings.

= 4.6.40 =
* Backup restore now works in every edition. The restore handler was previously unavailable in the free edition, which caused an HTTP 400 when uploading a backup file. The export class already adapts to the installed edition (it skips sections whose tables don't exist), so both editions now have a complete, working backup/restore for everything they manage.

= 4.6.39 =
* Backup restore: the "Select file" button and dropzone now reliably open the file picker (added a direct inline handler as a guaranteed fallback alongside the existing delegated one).

= 4.6.38 =
* Fixed the "Select file" button in the backup restore panel, which did not open the file picker (switched from a synthetic jQuery click to a native click on the file input). Added a matching "Select file" button to the rules CSV importer for a consistent experience. Expired-session uploads now show a clear "reload the page" message instead of a bare HTTP 400.

= 4.6.37 =
* Removed the duplicate Import/Export CSV buttons from the Rules page; rule CSV import/export now lives only in Sistema -> Herramientas to avoid confusion.

= 4.6.36 =
* Removed the free-tier numeric caps entirely. Pillar pages and rules are now unlimited in every edition, and the synonyms field is always available. When a paid license lapses, internal linking keeps working with no limit; only the premium modules (content, images, translation, automation, semantic, knowledge base) are gated. This also removes all locked/limited built-in functionality from the free build.

= 4.6.35 =
* Crear contenido consistency: Imágenes, Traducciones and Automatizaciones now share the same page background as Artículos, and their headers sit at the same position, so switching between the four tabs no longer makes the content jump.

= 4.6.34 =
* Fix: text inside the Crear contenido form selects was clipped vertically (notably in Safari). Selects now use a fixed height with centered single-line text so the option labels display in full.

= 4.6.33 =
* Sistema hub alignment: the navigation cards now share the same centered container as the section content below, so the cards' left edge lines up with the settings sidebar instead of floating centered across the screen.

= 4.6.32 =
* Sistema hub polish: opens on Ajustes by default, with the navigation order Ajustes / Bases de conocimiento / Herramientas. Removed the redundant page titles on Ajustes and Herramientas (the active hub card already names the section), so the sidebar column and the content panel align at the top. Settings content is now centered, matching Crear contenido.

= 4.6.31 =
* Fix: the Sistema hub now shows its navigation cards (Bases de conocimiento / Ajustes / Herramientas). The Ajustes and Herramientas pages render their own headers and don't use the shared page-header component, so the hub now prints the navigation directly.

= 4.6.30 =
* Maintenance release. Same as 4.6.29 (menu restructure into hubs) with a version bump to force a clean reinstall on servers where stale plugin files were being served.

= 4.6.29 =
* Menu restructure: the sidebar is now organised into hubs. "Crear contenido" groups Artículos, Imágenes, Traducciones and Automatizaciones. "Sistema" groups Bases de conocimiento (Paid), Ajustes and Herramientas. The top-level menu drops from ten-ish entries to four (Primeros pasos · Enlazado · Crear contenido · Sistema). All old page URLs still resolve and redirect to the matching tab, so nothing breaks.

= 4.6.28 =
* Polish: the hub navigation cards are now centered and sit just below the section header (instead of floating at the very top-left), so the navigation feels integrated with the section content.

= 4.6.27 =
* Redesign: the Enlazado hub navigation is now a row of compact icon cards (Páginas pilar / Reglas / Análisis semántico / Mapa de enlaces) instead of the old underlined tabs. The active card is highlighted in blue. The navigation is centralised in a reusable helper so the same look can be applied to other hubs later.

= 4.6.26 =
* Polish: dialog buttons are now centered. Fixed singular/plural agreement in the bulk-delete dialog text ("esta regla ha generado" vs "estas reglas han generado").

= 4.6.25 =
* Improvement: bulk rule deletion now uses the same three-option dialog as the single-rule trash icon (Cancelar / Eliminar solo las reglas / Eliminar reglas y sus enlaces). Previously bulk delete always removed the links too, with no choice. The backend now honours a keep_links flag so "Eliminar solo las reglas" preserves the links those rules inserted.

= 4.6.24 =
* Fix: the three buttons in the rule delete dialog now stay on a single row. The dialog widens to 620px when it has three actions (and remains 420px for the usual two-button case), and the footer no longer wraps.

= 4.6.23 =
* Improvement: the rule delete dialog now matches the rest of the plugin's confirmation dialogs — circular red trash icon, bounce-in animation, centered title/message and a red primary action. Three clearly-ordered buttons: Cancelar / Eliminar solo la regla / Eliminar regla y sus enlaces.
* Fix: bulk delete of rules now shows a working confirmation dialog. It previously used a modal whose CSS classes had no styles, so the dialog rendered invisible. Routed through the canonical FLINKDialog.delete dialog.

= 4.6.22 =
* Fix (root cause): the rule confirm dialog was invisible. A second .il-modal-overlay rule in admin.css set opacity:0 (it expected an .is-open class this dialog never used), so the dialog rendered fully transparent — present in the DOM and catching clicks, but unseen. The next click dismissed the invisible overlay. Rebuilt the dialog under its own #flcdlg-overlay namespace with the critical layout/visibility styles written inline, so no external stylesheet can ever hide it again. Affects delete, bulk delete and all rule-action confirmations.

= 4.6.21 =
* Fix (definitive): rule delete modal no longer flashes and disappears. Root cause was the dismiss listener using a click event: the opening click's mouseup landed on the freshly-inserted overlay and was read as a "click outside". Reworked to require both mousedown AND mouseup on the backdrop, which the opening click can never satisfy.
* Improvement: admin script cache-busting now keys on plugin version + file mtime, so updates always pick up the new JS even behind aggressive browser/CDN caching.

= 4.6.20 =
* Improvement: clearer tooltip on the rule reprocess button ("Reprocesar regla en todos los posts") so its purpose is obvious at a glance.

= 4.6.19 =
* Fix: rule deletion modal no longer flashes and disappears immediately. The "click outside to dismiss" listener was catching the original click that opened the modal as it bubbled up through the DOM. Now guarded with a 300ms minimum lifetime — the dismissal listener ignores any close attempt that arrives before the user could plausibly have read the dialog.

= 4.6.18 =
* Fix: rule action modal (delete + bulk delete) now actually works. The previous fix changed the modal's CSS class names from `il-modal-*` to `flink-modal-*` in the JavaScript but the matching CSS in `admin.css` still used the legacy names. The modal was being inserted into the DOM completely unstyled, so users perceived "clicking the trash icon does nothing". Reverted the class names in the JS to match the existing CSS.

= 4.6.17 =
* Fix: header illustrations on all main pages now render correctly. Previously the blue container appeared empty because `wp_kses_post()` was stripping every SVG element.
* Fix: "IA: generar sinónimos y plurales" button no longer overflows its container. Width cap now lifted automatically when the slot holds this longer label (also covers translations where the label is even longer).
* Fix: rule action modal (delete + bulk delete) now responds to clicks. Confirm/cancel/close buttons had mismatched IDs after the prefix migration; aligned both sides on `flink-modal-*`.
* Fix: "Descargar reglas (CSV)" and "Descargar copia (JSON)" no longer return a blank page. The export URLs used the legacy `il_action=` param while the handler listened for `flink_action=`. Aligned both sides.
* Fix: JSON export now actually includes optional sections (knowledge bases, content templates, image templates, automations). Previously the `SHOW TABLES LIKE` checks compared the real table name against a renamed string and never matched, so the export silently skipped those sections.
* Fix: JSON export now also includes plugin settings. The settings query was still using the legacy `il_%` LIKE prefix; updated to the current `flink_%`.

= 4.6.16 =
* Fix: "Mapa de enlaces" page now updates the link-stats cache after every bulk-apply operation. Previously the page could remain at zero counts even after applying rules to thousands of posts, until the user manually pressed "Recalcular todo".
* Fix: link-stats cache table name aligned with the rest of the plugin tables (`wp_il_link_stats`) for consistency. Existing installations are migrated automatically on activation.
* `maybe_install()` now verifies that the table physically exists, not just the schema version option — this protects against edge cases where the option was set but the table got dropped.
* Internal: build script now performs three additional safety checks before producing the ZIP (require_once paths resolve, called methods exist, bootstrap simulation succeeds).

= 4.5.1 (PRO) =
* (PRO) Fix: "Eliminar clave de OpenAI" did not actually delete the key after confirming in the new FLINKDialog modal. The native form submit was bypassing the `il_delete_openai_key` POST field that the server handler needs. Now injected as a hidden field before submitting.
* (PRO) Consent modal links updated to the canonical legal URLs on 4linking.com: `/politica-de-privacidad/` and `/terminos-y-condiciones/`.
* (PRO) Automatic language detection: when WordPress is running in an English locale, the consent modal links to the English versions (`/en/privacy-policy/` and `/en/terms-and-conditions/`). Other locales fall back to the Spanish versions.

= 4.5.0 (PRO) =
* (PRO) New OpenAI BYOK consent flow: when saving or replacing the OpenAI API key, the plugin now displays an informed-consent modal explaining the international transfer to OpenAI servers, the BYOK model and the user's responsibility to review AI-generated content before publishing. A required checkbox must be ticked to continue.
* (PRO) Consent audit-trail: each accepted consent is recorded in the option `il_openai_consent_log` (timestamp, user, IP, masked key hint) up to the 20 most recent entries. Provides RGPD art. 13 transparency evidence.
* (PRO) Server-side fallback gate in `il_openai_key` sanitize callback: rejects new key values not preceded by a fresh consent record (within 5 minutes), protecting against form submissions that bypass the JS layer.
* (PRO) "Eliminar clave" button now uses the branded FLINKDialog modal instead of the native browser `confirm()`, consistent with the rest of the plugin's destructive actions.
* (PRO) Filter `il_legal_urls` added so private deployments can override the URLs of the Privacy Policy and Plugin Terms shown in the consent modal.

= 4.4.39 =
* Improved upsell experience: animated demos on every PRO feature page show what the feature does step by step.
* PRO features now appear in the sidebar with a ✨ marker so users can discover and explore them.
* Settings tabs for Modules and License now show clear upgrade information instead of empty screens.
* Light visual refresh on upsell pages.

= 4.4.38 =
* First release on WordPress.org as 4Linking Lite.
* Rule-based internal linking, pillar pages, exclusions and basic link map.

== Upgrade Notice ==

= 4.5.1 =
(PRO only) Fixes the "delete OpenAI key" button that wasn't actually deleting the key after confirmation. Updates the consent modal links to the canonical legal URLs and adds automatic language detection for English locales.

= 4.5.0 =
(PRO only) Adds a consent modal before saving the OpenAI API key, with an audit trail of consents for RGPD compliance. Existing keys are not affected; the modal only appears when changing or saving a new key.

= 4.4.39 =
Improved upsell experience with animated demos and clearer information about PRO features. No changes to the rule-based internal linking engine.

= 4.4.38 =
First release.
