Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I'm working on a plugin that interacts with Gravity Forms, and under certain conditions I want to prevent a form from being deleted. Here's the method in Gravity Forms that handles deleting a form:

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);
}

Is it possible to hook into gform_before_delete_form and then do something to make delete_form() return at that point without continuing? e.g.,

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

I know that I could call wp_die() and just stop everything, but that's not very elegant. Is there a better way? It doesn't seem possible because of scope limitations, but I wanted to check in case there's some WP/PHP magic that I'm not aware of.

share|improve this question
    
Would this question be better-asked at the Gravity Forms support forum? Or is the GF part just to give context to the question regarding removing/preventing actions from firing? –  Chip Bennett Feb 10 '12 at 14:42
    
Yeah, it was just to give a concrete example, but I think the question could apply to lots of other situations as well. –  Ian Dunn Feb 10 '12 at 15:20
add comment

2 Answers 2

up vote 3 down vote accepted

Short answer: no.

Long answer: also no. Actions don't work that way.

Edit:

To elaborate and make your question totally generic:

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

function bar() {
  // stuff
}

There is nothing you can put in stuff that will prevent a call to foo() from returning 1, other than halting script execution entirely with die or exit.

Note: Throwing exceptions won't help either, because this has the same effect as halting script execution unless some previous caller catches the exeception.

Now, if this function is in a class somewhere, then you can define a subclass of it and replace this function with one of your own, then potentially use that, thus modifying the way this function works. That's about the best you can do, since PHP doesn't have any sort of aspect-oriented-programming mechanisms in it that would allow you to change function behavior at runtime.

share|improve this answer
    
I realize that it's probably not possible, but I already stated that up front in the question, so your answer doesn't really add anything new to the topic. At the very least, you should explain WHY the answer is no, instead of just saying, "it doesn't work that way." What I was really looking for was some kind of obscure or creative, non-obvious solution, and your answer doesn't give me any confidence that you even considered anything like that before firing off a quick reply. –  Ian Dunn Feb 10 '12 at 15:27
2  
Okay. You can't make it return from a do_action because it's not calling it with return do_action and also because actions don't return values to check for. There's no obscure or non-obvious solution, because code doesn't work that way. The most you can make the thing do is exit early with die() or exit(), which you already recognized in your question and so I didn't feel the need to elaborate on. Basically, you want to know how a called function can make the function its called from behave in a way other than it's written. Answer: You can't do that, because PHP has no way to do that. –  Otto Feb 11 '12 at 7:17
    
@IanDunn There's no reason to berate others trying to help. :) :) –  Brian Fegter Feb 11 '12 at 8:59
    
Brian, I just re-read my comment and I really don't think the tone qualifies as "berating," but I'll admit I was definitely frustrated when I wrote it, so I apologize if it came across as harsh. I thought Otto's original answer was dismissive and a little condescending, in addition to not actually offering any kind of solution, and that was frustrating. Any first-year CS major could tell me the obvious answer; I was looking for a more thoughtful and creative answer, but I should have communicated that better in the question. –  Ian Dunn Feb 11 '12 at 17:02
    
Otto, thanks for the revised answer. Overriding the method is a good thought, but I don't think it would work because the parent method would still be called instead of the child. Some other thoughts I've had include modifying the view files to remove the delete links, and asking the GF devs to add a filter that could trigger an early return, but neither of those are very promising. I still think that claiming it absolutely can't be done is short-sighted, though. It's entirely possible that there are hacks, workarounds, or different approaches we just haven't thought of yet. –  Ian Dunn Feb 11 '12 at 17:23
add comment

A creative solution would be to modify the actual form_id in the database during gform_before_delete_form so none of the proceeding actions will modify the form.

Then you can hook into gform_after_delete_form and modify the form_id back.

gform_before_delete_form

form_id = form_id + 1000000

gform_after_delete_form

form_id = form_id - 1000000 

(assuming you have less than a million forms!)

rough code:

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' ) );
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.