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.
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