{"id":250,"date":"2026-05-13T10:00:36","date_gmt":"2026-05-13T13:00:36","guid":{"rendered":"http:\/\/neodoor.neo\/?p=250"},"modified":"2026-05-21T09:02:32","modified_gmt":"2026-05-21T12:02:32","slug":"advanced-database-cleaner","status":"publish","type":"post","link":"https:\/\/www.portanova.com.br\/notebook\/advanced-database-cleaner\/","title":{"rendered":"[MU] Advanced Database Cleaner"},"content":{"rendered":"<h2>Aula: Limpeza de Banco de Dados com MU-Plugin \u2013 Substituindo o Advanced Database Cleaner<\/h2>\n<p><strong>Objetivo:<\/strong> Substituir um plugin robusto como o <code>Advanced Database Cleaner<\/code> por um MU-Plugin enxuto, que mant\u00e9m o banco de dados limpo removendo revis\u00f5es antigas, transients expirados, rascunhos autom\u00e1ticos, lixeira, coment\u00e1rios spam e outros res\u00edduos deixados por temas e plugins desinstalados.<\/p>\n<p><strong>Contexto:<\/strong> O <code>Advanced Database Cleaner<\/code> \u00e9 um plugin popular com interface gr\u00e1fica e op\u00e7\u00f5es avan\u00e7adas, mas muitas de suas fun\u00e7\u00f5es podem ser reproduzidas com c\u00f3digo eficiente e sem sobrecarga. Vamos criar um MU-Plugin que realiza a limpeza autom\u00e1tica via WP-Cron, sem necessidade de interface administrativa, tornando o processo transparente e de f\u00e1cil manuten\u00e7\u00e3o.<\/p>\n<h3>Funcionalidades implementadas no nosso MU-Plugin<\/h3>\n<ul>\n<li><strong>Remo\u00e7\u00e3o de revis\u00f5es antigas de posts\/p\u00e1ginas<\/strong> (padr\u00e3o: 30 dias)<\/li>\n<li><strong>Remo\u00e7\u00e3o de rascunhos autom\u00e1ticos (auto-drafts)<\/strong><\/li>\n<li><strong>Remo\u00e7\u00e3o de posts na lixeira (trash)<\/strong><\/li>\n<li><strong>Remo\u00e7\u00e3o de coment\u00e1rios spam, pendentes e na lixeira<\/strong><\/li>\n<li><strong>Remo\u00e7\u00e3o de pingbacks e trackbacks<\/strong><\/li>\n<li><strong>Remo\u00e7\u00e3o de transients expirados<\/strong> (lixo tempor\u00e1rio do WordPress)<\/li>\n<li><strong>Remo\u00e7\u00e3o de meta dados \u00f3rf\u00e3os (postmeta, commentmeta, usermeta, termmeta)<\/strong> \u2013 dados deixados por plugins desinstalados<\/li>\n<li><strong>Remo\u00e7\u00e3o de relacionamentos \u00f3rf\u00e3os (term_relationships)<\/strong><\/li>\n<li><strong>Remo\u00e7\u00e3o de op\u00e7\u00f5es \u00f3rf\u00e3s na tabela wp_options<\/strong> (res\u00edduos de plugins removidos)<\/li>\n<li><strong>Remo\u00e7\u00e3o de cache oEmbed<\/strong><\/li>\n<li><strong>Execu\u00e7\u00e3o autom\u00e1tica via WP-Cron<\/strong> (di\u00e1ria)<\/li>\n<li><strong>Log das opera\u00e7\u00f5es<\/strong> para depura\u00e7\u00e3o (opcional, ativado via constante)<\/li>\n<\/ul>\n<h3>C\u00f3digo do MU-Plugin<\/h3>\n<p>Crie a pasta <code>wp-content\/mu-plugins\/neodoor-db-cleaner\/<\/code> e dentro dela o arquivo <code><strong>neodoor-db-cleaner.php<\/strong><\/code> com o conte\u00fado abaixo:<\/p>\n<pre><code>&lt;?php\n\/**\n * Plugin Name:  Neodoor Database Cleaner\n * Description:  Limpeza autom\u00e1tica e segura do banco de dados: revis\u00f5es antigas, transients expirados, lixeira, spam, metadados \u00f3rf\u00e3os e res\u00edduos de plugins.\n * Version:      1.0\n * Author:       Reinaldo (Neodoor.neo)\n *\/\n\nif ( ! defined( 'ABSPATH' ) ) {\n    exit;\n}\n\nclass Neodoor_DB_Cleaner {\n\n    private static $instance = null;\n\n    \/\/ Configura\u00e7\u00f5es (podem ser alteradas aqui ou via constantes)\n    private $keep_revisions_days = 30;\n    private $log_enabled = false;\n\n    public static function get_instance() {\n        if ( null === self::$instance ) {\n            self::$instance = new self();\n        }\n        return self::$instance;\n    }\n\n    private function __construct() {\n        \/\/ Carrega configura\u00e7\u00f5es de constantes, se definidas\n        if ( defined( 'NEODOOR_DB_CLEANER_KEEP_REVISIONS_DAYS' ) ) {\n            $this-&gt;keep_revisions_days = intval( NEODOOR_DB_CLEANER_KEEP_REVISIONS_DAYS );\n        }\n        if ( defined( 'NEODOOR_DB_CLEANER_LOG_ENABLED' ) ) {\n            $this-&gt;log_enabled = (bool) NEODOOR_DB_CLEANER_LOG_ENABLED;\n        }\n\n        \/\/ Agenda a limpeza di\u00e1ria (se n\u00e3o estiver agendada)\n        add_action( 'wp', [ $this, 'schedule_cleanup' ] );\n        add_action( 'neodoor_db_daily_cleanup', [ $this, 'run_full_cleanup' ] );\n    }\n\n    \/**\n     * Agenda o evento de limpeza di\u00e1ria (hook: neodoor_db_daily_cleanup)\n     *\/\n    public function schedule_cleanup() {\n        if ( ! wp_next_scheduled( 'neodoor_db_daily_cleanup' ) ) {\n            wp_schedule_event( time(), 'daily', 'neodoor_db_daily_cleanup' );\n            $this-&gt;log( 'Evento de limpeza di\u00e1ria agendado.' );\n        }\n    }\n\n    \/**\n     * Executa todas as rotinas de limpeza\n     *\/\n    public function run_full_cleanup() {\n        global $wpdb;\n        \n        $this-&gt;log( 'Iniciando limpeza completa do banco de dados.' );\n        \n        \/\/ 1. Remove revis\u00f5es antigas\n        $this-&gt;delete_old_revisions();\n        \n        \/\/ 2. Remove rascunhos autom\u00e1ticos\n        $this-&gt;delete_auto_drafts();\n        \n        \/\/ 3. Remove posts na lixeira\n        $this-&gt;delete_trashed_posts();\n        \n        \/\/ 4. Remove coment\u00e1rios spam, pendentes e na lixeira\n        $this-&gt;delete_spam_comments();\n        $this-&gt;delete_pending_comments();\n        $this-&gt;delete_trashed_comments();\n        \n        \/\/ 5. Remove pingbacks e trackbacks\n        $this-&gt;delete_pingbacks_trackbacks();\n        \n        \/\/ 6. Remove transients expirados\n        $this-&gt;delete_expired_transients();\n        \n        \/\/ 7. Remove metadados \u00f3rf\u00e3os\n        $this-&gt;delete_orphaned_post_meta();\n        $this-&gt;delete_orphaned_comment_meta();\n        $this-&gt;delete_orphaned_user_meta();\n        $this-&gt;delete_orphaned_term_meta();\n        \n        \/\/ 8. Remove relacionamentos \u00f3rf\u00e3os\n        $this-&gt;delete_orphaned_term_relationships();\n        \n        \/\/ 9. Remove op\u00e7\u00f5es \u00f3rf\u00e3s (res\u00edduos de plugins desinstalados)\n        $this-&gt;delete_orphaned_options();\n        \n        \/\/ 10. Remove cache oEmbed\n        $this-&gt;delete_oembed_cache();\n        \n        \/\/ 11. Otimiza as tabelas (opcional)\n        $this-&gt;optimize_tables();\n        \n        $this-&gt;log( 'Limpeza completa finalizada.' );\n    }\n    \n    \/**\n     * Remove revis\u00f5es de posts\/p\u00e1ginas com mais de X dias\n     *\/\n    private function delete_old_revisions() {\n        global $wpdb;\n        $sql = $wpdb-&gt;prepare(\n            \"DELETE FROM {$wpdb-&gt;posts} \n             WHERE post_type = 'revision' \n             AND post_date &lt; NOW() - INTERVAL %d DAY\", $this-&gt;keep_revisions_days\n        );\n        $deleted = $wpdb-&gt;query( $sql );\n        $this-&gt;log( \"Revis\u00f5es antigas removidas: {$deleted}\" );\n    }\n    \n    \/**\n     * Remove rascunhos autom\u00e1ticos\n     *\/\n    private function delete_auto_drafts() {\n        global $wpdb;\n        $deleted = $wpdb-&gt;query(\n            \"DELETE FROM {$wpdb-&gt;posts} \n             WHERE post_status = 'auto-draft'\"\n        );\n        $this-&gt;log( \"Rascunhos autom\u00e1ticos removidos: {$deleted}\" );\n    }\n    \n    \/**\n     * Remove posts na lixeira\n     *\/\n    private function delete_trashed_posts() {\n        global $wpdb;\n        $deleted = $wpdb-&gt;query(\n            \"DELETE FROM {$wpdb-&gt;posts} \n             WHERE post_status = 'trash'\"\n        );\n        $this-&gt;log( \"Posts na lixeira removidos: {$deleted}\" );\n    }\n    \n    \/**\n     * Remove coment\u00e1rios com status 'spam'\n     *\/\n    private function delete_spam_comments() {\n        global $wpdb;\n        $deleted = $wpdb-&gt;query(\n            \"DELETE FROM {$wpdb-&gt;comments} \n             WHERE comment_approved = 'spam'\"\n        );\n        $this-&gt;log( \"Coment\u00e1rios spam removidos: {$deleted}\" );\n    }\n    \n    \/**\n     * Remove coment\u00e1rios pendentes (modera\u00e7\u00e3o)\n     *\/\n    private function delete_pending_comments() {\n        global $wpdb;\n        $deleted = $wpdb-&gt;query(\n            \"DELETE FROM {$wpdb-&gt;comments} \n             WHERE comment_approved = '0'\"\n        );\n        $this-&gt;log( \"Coment\u00e1rios pendentes removidos: {$deleted}\" );\n    }\n    \n    \/**\n     * Remove coment\u00e1rios na lixeira\n     *\/\n    private function delete_trashed_comments() {\n        global $wpdb;\n        $deleted = $wpdb-&gt;query(\n            \"DELETE FROM {$wpdb-&gt;comments} \n             WHERE comment_approved = 'trash'\"\n        );\n        $this-&gt;log( \"Coment\u00e1rios na lixeira removidos: {$deleted}\" );\n    }\n    \n    \/**\n     * Remove pingbacks e trackbacks\n     *\/\n    private function delete_pingbacks_trackbacks() {\n        global $wpdb;\n        $deleted = $wpdb-&gt;query(\n            \"DELETE FROM {$wpdb-&gt;comments} \n             WHERE comment_type IN ('pingback', 'trackback')\"\n        );\n        $this-&gt;log( \"Pingbacks\/trackbacks removidos: {$deleted}\" );\n    }\n    \n    \/**\n     * Remove transients expirados (dados tempor\u00e1rios)\n     *\/\n    private function delete_expired_transients() {\n        global $wpdb;\n        $timestamp = time();\n        \/\/ Remove transients expirados em lote para evitar timeout\n        $batch = 50;\n        $total_deleted = 0;\n        \n        while ( true ) {\n            \/\/ Busca chaves de timeout expiradas\n            $timeout_keys = $wpdb-&gt;get_col( $wpdb-&gt;prepare(\n                \"SELECT option_name FROM {$wpdb-&gt;options} \n                 WHERE option_name LIKE '_transient_timeout_%' \n                 AND CAST(option_value AS UNSIGNED) &lt; %d LIMIT %d\", $timestamp, $batch ) ); if ( empty( $timeout_keys ) ) { break; } \/\/ Prepara as chaves dos transients correspondentes $transient_keys = []; foreach ( $timeout_keys as $key ) { $transient_keys[] = '_transient_' . substr( $key, 19 ); } \/\/ Junta todas as chaves para remo\u00e7\u00e3o $all_keys = array_merge( $timeout_keys, $transient_keys ); $placeholders = implode( ', ', array_fill( 0, count( $all_keys ), '%s' ) ); $deleted = $wpdb-&gt;query( $wpdb-&gt;prepare(\n                \"DELETE FROM {$wpdb-&gt;options} WHERE option_name IN ({$placeholders})\",\n                $all_keys\n            ) );\n            \n            $total_deleted += $deleted;\n            \n            if ( count( $timeout_keys ) &lt; $batch ) { break; } } $this-&gt;log( \"Transients expirados removidos: {$total_deleted}\" );\n    }\n    \n    \/**\n     * Remove postmeta \u00f3rf\u00e3o (sem post correspondente)\n     *\/\n    private function delete_orphaned_post_meta() {\n        global $wpdb;\n        $deleted = $wpdb-&gt;query(\n            \"DELETE pm FROM {$wpdb-&gt;postmeta} pm\n             LEFT JOIN {$wpdb-&gt;posts} p ON p.ID = pm.post_id\n             WHERE p.ID IS NULL\"\n        );\n        $this-&gt;log( \"Postmeta \u00f3rf\u00e3o removido: {$deleted}\" );\n    }\n    \n    \/**\n     * Remove commentmeta \u00f3rf\u00e3o (sem comment correspondente)\n     *\/\n    private function delete_orphaned_comment_meta() {\n        global $wpdb;\n        $deleted = $wpdb-&gt;query(\n            \"DELETE cm FROM {$wpdb-&gt;commentmeta} cm\n             LEFT JOIN {$wpdb-&gt;comments} c ON c.comment_ID = cm.comment_id\n             WHERE c.comment_ID IS NULL\"\n        );\n        $this-&gt;log( \"Commentmeta \u00f3rf\u00e3o removido: {$deleted}\" );\n    }\n    \n    \/**\n     * Remove usermeta \u00f3rf\u00e3o (sem user correspondente)\n     *\/\n    private function delete_orphaned_user_meta() {\n        global $wpdb;\n        $deleted = $wpdb-&gt;query(\n            \"DELETE um FROM {$wpdb-&gt;usermeta} um\n             LEFT JOIN {$wpdb-&gt;users} u ON u.ID = um.user_id\n             WHERE u.ID IS NULL\"\n        );\n        $this-&gt;log( \"Usermeta \u00f3rf\u00e3o removido: {$deleted}\" );\n    }\n    \n    \/**\n     * Remove termmeta \u00f3rf\u00e3o (sem term correspondente)\n     *\/\n    private function delete_orphaned_term_meta() {\n        global $wpdb;\n        $deleted = $wpdb-&gt;query(\n            \"DELETE tm FROM {$wpdb-&gt;termmeta} tm\n             LEFT JOIN {$wpdb-&gt;terms} t ON t.term_id = tm.term_id\n             WHERE t.term_id IS NULL\"\n        );\n        $this-&gt;log( \"Termmeta \u00f3rf\u00e3o removido: {$deleted}\" );\n    }\n    \n    \/**\n     * Remove relacionamentos term_relationships \u00f3rf\u00e3os (sem post ou term correspondente)\n     *\/\n    private function delete_orphaned_term_relationships() {\n        global $wpdb;\n        \/\/ Remove relacionamentos sem post\n        $deleted1 = $wpdb-&gt;query(\n            \"DELETE tr FROM {$wpdb-&gt;term_relationships} tr\n             LEFT JOIN {$wpdb-&gt;posts} p ON p.ID = tr.object_id\n             WHERE p.ID IS NULL\"\n        );\n        \/\/ Remove relacionamentos sem term_taxonomy\n        $deleted2 = $wpdb-&gt;query(\n            \"DELETE tr FROM {$wpdb-&gt;term_relationships} tr\n             LEFT JOIN {$wpdb-&gt;term_taxonomy} tt ON tt.term_taxonomy_id = tr.term_taxonomy_id\n             WHERE tt.term_taxonomy_id IS NULL\"\n        );\n        $total = $deleted1 + $deleted2;\n        $this-&gt;log( \"Relacionamentos term_relationships \u00f3rf\u00e3os removidos: {$total}\" );\n    }\n    \n    \/**\n     * Remove op\u00e7\u00f5es \u00f3rf\u00e3s (res\u00edduos de plugins desinstalados)\n     * Lista negra b\u00e1sica de prefixos comuns de plugins.\n     *\/\n    private function delete_orphaned_options() {\n        global $wpdb;\n        \n        \/\/ Lista de prefixos de op\u00e7\u00f5es que geralmente s\u00e3o res\u00edduos\n        $prefixes = [\n            'widget_', 'cron', 'recently_activated', 'wpseo_', '_transient_',\n            '_site_transient_', 'rewrite_rules', 'auto_update_', 'wp_user_roles'\n        ];\n        \n        \/\/ Constr\u00f3i a cl\u00e1usula NOT LIKE para cada prefixo (mant\u00e9m os essenciais)\n        $not_like = \"\";\n        foreach ( $prefixes as $prefix ) {\n            $not_like .= $wpdb-&gt;prepare( \" AND option_name NOT LIKE %s\", $prefix . '%' );\n        }\n        \n        \/\/ Busca op\u00e7\u00f5es que n\u00e3o correspondem a plugins ativos ou temas (simplificado)\n        $sql = \"SELECT option_name FROM {$wpdb-&gt;options} \n                WHERE (option_name LIKE 'wp_%' OR option_name LIKE 'woocommerce_%' \n                       OR option_name LIKE 'elementor_%' OR option_name LIKE 'jetpack_%')\n                AND autoload = 'no' {$not_like}\n                LIMIT 200\";\n        \n        $options_to_delete = $wpdb-&gt;get_col( $sql );\n        \n        if ( ! empty( $options_to_delete ) ) {\n            $placeholders = implode( ', ', array_fill( 0, count( $options_to_delete ), '%s' ) );\n            $deleted = $wpdb-&gt;query( $wpdb-&gt;prepare(\n                \"DELETE FROM {$wpdb-&gt;options} WHERE option_name IN ({$placeholders})\",\n                $options_to_delete\n            ) );\n            $this-&gt;log( \"Op\u00e7\u00f5es \u00f3rf\u00e3s removidas: {$deleted}\" );\n        } else {\n            $this-&gt;log( \"Nenhuma op\u00e7\u00e3o \u00f3rf\u00e3 encontrada para remo\u00e7\u00e3o.\" );\n        }\n    }\n    \n    \/**\n     * Remove cache oEmbed (transients espec\u00edficos)\n     *\/\n    private function delete_oembed_cache() {\n        global $wpdb;\n        $deleted = $wpdb-&gt;query(\n            \"DELETE FROM {$wpdb-&gt;postmeta} \n             WHERE meta_key LIKE '_oembed_%'\"\n        );\n        $this-&gt;log( \"Cache oEmbed removido: {$deleted} registros\" );\n    }\n    \n    \/**\n     * Otimiza todas as tabelas do banco de dados (opcional)\n     * Pode ser pesado em sites grandes; desabilite se necess\u00e1rio.\n     *\/\n    private function optimize_tables() {\n        global $wpdb;\n        $tables = $wpdb-&gt;get_col( \"SHOW TABLES\" );\n        $optimized = 0;\n        foreach ( $tables as $table ) {\n            if ( $wpdb-&gt;query( \"OPTIMIZE TABLE {$table}\" ) ) {\n                $optimized++;\n            }\n        }\n        $this-&gt;log( \"Tabelas otimizadas: {$optimized} de \" . count( $tables ) );\n    }\n    \n    \/**\n     * Fun\u00e7\u00e3o de log simples (escreve em arquivo se habilitado)\n     *\/\n    private function log( $message ) {\n        if ( ! $this-&gt;log_enabled ) {\n            return;\n        }\n        $log_file = WP_CONTENT_DIR . '\/db-cleaner-log.txt';\n        $timestamp = current_time( 'mysql' );\n        $entry = \"[{$timestamp}] {$message}\" . PHP_EOL;\n        error_log( $entry, 3, $log_file );\n    }\n}\n\nNeodoor_DB_Cleaner::get_instance();\n<\/code><\/pre>\n<h3>Instru\u00e7\u00f5es de instala\u00e7\u00e3o<\/h3>\n<ol>\n<li>Certifique-se de que o autoloader <code>loader.php<\/code> esteja presente em <code>\/mu-plugins\/<\/code> (conforme aula anterior).<\/li>\n<li>Crie a pasta <code>neodoor-db-cleaner<\/code> dentro de <code>\/mu-plugins\/<\/code>.<\/li>\n<li>Dentro dela, crie o arquivo <code>neodoor-db-cleaner.php<\/code> e cole o c\u00f3digo acima.<\/li>\n<li>Desative e remova o plugin <code>advanced-database-cleaner<\/code> da lista de plugins.<\/li>\n<li>O MU-Plugin come\u00e7ar\u00e1 a funcionar imediatamente e agendar\u00e1 a limpeza di\u00e1ria automaticamente.<\/li>\n<\/ol>\n<h3>Configura\u00e7\u00e3o avan\u00e7ada (via constantes no wp-config.php)<\/h3>\n<p>Voc\u00ea pode ajustar o comportamento do plugin definindo as seguintes constantes no arquivo <code>wp-config.php<\/code>:<\/p>\n<pre><code>\/\/ Mant\u00e9m revis\u00f5es dos \u00faltimos 60 dias (padr\u00e3o: 30)\ndefine( 'NEODOOR_DB_CLEANER_KEEP_REVISIONS_DAYS', 60 );\n\n\/\/ Habilita logs de depura\u00e7\u00e3o (arquivo \/wp-content\/db-cleaner-log.txt)\ndefine( 'NEODOOR_DB_CLEANER_LOG_ENABLED', true );\n<\/code><\/pre>\n<h3>Teste manual da limpeza<\/h3>\n<p>Para executar a limpeza imediatamente (sem aguardar o cron di\u00e1rio), adicione o seguinte trecho temporariamente no tema ou em um plugin de teste:<\/p>\n<pre><code>do_action( 'neodoor_db_daily_cleanup' );\n<\/code><\/pre>\n<p>Ap\u00f3s executar, remova o trecho para n\u00e3o rodar duas vezes.<\/p>\n<h3>Verifica\u00e7\u00e3o e monitoramento<\/h3>\n<ul>\n<li><strong>phpMyAdmin:<\/strong> Acesse seu banco de dados e verifique a redu\u00e7\u00e3o no tamanho das tabelas <code>wp_posts<\/code>, <code>wp_postmeta<\/code> e <code>wp_options<\/code>.<\/li>\n<li><strong>Logs:<\/strong> Se habilitado, consulte o arquivo <code>\/wp-content\/db-cleaner-log.txt<\/code> para ver o que foi removido.<\/li>\n<li><strong>Performance:<\/strong> Monitore o tempo de carregamento do site antes e depois da limpeza.<\/li>\n<\/ul>\n<h3>Limita\u00e7\u00f5es e cuidados<\/h3>\n<ul>\n<li><strong>Sempre fa\u00e7a backup do banco de dados antes de executar limpezas agressivas.<\/strong> Em ambiente local isso \u00e9 menos cr\u00edtico, mas \u00e9 uma boa pr\u00e1tica.<\/li>\n<li>A remo\u00e7\u00e3o de op\u00e7\u00f5es \u00f3rf\u00e3s \u00e9 conservadora (mant\u00e9m op\u00e7\u00f5es com prefixos conhecidos como <code>widget_<\/code>, <code>cron<\/code>, etc.) para n\u00e3o quebrar funcionalidades. Se precisar de limpeza mais profunda, revise a lista de exclus\u00e3o.<\/li>\n<li>Em sites muito grandes (milhares de posts), a limpeza de transients e metadados pode levar alguns segundos. O c\u00f3digo usa batch para evitar timeout.<\/li>\n<li>Se voc\u00ea usa cache externo (Redis, Memcached), os transients podem n\u00e3o estar na base de dados \u2013 nesse caso, a remo\u00e7\u00e3o via SQL n\u00e3o ter\u00e1 efeito.<\/li>\n<li>Para uma limpeza ainda mais completa (tabelas \u00f3rf\u00e3s, detec\u00e7\u00e3o de plugins inativos), recomenda-se executar manualmente scripts SQL espec\u00edficos ou usar o WP-CLI.<\/li>\n<\/ul>\n<h3>Compara\u00e7\u00e3o com o plugin original<\/h3>\n<p>Nosso MU-Plugin substitui as principais fun\u00e7\u00f5es do Advanced Database Cleaner, com as seguintes diferen\u00e7as:<\/p>\n<ul>\n<li><strong>Sem interface administrativa:<\/strong> Tudo ocorre em segundo plano, sem bot\u00f5es ou telas para configurar.<\/li>\n<li><strong>Mais leve:<\/strong> Carrega apenas o necess\u00e1rio, sem CSS\/JS desnecess\u00e1rios.<\/li>\n<li><strong>Transparente:<\/strong> O c\u00f3digo est\u00e1 vis\u00edvel e pode ser ajustado conforme sua necessidade.<\/li>\n<li><strong>Agendamento fixo:<\/strong> Executa diariamente. Para outras frequ\u00eancias, altere a constante em <code>wp_schedule_event<\/code>.<\/li>\n<\/ul>\n<h3>Registro no caderno<\/h3>\n<p>Data: <!--?php echo date('d\/m\/Y'); ?--><\/p>\n<p>Funcionalidade: Limpeza autom\u00e1tica do banco de dados (revis\u00f5es, transients, metadados \u00f3rf\u00e3os, etc.)<\/p>\n<p>Plugins substitu\u00eddos: advanced-database-cleaner<\/p>\n<p>Tempo de implementa\u00e7\u00e3o: ~30 minutos (configura\u00e7\u00e3o e testes)<\/p>\n<p>Observa\u00e7\u00e3o: Em produ\u00e7\u00e3o, execute a limpeza manualmente antes de ativar o cron para evitar picos de carga.<\/p>\n<p>&nbsp;<\/p>\n<hr \/>\n<h2><span class=\"\">Explica\u00e7\u00e3o t\u00e9cnica sobre o &#8216;prefixo&#8217;<\/span><\/h2>\n<p class=\"ds-markdown-paragraph\"><span class=\"\">O prefixo\u00a0<\/span><strong><code>NEODOOR<\/code><\/strong><span class=\"\"><strong>\u00a0<\/strong>(ou\u00a0<\/span><code>Neodoor_<\/code><span class=\"\">) \u00e9 apenas um\u00a0<\/span><strong><span class=\"\">identificador \u00fanico<\/span><\/strong><span class=\"\">\u00a0que usamos para:<\/span><\/p>\n<ul>\n<li>\n<p class=\"ds-markdown-paragraph\"><strong><span class=\"\">Nomear classes<\/span><\/strong><span class=\"\">\u00a0(ex:\u00a0<\/span><code>Neodoor_Disable_RightClick<\/code><span class=\"\">) \u2013 para evitar conflito com outras classes que por acaso tenham o mesmo nome.<\/span><\/p>\n<\/li>\n<li>\n<p class=\"ds-markdown-paragraph\"><strong><span class=\"\">Nomear constantes<\/span><\/strong><span class=\"\">\u00a0(ex:\u00a0<\/span><code>NEODOOR_DB_CLEANER_KEEP_REVISIONS_DAYS<\/code><span class=\"\">) \u2013 para evitar conflitos globais.<\/span><\/p>\n<\/li>\n<li>\n<p class=\"ds-markdown-paragraph\"><strong><span class=\"\">Nomear hooks\/custom actions<\/span><\/strong><span class=\"\">\u00a0(ex:\u00a0<\/span><code>neodoor_db_daily_cleanup<\/code><span class=\"\">) \u2013 para garantir que nenhum outro plugin use o mesmo nome de hook.<\/span><\/p>\n<\/li>\n<\/ul>\n<p class=\"ds-markdown-paragraph\"><span class=\"\">O WordPress n\u00e3o exige nenhum prefixo espec\u00edfico. A \u00fanica regra \u00e9:\u00a0<\/span><strong><span class=\"\">use um prefixo \u00fanico e consistente<\/span><\/strong><span class=\"\">\u00a0para tudo que voc\u00ea criar (classes, fun\u00e7\u00f5es, constantes, hooks). Isso \u00e9 uma\u00a0<\/span><strong><span class=\"\">boa pr\u00e1tica de programa\u00e7\u00e3o<\/span><\/strong><span class=\"\">\u00a0para evitar colis\u00f5es com temas\/plugins de terceiros.<\/span><\/p>\n<h2><span class=\"\">O que acontece se voc\u00ea trocar\u00a0<\/span><code>NEODOOR<\/code><span class=\"\">\u00a0por\u00a0<\/span><code>PORTANOVA<\/code><span class=\"\">?<\/span><\/h2>\n<ul>\n<li>\n<p class=\"ds-markdown-paragraph\"><strong><span class=\"\">O plugin continua funcionando normalmente<\/span><\/strong><span class=\"\">\u00a0\u2013 pois todas as refer\u00eancias internas estar\u00e3o consistentes.<\/span><\/p>\n<\/li>\n<li>\n<p class=\"ds-markdown-paragraph\"><strong><span class=\"\">Nada quebra<\/span><\/strong><span class=\"\">\u00a0\u2013 desde que voc\u00ea substitua\u00a0<\/span><strong><span class=\"\">todas as ocorr\u00eancias<\/span><\/strong><span class=\"\">\u00a0do antigo prefixo pelo novo no c\u00f3digo.<\/span><\/p>\n<\/li>\n<\/ul>\n<h2><span class=\"\">Cuidados ao trocar<\/span><\/h2>\n<ol start=\"1\">\n<li>\n<p class=\"ds-markdown-paragraph\"><strong><span class=\"\">Use &#8220;pesquisar e substituir&#8221; no seu editor de c\u00f3digo<\/span><\/strong><span class=\"\">\u00a0(VS Code, Notepad++, etc.) para garantir que nenhuma ocorr\u00eancia seja esquecida.<\/span><\/p>\n<\/li>\n<li>\n<p class=\"ds-markdown-paragraph\"><strong><span class=\"\">Aten\u00e7\u00e3o a letras mai\u00fasculas\/min\u00fasculas<\/span><\/strong><span class=\"\">\u00a0\u2013\u00a0<\/span><code>Neodoor<\/code><span class=\"\">\u00a0\u00e9 diferente de\u00a0<\/span><code>NEODOOR<\/code><span class=\"\">. No c\u00f3digo temos:<\/span><\/p>\n<ul>\n<li>\n<p class=\"ds-markdown-paragraph\"><code>Neodoor_<\/code><span class=\"\">\u00a0(classe)<\/span><\/p>\n<\/li>\n<li>\n<p class=\"ds-markdown-paragraph\"><code>neodoor_<\/code><span class=\"\">\u00a0(hooks, fun\u00e7\u00f5es)<\/span><\/p>\n<\/li>\n<li>\n<p class=\"ds-markdown-paragraph\"><code>NEODOOR_<\/code><span class=\"\">\u00a0(constantes)<\/span><\/p>\n<\/li>\n<li>\n<p class=\"ds-markdown-paragraph\"><span class=\"\">Ao trocar, mantenha a mesma capitaliza\u00e7\u00e3o:\u00a0<\/span><code>Portanova_<\/code><span class=\"\">,\u00a0<\/span><code>portanova_<\/code><span class=\"\">,\u00a0<\/span><code>PORTANOVA_<\/code><span class=\"\">.<\/span><\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p class=\"ds-markdown-paragraph\"><strong><span class=\"\">Recomendo manter um padr\u00e3o<\/span><\/strong><span class=\"\">\u00a0\u2013 por exemplo, sempre usar o nome do seu projeto (ex:\u00a0<\/span><code>portanova<\/code><span class=\"\">) em min\u00fasculas para hooks e fun\u00e7\u00f5es, e mai\u00fasculas para constantes.<\/span><\/p>\n<\/li>\n<\/ol>\n<h2><span class=\"\">Vantagem de usar um prefixo personalizado<\/span><\/h2>\n<ul>\n<li>\n<p class=\"ds-markdown-paragraph\"><strong><span class=\"\">Identifica facilmente<\/span><\/strong><span class=\"\">\u00a0que aquele c\u00f3digo foi criado por voc\u00ea.<\/span><\/p>\n<\/li>\n<li>\n<p class=\"ds-markdown-paragraph\"><strong><span class=\"\">Evita conflitos<\/span><\/strong><span class=\"\">\u00a0caso instale um plugin que use o mesmo nome de classe (ex: outra pessoa tamb\u00e9m criou uma classe chamada\u00a0<\/span><code>Disable_RightClick<\/code><span class=\"\">).<\/span><\/p>\n<\/li>\n<li>\n<p class=\"ds-markdown-paragraph\"><strong><span class=\"\">Mais f\u00e1cil de dar manuten\u00e7\u00e3o<\/span><\/strong><span class=\"\">\u00a0em projetos grandes.<\/span><\/p>\n<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Aula: Limpeza de Banco de Dados com MU-Plugin \u2013 Substituindo o Advanced Database Cleaner Objetivo: Substituir um plugin robusto como o Advanced Database Cleaner por um MU-Plugin enxuto, que mant\u00e9m o banco de dados limpo removendo revis\u00f5es antigas, transients expirados, rascunhos autom\u00e1ticos, lixeira, coment\u00e1rios spam e outros res\u00edduos deixados por temas e plugins desinstalados. Contexto: [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2,4],"tags":[],"class_list":["post-250","post","type-post","status-publish","format-standard","hentry","category-lessons","category-pluginsmu"],"_links":{"self":[{"href":"https:\/\/www.portanova.com.br\/notebook\/wp-json\/wp\/v2\/posts\/250","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.portanova.com.br\/notebook\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.portanova.com.br\/notebook\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.portanova.com.br\/notebook\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.portanova.com.br\/notebook\/wp-json\/wp\/v2\/comments?post=250"}],"version-history":[{"count":0,"href":"https:\/\/www.portanova.com.br\/notebook\/wp-json\/wp\/v2\/posts\/250\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.portanova.com.br\/notebook\/wp-json\/wp\/v2\/media?parent=250"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.portanova.com.br\/notebook\/wp-json\/wp\/v2\/categories?post=250"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.portanova.com.br\/notebook\/wp-json\/wp\/v2\/tags?post=250"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}