mirror of
https://github.com/proelements/proelements.git
synced 2026-05-05 17:15:58 +00:00
v4.0.4.1
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
namespace ElementorPro\Modules\AtomicForm\Actions;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly
|
||||
}
|
||||
|
||||
abstract class Action_Base {
|
||||
|
||||
/**
|
||||
* Get the action type identifier.
|
||||
*
|
||||
* @return string Action type (e.g., 'email', 'webhook', 'collect-submissions')
|
||||
*/
|
||||
abstract public function get_type(): string;
|
||||
|
||||
/**
|
||||
* Execute the action with the provided form data and widget settings.
|
||||
*
|
||||
* @param array $form_data Sanitized form data submitted by the user.
|
||||
* Example: ['name' => 'John', 'email' => 'john@example.com']
|
||||
* @param array $widget_settings Full widget settings - action extracts what it needs.
|
||||
* Example: ['email_to' => 'admin@site.com', 'email_subject' => 'New form', ...]
|
||||
* @param array $context Additional context (post_id, form_id, form_name).
|
||||
* Example: ['post_id' => 123, 'form_id' => 'contact', 'form_name' => 'Contact Form']
|
||||
* @return array Result array with 'status' and optional data.
|
||||
* Success: ['status' => 'success', 'message' => '...', ...]
|
||||
* Failure: ['status' => 'failed', 'error' => '...', ...]
|
||||
*/
|
||||
abstract public function execute( array $form_data, array $widget_settings, array $context ): array;
|
||||
|
||||
/**
|
||||
* Validate widget settings for this action.
|
||||
*
|
||||
* @param array $widget_settings Widget settings to validate.
|
||||
* @return bool|\WP_Error True if valid, WP_Error otherwise.
|
||||
*/
|
||||
protected function validate_settings( array $widget_settings ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format a success result.
|
||||
*
|
||||
* @param string $message Success message.
|
||||
* @param array $additional_data Additional data to include.
|
||||
* @return array
|
||||
*/
|
||||
protected function success( string $message, array $additional_data = [] ): array {
|
||||
return array_merge(
|
||||
[
|
||||
'status' => 'success',
|
||||
'message' => $message,
|
||||
],
|
||||
$additional_data
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Format a failure result.
|
||||
*
|
||||
* @param string $error Error message.
|
||||
* @param array $additional_data Additional data to include.
|
||||
* @return array
|
||||
*/
|
||||
protected function failure( string $error, array $additional_data = [] ): array {
|
||||
return array_merge(
|
||||
[
|
||||
'status' => 'failed',
|
||||
'error' => $error,
|
||||
],
|
||||
$additional_data
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
<?php
|
||||
namespace ElementorPro\Modules\AtomicForm\Actions;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly
|
||||
}
|
||||
|
||||
class Action_Runner {
|
||||
|
||||
/**
|
||||
* Registered actions.
|
||||
*
|
||||
* @var Action_Base[]
|
||||
*/
|
||||
private static $actions = [];
|
||||
|
||||
/**
|
||||
* Register an action.
|
||||
*
|
||||
* @param Action_Base $action Action instance to register.
|
||||
* @return void
|
||||
*/
|
||||
public static function register_action( Action_Base $action ): void {
|
||||
self::$actions[ $action->get_type() ] = $action;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an action instance by type.
|
||||
*
|
||||
* @param string $type Action type.
|
||||
* @return Action_Base|null Action instance or null if not found.
|
||||
*/
|
||||
public static function create_action( string $type ): ?Action_Base {
|
||||
if ( ! isset( self::$actions[ $type ] ) ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return self::$actions[ $type ];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all registered actions.
|
||||
*
|
||||
* @return Action_Base[] Array of registered actions.
|
||||
*/
|
||||
public static function get_registered_actions(): array {
|
||||
return self::$actions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if an action type is registered.
|
||||
*
|
||||
* @param string $type Action type.
|
||||
* @return bool
|
||||
*/
|
||||
public static function has_action( string $type ): bool {
|
||||
return isset( self::$actions[ $type ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute multiple actions and gather results.
|
||||
*
|
||||
* @param string[] $actions Array of action type strings.
|
||||
* @param array $form_data Sanitized form data.
|
||||
* @param array $widget_settings Full widget settings for actions to extract what they need.
|
||||
* @param array $context Form context (post_id, form_id, form_name).
|
||||
* @return array Results containing actionResults, allActionsSucceeded, failedActions, and optional submissionId.
|
||||
*/
|
||||
public static function execute_actions( array $actions, array $form_data, array $widget_settings, array $context ): array {
|
||||
$action_results = [];
|
||||
$failed_actions = [];
|
||||
|
||||
foreach ( $actions as $action_type ) {
|
||||
|
||||
if ( ! Action_Type::is_valid( $action_type ) ) {
|
||||
$action_results[] = [
|
||||
'type' => $action_type,
|
||||
'status' => 'failed',
|
||||
'error' => sprintf( __( 'Invalid action type: %s', 'elementor-pro' ), $action_type ),
|
||||
];
|
||||
$failed_actions[] = $action_type;
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
$action = self::create_action( $action_type );
|
||||
|
||||
if ( ! $action ) {
|
||||
throw new \Exception( sprintf( __( 'Could not create action: %s', 'elementor-pro' ), $action_type ) );
|
||||
}
|
||||
|
||||
$result = $action->execute( $form_data, $widget_settings, $context );
|
||||
|
||||
$action_results[] = array_merge(
|
||||
[ 'type' => $action_type ],
|
||||
$result
|
||||
);
|
||||
} catch ( \Exception $e ) {
|
||||
$action_results[] = [
|
||||
'type' => $action_type,
|
||||
'status' => 'failed',
|
||||
'error' => $e->getMessage(),
|
||||
];
|
||||
$failed_actions[] = $action_type;
|
||||
}
|
||||
}
|
||||
|
||||
$all_actions_succeeded = empty( $failed_actions );
|
||||
|
||||
$response = [
|
||||
'actionResults' => $action_results,
|
||||
'allActionsSucceeded' => $all_actions_succeeded,
|
||||
'failedActions' => $failed_actions,
|
||||
];
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize default actions.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function init(): void {
|
||||
self::register_action( new Email_Action() );
|
||||
self::register_action( new Collect_Submissions_Action() );
|
||||
self::register_action( new Webhook_Action() );
|
||||
|
||||
/**
|
||||
* Allow registering custom actions.
|
||||
*
|
||||
* @param Action_Factory $factory The action factory instance.
|
||||
*/
|
||||
do_action( 'elementor_pro/atomic_forms/actions/register', __CLASS__ );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
namespace ElementorPro\Modules\AtomicForm\Actions;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly
|
||||
}
|
||||
|
||||
class Action_Type {
|
||||
const EMAIL = 'email';
|
||||
const COLLECT_SUBMISSIONS = 'collect-submissions';
|
||||
const WEBHOOK = 'webhook';
|
||||
|
||||
/**
|
||||
* Get all registered action types.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_all_types(): array {
|
||||
return [
|
||||
self::EMAIL,
|
||||
self::COLLECT_SUBMISSIONS,
|
||||
self::WEBHOOK,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if an action type is valid.
|
||||
*
|
||||
* @param string $type Action type to validate.
|
||||
* @return bool
|
||||
*/
|
||||
public static function is_valid( string $type ): bool {
|
||||
return in_array( $type, self::get_all_types(), true );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
<?php
|
||||
namespace ElementorPro\Modules\AtomicForm\Actions;
|
||||
|
||||
use ElementorPro\Core\Utils;
|
||||
use ElementorPro\Modules\Forms\Submissions\Database\Query;
|
||||
use ElementorPro\Modules\Forms\Submissions\Database\Repositories\Form_Snapshot_Repository;
|
||||
use Elementor\Utils as ElementorUtils;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly
|
||||
}
|
||||
|
||||
class Collect_Submissions_Action extends Action_Base {
|
||||
|
||||
public function get_type(): string {
|
||||
return Action_Type::COLLECT_SUBMISSIONS;
|
||||
}
|
||||
|
||||
public function execute( array $form_data, array $widget_settings, array $context ): array {
|
||||
$metadata_keys = $this->normalize_metadata_keys( $widget_settings['submissions_metadata'] ?? [] );
|
||||
|
||||
$field_metadata = $context['field_metadata'] ?? [];
|
||||
$fields = $this->prepare_fields( $form_data, $field_metadata );
|
||||
|
||||
$submission_id = Query::get_instance()->add_submission(
|
||||
[
|
||||
'main_meta_id' => 0,
|
||||
'post_id' => $context['post_id'],
|
||||
'referer' => $this->get_referer(),
|
||||
'referer_title' => $this->get_referer_title(),
|
||||
'element_id' => $context['form_id'],
|
||||
'form_name' => $context['form_name'],
|
||||
'campaign_id' => 0,
|
||||
'user_id' => get_current_user_id(),
|
||||
'user_ip' => in_array( 'remote_ip', $metadata_keys, true ) ? Utils::get_client_ip() : '',
|
||||
'user_agent' => in_array( 'user_agent', $metadata_keys, true ) ? $this->get_user_agent() : '',
|
||||
'actions_count' => 0,
|
||||
'actions_succeeded_count' => 0,
|
||||
'meta' => wp_json_encode( [] ),
|
||||
],
|
||||
$fields
|
||||
);
|
||||
|
||||
if ( ! $submission_id ) {
|
||||
return $this->failure( __( 'Failed to save submission to database', 'elementor-pro' ) );
|
||||
}
|
||||
|
||||
$this->store_form_snapshot( $context, $fields );
|
||||
|
||||
return $this->success(
|
||||
__( 'Submission saved successfully', 'elementor-pro' ),
|
||||
[ 'submissionId' => $submission_id ]
|
||||
);
|
||||
}
|
||||
|
||||
private function normalize_metadata_keys( array $raw ): array {
|
||||
$allowed = [ 'remote_ip', 'user_agent' ];
|
||||
|
||||
return array_values( array_intersect( $raw, $allowed ) );
|
||||
}
|
||||
|
||||
private function prepare_fields( array $form_data, array $field_metadata = [] ): array {
|
||||
$fields = [];
|
||||
|
||||
foreach ( $form_data as $key => $value ) {
|
||||
$meta = $field_metadata[ $key ] ?? [];
|
||||
$label = ! empty( $meta['label'] ) ? $meta['label'] : ucwords( str_replace( [ '_', '-' ], ' ', $key ) );
|
||||
$type = ! empty( $meta['type'] ) ? $meta['type'] : $this->guess_field_type( $key, $value );
|
||||
|
||||
$fields[] = [
|
||||
'id' => $key,
|
||||
'type' => $type,
|
||||
'label' => $label,
|
||||
'value' => is_array( $value ) ? implode( ', ', $value ) : $value,
|
||||
];
|
||||
}
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
private function guess_field_type( string $key, $value ): string {
|
||||
$key_lower = strtolower( $key );
|
||||
|
||||
if ( strpos( $key_lower, 'email' ) !== false ) {
|
||||
return 'email';
|
||||
}
|
||||
|
||||
if ( strpos( $key_lower, 'phone' ) !== false || strpos( $key_lower, 'tel' ) !== false ) {
|
||||
return 'tel';
|
||||
}
|
||||
|
||||
if ( is_array( $value ) ) {
|
||||
return 'checkbox';
|
||||
}
|
||||
|
||||
if ( strpos( $key_lower, 'message' ) !== false || ( is_string( $value ) && strlen( $value ) > 100 ) ) {
|
||||
return 'textarea';
|
||||
}
|
||||
|
||||
if ( strpos( $key_lower, 'url' ) !== false || strpos( $key_lower, 'website' ) !== false ) {
|
||||
return 'url';
|
||||
}
|
||||
|
||||
return 'text';
|
||||
}
|
||||
|
||||
private function store_form_snapshot( array $context, array $fields ): void {
|
||||
$snapshot_fields = array_map(
|
||||
function ( $field ) {
|
||||
return [
|
||||
'id' => $field['id'],
|
||||
'type' => $field['type'],
|
||||
'label' => $field['label'],
|
||||
];
|
||||
},
|
||||
$fields
|
||||
);
|
||||
|
||||
Form_Snapshot_Repository::instance()->create_or_update(
|
||||
$context['post_id'],
|
||||
$context['form_id'],
|
||||
[
|
||||
'name' => $context['form_name'],
|
||||
'fields' => $snapshot_fields,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
private function get_referer(): string {
|
||||
$referer = ElementorUtils::get_super_global_value( $_SERVER, 'HTTP_REFERER' );
|
||||
if ( $referer ) {
|
||||
return esc_url_raw( wp_unslash( $referer ) );
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
private function get_referer_title(): string {
|
||||
// For now, return empty as we don't have access to the frontend page title
|
||||
return '';
|
||||
}
|
||||
|
||||
private function get_user_agent(): string {
|
||||
$user_agent = ElementorUtils::get_super_global_value( $_SERVER, 'HTTP_USER_AGENT' );
|
||||
if ( $user_agent ) {
|
||||
return sanitize_textarea_field( wp_unslash( $user_agent ) );
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
<?php
|
||||
namespace ElementorPro\Modules\AtomicForm\Actions;
|
||||
|
||||
use ElementorPro\Modules\AtomicForm\Actions\Email_Settings;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly
|
||||
}
|
||||
|
||||
class Email_Action extends Action_Base {
|
||||
|
||||
public function get_type(): string {
|
||||
return Action_Type::EMAIL;
|
||||
}
|
||||
|
||||
public function execute( array $form_data, array $widget_settings, array $context ): array {
|
||||
$validation = $this->validate_settings( $widget_settings );
|
||||
|
||||
if ( is_wp_error( $validation ) ) {
|
||||
return $this->failure( $validation->get_error_message() );
|
||||
}
|
||||
|
||||
$email_settings = new Email_Settings( $widget_settings );
|
||||
|
||||
$to = $email_settings->to();
|
||||
$from = $email_settings->from();
|
||||
$from_name = $email_settings->from_name();
|
||||
$message = $email_settings->message();
|
||||
$subject = $email_settings->subject();
|
||||
$reply_to = $email_settings->reply_to();
|
||||
$cc = $email_settings->cc();
|
||||
$bcc = $email_settings->bcc();
|
||||
$content_type = $email_settings->content_type();
|
||||
|
||||
$field_metadata = $context['field_metadata'] ?? [];
|
||||
$message = $this->replace_shortcodes( $message, $form_data, 'html' === $content_type, $field_metadata );
|
||||
|
||||
$headers = [];
|
||||
$headers[] = sprintf( 'From: %s <%s>', $from_name, $from );
|
||||
$headers[] = sprintf( 'Reply-To: %s', $reply_to );
|
||||
|
||||
if ( 'html' === $content_type ) {
|
||||
$headers[] = 'Content-Type: text/html; charset=UTF-8';
|
||||
}
|
||||
|
||||
if ( ! empty( $cc ) ) {
|
||||
$headers[] = sprintf( 'Cc: %s', $cc );
|
||||
}
|
||||
|
||||
if ( ! empty( $bcc ) ) {
|
||||
$headers[] = sprintf( 'Bcc: %s', $bcc );
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter email headers for atomic forms.
|
||||
*
|
||||
* @param array $headers Email headers.
|
||||
* @param array $form_data Form data.
|
||||
* @param array $widget_settings Widget settings.
|
||||
*/
|
||||
$headers = apply_filters( 'elementor_pro/atomic_forms/email_headers', $headers, $form_data, $widget_settings );
|
||||
|
||||
/**
|
||||
* Filter email message for atomic forms.
|
||||
*
|
||||
* @param string $message Email message.
|
||||
* @param array $form_data Form data.
|
||||
* @param array $widget_settings Widget settings.
|
||||
*/
|
||||
$message = apply_filters( 'elementor_pro/atomic_forms/email_message', $message, $form_data, $widget_settings );
|
||||
|
||||
$email_sent = wp_mail( $to, $subject, $message, $headers );
|
||||
|
||||
if ( ! $email_sent ) {
|
||||
return $this->failure( __( 'Failed to send email', 'elementor-pro' ) );
|
||||
}
|
||||
|
||||
return $this->success( __( 'Email sent successfully', 'elementor-pro' ) );
|
||||
}
|
||||
|
||||
protected function validate_settings( array $widget_settings ) {
|
||||
$email_settings = new Email_Settings( $widget_settings );
|
||||
$email_to = $email_settings->to();
|
||||
|
||||
if ( ! empty( $email_to ) && ! is_email( $email_to ) ) {
|
||||
$emails = array_map( 'trim', explode( ',', $email_to ) );
|
||||
foreach ( $emails as $email ) {
|
||||
if ( ! is_email( $email ) ) {
|
||||
return new \WP_Error(
|
||||
'invalid_email',
|
||||
sprintf(
|
||||
/* translators: %s: Invalid email address. */
|
||||
__( 'Invalid email address: %s', 'elementor-pro' ),
|
||||
$email
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private function replace_shortcodes( string $message, array $form_data, bool $is_html, array $field_metadata = [] ): string {
|
||||
$line_break = $is_html ? '<br>' : "\n";
|
||||
|
||||
if ( strpos( $message, '[all-fields]' ) !== false ) {
|
||||
$all_fields_text = '';
|
||||
|
||||
foreach ( $form_data as $key => $value ) {
|
||||
$meta = $field_metadata[ $key ] ?? [];
|
||||
$formatted_key = ! empty( $meta['label'] ) ? $meta['label'] : ucwords( str_replace( [ '_', '-' ], ' ', $key ) );
|
||||
$formatted_value = is_array( $value ) ? implode( ', ', $value ) : $value;
|
||||
|
||||
if ( $is_html ) {
|
||||
$formatted_key = esc_html( $formatted_key );
|
||||
|
||||
if ( is_string( $formatted_value ) ) {
|
||||
$formatted_value = nl2br( esc_html( $formatted_value ) );
|
||||
}
|
||||
}
|
||||
|
||||
$all_fields_text .= sprintf(
|
||||
'%s: %s%s',
|
||||
$formatted_key,
|
||||
$formatted_value,
|
||||
$line_break
|
||||
);
|
||||
}
|
||||
|
||||
$message = str_replace( '[all-fields]', $all_fields_text, $message );
|
||||
}
|
||||
|
||||
$message = preg_replace_callback(
|
||||
'/\[field[^\]]*id=["\']([^"\']+)["\'][^\]]*\]/',
|
||||
function ( $matches ) use ( $form_data ) {
|
||||
$field_id = $matches[1];
|
||||
|
||||
if ( isset( $form_data[ $field_id ] ) ) {
|
||||
$value = $form_data[ $field_id ];
|
||||
|
||||
return is_array( $value ) ? implode( ', ', $value ) : $value;
|
||||
}
|
||||
|
||||
return '';
|
||||
},
|
||||
$message
|
||||
);
|
||||
|
||||
return $message;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
namespace ElementorPro\Modules\AtomicForm\Actions;
|
||||
|
||||
use ElementorPro\Core\Utils;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly
|
||||
}
|
||||
|
||||
class Email_Settings {
|
||||
private $email_settings;
|
||||
|
||||
public function __construct( array $widget_settings ) {
|
||||
$this->email_settings = $widget_settings['email'] ?? [];
|
||||
}
|
||||
|
||||
public function to() {
|
||||
return $this->email_settings['to'] ?? get_option( 'admin_email' );
|
||||
}
|
||||
|
||||
public function from() {
|
||||
return $this->email_settings['from'] ?? 'noreply@' . Utils::get_site_domain();
|
||||
}
|
||||
|
||||
public function from_name() {
|
||||
return $this->email_settings['from-name'] ?? get_bloginfo( 'name' );
|
||||
}
|
||||
|
||||
public function subject() {
|
||||
return $this->email_settings['subject'] ?? sprintf(
|
||||
/* translators: %s: Site title. */
|
||||
__( 'New message from "%s"', 'elementor-pro' ),
|
||||
get_bloginfo( 'name' )
|
||||
);
|
||||
}
|
||||
|
||||
public function message() {
|
||||
return $this->email_settings['message'] ?? '[all-fields]';
|
||||
}
|
||||
|
||||
public function reply_to() {
|
||||
return $this->email_settings['reply-to'] ?? $this->from();
|
||||
}
|
||||
|
||||
public function cc() {
|
||||
return $this->email_settings['cc'] ?? '';
|
||||
}
|
||||
|
||||
public function bcc() {
|
||||
return $this->email_settings['bcc'] ?? '';
|
||||
}
|
||||
|
||||
public function content_type() {
|
||||
return $this->email_settings['send-as'] ?? 'html';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
<?php
|
||||
namespace ElementorPro\Modules\AtomicForm\Actions;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly
|
||||
}
|
||||
|
||||
class Webhook_Action extends Action_Base {
|
||||
|
||||
public function get_type(): string {
|
||||
return Action_Type::WEBHOOK;
|
||||
}
|
||||
|
||||
public function execute( array $form_data, array $widget_settings, array $context ): array {
|
||||
$validation = $this->validate_settings( $widget_settings );
|
||||
if ( is_wp_error( $validation ) ) {
|
||||
return $this->failure( $validation->get_error_message() );
|
||||
}
|
||||
|
||||
$url = $widget_settings['webhook_url'];
|
||||
$method = strtoupper( $widget_settings['webhook_method'] ?? 'POST' );
|
||||
$timeout = isset( $widget_settings['webhook_timeout'] ) ? absint( $widget_settings['webhook_timeout'] ) : 30;
|
||||
|
||||
$payload = [
|
||||
'formData' => $form_data,
|
||||
'postId' => $context['post_id'],
|
||||
'formId' => $context['form_id'],
|
||||
'formName' => $context['form_name'],
|
||||
'timestamp' => current_time( 'mysql' ),
|
||||
'siteUrl' => get_site_url(),
|
||||
];
|
||||
|
||||
/**
|
||||
* Filter webhook payload for atomic forms.
|
||||
*
|
||||
* @param array $payload Webhook payload.
|
||||
* @param array $form_data Form data.
|
||||
* @param array $widget_settings Widget settings.
|
||||
* @param array $context Form context.
|
||||
*/
|
||||
$payload = apply_filters(
|
||||
'elementor_pro/atomic_forms/webhook_payload',
|
||||
$payload,
|
||||
$form_data,
|
||||
$widget_settings,
|
||||
$context
|
||||
);
|
||||
|
||||
$args = [
|
||||
'method' => $method,
|
||||
'timeout' => $timeout,
|
||||
'headers' => [
|
||||
'Content-Type' => 'application/json',
|
||||
'User-Agent' => 'Elementor Pro Atomic Forms/' . ELEMENTOR_PRO_VERSION,
|
||||
],
|
||||
'body' => wp_json_encode( $payload ),
|
||||
];
|
||||
|
||||
if ( ! empty( $widget_settings['webhook_headers'] ) && is_array( $widget_settings['webhook_headers'] ) ) {
|
||||
$args['headers'] = array_merge( $args['headers'], $widget_settings['webhook_headers'] );
|
||||
}
|
||||
|
||||
$response = wp_remote_request( $url, $args );
|
||||
|
||||
if ( is_wp_error( $response ) ) {
|
||||
return $this->failure(
|
||||
sprintf(
|
||||
/* translators: %s: Error message. */
|
||||
__( 'Webhook request failed: %s', 'elementor-pro' ),
|
||||
$response->get_error_message()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$response_code = wp_remote_retrieve_response_code( $response );
|
||||
$response_body = wp_remote_retrieve_body( $response );
|
||||
|
||||
if ( $response_code >= 200 && $response_code < 300 ) {
|
||||
return $this->success(
|
||||
__( 'Webhook delivered successfully', 'elementor-pro' ),
|
||||
[
|
||||
'responseCode' => $response_code,
|
||||
'responseBody' => $response_body,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
return $this->failure(
|
||||
sprintf(
|
||||
/* translators: %d: HTTP status code. */
|
||||
__( 'Webhook returned error status code: %d', 'elementor-pro' ),
|
||||
$response_code
|
||||
),
|
||||
[
|
||||
'responseCode' => $response_code,
|
||||
'responseBody' => $response_body,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
protected function validate_settings( array $widget_settings ) {
|
||||
if ( empty( $widget_settings['webhook_url'] ) ) {
|
||||
return new \WP_Error(
|
||||
'missing_url',
|
||||
__( 'Webhook URL is required', 'elementor-pro' )
|
||||
);
|
||||
}
|
||||
|
||||
if ( ! filter_var( $widget_settings['webhook_url'], FILTER_VALIDATE_URL ) ) {
|
||||
return new \WP_Error(
|
||||
'invalid_url',
|
||||
__( 'Invalid webhook URL', 'elementor-pro' )
|
||||
);
|
||||
}
|
||||
|
||||
if ( isset( $widget_settings['webhook_method'] ) ) {
|
||||
$allowed_methods = [ 'GET', 'POST', 'PUT', 'PATCH', 'DELETE' ];
|
||||
if ( ! in_array( strtoupper( $widget_settings['webhook_method'] ), $allowed_methods, true ) ) {
|
||||
return new \WP_Error(
|
||||
'invalid_method',
|
||||
__( 'Invalid HTTP method', 'elementor-pro' )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user