---
name: wp-dev
description: Desenvolvimento WordPress especializado com Quality Gate 70+. Cria e modifica plugins seguindo WordPress Coding Standards, desenvolve temas child, integra WooCommerce e resolve problemas WordPress.
---

# WordPress Plugin Developer

Skill para desenvolvimento WordPress profissional seguindo padrões Descomplicar®.

## Quando Usar

- Criar ou modificar plugins WordPress
- Desenvolver temas ou child themes
- Integrar funcionalidades WooCommerce
- Resolver problemas específicos WordPress
- Criar custom post types, taxonomias, widgets

## Quando NÃO Usar

- Para operações CRM (usar /crm-ops)
- Para operações servidor/SSH genéricas (usar agente especializado)
- Para manutenção rotineira WP (usar /today às segundas)

## Contexto NotebookLM

ANTES de executar, consultar notebooks para contexto especializado:

| Notebook | ID | Consultar quando |
|----------|-----|-----------------|
| WordPress e Elementor | 5be0d1a6 | Sempre |
| WordPress Config CLI | fb2f26bd-8cb0-4d4c-bafc-4f1ebb51c51d | Para WP-CLI e configuração |

```
mcp__notebooklm__notebook_query({
  notebook_id: "5be0d1a6-00f2-4cd9-b835-978cb7721601",
  query: "<adaptar ao contexto do pedido do utilizador>"
})

mcp__notebooklm__notebook_query({
  notebook_id: "fb2f26bd-8cb0-4d4c-bafc-4f1ebb51c51d",
  query: "<adaptar ao contexto de WP-CLI e configuração WordPress>"
})
```

Integrar insights do NotebookLM nas recomendações e decisões.

### Procedimentos Relacionados
- `PROC-WiP-Definicao.md` — Definição de projectos WordPress in a Package
- `PROC-WiP-Instalacao.md` — Instalação e configuração WiP
- `PROC-WiP-Gestao.md` — Gestão e manutenção WiP

---

## Protocolo Obrigatório

### 1. Pesquisa Inicial (MCP)
Antes de desenvolver, SEMPRE executar:
```
mcp__memory-supabase__search_memories "[keywords wordpress]"
mcp__wikijs__search_pages "[plugin/funcionalidade]"
```

### 2. Quality Gate 70+
Todo código WordPress deve atingir score mínimo 70/100:
- WordPress Coding Standards (WPCS)
- Funções documentadas com PHPDoc
- Hooks e filters bem estruturados
- Sem warnings/notices PHP
- Segurança: nonces, sanitização, escaping

### 3. Assinatura Obrigatória
Todo ficheiro PHP deve incluir:
```php
<?php
/**
 * [Nome do Plugin/Ficheiro]
 *
 * @author Descomplicar® Crescimento Digital
 * @link https://descomplicar.pt
 * @copyright 2025 Descomplicar®
 */
```

## Segurança WordPress (OBRIGATÓRIO)

- **Sanitizar inputs**: `sanitize_text_field()`, `sanitize_email()`, `absint()`
- **Escapar outputs**: `esc_html()`, `esc_attr()`, `esc_url()`
- **Nonces para forms**: `wp_nonce_field()`, `wp_verify_nonce()`
- **AJAX nonces**: `check_ajax_referer()`
- **Capability checks**: `current_user_can()` antes de acções admin
- **Prepared statements**: `$wpdb->prepare()` para queries

## Performance

- Enqueueing correcto: `wp_enqueue_script()`, `wp_enqueue_style()`
- Hooks no momento certo: `init`, `admin_init`, `wp_enqueue_scripts`
- Evitar queries em loops
- Usar transients para cache: `get_transient()`, `set_transient()`

## Estrutura Plugin Standard

```
plugin-name/
├── plugin-name.php          # Ficheiro principal
├── includes/
│   ├── class-plugin-name.php
│   └── class-plugin-name-admin.php
├── assets/
│   ├── css/
│   └── js/
├── templates/
├── languages/
└── readme.txt
```

