start_buffer(); // Nonce verification isn't used as it's not a login form but can be enabled with a filter. Note that caching the page will cause the nonce to fail after a cetain amount of time. if ( apply_filters( 'kadence_blocks_form_verify_nonce', false ) && ! check_ajax_referer( 'kb_form_nonce', '_kb_form_verify', false ) ) { $this->process_bail( __( 'Submission rejected, invalid security token. Reload the page and try again.', 'kadence-blocks' ), __( 'Token invalid', 'kadence-blocks' ) ); } $post_id = sanitize_text_field( wp_unslash( $_POST['_kb_adv_form_post_id'] ) ); $form_args = $this->get_form( $post_id ); $messages = $this->get_messages( $form_args['attributes'] ); // Check Recaptcha. if ( self::$captcha_attrs !== false ) { $captcha_settings = new Kadence_Blocks_Form_Captcha_Settings( self::$captcha_attrs ); if ( $captcha_settings->is_valid ) { $captcha_verify = new Kadence_Blocks_Form_Captcha_Verify( $captcha_settings ); $valid = false; switch ( $captcha_settings->service ) { case 'googlev3': $token = ! empty( $_POST['recaptcha_response'] ) ? $_POST['recaptcha_response'] : ''; $valid = $captcha_verify->verify_google( $token ); break; case 'googlev2': $token = ! empty( $_POST['g-recaptcha-response'] ) ? $_POST['g-recaptcha-response'] : ''; $valid = $captcha_verify->verify_google( $token ); break; case 'turnstile': $token = ! empty( $_POST['cf-turnstile-response'] ) ? $_POST['cf-turnstile-response'] : ''; $valid = $captcha_verify->verify_turnstile( $token ); break; case 'hcaptcha': $token = ! empty( $_POST['h-captcha-response'] ) ? $_POST['h-captcha-response'] : ''; $valid = $captcha_verify->verify_hcaptcha( $token ); break; } if ( ! $valid ) { $this->process_bail( $messages['recaptchaerror'], __( 'CAPTCHA Failed', 'kadence-blocks' ) ); } unset( $_POST['recaptcha_response'], $_POST['g-recaptcha-response'], $_POST['cf-turnstile-response'], $_POST['h-captcha-response'] ); } } $processed_fields = apply_filters( 'kadence_blocks_advanced_form_processed_fields', $this->process_fields( $form_args['fields'] ) ); $form_args = apply_filters( 'kadence_blocks_advanced_form_form_args', $form_args, $processed_fields, $post_id ); $submission_rejected = apply_filters( 'kadence_blocks_advanced_form_submission_reject', false, $form_args, $processed_fields, $post_id ); if ( $submission_rejected ) { $rejection_message = apply_filters( 'kadence_blocks_advanced_form_submission_reject_message', __( 'Submission rejected.', 'kadence-blocks' ), $form_args, $processed_fields, $post_id ); $this->process_bail( $rejection_message, $rejection_message ); } do_action( 'kadence_blocks_advanced_form_submission', $form_args, $processed_fields, $post_id ); $submission_results = $this->after_submit_actions( $form_args, $processed_fields, $post_id ); if ( self::$redirect ) { $final_data['redirect'] = self::$redirect; } if ( isset( $form_args['attributes']['submitHide'] ) && true == $form_args['attributes']['submitHide'] ) { $final_data['hide'] = true; } $success = isset( $submission_results['success'] ) && $submission_results['success']; $final_data['submissionResults'] = $submission_results; $success = apply_filters( 'kadence_blocks_advanced_form_submission_success', $success, $form_args, $processed_fields, $post_id, $submission_results ); $messages = apply_filters( 'kadence_blocks_advanced_form_submission_messages', $messages, $form_args, $processed_fields, $post_id, $submission_results ); if ( ! $success ) { $this->process_bail( $messages['error'], __( 'Third Party Failed', 'kadence-blocks' ) ); } else { $final_data['html'] = '
' . $messages['success'] . '
'; $this->send_json( $final_data ); } } else { $this->process_bail( __( 'Submission failed', 'kadence-blocks' ), __( 'No Data', 'kadence-blocks' ) ); } } /** * Sanitize the field * * @param string $field_type the field type. * @param mixed $value the field value. */ private function sanitize_field( $field_type, $value, $multi_select = false ) { switch ( $field_type ) { case 'text': case 'tel': case 'password': case 'hidden': case 'search': case 'select': $value = ( $multi_select && is_array( $value ) ? sanitize_text_field( implode( ', ', $value ) ) : sanitize_text_field( $value ) ); break; case 'checkbox': $value = ( is_array( $value ) ? sanitize_text_field( implode( ', ', $value ) ) : sanitize_text_field( $value ) ); break; case 'radio': $value = ( is_array( $value ) ? sanitize_text_field( implode( ', ', $value ) ) : sanitize_text_field( $value ) ); break; case 'url': $value = esc_url_raw( trim( $value ) ); break; case 'textarea': $value = sanitize_textarea_field( $value ); break; case 'email': $value = sanitize_email( trim( $value ) ); break; case 'accept': $value = !empty( $value ) ? esc_html__( 'Accept', 'kadence-blocks' ) : esc_html__( 'Did not accept', 'kadence-blocks' ); break; default: /** * Sanitize field value. * Filters the value of the form field for sanitization purpose. * The dynamic portion of the hook name, `$field_type`, refers to the field type. * * @param string $value The field value. */ $value = apply_filters( "kadence_blocks_form_sanitize_{$field_type}", $value ); } return $value; } /** * Process the submit actions. * * @param array $form_args the form args. * @param array $processed_fields the processed fields. * @param int $post_id the post id. */ public function after_submit_actions( $form_args, $processed_fields, $post_id ) { $submission_results = array( 'success' => true ); $actions = apply_filters( 'kadence_blocks_advanced_form_actions', isset( $form_args['attributes']['actions'] ) ? $form_args['attributes']['actions'] : array( 'email' ), $form_args, $processed_fields, $post_id ); $submit_actions = new Kadence_Blocks_Advanced_Form_Submit_Actions( $form_args, $processed_fields, $post_id ); foreach ( $actions as $action ) { switch ( $action ) { case 'email': $submit_actions->email(); break; case 'redirect': if ( isset( $form_args['attributes']['redirect'] ) && ! empty( trim( $form_args['attributes']['redirect'] ) ) ) { self::$redirect = apply_filters( 'kadence_blocks_advanced_form_redirect', trim( $form_args['attributes']['redirect'] ), $form_args, $processed_fields, $post_id ); } break; case 'mailerlite': $submit_actions->mailerlite(); break; case 'fluentCRM': $submit_actions->fluentCRM(); break; } } $submission_results = apply_filters( 'kadence_advanced_form_actions', $submission_results, $actions, $form_args, $processed_fields, $post_id ); return $submission_results; } /** * Process the uploads into arrays. * * @param array $file_post. */ public function rearrange_array_files( $file_post ) { $is_multi = is_array( $file_post['name'] ); $file_count = $is_multi ? count( $file_post['name'] ) : 1; $file_keys = array_keys( $file_post ); $file_ary = array(); for ( $i = 0; $i < $file_count; $i++ ) { foreach ( $file_keys as $key ) { if ( $is_multi ) { $file_ary[ $i ][ $key ] = $file_post[ $key ][ $i ]; } else { $file_ary[ $i ][ $key ] = $file_post[ $key ]; } } } return $file_ary; } /** * Process the fields * * @param array $fields the fields. */ public function process_fields( $fields ) { $processed_fields = []; $field_errors = []; foreach ( $fields as $index => $field ) { $expected_field = ! empty( $field['inputName'] ) ? $field['inputName'] : 'field' . $field['uniqueID']; // Skip proccessing this field if it's misssing (usually because hidden frontend). if ( ( ! isset( $_POST[ $expected_field ] ) || ( isset( $_POST[ $expected_field ] ) && $_POST[ $expected_field ] === '' ) ) && empty( $_FILES[ $expected_field ] ) ) { if ( ! empty( $field['required'] ) && $field['required'] ) { if ( ! empty( $field['kadenceFieldConditional']['conditionalData']['enable'] ) ) { continue; } else { $required_message = ! empty( $field['required_message'] ) ? $field['required_message'] : __( 'Missing a required field', 'kadence-blocks' ); $field_errors[] = [ 'message' => $required_message, 'field' => $expected_field, ]; continue; } } else { continue; } } $value = $this->sanitize_field( $field['type'], isset( $_POST[ $expected_field ] ) ? $_POST[ $expected_field ] : '', empty( $field['multiSelect'] ) ? false : $field['multiSelect'] ); // Fail if this field is empty and is required. Note the strict comparison to empty string. if ( $value === '' && ! empty( $field['required'] ) && $field['required'] && $field['type'] !== 'file' && $field['type'] !== 'number' ) { $required_message = ! empty( $field['required_message'] ) ? $field['required_message'] : __( 'Missing a required field', 'kadence-blocks' ); $field_errors[] = [ 'message' => $required_message, 'field' => $expected_field, ]; continue; } // Fail if this field is number and required and value is not numeric. if ( ! empty( $field['required'] ) && $field['required'] && ! is_numeric( $value ) && $field['type'] === 'number' ) { $required_message = ! empty( $field['required_message'] ) ? $field['required_message'] : __( 'Missing a required field', 'kadence-blocks' ); $field_errors[] = [ 'message' => $required_message, 'field' => $expected_field, ]; continue; } // If field is file, verify and process the file. $file_array = []; $file_name_array = []; if ( $field['type'] === 'file' ) { // Skip file processing if we already have errors. if ( ! empty( $field_errors ) ) { continue; } // File required & skipped. if ( isset( $_FILES[ $expected_field ] ) ) { if ( empty( $file['size'] ) && ! empty( $field['required'] ) && $field['required'] ) { } $post_file = $this->rearrange_array_files( $_FILES[ $expected_field ] ); if ( is_array( $post_file ) ) { $file_count = count( $post_file ); $max_count = ! empty( $field['multipleLimit'] ) ? absint( $field['multipleLimit'] ) : 5; if ( isset( $field['multiple'] ) && $field['multiple'] && $file_count > $max_count ) { $field_errors[] = [ 'message' => __( 'Trying to include too many files.', 'kadence-blocks' ), 'field' => $expected_field, 'type' => 'custom', ]; continue; } foreach ( $post_file as $file ) { $file_name_array[] = $file['name']; if ( empty( $file['size'] ) && ! empty( $field['required'] ) && $field['required'] ) { $required_message = ! empty( $field['required_message'] ) ? $field['required_message'] : __( 'Missing a required field', 'kadence-blocks' ); $field_errors[] = [ 'message' => $required_message, 'field' => $expected_field, ]; continue 2; // Skip to next field. } else if ( empty( $file['size'] ) ) { continue; } $max_upload_size_mb = empty( $field['maxSizeMb'] ) ? 10 : $field['maxSizeMb']; $max_upload_size_bytes = $max_upload_size_mb * pow( 1024, 2 ); // Is file too big. if ( $file['size'] > $max_upload_size_bytes ) { $field_errors[] = [ 'message' => __( 'File too large', 'kadence-blocks' ), 'field' => $expected_field, 'type' => 'custom', ]; continue 2; // Skip to next field. } if ( ! is_uploaded_file( $file['tmp_name'] ) ) { $field_errors[] = [ 'message' => __( 'File could not be uploaded', 'kadence-blocks' ), 'field' => $expected_field, 'type' => 'custom', ]; continue 2; // Skip to next field. } $allowed_file_categories = empty( $field['allowedTypes'] ) ? [ 'images' ] : $field['allowedTypes']; $allowed_file_mimes = apply_filters( 'kadence_form_allowed_mime_types', $this->get_allowed_mimes( $allowed_file_categories ), $field ); $file_size = filesize( $file['tmp_name'] ); // Check if multisite has a quota. if ( is_multisite() ) { require_once ABSPATH . 'wp-includes/ms-functions.php'; require_once ABSPATH . 'wp-admin/includes/ms.php'; $space = get_upload_space_available(); if ( $space < $file_size || upload_is_user_over_quota( false ) ) { $field_errors[] = [ 'message' => __( 'Not enough disk quota on this website.', 'kadence-blocks' ), 'field' => $expected_field, 'type' => 'custom', ]; continue 2; // Skip to next field. } } if ( ! function_exists( 'wp_handle_upload' ) ) { require_once ABSPATH . 'wp-admin/includes/file.php'; } add_filter( 'kb_process_advanced_form_submit_prefilter', [ $this, 'override_upload_directory' ] ); $file_upload = wp_handle_upload( $file, [ 'action' => 'kb_process_advanced_form_submit', 'unique_filename_callback' => [ $this, 'set_custom_upload_unique_filename' ], 'test_form' => false, 'test_type' => true, 'mimes' => $allowed_file_mimes, ] ); if ( isset( $file_upload['url'] ) ) { $this->add_htaccess_to_uploads_root(); $file_array[] = $file_upload['url']; } else { if ( ! empty( $file_upload['error'] ) ) { $field_errors[] = [ 'message' => $file_upload['error'], 'field' => $expected_field, ]; } else { $field_errors[] = [ 'message' => __( 'Failed to upload file', 'kadence-blocks' ), 'field' => $expected_field, 'type' => 'custom', ]; } continue 2; // Skip to next field. } } } } } $processed_fields[] = [ 'label' => ( ! empty( $field['label'] ) ? strip_tags( $field['label'] ) : '' ), 'type' => $field['type'], 'required' => empty( $field['required'] ) ? false : $field['required'], 'value' => 'file' === $field['type'] ? implode( ', ', $file_array ) : $value, 'uniqueID' => $field['uniqueID'], 'name' => $expected_field, 'file_name' => 'file' === $field['type'] ? implode( ', ', $file_name_array ) : '', ]; } // If we have any field errors, process_bail with all errors. if ( ! empty( $field_errors ) ) { $error_message = implode( ' ', array_unique( array_column( $field_errors, 'message' ) ) ); $this->process_bail( __( 'Submission Failed', 'kadence-blocks' ), $error_message, $field_errors ); } return $processed_fields; } /** * Bail out something isn't correct. * * @param string $error Error to display. * @param string $note Note to show in console. * @param array $field_errors Array of field errors with message and field name. */ public function process_bail( $error, $note, $field_errors = null ) { $notices = []; $notices['error']['note'] = $error; $out = [ 'html' => $this->html_from_notices( $notices ), 'console' => $note, 'fieldErrors' => $field_errors, 'message' => $error, ]; $this->send_json( $out, true ); } /** * Create HTML string from notices * * @param array $notices Notices to display. * * @return string */ public function html_from_notices( $notices = array() ) { $html = ''; foreach ( $notices as $note_type => $notice ) { if ( ! empty( $notice['note'] ) ) { $html .= '
' . $notice['note'] . '
'; } } return $html; } /** * Starts a flushable buffer */ public function start_buffer() { if ( ! did_action( 'kadence_blocks_forms_buffer_started' ) ) { ob_start(); /** * Runs when buffer is started * * Used to prevent starting buffer twice */ do_action( 'kadence_blocks_forms_buffer_started' ); } } /** * Wrapper for wp_send_json() with output buffering * * @since 1.8.0 * * @param array $data Data to return * @param bool $is_error Optional. Is this an error. Default false. */ public function send_json( $data = array(), $is_error = false ) { $buffer = ob_get_clean(); /** * Runs before Kadence Blocks Forms returns json via wp_send_json() exposes output buffer * * @param string|null $buffer Buffer contents * @param bool $is_error If we think this is an error response or not. */ do_action( 'kadence_blocks_forms_buffer_flushed', $buffer, $is_error ); $data['headers_sent'] = headers_sent(); if ( ! $is_error ) { //status_header( 200 ); $data['success'] = true; $data['show_message'] = true; wp_send_json( $data ); } else { wp_send_json_error( $data ); } } /** * Get Allowed Mime Types. * * @param array $categories an array of category names. */ public function get_allowed_mimes( $categories ) { $allowed_mime_types = array(); $document_type = array( 'txt|asc|c|cc|h|srt' => 'text/plain', 'csv' => 'text/csv', 'doc' => 'application/msword', 'pot|pps|ppt' => 'application/vnd.ms-powerpoint', 'xla|xls|xlt|xlw' => 'application/vnd.ms-excel', 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'docm' => 'application/vnd.ms-word.document.macroEnabled.12', 'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template', 'dotm' => 'application/vnd.ms-word.template.macroEnabled.12', 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'xlsm' => 'application/vnd.ms-excel.sheet.macroEnabled.12', 'xlsb' => 'application/vnd.ms-excel.sheet.binary.macroEnabled.12', 'xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template', 'xltm' => 'application/vnd.ms-excel.template.macroEnabled.12', 'xlam' => 'application/vnd.ms-excel.addin.macroEnabled.12', 'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation', 'pptm' => 'application/vnd.ms-powerpoint.presentation.macroEnabled.12', 'ppsx' => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow', 'ppsm' => 'application/vnd.ms-powerpoint.slideshow.macroEnabled.12', 'potx' => 'application/vnd.openxmlformats-officedocument.presentationml.template', 'potm' => 'application/vnd.ms-powerpoint.template.macroEnabled.12', 'ppam' => 'application/vnd.ms-powerpoint.addin.macroEnabled.12', 'sldx' => 'application/vnd.openxmlformats-officedocument.presentationml.slide', 'sldm' => 'application/vnd.ms-powerpoint.slide.macroEnabled.12', 'onetoc|onetoc2|onetmp|onepkg' => 'application/onenote', 'oxps' => 'application/oxps', 'xps' => 'application/vnd.ms-xpsdocument', 'odt' => 'application/vnd.oasis.opendocument.text', 'odp' => 'application/vnd.oasis.opendocument.presentation', 'ods' => 'application/vnd.oasis.opendocument.spreadsheet', 'odg' => 'application/vnd.oasis.opendocument.graphics', 'odc' => 'application/vnd.oasis.opendocument.chart', 'odb' => 'application/vnd.oasis.opendocument.database', 'odf' => 'application/vnd.oasis.opendocument.formula', 'wp|wpd' => 'application/wordperfect', 'key' => 'application/vnd.apple.keynote', 'numbers' => 'application/vnd.apple.numbers', 'pages' => 'application/vnd.apple.pages', ); $mimtypes = array( 'image' => array( 'jpg|jpeg|jpe' => 'image/jpeg', 'gif' => 'image/gif', 'png' => 'image/png', ), 'images' => array( 'jpg|jpeg|jpe' => 'image/jpeg', 'gif' => 'image/gif', 'png' => 'image/png', ), 'pdf' => array( 'pdf' => 'application/pdf', ), 'video' => array( 'mp4|m4v' => 'video/mp4', 'mpeg|mpg|mpe' => 'video/mpeg', 'mov|qt' => 'video/quicktime', 'wmv' => 'video/x-ms-wmv', ), 'audio' => array( 'mp3|m4a|m4b' => 'audio/mpeg', 'aac' => 'audio/aac', 'wav' => 'audio/wav', 'ra|ram' => 'audio/x-realaudio', 'mid|midi' => 'aaudio/midi', 'mka' => 'audio/x-matroska', 'wma' => 'audio/x-ms-wma', 'wax' => 'audio/x-ms-wax', 'ogg|oga' => 'audio/ogg', ), 'documents' => $document_type, 'document' => $document_type, 'design' => array( // New "design" category 'ai' => 'application/postscript', // Adobe Illustrator 'ait' => 'application/postscript', // Adobe Illustrator Template 'eps' => 'application/postscript', // Encapsulated PostScript 'psd' => 'image/vnd.adobe.photoshop', // Adobe Photoshop 'psb' => 'image/vnd.adobe.photoshop', // Adobe Photoshop Large Document Format 'xcf' => 'image/x-xcf', // GIMP File 'svg' => 'image/svg+xml', // Scalable Vector Graphics 'svgz' => 'image/svg+xml', // Gzipped Scalable Vector Graphics ), 'archive' => array( 'zip' => 'application/zip', ), ); foreach ( $categories as $category ) { if ( isset( $mimtypes[ $category ] ) ) { $allowed_mime_types = array_merge( $allowed_mime_types, $mimtypes[ $category ] ); } } return $allowed_mime_types; } /** * Add filter to override the upload directory for form submissions. * * @param array $file the file. */ public function override_upload_directory( $file ) { add_filter( 'upload_dir', array( $this, 'set_custom_upload_directory' ), 10 ); add_filter( 'wp_handle_upload', array( $this, 'remove_set_custom_upload_directory' ), 10, 2 ); return $file; } /** * Set the custom upload directory. * * @param array $param the upload directory params. */ public function set_custom_upload_directory( $param ) { $subfolder = '/kadence_form/' . date( 'Y' ) . '/' . date( 'm' ); $param['url'] = isset( $param['baseurl'] ) ? $param['baseurl'] . $subfolder : $subfolder; $param['path'] = isset( $param['basedir'] ) ? $param['basedir'] . $subfolder : $subfolder; return apply_filters( 'kadence_blocks_advanced_form_upload_directory', $param ); } /** * Remove the filter to override the upload directory for form submissions. * * @param array $fileinfo the file info. * @param array $param the upload directory params. */ public function remove_set_custom_upload_directory( $fileinfo, $param ) { remove_filter( 'upload_dir', array( $this, 'set_custom_upload_directory' ), 10 ); return $fileinfo; } /** * Set custom file name with timestamp included. * * @param string $dir the upload directory. * @param string $name the file name. * @param string $ext the file extension. */ public function set_custom_upload_unique_filename( $dir, $name, $ext ) { $time_name = apply_filters( 'kadence_blocks_advanced_form_upload_file_name', time() . '_' . wp_generate_password( 16, false ) . '.' . $ext, $dir, $name ); return wp_unique_filename( $dir, $time_name ); } /** * Get form details * * @param integer $post_id the form post id. * @param string $form_id the form id. */ private function get_form( $post_id ) { $form_args = array(); $blocks = ''; $post_data = get_post( absint( $post_id ) ); if ( is_object( $post_data ) && 'kadence_form' === $post_data->post_type && 'publish' === $post_data->post_status && empty( $post_data->post_password ) ) { $blocks = parse_blocks( $post_data->post_content ); } // No form field inner blocks found. if ( ! is_array( $blocks ) || empty( $blocks ) || ! isset( $blocks[0]['blockName'] ) || $blocks[0]['blockName'] !== 'kadence/advanced-form' || empty( $blocks[0]['innerBlocks'] ) ) { $this->process_bail( __( 'Submission Failed', 'kadence-blocks' ), __( 'Data not found', 'kadence-blocks' ) ); } $post_meta = get_post_meta( $post_id ); $meta_args = array(); foreach ( $post_meta as $meta_key => $meta_value ) { if ( strpos( $meta_key, '_kad_form_' ) === 0 && isset( $meta_value[0] ) ){ $meta_args[ str_replace( '_kad_form_', '', $meta_key ) ] = maybe_unserialize( $meta_value[0] ); } } $form_args['attributes'] = json_decode( json_encode( $meta_args ), true ); foreach ( $blocks[0]['innerBlocks'] as $block ) { $this->recursively_parse_blocks( $block ); } $form_args['fields'] = self::$fields; return $form_args; } /** * Gets all the field blocks that are in post. * * @access private * * @param string $block The page content content. */ private function recursively_parse_blocks( $block ) { if ( ! is_object( $block ) && is_array( $block ) && isset( $block['blockName'] ) ) { if ( isset( $block['innerBlocks'] ) && ! empty( $block['innerBlocks'] ) && is_array( $block['innerBlocks'] ) ) { foreach ( $block['innerBlocks'] as $inner_block ) { $this->recursively_parse_blocks( $inner_block ); } } else { if ( 'kadence/advanced-form-submit' !== $block['blockName'] && strpos( $block['blockName'], 'kadence/advanced-form-' ) === 0 ) { self::$fields[] = array_merge( $block['attrs'], array( 'type' => str_replace( 'kadence/advanced-form-', '', $block['blockName'] ) ) ); if ( $block['blockName'] === 'kadence/advanced-form-captcha' ) { self::$captcha_attrs = $block['attrs']; } } } } } /** * Get form messages * * @param array $form_attributes the form attributes. */ private function get_messages( $form_attributes ) { $messages = array( 'success' => esc_html__( 'Submission Success, Thanks for getting in touch!', 'kadence-blocks' ), 'error' => esc_html__( 'Submission Failed', 'kadence-blocks' ), 'recaptchaerror' => esc_html__( 'Submission Failed, reCaptcha spam prevention. Please reload your page and try again.', 'kadence-blocks' ), ); if ( empty( $form_attributes['messages'] ) || ! is_array( $form_attributes['messages'] ) ) { return $messages; } foreach ( $form_attributes['messages'] as $key => $message ) { if ( ! empty( $message ) ) { $messages[ $key ] = $message; } } return $messages; } /** * Create .htaccess in uploads folder to prevent PHP execution. * This security precaution exists in case the server was misconfigured to execute unintended file extensions. * * @return void */ public function add_htaccess_to_uploads_root() { $wp_uploads = wp_upload_dir(); $kadence_form_root_upload_dir = $this->get_kadence_form_root_upload_dir(); if ( ! $wp_uploads['error'] ) { $htaccess_file = $wp_uploads['basedir'] . '/'. $kadence_form_root_upload_dir .'/.htaccess'; $content = '# Prevent PHP execution in this folder for all files in case server is misconfigured to execute unintended file extensions. SetHandler none SetHandler default-handler Options -ExecCGI RemoveHandler .cgi .php .php3 .php4 .php5 .phtml .pl .py .pyc .pyo Header set X-Robots-Tag "noindex" '; $content_array = explode( "\n", $content ); $content_array = apply_filters( 'kadence_blocks_form_upload_htaccess_rules', $content_array ); insert_with_markers( $htaccess_file, 'Kadence Blocks', $content_array ); } } /** * Given the direct link to a file, return the url to the downloader. * * @param $file_url * * @return mixed */ public function get_downloader_url( $file_url ) { $kadence_form_root_upload_dir = $this->get_kadence_form_root_upload_dir(); $file_path = explode($kadence_form_root_upload_dir, $file_url, 2); // Couldn't find the root directory just return the url if( !isset( $file_path[1]) ) { return $file_url; } $query_args = array( 'kadence-form-download' => $kadence_form_root_upload_dir . $file_path[1] ); return add_query_arg( $query_args, home_url() ); } /** * Given the direct link to a file, return the url to the downloader. * * @return mixed|string */ public function get_kadence_form_root_upload_dir() { $root_dir = 'kadence_form'; $kadence_form_upload_dir = $this->set_custom_upload_directory( array() ); if( !empty( $kadence_form_upload_dir['path'] ) ){ $upload_dir_parts = explode( '/', $kadence_form_upload_dir['path'] ); $upload_dir_parts = array_values( array_filter($upload_dir_parts) ); $root_dir = $upload_dir_parts[0]; } return $root_dir; } } KB_Ajax_Advanced_Form::get_instance();