web-dev-qa-db-ja.com

アクションコールバックは、親が実行を続けるのを妨げることができますか?

私は重力フォームと相互作用するプラグインを開発しています、そして特定の条件下ではフォームが削除されないようにしたいのです。これは、重力フォームでフォームの削除を処理する方法です。

public static function delete_form($form_id){
    global $wpdb;

    if(!GFCommon::current_user_can_any("gravityforms_delete_forms"))
        die(__("You don't have adequate permission to delete forms.", "gravityforms"));

    do_action("gform_before_delete_form", $form_id);

    $form_meta_table = self::get_meta_table_name();
    $form_table = self::get_form_table_name();

    //Deleting form Entries
    self::delete_leads_by_form($form_id);

    //Delete form meta
    $sql = $wpdb->prepare("DELETE FROM $form_meta_table WHERE form_id=%d", $form_id);
    $wpdb->query($sql);

    //Deleting form Views
    self::delete_views($form_id);

    //Delete form
    $sql = $wpdb->prepare("DELETE FROM $form_table WHERE id=%d", $form_id);
    $wpdb->query($sql);

    do_action("gform_after_delete_form", $form_id);
}

gform_before_delete_formにフックしてから、続行せずにdelete_form()がその時点で戻るようにすることは可能ですか?例えば。、

public function preventGravityFormDeletion()
{
    if( $someCondition )
    {
        // do something that forces delete_form() to stop
    }
}
add_action( 'gform_before_delete_form', array( $this, 'preventGravityFormDeletion' ) );

私はwp_die()を呼び出してすべてを止めることができることを知っていますが、それはそれほどエレガントではありません。もっと良い方法はありますか?範囲の制限のためにそれは可能ではないようですが、私は私が知らないWP/PHPの魔法があるかどうかを確認したいと思いました。

6
Ian Dunn

短い答え:いいえ。

長い答え:いいえアクションはそのようには機能しません。

編集:

あなたの質問を精巧にして完全に一般的にするには:

function foo() {
  bar();
  return 1;
}

function bar() {
  // stuff
}

スクリプトの実行をdieまたはexitで完全に停止する以外に、foo()への呼び出しが1を返すのを妨げるものを入れることはできません。

注:例外をスローしても役に立ちません。これは、以前の呼び出し側がこの例外をキャッチしない限り、スクリプトの実行を停止するのと同じ効果があるためです。

この関数がどこかのクラスにある場合は、そのサブクラスを定義してこの関数を自分のサブクラスに置き換えることができます。それからそれを使用して、この関数の動作方法を変更することができます。 PHPには、実行時に関数の振る舞いを変更できるようなアスペクト指向プログラミングのメカニズムがないため、これはできる限りのことです。

4
Otto

創造的な解決策は、gform_before_delete_formの間にデータベース内の実際のform_idを修正することで、それ以降のどのアクションもフォームを修正することはありません。

それから、gform_after_delete_formにフックしてform_idを修正することができます。

gform_before_delete_form

form_id = form_id + 1000000

gform_after_delete_form

form_id = form_id - 1000000 

(フォームが100万未満の場合)

大まかなコード:

public function preventGravityFormDeletion()
{
if( $someCondition )
    {
    global $wpdb;
    $temp_form_id = 1000000+$form_id;
    $sql = $wpdb->prepare("UPDATE $form_meta_table SET form_id = $temp_form_id WHERE form_id=$form_id");
    $wpdb->query($sql);
    $sql = $wpdb->prepare("UPDATE $form_table SET id = $temp_form_id WHERE id=$form_id");
    $wpdb->query($sql);
    }
}
add_action( 'gform_before_delete_form', array( $this, 'preventGravityFormDeletion' ) );
5
Jamie