Now Reading
Converting Formidable Forms date to a Unix Timestamp
0

Converting Formidable Forms date to a Unix Timestamp

by Simon ParkerJanuary 25, 2022

Formidable Forms is a great WordPress plugin that provides a simple yet powerful UI for creating forms. It is now the only form plugin we use on our sites.

One of the main features we utilise Formidable forms for is its capability to send API data to any external source.

This is particularly useful for when certain products or, in our case, CRM systems do not have specific actions built into their current “integrations” or plugins.

One recent project required that we use Formidable forms to send a date to an external CRM API to update a date field.

So we setup the Send API Data action to send the resulting date field to the external CRM API which gave the following error.

"isValid":false,"message": "2021-12-14 was not a valid long."

A couple of quick support tickets and tests shows that the CRM only accepts unix timestamps onto this date field.

The Formidable Forms support as always were very quick to respond and very helpful in their reply. They suggested that we use the form validation hook and create a filter that would copy the date field and convert this to the needed timestamp in the function.

The suggested code from their documentation is

add_filter('frm_validate_field_entry', 'copy_my_field', 10, 3);
function copy_my_field($errors, $posted_field, $posted_value){
  if ( $posted_field->id == 25 ) { //change 25 to the ID of the field to change
    $_POST['item_meta'][$posted_field->id] = $_POST['item_meta'][20]; //Change 20 to the ID of the field to copy
  }
  return $errors;
}

We need to replace the 25 above with the hidden field ID which is in our case 211 and the field to copy with 122 our original date field. We find these easily by clicking on the form field in the editor and it is shown at the top of the options section for each field in the forms.

From the Formidable Forms documentation and from their support email the form should be posting the data in YYYY-MM-DD formatting and their suggestion was to use the strtotimephp function to convert the date into a timestamp

So our initial code was

add_filter('frm_validate_field_entry', 'copy_my_field', 10, 3);
function copy_my_field($errors, $posted_field, $posted_value){
    if ( $posted_field->id == 211 ) {
        $_POST['item_meta'][$posted_field->id] = strtotime( $_POST['item_meta'][122] );
    }
    return $errors;
}

I added this to the test site using the brilliant Code Snippets plugin and activated it. And the result was nothing happened.

The new hidden field was not getting populated and we had no error.

We decided to first check that the code was actually being run correctly so we change our function to

 

add_filter('frm_validate_field_entry', 'copy_my_field', 10, 3);
function copy_my_field($errors, $posted_field, $posted_value){
    if ( $posted_field->id == 211 ) {
        $_POST['item_meta'][$posted_field->id] = 1643027290;
    }
    return $errors;
}

This instead of using strtotime now just tries to post a valid unix timestamp into the field. This entered the timestamp into the hidden field, however, the API post then had a new issue which was that the above timestamp we entered was not actually midnight. when posting a date to the API it has to be at Midnight. but more importantly this means that the posted field is not a valid input for strtotime.

We again double check the Formidable forms documentation and on the first line of their knowledgebase article for the date field  it confirms that “A Date field stores values in the Y-m-d format but the field displays dates in the format selected in your Formidable Global Settings.”

But for whatever reason, strtotime can’t accept this. So we move to instead use the DateTime php functions. It allows you to provide a format that it will accept specific ordering of Day Month and Year.

We modify our function as follows,

add_filter('frm_validate_field_entry', 'copy_my_field', 10, 3);
function copy_my_field($errors, $posted_field, $posted_value){
    if ( $posted_field->id == 211 ) {
        $_POST['item_meta'][$posted_field->id] = DateTime::createFromFormat('Y-m-d', $_POST['item_meta'][20])->getTimestamp();;
    }
    return $errors;
}

This now specifies that we are expecting the Formidable Forms date field to be in the format YYYY-MM-DD format and to convert this into a unix timestamp.

Once again failure.

Interestingly this actually causes a critical error in WordPress when submitting the form.

Enable Debugging on WordPress and submit again so we can see the error.

PHP Fatal error:  Uncaught Error: Call to a member function getTimestamp() on bool

We tested separately that the Date Time function can accept a date in that format within WordPress and it has no issues.

So we look at the actual posted data in Chrome Dev Tools so we can see what is being posted by the form.

 "formValues":{
      "Date":"24/01/2022",

So while the Date field may well be saved in the database in a Y-m-d format. It is not posted in that format from the form to the submit form function.

So we update the function to match this format.

add_filter('frm_validate_field_entry', 'copy_my_field', 10, 3);
function copy_my_field($errors, $posted_field, $posted_value){
    if ( $posted_field->id == 211 ) {
        $_POST['item_meta'][$posted_field->id] = DateTime::createFromFormat('d/m/Y', $_POST['item_meta'][20])->getTimestamp();;
    }
    return $errors;
}

And we now have the unix timestamp correctly into the hidden field.

We still however get an error from the API as this timestamp is not at midnight. the DateTime php function will fill in the time as now() if it is not provided with a time to use.

Fortunately from their documentation and Stackoverflow we can see that adding a pipe to the end of the date format overrides the time to set it to Midnight.

 

add_filter('frm_validate_field_entry', 'copy_my_field', 10, 3);
function copy_my_field($errors, $posted_field, $posted_value){
    if ( $posted_field->id == 211 ) {
        $_POST['item_meta'][$posted_field->id] = DateTime::createFromFormat('d/m/Y|', $_POST['item_meta'][20])->getTimestamp();;
    }
    return $errors;
}

We add the Pipe to the end of the format and we get a final error. Just from the CRM this time. From their documentation they expect the Unix timestamp to be in milliseconds not seconds.

Thankfully this final fix is simple enough. add a (* 1000) to the function.

I also added in some changes to the function name as we may need to use this code again in other forms. Specifically, this code only looks for a field with the ID of 211 to be posted and if it is then it copies over the value of field 122 after changing it to a Unix timestamp. If we have another form then these IDs will change.

So our final function for converting this Formidable Forms date field to a Unix timestamp that is in milliseconds is

add_filter('frm_validate_field_entry', 'form9', 10, 3);
function form9($errors, $posted_field, $posted_value){
    if ( $posted_field->id == 211 ) { //change 25 to the ID of the field to change
	$_POST['item_meta'][$posted_field->id] = 
DateTime::createFromFormat('d/m/Y|', $_POST['item_meta'][122])->getTimestamp() * 1000;
   }
    return $errors;
}

I believe the inconsistency with the date field is likely because of this being a UK site where the date field is set to use UK formatting. Apparently the strtotime function will use the separator to distinguish which date format is being used. From their docs,

” Dates in the m/d/y or d-m-y formats are disambiguated by looking at the separator between the various components: if the separator is a slash (/), then the American m/d/y is assumed; whereas if the separator is a dash (-) or a dot (.), then the European d-m-y format is assumed.”

Our date format is a mix of both here. The format is the day then month then year d/m/y but the posted data sent from the form is wth a / slash so strtotime will assume it is American m/d/y. If we had done this on any day before the 12th of this month it would likely have worked and then stopped working after it hit the 13th of the month. Although it would have obviously also sent the wrong Unix timestamp.

Once again it does show how even the simplest tasks can not only take hours to complete but also draw attention to inconsistencies throughout various plugins and their documentation when trying to do something a little outside the norm.

Lesson learned? Always check the post data in chrome first so you know what is actually being sent.

What's your reaction?
Love It
100%
Interested
0%
Meh...
0%
What?
0%
Hate It
0%
Sad
0%
About The Author
Simon Parker

Leave a Response