Preserving $_GET parameter while using custom Rewrite Rule

This third party add-on plugin for Gravity Forms allows you to edit existing posts via the front end when you embed a form in your chosen template.

All you need to do is append the GET variable/parameter ?gform_post_id=1 to the end of your URL which contains the current form and it will pre-populate your form with existing post data (from post meta fields, etc) and then update the post when you re-submit it.

Read More

This works only when using a get style parameter attached to your URL in the form of ?gform_post_id=1… where 1 is the post ID in this example.

I don’t want ugly URLs, I want pretty URLs, so I’m using the following re-write rules to tidy up my permalinks;

function gform_rewrite(){

    global $wp_rewrite;

    add_rewrite_tag('%gform_post_id%','([^&]+)');

    add_rewrite_rule(
        '^user/account/edit/([^/]*)/?',
        'index.php?page_id=183&gform_post_id=$matches[1]','top'
     );
}

Which takes this,

/index.php?page_id=100&gform_post_id=1

…and allows for this instead,

/user/account/edit/1

My query_vars are set as you can see in a var_dump

  ["query_vars"]=>
  array(56) {
    ["page_id"]=>
    int(100)
    ["gform_post_id"]=>
    string(3) "1"
    //....etc

Of course though with pretty permalinks on, the $_GET variable no longer holds my gform_post_id parameter which means that although the following shows the correct destination as per the rewrite rule above,

/user/account/edit/1   

…it does not pre-populate my form with post data as it does when accessing the same page directly via,

/index.php?page_id=100&gform_post_id=1

Any thoughts on ways around this?

Notes:

The plugin as linked in my opening declares the following line;

$this->get_post_object($_REQUEST[$this->options['request_id']]);

…to extract data out of of the $_REQUEST variable;

The option request_id is mapped to gform_post_id which should be set as the $_GET variable parameter.

  public $options = array(
    'request_id' => 'gform_post_id' // here we are...
    ,'post_status' => 'default'
    ,'capabilities' => array(
      'update' => 'default' 
      ,'delete' => 'disable' 
    )
    ,'entries' => true
  );

I have tried hooking onto the request filter and setting the $_GET variable myself but to no avail. I could be hooking to late in the piece but as it stands I’m a little unsure of how to tackle this problem without directly modifying the plugin itself.

Related posts

Leave a Reply

2 comments

  1. The solution to my problem was to ultimately unhook the construct function on init within the plugin and then re-add the plugin construct function on the wp hook.

     global $gform_update_post;
     remove_action( 'init', array($gform_update_post, 'init'), 100 );
     add_action( 'wp', array($gform_update_post, 'init'), 100 );
    

    This now means that I can access:

    /user/account/edit/1  
    

    …successfully with my form pre-populating data pertaining to the post ID in this case 1.

    However when re-submitting this form it creates a new post ID instead of updating the original post ID 1 as shown in the URL.

    Therefore in my situation I did this;

     global $gform_update_post;
     add_action( 'wp', array($gform_update_post, 'init'), 100 );
    

    …instead of removing the original construct action within the plugin, I left it in place, and instead re-declared the construct action on the wp hook which ensured all of the necessary Gravity Form hooks are firing in the right place to allow the form to update the same post ID in which I am editing (shown in URL).

    Beyond that I couldn’t be bothered trying to figure out what specifically within the plugin was causing this update vs create new post ID quirk.

    For anyone else trying this with the Gravity Forms add-on as listed in my OP you still need to set your $_GET or $_REQUEST variable on the request action hook, like so:

    add_filter( 'request', 'alter_the_query', 1 );
    
    function alter_the_query( $request ) {
       $_REQUEST['gform_post_id'] =  $request['gform_post_id'];
           return $request;
    
    }