## Template Plugin Principal

```php
<?php
/**
 * Plugin Name
 *
 * @package           PluginName
 * @author            Descomplicar® Crescimento Digital
 * @copyright         2025 Descomplicar®
 * @license           GPL-2.0-or-later
 *
 * @wordpress-plugin
 * Plugin Name:       Plugin Name
 * Plugin URI:        https://descomplicar.pt/plugin-name
 * Description:       Descrição do plugin.
 * Version:           1.0.0
 * Requires at least: 6.0
 * Requires PHP:      8.0
 * Author:            Descomplicar®
 * Author URI:        https://descomplicar.pt
 * Text Domain:       plugin-name
 * License:           GPL v2 or later
 * License URI:       https://www.gnu.org/licenses/gpl-2.0.html
 */

defined('ABSPATH') || exit;

define('PLUGIN_NAME_VERSION', '1.0.0');
define('PLUGIN_NAME_PATH', plugin_dir_path(__FILE__));
define('PLUGIN_NAME_URL', plugin_dir_url(__FILE__));

// Autoloader ou includes
require_once PLUGIN_NAME_PATH . 'includes/class-plugin-name.php';

// Inicialização
function plugin_name_init() {
    load_plugin_textdomain('plugin-name', false, dirname(plugin_basename(__FILE__)) . '/languages/');
}
add_action('plugins_loaded', 'plugin_name_init');

// Activação
register_activation_hook(__FILE__, 'plugin_name_activate');
function plugin_name_activate() {
    // Criar tabelas, opções, etc.
}

// Desactivação
register_deactivation_hook(__FILE__, 'plugin_name_deactivate');
function plugin_name_deactivate() {
    // Limpeza
}
```

## Checklist Antes de Entregar

- [ ] Assinatura Descomplicar® em todos os ficheiros
- [ ] Segurança: nonces, sanitização, escaping
- [ ] WordPress Coding Standards
- [ ] Sem erros PHP (php -l)
- [ ] Textdomain para traduções
- [ ] Uninstall hook para limpeza
- [ ] Testado em versão WP recente

---

## Hooks WordPress Essenciais

### Actions (fazer algo)

```php
// Init - inicializar plugin
add_action('init', 'register_custom_post_type');

// Enqueue scripts/styles
add_action('wp_enqueue_scripts', 'enqueue_assets');
add_action('admin_enqueue_scripts', 'enqueue_admin_assets');

// Save post
add_action('save_post', 'save_custom_meta', 10, 3);

// Admin menu
add_action('admin_menu', 'register_admin_page');

// AJAX
add_action('wp_ajax_my_action', 'handle_ajax');
add_action('wp_ajax_nopriv_my_action', 'handle_ajax_public');

// WooCommerce
add_action('woocommerce_before_cart', 'add_notice');
add_action('woocommerce_checkout_order_processed', 'process_order', 10, 3);
```

### Filters (modificar dados)

```php
// Modificar título
add_filter('the_title', 'custom_title', 10, 2);

// Modificar conteúdo
add_filter('the_content', 'add_content_suffix');

// Query
add_filter('pre_get_posts', 'modify_query');

// WooCommerce
add_filter('woocommerce_cart_item_price', 'custom_price', 10, 2);
add_filter('woocommerce_checkout_fields', 'custom_checkout_fields');
```

## Erros Comuns e Soluções

### 1. White Screen of Death (WSOD)

```bash
# Activar WP_DEBUG
define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define('WP_DEBUG_DISPLAY', false);

# Ver erro
tail -f wp-content/debug.log
```

### 2. Plugin Conflict

```bash
# Desactivar todos os plugins via BD
UPDATE wp_options SET option_value = '' WHERE option_name = 'active_plugins';

# Reactivar um a um para identificar conflito
```

