PluginProbe
Hello Plus / 1.7.0
Hello Plus v1.7.0
trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.1.0 1.1.1 1.1.2 1.1.3 1.2.0 1.2.1 1.3.0 1.4.0 1.4.1 1.5.0 1.5.1 1.5.2 1.5.3 1.6.0 1.6.1 1.6.2 1.7.0 1.7.1 1.7.2 1.7.3 All 30 releases
hello-plus / modules / forms / components / ajax-handler.php

ajax-handler.php in Hello Plus 1.7.0, at modules/forms/components/ajax-handler.php

269 lines 7.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace HelloPlus\Modules\Forms\Components;
3
4 use HelloPlus\Includes\Utils;
5 use HelloPlus\Modules\Forms\Classes\Form_Record;
6 use HelloPlus\Modules\Forms\Module;
7
8 if ( ! defined( 'ABSPATH' ) ) {
9 exit; // Exit if accessed directly
10 }
11
12 class Ajax_Handler {
13
14 public $is_success = true;
15 public $messages = [
16 'success' => [],
17 'error' => [],
18 'admin_error' => [],
19 ];
20 public $data = [];
21 public $errors = [];
22
23 private $current_form;
24
25 const SUCCESS = 'success';
26 const ERROR = 'error';
27 const FIELD_REQUIRED = 'required_field';
28 const INVALID_FORM = 'invalid_form';
29 const SERVER_ERROR = 'server_error';
30 const SUBSCRIBER_ALREADY_EXISTS = 'subscriber_already_exists';
31 const NONCE_ACTION = 'ehp-form-submission';
32
33 public static function get_default_messages(): array {
34 return [
35 self::SUCCESS => esc_html__( 'Your submission was successful.', 'hello-plus' ),
36 self::ERROR => esc_html__( 'Your submission failed because of an error.', 'hello-plus' ),
37 self::FIELD_REQUIRED => esc_html__( 'This field is required.', 'hello-plus' ),
38 self::INVALID_FORM => esc_html__( 'Your submission failed because the form is invalid.', 'hello-plus' ),
39 self::SERVER_ERROR => esc_html__( 'Your submission failed because of a server error.', 'hello-plus' ),
40 self::SUBSCRIBER_ALREADY_EXISTS => esc_html__( 'Subscriber already exists.', 'hello-plus' ),
41 ];
42 }
43
44 public static function get_default_message( $id, $settings ): string {
45 if ( ! empty( $settings['custom_messages'] ) ) {
46 $field_id = $id . '_message';
47 if ( isset( $settings[ $field_id ] ) ) {
48 return $settings[ $field_id ];
49 }
50 }
51
52 $default_messages = self::get_default_messages();
53
54 return $default_messages[ $id ] ?? esc_html__( 'Unknown error.', 'hello-plus' );
55 }
56
57 public function ajax_send_form() {
58 check_ajax_referer( self::NONCE_ACTION, 'nonce' );
59
60 // $post_id that holds the form settings.
61 $post_id = filter_input( INPUT_POST, 'post_id', FILTER_SANITIZE_NUMBER_INT );
62 $queried_id = filter_input( INPUT_POST, 'queried_id', FILTER_SANITIZE_NUMBER_INT );
63
64 // $queried_id the post for dynamic values data.
65 if ( ! $queried_id ) {
66 $queried_id = $post_id;
67 }
68
69 // Make the post as global post for dynamic values.
70 Utils::elementor()->db->switch_to_post( $queried_id );
71
72 $form_id = filter_input( INPUT_POST, 'form_id', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
73
74 $elementor = Utils::elementor();
75 $document = $elementor->documents->get( $post_id );
76 $form = null;
77 $template_id = null;
78
79 if ( $document ) {
80 $form = Module::find_element_recursive( $document->get_elements_data(), (string) $form_id );
81 }
82
83 if ( ! empty( $form['templateID'] ) ) {
84 $template = Utils::elementor()->documents->get( $form['templateID'] );
85
86 if ( ! $template ) {
87 return false;
88 }
89
90 $template_id = $template->get_id();
91 $form = $template->get_elements_data()[0];
92 }
93
94 if ( empty( $form ) ) {
95 $this
96 ->add_error_message( self::get_default_message( self::INVALID_FORM, [] ) )
97 ->send();
98 }
99
100 // restore default values
101 $widget = $elementor->elements_manager->create_element_instance( $form );
102 $form['settings'] = $widget->get_settings_for_display();
103 $form['settings']['id'] = $form_id;
104 $form['settings']['form_post_id'] = $template_id ? $template_id : $post_id;
105
106 // TODO: Should be removed if there is an ability to edit "global widgets"
107 $form['settings']['edit_post_id'] = $post_id;
108
109 $this->current_form = $form;
110
111 if ( empty( $form['settings']['form_fields'] ) ) {
112 $this
113 ->add_error_message( self::get_default_message( self::INVALID_FORM, $form['settings'] ) )
114 ->send();
115 }
116
117 // the fields are not fixed so they will be validated afterwards
118 $form_fields = filter_input(
119 INPUT_POST,
120 'form_fields',
121 FILTER_SANITIZE_FULL_SPECIAL_CHARS,
122 FILTER_REQUIRE_ARRAY
123 );
124
125 $record = new Form_Record( $form_fields, $form );
126
127 if ( ! $record->validate( $this ) ) {
128 $this
129 ->add_error( $record->get( 'errors' ) )
130 ->add_error_message( self::get_default_message( self::ERROR, $form['settings'] ) )
131 ->send();
132 }
133
134 $record->process_fields( $this );
135 //check for process errors
136 if ( ! empty( $this->errors ) ) {
137 $this->send();
138 }
139
140 $module = Module::instance();
141
142 $actions = $module->actions_registrar->get();
143 $errors = array_merge( $this->messages['error'], $this->messages['admin_error'] );
144
145 foreach ( $actions as $action ) {
146
147 $exception = null;
148
149 try {
150 $action->run( $record, $this );
151
152 $this->handle_bc_errors( $errors );
153 } catch ( \Exception $e ) {
154 $exception = $e;
155
156 // Add an admin error.
157 if ( ! in_array( $exception->getMessage(), $this->messages['admin_error'], true ) ) {
158 $this->add_admin_error_message( "{$action->get_label()} {$exception->getMessage()}" );
159 }
160
161 // Add a user error.
162 $this->add_error_message( $this->get_default_message( self::ERROR, $this->current_form['settings'] ) );
163 }
164
165 $errors = array_merge( $this->messages['error'], $this->messages['admin_error'] );
166 }
167
168 $this->send();
169 }
170
171 public function add_success_message( $message ) {
172 $this->messages['success'][] = $message;
173
174 return $this;
175 }
176
177 public function add_response_data( $key, $data ) {
178 $this->data[ $key ] = $data;
179
180 return $this;
181 }
182
183 public function add_error_message( $message ) {
184 $this->messages['error'][] = $message;
185 $this->set_success( false );
186
187 return $this;
188 }
189
190 public function add_error( $field, $message = '' ) {
191 if ( is_array( $field ) ) {
192 $this->errors += $field;
193 } else {
194 $this->errors[ $field ] = $message;
195 }
196
197 $this->set_success( false );
198
199 return $this;
200 }
201
202 public function add_admin_error_message( $message ) {
203 $this->messages['admin_error'][] = $message;
204 $this->set_success( false );
205
206 return $this;
207 }
208
209 public function set_success( $is_success ) {
210 $this->is_success = $is_success;
211
212 return $this;
213 }
214
215 public function send() {
216 if ( $this->is_success ) {
217 wp_send_json_success( [
218 'message' => $this->get_default_message( self::SUCCESS, $this->current_form['settings'] ),
219 'data' => $this->data,
220 ] );
221 }
222
223 if ( empty( $this->messages['error'] ) && ! empty( $this->errors ) ) {
224 $this->add_error_message( $this->get_default_message( self::INVALID_FORM, $this->current_form['settings'] ) );
225 }
226
227 $post_id = filter_input( INPUT_POST, 'post_id', FILTER_SANITIZE_NUMBER_INT );
228
229 $error_msg = implode( '<br>', $this->messages['error'] );
230
231 if ( current_user_can( 'edit_post', $post_id ) && ! empty( $this->messages['admin_error'] ) ) {
232 $this->add_admin_error_message( esc_html__( 'This message is not visible to site visitors.', 'hello-plus' ) );
233 $error_msg .= '<div class="elementor-forms-admin-errors">' . implode( '<br>', $this->messages['admin_error'] ) . '</div>';
234 }
235
236 wp_send_json_error( [
237 'message' => $error_msg,
238 'errors' => $this->errors,
239 'data' => $this->data,
240 ] );
241 }
242
243 public function get_current_form() {
244 return $this->current_form;
245 }
246
247 /**
248 * BC: checks if the current action add some errors to the errors array
249 * if it adds an error the "run" method treat it as a failed action.
250 *
251 * @param $errors
252 *
253 * @throws \Exception
254 */
255 private function handle_bc_errors( $errors ) {
256 $current_errors = array_merge( $this->messages['error'], $this->messages['admin_error'] );
257 $errors_diff = array_diff( $current_errors, $errors );
258
259 if ( count( $errors_diff ) > 0 ) {
260 throw new \Exception( esc_html( implode( ', ', $errors_diff ) ) );
261 }
262 }
263
264 public function __construct() {
265 add_action( 'wp_ajax_helloplus_forms_lite_send_form', [ $this, 'ajax_send_form' ] );
266 add_action( 'wp_ajax_nopriv_helloplus_forms_lite_send_form', [ $this, 'ajax_send_form' ] );
267 }
268 }
269