Como implementar a atualização do plugin WordPress que modifica o banco de dados?

10

Desenvolvo um plugin WordPress, que possui várias tabelas de banco de dados próprias. O plug-in cria essas tabelas quando ativadas e as remove quando excluídas / desinstaladas.

Eu tenho que implementar um processo de atualização do plugin que atualiza o código do plugin e a estrutura das tabelas. O caso mais simples seria adicionar uma nova coluna a uma das tabelas. O caso mais complexo seria criar uma nova estrutura de tabelas e atualizar o conteúdo de acordo.

Como você recomendaria para resolver esse problema? Existe alguma função interna do WordPress que possa ajudar?

Misha Moroshko
fonte

Respostas:

4

A maneira correta de fazer isso hoje em dia é incluir o esquema como um arquivo na fonte do plug-in e usar a função embutida do WordPress dbDelta () para atualizar o banco de dados conforme necessário usando esse esquema. O código real necessário é muito simples:

$sql = file_get_contents( plugin_dir_path(__FILE__) . "/schema.sql" );
dbDelta( $sql );

Isso criará e atualizará o banco de dados para você, conforme necessário. Quando eu verifiquei pela última vez, ele não excluiu colunas antigas não utilizadas; portanto, você precisará codificá-lo por meio de uma verificação de versão. Este é um belo recurso do WordPress e economiza bastante tempo. Cuidado ao criar o arquivo schema.sql ao copiar o espaçamento em uma exportação de esquema mysql exatamente como o código dbDelta () tem a reputação de ser muito exigente quanto ao espaçamento. Você também deve testar a versão do banco de dados e, se não for a mais recente, chame o acima para atualizar o banco de dados. Você também pode precisar fazer atualizações específicas para cobrir alterações que o dbDelta () não acerta (por exemplo, excluindo uma coluna). É fácil escrever um teste lógico simples para verificar se a versão foi atualizada e fazer essas atualizações manuais via $ wpdb. Por exemplo, você pode soltar uma coluna que agora não está sendo usada.

$installed_ver = get_option(MY_DB_VERSION);
$wpp = $wpdb->prefix . "mypluginname";
if ($installed_ver < 102)
        $wpdb->query("ALTER TABLE ${wpp}_movies DROP nft_date");
if ($installed_ver < 107)
        $wpdb->query("ALTER TABLE ${wpp}_movies CHANGE lastupdated "
        . "lastupdated TIMESTAMP on update CURRENT_TIMESTAMP "
        . "NOT NULL DEFAULT CURRENT_TIMESTAMP");

update_option(MY_DB_VERSION, $db_version);

Isso é simplificado da execução do código, desculpas se eu o tiver quebrado no processo de simplificação para publicação.

Também tenha em mente que, a partir do WordPress 3.9.2, o WordPress nem sempre executa o gancho de ativação ao atualizar o plug-in (especificamente, se uma atualização em massa é feita na página Atualizações do painel).

Brian C
fonte
Hoje em dia, comecei a tirar a versão do banco de dados a partir da hora da modificação do arquivo schema.sql. Isso significa que apenas a atualização do arquivo schema.sql é suficiente para causar uma atualização do banco de dados; não é necessário lembrar de editar a versão do banco de dados. Algo como: $ db_version = filemtime ("schema.sql");
Brian C
11
Então, se o tempo do arquivo mudar de algo externo, como mover servidores, a versão mtime e db mudam?
Walf
O tempo do arquivo está sempre no GMT, e os servidores raramente diferem por alguns segundos; portanto, é quase impossível que ele seja acionado duas vezes por isso. No entanto, mesmo que seja acionado novamente, nenhum dano é causado, pois é executado uma vez e faz uma comparação com o banco de dados ativo, obviamente sem alterar nada. Essa é a coisa bonita do dbDelta () - ele pode ser executado várias vezes sem problemas. Boa pergunta, obrigado.
Brian C
3

Em suma, sim a $wpdbclasse. Veja Codex para mais informações.

Sempre que você interagir com uma tabela personalizada (ou qualquer tabela, na verdade), você deve passar por isso $wpdb- verifique se você está familiarizado com o preparemétodo que pode ajudar a escapar de consultas e evitar injeções.

Você já deve estar familiarizado, pois deve usá-lo para criar a tabela. No gancho de instalação, você deve ter algo como:

$charset_collate = '';
if ( ! empty($wpdb->charset) )
    $charset_collate = "DEFAULT CHARACTER SET $wpdb->charset";
if ( ! empty($wpdb->collate) )
    $charset_collate .= " COLLATE $wpdb->collate";

//Create custom table
$sql_custom_table ="CREATE TABLE {$wpdb->prefix}my_table (
    id bigint(20) unsigned NOT NULL auto_increment,
    column_a varchar(255) default NULL,
    column_b varchar(255) default NULL,
    PRIMARY KEY  (id)
    ) $charset_collate; ";

require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($sql_custom_table);

Na verdade, esse código é executado sempre que o plug-in é ativado (ou seja, não apenas instalado). Portanto, ele será executado quando alguém atualizar o plug-in automaticamente . Nota: Se eles atualizarem substituindo o plug-in manualmente - então não será -, será necessário ativar o código acima admin_initquando seu plug-in for atualizado (armazene o número da versão na tabela de opções, verifique a versão atual) .

Agora você normalmente não deseja que o CREATE TABLEcomando SQL esteja em execução toda vez que você atualizar o plug-in - é aqui que dBDelta()entra.

Antes de executar o comando acima - ele verifica se a tabela existe. Além disso, ele verifica os tipos de coluna. Portanto, se a tabela não existir, ela será criada, se existir, mas alguns tipos de coluna foram alterados, ela será atualizada e, se uma coluna não existir - ela será adicionada.

Infelizmente - se você remover uma coluna das opções acima, ela não será removida automaticamente. Para remover colunas / tabelas, é necessário especificá- DROPlas (verifique se elas existem antes de você).

Stephen Harris
fonte