É possível forçar a atualização do gancho de seu módulo?

18

Eu sou o autor do módulo Date iCal e a nova versão principal em que estou trabalhando (3.x) exige uma atualização de esquema em duas partes para usuários com o 2.x instalado. Eu escrevi o gancho de atualização que faz essas alterações, mas se um dos meus usuários não conseguir executar o script de atualização do banco de dados, eles receberão uma mensagem de erro relacionada aos importadores de feeds do iCal.

A solução certa é que eles executem o script de atualização ... mas se eles entrarem e mudarem manualmente seus importadores para se livrar da mensagem, seus importadores permanecerão permanentemente quebrados (porque a segunda parte da atualização do esquema não será foram executados).

Existe alguma maneira de exibir uma mensagem para usuários que não executaram a atualização? Ou, de alguma maneira, executar forçosamente o gancho de atualização na primeira vez que um carregamento de página ocorre quando o 3.x é instalado sobre o 2.x?

coredumperror
fonte
2
Eu imagino que você poderia fazer um variable_set()na sua função de atualização que define uma variável, quando foi executada com êxito, que você poderia ver dentro de um, _preprocess_page()mas você o observaria toda vez, para não ter certeza de quão amigável seria o desempenho.
Jimajamma

Respostas:

4

estendendo sobre o comentário de Jimajamma:

faça um variable_set()na sua função de atualização que define uma variável quando ela foi executada com sucesso e que você pode ver dentro de uma _preprocess_page ()

e, em vez de verificar isso em cada carregamento da página, faça-o apenas se estiver navegando na área de administração e se a versão instalada for 3.0 (3.1, 3.2, interrompa essa verificação se você parar de oferecer suporte à versão antiga como um caminho de atualização).

Além disso, use hook_requirements para fornecer feedback sobre a página do relatório de status:

Verifique os requisitos de instalação e faça o relatório de status.
(...)
A fase 'runtime' não se limita aos requisitos puros de instalação, mas também pode ser usada para obter informações de status mais gerais, como tarefas de manutenção e problemas de segurança.

Andre Baumeier
fonte
15

Existem algumas maneiras de forçar a atualização do módulo.

  1. Chamando a função de atualização diretamente.

    $sandbox = [];
    module_load_include('install', 'FOO');
    FOO_update_7001($sandbox);
  2. Redefinindo a versão do esquema para o ponto de interesse e execute as atualizações novamente como de costume.

    drupal_set_installed_schema_version('module_name', '7000');

    Ou redefina para executar novamente apenas o esquema de atualização mais recente:

    drupal_set_installed_schema_version('foo', drupal_get_installed_schema_version('foo') - 1);

    Notas:

    • Isso pode ser colocado hook_install, portanto, durante o processo de atualização, todos os ganchos de atualização sequenciais serão executados.
    • Para usar esta função fora do arquivo de instalação, você deve incluir o Drupal install.incprimeiro e o arquivo de instalação do módulo, por exemplo

      require_once DRUPAL_ROOT . '/includes/install.inc';
      module_load_include('install', 'foo');
    • Considere adicionar ini_set('max_execution_time', 0);atualizações de instalação mais longas para evitar o tempo limite do PHP.
  3. Usando drush. Veja abaixo alguns exemplos:

    • drush eval 'module_load_include('install', 'foo'); $s = []; foo_update_7001($s);'
    • drush sqlq "UPDATE system SET schema_version = 7000 WHERE name = 'foo'" && drush -y updb
kenorb
fonte
1
Oh legal, eu não sabia drupal_set_installed_schema_version(). Isso seria super útil para depurar ganchos de atualização!
Coredumperror
1
Portanto, o principal problema de colocá-lo hook_install()é a execução de longas atualizações em lotes (em área restrita). Na situação ideal, deve haver uma maneira de disparar atualizações da mesma maneira update.phpque reinicia o encadeamento do PHP para evitar tempos limite. Idéias de formiga como fazer isso?
Alex Skrypnyk
@ Alex.Designworks Você pode adicionar ini_set('max_execution_time', 0);antes de acionar as atualizações.
Kenorb #
1

(Reescrito em uma resposta)

Você pode "SELECT schema_version FROM system" para detectar se uma atualização foi executada. Caso contrário, recuse-o a executar (com uma mensagem de erro).

user18099
fonte
Por favor, reformule sua resposta e tente dar um exemplo de uso.
Елин Й.
Ignore este comentário.
Coredumperror
Receio que isso não funcione, porque a funcionalidade em questão é um plug-in para outro módulo e não posso impedir que esse módulo permita que os usuários mexam com seus importadores.
Coredumperror 21/11
Você não pode verificar a versão do esquema do módulo que pretende monitorar atualizações?
user18099
0

Concordo com as sugestões acima - minha única adição seria investigar "Acionadores e ações" também - parece que você precisa de uma ação (notificar o usuário ou executar uma atualização) para ocorrer quando um acionador (o usuário verifica a página de administração, etc.) é acionado . Para exemplos de uso, consulte o módulo Exemplos, existem códigos de exemplo de ação e acionador. :)

mechhfly
fonte
0

function MYMODULE_install() { $functions = get_defined_functions(); foreach ($functions['user'] as $function) { if (strpos($function, 'MYMODULE_update_') === 0) { call_user_func($function); } } }

Alex Skrypnyk
fonte