PluginProbe
Hello Plus / 1.2.0
Hello Plus v1.2.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 / classes / form-record.php

form-record.php in Hello Plus 1.2.0, at modules/forms/classes/form-record.php

340 lines 9.2 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\Classes;
3
4 use HelloPlus\Includes\Utils;
5 use HelloPlus\Modules\Forms\Components\Ajax_Handler;
6
7 if ( ! defined( 'ABSPATH' ) ) {
8 exit; // Exit if accessed directly
9 }
10
11 class Form_Record {
12 protected $sent_data;
13 protected $fields;
14 protected $form_type;
15 protected $form_settings;
16 protected $files = [];
17 protected $meta = [];
18
19 public function get_formatted_data( $with_meta = false ): array {
20 $formatted = [];
21 $no_label = esc_html__( 'No Label', 'hello-plus' );
22 $fields = $this->fields;
23
24 if ( $with_meta ) {
25 $fields = array_merge( $fields, $this->meta );
26 }
27
28 foreach ( $fields as $key => $field ) {
29 if ( empty( $field['title'] ) ) {
30 $formatted[ $no_label . ' ' . $key ] = $field['value'];
31 } else {
32 $formatted[ $field['title'] ] = $field['value'];
33 }
34 }
35
36 return $formatted;
37 }
38
39 /**
40 * @param Ajax_Handler $ajax_handler An instance of the ajax handler.
41 *
42 * @return bool
43 */
44 public function validate( Ajax_Handler $ajax_handler ): bool {
45 foreach ( $this->fields as $id => $field ) {
46 $field_type = $field['type'];
47 if ( ! empty( $field['required'] ) && '' === $field['value'] && 'upload' !== $field_type ) {
48 $ajax_handler->add_error( $id, Ajax_Handler::get_default_message( Ajax_Handler::FIELD_REQUIRED, $this->form_settings ) );
49 }
50
51 /**
52 * Hello+ form field validation.
53 *
54 * Fires when a single form field is being validated. This hook allows developers
55 * to validate individual field types.
56 *
57 * The dynamic portion of the hook name, `$field_type`, refers to the field type.
58 *
59 * @since 1.0.0
60 *
61 * @param array $field Form field.
62 * @param Form_Record $this An instance of the form record.
63 * @param Ajax_Handler $ajax_handler An instance of the ajax handler.
64 */
65 do_action( "hello_plus/forms/validation/{$field_type}", $field, $this, $ajax_handler );
66 }
67
68 /**
69 * Hello+ form validation.
70 *
71 * Fires when form fields are being validated. This hook allows developers
72 * to validate all form fields.
73 *
74 * @since 1.0.0
75 *
76 * @param Form_Record $this An instance of the form record.
77 * @param Ajax_Handler $ajax_handler An instance of the ajax handler.
78 */
79 do_action( 'hello_plus/forms/validation', $this, $ajax_handler );
80
81 return empty( $ajax_handler->errors );
82 }
83
84 /**
85 * @param Ajax_Handler $ajax_handler An instance of the ajax handler.
86 *
87 */
88 public function process_fields( Ajax_Handler $ajax_handler ) {
89 foreach ( $this->fields as $id => $field ) {
90 $field_type = $field['type'];
91
92 /**
93 * Hello+ form field process.
94 *
95 * Fires when a single form field is being processed. This hook allows developers
96 * to process individual field types.
97 *
98 * The dynamic portion of the hook name, `$field_type`, refers to the field type.
99 *
100 * @since 1.0.0
101 *
102 * @param array $field Form field.
103 * @param Form_Record $this An instance of the form record.
104 * @param Ajax_Handler $ajax_handler An instance of the ajax handler.
105 */
106 do_action( "hello_plus/forms/process/{$field_type}", $field, $this, $ajax_handler );
107 }
108
109 /**
110 * Hello+ form process.
111 *
112 * Fires when form fields are being processed. This hook allows developers
113 * to process all form fields.
114 *
115 * @since 1.0.0
116 *
117 * @param Form_Record $this An instance of the form record.
118 * @param Ajax_Handler $ajax_handler An instance of the ajax handler.
119 */
120 do_action( 'hello_plus/forms/process', $this, $ajax_handler );
121 }
122
123 public function get( $property ) {
124 if ( isset( $this->{$property} ) ) {
125 return $this->{$property};
126 }
127
128 return null;
129 }
130
131 public function set( $property, $value ) {
132 $this->{$property} = $value;
133 }
134
135 public function get_form_settings( $setting ) {
136 if ( isset( $this->form_settings[ $setting ] ) ) {
137 return $this->form_settings[ $setting ];
138 }
139
140 return null;
141 }
142
143 public function get_field( $args ) {
144 return wp_list_filter( $this->fields, $args );
145 }
146
147 public function remove_field( $id ) {
148 unset( $this->fields[ $id ] );
149 }
150
151 public function update_field( $field_id, $property, $value ) {
152 if ( ! isset( $this->fields[ $field_id ] ) || ! isset( $this->fields[ $field_id ][ $property ] ) ) {
153 return;
154 }
155 $this->fields[ $field_id ][ $property ] = $value;
156 }
157
158 public function get_form_meta( $meta_keys = [] ) {
159
160 $result = [];
161
162 foreach ( $meta_keys as $metadata_type ) {
163 switch ( $metadata_type ) {
164 case 'date':
165 $result['date'] = [
166 'title' => esc_html__( 'Date', 'hello-plus' ),
167 'value' => date_i18n( get_option( 'date_format' ) ),
168 ];
169 break;
170
171 case 'time':
172 $result['time'] = [
173 'title' => esc_html__( 'Time', 'hello-plus' ),
174 'value' => date_i18n( get_option( 'time_format' ) ),
175 ];
176 break;
177
178 case 'page_url':
179 $referrer = filter_input( INPUT_POST, 'referrer', FILTER_SANITIZE_URL );
180 $result['page_url'] = [
181 'title' => esc_html__( 'Page URL', 'hello-plus' ),
182 'value' => $referrer ? esc_url_raw( wp_unslash( $referrer ) ) : '',
183 ];
184 break;
185
186 case 'page_title':
187 $referrer_title = filter_input( INPUT_POST, 'referer_title', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
188 $result['page_title'] = [
189 'title' => esc_html__( 'Page Title', 'hello-plus' ),
190 'value' => $referrer_title ? sanitize_text_field( wp_unslash( $referrer_title ) ) : '',
191 ];
192 break;
193
194 case 'user_agent':
195 $user_agent = filter_input( INPUT_SERVER, 'HTTP_USER_AGENT', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
196 $result['user_agent'] = [
197 'title' => esc_html__( 'User Agent', 'hello-plus' ),
198 'value' => $user_agent ? sanitize_textarea_field( wp_unslash( $user_agent ) ) : '',
199 ];
200 break;
201
202 case 'remote_ip':
203 $result['remote_ip'] = [
204 'title' => esc_html__( 'Remote IP', 'hello-plus' ),
205 'value' => Utils::get_client_ip(),
206 ];
207 break;
208 case 'credit':
209 $result['credit'] = [
210 'title' => esc_html__( 'Powered by', 'hello-plus' ),
211 'value' => esc_html__( 'Elementor', 'hello-plus' ),
212 ];
213 break;
214 }
215 }
216
217 return $result;
218 }
219
220 private function set_meta() {
221 $form_metadata = $this->form_settings['form_metadata'];
222
223 if ( empty( $form_metadata ) ) {
224 return;
225 }
226
227 $this->meta = $this->get_form_meta( $form_metadata );
228 }
229
230 private function set_fields() {
231 foreach ( $this->form_settings['form_fields'] as $form_field ) {
232 $field = [
233 'id' => $form_field['custom_id'],
234 'type' => $form_field['field_type'],
235 'title' => $form_field['field_label'],
236 'value' => '',
237 'raw_value' => '',
238 'required' => ! empty( $form_field['required'] ),
239 ];
240
241 if ( 'upload' === $field['type'] ) {
242 $field['file_sizes'] = $form_field['file_sizes'] ?? '';
243 $field['file_types'] = $form_field['file_types'] ?? '';
244 $field['max_files'] = $form_field['max_files'] ?? '';
245 $field['attachment_type'] = $form_field['attachment_type'] ?? '';
246 }
247
248 if ( isset( $this->sent_data[ $form_field['custom_id'] ] ) ) {
249 $field['raw_value'] = $this->sent_data[ $form_field['custom_id'] ];
250
251 $value = $field['raw_value'];
252
253 if ( is_array( $value ) ) {
254 $value = implode( ', ', $value );
255 }
256
257 $field['value'] = $this->sanitize_field( $field, $value );
258 }
259 $this->fields[ $form_field['custom_id'] ] = $field;
260 }
261 }
262
263 private function sanitize_field( $field, $value ) {
264 $field_type = $field['type'];
265 switch ( $field_type ) {
266 case 'text':
267 case 'password':
268 case 'hidden':
269 case 'search':
270 case 'checkbox':
271 case 'radio':
272 case 'select':
273 $value = sanitize_text_field( $value );
274 break;
275 case 'url':
276 $value = esc_url_raw( $value );
277 break;
278 case 'textarea':
279 $value = sanitize_textarea_field( $value );
280 break;
281 case 'email':
282 $value = sanitize_email( $value );
283 break;
284 default:
285 /**
286 * Sanitize field value.
287 *
288 * Filters the value of the form field for sanitization purpose. This hook allows
289 * developers to add custom sanitization for field values.
290 *
291 * The dynamic portion of the hook name, `$field_type`, refers to the field type.
292 *
293 * @since 1.0.0
294 *
295 * @param string $value The field value.
296 * @param array $field The field array.
297 */
298 $value = apply_filters( "hello_plus/forms/sanitize/{$field_type}", $value, $field );
299 }
300
301 return $value;
302 }
303
304 public function replace_setting_shortcodes( $setting, $urlencode = false ) {
305 // Shortcode can be `[field id="fds21fd"]` or `[field title="Email" id="fds21fd"]`, multiple shortcodes are allowed
306 return preg_replace_callback( '/(\[field[^]]*id="(\w+)"[^]]*\])/', function ( $matches ) use ( $urlencode ) {
307 $value = '';
308
309 if ( isset( $this->fields[ $matches[2] ] ) ) {
310 $value = $this->fields[ $matches[2] ]['value'];
311 }
312
313 if ( $urlencode ) {
314 $value = rawurlencode( $value );
315 }
316 return $value;
317 }, $setting );
318 }
319
320
321 public function has_field_type( $type ) {
322 foreach ( $this->fields as $id => $field ) {
323 if ( $type === $field['field_type'] ) {
324 return true;
325 }
326 }
327
328 return false;
329 }
330
331 public function __construct( $sent_data, $form ) {
332 $this->form_type = $form['widgetType'];
333 $this->form_settings = $form['settings'];
334 $this->sent_data = stripslashes_deep( $sent_data );
335
336 $this->set_fields();
337 $this->set_meta();
338 }
339 }
340