[Forminator Pro] API and Forminator

Hi

Do you mind giving me a little help as we are not developers, just designers

Client wants the form to send data via JSON which we understand is built in with the API function.

Is this done by us setting the form up so it sends to an address at their end so their code can pick on the values submitted from the form?

Or can they retrieve the data from a URL on the website.

Thanks

Barry

  • Adam
    • Support Gorilla

    Hi Barry – DSM

    I hope you’re well today!

    I think it would be doable. I understand that this should be happening upon form submission (kind of “real time”:wink: and the data should be send to/retrieved by some external script/service, is that right?

    Assuming that you got the form set to save entries into the database, you could start with hooking up to this action hook:

    forminator_custom_form_after_save_entry

    It will give you an ID of a submitted form so you can check that ID to see if the form that you wish to “handle” was submitted and if so, use that ID to retrieve form data using Forminator API (“get_entries”/”get_entry” methods).

    You’d also want to use core PHP “json_encode()” function.

    A very simple example that upon submission reads all the submissions for a given form and simply records them in a debug.log file (if WP debugging with output to file is enabled):

    add_action( 'forminator_custom_form_after_save_entry', 'my_job_submit' );
    function my_job_submit( $form_id ) {

    $entries = json_encode( Forminator_API::get_entries( $form_id ) );

    error_log( ' SUBMITTED: ' . $form_id . 'JSON: ' . $entries );
    }

    Instead of calling “error_log” function you’d most likely want to connect to some URL at this point, making GET or POST request to send that JSON data.

    If you tell me a bit more how exactly this should work (note: above code doesn’t take “current submission” – it takes all entries at once!) I might be able to give you a bit more detailed suggestions though :slight_smile:

    Best regards,

    Adam

  • Barry - DSM
    • Site Builder, Child of Zeus

    The suggested action hook doesn’t seem to work for me.

    I turned on the

    define( ‘WP_DEBUG’, true );

    define( ‘WP_DEBUG_LOG’, true );

    and added to my functions.php file

    add_action( ‘forminator_custom_form_after_save_entry’, ‘my_job_submit’ );

    function my_job_submit( $form_id ) {

    $entries = json_encode( Forminator_API::get_entries( $form_id ) );

    error_log( ‘ SUBMITTED: ‘ . $form_id . ‘JSON: ‘ . $entries );

    }

    I then submitted a Forminator Form but no debug.log file has appeared yet.

  • Adam
    • Support Gorilla

    Hello Barry – DSM

    Is the form that you tested set to store entries in the database? By default that should be on but it might have been disabled in “Data Storage” option in “Settings” tab of form settings.

    Please double-check it as otherwise this hook will not be fired up.

    You can also try other related hooks:

    forminator_custom_form_before_save_entry

    forminator_custom_form_before_handle_submit
    forminator_custom_form_after_handle_submit

    Note that the last two do take one more parameter so the code should be a bit different for them, e.g.

    add_action( 'forminator_custom_form_after_handle_submit', 'my_job_submit', 15, 2);
    function my_job_submit( $form_id, $response ) {
    error_log( ' SUBMITTED: ' . $form_id );
    }

    Best regards,

    Adam

  • Barry - DSM
    • Site Builder, Child of Zeus

    I still cant get it to work. ( I’ve turned off hummingbird and defender encase of caching and security ) The only thing that’s appearing in the debug.log is:

    [30-Apr-2019 14:48:11 UTC] [WPMUDEV API Error] 4.7.1 | cURL error 28: Operation timed out after 15000 milliseconds with 0 bytes received ((unknown URL) [500])

    I’ve tried the suggested code one at a time and all 3 at once in the functions.php file with no change to the debug.log

    add_action( ‘forminator_custom_form_after_save_entry’, ‘my_job_submit’ );

    add_action( ‘forminator_custom_form_after_handle_submit’, ‘my_job_submit’, 15, 2);

    add_action( ‘forminator_custom_form_before_handle_submit’, ‘my_job_submit’, 15, 2);

    function my_job_submit( $form_id ) {

    $entries = json_encode( Forminator_API::get_entries( $form_id ) );

    error_log( ‘ SUBMITTED: ‘ . $form_id . ‘JSON: ‘ . $entries );

    }

    function my_job_submit( $form_id, $response ) {

    error_log( ‘ SUBMITTED: ‘ . $form_id );

    }

  • Adam
    • Support Gorilla

    Hello Barry – DSM

    I realize that the question that I’m going to ask sound very “lame” and a bit stupid but… are you sure you are actually adding the code into a right functions.php file?

    I’m asking about this because if this specific code was added to the site (as you shared it in your post above)

    add_action( 'forminator_custom_form_after_save_entry', 'my_job_submit' );
    add_action( 'forminator_custom_form_after_handle_submit', 'my_job_submit', 15, 2);
    add_action( 'forminator_custom_form_before_handle_submit', 'my_job_submit', 15, 2);

    function my_job_submit( $form_id ) {
    $entries = json_encode( Forminator_API::get_entries( $form_id ) );
    error_log( ' SUBMITTED: ' . $form_id . 'JSON: ' . $entries );
    }
    function my_job_submit( $form_id, $response ) {
    error_log( ' SUBMITTED: ' . $form_id );
    }

    it would have to trigger error, most likely a Fatal Error, so it would break the site or at least definitely generate a debug.log if debugging to a file is enabled.

    If the site is still working uninterrupted and there’s no debug.log created with this code present in functions.php file of an active theme – it suggests that this code is not even executed which would mean it’s not even “picked up” (so it’s in a wrong place).

    Best regards,

    Adam

  • Adam
    • Support Gorilla

    Hello Barry – DSM

    So my idea wasn’t that “lame” after all :slight_smile: Anyway, I’m glad you were able to make the code executed. We’re a step closer now :slight_smile:

    What you’re getting now is JSON containing all the entries (submissions) of the given form. I understand that you need to get a specific entry and that can also be done by replacing:

    Forminator_API::get_entries( $form_id )

    with

    Forminator_API::get_entry( $form_id, $entry_id )

    However, that also means that you need to actually know the ID of the entry you want to fetch. The question is then whether this will be specific entries requested or you just need the “most recent”/”current one”.

    Assuming that we’re still on the “upon submission” line (so you need the entry that was “just made” by the user who submitted the form, we’d need to find the last entry ID. I’m not entirely sure if that’s an expected (recommended) way to do it but we could actually “count” submissions:

    function my_job_submit( $form_id ) {
    $entry_num = Forminator_API::count_entries( $form_id );
    // Note: I'm not sure if in the line below it should be $entry_num or $entry_num-1
    // this would have to be tested as it depends on whether the entries
    // are numbered starting from 1 or from 0
    $entry = json_encode( Forminator_API::get_entry( $form_id, $entry_num ) );
    error_log( ' SUBMITTED: ' . $form_id . 'JSON: ' . $entry );
    }

    This should basically give you the same kind of data in debug.log but for the last (“current”:wink: submission. Since this is already JSON you can then actually replace the entire “error_log” line with some call (e.g. CURL performing POST or GET request) to the endpoint on that other site sending that data instead of writing it to the “debug.log”.

    However, after your last post I just realized that I’m not sure if I’m actually giving you a right advice because you wrote: “that can be retrieved from a wordpress URL”.

    Does this mean that you do not want Forminator to “actively” send form data to some external URL upon submission but instead you want some external code to be able to “ask Forminator” for specific form entry “on demand”? That can be done too and wouldn’t be that far from what we discussed so far but I’d like to make sure that we are on the same side before we go any further with this :slight_smile:

    Best regards,

    Adam

  • Barry - DSM
    • Site Builder, Child of Zeus

    Hi Adam,

    The client says they’d like every successful form submission to be emailed individually.

    They like it to match the format below.

    [

    {“entry_id”:”57″,”entry_type”:”custom-forms”,”form_id”:”192″,”is_spam”:”0″,”date_created_sql”:”2019-05-01 15:19:57″,”date_created”:”1 May 2019″,”time_created”:”1 May 2019 @ 15:19 PM”,”meta_data”:{“name-1”:{“id”:”706″,”value”:”test please ignore”},”name-2″:{“id”:”707″,”value”:”test please ignore”},”select-2″:{“id”:”708″,”value”:”other”},”select-1″:{“id”:”709″,”value”:”word”},”address-1″:{“id”:”710″,”value”:{“street_address”:”test please ignore”}},”text-3″:{“id”:”711″,”value”:”test please ignore”},”text-5″:{“id”:”712″,”value”:”test please ignore”},”text-4″:{“id”:”713″,”value”:”test please ignore”},”phone-1″:{“id”:”714″,”value”:”00000 000 000″},”email-1″:{“id”:”715″,”value”:”b.miley@dsmdesign.co.uk”},”number-1″:{“id”:”716″,”value”:”1″},”number-2″:{“id”:”717″,”value”:”1″},”number-3″:{“id”:”718″,”value”:”1″},”number-4″:{“id”:”719″,”value”:”1″},”number-5″:{“id”:”720″,”value”:”1″},”number-6″:{“id”:”721″,”value”:”1″},”text-2″:{“id”:”722″,”value”:”1″},”select-9″:{“id”:”723″,”value”:”one”},”date-2″:{“id”:”724″,”value”:”01/01/2019″},”date-3″:{“id”:”725″,”value”:”04/01/2019″},”gdprcheckbox-1″:{“id”:”726″,”value”:”true”},”textarea-1″:{“id”:”727″,”value”:”test please ignore”},”_forminator_user_ip”:{“id”:”728″,”value”:”81.136.197.155″}}}

    ]

    How do we change the function to email instead of sending to the data.log

  • Adam
    • Support Gorilla

    Hi Barry – DSM

    We could expand this code a bit, basically what would have to be done would be simply to replace “error_log()” function in the most recent version with a wp_mail() function but if it’s about mailing there might a different/better way to do this as mail notifications are already built in into the plugin.

    I’ve asked our developers to lend us a hand with this so they’ll look into it and I believe they’ll be able to suggest something that would work for you.

    Please note though: I realize that this might be a bit urgent and I’ve asked them to help as fast as possible but this is more of an individual customization rather than an issue/glitch/bug and they’re dealing with a lot of complex stuff on daily basis so I’d appreciate a bit more patience.

    Best regards,

    Adam

  • Barry - DSM
    • Site Builder, Child of Zeus

    I re-read the code above and attempted to get it working

    Forminator_API::get_entry( $form_id, $entry_id )

    that function worked but it’s no good if we cant just send the current entry.

    When I tried the count entries you suggested it show 1 entry but it was the wrong form and the wrong id.

    function my_job_submit( $form_id ) {
    $entry_num = Forminator_API::count_entries( $form_id );
    // Note: I'm not sure if in the line below it should be $entry_num or $entry_num-1
    // this would have to be tested as it depends on whether the entries
    // are numbered starting from 1 or from 0
    $entry = json_encode( Forminator_API::get_entry( $form_id, $entry_num ) );
    error_log( ' SUBMITTED: ' . $form_id . 'JSON: ' . $entry );
    }

  • Kostas
    • CTO

    Hey Barry – DSM ,

    I’m not really sure why you want to send a json via e-mail ( that’s what I understand from the last replies at least so I hope I’m correct), but in any case with these small changes you can easily achieve that.

    It would be better if you add this kind of code as a mu-plugin ( must use plugin ) to keep it separated from the theme’s files.

    How to install:

    Always make sure to keep a backup of your site before changing/adding custom code.

    1] Navigate to your /wp-content/ directory and create a new one named mu-plugins if it doesn’t exist.

    2] Inside the mu-plugins folder create a file named frmt-send-mail-with-json.php

    3] Edit the file and copy / paste this code snippet inside.

    <?php

    add_action(
    'forminator_custom_form_after_save_entry',
    function( $form_id, $response ) {

    // change number 5 with your Forms ID.
    $my_form = 5;
    // change to the address that you want to send the json.
    $to = 'some@email.test';
    // enter some subject for the e-mail.
    $subject = 'Some Subject';

    // Do not edit after this line.
    if ( intval( $form_id ) === $my_form ) {

    global $wpdb;

    $last_entry = $wpdb->get_results(
    $wpdb->prepare(
    "SELECT entry_id, form_id
    FROM {$wpdb->prefix}frmt_form_entry
    WHERE form_id = %d
    ORDER BY entry_id DESC
    LIMIT 1",
    $form_id
    )
    );

    $entry = json_encode( Forminator_API::get_entry( $form_id, $last_entry[0]->entry_id ) );

    $headers = array( 'Content-Type: text/plain; charset=UTF-8' );

    wp_mail( $to, $subject, $entry, $headers );
    }

    },
    15,
    2
    );

    4] Save and close the file.

    5] The final path should look like /wp-content/mu-plugins/frmt-send-mail-with-json.php

    As you can see in the code you will have to make some minor changes to finish this so it works for your form :slight_smile: .

    You will have to change the “5” from $my_form to be the same as your Form ID. This is to only have this code working for a specific form just in case you have more than 1 forms. And also change the $to and $subject values to adjust were you want the e-mail to go.

    This code will get the “last” forminator entry after a form is submitted and mail it as a json to the address that you want.

    Tell me if you need further help with this!

    Regards,

    Konstantinos

  • Luis Soriano
    • Ex Staff

    Hi Daniel

    Hope you are doing fine!

    You can use some custom code to post values to an API endpoint. Add a must-use plugin to your site’s wp-content/mu-plugins folder like this https://wpmudev.com/docs/using-wordpress/installing-wordpress-plugins/#installing-mu-plugins, then add some code as the following to the plugin’s php file. Remember this is a general code example, just to put you in the right track:

    <?php
    
    add_action(
        'forminator_custom_form_submit_before_set_fields',
        function ($entry, $form_id, $form_data_array) {
            if ($form_id != 360) {
                return;
            }
            
            $entries = wp_json_encode( Forminator_API::get_entries( $form_id ) );
        
    
            // API key & Endpoint
            $endpoint = 'https://endpoint.com/api';
    
            // Send the data to the API
            $response = wp_remote_post($endpoint, [
                'body'        => $entries,
                'headers'     => [
                    'Content-Type' => 'application/json',
                ],
                'timeout'     => 60,
                'redirection' => 5,
                'blocking'    => true,
                'httpversion' => '1.0',
                'data_format' => 'body',
            ]);
    
            echo "<pre>";
            print_r($response);
            echo "</pre>";
            die();
    
            if (is_wp_error($response)) {
                // Handle error
            } else {
              // Handle success
            }
    
        },
        10,
        3
    );

    Please change the 360 number to your form id and the $endpoint variable to the API endpoint you will be using. We recommend to test this on the dev/staging version first before putting it on the live site.

    If additional assistance is required, please open a new ticket, so we can provide more precise help for your request.

    Kind regards

    Luis