# WiseWand Plugin — Claude Code Guide

**WordPress plugin for AI content generation, RSS feeds, editorial calendar, and SEO.**
Version 2.9.12 | PHP 8.0+ | WP 6.2+ | Text domain: `wisewand-ai-content-writer-seo-content-generator`

---

## Code Style (WordPress Coding Standards)

- **Tabs** for indentation (not spaces)
- **Yoda conditions**: `if ( 'value' === $var )` not `if ( $var === 'value' )`
- Control brace on same line; function brace on new line
- Spaces inside parentheses: `if ( $x )` not `if ($x)`
- All functions/classes prefixed `wisewand_` or `Wisewand\`
- ABSPATH check at top of every PHP file

## Security Pattern (mandatory for all AJAX/form handlers)

Order matters — always this sequence:
1. **Nonce** — `check_ajax_referer( 'action', 'nonce' )`
2. **Capability** — `current_user_can( 'manage_options' )`
3. **Sanitize** input — `sanitize_text_field( wp_unslash( $_POST['x'] ) )`
4. **Validate** — check required fields, types
5. **Process** — business logic with error handling
6. **Escape** output — `esc_html()`, `esc_attr()`, `esc_url()`
7. **Prepared SQL** — always `$wpdb->prepare()`, no exceptions

## Architecture

```
includes/
  Core/Plugin.php        — Central controller, hook registration
  Admin/                 — Admin pages (RSS, Calendar, Settings)
  API/                   — REST API & webhook handlers
  RSS/                   — Feed sync engine, manager, importers
  Calendar/              — Editorial calendar
  Content/               — Content management
  Media/                 — Media handling
  SEO/                   — DataForSEO integration
  Utils/                 — API clients, Options wrapper, helpers
  Repositories/          — Database access (Base_Repository pattern)
  Database/              — Schema, migrations, version tracking
  Security/              — Security manager
  Logging/               — Activity logging
```

## Key Patterns

- **Options**: Always use `Wisewand\Utils\Options` wrapper, never raw `get_option()`
- **Repositories**: Extend `Base_Repository`, inject `$wpdb` in constructor
- **AJAX registration**: In `Plugin.php` via `add_action( 'wp_ajax_wisewand_*' )`
- **Logging**: `if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { error_log( 'Wisewand: ...' ); }`
- **i18n**: Every user-visible string must use `__()` / `esc_html__()` with full text domain
- **Migrations**: All schema changes via `includes/Database/migrations/Migration_0XX_Name.php`

## Naming Conventions

- **Actions**: `wisewand_{noun}_{verb}` (e.g., `wisewand_feed_imported`)
- **Filters**: `wisewand_{noun}_{property}` (e.g., `wisewand_post_status`)
- **Options**: `wisewand_{category}_{setting}` (e.g., `wisewand_rss_auto_import`)
- **Constants**: `WISEWAND_VERSION`, `WISEWAND_PLUGIN_VERSION` (both exist — keep in sync)
- **Commit types**: fix, feat, refactor, docs, test, chore
- **Commit scopes**: core, rss, calendar, seo, admin, api, security

## Common Commands

```bash
# Syntax check
php -l includes/Admin/Example.php
find includes/ -name "*.php" -exec php -l {} \;
```

## Known Gotchas

- Dual version constants: `WISEWAND_PLUGIN_VERSION` and `WISEWAND_VERSION` — keep both in sync
- Repository classes are very large (23k+ lines) — avoid making them bigger
- No object caching (`wp_cache_*`) anywhere yet — add when touching hot paths
- Articles can get stuck in "importing" state — check `RSS_Sync_Engine`
- No transaction wrapping in database migrations
- Blocking `sleep()` calls in CRON operations

## Agent System

Seven agents defined in `.claude/agents/`. The Orchestrator coordinates: Explorer → Planner → Builder → Quality Guardian → Docs Manager. Just describe what you want.

## WordPress.org Compliance

- GPL-2.0-or-later license on all files
- No obfuscated code, no phone-home without consent
- All output escaped, all input sanitized, all SQL prepared
- Full i18n with correct text domain
