Plugin gerou XXX de caracteres inválidos durante ativação

Estou estudando criação de plugins para WordPress e, como parte inicial dos meus estudos é criar um plugin de administração de boletins escolares de estudantes de uma escola fictícia.

Eu preciso criar algumas tabelas no banco assim que o usuário ativar o plugin. De acordo com a documentação do WordPress, uma das formas de realizar isso seria criar as consultas SQL dentro do arquivo main.php no diretório inicial do plugin e depois registrar as funções com register_activation_hook(__FILE__, 'function');.

Porém, ao salvar o arquivo principal do meu plugin e ativá-lo no painel administrativo do WordPress, a seguinte mensagem de aviso é gerada:

O plugin gerou 808 caracteres de saída inesperada durante a ativação. Se você notar mensagens de “cabeçalhos já enviados”, problemas com feeds ou outros problemas, tente desativar ou remover este plugin.

Ao verificar o banco, noto que nem a tabela e muito menos os registros foram inseridos. Não consigo entender quais seriam esses caracteres adicionais uma vez que não teria como debugar meu código para identificar o erro.

Segue abaixo meu código. Agradeço desde já toda ajuda!

<?php  /**  * Plugin Name: Boletim de Notas  * Plugin URL: http://www.edinaldoribeiro.com.br  * Description: Plugin de administração de notas e geração de boletins escolares online.  * Version: 1.0  * Requires at least: 5.2  * Requires PHP: 7.2  * Author: Edinaldo Ribeiro  * Author URI: http://www.edinaldoribeiro.com.br  * License: GPL v2 or later  * License URI: https://www.gnu.org/licenses/gpl-2.0.html  */  defined('ABSPATH') or die('Página indisponível');  global $  db_version; $  db_version = '1.0';  function install_plugin(){      global $  wpdb;     global $  db_version;      $  table = $  wpdb->prefix . "estudantes";     $  charset_collate = $  wpdb->get_charset_collate();      $  sql = "CREATE TABLE $  table (         id INT NOT NULL AUTO_INCREMENT,         time DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',         name tinytext NOT NULL DEFAULT 'unnamed',         age INT NOT NULL DEFAULT 0,         url varchar(55) NOT NULL DEFAULT '',         PRIMARY KEY  (id)     ) $  charset_collate;";      require_once(ABSPATH.'wp-admin/includes/upgrade.php');     dbDelta($  sql);      add_option('db_version', $  db_version); }  function install_plugin_data() {     global $  wpdb;      $  name = "Edinaldo Ribeiro";     $  age = '23';      $  table = $  wpdb->prefix . 'estudantes';      $  wpdb->insert(         $  table,         array(             'time' => current_time('mysql'),             'name' => $  name,             'age' => $  age         )     ); }  register_activation_hook(__FILE__, 'install_plugin'); register_activation_hook(__FILE__, 'install_plugin_data'); 

Limpiar filas con emails inválidos de una hoja de cálculo de Google

Pues llevo bastante peleándome con este asunto, ya que, si no fuera porque la función tiene que hacer muchas cosas más, tardaría menos haciéndolo con filtros a mano…

La cosa es que quiero eliminar de un Google Sheet todas las filas cuya celda de email sean inválidos o de Gmail.

Al principio lo hice con una macro que me dio el siguiente código:

function Limpiarfilasycolumnas() {    //Seleccionar hoja y empezar   var spreadsheet = SpreadsheetApp.getActive();     //No funciona   //Localizar y eliminar todo lo que no sea un email   spreadsheet.getRange('E:E').activate();   spreadsheet.getRange('E:E').createFilter();   spreadsheet.getRange('E1').activate();   var criteria = SpreadsheetApp.newFilterCriteria()   .whenFormulaSatisfied('=NOT(REGEXMATCH(E:E;"^([A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,})$  "))')   .build();   spreadsheet.getActiveSheet().getFilter().setColumnFilterCriteria(5, criteria);   var sheet = spreadsheet.getActiveSheet();   sheet.getRange(2,1,spreadsheet.getActiveSheet().getLastRow()).activate();   spreadsheet.getActiveSheet().deleteRows(spreadsheet.getActiveRange().getRow(), spreadsheet.getActiveRange().getNumRows());   spreadsheet.getActiveSheet().getFilter().remove();    //No funciona   //Localizar y borrar los emails de Gmail   spreadsheet.getRange('E:E').activate();   spreadsheet.getRange('E:E').createFilter();   spreadsheet.getRange('E1').activate();   var criteria = SpreadsheetApp.newFilterCriteria()   .whenTextContains('gmail.com')   .build();   spreadsheet.getActiveSheet().getFilter().setColumnFilterCriteria(5, criteria);   var sheet = spreadsheet.getActiveSheet();   sheet.getRange(2,1,spreadsheet.getActiveSheet().getLastRow()).activate();   spreadsheet.getActiveSheet().deleteRows(spreadsheet.getActiveRange().getRow(), spreadsheet.getActiveRange().getNumRows());   spreadsheet.getActiveSheet().getFilter().remove();   }; 

Pero haciendo pruebas me percaté de que si la hoja era distinta, ya no funcionaba la macro… Así que después de leerme todas las preguntas con título relacionado, me decanté por hacerlo por Javascript como comentaba el usuario Rubén en una de sus respuestas.

Así que, he hecho el código simulando el filtro con Javascript y me ha quedado lo siguiente:

function Pruebas()  {   var ss = SpreadsheetApp.getActive();   limpia_columna_email(ss.getActiveSheet());   SpreadsheetApp.getUi().alert("Hoja actualizada correctamente"); };  function limpia_columna_email(ss) {   var emails = ss.getRange("E:E").getValues();   for(var i = emails.length-1; i > 0 ; i--)   {     if(!validar_mail(emails[i][0])) ss.deleteRow(i+1);   } };  function validar_mail(email) {   var patron = new RegExp("^([A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,})$  ");   if(email == null || email == "") return false;   if(email.search("gmail.com") != -1) return false;   return patron.test(email);   return false; //Aquí no debe de llegar nunca }; 

Ahora bien, la hoja que le paso tiene más de 5000 filas… y ejecutar el código ha tardado una barbaridad (vamos, si me descuido me veo el capítulo de Stranger Things entero…).

Más que optimizar, que también sería bienvenido ¿se os ocurre como hacerlo de otra manera para que no tarde tanto?

Gracias de antemano.