Files
igny8/v2/V2-Execution-Docs/03A-wp-plugin-standalone.md
IGNY8 VPS (Salman) 0570052fec 1
2026-03-23 17:20:51 +00:00

912 lines
44 KiB
Markdown

# IGNY8 Phase 3: WordPress Plugin — Standalone SEO (03A)
## 10-Module Free SEO Plugin for WordPress
**Document Version:** 1.0
**Date:** 2026-03-23
**Phase:** IGNY8 Phase 3 — WordPress Ecosystem
**Status:** Build Ready
**Source of Truth:** Codebase at `/data/app/igny8/`
**Audience:** Claude Code, WordPress Developers, Architects
---
## 1. CURRENT STATE
### Existing WordPress Integration
The IGNY8 WordPress Bridge Plugin v1.5.2 exists at `/data/app/igny8/plugins/wordpress/source/igny8-wp-bridge/`. It provides:
- Content sync from IGNY8 SaaS → WordPress via `POST /wp-json/igny8/v1/sync/push`
- SAG blueprint sync via `POST /wp-json/igny8/v1/sag/sync-blueprint`
- Taxonomy creation via `POST /wp-json/igny8/v1/sag/create-taxonomies`
- API key authentication using `X-IGNY8-API-KEY` header
- REST namespace: `/wp-json/igny8/v1/`
### What Does NOT Exist
- No standalone SEO capabilities (users rely on Yoast/RankMath alongside IGNY8)
- No schema generation, sitemap control, redirect management, or site audit
- No internal link mapping or social sharing features
- No analytics connector or SMTP mail management
- No migration path from competing plugins
### Phase 2 Foundation Available
- 02D Linker Internal: SAGLink model and link scoring logic in IGNY8 backend — feeds the plugin's internal linking module in connected mode
- 02G Rich Schema SERP: 10 JSON-LD schema types and schema validation in IGNY8 backend — feeds the plugin's schema module in connected mode
### What v2 Changes
Phase 3 builds a **completely new plugin** (not a patch to v1.5.2). The v1.5.2 bridge becomes deprecated once v2 is deployed. The new plugin works in two modes:
- **Standalone mode** (this doc): Full free SEO plugin — no IGNY8 subscription required
- **Connected mode** (03B): Extends standalone with IGNY8 SaaS integration
---
## 2. WHAT TO BUILD
### Overview
A comprehensive WordPress SEO plugin with 10 standalone modules that function without an IGNY8 SaaS subscription. Each module is independently toggleable from Settings → Modules. The plugin replaces Yoast SEO, RankMath, or All in One SEO as a complete, free alternative.
### Plugin Identity
- **Plugin Name:** IGNY8
- **Text Domain:** `igny8`
- **REST Namespace:** `/wp-json/igny8/v1/`
- **Option Prefix:** `igny8_`
- **Post Meta Prefix:** `_igny8_`
- **Term Meta Prefix:** `_igny8_term_`
- **Table Prefix:** `{wp_prefix}igny8_`
- **Min Requirements:** WordPress 5.9+, PHP 7.4+
- **License:** GPL v2+
- **Public API:** `igny8()` returns main singleton — e.g., `igny8()->seo->get_title()`, `igny8()->schema->get_json_ld()`
### Module 1: SEO Core
**Purpose:** Focus keyword management, title/meta tag control, content analysis, Open Graph, breadcrumbs, and robots meta — the foundation of on-page SEO.
**Classes:**
| Class | File | Purpose |
|-------|------|---------|
| `IGNY8_SEO_Module` | `modules/seo/class-seo-module.php` | Module bootstrap, hook registration |
| `IGNY8_Meta_Box` | `modules/seo/class-meta-box.php` | Post editor meta box UI + save handler |
| `IGNY8_Title_Tag` | `modules/seo/class-title-tag.php` | `<title>` management via `document_title_parts` filter |
| `IGNY8_Meta_Tags` | `modules/seo/class-meta-tags.php` | Output `<meta>` description, robots, canonical in `<head>` |
| `IGNY8_Content_Analysis` | `modules/seo/class-content-analysis.php` | Real-time SEO scoring in admin JS |
| `IGNY8_Breadcrumbs` | `modules/seo/class-breadcrumbs.php` | Breadcrumb HTML generation + BreadcrumbList schema |
| `IGNY8_OpenGraph` | `modules/seo/class-opengraph.php` | OG + Twitter Card meta tags |
| `IGNY8_Robots_Txt` | `modules/seo/class-robots-txt.php` | Virtual robots.txt manager |
| `IGNY8_Verification` | `modules/seo/class-verification.php` | Webmaster verification code output |
**Features:**
- Focus keyword per post/page/product (primary + secondary keywords array)
- SEO title + meta description editor with live SERP preview
- Content analysis: keyword density, heading structure, readability (Flesch-Kincaid)
- Title tag templates per post type, taxonomy, author, and date archives
- Breadcrumbs via shortcode `[igny8_breadcrumbs]` + function `igny8()->seo->get_breadcrumbs()`
- Open Graph meta tags (og:title, og:description, og:image, og:type)
- Twitter Cards (twitter:card, twitter:title, twitter:description, twitter:image)
- Robots meta per post (noindex, nofollow, noarchive)
- Canonical URL override
- Webmaster verification codes (Google, Bing, Yandex, Pinterest)
- Consolidated `wp_head` output at priority 1 — single hook for all `<title>`, meta, OG, robots, canonical, schema
**Post Meta Keys:**
```
_igny8_focus_keyword -- string: primary focus keyword
_igny8_secondary_keywords -- JSON array: additional target keywords
_igny8_seo_title -- string: custom SEO title
_igny8_meta_description -- string: custom meta description
_igny8_canonical_url -- string: canonical URL override
_igny8_robots_index -- string: index/noindex
_igny8_robots_follow -- string: follow/nofollow
_igny8_og_title -- string: OG title override
_igny8_og_description -- string: OG description override
_igny8_og_image -- int: attachment ID for OG image
_igny8_twitter_title -- string: Twitter title override
_igny8_twitter_description -- string: Twitter description override
_igny8_seo_score -- int: 0-100 overall SEO score
_igny8_content_score -- int: 0-100 content quality score
_igny8_readability_score -- float: Flesch-Kincaid readability
_igny8_last_analysis -- string: ISO timestamp of last analysis
```
**Term Meta Keys:**
```
_igny8_term_seo_title -- string: term archive SEO title
_igny8_term_meta_description -- string: term archive meta description
_igny8_term_robots_index -- string: index/noindex
_igny8_term_og_image -- int: attachment ID
```
**Options:**
```
igny8_seo_settings -- JSON: {title_templates: {...}, separator: " | ", defaults: {...}}
igny8_social_profiles -- JSON: {facebook, twitter, linkedin, youtube, instagram, pinterest}
```
**Hooks:**
- Actions: `wp_head` (priority 1), `add_meta_boxes`, `save_post`, `document_title_parts`
- Filters: `igny8_title_parts`, `igny8_title_separator`, `igny8_meta_description`, `igny8_robots_meta`, `igny8_canonical_url`, `igny8_breadcrumbs`, `igny8_seo_score`
### Module 2: Schema (JSON-LD)
**Purpose:** Automatic and customizable structured data markup for rich search results.
**Classes:**
| Class | File | Purpose |
|-------|------|---------|
| `IGNY8_Schema_Module` | `modules/schema/class-schema-module.php` | Module bootstrap |
| `IGNY8_Schema_Generator` | `modules/schema/class-schema-generator.php` | Main dispatcher, merges all types |
| `IGNY8_Schema_Article` | `modules/schema/class-schema-article.php` | Article/BlogPosting schema |
| `IGNY8_Schema_LocalBusiness` | `modules/schema/class-schema-local-business.php` | LocalBusiness schema |
| `IGNY8_Schema_Product` | `modules/schema/class-schema-product.php` | Product schema (WooCommerce) |
| `IGNY8_Schema_FAQ` | `modules/schema/class-schema-faq.php` | FAQPage schema |
| `IGNY8_Schema_HowTo` | `modules/schema/class-schema-howto.php` | HowTo schema |
| `IGNY8_Schema_Organization` | `modules/schema/class-schema-organization.php` | Organization/Person |
| `IGNY8_Schema_WebPage` | `modules/schema/class-schema-webpage.php` | WebPage/CollectionPage |
| `IGNY8_Schema_Breadcrumb` | `modules/schema/class-schema-breadcrumb.php` | BreadcrumbList |
| `IGNY8_Schema_Service` | `modules/schema/class-schema-service.php` | Service schema |
| `IGNY8_Schema_Custom` | `modules/schema/class-schema-custom.php` | Raw JSON-LD editor |
**Features:**
- Auto-detect schema type per post type
- 10 supported types: Article/BlogPosting, Organization/Person, WebPage/CollectionPage, BreadcrumbList, FAQPage, HowTo, LocalBusiness, Service, Product (WooCommerce), WebSite+SearchAction
- Custom schema editor (raw JSON-LD input)
- Schema validation against Google Rich Results requirements
- Global settings: Organization vs Person, default types per post type
- Single `<script type="application/ld+json">` block in head (merged from all types)
**Methods:** `get_json_ld($post_id)`, `render_schema($post_id)`, `detect_schema_type($post_id)`, `get_organization_schema()`, `get_breadcrumb_schema($post_id)`
**Post Meta:** `_igny8_schema_type`, `_igny8_schema_custom`, `_igny8_schema_faq` (connected), `_igny8_schema_howto` (connected)
**Options:** `igny8_schema_settings` — JSON: `{org_type, name, logo, knowledge_graph}`
**Hooks:** `igny8_schema_types`, `igny8_schema_{type}`, `igny8_json_ld`
### Module 3: Sitemap (XML)
**Purpose:** XML sitemaps with image support and search engine notification.
**Classes:**
| Class | File | Purpose |
|-------|------|---------|
| `IGNY8_Sitemap_Module` | `modules/sitemap/class-sitemap-module.php` | Module bootstrap |
| `IGNY8_Sitemap_Index` | `modules/sitemap/class-sitemap-index.php` | Sitemap index file |
| `IGNY8_Sitemap_Posts` | `modules/sitemap/class-sitemap-posts.php` | Post type sub-sitemaps |
| `IGNY8_Sitemap_Taxonomies` | `modules/sitemap/class-sitemap-taxonomies.php` | Taxonomy sub-sitemaps |
| `IGNY8_Sitemap_Images` | `modules/sitemap/class-sitemap-images.php` | Image sitemap |
| `IGNY8_Sitemap_XSL` | `modules/sitemap/class-sitemap-xsl.php` | XSL stylesheet for browser view |
**Rewrite Rules:**
```
/sitemap_index.xml → sitemap index
/sitemap-{post_type}.xml → post type sitemaps
/sitemap-{taxonomy}.xml → taxonomy sitemaps
/sitemap-images.xml → image sitemap
/sitemap.xsl → XSL stylesheet
```
**Features:**
- Sitemap index + sub-sitemaps per post type and taxonomy
- Image sitemaps
- XSL stylesheet for human-readable browser view
- Respects noindex settings from SEO Core module
- Auto-ping search engines on update
- Exclusion rules (specific posts, taxonomies)
**Options:** `igny8_sitemap_settings` — JSON: `{included_post_types, included_taxonomies, excluded_urls}`
**Hooks:** `igny8_sitemap_post_types`, `igny8_sitemap_taxonomies`, `igny8_sitemap_excluded_urls`
### Module 4: Redirects
**Purpose:** 301/302/307 redirect management with 404 monitoring and auto-redirect on slug changes.
**Classes:**
| Class | File | Purpose |
|-------|------|---------|
| `IGNY8_Redirects_Module` | `modules/redirects/class-redirects-module.php` | Module bootstrap |
| `IGNY8_Redirect_Manager` | `modules/redirects/class-redirect-manager.php` | CRUD + matching engine |
| `IGNY8_404_Monitor` | `modules/redirects/class-404-monitor.php` | 404 logging with hit counts |
| `IGNY8_Auto_Redirect` | `modules/redirects/class-auto-redirect.php` | Auto-redirect on slug change via `post_updated` |
**Features:**
- CRUD for 301/302/307 redirects
- 404 monitoring with hit counts, referrer, user agent (hashed IP for privacy)
- Auto-redirect on slug change via `post_updated` hook
- CSV import/export
- Regex redirect support (advanced)
- One-click redirect creation from 404 log
**Methods:** `add_redirect($source, $target, $type)`, `log_404($url, $referrer)`, `create_redirect_from_404($url, $target)`
**Options:** `igny8_redirect_settings` — JSON: `{auto_redirect_on_slug_change: true}`
**Database Table: `{prefix}igny8_redirects`**
```sql
CREATE TABLE {prefix}igny8_redirects (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
source_url VARCHAR(500) NOT NULL,
target_url VARCHAR(500) NOT NULL,
type SMALLINT DEFAULT 301,
hits INT DEFAULT 0,
last_hit DATETIME NULL,
created_at DATETIME NOT NULL,
is_active TINYINT(1) DEFAULT 1,
INDEX idx_source (source_url(191))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
```
**Database Table: `{prefix}igny8_404_log`**
```sql
CREATE TABLE {prefix}igny8_404_log (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
url VARCHAR(500) NOT NULL,
referrer VARCHAR(500) NULL,
user_agent VARCHAR(500) NULL,
ip_hash VARCHAR(64) NULL,
hits INT DEFAULT 1,
first_hit DATETIME NOT NULL,
last_hit DATETIME NOT NULL,
is_resolved TINYINT(1) DEFAULT 0,
redirect_id BIGINT NULL,
INDEX idx_url (url(191))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
```
### Module 5: Site Intelligence
**Purpose:** Automated site audit with orphan page detection, thin content scanning, duplicate meta finder, and keyword cannibalization detection.
**Classes:**
| Class | File | Purpose |
|-------|------|---------|
| `IGNY8_Intelligence_Module` | `modules/site-intelligence/class-intelligence-module.php` | Module bootstrap |
| `IGNY8_Site_Audit` | `modules/site-intelligence/class-site-audit.php` | Full audit runner |
| `IGNY8_Orphan_Detector` | `modules/site-intelligence/class-orphan-detector.php` | Pages with no inbound links |
| `IGNY8_Thin_Content` | `modules/site-intelligence/class-thin-content.php` | Below threshold word count |
| `IGNY8_Empty_Terms` | `modules/site-intelligence/class-empty-terms.php` | Taxonomy terms with 0 posts |
| `IGNY8_Cannibalization` | `modules/site-intelligence/class-cannibalization.php` | Multiple pages targeting same keyword |
| `IGNY8_Duplicate_Meta` | `modules/site-intelligence/class-duplicate-meta.php` | Duplicate title/description finder |
| `IGNY8_Cluster_Detector` | `modules/site-intelligence/class-cluster-detector.php` | Topic grouping via keyword similarity |
| `IGNY8_Gap_Analysis` | `modules/site-intelligence/class-gap-analysis.php` | SAG gap analysis (connected mode only) |
| `IGNY8_Cluster_Health` | `modules/site-intelligence/class-cluster-health.php` | Cluster health scoring (connected mode only) |
**Features:**
- Site audit runner via WP Cron (weekly) + manual trigger
- Orphan page detection (no internal links pointing to it)
- Thin content scanner (configurable word count threshold, default 300)
- Empty taxonomy term detection
- Duplicate title/meta description finder
- Keyword cannibalization detection (multiple pages targeting same keyword)
- Auto-cluster detection (topic grouping across posts via keyword similarity)
- Dashboard with severity badges (critical/warning/info) and actionable fix suggestions
- Connected mode adds: SAG gap analysis, cluster health scoring (from 01G)
**Methods:** `run_full_audit()`, `get_audit_results($args)`, `get_orphan_pages()`, `get_thin_content()`, `detect_clusters($posts)`
**Options:** `igny8_intelligence_settings` — JSON: `{audit_schedule, thresholds: {thin_content_min: 300}, exclusions}`
**Database Table: `{prefix}igny8_audit_results`**
```sql
CREATE TABLE {prefix}igny8_audit_results (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
audit_type VARCHAR(50) NOT NULL,
post_id BIGINT NULL,
term_id BIGINT NULL,
severity VARCHAR(20) NOT NULL,
message TEXT NOT NULL,
data LONGTEXT NULL,
audit_date DATETIME NOT NULL,
is_resolved TINYINT(1) DEFAULT 0,
INDEX idx_type_date (audit_type, audit_date)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
```
### Module 6: Internal Linking
**Purpose:** Site-wide link crawl, per-post link audit, link suggestions, and orphan content detection.
**Classes:**
| Class | File | Purpose |
|-------|------|---------|
| `IGNY8_Linking_Module` | `modules/linking/class-linking-module.php` | Module bootstrap |
| `IGNY8_Link_Auditor` | `modules/linking/class-link-auditor.php` | Per-post link audit |
| `IGNY8_Link_Suggestions` | `modules/linking/class-link-suggestions.php` | Content similarity link suggestions |
| `IGNY8_Orphan_Links` | `modules/linking/class-orphan-links.php` | Pages with zero inbound links |
| `IGNY8_Link_Graph` | `modules/linking/class-link-graph.php` | Link equity visualization |
| `IGNY8_Auto_Linker` | `modules/linking/class-auto-linker.php` | Auto-link insertion (connected mode only) |
| `IGNY8_Link_Rules` | `modules/linking/class-link-rules.php` | Keyword-based link rules (connected mode only) |
**Features:**
- Full site link crawl + link map stored in `{prefix}igny8_link_map`
- Per-post link audit: outbound count, inbound count, orphan status
- Link suggestions: "This post should link to X" based on content similarity
- Link equity visualization (which pages pass authority)
- Orphan content detection (pages with zero inbound internal links)
- Connected mode adds: auto-link insertion based on keyword rules from IGNY8 backend (02D)
**Methods:** `crawl_links()`, `get_post_links($post_id)`, `get_link_suggestions($post_id)`, `get_orphan_pages()`, `auto_link_content($post_id)` (connected)
**Post Meta:** `_igny8_related_links` (JSON: `[{post_id, anchor_text, priority}]`), `_igny8_link_suggestions` (JSON)
**Options:** `igny8_linking_settings` — JSON: `{auto_link_rules, max_links_per_post}`
**Database Table: `{prefix}igny8_link_map`**
```sql
CREATE TABLE {prefix}igny8_link_map (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
source_post_id BIGINT NOT NULL,
target_post_id BIGINT NOT NULL,
anchor_text VARCHAR(500) NULL,
is_follow TINYINT(1) DEFAULT 1,
link_position VARCHAR(20) NULL,
last_crawled DATETIME NOT NULL,
INDEX idx_source (source_post_id),
INDEX idx_target (target_post_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
```
### Module 7: Google Search Console
**Purpose:** OAuth 2.0 GSC connection with search performance dashboard and keyword tracking.
**Classes:**
| Class | File | Purpose |
|-------|------|---------|
| `IGNY8_GSC_Module` | `modules/gsc/class-gsc-module.php` | Module bootstrap |
| `IGNY8_GSC_Auth` | `modules/gsc/class-gsc-auth.php` | OAuth 2.0 flow |
| `IGNY8_GSC_Dashboard` | `modules/gsc/class-gsc-dashboard.php` | Performance dashboard |
| `IGNY8_GSC_Keywords` | `modules/gsc/class-gsc-keywords.php` | Keyword position tracking |
| `IGNY8_GSC_Indexing` | `modules/gsc/class-gsc-indexing.php` | URL indexing requests (connected mode only) |
| `IGNY8_GSC_URL_Inspection` | `modules/gsc/class-gsc-url-inspection.php` | URL Inspection API (connected mode only) |
**Features:**
- OAuth 2.0 connection flow to Google Search Console
- Search performance dashboard: clicks, impressions, CTR, avg position
- Keyword position tracking over time
- Date range filtering
- Top pages by performance
- Data stored locally for historical tracking
- Connected mode adds: URL Inspection API, indexing requests, status sync from IGNY8 backend (02C)
**Methods:** `authorize_gsc()`, `get_search_metrics($args)`, `get_keyword_positions($args)`, `inspect_url($url)` (connected), `request_indexing($url)` (connected)
**Options:** `igny8_gsc_token` (encrypted), `igny8_gsc_property` (selected GSC property URL)
### Module 8: Socializer
**Purpose:** Lightweight share buttons and social profile management.
**Classes:**
| Class | File | Purpose |
|-------|------|---------|
| `IGNY8_Socializer_Module` | `modules/socializer/class-socializer-module.php` | Module bootstrap |
| `IGNY8_Share_Buttons` | `modules/socializer/class-share-buttons.php` | CSS/JS share button rendering |
| `IGNY8_Social_Profiles` | `modules/socializer/class-social-profiles.php` | Organization social URLs |
| `IGNY8_Auto_Poster` | `modules/socializer/class-auto-poster.php` | Auto-post on publish (connected mode only) |
| `IGNY8_Twitter_API` | `modules/socializer/class-twitter-api.php` | Twitter/X API (connected mode only) |
| `IGNY8_Facebook_API` | `modules/socializer/class-facebook-api.php` | Facebook Pages API (connected mode only) |
| `IGNY8_LinkedIn_API` | `modules/socializer/class-linkedin-api.php` | LinkedIn API (connected mode only) |
| `IGNY8_OG_Image_Generator` | `modules/socializer/class-og-image-generator.php` | Dynamic OG image (connected mode only) |
**Features:**
- Pure CSS/JS share buttons (<5KB total, no external scripts)
- Position options: floating sidebar, above content, below content, inline
- Networks: Facebook, X/Twitter, LinkedIn, Pinterest, WhatsApp, Telegram, Email, Copy Link
- Social profile management (org social URLs)
- Share count display (optional, via API)
- Connected mode adds: auto-post on publish via 02H SocialAccount OAuth, dynamic OG image generation
**Methods:** `render_share_buttons($post_id)`, `get_social_profiles()`, `post_to_social($post_id)` (connected)
**Options:** `igny8_share_settings` — JSON: `{networks, position, style}`
**Frontend Assets:** `share-buttons.css` (<3KB), `share-buttons.js` (<2KB) — conditionally enqueued only when enabled
### Module 9: Analytics + SMTP
**Purpose:** Analytics script injection (GA4, GTM, pixels) and SMTP mail override.
**Classes (Analytics):**
| Class | File | Purpose |
|-------|------|---------|
| `IGNY8_Analytics_Module` | `modules/analytics/class-analytics-module.php` | Module bootstrap |
| `IGNY8_GA_Connector` | `modules/analytics/class-ga-connector.php` | GA4 measurement ID injection |
| `IGNY8_GTM_Connector` | `modules/analytics/class-gtm-connector.php` | Google Tag Manager container |
| `IGNY8_Pixel_Manager` | `modules/analytics/class-pixel-manager.php` | Facebook, TikTok, Pinterest pixels |
| `IGNY8_Script_Manager` | `modules/analytics/class-script-manager.php` | Custom header/footer scripts |
**Classes (SMTP):**
| Class | File | Purpose |
|-------|------|---------|
| `IGNY8_SMTP_Module` | `modules/smtp/class-smtp-module.php` | Module bootstrap |
| `IGNY8_SMTP_Mailer` | `modules/smtp/class-smtp-mailer.php` | SMTP mail override |
| `IGNY8_Email_Log` | `modules/smtp/class-email-log.php` | Delivery log with status |
| `IGNY8_Email_Test` | `modules/smtp/class-email-test.php` | Test email sender |
**Features (Analytics):**
- GA4 measurement ID connector (script injection via `wp_head`)
- Google Tag Manager container ID
- Facebook Pixel, TikTok Pixel, Pinterest Tag
- Custom header/footer scripts (with placement control)
**Features (SMTP):**
- SMTP mail override (host, port, user, pass, encryption SSL/TLS)
- Email delivery log with status tracking
- Test email sender
- From name + from email override
**Options:**
```
igny8_analytics_settings -- JSON: {ga_id, gtm_id, fb_pixel, tiktok_pixel, pinterest_tag, custom_scripts}
igny8_smtp_settings -- JSON: {host, port, user, pass, encryption, from_name, from_email}
```
**SMTP Hooks:** `wp_mail` (override), `wp_mail_from`, `wp_mail_from_name`
**Database Table: `{prefix}igny8_email_log`**
```sql
CREATE TABLE {prefix}igny8_email_log (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
to_email VARCHAR(320) NOT NULL,
subject VARCHAR(500) NOT NULL,
status VARCHAR(20) NOT NULL,
error_message TEXT NULL,
sent_at DATETIME NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
```
### Module 10: Import (Migration)
**Purpose:** One-click migration from Yoast SEO, RankMath, and All in One SEO.
**Classes:**
| Class | File | Purpose |
|-------|------|---------|
| `IGNY8_Importer` | `data/class-importer.php` | Base importer with rollback |
| `IGNY8_Yoast_Importer` | `data/class-yoast-importer.php` | Yoast SEO migration |
| `IGNY8_RankMath_Importer` | `data/class-rankmath-importer.php` | RankMath migration |
| `IGNY8_AIOSEO_Importer` | `data/class-aioseo-importer.php` | All in One SEO migration |
**Features:**
- One-click import from: Yoast SEO, RankMath, All in One SEO
- Imports: focus keywords, SEO titles, meta descriptions, robots settings, redirects, schema settings
- Pre-import preview showing what will be migrated (dry run mode)
- Rollback capability (stores original values before overwrite)
**Meta Key Mapping (Yoast → IGNY8):**
```
_yoast_wpseo_focuskw → _igny8_focus_keyword
_yoast_wpseo_title → _igny8_seo_title
_yoast_wpseo_metadesc → _igny8_meta_description
_yoast_wpseo_canonical → _igny8_canonical_url
_yoast_wpseo_meta-robots-noindex → _igny8_robots_index
_yoast_wpseo_opengraph-title → _igny8_og_title
_yoast_wpseo_opengraph-description → _igny8_og_description
```
**Meta Key Mapping (RankMath → IGNY8):**
```
rank_math_focus_keyword → _igny8_focus_keyword
rank_math_title → _igny8_seo_title
rank_math_description → _igny8_meta_description
rank_math_canonical_url → _igny8_canonical_url
rank_math_robots → _igny8_robots_index + _igny8_robots_follow
rank_math_facebook_title → _igny8_og_title
rank_math_facebook_description → _igny8_og_description
```
**Meta Key Mapping (AIOSEO → IGNY8):**
```
_aioseo_title → _igny8_seo_title
_aioseo_description → _igny8_meta_description
_aioseo_canonical_url → _igny8_canonical_url
_aioseo_robots_noindex → _igny8_robots_index
_aioseo_og_title → _igny8_og_title
_aioseo_og_description → _igny8_og_description
```
---
## 3. DATA MODELS & APIS
### Database Tables (6 total)
All tables created on plugin activation by `class-installer.php`:
| # | Table | Module | Purpose |
|---|-------|--------|---------|
| 1 | `{prefix}igny8_redirects` | Redirects | 301/302/307 redirect rules |
| 2 | `{prefix}igny8_404_log` | Redirects | 404 error logging |
| 3 | `{prefix}igny8_link_map` | Internal Linking | Page-to-page link relationships |
| 4 | `{prefix}igny8_audit_results` | Site Intelligence | Audit findings |
| 5 | `{prefix}igny8_email_log` | SMTP | Email delivery log |
| 6 | `{prefix}igny8_sync_queue` | (Connected prep) | Sync queue for connected mode readiness |
**Table 6: `{prefix}igny8_sync_queue`** (created in standalone for connected mode readiness)
```sql
CREATE TABLE {prefix}igny8_sync_queue (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
igny8_content_id VARCHAR(100) NOT NULL,
content_type VARCHAR(50) NOT NULL,
sync_status VARCHAR(20) NOT NULL DEFAULT 'pending',
wp_post_id BIGINT NULL,
wp_term_id BIGINT NULL,
data LONGTEXT NULL,
created_at DATETIME NOT NULL,
synced_at DATETIME NULL,
error_message TEXT NULL,
INDEX idx_status (sync_status)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
```
### REST API Endpoints (public)
All endpoints under `/wp-json/igny8/v1/`:
| Method | Endpoint | Purpose | Auth |
|--------|----------|---------|------|
| GET | `/related/{post_id}` | Related content links | None (public) |
| GET | `/cluster/{cluster_id}` | Cluster content list | None (public) |
| GET | `/term/{term_id}/content` | Rich term content | None (public) |
| GET | `/audit/summary` | Site audit results | Admin nonce |
| GET | `/structure/overview` | Site structure summary | Admin nonce |
### Options Summary
All options use `igny8_` prefix and store JSON:
| Option Key | Module | Content |
|------------|--------|---------|
| `igny8_seo_settings` | SEO Core | Title templates, separator, defaults |
| `igny8_social_profiles` | SEO Core | Organization social URLs |
| `igny8_schema_settings` | Schema | Org type, name, logo, knowledge graph |
| `igny8_sitemap_settings` | Sitemap | Included post types, taxonomies |
| `igny8_redirect_settings` | Redirects | Auto-redirect on slug change |
| `igny8_intelligence_settings` | Site Intelligence | Audit schedule, thresholds, exclusions |
| `igny8_linking_settings` | Internal Linking | Auto-link rules, max links per post |
| `igny8_gsc_token` | GSC | Encrypted OAuth token |
| `igny8_gsc_property` | GSC | Selected GSC property URL |
| `igny8_share_settings` | Socializer | Networks, position, style |
| `igny8_analytics_settings` | Analytics | GA4, GTM, pixel IDs, custom scripts |
| `igny8_smtp_settings` | SMTP | Host, port, user, pass, encryption |
---
## 4. IMPLEMENTATION STEPS
### File Structure
```
igny8/
├── igny8.php # Plugin header, constants, bootstrap
├── readme.txt # WordPress.org readme
├── uninstall.php # Full cleanup on uninstall
├── includes/
│ ├── class-igny8.php # Main singleton class
│ ├── class-module-manager.php # Register/activate/deactivate modules
│ ├── class-api-client.php # IGNY8 SaaS API client (connected mode)
│ ├── class-connection.php # API key validation, connection status
│ ├── class-utils.php # Shared utilities
│ ├── class-rest-api.php # Plugin REST endpoints
│ ├── class-compatibility.php # Detect Yoast/RankMath conflicts
│ ├── modules/
│ │ ├── seo/ # Module 1 — 9 class files
│ │ ├── schema/ # Module 2 — 12 class files
│ │ ├── sitemap/ # Module 3 — 6 class files
│ │ ├── redirects/ # Module 4 — 4 class files
│ │ ├── site-intelligence/ # Module 5 — 10 class files
│ │ ├── linking/ # Module 6 — 7 class files
│ │ ├── gsc/ # Module 7 — 6 class files
│ │ ├── socializer/ # Module 8 — 8 class files
│ │ ├── analytics/ # Module 9a — 5 class files
│ │ ├── smtp/ # Module 9b — 4 class files
│ │ ├── content-sync/ # Module 11 [CONNECTED] — 6 class files
│ │ └── sag/ # Module 12 [CONNECTED] — 6 class files
│ ├── admin/
│ │ ├── class-admin-menu.php # Top-level menu + submenus
│ │ ├── class-dashboard.php # Overview + quick actions
│ │ ├── class-setup-wizard.php # 6-step first-run wizard
│ │ ├── class-compatibility-notice.php
│ │ ├── views/ # PHP template files
│ │ └── assets/ # admin.css, admin.js, meta-box.css, meta-box.js
│ ├── frontend/
│ │ ├── class-head-output.php # All <head> tag consolidation
│ │ ├── class-share-output.php # Share button rendering
│ │ └── assets/ # share-buttons.css, share-buttons.js
│ ├── data/
│ │ ├── class-installer.php # Create all DB tables on activation
│ │ ├── class-migrator.php # Version-based migration handler
│ │ └── class-importer.php # Base importer + Yoast/RankMath/AIOSEO
│ └── integrations/
│ ├── class-woocommerce.php # WooCommerce SEO + schema
│ └── class-theme-bridge.php # Communication with companion theme
└── languages/
└── igny8.pot # Translation template
```
### Build Sequence
**Phase 1: Foundation (Days 1-3)**
1. Create plugin skeleton: `igny8.php` with header, constants, autoloader
2. Build `class-igny8.php` singleton — `instance()`, `init()`, `load_modules()`
3. Build `class-module-manager.php``register()`, `activate()`, `deactivate()`, `is_active()`, `boot()`
4. Build admin menu structure: `class-admin-menu.php` with top-level + submenus
5. Build setup wizard: `class-setup-wizard.php` with 6 steps
6. Build `class-installer.php` — create all 6 DB tables via `dbDelta()`
7. Build `class-rest-api.php` — register 5 public endpoints
8. Build `class-compatibility.php` — detect Yoast/RankMath/AIOSEO active
**Phase 2: SEO Core (Days 4-7)**
1. Build `IGNY8_SEO_Module` — module bootstrap + all hook registrations
2. Build `IGNY8_Meta_Box` — post editor meta box with all 16 post meta fields
3. Build `IGNY8_Title_Tag` — template system via `document_title_parts` filter
4. Build `IGNY8_Meta_Tags``<meta>` output in `<head>`
5. Build `IGNY8_Content_Analysis` — real-time SEO scoring (keyword density, heading structure, readability)
6. Build `IGNY8_Breadcrumbs` — shortcode + BreadcrumbList schema
7. Build `IGNY8_OpenGraph` — OG + Twitter Card tags
8. Build `IGNY8_Robots_Txt` — virtual robots.txt
9. Build `IGNY8_Verification` — webmaster codes
10. Build `class-head-output.php` — consolidated `wp_head` at priority 1
**Phase 3: Schema + Sitemap + Redirects (Days 8-10)**
1. Build schema module: generator dispatcher + 10 type-specific classes
2. Build sitemap module: index + post/taxonomy/image sub-sitemaps + XSL
3. Build redirects module: CRUD + 404 monitor + auto-redirect
**Phase 4: Site Intelligence (Days 11-13)**
1. Build audit runner with WP Cron weekly schedule
2. Build 7 audit type classes (orphan, thin, empty terms, cannibalization, duplicate meta, cluster detector)
3. Build audit dashboard with severity badges
**Phase 5: Internal Linking (Days 14-15)**
1. Build link crawl engine + link map table
2. Build per-post link audit + suggestions
3. Build link graph visualization
**Phase 6: Socializer + Analytics/SMTP + GSC (Days 16-18)**
1. Build share buttons (<5KB CSS/JS)
2. Build analytics script connectors
3. Build SMTP override + email log
4. Build GSC OAuth flow + dashboard
**Phase 7: Import (Days 19-20)**
1. Build base importer with dry run + rollback
2. Build Yoast → IGNY8 mapping
3. Build RankMath → IGNY8 mapping
4. Build AIOSEO → IGNY8 mapping
**Phase 8: Compliance (Days 28-30)**
1. WordPress.org compliance audit — sanitize all inputs, escape all outputs
2. i18n pass — all strings through `__()` / `esc_html__()` with `igny8` domain
3. readme.txt with full feature list, changelog, screenshots
4. Accessibility review — ARIA labels, keyboard navigation in admin
### Setup Wizard (6 Steps)
| Step | Title | Content |
|------|-------|---------|
| 1 | Site Type | Blog, Business, eCommerce, Local Business, SaaS, Portfolio |
| 2 | SEO Import | Detect existing Yoast/RankMath/AIOSEO, offer import |
| 3 | Site Basics | Site name, Organization/Person, logo, title separator |
| 4 | Social Profiles | Social URLs + default sharing image |
| 5 | Connect to IGNY8 | API key input (optional, clear skip button) |
| 6 | Done | Summary, run first audit CTA |
### Admin Menu Structure
```
IGNY8 (top-level, dashicons-chart-area)
├── Dashboard — Overview + quick actions
├── SEO — Meta box settings, title templates
├── Schema — Default types, organization settings
├── Sitemaps — Post type/taxonomy inclusion
├── Redirects — CRUD + 404 monitor
├── Site Intelligence — Audit dashboard
├── Internal Links — Link map, suggestions
├── Search Console — GSC dashboard
├── Socializer — Buttons, profiles
├── Analytics — GA4, GTM, pixels
├── SMTP — Mail settings, log
├── Import — Migration wizard
└── Settings — Modules toggle, general settings
```
### Performance Rules
| Rule | Implementation |
|------|---------------|
| Zero CSS on frontend unless share buttons enabled | Conditional `wp_enqueue_style` check |
| Zero JS on frontend unless interactive features active | Conditional `wp_enqueue_script` check |
| All `<head>` output in single hook at priority 1 | `class-head-output.php` consolidation |
| Schema as single JSON-LD block | `class-schema-generator.php` merges all types |
| Admin assets only on IGNY8 admin pages | `get_current_screen()` check |
| Meta box assets only on post editor | Screen check before enqueue |
| Site audit via WP Cron, never on page load | `wp_schedule_event()` weekly |
| Link crawl as background process | WP Cron, batch processing |
| Connected API calls never block page requests | WP Cron queue, async |
| Option reads via object cache | `wp_cache_get/set` wrapping |
### WordPress.org Compliance
- GPL v2+ license header in all files
- No phone-home without explicit user consent
- All user-facing strings translatable via `igny8` text domain using `__()`, `esc_html__()`, `_e()`, `esc_html_e()`
- Sanitize all inputs: `sanitize_text_field()`, `wp_kses_post()`, `absint()`, `sanitize_url()`
- Escape all outputs: `esc_html()`, `esc_attr()`, `esc_url()`, `wp_kses_post()`
- Use WP APIs: Settings API, REST API, `WP_Query` — no direct DB queries where WP functions exist
- Nonce verification on all form submissions: `wp_nonce_field()` / `wp_verify_nonce()`
- Capability checks: `current_user_can('manage_options')` for admin pages
---
## 5. ACCEPTANCE CRITERIA
### Foundation
- [ ] Plugin activates without errors on WordPress 5.9+ with PHP 7.4+
- [ ] All 6 database tables created on activation via `dbDelta()`
- [ ] Setup wizard runs on first activation with all 6 steps functional
- [ ] Module manager toggles modules on/off without errors
- [ ] `igny8()` public API returns singleton with module access
- [ ] Compatibility checker detects active Yoast/RankMath/AIOSEO and shows admin notice
### SEO Core (Module 1)
- [ ] Meta box renders on post/page/product edit screens with all fields
- [ ] SEO title and meta description save to post meta and render in `<head>`
- [ ] Title tag templates work with variables: `{title}`, `{site_name}`, `{separator}`
- [ ] Content analysis scores keyword density, heading structure, readability (0-100)
- [ ] Breadcrumbs render via shortcode `[igny8_breadcrumbs]` with BreadcrumbList schema
- [ ] Open Graph + Twitter Card tags render correctly in `<head>`
- [ ] Robots meta (noindex/nofollow) respected by output and sitemaps
- [ ] Canonical URL override renders in `<head>`
### Schema (Module 2)
- [ ] Auto-detects schema type per post type
- [ ] Renders valid JSON-LD in single `<script>` block
- [ ] All 10 schema types produce valid structured data
- [ ] Custom JSON-LD editor accepts and renders user input
- [ ] Schema passes Google Rich Results Test validation
### Sitemap (Module 3)
- [ ] `/sitemap_index.xml` renders with sub-sitemap links
- [ ] Per-post-type and per-taxonomy sub-sitemaps render
- [ ] Image sitemap included
- [ ] XSL stylesheet provides human-readable browser view
- [ ] Noindexed posts excluded from sitemap
- [ ] Search engines pinged on sitemap update
### Redirects (Module 4)
- [ ] Create/read/update/delete 301/302/307 redirects
- [ ] 404 errors logged with hit count, referrer, hashed IP
- [ ] Auto-redirect created on slug change
- [ ] One-click redirect from 404 log entry
- [ ] CSV import/export functional
### Site Intelligence (Module 5)
- [ ] Full audit runs via WP Cron weekly and manual trigger
- [ ] Orphan pages, thin content, empty terms, duplicates, cannibalization detected
- [ ] Dashboard shows severity badges (critical/warning/info) with counts
- [ ] Individual audit items dismissible/resolvable
### Internal Linking (Module 6)
- [ ] Full site link crawl completes and populates `igny8_link_map`
- [ ] Per-post link audit shows inbound/outbound counts
- [ ] Link suggestions generated based on content similarity
- [ ] Orphan pages (zero inbound links) identified
### GSC (Module 7)
- [ ] OAuth 2.0 flow connects to Google Search Console
- [ ] Dashboard shows clicks, impressions, CTR, avg position with date range
- [ ] Keyword position tracking displays historical data
### Socializer (Module 8)
- [ ] Share buttons render at configured position (<5KB total)
- [ ] All 8 networks functional (Facebook, X, LinkedIn, Pinterest, WhatsApp, Telegram, Email, Copy)
- [ ] Button display conditionally enqueued — zero CSS/JS when disabled
### Analytics + SMTP (Module 9)
- [ ] GA4, GTM, Facebook Pixel, TikTok Pixel scripts inject correctly
- [ ] Custom header/footer scripts render in correct position
- [ ] SMTP override sends mail via configured server
- [ ] Email log records all sent/failed emails
- [ ] Test email sends successfully
### Import (Module 10)
- [ ] Yoast SEO meta data imports correctly with key mapping
- [ ] RankMath meta data imports correctly with key mapping
- [ ] All in One SEO meta data imports correctly with key mapping
- [ ] Dry run preview shows migration summary without writing
- [ ] Rollback restores original values
### Performance & Compliance
- [ ] Zero frontend CSS/JS impact when share buttons disabled
- [ ] All `<head>` output consolidated in single `wp_head` hook at priority 1
- [ ] Admin assets loaded only on IGNY8 admin pages
- [ ] All user strings translatable via `igny8` text domain
- [ ] All inputs sanitized, all outputs escaped
- [ ] Nonce verification on all form submissions
- [ ] Plugin passes WordPress Plugin Check (PCP) tool
---
## 6. CLAUDE CODE INSTRUCTIONS
### Context Requirements
Before starting implementation:
1. Read existing WP Bridge plugin at `/data/app/igny8/plugins/wordpress/source/igny8-wp-bridge/` — understand current structure
2. Read 02D (Linker Internal) for IGNY8 backend linking logic that feeds Module 6
3. Read 02G (Rich Schema SERP) for schema types that feed Module 2
### Execution Order
```
Foundation → SEO Core → Schema+Sitemap+Redirects → Intelligence → Linking → Social+Analytics+GSC → Import → Compliance
```
### Critical Rules
1. **All IDs are integers** — BigAutoField on IGNY8 side, BIGINT AUTO_INCREMENT on WP side
2. **IGNY8 model names are PLURAL** — Clusters, Keywords, Tasks, ContentIdeas, Images, Content (stays singular)
3. **Table prefix** — All WP tables use `{wp_prefix}igny8_` prefix
4. **Post meta prefix** — All `_igny8_` prefixed
5. **Term meta prefix** — All `_igny8_term_` prefixed
6. **Option prefix** — All `igny8_` prefixed
7. **Text domain**`igny8` for all translatable strings
8. **REST namespace**`/wp-json/igny8/v1/`
9. **No direct DB queries** where WP functions exist (`WP_Query`, `get_post_meta`, `get_option`)
10. **Sanitize inputs**`sanitize_text_field()`, `wp_kses_post()`, `absint()`, `sanitize_url()`
11. **Escape outputs**`esc_html()`, `esc_attr()`, `esc_url()`, `wp_kses_post()`
12. **Nonce on forms**`wp_nonce_field()` / `wp_verify_nonce()` / `check_ajax_referer()`
13. **Capability checks**`current_user_can('manage_options')` for admin pages
14. **Module pattern** — Every module implements `register()`, `activate()`, `deactivate()`, `is_active()`, `boot()`
### Testing
- Activate plugin on WordPress 5.9+ with PHP 7.4+
- Run setup wizard through all 6 steps
- Toggle each module on/off — verify no errors
- Create a post, fill all SEO meta, verify `<head>` output
- Check sitemap renders at `/sitemap_index.xml`
- Create redirect, trigger 404, verify logging
- Run manual audit, verify dashboard results
- Run link crawl, verify link map populated
- Connect GSC via OAuth, verify dashboard data
- Test share buttons at all positions
- Configure GA4 + SMTP, verify injection + mail delivery
- Import from Yoast test data, verify mapping
- Run WordPress Plugin Check (PCP) tool for compliance
### File Creation Order
```
1. igny8.php (plugin header + bootstrap)
2. includes/class-igny8.php (singleton)
3. includes/class-module-manager.php (module orchestration)
4. includes/data/class-installer.php (DB tables)
5. includes/admin/class-admin-menu.php (menu structure)
6. includes/admin/class-setup-wizard.php (first-run wizard)
7. includes/class-rest-api.php (public endpoints)
8. includes/class-compatibility.php (conflict detection)
9. includes/modules/seo/* (Module 1 — 9 files)
10. includes/frontend/class-head-output.php (consolidated <head>)
11. includes/modules/schema/* (Module 2 — 12 files)
12. includes/modules/sitemap/* (Module 3 — 6 files)
13. includes/modules/redirects/* (Module 4 — 4 files)
14. includes/modules/site-intelligence/* (Module 5 — 10 files)
15. includes/modules/linking/* (Module 6 — 7 files)
16. includes/modules/gsc/* (Module 7 — 6 files)
17. includes/modules/socializer/* (Module 8 — 8 files)
18. includes/modules/analytics/* (Module 9a — 5 files)
19. includes/modules/smtp/* (Module 9b — 4 files)
20. includes/data/class-importer.php + importers (Module 10 — 4 files)
21. includes/integrations/class-woocommerce.php (WooCommerce)
22. includes/integrations/class-theme-bridge.php (theme communication)
23. uninstall.php (cleanup)
24. languages/igny8.pot (i18n template)
```
### Cross-References
| Doc | Relationship |
|-----|-------------|
| 02D Linker Internal | IGNY8 backend SAGLink scoring → feeds Module 6 auto-linker in connected mode |
| 02G Rich Schema SERP | IGNY8 backend schema generation → feeds Module 2 via bulk push in connected mode |
| 02C GSC Integration | IGNY8 backend GSC metrics → feeds Module 7 URL Inspection in connected mode |
| 02H Socializer | IGNY8 backend SocialAccount OAuth → feeds Module 8 auto-poster in connected mode |
| 03B WP Plugin Connected | Extends this plugin with 2 connected-mode modules (Content Sync, SAG Structure) |
| 03C Companion Theme | Theme consumes plugin API: `igny8()->seo`, `igny8()->schema`, `igny8()->linking` |
| 03D Toolkit Plugin | If both installed, toolkit SMTP defers to this plugin's SMTP module |