モジュールの更新フックを強制的に実行することは可能ですか?


18

私はDate iCalモジュールの作成者であり、現在作業中の新しいメジャーバージョン(3.x)では、2.xがインストールされているユーザーに対して2つの部分からなるスキーマの更新が必要です。これらの変更を行う更新フックを作成しましたが、ユーザーの1人がデータベース更新スクリプトの実行に失敗すると、iCalフィードインポーターに関するエラーメッセージが表示されます。

適切な解決策は、更新スクリプトを実行することです...しかし、メッセージを削除するためにインポーターを手動で変更するだけでは、インポーターは完全に壊れたままになります(スキーマ更新の2番目の部分は実行された)。

更新を実行していないユーザーにメッセージを表示する方法はありますか?または、3.xが2.xの上にインストールされたときに初めてページの読み込みが行われたときに、どういうわけか強制的に更新フックを実行しますか?


2
私はあなたが行うことができます想像variable_set()が正常にあなたの中で見ることができることを実行したとき、変数を設定し、あなたの更新機能で_preprocess_page()はなく、あなたはそうではないことを確認友好これは次のようになりますどのようにパフォーマンスにそれを毎回見ていると思います。
ジマジャマ

回答:


4

Jimajammaからのコメントの拡張:

やるvariable_set())(それがうまくあなたが_preprocess_page内で見ることができることを実行したとき、変数を設定し、あなたの更新機能に

すべてのページの読み込みでこれをチェックする代わりに、管理領域を閲覧し、インストールされたバージョンが3.0(3.1、3.2、アップグレードパスとして古いバージョンのサポートを停止した場合、そのチェックを強制終了する)の場合にのみ実行してください。

さらに、hook_requirementsを使用して、ステータスレポートページに関するフィードバックを提供します。

インストール要件を確認し、ステータスレポートを作成します。
(...)
「ランタイム」フェーズは、純粋なインストール要件に限定されず、メンテナンスタスクやセキュリティの問題など、より一般的なステータス情報にも使用できます。


15

モジュールの更新を強制する方法はいくつかあります。

  1. 更新機能を直接呼び出します。

    $sandbox = [];
    module_load_include('install', 'FOO');
    FOO_update_7001($sandbox);
  2. スキーマバージョンを目的のポイントにリセットし、通常どおり更新を再度実行します。

    drupal_set_installed_schema_version('module_name', '7000');

    または、リセットして最新の更新スキーマのみを再実行します。

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

    ノート:

    • これはに配置できるhook_installため、更新プロセス中にすべての連続した更新フックが実行されます。
    • インストールファイルの外部でこの機能を使用するには、install.inc最初にDrupal とモジュールのインストールファイルを含める必要があります。例えば

      require_once DRUPAL_ROOT . '/includes/install.inc';
      module_load_include('install', 'foo');
    • ini_set('max_execution_time', 0);PHPのタイムアウトを防ぐために、より長いインストールアップデートを追加することを検討してください。
  3. を使用しdrushます。以下の例をご覧ください。

    • 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

1
いいね、私は知らなかったdrupal_set_installed_schema_version()。これは、更新フックをデバッグするのに非常に便利です!
coredumperror

1
したがって、それを配置する際の主な問題は、hook_install()長時間のバッチ(サンドボックス)更新の実行です。理想的な状況では、update.phpタイムアウトを防ぐためにPHPスレッドを再起動するのと同じ方法で更新をトリガーする方法が必要です。Antはその方法を考えていますか?
アレックスSkrypnyk

@ Alex.Designworks ini_set('max_execution_time', 0);更新をトリガーする前に追加できます。
ケノーブ

1

(答えに言い換える)

「schema_version FROM system」を選択して、更新が実行されたかどうかを検出できます。そうでない場合は、実行を拒否します(エラーメッセージが表示されます)。


答えを言い換えて、使用例を示してみてください。
ЕлинЙ.

このコメントは無視してください。
coredumperror

問題の機能は別のモジュールのプラグインであり、そのモジュールがユーザーがインポーターを台無しにするのを防ぐことはできないので、私はそれが機能しないことを恐れています。
coredumperror

更新を監視するモジュールのスキーマバージョンを確認できませんか?
user18099

0

私は上記の提案に同意します-私の唯一の追加は「トリガーとアクション」を調査することです-トリガー(ユーザーが管理ページなどをチェックする)がプルされたときに発生するアクション(ユーザーに通知または更新を実行)が必要なようです。使用例については、サンプルモジュールを参照してください。アクションとトリガーの両方のサンプルコードがあります。:)


0

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.