PluginProbe
Block Animations, Motion & Scroll Effects – Ghost Kit / 2.25.0
Block Animations, Motion & Scroll Effects – Ghost Kit v2.25.0
3.7.2 3.7.1 3.7.0 3.6.1 trunk 1.6.3 2.25.0 3.3.0 3.3.1 3.3.2 3.3.3 3.4.0 3.4.1 3.4.2 3.4.3 3.4.4 3.4.5 3.4.6 3.5.0 3.5.1 3.6.0
ghostkit / gutenberg / blocks / form / block.php

block.php in Block Animations, Motion & Scroll Effects – Ghost Kit 2.25.0, at gutenberg/blocks/form/block.php

570 lines 18.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Form block.
4 *
5 * @package ghostkit
6 */
7
8 if ( ! defined( 'ABSPATH' ) ) {
9 exit;
10 }
11
12 require_once $this->plugin_path . 'gutenberg/blocks/form/field-attributes/index.php';
13 require_once $this->plugin_path . 'gutenberg/blocks/form/field-label/index.php';
14 require_once $this->plugin_path . 'gutenberg/blocks/form/field-description/index.php';
15
16 /**
17 * Class GhostKit_Form_Block
18 */
19 class GhostKit_Form_Block {
20 /**
21 * Unique ID.
22 *
23 * @var integer
24 */
25 public $form_id = 0;
26
27 /**
28 * Form post data after submit.
29 *
30 * @var array
31 */
32 public $form_post_data = array();
33
34 /**
35 * Default form block attribute values.
36 *
37 * @var array
38 */
39 public $default_attrs = array();
40
41 /**
42 * GhostKit_Form_Block constructor.
43 */
44 public function __construct() {
45 add_action( 'template_redirect', array( $this, 'get_post_data' ) );
46 add_action( 'wp_footer', array( $this, 'reset_post_data' ) );
47
48 add_action( 'init', array( $this, 'init' ) );
49
50 add_action( 'gkt_assets_store', array( $this, 'assets_store' ) );
51
52 add_action( 'gkt_form_email_before_send', array( $this, 'mail_before_send' ) );
53 add_action( 'gkt_form_email_after_send', array( $this, 'mail_after_send' ) );
54
55 add_filter( 'render_block', array( $this, 'maybe_submit_form' ), 10, 2 );
56 }
57
58 /**
59 * Save post data and redirect after form submitted.
60 */
61 public function get_post_data() {
62 if ( ! is_admin() && ! session_id() ) {
63 session_start();
64 }
65
66 // phpcs:disable
67 if ( ! is_admin() && isset( $_POST['ghostkit_form_id'] ) ) {
68 $_SESSION['ghostkit_form_submit_post'] = $_POST;
69 wp_redirect( $_SERVER['REQUEST_URI'] );
70 exit;
71 }
72 // phpcs:enable
73
74 if ( isset( $_SESSION['ghostkit_form_submit_post'] ) ) {
75 $this->form_post_data = $_SESSION['ghostkit_form_submit_post'];
76 }
77 }
78
79 /**
80 * Reset post data.
81 */
82 public function reset_post_data() {
83 if ( ! empty( $this->form_post_data ) ) {
84 $this->form_post_data = array();
85 }
86 if ( isset( $_SESSION['ghostkit_form_submit_post'] ) ) {
87 unset( $_SESSION['ghostkit_form_submit_post'] );
88 }
89 }
90
91 /**
92 * Init.
93 */
94 public function init() {
95 if ( ! function_exists( 'register_block_type' ) ) {
96 return;
97 }
98
99 $from_email = '';
100 $admin_email = get_option( 'admin_email' );
101 $blogname = get_option( 'blogname' );
102
103 // phpcs:ignore
104 if ( isset( $_SERVER[ 'SERVER_NAME' ] ) ) {
105 // phpcs:ignore
106 $sitename = strtolower( $_SERVER[ 'SERVER_NAME' ] );
107 } else {
108 $site_url = site_url();
109 $site_url_parts = wp_parse_url( $site_url );
110 $sitename = $site_url_parts['host'];
111 }
112
113 if ( substr( $sitename, 0, 4 ) === 'www.' ) {
114 $sitename = substr( $sitename, 4 );
115 }
116
117 if ( strpbrk( $admin_email, '@' ) === '@' . $sitename ) {
118 $from_email = $admin_email;
119 } else {
120 $from_email = 'wordpress@' . $sitename;
121 }
122
123 $this->default_attrs = array(
124 'mailAllow' => true,
125 'mailTo' => $admin_email,
126 'mailSubject' => $blogname . ' "{field_subject}"',
127 'mailFrom' => '"' . $blogname . '" <' . $from_email . '>',
128 'mailReplyTo' => '{field_email}',
129 'mailMessage' => '{all_fields}',
130 'confirmationType' => 'message',
131 'confirmationMessage' => esc_html__( 'Thank you for contacting us! We will be in touch with you shortly.', 'ghostkit' ),
132 );
133
134 register_block_type(
135 'ghostkit/form',
136 array(
137 'render_callback' => array( $this, 'block_render' ),
138 'attributes' => array(
139 'mailAllow' => array(
140 'type' => 'boolean',
141 'default' => $this->default_attrs['mailAllow'],
142 ),
143 'mailTo' => array(
144 'type' => 'string',
145 'default' => $this->default_attrs['mailTo'],
146 ),
147 'mailSubject' => array(
148 'type' => 'string',
149 'default' => $this->default_attrs['mailSubject'],
150 ),
151 'mailFrom' => array(
152 'type' => 'string',
153 'default' => $this->default_attrs['mailFrom'],
154 ),
155 'mailReplyTo' => array(
156 'type' => 'string',
157 'default' => $this->default_attrs['mailReplyTo'],
158 ),
159 'mailMessage' => array(
160 'type' => 'string',
161 'default' => $this->default_attrs['mailMessage'],
162 ),
163
164 'confirmationType' => array(
165 'type' => 'string',
166 'default' => $this->default_attrs['confirmationType'],
167 ),
168 'confirmationMessage' => array(
169 'type' => 'string',
170 'default' => $this->default_attrs['confirmationMessage'],
171 ),
172 'confirmationRedirect' => array(
173 'type' => 'string',
174 ),
175
176 'className' => array(
177 'type' => 'string',
178 ),
179 ),
180 )
181 );
182 }
183
184 /**
185 * Register gutenberg block output
186 *
187 * @param array $attributes - block attributes.
188 * @param string $inner_blocks - inner blocks.
189 *
190 * @return string
191 */
192 public function block_render( $attributes, $inner_blocks ) {
193 ob_start();
194
195 $class = 'ghostkit-form';
196
197 if ( isset( $attributes['className'] ) ) {
198 $class .= ' ' . $attributes['className'];
199 }
200
201 $form_slug = 'ghostkit_form_' . $this->form_id;
202 $form_id = 'gkt_form_' . hash( 'crc32b', $form_slug );
203
204 $this->form_id += 1;
205
206 $url = add_query_arg( array() );
207 $frag = strstr( $url, '#' );
208
209 if ( $frag ) {
210 $url = substr( $url, 0, -strlen( $frag ) );
211 }
212
213 $url .= '#' . $form_id;
214
215 // Add unique slug to id and for attributes.
216 $inner_blocks = str_replace( 'id="', 'id="' . $form_id . '_', $inner_blocks );
217 $inner_blocks = str_replace( 'for="', 'for="' . $form_id . '_', $inner_blocks );
218
219 // Google reCaptcha.
220 $recaptcha_site_key = get_option( 'ghostkit_google_recaptcha_api_site_key' );
221 $recaptcha_secret_key = get_option( 'ghostkit_google_recaptcha_api_secret_key' );
222
223 ?>
224
225 <div class="<?php echo esc_attr( $class ); ?>" id="<?php echo esc_attr( $form_id ); ?>">
226 <form method="POST" name="ghostkit-form" action="<?php echo esc_url( $url ); ?>">
227 <?php
228 // phpcs:ignore
229 echo do_blocks( $inner_blocks );
230
231 // Add `__` prefix to prevent conflict with form id attribute duplicate.
232 wp_nonce_field( 'ghostkit_form', '__' . $form_id );
233 ?>
234 <input type="hidden" name="ghostkit_form_id" value="<?php echo esc_attr( $form_id ); ?>">
235 <?php
236 if ( $recaptcha_site_key && $recaptcha_secret_key ) {
237 ?>
238 <input type="hidden" name="ghostkit_form_google_recaptcha" />
239 <?php
240 }
241 ?>
242 </form>
243 </div>
244
245 <?php
246
247 return ob_get_clean();
248 }
249
250 /**
251 * Submit form and replace Form block output.
252 *
253 * @param string $block_content - block content.
254 * @param array $block - block attributes.
255 *
256 * @return string
257 */
258 public function maybe_submit_form( $block_content, $block ) {
259 if ( ! isset( $block['blockName'] ) || 'ghostkit/form' !== $block['blockName'] ) {
260 return $block_content;
261 }
262
263 $form_id = '';
264
265 preg_match( '/<input type="hidden" name="ghostkit_form_id" value="(\w+)"/', $block_content, $parse_form_id );
266
267 if ( $parse_form_id && isset( $parse_form_id[1] ) && $parse_form_id[1] ) {
268 $form_id = $parse_form_id[1];
269 }
270
271 if ( ! $form_id ) {
272 return $block_content;
273 }
274
275 $attributes = array_merge(
276 $this->default_attrs,
277 $block['attrs']
278 );
279
280 $class = 'ghostkit-form';
281
282 if ( isset( $attributes['className'] ) ) {
283 $class .= ' ' . $attributes['className'];
284 }
285
286 $success = false;
287 $errors = array();
288 $new_content = '';
289
290 // Form send.
291 if ( isset( $this->form_post_data[ '__' . $form_id ] ) ) {
292 $nonce = sanitize_text_field( wp_unslash( $this->form_post_data[ '__' . $form_id ] ) );
293
294 if ( wp_verify_nonce( $nonce, 'ghostkit_form' ) ) {
295 // validate Google reCaptcha.
296 if ( ! $this->verify_recaptcha() ) {
297 $errors[] = esc_html__( 'Google reCaptcha form verification failed.', 'ghostkit' );
298 }
299
300 if ( ! count( $errors ) ) {
301 $success = true;
302
303 if ( $attributes['mailAllow'] ) {
304 do_action( 'gkt_form_email_before_send', $form_id, $attributes );
305
306 $success = $this->process_mail( $attributes );
307
308 do_action( 'gkt_form_email_after_send', $form_id, $attributes );
309 }
310
311 if ( ! $success ) {
312 $error = error_get_last();
313 $errors[] = isset( $error['message'] ) ? $error['message'] : esc_html__( 'Something went wrong while trying to send the form.', 'ghostkit' );
314 }
315 }
316 } else {
317 $errors[] = esc_html__( 'Something went wrong while trying to send the form.', 'ghostkit' );
318 }
319
320 $this->reset_post_data();
321 }
322
323 // Form submit errors.
324 if ( ! empty( $errors ) ) {
325 ob_start();
326 ?>
327 <div class="ghostkit-alert ghostkit-alert-form ghostkit-alert-form-error"><div class="ghostkit-alert-content">
328 <?php
329 foreach ( $errors as $error ) {
330 echo '<p>' . esc_html( $error ) . '</p>';
331 }
332 ?>
333 </div></div>
334 <?php
335 $new_content = ob_get_clean();
336
337 // Form submit success.
338 } elseif ( $success ) {
339 ob_start();
340 if ( 'redirect' === $attributes['confirmationType'] ) {
341 ?>
342 <div class="ghostkit-alert ghostkit-alert-form ghostkit-alert-form-success"><div class="ghostkit-alert-content"><p>
343 <?php
344 echo wp_kses_post(
345 sprintf(
346 // translators: %s - redirect link.
347 __( 'Your form is successfully submitted. Redirecting to %s...', 'ghostkit' ),
348 '<a href="' . esc_url( $attributes['confirmationRedirect'] ) . '">' . esc_url( $attributes['confirmationRedirect'] ) . '</a>'
349 )
350 );
351 ?>
352 </p></div></div>
353 <script>
354 setTimeout( () => {
355 window.location.href = "<?php echo esc_url( $attributes['confirmationRedirect'] ); ?>";
356 }, 3000 );
357 </script>
358 <?php
359 } else {
360 ?>
361 <div class="ghostkit-alert ghostkit-alert-form ghostkit-alert-form-success"><div class="ghostkit-alert-content"><p>
362 <?php echo wp_kses_post( $attributes['confirmationMessage'] ); ?>
363 </p></div></div>
364 <?php
365 }
366 $new_content = ob_get_clean();
367 }
368
369 if ( $new_content ) {
370 ob_start();
371 ?>
372 <div class="<?php echo esc_attr( $class ); ?>" id="<?php echo esc_attr( $form_id ); ?>">
373 <?php echo $new_content; // phpcs:ignore ?>
374 </div>
375 <?php
376 return ob_get_clean();
377 }
378
379 return $block_content;
380 }
381
382 /**
383 * Add Alert block assets.
384 *
385 * @param string $name - asset name.
386 */
387 public function assets_store( $name ) {
388 if ( 'ghostkit-block-form' === $name ) {
389 GhostKit_Assets::store_used_assets( 'ghostkit-block-alert', true, 'style' );
390 GhostKit_Assets::store_used_assets( 'ghostkit-block-alert', true, 'script' );
391 GhostKit_Assets::store_used_assets( 'ghostkit-block-button', true, 'style' );
392 GhostKit_Assets::store_used_assets( 'ghostkit-block-button', true, 'script' );
393 }
394 }
395
396 /**
397 * Verify Google reCaptcha.
398 *
399 * @return bool
400 */
401 private function verify_recaptcha() {
402 $recaptcha_secret_key = get_option( 'ghostkit_google_recaptcha_api_secret_key' );
403 $recaptcha_site_key = get_option( 'ghostkit_google_recaptcha_api_site_key' );
404
405 // no captcha enabled.
406 if ( ! $recaptcha_secret_key || ! $recaptcha_site_key ) {
407 return true;
408 }
409
410 // phpcs:disable
411 if ( ! isset( $this->form_post_data['ghostkit_form_google_recaptcha'] ) ) {
412 return false;
413 }
414
415 $token = sanitize_text_field( wp_unslash( $this->form_post_data['ghostkit_form_google_recaptcha'] ) );
416 // phpcs:enable
417
418 // empty token.
419 if ( ! $token ) {
420 return false;
421 }
422
423 $verify_token_request = wp_remote_post(
424 'https://www.google.com/recaptcha/api/siteverify',
425 array(
426 'timeout' => 30,
427 'body' => array(
428 'secret' => $recaptcha_secret_key,
429 'response' => $token,
430 ),
431 )
432 );
433
434 if ( is_wp_error( $verify_token_request ) ) {
435 return false;
436 }
437
438 $response = wp_remote_retrieve_body( $verify_token_request );
439
440 if ( is_wp_error( $response ) ) {
441 return false;
442 }
443
444 $response = json_decode( $response, true );
445
446 if ( ! isset( $response['success'] ) ) {
447 return false;
448 }
449
450 return $response['success'];
451 }
452
453 /**
454 * Template string with POST data.
455 *
456 * @param String $string - string for template.
457 *
458 * @return string
459 */
460 public function template( $string ) {
461 $all_fields = '';
462
463 // phpcs:ignore
464 foreach ( (array) $this->form_post_data as $name => $val ) {
465 if ( is_array( $val ) && isset( $val['value'] ) ) {
466 $sanitized_label = isset( $val['label'] ) ? sanitize_text_field( wp_unslash( $val['label'] ) ) : '';
467 $sanitized_val = '';
468
469 if ( is_array( $val['value'] ) ) {
470 foreach ( $val['value'] as $val ) {
471 $sanitized_val .= '<li>' . sanitize_textarea_field( wp_unslash( $val ) ) . '</li>';
472 }
473 $sanitized_val = '<ul>' . $sanitized_val . '</ul>';
474 } else {
475 $sanitized_val = sanitize_textarea_field( wp_unslash( $val['value'] ) );
476
477 // Name field support.
478 if ( isset( $val['middle'] ) ) {
479 $sanitized_val .= ' ' . sanitize_textarea_field( wp_unslash( $val['middle'] ) );
480 }
481 if ( isset( $val['last'] ) ) {
482 $sanitized_val .= ' ' . sanitize_textarea_field( wp_unslash( $val['last'] ) );
483 }
484 }
485
486 $string = str_replace( "{{$name}}", $sanitized_val, $string );
487
488 $all_fields .= '
489 <table role="presentation" border="0" cellpadding="0" cellspacing="0" class="field-row"><tbody>
490 <tr><td class="field-row-label">' . ( $sanitized_label ? ( '<strong>' . $sanitized_label . '</strong>' ) : '' ) . '</td></tr>
491 <tr><td class="field-row-value">' . wpautop( $sanitized_val ) . '</td></tr>
492 </tbody></table>
493 ';
494 }
495 }
496
497 $string = str_replace( '{all_fields}', $all_fields, $string );
498
499 return $string;
500 }
501
502 /**
503 * Process email using wp_mail function.
504 *
505 * @param array $attributes - Form block attributes.
506 *
507 * @return boolean
508 */
509 public function process_mail( $attributes ) {
510 // Template all attributes.
511 foreach ( $attributes as $k => $attr ) {
512 if ( is_string( $attr ) ) {
513 $attributes[ $k ] = $this->template( $attr );
514 }
515 }
516
517 // Prepare headers.
518 $headers = array(
519 'Content-Type: text/html; charset=utf-8',
520 "From: {$attributes['mailFrom']}",
521 "Return-Path: {$attributes['mailTo']}",
522 "Reply-To: {$attributes['mailReplyTo']}",
523 );
524
525 // Prepare message.
526 $message = $this->get_mail_html( $attributes );
527
528 return wp_mail( $attributes['mailTo'], $attributes['mailSubject'], $message, $headers );
529 }
530
531 /**
532 * Get mail HTML template.
533 *
534 * @param array $attributes - From block attributes.
535 *
536 * @return string
537 */
538 public function get_mail_html( $attributes ) {
539 ob_start();
540
541 include ghostkit()->plugin_path . 'gutenberg/blocks/form/mail-template/index.php';
542
543 return ob_get_clean();
544 }
545
546 /**
547 * Mail before send.
548 */
549 public function mail_before_send() {
550 add_filter( 'wp_mail_content_type', array( $this, 'get_content_type' ) );
551 }
552
553 /**
554 * Mail after send.
555 */
556 public function mail_after_send() {
557 remove_filter( 'wp_mail_content_type', array( $this, 'get_content_type' ) );
558 }
559
560 /**
561 * Change wp_mail content type to HTML.
562 *
563 * @return string
564 */
565 public function get_content_type() {
566 return 'text/html';
567 }
568 }
569 new GhostKit_Form_Block();
570