### 3. Memory Limit

```php
// wp-config.php
define('WP_MEMORY_LIMIT', '256M');
define('WP_MAX_MEMORY_LIMIT', '512M');
```

### 4. Permissões

```bash
# Padrão seguro
find /path -type d -exec chmod 755 {} \;
find /path -type f -exec chmod 644 {} \;
chmod 600 wp-config.php
```

### 5. Páginas com shortcodes React/Vite

Páginas que usam shortcodes para renderizar componentes React (ex: `[react-app]`, `[vite-app]`, `[app-root]`) **nunca devem ser editadas via editor wp-admin** (Gutenberg ou Classic). O editor pode:
- Adicionar `<p>` e `<br>` indesejados à volta do shortcode
- Remover atributos ou alterar aspas
- Quebrar a montagem do componente React no DOM

**Procedimento correcto:**

```bash
# Ver conteúdo actual da página
wp post get <ID> --field=content --ssh=<server>

# Editar conteúdo via WP-CLI
wp post update <ID> --post_content='[react-app id="main"]' --ssh=<server>

# Ou via SQL directo (quando WP-CLI não é suficiente)
UPDATE wp_posts SET post_content = '[react-app id="main"]' WHERE ID = <ID>;
```

**Identificar páginas afectadas:**

```bash
# Listar páginas com shortcodes React/Vite
wp post list --post_type=page --fields=ID,post_title,post_content --format=csv --ssh=<server> | grep -iE '\[(react|vite|app)'
```

**Regra:** Ao criar ou manter plugins que registam shortcodes para aplicações React/Vite, documentar no `readme.txt` do plugin que as páginas associadas devem ser editadas exclusivamente via WP-CLI ou BD.

## Datasets Dify (Consulta Obrigatória)

Em caso de dúvidas ou para aprofundar conhecimento, consultar os seguintes datasets via MCP:

| Dataset | ID | Prioridade |
|---------|----|-----------:|
| **Wordpress** | `9da0b2b9-5051-4b99-b9f6-20bf35067092` | 1 |
| **Elementor** | `9c77d3e2-4d88-4a43-abff-d4e681267cc7` | 1 |
| **Crocooblock** | `139cdf67-afce-46ec-9ccd-2a06040e5b9d` | 1 |
| **Crocoblock** | `bdf85c26-1824-4021-92d1-be20501b35ac` | 1 |
| **Kivicare** | `2e9b7c48-c630-457a-83a0-db8e77f76eae` | 2 |
| **Desenvolvimento de WebSites** | `c8489151-de94-42b2-8cee-c0b961cfac6d` | 2 |

### Como Consultar

```javascript
// Desenvolvimento de plugins WordPress
mcp__notebooklm__notebook_query, mcp__dify-kb__dify_kb_retrieve_segments({
  dataset_id: "9da0b2b9-5051-4b99-b9f6-20bf35067092",
  query: "plugin development hooks filters"
})

// Widgets e extensões Elementor
mcp__dify-kb__dify_kb_retrieve_segments({
  dataset_id: "9c77d3e2-4d88-4a43-abff-d4e681267cc7",
  query: "custom widget dynamic tags"
})

// JetEngine e Crocoblock
mcp__dify-kb__dify_kb_retrieve_segments({
  dataset_id: "139cdf67-afce-46ec-9ccd-2a06040e5b9d",
  query: "jetengine custom post type relations"
})

// WooCommerce e e-commerce
mcp__dify-kb__dify_kb_retrieve_segments({
  dataset_id: "9da0b2b9-5051-4b99-b9f6-20bf35067092",
  query: "woocommerce hooks checkout cart"
})
```

### Quando Consultar

- Desenvolver plugins WordPress
- Criar widgets Elementor customizados
- Configurar JetEngine/Crocoblock
- Integrar WooCommerce
- Implementar custom post types

---

## Exemplos

