phpwordpresswordpress-plugin-creationwordpress-hook

Formidable Form frm_after_create_entry create a double entry


I'm trying to develop a custom action for FormidableForm that let user go through the helloasso checkout process and register it when redirected to the "thank you" page.

In this action I want to use the "frm_after_create_entry" action hook to get the created entry id and redirect my user on an other page with this id as param.

The problem is that if i use this action the user entry is created twice.

Here's my code :

<?php

require_once __DIR__ . '/../http-query-functions.php';
require_once __DIR__ . '/helloAsso-actions/HelloAssoAuthenticator.php';

class HelloAssoCheckoutAction extends FrmFormAction
{
    private string $user_form_id;
    private string $access_token;
    private string $data_to_send_for_checkout;
    private array $action_parameters;
    private array $user_form_values;

    function __construct()
    {
        $action_ops = array(
            'classes'   => 'dashicons dashicons-format-aside',
            'limit'     => 99,
            'priority'  => 50,
            'event'  => array('create'),
        );

        $this->FrmFormAction('HelloAssoCheckoutAction', __('HelloAsso Checkout', 'formidable'), $action_ops);

        add_filter('frm_validate_entry', array($this, 'prepare_checkout'), 10, 2);
        add_action('frm_after_create_entry', array($this, 'checkout'), 50, 2);
        add_action('init', array($this, 'register_helloasso_shortcodes'));
    }

    function register_helloasso_shortcodes()
    {
        add_shortcode('helloasso_checkout_status', array($this, 'set_checkout_status'));
    }


    function form($form_action, $args = array())
    {
       //... HTML form to set action parameters
    }


    function get_defaults()
    {
        return array(
            'template_name' => '',
            'my_content' => '',
        );
    }

    function prepare_checkout($errors, $values)
    {
        $this->user_form_id = $values['form_id'];
        $form_actions = FrmFormAction::get_action_for_form($this->user_form_id, 'helloassocheckoutaction');
        if (empty($form_actions)) {
            return;
        }
        $form_action = reset($form_actions);

        $this->action_parameters = $form_action->post_content;
        $this->user_form_values = $values;

        $this->connect_to_hello_asso($this->action_parameters['token_endpoint'], $this->action_parameters['client_id'], $this->action_parameters['client_secret']);

        return $errors;
    }

    private function connect_to_hello_asso($token_endpoint, $client_id, $client_secret)
    {
        $helloAsso_ahthenticator = new HelloAssoAuthenticator();
        $this->access_token = $helloAsso_ahthenticator->get_access_token($token_endpoint, $client_id, $client_secret);
    }


    function checkout($entry_id, $form_id)
    {

        $form_actions = FrmFormAction::get_action_for_form($form_id, 'helloassocheckoutaction');
        if (empty($form_actions)) {
            echo 'No action for this form, return errors';
            return;
        }

        $this->set_post_data($entry_id);


        $this->redirect_to_helloAsso_checkout($this->action_parameters['checkout_endpoint'], $this->access_token, $this->data_to_send_for_checkout);
    }

    private function set_post_data($entry_id)
    {
        $this->data_to_send_for_checkout = json_encode(array(
            "totalAmount" => $this->action_parameters['initial_amount'] * 100, // Amount in cents
            "initialAmount" => $this->action_parameters['initial_amount'] * 100,
            "itemName" => $this->action_parameters['campain_name'],
            "backUrl" => sanitize_url($this->action_parameters['back_url']),
            "errorUrl" => sanitize_url($this->action_parameters['error_url']),
            "returnUrl" => sanitize_url($this->action_parameters['success_url'] . "?entry=" . $entry_id),
            "containsDonation" => true,
            "payer" => array(
                "firstName" => sanitize_text_field($this->user_form_values['item_meta'][$this->action_parameters['name_field']]['first']),
                "lastName" => sanitize_text_field($this->user_form_values['item_meta'][$this->action_parameters['name_field']]['last']),
                "email" => sanitize_email($this->user_form_values['item_meta'][$this->action_parameters['mail_field']]),
                "dateOfBirth" => sanitize_text_field($this->user_form_values['item_meta'][$this->action_parameters['birthdate_field']]),
                "address" => sanitize_text_field($this->user_form_values['item_meta'][$this->action_parameters['address_field']]['line1']),
                "city" => sanitize_text_field($this->user_form_values['item_meta'][$this->action_parameters['address_field']]['city']),
                "zipCode" => sanitize_text_field($this->user_form_values['item_meta'][$this->action_parameters['address_field']]['zip']),
                "country" => "FRA"
            )
        ), true);
    }

    private function redirect_to_helloAsso_checkout($checkout_endpoint, $access_token, $form_data_json)
    {
        $response = create_curl_post_and_return_json_response($checkout_endpoint, $form_data_json, array(
            'Content-Type: application/json',
            'Authorization: Bearer ' . $access_token
        ));

        if (isset($response['error'])) {
            throw new Exception($response['error'] . ' ' . $response['message']);
        }

        header('Location: ' . wp_sanitize_redirect($response['redirectUrl']));
    }

    function set_checkout_status($atts)
    {
        if (isset($_GET['entry']) && isset($_GET['orderId']) && isset($_GET['code'])) {
            echo "paiement status for entry " . $_GET['entry'] . " is " . $_GET['code'] . " for order " . $_GET['orderId'];
            //TODO update the entry status 

        } else {
            echo "no entry id or code or order id";
        }
    }
}

To be sure that it came from the use of frm_after_create_entry

I looked for other action that would let me get the entryId but I didn't find it.

I admit that PHP and wordpress are not my primary stack and I may have used a great deal of LLM to get there.


Solution

  • I don't know if it's the right anwser but I made it work by disabling the option to send the form with AJAX