web-dev-qa-db-ja.com

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

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

正しい解決策は、更新スクリプトを実行することです...しかし、彼らが入り、手動でインポーターを変更してメッセージを取り除く場合、インポーターは永続的に壊れたままになります(スキーマ更新の2番目の部分は行われないため)実行されました)。

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

18
coredumperror

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

更新関数でvariable_set()を実行して、正常に実行されたときに_preprocess_page()内で確認できる変数を設定します

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

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

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

4
Andre Baumeier

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

  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_に配置できるため、更新プロセス中にすべての後続の更新フックが実行されます。
    • この関数をインストールファイルの外で使用するには、まずDrupal _install.inc_とモジュールのインストールファイルを含めます。

      _require_once DRUPAL_ROOT . '/includes/install.inc';
      module_load_include('install', 'foo');
      _
    • PHPタイムアウトを防ぐために、より長いインストール更新のためにini_set('max_execution_time', 0);を追加することを検討してください。
  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_
15
kenorb

(回答に書き換え)

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

1
user18099

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

0
mechhfly

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

0
Alex Skrypnyk