Skip to content

v6.24.0

Choose a tag to compare

@github-actions github-actions released this 11 Sep 00:11
· 24 commits to main since this release
c08e59a

Fixed

  • Hub de e-mails não oferecia um token que o próprio padrão usa (#1143): a lista de ajuda por e-mail é texto escrito à mão ao lado de um template mantido em outro lugar, então ela deriva em silêncio — nas duas direções. Guarda nova compara catálogo, allowlist e arquivos: um token usado no corpo padrão e ausente da lista falha o CI.
  • E-mail de aprovação de agendamento não trazia o link de cancelamento (#1143): num calendário que exige aprovação, o e-mail da reserva só diz "aguardando aprovação, você receberá a confirmação" — a confirmação é o e-mail de aprovação, e ele era o único dos cinco e-mails de agendamento sem o link. Quem tinha o agendamento de fato confirmado era justamente quem não conseguia cancelar pela caixa de entrada. A cobertura existente provava o token resolvendo dentro de um override do hub, o que não diz nada sobre o corpo que uma instalação sem override recebe.
  • Campo numérico do admin salvava valor inválido pelo autosave (#1114): o widget salva a cada tecla e nunca consultava a validade do campo, então min, max e step eram decorativos ali — vazio, negativo e decimal passavam. Os dois caminhos de autosave passam a recusar o que o navegador considera inválido; toggles não são afetados.
  • Limpar um limite na aba Rate Limit gravava zero e bloqueava o eixo inteiro (#1114): os checadores leem contagem >= 0 como "limite já atingido", então um ip_max_per_hour apagado barrava toda submissão de todo endereço. Campo vazio ou ausente passa a manter o valor gravado, com piso igual ao min que o próprio campo declara.
  • Campo obrigatório no perfil de usuário não era exigido em ponta nenhuma (#1120): is_required só desenhava o asterisco — nenhum input emitia o atributo e o salvamento não conferia a flag, então um campo marcado obrigatório gravava vazio em silêncio. Agora o navegador exige e o servidor preserva o valor gravado quando o campo chega vazio, avisando quais preservou.
  • Limpar o campo de lembrete de uma campanha de rerrematrícula gravava zero (#1117): absint( '' ) é 0, e a varredura lê DATEDIFF(end_date, CURDATE()) <= reminder_days — o lembrete passava a sair só no último dia da campanha, tarde demais para servir, sem nada na tela dizendo que o valor mudou.
  • Limpar um campo numérico no admin gravava o piso daquela chave, em silêncio (#1111): (int) '' é 0, então esvaziar o campo escrevia o menor valor aceito — e o autosave salva a cada tecla, então bastava apagar para retomar a digitação. O endpoint agora recusa valor vazio e mantém o gravado; 0 digitado continua valendo.
  • O e-mail de acesso concedido nunca foi enviado por nenhuma instalação (#1123): notify_capability_grant guardava o envio e não era escrita em lugar nenhum — nem campo, nem allowlist, nem padrão declarado — então a guarda lia false para sempre, enquanto o hub de e-mails oferecia o texto para edição. Ganhou interruptor na aba SMTP, desligado por padrão para preservar o comportamento de hoje.
  • Linha de horário de trabalho pela metade era gravada em silêncio (#1128): a guarda do servidor era isset( $entry['entry1'] ), e isset( '' ) é verdadeiro — então uma linha com horário vazio passava. O formulário público de recadastramento era ainda mais permissivo: conferia só o dia. Agora um só sanitizador decide pelas duas telas.
  • Reativar uma campanha de recadastramento não avisava ninguém (#1125): ao expirar, as submissões pendentes viram expired; a reativação não as reabria — e a semeadura pula quem já tem linha — então o usuário ficava num estado que nem deixava enviar nem desenhava aviso. O convite por e-mail também não saía, porque busca só pending. Reativar agora reabre as expired, sem tocar em approved/submitted.
  • Quem entra na audiência depois da ativação não via a campanha (#1125): a semeadura é evento único na transição para ativa, então esse usuário nunca ganhava linha e caía no mesmo vão mudo. Agora "sem submissão" é um estado que pode enviar — o que também cobre a submissão excluída pelo administrador, devolvendo o usuário ao início.
  • Modo escuro: as 28 folhas passam a pintar pela paleta (#1126): metade delas não usava token nenhum — calendário, encurtador, recrutamento, recadastramento, submissões, painel de certificados, público-alvo, modelo de e-mail e as demais pintavam com hex fixo, então badges, modais, tabelas e o balão de toast ficavam claros dentro da tela escura. A catraca bloqueia em zero; o que segue literal é decisão com o motivo escrito ao lado.
  • A paleta precisa estar na página, e ela não estava — de quatro formas (#1126): uma custom property não declarada invalida a declaração inteira, não cai para o literal anterior. Dezesseis enfileiramentos liam var(--ffc-*) sem declarar ffc-common; o dashboard e a lista de editais redeclaravam --ffc-* localmente, o que sombreia a paleta para tudo ali dentro; duas regras liam token que nunca existiu, escondidas atrás do valor de reserva; e a página pública de cancelamento monta o próprio documento, então nunca passou pelo enfileiramento — ficou sem fundo, sem cor de texto e com o botão despintado, nos dois temas.
  • O interruptor não chegava a quatro telas públicas (#1126): calendário, público-alvo (dois caminhos) e editais enfileiravam a paleta mas não o script que põe .ffc-dark-mode no <html>. Sem ele todo var(--ffc-*) resolve pelo bloco claro, por mais tokenizada que a folha esteja. A paleta sozinha não é o tema.
  • Texto que não declara cor herdava quase-preto, e controle de formulário nem isso (#1126): quem não declara color herda de fora do plugin — do body do wp-admin ou do tema — e cai em 1,28:1 sobre fundo escuro; era a legenda do calendário e o rótulo "Modelo:". Um <button>, <input>, <select> ou <textarea> não herda color e nem a regra de base o alcança: eram 18, incluindo todo campo do formulário público de recadastramento e da edição de perfil. As tarjas do admin precisaram de terceira resposta — nomear os nós de texto, porque qualquer declaração direta vence um valor herdado.
  • opacity e .alternate: dois defeitos que nenhum token corrigiria (#1126): a linha passada/cancelada da agenda levava opacity, que desbota texto e fundo juntos e derruba qualquer contraste que os tokens garantiram — 3,11:1 medido. E .alternate é a terceira forma de zebrar linha do WordPress, a que o plugin escreve à mão sete vezes só na aba de Cache.
  • Cor inline vencia a folha tokenizada (#1126): o aviso de e-mails desligados carregava a paleta inteira num style="" do PHP, em cinco telas; badges e faixas de edital fixavam #333 sobre uma cor que o administrador escolhe. Para o segundo caso nenhum token serve — o texto passa a ser calculado por luminância WCAG, com 4,58:1 garantido sobre qualquer cor do cubo RGB.
  • Três rótulos de botão reprovavam o contraste (#1126): sucesso (3,35:1) e aviso (3,04:1) sobre branco, e .ffc-text-warning usando cor de sinal como texto. O verde escureceu para #00801e; nasceram os pares on-success e on-warning — o primeiro inverte entre os temas, o segundo não, porque o aviso é tom médio-claro nos dois.
  • Trocar o modo escuro só valia no carregamento seguinte (#1126): o seletor salva sozinho, mas nada repintava a página — nas duas direções, o que se lê como um salvamento que falhou. O autosave passa a anunciar o que gravou e o script do tema aplica na hora, inclusive parando de seguir o sistema operacional ao sair do "automático".
  • Dez pares de cor da paleta reprovavam o contraste mínimo (#1132): o pior era o rótulo do botão primário no tema escuro — branco sobre a primária clara, 2,52:1, desde que o tema escuro existe. O Material 3 inverte esse par no escuro (a primária clareia, o texto sobre ela escurece) e o plugin só tinha feito metade. Corrigidos também os contornos de campo e card nos dois temas e o anel de foco, que compunha 1,78:1 no claro.
  • Placeholder e indicador de aviso ficaram mais escuros no tema claro (#1132): #8c8f94 e #dba617 vêm da paleta do próprio WordPress e reprovavam 3,24:1 e 2,22:1. A correção afasta um pouco o plugin do visual do wp-admin — foi decisão deliberada, em favor da legibilidade.
  • Cinco dos oito mutadores de audiência não invalidavam o cache de audiências do usuário (#1127): a chave morava num grupo literal próprio, fora do par Reader/Writer, então cada mutador tinha de lembrar sozinho — e bulk_add_members(), o caminho do admin, não lembrava. Decidia errado a campanha de recadastramento no painel e os campos personalizados no perfil. A chave passa a morar no grupo do par, com um só ponto de invalidação e TTL, que antes não havia.
  • Sair de uma audiência não limpava o cache de quem saiu (#1127): set_members() invalidava só a lista que entrava, então quem era removido seguia vendo a audiência. cascade_self_join() não invalidava nada — nem por id, nem a versão de consulta — e altera allow_self_join, que a lista devolve.

Changed

  • Cancelar um agendamento pelo painel passa a abrir um diálogo, não um confirm() (#1140): o confirm() não dizia qual agendamento seria cancelado e não tinha campo de motivo — então um cancelamento pelo painel gravava motivo vazio enquanto o mesmo pelo link do e-mail gravava o que a pessoa escreveu. O endpoint já aceitava e sanitizava reason; a lacuna era só do cliente. O diálogo mostra serviço e data/hora, e reaproveita as mesmas strings da página pública.
  • Modal vira componente compartilhado na paleta (#1140): havia duas cópias — uma no público-alvo, outra no admin de recadastramento — e o painel seria a terceira. A do público-alvo foi para ffc-common.css, que toda folha que já a usava declara como dependência. A do admin ficou onde está: seletores sem escopo, outra tela.
  • Entradas numéricas do admin fora das abas de configuração agora exigem valor (#1117): 19 campos ganharam required — auto-agendamento, quiz, recrutamento, rerrematrícula e modelo de e-mail. Oito ficaram de fora, cada um com o motivo travado em teste: em cinco vazio significa "herdar o global" ou "sem limite", um não é campo de formulário, e em dois a obrigatoriedade pertence à definição do campo.
  • required passa a acompanhar os blocos que o JS esconde (#1117, #1120): campo obrigatório escondido trava o envio apontando para um controle que ninguém vê. Fecha junto dois casos já vivos — as linhas de horário de trabalho do editor de calendário, e os dois campos de hora do perfil de usuário, obrigatórios dentro de seções recolhíveis.
  • Os dois caminhos de autosave do admin viraram um só widget (#1116): o data-ffc-autosave-form-key tinha implementação própria em ffc-admin.js — mesmo trabalho, outro evento, outro badge — e a guarda de validade do #1114 precisou ser escrita duas vezes para alcançar os dois. Agora um widget lê os dois atributos; os endpoints seguem separados, com capacidade e nonce próprios.
  • Badge de autosave dos metaboxes passa a seguir o modo escuro (#1116): usava hex fixo em vez dos tokens --ffc-*. De quebra, distingue queda de conexão de recusa do servidor, que a implementação antiga achatava num "falha ao salvar" genérico, e os textos das abas de configuração deixam de ser literais em inglês no JS.
  • Entradas numéricas das abas de configuração agora são obrigatórias (#1114): 38 campos ganharam required, e o smtp_port — o único sem limite algum — ganhou faixa. Os caps de endpoint de leitura passam a dizer no próprio card que ali 0 remove o limite, ao contrário dos demais.
  • Piso da janela de emissão de captcha baixado de 60s para 1s (#1111): abaixo de um minuto o limite vira decorativo — o campo passa a dizer isso como recomendação, em vez de o código recusar, alinhando com os demais limites da aba.
  • Horário de trabalho: a regra da linha agora é exigida, e antes do envio (#1128): entrada do primeiro turno e saída do último são obrigatórias, o intervalo é opcional — regra que existia só como um required no markup e que ninguém tinha escrito. Uma linha pela metade bloqueia o envio nomeando o que falta e abrindo a seção recolhida, em vez de o servidor decidir sozinho o que descartar; nada do que foi digitado se perde. ⚠ Linha sem horário nenhum deixa de ser gravada: um dia sem linha já significa "não trabalho neste dia".
  • Nenhum status de recadastramento produz mais tela em branco (#1125): o painel tratava approved e submitted e caía num continue mudo para todo o resto. Ganhou ramo final mostrando o status legível — os dois casos que caíam ali estão corrigidos na origem, e o ramo existe para o próximo status não repetir a história.
  • Modo escuro passa a repintar o que o WordPress desenha (#1126): o modo escuro era só a troca de tokens, e nada aplicava esses tokens ao chrome do core — então rótulos de form-table ficavam escuros sobre fundo escuro e os campos continuavam brancos dentro do card escuro. Rótulos, campos, cards, metaboxes, tabelas de listagem, abas, botões secundários e avisos passam a seguir a paleta. Falta ainda a metade das folhas de admin que não usam token nenhum.

Removed

  • ⚠ O argumento $token de check_verification() (#1048): anunciado obsoleto na 6.22.0, removido agora conforme o prazo publicado. RateLimiter::check_verification() e RateLimitChecker::check_verification() passam a receber só o IP. Nenhum chamador passava o segundo argumento, e quem passar não quebra — o PHP ignora argumento excedente em função de usuário.
  • Sete acessores do SettingsReader que liam a opção errada (#1123): admin_bar_allowed(), wp_admin_blocked() e admins_bypassed() liam chaves de ffc_user_access_settings; ip_cache_enabled(), ip_api_enabled(), ip_cache_ttl() e gps_cache_ttl() liam chaves de ffc_geolocation_settings, duplicando acessores corretos que já existiam. Nada os chamava, e nada escrevia aquelas chaves em ffc_settings — devolviam o padrão embutido para sempre.

Added

  • Emissão de desafios ALTCHA agora é configurável (#1111): teto e janela no bloco de IP da aba Rate Limit, padrões 60 e 600s — os valores que já vigoravam — e teto 0 = sem limite. Era o único limite do sistema sem controle na interface: atrás de NAT institucional ele barrava o formulário para todos depois do 60º desafio, com 429 e nenhum erro visível.
  • Guarda de caminho de escrita sobre ffc_settings (#1123, #993): toda chave lida da opção precisa poder ser gravada nela — por campo, por allowlist de autosave ou por padrão declarado. Bloqueia em zero, sem baseline, e pega as duas formas que motivaram a issue: o acessor de chave alheia e a funcionalidade dormente. Junto vai uma catraca das 32 chaves lidas sem declaração, que só encolhe.
  • O guarda de modo escuro passa a medir contraste (#1132): antes só procurava cor literal — via presença, não legibilidade. Agora calcula a razão WCAG de cada par que o CSS realmente pinta, nos dois temas, e bloqueia em zero. Teria acusado o botão primário do tema escuro no dia em que ele foi escrito.
  • Catraca de cor literal por folha de estilo (#1126): as sete folhas convertidas bloqueiam em zero; as demais carregam o número medido como orçamento que só encolhe. Junto vai a metade que faltava — toda folha que lê var(--ffc-*) precisa declarar ffc-common como dependência, que é o que achou os dezesseis enfileiramentos sem paleta.