=== Rota WP Core ===
Contributors: rotalabs
Author: RotaLabs
Author URI: https://rotalabs.co
Donate link: https://rotalabs.co/br/products/rota-wp
Tags: affiliate, links, shortcode, travel, blocks
Requires at least: 6.0
Tested up to: 7.0
Requires PHP: 7.4
Stable tag: 1.4.37
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Affiliate link library and visual blocks for WordPress. Shortcode, four styles. Free core; optional Pro license (opt-in API).

== Description ==

**Rota WP Core** centralizes affiliate links in a reusable library and lets you place visual CTA blocks in posts and pages.

**Local features (GPL, no account required):**

* Link library (custom post type) with order, icon, CTA text, and metadata.
* Reusable visual blocks (custom post type) with manual link selection.
* Free styles **1 and 2**; shortcode `[rota-wp-core bloco="slug"]` and optional `limite="N"`.
* Optional automatic insertion by category.
* GA4 events on the front end **only** if your site already loads `gtag` (the plugin does not install analytics).
* No "Powered by" links or credits on the public site.

**Optional RotaLabs service (opt-in on the License screen):**

* **WordPress.org package:** all four visual styles, themes, editorial modes, and unlimited links per block are included locally without a license key (GPL-compliant directory build).
* **Optional RotaLabs service (License screen, opt-in):** free registration (4 → 10 links on the commercial ZIP) or Pro key for the rotalabs.co download channel — not required for features in the directory build.
* **Updates:** WordPress.org installs update via the official plugin directory. ZIP from rotalabs.co uses a separate signed update channel.

Privacy policy and terms: https://rotalabs.co/br/privacy and https://rotalabs.co/br/terms

== Screenshots ==

1. Link library in the WordPress admin.
2. Visual block editor with style picker.
3. License screen (optional free registration and Pro activation).

== Installation ==

**WordPress.org (recommended for the directory):**

1. Go to **Plugins → Add New** and search for "Rota WP Core".
2. Install and activate.
3. Open **Rota WP Core → Links** and add your links.
4. Open **Rota WP Core → Blocks**, build blocks, and copy the shortcode.

**Manual ZIP (rotalabs.co):**

1. Download the ZIP from https://rotalabs.co/products/rota-wp
2. Use **Plugins → Add New → Upload Plugin**, activate, then follow steps 3–4 above.

== Frequently Asked Questions ==

= Does the plugin work without a RotaLabs account? =

Yes. Styles 1 and 2, the link library, blocks, and the shortcode work locally. An account or license is only needed for Pro styles (3 and 4) or the free-registration benefit (more links per block).

= What data is sent to rotalabs.co? =

Only when you **opt in**:

* **Register site (free):** WordPress administrator email, site URL, plugin version.
* **Activate Pro license:** license key and site URL (validation/activation).

The plugin does not track public site visitors. GA4 depends on `gtag` you already installed in your theme or another plugin.

Privacy policy: https://rotalabs.co/br/privacy

= Where do updates come from? =

* Installed from **WordPress.org** → updates via the WordPress dashboard (official SVN).
* Installed from **RotaLabs ZIP** → signed updates from the RotaLabs API (separate channel).

= How do I insert a block? =

`[rota-wp-core bloco="block-slug"]`

Optional limit: `[rota-wp-core bloco="slug" limite="4"]`

= What is the grace period for styles 3 and 4? =

Sites that already used styles 3/4 before v1.1 keep access for 30 days while migrating to the Pro model. This is not trialware with automatic lockout after install; it is a transition for sites that already had the feature active.

= Does the plugin install Google Analytics? =

No. It only fires events if `gtag` exists on the front end.

== Upgrade Notice ==

