Files
Claude Code 4a55d51329 feat(wordpress): EMCP Tools workflow skills + widget catalogs + pending wordpress skills
- emcp-page-building, emcp-content-ops, emcp-site-audit: EMCP Tools MCP
  workflows verified live (atomic/legacy interplay, apply-template overwrite
  risk, create-theme-template goes live immediately, false-positive malware
  pattern in scan-security, change ledger + rollback)
- elementor-pro-widgets: 30+5 native Elementor Pro widgets (curated catalog)
- elementskit-widgets / powerpack-widgets: 42 + 97 third-party widgets,
  widgetType extracted from plugin source (not guessed by convention)
- plugin.json bumped 1.2.0 -> 1.3.0, keywords + description updated
- commits pending wordpress skills already present as untracked files
  (emcp-tools, wordfence, wp-activity-log, seguranca-descomplicar,
  webp-express, wp-fastest-cache, wp-font-perf, wp-meteor,
  wp-activity-log, redis-object-cache, app-for-cloudflare) and pending
  edits (rank-math, wp-cli, wp-content-seo-gate)
2026-08-19 03:44:00 +01:00

461 lines
26 KiB
Markdown

---
name: redis-object-cache
description: Gestão e diagnóstico do plugin Redis Object Cache (redis-cache, Till Krüss) via WP-CLI em servidores CWP. Cobre estado da ligação (wp redis status), drop-in object-cache.php, isolamento por site via WP_REDIS_DATABASE/WP_REDIS_PREFIX no bundle partilhado, PING/PONG, flush pós-SQL directo, e diferença entre object cache e page cache (WP Fastest Cache/WP Meteor). Usar quando "redis object cache", "redis-cache", "wp redis status", "object cache", "isolamento redis", "colisão de base redis", "WP_REDIS_DATABASE", "cache não invalida", "predis vs phpredis".
---
# /redis-object-cache — Gestão e Diagnóstico Redis Object Cache
Plugin `redis-cache` (Till Krüss), versão `2.8.0` confirmada em produção.
Object cache persistente — cache de objectos/queries WordPress, **não** é
page cache (ver secção "Object cache vs page cache" abaixo).
**Fonte:** `CONFIG-Plugins-Referencia.md` secção 6 (Redis Object Cache,
mapeado 16-08-2026) + verificação SSH ao vivo desta sessão (16-08-2026) em
`emanuelalmeida.pt` e nos 7 sites do bundle + expansão de cobertura
(16-08-2026) por leitura integral do código-fonte do plugin
(`includes/object-cache.php`, `includes/class-plugin.php`,
`includes/class-predis.php`, `includes/class-metrics.php`,
`includes/diagnostics.php`, `includes/cli/class-commands.php`,
`wp-includes/load.php` do core) — mapeamento exaustivo de todas as
constantes `WP_REDIS_*`, subcomandos WP-CLI, hooks e semântica de grupos,
não apenas o subconjunto tocado na auditoria pontual original.
---
## Contexto CWP — sempre obrigatório
```bash
# Via SSH directo (mais rápido para wp redis, comando nativo)
ssh server "sudo -u USER /usr/local/bin/wp redis status --path=/home/USER/SITE_PATH"
# Formato CWP completo (PHP versionado)
sudo -u USER /opt/alt/php-fpm82/usr/bin/php /usr/local/bin/wp redis status \
--allow-root --path=/home/USER/public_html
```
```
servidor: server.descomplicar.pt | porta: 9443 | user: root
```
**Único comando nativo do plugin:** `wp redis <subcomando>`. Confirmado ao
vivo (`wp redis --help --path=$PATH`):
| Subcomando | Faz |
|---|---|
| `wp redis status` | Mostra ligação, client, host/porta/DB/prefixo, grupos, drop-in |
| `wp redis enable` | Activa a cache (escreve o drop-in `object-cache.php`) |
| `wp redis disable` | Desactiva a cache (remove o drop-in) |
| `wp redis update-dropin` | Actualiza o drop-in para a versão do plugin instalado |
**Gotcha real confirmado nesta sessão:** `wp redis flush` **não existe**.
A própria ajuda do comando diz: *"To flush call `wp cache flush`"*. Usar
sempre o comando genérico do WP-CLI (`wp cache flush`), que funciona porque
o drop-in `object-cache.php` está activo e intercepta o wrapper nativo.
**Reconfirmado nesta expansão (16-08-2026):** `wp help redis --path=$PATH`
ao vivo devolve exactamente os mesmos 4 subcomandos. O código-fonte
(`includes/cli/class-commands.php`, classe `Commands extends WP_CLI_Command`)
só define 4 métodos públicos — `status()`, `enable()`, `disable()`,
`update_dropin()` (mapeado para `update-dropin` via `@subcommand`) — pelo que
esta lista é exaustiva, não apenas a amostra testada. Não existe `wp redis
flush` nem `wp redis info` nesta versão (2.8.0).
---
## 1. Diagnóstico rápido — `wp redis status`
```bash
PATH=/home/USER/SITE_PATH
wp redis status --path=$PATH
```
Output real (`emanuelalmeida.pt`, DB 12):
```
Status: Ligado
Client: Predis (v2.4.0)
Drop-in: Valid
Disabled: No
Ping: PONG
Errors: []
PhpRedis: Not loaded
Relay: Not loaded
Predis: 2.4.0
PHP Version: 8.2.31
Plugin Version: 2.8.0
Redis Version: 5.0.3
WP_REDIS_HOST: "127.0.0.1"
WP_REDIS_PORT: 6379
WP_REDIS_DATABASE: 12
WP_REDIS_PREFIX: "emanuelalmeida_pt_"
WP_CACHE_KEY_SALT: "..."
Timeout: 1
Read Timeout: 1
Global Groups: [...24 grupos: blog-details, users, site-transient, ...]
Ignored Groups: ["counts", "plugins", "theme_json", "WPForms_Entry_Handler", "themes"]
Drop-ins: ["Redis Object Cache Drop-In v2.8.0 by Till Krüss"]
```
| Campo a verificar | Valor esperado | Se falhar |
|---|---|---|
| `Status` | `Ligado` | `Não ligado` → drop-in ausente ou desactivado, correr `wp redis enable` |
| `Ping` | `PONG` | Qualquer outra coisa → Redis não responde na porta 6379, verificar serviço `redis-server` no host |
| `Drop-in` | `Valid` | `Invalid`/`Outdated` → correr `wp redis update-dropin` |
| `Client` | `Predis 2.4.0` | Confirmado — `PhpRedis`/`Relay` **não instalados** no servidor (extensão PHP nativa ausente); Predis é fallback 100% funcional em PHP puro, apenas mais lento. Não é erro, é a configuração real e estável do servidor |
| `WP_REDIS_DATABASE` | número único por site | Ver secção "Isolamento entre sites" |
Ler `object-cache.php` como drop-in activo (não apenas plugin) é o
diferencial: `wp plugin is-active redis-cache` só confirma que o plugin
está ligado, **não** confirma que o drop-in está a interceptar as chamadas
de cache. `wp redis status` é a única fonte fiável de estado real.
---
## 2. Isolamento entre sites do bundle — verificação de integridade
Todos os sites do bundle Descomplicar® partilham a **mesma instância Redis**
(`127.0.0.1:6379`, um único servidor Redis no host). O isolamento é feito por
duas camadas independentes — `WP_REDIS_DATABASE` (índice de base lógica
Redis, 0-15 por omissão) **e** `WP_REDIS_PREFIX` (prefixo de chave) — para
que uma colisão numa camada não cause colisão real de dados.
### Comando repetível — listar DB de todos os sites e confirmar zero colisão
```bash
#!/usr/bin/env bash
# Corre no servidor (via ssh server "...") ou local com ssh -p 9443 root@server.descomplicar.pt
declare -A SITES=(
[descomplicar.pt]="ealmeida:/home/ealmeida/public_html"
[emanuelalmeida.pt]="ealmeida:/home/ealmeida/emanuelalmeida.pt"
[carstuff.pt]="carstuff:/home/carstuff/public_html"
[familyclinic.pt]="familycl:/home/familycl/public_html"
[ignitionvortex.pt]="ignition:/home/ignition/public_html"
[solarfvengenharia.com]="solarfv:/home/solarfv/public_html"
[watercontrol.pt]="wtc:/home/wtc/public_html"
)
DBS=""
for site in "${!SITES[@]}"; do
user="${SITES[$site]%%:*}"; path="${SITES[$site]#*:}"
active=$(sudo -u "$user" /usr/local/bin/wp plugin is-active redis-cache --path="$path" 2>/dev/null && echo ACTIVE || echo INACTIVE)
db=$(sudo -u "$user" /usr/local/bin/wp config get WP_REDIS_DATABASE --path="$path" 2>/dev/null)
prefix=$(sudo -u "$user" /usr/local/bin/wp config get WP_REDIS_PREFIX --path="$path" 2>/dev/null)
printf "%-24s %-9s DB=%-3s prefix=%s\n" "$site" "$active" "$db" "$prefix"
[ "$active" = "ACTIVE" ] && DBS="$DBS $db"
done
echo "--- DBs activas: $DBS"
echo "--- duplicados:"; echo $DBS | tr ' ' '\n' | sort | uniq -d
```
**Resultado real desta sessão (16-08-2026):**
| Site | Plugin | `WP_REDIS_DATABASE` | `WP_REDIS_PREFIX` |
|---|---|---|---|
| descomplicar.pt | **inactive** | `0` (default, não usado) | — |
| emanuelalmeida.pt | active | `12` | `emanuelalmeida_pt_` |
| carstuff.pt | active | `1` | `carstuff_` |
| familyclinic.pt | active | `3` | `familycl_` |
| ignitionvortex.pt | active | `4` | `ignition_` |
| solarfvengenharia.com | active | `6` | `solarfv_` |
| watercontrol.pt | active | `7` | `wtc_` |
**Zero colisões** — DBs activas `{1, 3, 4, 6, 7, 12}` são todas distintas, e
mesmo que duas colidissem, o `WP_REDIS_PREFIX` distinto por site seria a
segunda barreira. `descomplicar.pt` (site principal Descomplicar®) tem o
plugin **instalado mas inactivo** — não usa object cache Redis; confirmar
antes de assumir que está coberto pelo bundle.
**Gotcha:** a linha `echo $DBS | tr ' ' '\n' | sort | uniq -d` fica vazia
quando não há duplicados — silêncio = sucesso. Um output não-vazio ali é
alarme real de colisão de DB entre dois sites do bundle.
---
## 3. Object cache vs page cache — não conflitam, são camadas diferentes
| Camada | Plugin | O que guarda | Onde vive |
|---|---|---|---|
| **Object cache** | Redis Object Cache (este) | Resultados de queries SQL, `wp_options` autoload, transients, meta — substitui o cache-in-memory por pedido do WordPress (`WP_Object_Cache`) por um persistente entre pedidos | Redis (`127.0.0.1:6379`) |
| **Page cache** | WP Fastest Cache / WP Meteor | HTML final já renderizado de uma página, servido antes do WordPress arrancar | Ficheiros estáticos em disco (`wp-content/cache/`) |
São independentes e **complementares**: o page cache evita mesmo carregar o
WordPress; quando falha um cache de página (visitante logado, POST,
página não cacheável) é o object cache Redis que absorve o custo das
queries repetidas. Não há necessidade de coordenar TTLs ou invalidação
entre os dois — cada um limpa-se pelo seu próprio mecanismo (`wp cache
flush` para Redis; purga própria do WP Fastest Cache/WP Meteor para HTML).
---
## 4. Gotcha crítico — SQL directo não invalida o Redis
**Mesma nota da skill `/rank-math`:** qualquer alteração feita via `wp db
query` (UPDATE/DELETE directo em `wp_options`, `wp_postmeta`, etc.) **não
passa pelas funções WordPress** (`update_option()`, `update_post_meta()`)
que disparam a invalidação de cache. Com o object cache Redis activo, os
dados antigos continuam servidos da cache até expirarem ou até um flush
explícito — o que pode demorar minutos a horas dependendo do grupo.
**Regra:** SEMPRE `wp cache flush --path=$PATH` imediatamente a seguir a
qualquer `wp db query` de escrita, antes de validar o resultado no site.
```bash
wp db query "UPDATE ${PREFIX}options SET option_value='...' WHERE option_name='...';" --path=$PATH
wp cache flush --path=$PATH # OBRIGATÓRIO — sem isto o Redis serve dados stale
```
Sem este passo, uma auditoria/correcção pode parecer ter falhado (o browser
mostra o valor antigo) quando na verdade a escrita na BD foi bem-sucedida —
é só a camada de cache que ainda não sabe.
---
## 5. Grupos ignorados por omissão
Confirmado via `wp redis status`:
```
Ignored Groups: ["counts", "plugins", "theme_json", "WPForms_Entry_Handler", "themes"]
```
Estes grupos ficam **fora** do Redis mesmo com o object cache activo —
mudam com frequência ou têm de reflectir estado imediato (contagem de
comentários, lista de plugins/temas). É a configuração por omissão do
plugin, correcta para não introduzir dados desactualizados nestes pontos.
Os restantes 24 grupos (`users`, `site-transient`, `usermeta`,
`redis-cache`, etc.) são cacheados normalmente — ver output completo de
`wp redis status` para a lista exaustiva por site.
---
## 6. Constantes completas suportadas (`WP_REDIS_*`)
Levantamento exaustivo por leitura integral de
`includes/object-cache.php` (drop-in, 3066 linhas), `includes/class-plugin.php`
(1685 linhas), `includes/class-predis.php`, `includes/class-metrics.php` e
`includes/diagnostics.php` — não apenas as 5 constantes usadas no bundle
Descomplicar®. Todas por definir em `wp-config.php` **antes** do WordPress
arrancar (mesmo princípio do `WP_REDIS_DATABASE`/`WP_REDIS_PREFIX` já usado).
### Ligação básica
| Constante | Default | Descrição |
|---|---|---|
| `WP_REDIS_HOST` | `127.0.0.1` | Host do servidor Redis |
| `WP_REDIS_PORT` | `6379` | Porta TCP |
| `WP_REDIS_PATH` | — | Caminho do socket Unix; só usado quando `WP_REDIS_SCHEME=unix` (nesse caso `host`/`port` são descartados) |
| `WP_REDIS_SCHEME` | `tcp` | `tcp` / `unix` / `tls` (`rediss`) |
| `WP_REDIS_DATABASE` | `0` | Índice da base lógica Redis (0-15 por omissão) — usado no isolamento entre sites (secção 2) |
| `WP_REDIS_PASSWORD` | — | String (só password) ou array `[username, password]` para ACL Redis 6+. Mascarado como `••••••••` em `wp redis status`/diagnostics |
| `WP_REDIS_USERNAME` | — | Username ACL explícito; sobrepõe-se ao `[0]` de `WP_REDIS_PASSWORD` quando ambos definidos (só cliente Predis) |
| `WP_REDIS_TIMEOUT` | `1` | Timeout de ligação, em segundos |
| `WP_REDIS_READ_TIMEOUT` | `1` | Timeout de leitura, em segundos |
| `WP_REDIS_RETRY_INTERVAL` | `null` | Intervalo entre tentativas de reconexão, em ms |
| `WP_REDIS_SSL_CONTEXT` | — | Array de opções de stream context PHP para TLS, ex. `['verify_peer' => false]` |
| `WP_REDIS_CLIENT` | auto (`phpredis` se a extensão existir, senão `predis`) | `phpredis` / `pecl` (alias de `phpredis`) / `relay` / `credis` / `predis` — força o cliente |
| `WP_REDIS_IGBINARY` | `false` | bool — usa serialização `igbinary` se a extensão `igbinary` estiver carregada |
**Mecanismo:** `build_parameters()` em `object-cache.php` itera um array fixo
de settings (`scheme, host, port, path, password, database, timeout,
read_timeout, retry_interval`) e resolve cada um via
`sprintf('WP_REDIS_%s', strtoupper($setting))` — é assim, literalmente, que
o nome de cada constante é gerado a partir do parâmetro Redis correspondente.
### Alta disponibilidade / escala
| Constante | Descrição |
|---|---|
| `WP_REDIS_CLUSTER` | Array de DSNs (ou string = id de ligação nomeada) — activa modo Redis Cluster |
| `WP_REDIS_SHARDS` | Array de servidores — sharding client-side via `RedisArray` (só cliente `phpredis`) |
| `WP_REDIS_SENTINEL` | Nome do serviço Sentinel — requer `WP_REDIS_SERVERS` com os hosts dos sentinels |
| `WP_REDIS_SERVERS` | Array de servidores — replicação Predis (`options['replication']='predis'`) ou lista de sentinels quando `WP_REDIS_SENTINEL` também está definida |
Nenhuma destas está em uso no bundle Descomplicar® (todos os sites usam uma
única instância Redis local, sem cluster/replicação) — documentado aqui por
cobertura completa do plugin, não por uso confirmado em produção.
### Comportamento da cache
| Constante | Default | Descrição |
|---|---|---|
| `WP_REDIS_PREFIX` | — | Prefixo de chave (isolamento, ver secção 2); herda de `WP_CACHE_KEY_SALT` se esta estiver definida e `WP_REDIS_PREFIX` não estiver; em Cloudways é preenchido automaticamente a partir de `HTTP_X_APP_USER` |
| `WP_REDIS_SELECTIVE_FLUSH` | `false` | bool — `wp cache flush`/`flush()` só apaga chaves com o prefixo (script Lua via `SCAN`+`DEL`) em vez de `FLUSHDB` total à base lógica inteira |
| `WP_REDIS_GLOBAL_GROUPS` | 17 grupos por omissão (ver secção 9) | array — **substitui** (não soma) a lista de grupos partilhados entre sites de uma rede multisite |
| `WP_REDIS_IGNORED_GROUPS` | `[]` (vazio no plugin) | array — **substitui** a lista de grupos que nunca são persistidos no Redis |
| `WP_REDIS_UNFLUSHABLE_GROUPS` | `[]` (vazio) | array — **substitui** a lista de grupos que continuam em cache mas sobrevivem a um `flush()` |
| `WP_REDIS_MAXTTL` | — | int (segundos) — tecto aplicado a QUALQUER TTL, incluindo entradas "para sempre" (`expire=0`); `validate_expiration()` força o valor para o máximo sempre que `expiration === 0 \|\| expiration > max` |
| `WP_REDIS_FLUSH_TIMEOUT` | `5` | int (segundos) — timeout de socket aplicado só durante o flush selectivo/scripts Lua (`execute_lua_script()`) |
| `WP_REDIS_DISABLE_GROUP_FLUSH` | `false` | bool — `flush_group()` deixa de ser selectivo e cai num `flush()` total à base |
| `WP_REDIS_GRACEFUL` | `false` | bool — falha silenciosamente (sem excepção fatal) se o Redis estiver inacessível na ligação inicial |
| `WP_REDIS_DISABLED` | `false` | bool — desliga TODO o drop-in (nenhuma função `wp_cache_*` chega a ser definida, pois envolve o ficheiro inteiro num `if`); ver nuance de segurança na secção "Erros comuns" |
### Admin / UI / segurança
| Constante | Default | Descrição |
|---|---|---|
| `WP_REDIS_DISABLE_BANNERS` | `false` | bool — esconde todos os banners de upsell "Object Cache Pro" (dashboard, JS admin `disable_pro`, aviso WooCommerce) |
| `WP_REDIS_DISABLE_DROPIN_BANNERS` | `false` | bool — esconde só os avisos "drop-in em falta/desactualizado" no admin |
| `WP_REDIS_DISABLE_ADMINBAR` | `false` | bool — remove o nó "Object Cache" da barra de admin |
| `WP_REDIS_DISABLE_COMMENT` | `false` | bool — suprime o comentário HTML de rodapé "Performance optimized by Redis Object Cache" (hook `shutdown`) |
| `WP_REDIS_MANAGER_CAPABILITY` | `manage_options` (`manage_network_options` em multisite) | string — sobrepõe-se à capability necessária para gerir o plugin (menu, acções, admin bar); passa também pelo filtro `redis_cache_manager_capability` |
| `WP_REDIS_DISABLE_DROPIN_CHECK` | `false` | bool — salta o teste completo de escrita (copiar/verificar versão/apagar ficheiro `object-cache.tmp`), só confirma existência+permissão de escrita do drop-in já instalado |
| `WP_REDIS_DISABLE_DROPIN_AUTOUPDATE` | `false` | bool — desliga a auto-actualização do drop-in em `admin_init` quando a versão instalada do plugin muda |
### Métricas
| Constante | Default | Descrição |
|---|---|---|
| `WP_REDIS_DISABLE_METRICS` | `false` | bool — desliga completamente a recolha de métricas (esconde tab "Metrics", widget de dashboard, secção da admin bar) |
| `WP_REDIS_METRICS_MAX_TIME` | `3600` (`HOUR_IN_SECONDS`) | int (segundos) — janela de retenção/visualização das métricas; usado tanto para o gráfico como para a purga via cron `rediscache_discard_metrics` |
### Caminho do plugin
| Constante | Descrição |
|---|---|
| `WP_REDIS_PLUGIN_PATH` | Só tem efeito se definida **antes** do ficheiro principal do plugin carregar (`if (!defined('WP_REDIS_PLUGIN_PATH')) define(...)`) — é o mecanismo que o bundle partilhado Descomplicar® usa para apontar o drop-in de cada site para a cópia partilhada do plugin em vez de `wp-content/plugins/redis-cache` local |
---
## 7. Grupos de cache — semântica exacta dos 3 tipos
O construtor de `WP_Object_Cache` (`object-cache.php` linhas ~508-529) usa
três arrays distintos, cada um com comportamento próprio:
| Tipo | Efeito | Constante de override | Lista por omissão do plugin |
|---|---|---|---|
| `global_groups` | Partilhado entre todos os sites de uma rede multisite (não leva `blog_prefix`) | `WP_REDIS_GLOBAL_GROUPS` (substitui) | 17 grupos: `blog-details, blog-id-cache, blog-lookup, global-posts, networks, rss, sites, site-details, site-lookup, site-options, site-transient, users, useremail, userlogins, usermeta, user_meta, userslugs` (+ `redis-cache` sempre adicionado) |
| `ignored_groups` | Nunca chega a ir para o Redis — fica só em memória do pedido actual | `WP_REDIS_IGNORED_GROUPS` (substitui) | **`[]` vazio no próprio plugin** |
| `unflushable_groups` | Fica em cache normalmente, mas sobrevive a um `flush()`/`wp cache flush` | `WP_REDIS_UNFLUSHABLE_GROUPS` (substitui) | `[]` vazio |
**Correcção/precisão sobre a secção 5 acima:** os 5 "grupos ignorados por
omissão" vistos em `wp redis status`
(`counts, plugins, theme_json, WPForms_Entry_Handler, themes`) **não são
configuração do plugin `redis-cache`** — o array `$ignored_groups` do
próprio plugin nasce vazio. São chamadas em runtime à função wrapper
`wp_cache_add_non_persistent_groups()` (que faz `array_merge`, não
substitui) feitas por:
- **WordPress core**, em `wp-includes/load.php::wp_start_object_cache()`
(confirmado ao vivo nesta expansão): `wp_cache_add_non_persistent_groups(
['counts', 'plugins', 'theme_json'] )`, logo a seguir a carregar o drop-in;
- **WordPress core**, em `wp-includes/class-wp-theme.php:264`:
`wp_cache_add_non_persistent_groups( 'themes' )`;
- **Plugin WPForms** (`WPForms_Entry_Handler`), específico deste site — noutro
site sem WPForms este grupo não aparece.
Ou seja: a lista de grupos ignorados varia por site consoante os plugins
activos, não é fixa do `redis-cache`. Da mesma forma, o WordPress core
regista o seu próprio conjunto (mais amplo, 22 grupos incluindo
`blog_meta`, `image_editor`, `network-queries`, `site-queries`,
`theme_files`, `translation_files`, `user-queries`) via
`wp_cache_add_global_groups()` no mesmo `wp_start_object_cache()`, que se
soma (`array_unique(array_merge(...))`) aos 17 do plugin.
---
## 8. Arquitectura — zero `wp_options`, tudo por constante
Confirmado ao vivo nesta expansão:
```bash
wp option list --search='*redis*' --path=$PATH --format=json # []
wp option list --search='*rediscache*' --path=$PATH --format=json # []
```
O `redis-cache` **não grava nenhuma opção na base de dados**. Não há página
de definições com formulário — `includes/ui/settings.php` é só um wrapper
de tabs (Overview/Metrics/Diagnostics) que lê constantes e o estado ao vivo
do Redis. Toda a configuração vive em `wp-config.php` (constantes) e o único
estado persistente do plugin é:
- o próprio ficheiro drop-in `wp-content/object-cache.php` (presença =
cache activa);
- as métricas, gravadas **dentro do próprio Redis** como sorted set na chave
`<prefix>metrics:redis-cache` (via `ZADD`/`ZRANGEBYSCORE`), purgadas por
hora via cron `rediscache_discard_metrics` — não em `wp_options` nem em
ficheiro.
Isto tem implicação directa para migração/clonagem de sites: copiar
`wp_options` entre sites nunca traz nem perde configuração deste plugin —
só o `wp-config.php` (constantes) e o `wp-content/object-cache.php`
(presença do drop-in) importam.
---
## 9. Interface admin — o que existe na prática
- **3 tabs** na página `Definições → Redis` (`options-general.php?page=redis-cache`,
ou `settings.php?page=redis-cache` em multisite): **Overview**, **Metrics**
(desactivado se `Metrics::is_enabled()` for falso, i.e.
`WP_REDIS_DISABLE_METRICS`), **Diagnostics** (o mesmo output de
`wp redis status`, renderizado em HTML).
- **Admin bar**: nó "Object Cache" (removível com `WP_REDIS_DISABLE_ADMINBAR`)
com submenu "Flush Cache" (AJAX, acção `roc_flush_cache`) e "Settings";
mostra hit-ratio/hits/misses/tamanho da página actual em hover.
- **Widget de dashboard** ("Redis Object Cache"), só visível a quem tem a
capability de gestão e só se `Metrics::is_enabled()`.
- **Integração Query Monitor**: regista um collector/output próprio
(`class-qm-collector.php`, `class-qm-output.php`) que acrescenta um painel
"Cache" ao Query Monitor quando este plugin está activo — automático, sem
configuração.
- **Aviso específico WooCommerce**: notice de upsell Pro nas páginas de
encomendas/produtos/analytics do WooCommerce (silenciável com
`WP_REDIS_DISABLE_BANNERS`).
### Acções da página de definições vs comandos WP-CLI
A página admin usa links com nonce (`?action=<x>&_wpnonce=...`) que chamam
exactamente a mesma lógica dos comandos WP-CLI:
| Acção admin (`action=`) | Equivalente WP-CLI | Efeito |
|---|---|---|
| `enable-cache` | `wp redis enable` | Copia `includes/object-cache.php` para `wp-content/object-cache.php` |
| `disable-cache` | `wp redis disable` | Apaga `wp-content/object-cache.php` |
| `update-dropin` | `wp redis update-dropin` | Reescreve o drop-in com a versão actual do plugin |
| `flush-cache` | `wp cache flush` | Chama `wp_cache_flush()` directamente (sem passar pelo WP-CLI genérico) |
---
## 10. Hooks disponíveis para integração
| Hook | Tipo | Quando dispara |
|---|---|---|
| `redis_object_cache_enable` | action | Depois de copiar o drop-in ao activar (via admin ou `wp redis enable`) — argumento: `bool $result` |
| `redis_object_cache_disable` | action | Depois de apagar o drop-in ao desactivar |
| `redis_object_cache_update_dropin` | action | Depois de `wp redis update-dropin` / auto-update |
| `redis_object_cache_flush` | action | Em cada `flush()` — argumentos: `$results, $deprecated, $selective, $salt, $execute_time` |
| `redis_cache_manager_capability` | filter | Sobrepõe a capability de gestão (default `manage_options`/`manage_network_options`), além/em vez de `WP_REDIS_MANAGER_CAPABILITY` |
| `redis_cache_validate_dropin` | filter | Sobrepõe a validação de "o drop-in instalado é o deste plugin" (compara `PluginURI`) |
| `redis_cache_add_non_persistent_groups` | filter | Filtra a lista de grupos antes de `add_non_persistent_groups()` os fundir em `ignored_groups` |
---
## 11. Auto-resolução de conflitos com outros plugins de cache
O plugin desactiva proactivamente os object caches nativos de outros
plugins de cache/performance para evitar dois drop-ins a lutar pelo mesmo
ficheiro:
```php
add_filter( 'perflab_disable_object_cache_dropin', '__return_true' ); // WordPress Performance Lab
add_filter( 'w3tc_config_item_objectcache.enabled', '__return_false' ); // W3 Total Cache
add_action( 'litespeed_init', [ $this, 'litespeed_disable_objectcache' ] ); // LiteSpeed Cache
```
Relevante para o bundle Descomplicar®: confirma que activar `redis-cache`
num site que também tenha W3TC ou LiteSpeed Cache instalado (mesmo que
inactivo o respectivo módulo de object cache) não gera conflito — o
`redis-cache` desliga automaticamente a componente de object cache desses
plugins via filtro, sem intervenção manual.
## Erros comuns
| Sintoma | Causa | Solução |
|---|---|---|
| `wp redis flush` → "not a registered command" | Subcomando não existe no plugin | Usar `wp cache flush` (genérico WP-CLI, funciona via drop-in activo) |
| Dados alterados por `wp db query` não aparecem no site | Redis serve versão em cache, SQL directo não invalida | `wp cache flush --path=$PATH` logo a seguir a qualquer escrita SQL |
| `wp redis status` mostra `Client: Predis`, não `PhpRedis` | Extensão PHP nativa `redis` não instalada no servidor | Não é erro — Predis é fallback 100% funcional, apenas mais lento; upgrade futuro se a extensão for instalada |
| Dois sites com o mesmo `WP_REDIS_DATABASE` (colisão) | `wp-config.php` copiado entre sites sem ajustar `WP_REDIS_DATABASE`/`WP_REDIS_PREFIX` | Correr a verificação da secção 2 após qualquer clone/migração de site no mesmo servidor; atribuir DB livre (0-15) e prefixo único |
| `wp redis status` → `Status: Não ligado` mas plugin activo | Drop-in `object-cache.php` ausente/removido de `wp-content/` (ex.: apagado por engano numa migração) | `wp redis enable` reescreve o drop-in |
| Confundir "plugin activo" com "cache activa" | `wp plugin is-active redis-cache` só confirma o plugin, não o drop-in | Confirmar sempre com `wp redis status` → `Ping: PONG` |
| Definir `WP_REDIS_DISABLED=true` sem remover o drop-in | Comportamento intencional, não um bug | Não é preciso apagar `object-cache.php`; a constante sozinha faz com que nenhuma função `wp_cache_*` seja definida pelo drop-in, e o WordPress core (`wp-includes/load.php::wp_start_object_cache()`) deteta isso e carrega automaticamente o fallback nativo `wp-includes/cache.php` — confirmado por leitura do core nesta expansão |
| `wp redis status` → grupos ignorados diferentes de site para site | Não é config do plugin — WordPress core adiciona `counts/plugins/theme_json/themes` e plugins activos (ex. WPForms → `WPForms_Entry_Handler`) via `wp_cache_add_non_persistent_groups()` em runtime | Normal; comparar só via `WP_REDIS_IGNORED_GROUPS` se quiseres saber o que o `redis-cache` em si define (por omissão, nenhum) |