LGPD

Exportar dados pessoais no WordPress: atender o pedido LGPD do titular

Caiu um e-mail pedindo “todos os meus dados” e o relógio da LGPD começou a correr. O WordPress tem isso pronto desde a 4.9.6: vá em Ferramentas > Exportar dados pessoais, digite o e-mail do titular e envie o pedido. Depois que ele confirma pelo link, você clica em Baixar dados pessoais e o núcleo gera um ZIP em wp-content/uploads/wp-personal-data-exports/.

O problema é que esse ZIP sai pela metade: o núcleo exporta o perfil, os comentários e os anexos de mídia, e nada do que o seu plugin ou o WooCommerce guardaram em tabela própria ou em user meta entra.

Registrando seu exportador

add_filter('wp_privacy_personal_data_exporters', function (array $exporters): array {
    $exporters['minha-newsletter'] = [
        'exporter_friendly_name' => 'Newsletter da loja',
        'callback'               => 'rt_exportar_newsletter',
    ];

    return $exporters;
});

function rt_exportar_newsletter(string $email, int $page = 1): array {
    global $wpdb;

    $linha = $wpdb->get_row($wpdb->prepare(
        "SELECT origem, criado_em FROM {$wpdb->prefix}newsletter WHERE email = %s",
        $email
    ), ARRAY_A);

    $data = [];

    if ($linha) {
        $data[] = [
            'group_id'    => 'newsletter',
            'group_label' => 'Newsletter',
            'item_id'     => 'newsletter-' . md5($email),
            'data'        => [
                ['name' => 'Origem do cadastro', 'value' => $linha['origem']],
                ['name' => 'Data do aceite',     'value' => $linha['criado_em']],
            ],
        ];
    }

    return ['data' => $data, 'done' => true];
}

Onde isso costuma quebrar

A chave done é obrigatória. Com milhares de linhas, devolva um lote por chamada usando o $page e só mande done => true no último; devolver false pra sempre trava o admin em loop.

E saiba onde o arquivo mora: uploads é público, então o ZIP fica acessível por URL pra quem souber o endereço, e a única barreira é o hash aleatório no nome. Um cron horário apaga os exports com mais de três dias, prazo que o filtro wp_privacy_export_expiration muda. Não copie o ZIP pra outra pasta.

Os pedidos ficam no post type user_request, com status request-pending até o titular confirmar. Se a confirmação não chega, o problema é entrega de e-mail, não o exportador: teste com sudo -u www-data wp eval "var_dump(wp_mail('voce@dominio.com','teste','ok'));".

Post Recentes

Desativar o 2FA do Magento 2 no ambiente local sem quebrar o admin

Cópia local do Magento pedindo código do autenticador e o e-mail de setup não chega. Desligue os dois módulos de…

1 dia atrás

Erro 429 na API de IA: backoff exponencial em PHP com retry e usleep

Seu script em lote morre no meio com HTTP 429 Too Many Requests? Leia o header Retry-After e troque o…

2 dias atrás

WooCommerce sem métodos de entrega no checkout: como achar a área errada

O checkout avisa que não existem métodos de entrega disponíveis. Veja a ordem de checagem nas áreas de entrega e…

2 dias atrás

usort PHP: ordenar array de arrays por um campo com o spaceship

Ordene uma lista de produtos por preço em uma linha de PHP 8.3, sem montar colunas separadas pro array_multisort, e…

3 dias atrás

Ativar WP_DEBUG_LOG no WordPress: log de erros sem aparecer na tela

Tela branca ou fatal error no site e o visitante não pode ver a mensagem. Grave os erros do WordPress…

4 dias atrás

CNPJ alfanumérico Magento 2: módulo grátis com máscara e validação

Módulo gratuito Roger_CnpjAlfanumerico que aplica máscara e validação do novo CNPJ alfanumérico no checkout e formulários do Magento 2 e…

3 meses atrás