### Exemplo 1: Criar plugin simples
```
User: /wp-dev criar plugin de custom post type "Serviços"
→ Pesquisa memória e KB Dify
→ Gera estrutura de plugin
→ Implementa CPT com ACF integration
→ Testes de segurança e WPCS
→ Score 75/100 ✅
```

### Exemplo 2: Widget Elementor
```
User: /wp-dev widget elementor para mostrar últimos serviços
→ Consulta dataset Elementor
→ Implementa widget com controls
→ Renderiza output com template
→ Testa em diferentes layouts
```

### Exemplo 3: Integração WooCommerce
```
User: /wp-dev adicionar campo personalizado no checkout
→ Consulta dataset Wordpress (WooCommerce)
→ Usa hooks woocommerce_checkout_fields
→ Implementa validação e save
→ Testa fluxo completo
```

---

## Instrumentação Automática

Esta skill grava métricas automaticamente para análise PDCA.

### Baseline

| Métrica | Valor |
|---------|-------|
| Tempo baseline | 4 horas |
| Tempo target | 2 horas |
| Melhoria esperada | -50% |

### Query para Gravar (executar no final)

```sql
INSERT INTO tblskill_agent_metrics (
  type, name, duration_ms, status, staff_id,
  kb_consulted, kb_cache_hit, tool_calls, project_id
) VALUES (
  'skill', '/wp-dev', {DURACAO_MS}, '{STATUS}', 25,
  {KB_CONSULTADO}, {CACHE_HIT}, {TOOL_CALLS}, {PROJECT_ID}
);
```

### Ver Métricas

```bash
/metrics /wp-dev
```

---

**Versão**: 1.2.0 | **Data**: 2026-03-12 | **Instrumentação**: Activa

---

## Media Bank (D7-MB-001)

**Quando consultar:** antes de gerar ou fazer upload de hero image, featured image ou imagens inline para plugins/temas WordPress. Permite reutilizar matéria-prima existente em vez de gerar do zero.

**Workflow tentativa-primeiro:**

1. Pesquisar via MCP `media-bank`:
   ```
   mcp__media-bank__search_media(
     query="<descrição EN do tema do post/plugin>",
     type="image",
     tema="wordpress-web",        # ou outro dos 9 temas
     orientation="landscape",
     min_quality=7,
     min_width=1600,
     exclude_used_in_last_days=30,
     limit=5
   )
   ```
2. Avaliar candidatos por `description_en` + `quality_score`.
3. Se ≥1 adequado → usar `path_local` como input (upload via `wp media import` ou composição prévia).
4. Se nenhum → fallback para geração IA (Flux/Replicate/design-engine).
5. Marcar uso: `mcp__media-bank__mark_used(asset_id, {type:"wp-post", ref:"<post_id>", date:"<YYYY-MM-DD>"})`.

**Fallback REST** (se MCP indisponível):
```bash
SK=$(grep SERVICE_KEY /media/ealmeida/Dados/Hub/05-Projectos/Banco-Imagens-Videos/scripts/.env | cut -d= -f2)
curl -s "https://mem.descomplicar.pt/rest/v1/media_bank_assets?type=eq.image&tema=eq.wordpress-web&orientation=eq.landscape&quality_score=gte.7&deleted_at=is.null&order=quality_score.desc&limit=5" \
  -H "apikey: $SK" -H "Authorization: Bearer $SK"
```

**Regra inviolável:** matéria-prima local. Usar como input para composição — NUNCA inserir o ficheiro raw directamente em publicação pública.

Ver `Hub/06-Operacoes/Procedimentos/D7-Tecnologia/MCP/PROC-Media-Bank.md` (D7-MB-001) para detalhes.

---

## Healing Log

Registo de erros conhecidos e como evitá-los. Lido automaticamente antes de executar.

```jsonl
{"date":"","issue":"","fix":"","source":"user|auto"}
```

*Adicionar nova linha após cada erro corrigido.*