= 1.4.37 =
* Carrossel — estilo 3 (cards coloridos): lane de scroll deixa de herdar display: grid / regras de .rwp-colored….
* Carrossel — estilos 1/2/5: overrides flex consolidados para .rwp-grid-* e .rwp-grid-trust em modo scroll (mes….

= 1.4.36 =
* Carrossel — estilo 4 (hero): .rwp-hero-grid deixava de usar display: grid em modo scroll; faixa horizontal e….
* Mobile: media query não força coluna única em lanes .rwp-scroll-lane.

= 1.4.35 =
* Front — Links em Carrossel: render respeita links_layout=carousel já salvo na meta (sem rebaixar entitlement….
* Estilo 4 — hero: links usam render_links_container / scroll lane como os demais estilos.

= 1.4.34 =
* Admin — estilo do bloco: removido loop infinito setStyle → trigger('change') que estourava a stack do jQuery….

== Changelog ==

= 1.4.37 =
* Carrossel — estilo 3 (cards coloridos): lane de scroll deixa de herdar `display: grid` / regras de `.rwp-colored-static` e `overflow-y: auto`; faixa horizontal com cards de largura fixa e setas funcionais.
* Carrossel — estilos 1/2/5: overrides flex consolidados para `.rwp-grid-*` e `.rwp-grid-trust` em modo scroll (mesma causa de especificidade do estilo 4 corrigido em 1.4.36).

= 1.4.36 =
* Carrossel — estilo 4 (hero): `.rwp-hero-grid` deixava de usar `display: grid` em modo scroll; faixa horizontal e setas passam a funcionar (antes ficava grade 2 colunas com controles visíveis).
* Mobile: media query não força coluna única em lanes `.rwp-scroll-lane`.

= 1.4.35 =
* Front — Links em Carrossel: render respeita `links_layout=carousel` já salvo na meta (sem rebaixar entitlement no `should_use_scroll`); hub recebe `rwp-layout-scroll` e wrapper `data-rwp-scroll`.
* Estilo 4 — hero: links usam `render_links_container` / scroll lane como os demais estilos.
* Safe mode: `get_block_data_minimal()` inclui `links_layout` para decisão de layout consistente.

= 1.4.34 =
* Admin — estilo do bloco: removido loop infinito `setStyle` → `trigger('change')` que estourava a stack do jQuery na carga da página e impedia seleção de links e pré-visualização.

= 1.4.33 =
* Admin — links do bloco: seleção na biblioteca volta a popular a coluna “Ordem no bloco”; título via `data-link-title`; leitura estável de `data-link-id`.
* Admin — pré-visualização: script do bloco não depende mais de `media-editor` para carregar; AJAX envia `link_ids` de forma compatível com PHP; refresh após sync de links e ao abrir a tela.

= 1.4.32 =
* WordPress.org — Guideline 5: canal `RWP_BUILD_CHANNEL=wordpress_org` (injetado em `package:rotawp-wporg`) libera localmente estilos 3–4, temas Pro, densidade expandida, duplicar bloco, A/B, TOC completo e links ilimitados sem chave.
* Tela Licença no pacote .org: aviso de build completo; sem fetch de atualização RotaLabs no carregamento.
* GA4 nas configurações: padrão desligado no pacote WordPress.org.
* `RWP_Updater::fetch_manifest()` não contacta rotalabs.co quando o canal de update é `wordpress`.

= 1.4.31 =
* Admin — tema visual: seleção alinhada ao radio (`:checked` + `is-selected` só no picker editorial); clique sem `preventDefault` desnecessário.
* Pro — altura do hub: três controles em Configurações (compacta, normal, expandida); `0` = altura livre conforme conteúdo. Migração automática do campo legado `block_max_height` quando as novas chaves ainda não existirem.
* Free / sem limite: blocos expandem com título, descrição e cards; sem teto fixo no CSS. Texto do metabox editorial atualizado.

= 1.4.30 =
* Admin — tema visual: clique nos swatches passa a selecionar o tema, atualizar borda `is-selected` e refrescar a pré-visualização; temas Pro bloqueados exibem aviso (como os estilos).
* Admin — estilos: seleção reforçada (radio + evento `change` para a prévia).

= 1.4.29 =
* Plugin Check: removido BOM UTF-8 em `rotawp-core.php`; `Stable tag` alinhado à versão do plugin.
* Segurança (admin): sanitização explícita de `$_POST` no save do bloco CTA e emoji de link; avisos GET de redirect documentados com `phpcs:ignore` onde apropriado.

= 1.4.28 =
* Títulos dos blocos: negrito garantido com `<strong class="rwp-title-text">` e seletores em `.rwp-core-hub` (resiste a reset de temas/Divi em `<p>`).
* Estilo 4 — CTA hero: texto branco legível em todos os estados; botão com `width: fit-content` e alinhamento à esquerda (largura conforme o texto).

= 1.4.27 =
* Estilo 3: removida imagem lateral no admin e no front; cards ocupam a largura da grade com descrição dos links visível.
* Títulos dos blocos: `<h3>` substituído por `<p class="rwp-title">` (18px, negrito) em todos os layouts e no fallback mínimo.
* Editor de blocos: metabox “Pré-visualização” passa para a coluna principal, abaixo de “Textos e mídia”.

= 1.4.26 =
* Visual “quebrado” / lista mínima em páginas publicadas e teste Divi: deixa de forçar render mínimo quando `is_preview()` ou `?preview=true` (motivo `wp_preview` no HTML). O layout completo volta no front; proteção do editor continua via placeholder/REST.
* Filtro opcional `rwp_force_minimal_in_preview` (default `false`) para reativar o comportamento antigo se necessário.

= 1.4.25 =
* Lista mínima com modo seguro desligado: `?preview` genérico na URL não força mais render mínimo (só `preview=true` / `preview=1` ou `is_preview()` do WordPress).
* Fallback de template: se estilo-3/4/5 falhar, tenta layout completo em estilo-1 antes da lista mínima.
* Diagnóstico no HTML: `data-rwp-render-reason` em modo mínimo (`safe_mode_setting`, `wp_preview`, `template_error`); layout completo usa `data-rwp-render="full"`.
* CSS/JS no Divi: enqueue tardio no `wp_footer` quando o shortcode roda após `wp_enqueue_scripts`.
* Logs `hub_render_ok` incluem `render_reason`.

= 1.4.24 =
* 503 / timeout no hub (estilo-2 e demais): recursão infinita `RWP_Themes::sanitize_key()` ↔ `can_use_theme()` ao montar classes da seção (`hub_tpl_before_section_classes` sem `hub_tpl_after_section_classes`).
* `can_use_theme()` passa a validar com `sanitize_key()` do WordPress + `get_definitions()`, sem chamar `sanitize_key()` do plugin.
* `RWP_Layout::editorial_modifier_classes()` usa tema já normalizado do bloco no caminho de render.

= 1.4.23 =
* 503 após `hub_before_render_styles`: filtros `rwp_render_link_attrs` e `rwp_layout_should_use_scroll` desligados no front por padrão (`rwp_run_render_filters`); evita travamento por hooks de tema/Divi na primeira passagem.
* URLs e attrs dos cards: truncamento de `url` em `get_link_data` e em `card_attrs` antes de `esc_attr`.
* Reentrância: guarda em `render_block_preview` + logs `hub_tpl_*` / `hub_style_render_*` para localizar a subetapa exata no debug.
* Integrações que dependem dos filtros no front devem usar `add_filter( 'rwp_run_render_filters', '__return_true' );`.

= 1.4.22 =
* 503 / timeout no template completo: guarda de reentrância em `rwp_layout_should_use_scroll` e `rwp_render_link_attrs` (evita recursão infinita de temas/plugins no Divi).
* Textos enormes em meta: truncamento UTF-8 em títulos/descrições/botões dos links e no cabeçalho do bloco antes de `esc_html` / `esc_attr`, reduzindo custo de escape em metas acidentais gigantes.
* Diagnóstico: `hub_php_fatal` no shutdown passa a incluir `last_hub_render` (último evento `hub_*` registrado no request).

= 1.4.21 =
* Template final do hub (safe mode OFF): logs por subetapa (`hub_before_hydrate_images`, `hub_after_hydrate_images`, `hub_before_render_styles`, `hub_after_render_styles`).
* Fallback por request: se o template completo lançar exceção, aplica `hub_template_fallback_minimal` e renderiza versão mínima sem derrubar a página.
* `hub_render_ok.minimal` agora reflete o modo realmente usado no request (inclui fallback/preview forçado).

= 1.4.20 =
* Render completo em produção: sanitização de densidade/display/theme/layout no `get_block_data_raw` agora usa caminho rápido sem validações de licença/transient durante render (menos risco de travar entre `hub_after_ab` e `hub_after_block_data`).
* Mantém validação/licenciamento no admin/salvamento; otimização aplicada apenas no caminho de montagem de bloco no front.

= 1.4.19 =
* Preview (`?preview=true`) com safe mode OFF: força render mínimo para evitar loop pesado e 503 no editor/previews enquanto mantém layout completo no front publicado.
* Diagnóstico do bloco: novos eventos `hub_block_data_stage` no caminho completo para identificar exatamente a etapa que congela entre `hub_after_ab` e `hub_after_block_data`.
* Montagem de densidade: `resolve_density()` passa a aceitar valor já carregado para evitar leitura extra de meta.

= 1.4.18 =
* Render completo (safe mode OFF): `get_block_data_raw()` agora lê os metadados do bloco em lote (`get_post_meta($block_id)`) em vez de dezenas de consultas individuais/fallback legado por chave.
* Shortcode `limite`: no fluxo completo, o limite volta a ser respeitado no carregamento de links (`get_link_data_for_prepared_block`).

= 1.4.17 =
* Ícones de link: apenas emoji (grade de sugestões + campo opcional). Removida opção SVG no admin; meta `_rwp_icon_svg` apagada ao salvar; front não lê mais SVG (links antigos com SVG passam a usar emoji, padrão ✈️).

= 1.4.16 =
* 503 com modo seguro desligado: layout completo não chama mais `wp_get_attachment_image_url` durante `get_block_data` no front (URLs hero/lateral só na hora do HTML); `icon_svg` gigante ignorado no front.
* Editor REST (`/wp-json/wp/v2/posts/...`): shortcode vira placeholder — evita render pesado ao salvar/abrir post no Divi/Gutenberg (causava timeout mesmo com 4 links).

= 1.4.15 =
* Modo seguro: caminho ultra-leve — corta `link_ids` antes de carregar meta pesada (sem hero/side image, sem `icon_svg`/badges por link); `get_link_data_lite()` só título + URL.
* Diagnóstico: logs `hub_after_ab`, `hub_after_block_data`, `hub_after_links` e `hub_php_fatal` no shutdown (quando PHP registra fatal).

= 1.4.14 =
* Log de debug do hub (Configurações → Estabilidade): linhas `[Rota WP Core]` em `wp-content/debug.log` com memória, block_id, fase do render e exceções.
* Constante opcional `RWP_DEBUG_HUB` no `wp-config.php` para forçar log.
* Modo render seguro agora usa HTML mínimo (lista de links), sem carrossel nem templates pesados — deve evitar 503 quando o layout completo estoura o servidor.
* Modo seguro não carrega `rota-wp-core.js` (só CSS).
* Cache de render por request; SVG de ícone muito grande volta para emoji.
* `try/catch` no render com comentário HTML em caso de falha (e log se debug ativo).

= 1.4.13 =
* 503 ao editar artigos/blocos: no admin e na prévia REST do Gutenberg, o hub não monta mais o HTML completo (evita timeout/fatal ao abrir `post.php`). Só a prévia AJAX da tela do bloco CTA renderiza o hub inteiro.
* Filtro de emergência `rwp_skip_hub_render` para forçar placeholder.

= 1.4.12 =
* Configurações → Estabilidade: opção para desativar registro do bloco Gutenberg (`rotawp-core/hub`); shortcode `[rota-wp-core]` continua ativo.
* Modo render seguro: desliga A/B Pro e telemetria REST (impressões/cliques) no front; mantém HTML do hub.
* A/B cookie: guarda via `RWP_Renderer::is_rendering()` (o hook `doing_action('render_block')` não existe no WordPress); também cobre `doing_filter('render_block')`.

= 1.4.11 =
* 503 em posts com hub Gutenberg: cookie A/B não é mais enviado durante `the_content` / `render_block`; auto-insert respeita hub já renderizado e detecta bloco em blocos reutilizáveis (`core/block`).
* Render: guarda contra reentrância; classes de layout/tema com fallback se deploy parcial.
* A/B: cache por request em `find_config` (menos `get_posts` por página).

= 1.4.10 =
* 503 / página quebrada em posts com hub: auto-insert não duplica mais quando o conteúdo já tem o bloco Gutenberg; assets e renderer toleram classes opcionais ausentes; cookie A/B só é gravado antes do output.
* REST de cliques/impressões no `wp_localize_script` só quando `RWP_Click_Rest` está carregado.
* Lista de Links: coluna Blocos (quantos blocos CTA usam o link) no lugar de Ordem.

= 1.4.9 =
* Impressões no viewport (IntersectionObserver) + REST `rwp/v1/impression`.
* CTR por bloco no relatório Analytics (cliques ÷ impressões).
* Testes A/B (Pro): metabox no bloco, cookie 30 dias, relatório A vs B em Analytics.
* Configuração de contagem interna cobre impressões e cliques.

= 1.4.8 =
* Bloco Gutenberg `rotawp-core/hub` — seletor de bloco, override de estilo e limite; prévia via ServerSideRender.
* Importar / Exportar JSON de links e blocos (menu Rota.WP Core).
* Assets do hub carregam quando o post contém o bloco Gutenberg.
