plugin_path . 'gutenberg/blocks/form/field-attributes/index.php'; require_once ghostkit()->plugin_path . 'gutenberg/blocks/form/field-label/index.php'; require_once ghostkit()->plugin_path . 'gutenberg/blocks/form/field-description/index.php'; /** * Class GhostKit_Form_Block */ class GhostKit_Form_Block { /** * Unique ID. * * @var integer */ public $form_id = 0; /** * Form post data after submit. * * @var array */ public $form_post_data = array(); /** * Default form block attribute values. * * @var array */ public $default_attrs = array(); /** * GhostKit_Form_Block constructor. */ public function __construct() { add_action( 'template_redirect', array( $this, 'get_post_data' ) ); add_action( 'wp_footer', array( $this, 'reset_post_data' ) ); add_action( 'init', array( $this, 'init' ) ); add_action( 'gkt_form_email_before_send', array( $this, 'mail_before_send' ) ); add_action( 'gkt_form_email_after_send', array( $this, 'mail_after_send' ) ); add_filter( 'render_block', array( $this, 'maybe_submit_form' ), 10, 2 ); } /** * Save post data and redirect after form submitted. */ public function get_post_data() { // phpcs:disable if ( ! is_admin() && isset( $_POST['ghostkit_form_id'] ) ) { $this->form_post_data = $_POST; } // phpcs:enable } /** * Reset post data. */ public function reset_post_data() { if ( ! empty( $this->form_post_data ) ) { $this->form_post_data = array(); } } /** * Init. */ public function init() { $from_email = ''; $admin_email = get_option( 'admin_email' ); $blogname = get_option( 'blogname' ); // phpcs:ignore if ( isset( $_SERVER[ 'SERVER_NAME' ] ) ) { // phpcs:ignore $sitename = strtolower( $_SERVER[ 'SERVER_NAME' ] ); } else { $site_url = site_url(); $site_url_parts = wp_parse_url( $site_url ); $sitename = $site_url_parts['host']; } if ( substr( $sitename, 0, 4 ) === 'www.' ) { $sitename = substr( $sitename, 4 ); } if ( strpbrk( $admin_email, '@' ) === '@' . $sitename ) { $from_email = $admin_email; } else { $from_email = 'wordpress@' . $sitename; } $this->default_attrs = array( 'mailAllow' => true, 'mailTo' => $admin_email, 'mailSubject' => $blogname . ' "{field_subject}"', 'mailFrom' => '"' . $blogname . '" <' . $from_email . '>', 'mailReplyTo' => '{field_email}', 'mailMessage' => '{all_fields}', 'confirmationType' => 'message', 'confirmationMessage' => esc_html__( 'Thank you for contacting us! We will be in touch with you shortly.', 'ghostkit' ), ); register_block_type_from_metadata( __DIR__, array( 'render_callback' => array( $this, 'block_render' ), 'attributes' => array( 'mailAllow' => array( 'type' => 'boolean', 'default' => $this->default_attrs['mailAllow'], ), 'mailTo' => array( 'type' => 'string', 'default' => $this->default_attrs['mailTo'], ), 'mailSubject' => array( 'type' => 'string', 'default' => $this->default_attrs['mailSubject'], ), 'mailFrom' => array( 'type' => 'string', 'default' => $this->default_attrs['mailFrom'], ), 'mailReplyTo' => array( 'type' => 'string', 'default' => $this->default_attrs['mailReplyTo'], ), 'mailMessage' => array( 'type' => 'string', 'default' => $this->default_attrs['mailMessage'], ), 'confirmationType' => array( 'type' => 'string', 'default' => $this->default_attrs['confirmationType'], ), 'confirmationMessage' => array( 'type' => 'string', 'default' => $this->default_attrs['confirmationMessage'], ), 'confirmationRedirect' => array( 'type' => 'string', ), 'className' => array( 'type' => 'string', ), ), ) ); } /** * Register gutenberg block output * * @param array $attributes - block attributes. * @param string $inner_blocks - inner blocks. * * @return string */ public function block_render( $attributes, $inner_blocks ) { $class = 'ghostkit-form'; if ( isset( $attributes['className'] ) ) { $class .= ' ' . $attributes['className']; } $form_slug = 'ghostkit_form_' . $this->form_id; $form_id = 'gkt_form_' . hash( 'crc32b', $form_slug ); $this->form_id += 1; $url = add_query_arg( array() ); $frag = strstr( $url, '#' ); if ( $frag ) { $url = substr( $url, 0, -strlen( $frag ) ); } $url .= '#' . $form_id; // Add unique slug to id and for attributes. $inner_blocks = str_replace( 'id="', 'id="' . $form_id . '_', $inner_blocks ); $inner_blocks = str_replace( 'for="', 'for="' . $form_id . '_', $inner_blocks ); // Google reCaptcha. $recaptcha_site_key = get_option( 'ghostkit_google_recaptcha_api_site_key' ); $recaptcha_secret_key = get_option( 'ghostkit_google_recaptcha_api_secret_key' ); ob_start(); // Honeypot protection. ?> 'POST', 'name' => 'ghostkit-form', 'action' => esc_url( $url ), 'class' => $class, 'id' => $form_id, ) ); return sprintf( '
%2$s
', $wrapper_attributes, $output ); } /** * Submit form and replace Form block output. * * @param string $block_content - block content. * @param array $block - block attributes. * * @return string */ public function maybe_submit_form( $block_content, $block ) { if ( ! isset( $block['blockName'] ) || 'ghostkit/form' !== $block['blockName'] ) { return $block_content; } $form_id = ''; preg_match( '/default_attrs, $block['attrs'] ); $class = 'ghostkit-form'; if ( isset( $attributes['className'] ) ) { $class .= ' ' . $attributes['className']; } $success = false; $errors = array(); $new_content = ''; // Form send. if ( isset( $this->form_post_data[ '__' . $form_id ] ) ) { $nonce = sanitize_text_field( wp_unslash( $this->form_post_data[ '__' . $form_id ] ) ); if ( wp_verify_nonce( $nonce, 'ghostkit_form' ) ) { // check for honeypot. if ( ! $this->verify_honeypot() ) { $errors[] = esc_html__( 'Your actions look suspicious, the form was not submitted.', 'ghostkit' ); } // validate Google reCaptcha. if ( ! $this->verify_recaptcha() ) { $errors[] = esc_html__( 'Google reCaptcha form verification failed.', 'ghostkit' ); } if ( ! count( $errors ) ) { $success = true; if ( $attributes['mailAllow'] ) { do_action( 'gkt_form_email_before_send', $form_id, $attributes ); $success = $this->process_mail( $attributes ); do_action( 'gkt_form_email_after_send', $form_id, $attributes ); } if ( ! $success ) { $error = error_get_last(); $errors[] = isset( $error['message'] ) ? $error['message'] : esc_html__( 'Something went wrong while trying to send the form.', 'ghostkit' ); } } } else { $errors[] = esc_html__( 'Something went wrong while trying to send the form.', 'ghostkit' ); } $this->reset_post_data(); } // Form submit errors. if ( ! empty( $errors ) ) { ob_start(); ?>
' . esc_html( $error ) . '

'; } ?>

' . esc_url( $attributes['confirmationRedirect'] ) . '' ) ); ?>

remove_hash_from_address_bar(); return ob_get_clean(); } return $block_content; } /** * Verify Honeypot Field. * * @return bool */ private function verify_honeypot() { if ( ! empty( $this->form_post_data['ghostkit_verify_email'] ) ) { return false; } return true; } /** * Verify Google reCaptcha. * * @return bool */ private function verify_recaptcha() { $recaptcha_secret_key = get_option( 'ghostkit_google_recaptcha_api_secret_key' ); $recaptcha_site_key = get_option( 'ghostkit_google_recaptcha_api_site_key' ); // no captcha enabled. if ( ! $recaptcha_secret_key || ! $recaptcha_site_key ) { return true; } if ( ! isset( $this->form_post_data['ghostkit_form_google_recaptcha'] ) ) { return false; } $token = sanitize_text_field( wp_unslash( $this->form_post_data['ghostkit_form_google_recaptcha'] ) ); // empty token. if ( ! $token ) { return false; } $verify_token_request = wp_remote_post( 'https://www.google.com/recaptcha/api/siteverify', array( 'timeout' => 30, 'body' => array( 'secret' => $recaptcha_secret_key, 'response' => $token, ), ) ); if ( is_wp_error( $verify_token_request ) ) { return false; } $response = wp_remote_retrieve_body( $verify_token_request ); if ( is_wp_error( $response ) ) { return false; } $response = json_decode( $response, true ); $threshold = apply_filters( 'gkt_recaptcha_threshold', 0.5 ); $verified = isset( $response['success'] ) && $response['success'] && 'ghostkit' === $response['action'] && $response['score'] >= $threshold; $verified = apply_filters( 'gkt_recaptcha_verify_response', $verified, $response ); return $verified; } /** * Remove hash from address bar when form submitted. * It will solve the problem when you can submit the submitted form data again after page refresh. */ public function remove_hash_from_address_bar() { ?> form_post_data as $name => $val ) { if ( is_array( $val ) && isset( $val['value'] ) ) { $sanitized_label = isset( $val['label'] ) ? sanitize_text_field( wp_unslash( $val['label'] ) ) : ''; $sanitized_val = ''; if ( is_array( $val['value'] ) ) { foreach ( $val['value'] as $val ) { $sanitized_val .= '
  • ' . sanitize_textarea_field( wp_unslash( $val ) ) . '
  • '; } $sanitized_val = ''; } else { $sanitized_val = sanitize_textarea_field( wp_unslash( $val['value'] ) ); // Name field support. if ( isset( $val['middle'] ) ) { $sanitized_val .= ' ' . sanitize_textarea_field( wp_unslash( $val['middle'] ) ); } if ( isset( $val['last'] ) ) { $sanitized_val .= ' ' . sanitize_textarea_field( wp_unslash( $val['last'] ) ); } } $template = str_replace( "{{$name}}", $sanitized_val, $template ); $all_fields .= ' '; } } $template = str_replace( '{all_fields}', $all_fields, $template ); return $template; } /** * Process email using wp_mail function. * * @param array $attributes - Form block attributes. * * @return boolean */ public function process_mail( $attributes ) { // Template all attributes. foreach ( $attributes as $k => $attr ) { if ( is_string( $attr ) ) { $attributes[ $k ] = $this->template( $attr ); } } // Prepare headers. $headers = array( 'Content-Type: text/html; charset=utf-8', "From: {$attributes['mailFrom']}", "Return-Path: {$attributes['mailTo']}", "Reply-To: {$attributes['mailReplyTo']}", ); // Prepare message. $message = $this->get_mail_html( $attributes ); return wp_mail( $attributes['mailTo'], $attributes['mailSubject'], $message, $headers ); } /** * Get mail HTML template. * * @param array $attributes - From block attributes. * * @return string */ public function get_mail_html( $attributes ) { ob_start(); include ghostkit()->plugin_path . 'gutenberg/blocks/form/mail-template/index.php'; return ob_get_clean(); } /** * Mail before send. */ public function mail_before_send() { add_filter( 'wp_mail_content_type', array( $this, 'get_content_type' ) ); } /** * Mail after send. */ public function mail_after_send() { remove_filter( 'wp_mail_content_type', array( $this, 'get_content_type' ) ); } /** * Change wp_mail content type to HTML. * * @return string */ public function get_content_type() { return 'text/html'; } } new GhostKit_Form_Block();