feat: initial ACRIB WordPress deployment
- WordPress 6.9.4 (es_ES) with Kadence theme - Homepage: Hero, La Asociación, Pilares, Beneficios, Eventos, Miembros, Hazte Miembro, Contacto - Brand identity: #13294b navy, #a12932 burgundy, #c69c48 gold - Fonts: Raleway (headings) + Source Sans 3 (body) + Lato (UI) - Plugins: Kadence Blocks, Polylang, Contact Form 7 - Custom CSS with full brand styling and responsive layout - HTTPS enforced via wp-config.php proxy detection
This commit is contained in:
@@ -0,0 +1,119 @@
|
||||
<?php
|
||||
/**
|
||||
* REST API ActiveCampaign controller customized for Kadence Form
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* REST API controller class.
|
||||
*
|
||||
*/
|
||||
class Kadence_ActiveCampaign_REST_Controller extends WP_REST_Controller {
|
||||
|
||||
/**
|
||||
* Include property name.
|
||||
*/
|
||||
const PROP_END_POINT = 'endpoint';
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->namespace = 'kb-activecampaign/v1';
|
||||
$this->rest_base = 'get';
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the routes for the objects of the controller.
|
||||
*
|
||||
* @see register_rest_route()
|
||||
*/
|
||||
public function register_routes() {
|
||||
register_rest_route(
|
||||
$this->namespace,
|
||||
'/' . $this->rest_base,
|
||||
array(
|
||||
array(
|
||||
'methods' => WP_REST_Server::READABLE,
|
||||
'callback' => array( $this, 'get_items' ),
|
||||
'permission_callback' => array( $this, 'get_items_permission_check' ),
|
||||
'args' => $this->get_collection_params(),
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a given request has access to search content.
|
||||
*
|
||||
*
|
||||
* @param WP_REST_Request $request Full details about the request.
|
||||
*
|
||||
* @return true|WP_Error True if the request has search access, WP_Error object otherwise.
|
||||
*/
|
||||
public function get_items_permission_check( $request ) {
|
||||
return current_user_can( 'edit_posts' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a collection of objects.
|
||||
*
|
||||
* @param WP_REST_Request $request Full details about the request.
|
||||
*
|
||||
* @return WP_REST_Response|WP_Error|Array Response object on success, or WP_Error object on failure.
|
||||
*/
|
||||
public function get_items( $request ) {
|
||||
$api_key = get_option( 'kadence_blocks_activecampaign_api_key' );
|
||||
$api_base = get_option( 'kadence_blocks_activecampaign_api_base' );
|
||||
$end_point = $request->get_param( self::PROP_END_POINT );
|
||||
|
||||
$base_url = $api_base . '/api/3/' . $end_point;
|
||||
|
||||
if ( empty( $api_key ) || empty( $api_base ) ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$request_url = add_query_arg( array(
|
||||
'api_secret' => $api_key,
|
||||
), $base_url );
|
||||
|
||||
$request_args = array(
|
||||
'headers' => array(
|
||||
'Api-Token' => $api_key,
|
||||
),
|
||||
);
|
||||
|
||||
$response = wp_safe_remote_get( $request_url, $request_args );
|
||||
|
||||
if ( is_wp_error( $response ) || 200 != (int) wp_remote_retrieve_response_code( $response ) ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$body = json_decode( wp_remote_retrieve_body( $response ), true );
|
||||
|
||||
if ( ! is_array( $body ) ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
return $body;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the query params for the search results collection.
|
||||
*
|
||||
* @return array Collection parameters.
|
||||
*/
|
||||
public function get_collection_params() {
|
||||
$query_params = parent::get_collection_params();
|
||||
|
||||
$query_params[ self::PROP_END_POINT ] = array(
|
||||
'description' => __( 'Actionable endpoint for api call.', 'kadence-blocks' ),
|
||||
'type' => 'string',
|
||||
);
|
||||
|
||||
return $query_params;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,831 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Advanced Form Ajax Handing.
|
||||
*
|
||||
* @package Kadence Blocks
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Main plugin class
|
||||
*/
|
||||
class KB_Ajax_Advanced_Form {
|
||||
|
||||
/**
|
||||
* Instance Control
|
||||
*
|
||||
* @var null
|
||||
*/
|
||||
private static $instance = null;
|
||||
|
||||
private static $redirect = false;
|
||||
|
||||
private static $fields = [];
|
||||
|
||||
private static $captcha_attrs = false;
|
||||
|
||||
/**
|
||||
* Instance Control
|
||||
*/
|
||||
public static function get_instance() {
|
||||
if ( is_null( self::$instance ) ) {
|
||||
self::$instance = new self();
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Class Constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
add_action( 'wp_ajax_kb_process_advanced_form_submit', array( $this, 'process_ajax' ) );
|
||||
add_action( 'wp_ajax_nopriv_kb_process_advanced_form_submit', array( $this, 'process_ajax' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the form submit.
|
||||
*/
|
||||
public function process_ajax() {
|
||||
$final_data = array();
|
||||
|
||||
if ( isset( $_POST['_kb_adv_form_id'] ) && ! empty( $_POST['_kb_adv_form_id'] ) && isset( $_POST['_kb_adv_form_post_id'] ) && ! empty( $_POST['_kb_adv_form_post_id'] ) ) {
|
||||
$this->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'] = '<div class="kb-adv-form-message kb-adv-form-success">' . $messages['success'] . '</div>';
|
||||
$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 .= '<div class="kb-adv-form-message kb-adv-form-warning">' . $notice['note'] . '</div>';
|
||||
}
|
||||
}
|
||||
|
||||
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',
|
||||
'webp' => 'image/webp',
|
||||
),
|
||||
'images' => array(
|
||||
'jpg|jpeg|jpe' => 'image/jpeg',
|
||||
'gif' => 'image/gif',
|
||||
'png' => 'image/png',
|
||||
'webp' => 'image/webp',
|
||||
),
|
||||
'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.
|
||||
<Files *>
|
||||
SetHandler none
|
||||
SetHandler default-handler
|
||||
Options -ExecCGI
|
||||
RemoveHandler .cgi .php .php3 .php4 .php5 .phtml .pl .py .pyc .pyo
|
||||
</Files>
|
||||
<IfModule headers_module>
|
||||
Header set X-Robots-Tag "noindex"
|
||||
</IfModule>';
|
||||
$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();
|
||||
@@ -0,0 +1,308 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class for parsing settings from advanced form captcha block.
|
||||
*/
|
||||
class Kadence_Blocks_Form_Captcha_Settings {
|
||||
|
||||
/**
|
||||
* Public captcha Key
|
||||
*
|
||||
* @var bool|string
|
||||
*/
|
||||
public $public_key = false;
|
||||
|
||||
/**
|
||||
* Secret captcha Key
|
||||
*
|
||||
* @var bool|string
|
||||
*/
|
||||
public $secret_key = false;
|
||||
|
||||
/**
|
||||
* Captcha language
|
||||
*
|
||||
* @var bool|string
|
||||
*/
|
||||
public $language = 'auto';
|
||||
|
||||
/**
|
||||
* Are settings sourced from Kadence Captcha plugin
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $using_kadence_captcha = false;
|
||||
|
||||
/**
|
||||
* Are settings sourced from Kadence blocks globals
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $using_kadence_blocks_settings = true;
|
||||
|
||||
/**
|
||||
* Captcha service
|
||||
* googlev2, googlev3, turnstile, or hcaptcha
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $service;
|
||||
|
||||
/**
|
||||
* Do we have required settings to show & validate captcha
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $is_valid = false;
|
||||
|
||||
public $pass_score = '0.5';
|
||||
|
||||
public $theme = 'light';
|
||||
|
||||
public $size = 'normal';
|
||||
|
||||
// Properties for custom recaptcha notice settings
|
||||
public $hideRecaptcha = false;
|
||||
|
||||
public $showRecaptchaNotice = false;
|
||||
|
||||
public $recaptchaNotice = '';
|
||||
|
||||
public function __construct( $attributes ) {
|
||||
$this->is_using_kadence_captcha_settings( $attributes );
|
||||
$this->is_using_kadence_blocks_settings( $attributes );
|
||||
$this->get_captcha_service( $attributes );
|
||||
$this->get_public_key( $attributes );
|
||||
$this->get_secret_key( $attributes );
|
||||
$this->get_captcha_language( $attributes );
|
||||
$this->get_styles( $attributes );
|
||||
$this->get_notice_settings( $attributes );
|
||||
$this->has_valid_settings();
|
||||
}
|
||||
|
||||
private function has_valid_settings() {
|
||||
if ( ! empty( $this->service ) && ! empty( $this->public_key ) && ! empty( $this->secret_key ) ) {
|
||||
$this->is_valid = true;
|
||||
}
|
||||
}
|
||||
|
||||
private function get_captcha_service( $attributes ) {
|
||||
if ( $this->using_kadence_captcha ) {
|
||||
$key = array(
|
||||
0 => 'googlev2',
|
||||
1 => 'googlev3',
|
||||
2 => 'turnstile'
|
||||
);
|
||||
|
||||
$captcha_key = $this->get_kadence_captcha_stored_value( 'enable_v3' );
|
||||
if ( isset( $key[ $captcha_key ] ) ) {
|
||||
$this->service = $key[ $captcha_key ];
|
||||
}
|
||||
} elseif ( ! empty( $attributes['type'] ) ) {
|
||||
$this->service = $attributes['type'];
|
||||
} else {
|
||||
$this->service = 'googlev2'; // default value from block.json
|
||||
}
|
||||
}
|
||||
|
||||
private function get_captcha_language( $attributes ) {
|
||||
if ( $this->using_kadence_captcha ) {
|
||||
$stored_value = $this->get_kadence_captcha_stored_value( 'recaptcha_lang' );
|
||||
$filtered_value = apply_filters( 'kt_recaptcha_option_value', $stored_value, 'recaptcha_lang' );
|
||||
|
||||
$this->language = ! empty( $filtered_value ) ? $filtered_value : false;
|
||||
} elseif ( $this->using_kadence_blocks_settings && ! empty( get_option( 'kadence_blocks_recaptcha_language' ) ) ) {
|
||||
$this->language = get_option( 'kadence_blocks_recaptcha_language' );
|
||||
} elseif ( isset( $attributes['recaptchaLanguage'] ) ) {
|
||||
$this->language = $attributes['recaptchaLanguage'];
|
||||
}
|
||||
}
|
||||
|
||||
private function is_using_kadence_captcha_settings( $attributes ) {
|
||||
if ( isset( $attributes['useKcSettings'] ) && $attributes['useKcSettings'] ) {
|
||||
$this->using_kadence_captcha = true;
|
||||
} else {
|
||||
$this->using_kadence_captcha = false;
|
||||
}
|
||||
}
|
||||
|
||||
private function is_using_kadence_blocks_settings( $attributes ) {
|
||||
if ( !isset( $attributes['useKbSettings'] ) || ( isset( $attributes['useKbSettings'] ) && $attributes['useKbSettings'] ) ) {
|
||||
$this->using_kadence_blocks_settings = true;
|
||||
} else {
|
||||
$this->using_kadence_blocks_settings = false;
|
||||
}
|
||||
}
|
||||
|
||||
private function get_public_key( $attributes ) {
|
||||
if ( $this->using_kadence_captcha ) {
|
||||
$slug = '';
|
||||
$key = '';
|
||||
|
||||
switch ( $this->service ) {
|
||||
case 'googlev2':
|
||||
$slug = 'kt_re_site_key';
|
||||
break;
|
||||
case 'googlev3':
|
||||
$slug = 'v3_re_site_key';
|
||||
break;
|
||||
case 'turnstile':
|
||||
$slug = 'turnstile_site_key';
|
||||
break;
|
||||
}
|
||||
$key = $this->get_kadence_captcha_stored_value( $slug, '' );
|
||||
} elseif ( ! empty( $this->service ) ) {
|
||||
if ( $this->using_kadence_blocks_settings ) {
|
||||
$option_key = '';
|
||||
switch ( $this->service ) {
|
||||
case 'googlev2':
|
||||
case 'googlev3':
|
||||
$option_key = 'kadence_blocks_recaptcha_site_key';
|
||||
break;
|
||||
case 'turnstile':
|
||||
$option_key = 'kadence_blocks_turnstile_site_key';
|
||||
break;
|
||||
case 'hcaptcha':
|
||||
$option_key = 'kadence_blocks_hcaptcha_site_key';
|
||||
break;
|
||||
}
|
||||
|
||||
$key = get_option( $option_key );
|
||||
} else {
|
||||
switch ( $this->service ) {
|
||||
case 'googlev2':
|
||||
case 'googlev3':
|
||||
$option_key = 'recaptchaSiteKey';
|
||||
break;
|
||||
case 'turnstile':
|
||||
$option_key = 'turnstileSiteKey';
|
||||
break;
|
||||
case 'hcaptcha':
|
||||
$option_key = 'hCaptchaSiteKey';
|
||||
break;
|
||||
}
|
||||
$key = isset( $attributes[ $option_key ] ) ? $attributes[ $option_key ] : '';
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! empty( $key ) ) {
|
||||
$this->public_key = $key;
|
||||
} else {
|
||||
$this->public_key = false;
|
||||
}
|
||||
}
|
||||
|
||||
private function get_secret_key( $attributes ) {
|
||||
if ( $this->using_kadence_captcha ) {
|
||||
$slug = '';
|
||||
|
||||
switch ( $this->service ) {
|
||||
case 'googlev2':
|
||||
$slug = 'kt_re_secret_key';
|
||||
break;
|
||||
case 'googlev3':
|
||||
$slug = 'v3_re_secret_key';
|
||||
break;
|
||||
case 'turnstile':
|
||||
$slug = 'turnstile_secret_key';
|
||||
break;
|
||||
}
|
||||
|
||||
$key = $this->get_kadence_captcha_stored_value( $slug, '' );
|
||||
} elseif ( ! empty( $this->service ) ) {
|
||||
if ( $this->using_kadence_blocks_settings ) {
|
||||
$option_key = '';
|
||||
switch ( $this->service ) {
|
||||
case 'googlev2':
|
||||
case 'googlev3':
|
||||
$option_key = 'kadence_blocks_recaptcha_secret_key';
|
||||
break;
|
||||
case 'turnstile':
|
||||
$option_key = 'kadence_blocks_turnstile_secret_key';
|
||||
break;
|
||||
case 'hcaptcha':
|
||||
$option_key = 'kadence_blocks_hcaptcha_secret_key';
|
||||
break;
|
||||
}
|
||||
$key = get_option( $option_key );
|
||||
} else {
|
||||
switch ( $this->service ) {
|
||||
case 'googlev2':
|
||||
case 'googlev3':
|
||||
$option_key = 'recaptchaSecretKey';
|
||||
break;
|
||||
case 'turnstile':
|
||||
$option_key = 'turnstileSecretKey';
|
||||
break;
|
||||
case 'hcaptcha':
|
||||
$option_key = 'hCaptchaSecretKey';
|
||||
break;
|
||||
}
|
||||
$key = isset( $attributes[ $option_key ] ) ? $attributes[ $option_key ] : '';
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! empty( $key ) ) {
|
||||
$this->secret_key = $key;
|
||||
} else {
|
||||
$this->secret_key = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Pull stored value from Kadence Captcha Plugin
|
||||
* Function pulled directly from that plugin
|
||||
*
|
||||
* @param $key
|
||||
* @param $default
|
||||
*
|
||||
* @return mixed|string
|
||||
*/
|
||||
public function get_kadence_captcha_stored_value( $key, $default = '' ) {
|
||||
// Get all stored values.
|
||||
$stored = ( apply_filters( 'kadence_recaptcha_network', false ) ? get_site_option( 'kt_recaptcha', array() ) : get_option( 'kt_recaptcha', array() ) );
|
||||
|
||||
// Check if value exists in stored values array.
|
||||
if ( ! empty( $stored ) && ! is_array( $stored ) ) {
|
||||
$stored = json_decode( $stored, true );
|
||||
}
|
||||
// Check if value exists in stored values array.
|
||||
if ( ! empty( $stored ) && ( ( isset( $stored[ $key ] ) && '0' == $stored[ $key ] ) || ! empty( $stored[ $key ] ) ) ) {
|
||||
return $stored[ $key ];
|
||||
}
|
||||
|
||||
// Stored value not found, use default value.
|
||||
return $default;
|
||||
}
|
||||
|
||||
private function get_styles( $attributes ) {
|
||||
if ( $this->using_kadence_captcha ) {
|
||||
$this->pass_score = $this->get_kadence_captcha_stored_value( 'v3_pass_score', '0.5' );
|
||||
$this->theme = $this->get_kadence_captcha_stored_value( 'kt_re_theme', 'light' );
|
||||
$this->size = $this->get_kadence_captcha_stored_value( 'kt_re_size', 'normal' );
|
||||
} else {
|
||||
if ( ! empty( $attributes['theme'] ) ) {
|
||||
$this->theme = $attributes['theme'];
|
||||
}
|
||||
|
||||
if ( ! empty( $attributes['size'] ) ) {
|
||||
$this->size = $attributes['size'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get notice settings from attributes
|
||||
private function get_notice_settings( $attributes ) {
|
||||
if ( isset( $attributes['hideRecaptcha'] ) ) {
|
||||
$this->hideRecaptcha = $attributes['hideRecaptcha'];
|
||||
}
|
||||
|
||||
if ( isset( $attributes['showRecaptchaNotice'] ) ) {
|
||||
$this->showRecaptchaNotice = $attributes['showRecaptchaNotice'];
|
||||
}
|
||||
|
||||
if ( isset( $attributes['recaptchaNotice'] ) ) {
|
||||
$this->recaptchaNotice = $attributes['recaptchaNotice'];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class for verifying captcha submissions from advanced form block.
|
||||
*/
|
||||
class Kadence_Blocks_Form_Captcha_Verify {
|
||||
|
||||
/**
|
||||
* @var Kadence_Blocks_Form_Captcha_Settings
|
||||
*/
|
||||
private $captcha_settings;
|
||||
|
||||
public function __construct( $captcha_settings ) {
|
||||
$this->captcha_settings = $captcha_settings;
|
||||
}
|
||||
|
||||
public function verify_google( $token ) {
|
||||
return $this->verify_generic( $token, 'https://www.google.com/recaptcha/api/siteverify' );
|
||||
}
|
||||
|
||||
public function verify_turnstile( $token = '' ) {
|
||||
return $this->verify_generic( $token, 'https://challenges.cloudflare.com/turnstile/v0/siteverify' );
|
||||
}
|
||||
|
||||
public function verify_hcaptcha( $token ) {
|
||||
return $this->verify_generic( $token, 'https://api.hcaptcha.com/siteverify' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check Recaptcha
|
||||
*
|
||||
* @param string $token Recaptcha token.
|
||||
* @param string $url API endpoint for verification.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function verify_generic( $token, $url ) {
|
||||
$secret = $this->captcha_settings->secret_key;
|
||||
|
||||
$args = array(
|
||||
'body' => array(
|
||||
'secret' => $secret,
|
||||
'response' => $token,
|
||||
'remoteip' => $_SERVER['REMOTE_ADDR']
|
||||
),
|
||||
);
|
||||
$verify_request = wp_remote_post( $url, $args );
|
||||
if ( is_wp_error( $verify_request ) ) {
|
||||
return false;
|
||||
}
|
||||
$response = wp_remote_retrieve_body( $verify_request );
|
||||
if ( is_wp_error( $response ) ) {
|
||||
return false;
|
||||
}
|
||||
$response = json_decode( $response, true );
|
||||
|
||||
return isset( $response['success'] ) ? $response['success'] : false;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
/**
|
||||
* Load all the files for Advanced form block.
|
||||
*
|
||||
* @package Kadence Blocks.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
require_once KADENCE_BLOCKS_PATH . 'includes/blocks/class-kadence-blocks-advanced-form-block.php';
|
||||
require_once KADENCE_BLOCKS_PATH . 'includes/blocks/form/class-kadence-blocks-advanced-form-input-block.php';
|
||||
require_once KADENCE_BLOCKS_PATH . 'includes/blocks/form/class-kadence-blocks-text-input-block.php';
|
||||
require_once KADENCE_BLOCKS_PATH . 'includes/blocks/form/class-kadence-blocks-textarea-input-block.php';
|
||||
require_once KADENCE_BLOCKS_PATH . 'includes/blocks/form/class-kadence-blocks-email-input-block.php';
|
||||
require_once KADENCE_BLOCKS_PATH . 'includes/blocks/form/class-kadence-blocks-number-input-block.php';
|
||||
require_once KADENCE_BLOCKS_PATH . 'includes/blocks/form/class-kadence-blocks-hidden-input-block.php';
|
||||
require_once KADENCE_BLOCKS_PATH . 'includes/blocks/form/class-kadence-blocks-date-input-block.php';
|
||||
require_once KADENCE_BLOCKS_PATH . 'includes/blocks/form/class-kadence-blocks-time-input-block.php';
|
||||
require_once KADENCE_BLOCKS_PATH . 'includes/blocks/form/class-kadence-blocks-telephone-input-block.php';
|
||||
require_once KADENCE_BLOCKS_PATH . 'includes/blocks/form/class-kadence-blocks-file-block.php';
|
||||
require_once KADENCE_BLOCKS_PATH . 'includes/blocks/form/class-kadence-blocks-radio-block.php';
|
||||
require_once KADENCE_BLOCKS_PATH . 'includes/blocks/form/class-kadence-blocks-select-block.php';
|
||||
require_once KADENCE_BLOCKS_PATH . 'includes/blocks/form/class-kadence-blocks-checkbox-block.php';
|
||||
require_once KADENCE_BLOCKS_PATH . 'includes/blocks/form/class-kadence-blocks-captcha-block.php';
|
||||
require_once KADENCE_BLOCKS_PATH . 'includes/blocks/form/class-kadence-blocks-accept-block.php';
|
||||
require_once KADENCE_BLOCKS_PATH . 'includes/blocks/form/class-kadence-blocks-submit-block.php';
|
||||
require_once KADENCE_BLOCKS_PATH . 'includes/advanced-form/advanced-form-rest-api.php';
|
||||
require_once KADENCE_BLOCKS_PATH . 'includes/advanced-form/advanced-form-cpt.php';
|
||||
require_once KADENCE_BLOCKS_PATH . 'includes/advanced-form/advanced-form-ajax.php';
|
||||
require_once KADENCE_BLOCKS_PATH . 'includes/advanced-form/advanced-form-submit-actions.php';
|
||||
require_once KADENCE_BLOCKS_PATH . 'includes/advanced-form/activecampaign-rest-api.php';
|
||||
require_once KADENCE_BLOCKS_PATH . 'includes/advanced-form/getresponse-rest-api.php';
|
||||
require_once KADENCE_BLOCKS_PATH . 'includes/advanced-form/advanced-form-captcha-settings.php';
|
||||
require_once KADENCE_BLOCKS_PATH . 'includes/advanced-form/advanced-form-captcha-verify.php';
|
||||
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
class Kadence_Blocks_Form_CPT_Rest_Controller extends WP_REST_Posts_Controller {
|
||||
/**
|
||||
* Registers the routes for the objects of the controller.
|
||||
*
|
||||
* @see register_rest_route()
|
||||
*/
|
||||
public function register_routes() {
|
||||
parent::register_routes();
|
||||
|
||||
register_rest_route(
|
||||
$this->namespace,
|
||||
'/' . $this->rest_base . '/auto-draft',
|
||||
array(
|
||||
array(
|
||||
'methods' => WP_REST_Server::CREATABLE,
|
||||
'callback' => array( $this, 'create_auto_draft' ),
|
||||
'permission_callback' => array( $this, 'create_item_permissions_check' ),
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an auto draft.
|
||||
*
|
||||
* @param WP_REST_Request $request
|
||||
*
|
||||
* @return WP_REST_Response
|
||||
*/
|
||||
public function create_auto_draft( $request ) {
|
||||
require_once ABSPATH . 'wp-admin/includes/post.php';
|
||||
|
||||
unset( $_REQUEST['content'], $_REQUEST['excerpt'] );
|
||||
$post = get_default_post_to_edit( $this->post_type, true );
|
||||
|
||||
$request->set_param( 'context', 'edit' );
|
||||
|
||||
return $this->prepare_item_for_response( $post, $request );
|
||||
}
|
||||
|
||||
public function get_items_permissions_check( $request ) {
|
||||
if ( ! current_user_can( get_post_type_object( $this->post_type )->cap->edit_posts ) ) {
|
||||
return new WP_Error( 'rest_cannot_view', __( 'You do not have permission to view these posts.', 'kadence-blocks' ) );
|
||||
}
|
||||
|
||||
return parent::get_items_permissions_check( $request );
|
||||
}
|
||||
|
||||
public function get_item_permissions_check( $request ) {
|
||||
if ( ! current_user_can( 'edit_post', $request['id'] ) ) {
|
||||
return new WP_Error( 'rest_cannot_view', __( 'You do not have permission to view these posts.', 'kadence-blocks' ) );
|
||||
}
|
||||
|
||||
return parent::get_item_permissions_check( $request );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,333 @@
|
||||
<?php
|
||||
/**
|
||||
* Class to Build the Advanced Form Submit Actions.
|
||||
*
|
||||
* @package Kadence Blocks
|
||||
*/
|
||||
class Kadence_Blocks_Advanced_Form_Submit_Actions {
|
||||
|
||||
public $form_args;
|
||||
|
||||
public $responses;
|
||||
|
||||
public $post_id;
|
||||
|
||||
public function __construct( $form_args, $responses, $post_id ) {
|
||||
$this->form_args = $form_args;
|
||||
$this->responses = $responses;
|
||||
$this->post_id = $post_id;
|
||||
}
|
||||
/**
|
||||
* Get the mapped attributes from responses.
|
||||
*
|
||||
* @param array $map the map array.
|
||||
* @param bool $no_email if no email.
|
||||
* @param bool $auto_map if auto map.
|
||||
*/
|
||||
public function get_mapped_attributes_from_responses( $map, $no_email = true, $auto_map = false ) {
|
||||
$mapped_attributes = array();
|
||||
|
||||
if ( ! empty( $map ) ) {
|
||||
foreach ( $this->responses as $key => $data ) {
|
||||
$unique_id = $data['uniqueID'];
|
||||
if ( isset( $map[ $unique_id ] ) && ( ! empty( $map[ $unique_id ] ) || $auto_map ) ) {
|
||||
if ( $no_email && 'email' === $map[ $unique_id ] ) {
|
||||
continue;
|
||||
} else if ( 'none' === $map[ $unique_id ] ) {
|
||||
continue;
|
||||
} else if ( 'OPT_IN' === $map[ $unique_id ] ) {
|
||||
if ( $data['value'] ) {
|
||||
$mapped_attributes[ $map[ $unique_id ] ] = true;
|
||||
} else {
|
||||
$mapped_attributes[ $map[ $unique_id ] ] = false;
|
||||
}
|
||||
} else if ( $auto_map ) {
|
||||
$mapped_attributes[ $data['label'] ] = $data['value'];
|
||||
} else {
|
||||
$mapped_attributes[ $map[ $unique_id ] ] = $data['value'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $mapped_attributes;
|
||||
}
|
||||
/**
|
||||
* Get email from responses.
|
||||
*
|
||||
* @param array $map the map array.
|
||||
*/
|
||||
public function get_email_from_responses( $map ) {
|
||||
$email = '';
|
||||
$mapped_email = '';
|
||||
|
||||
foreach ( $this->responses as $key => $data ) {
|
||||
$unique_id = $data['uniqueID'];
|
||||
if ( $map && isset( $map[ $unique_id ] ) && 'email' === $map[ $unique_id ] && ! $email ) {
|
||||
$mapped_email = $data['value'];
|
||||
} else if ( 'email' === $data['type'] ) {
|
||||
$email = $data['value'];
|
||||
}
|
||||
}
|
||||
|
||||
return $mapped_email ? $mapped_email : $email;
|
||||
}
|
||||
/**
|
||||
* Get the mapped attributes from responses.
|
||||
*
|
||||
* @param array $map the map array.
|
||||
* @param bool $no_email if no email.
|
||||
* @param bool $auto_map if auto map.
|
||||
*/
|
||||
public function get_response_field_by_name( $name ) {
|
||||
foreach ( $this->responses as $response ) {
|
||||
if ( isset( $response['name'] ) && $response['name'] == $name ) {
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
/**
|
||||
* Handle Field Replacements.
|
||||
*
|
||||
* @param string $text the text to replace.
|
||||
*/
|
||||
public function do_field_replacements( $text ) {
|
||||
if ( strpos( $text, '{' ) !== false && strpos( $text, '}' ) !== false ) {
|
||||
preg_match_all( '/{(.*?)}/', $text, $match );
|
||||
if ( is_array( $match ) && isset( $match[1] ) && is_array( $match[1] ) ) {
|
||||
foreach ( $match[1] as $field_name ) {
|
||||
if ( isset( $field_name ) ) {
|
||||
$field_to_insert = $this->get_response_field_by_name( $field_name );
|
||||
if ( $field_to_insert && isset( $field_to_insert['value'] ) ) {
|
||||
$text = str_replace( '{' . $field_name . '}', wp_unslash( $field_to_insert['value'] ), $text );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( strpos( $text, '{page_title}' ) !== false ) {
|
||||
global $post;
|
||||
$refer_id = is_object( $post ) ? $post->ID : url_to_postid( wp_get_referer() );
|
||||
$text = str_replace( '{page_title}', get_the_title( $refer_id ), $text );
|
||||
}
|
||||
|
||||
return $text;
|
||||
}
|
||||
/**
|
||||
* Handle the email action.
|
||||
*/
|
||||
public function email() {
|
||||
$to = isset( $this->form_args['attributes']['email']['emailTo'] ) && ! empty( trim( $this->form_args['attributes']['email']['emailTo'] ) ) ? trim( $this->form_args['attributes']['email']['emailTo'] ) : get_option( 'admin_email' );
|
||||
$subject = isset( $this->form_args['attributes']['email']['subject'] ) && ! empty( trim( $this->form_args['attributes']['email']['subject'] ) ) ? $this->form_args['attributes']['email']['subject'] : '[' . get_bloginfo( 'name' ) . ' ' . __( 'Submission', 'kadence-blocks' ) . ']';
|
||||
$from_email = isset( $this->form_args['attributes']['email']['fromEmail'] ) && ! empty( trim( $this->form_args['attributes']['email']['fromEmail'] ) ) ? sanitize_email( $this->do_field_replacements( trim( $this->form_args['attributes']['email']['fromEmail'] ) ) ) : '';
|
||||
$from_name = ( isset( $this->form_args['attributes']['email']['fromName'] ) && ! empty( trim( $this->form_args['attributes']['email']['fromName'] ) ) ? trim( $this->form_args['attributes']['email']['fromName'] ) . ' ' : '' );
|
||||
$email_cc = isset( $this->form_args['attributes']['email']['cc'] ) && ! empty( trim( $this->form_args['attributes']['email']['cc'] ) ) ? $this->do_field_replacements( trim( $this->form_args['attributes']['email']['cc'] ) ) : '';
|
||||
$email_bcc = isset( $this->form_args['attributes']['email']['bcc'] ) && ! empty( trim( $this->form_args['attributes']['email']['bcc'] ) ) ? $this->form_args['attributes']['email']['bcc'] : '';
|
||||
|
||||
$to = $this->do_field_replacements( $to );
|
||||
$subject = $this->do_field_replacements( $subject );
|
||||
$from_name = $this->do_field_replacements( $from_name );
|
||||
$email_bcc = $this->do_field_replacements( $email_bcc );
|
||||
|
||||
$email_content = '';
|
||||
$reply_email = false;
|
||||
foreach ( $this->responses as $key => $data ) {
|
||||
if ( 'email' === $data['type'] ) {
|
||||
$reply_email = $data['value'];
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset( $this->form_args['attributes']['email']['replyTo'] ) && 'from_email' === $this->form_args['attributes']['email']['replyTo'] ) {
|
||||
$reply_email = $from_email ? $from_email : false;
|
||||
}
|
||||
|
||||
if ( ! isset( $this->form_args['attributes']['email']['html'] ) || ( isset( $this->form_args['attributes']['email']['html'] ) && $this->form_args['attributes']['email']['html'] ) ) {
|
||||
$args = array( 'fields' => $this->responses );
|
||||
$email_content = kadence_blocks_get_template_html( 'form-email.php', $args );
|
||||
$headers = 'Content-Type: text/html; charset=UTF-8' . "\r\n";
|
||||
} else {
|
||||
foreach ( $this->responses as $key => $data ) {
|
||||
if ( is_array( $data['value'] ) ) {
|
||||
$data['value'] = explode( ', ', $data['value'] );
|
||||
}
|
||||
$email_content .= strip_tags( $data['label'] ) . ': ' . wp_unslash( $data['value'] ) . "\n\n";
|
||||
}
|
||||
$headers = 'Content-Type: text/plain; charset=UTF-8' . "\r\n";
|
||||
}
|
||||
|
||||
$body = $email_content;
|
||||
|
||||
if ( $reply_email ) {
|
||||
$headers .= 'Reply-To: <' . $reply_email . '>' . "\r\n";
|
||||
}
|
||||
|
||||
if ( $from_email ) {
|
||||
$headers .= 'From: ' . $from_name . '<' . $from_email . '>' . "\r\n";
|
||||
}
|
||||
|
||||
$cc_headers = '';
|
||||
if ( $email_cc ) {
|
||||
$cc_emails = explode( ',', $email_cc );
|
||||
$sanitized_cc_emails = array();
|
||||
foreach ( $cc_emails as $cc_email ) {
|
||||
$sanitized_cc_emails[] = sanitize_email( trim( $cc_email ) );
|
||||
}
|
||||
$cc_headers = 'Cc: ' . implode( ',', $sanitized_cc_emails ) . "\r\n";
|
||||
}
|
||||
|
||||
$bcc_headers = '';
|
||||
if ( $email_bcc ) {
|
||||
$bcc_emails = explode( ',', $email_bcc );
|
||||
$sanitized_bcc_emails = array();
|
||||
foreach ( $bcc_emails as $bcc_email ) {
|
||||
$sanitized_bcc_emails[] = sanitize_email( trim( $bcc_email ) );
|
||||
}
|
||||
$bcc_headers = 'Bcc: ' . implode( ',', $sanitized_bcc_emails ) . "\r\n";
|
||||
}
|
||||
|
||||
wp_mail( $to, $subject, $body, $headers . $cc_headers . $bcc_headers );
|
||||
}
|
||||
/**
|
||||
* Mailerlite rest call.
|
||||
*
|
||||
* @param string $api_url api url.
|
||||
* @param string $method method.
|
||||
* @param array $body body.
|
||||
*/
|
||||
public function mailerlite_rest_call( $api_url, $method, $body ) {
|
||||
$api_key = get_option( 'kadence_blocks_mailerlite_api' );
|
||||
|
||||
if ( empty( $api_key ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$response = wp_remote_post(
|
||||
$api_url,
|
||||
array(
|
||||
'method' => $method,
|
||||
'timeout' => 10,
|
||||
'headers' => array(
|
||||
'accept' => 'application/json',
|
||||
'content-type' => 'application/json',
|
||||
'X-MailerLite-ApiKey' => $api_key,
|
||||
),
|
||||
'body' => json_encode( $body ),
|
||||
)
|
||||
);
|
||||
|
||||
if ( is_wp_error( $response ) ) {
|
||||
$error_message = $response->get_error_message();
|
||||
error_log( "Something went wrong: $error_message" );
|
||||
return false;
|
||||
} else {
|
||||
if ( ! isset( $response['response'] ) || ! isset( $response['response']['code'] ) ) {
|
||||
error_log( __( 'No Response from MailerLite', 'kadence-blocks' ) );
|
||||
return false;
|
||||
}
|
||||
if ( 400 === $response['response']['code'] ) {
|
||||
error_log( print_r( $response['response'], true ) );
|
||||
$this->process_bail( $response['response']['message'] . ' ' . __( 'MailerLite Misconfiguration', 'kadence-blocks' ), __( 'MailerLite Failed', 'kadence-blocks' ) );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return $response;
|
||||
}
|
||||
/**
|
||||
* Mailerlite.
|
||||
*/
|
||||
public function mailerlite() {
|
||||
|
||||
$mailerlite_default = array(
|
||||
'map' => array(),
|
||||
'group' => '',
|
||||
);
|
||||
|
||||
$mailerlite_args = ( isset( $this->form_args['attributes']['mailerlite'] ) && is_array( $this->form_args['attributes']['mailerlite'] ) && isset( $this->form_args['attributes']['mailerlite'] ) ? $this->form_args['attributes']['mailerlite'] : $mailerlite_default );
|
||||
$group = ( isset( $mailerlite_args['group'] ) ? $mailerlite_args['group'] : '' );
|
||||
$map = ( isset( $mailerlite_args['map'] ) && is_array( $mailerlite_args['map'] ) ? $mailerlite_args['map'] : array() );
|
||||
$body = array( 'fields' => array() );
|
||||
$email = false;
|
||||
|
||||
$mapped_attributes = $this->get_mapped_attributes_from_responses( $map );
|
||||
$email = $this->get_email_from_responses( $map );
|
||||
|
||||
$body['fields'] = $mapped_attributes;
|
||||
$body['email'] = $email;
|
||||
|
||||
if ( empty( $body['fields'] ) ) {
|
||||
unset( $body['fields'] );
|
||||
}
|
||||
|
||||
$group_id = '';
|
||||
if ( ! empty( $group ) && is_array( $group ) ) {
|
||||
$group_id = ( isset( $group['value'] ) && ! empty( $group['value'] ) ? $group['value'] : '' );
|
||||
}
|
||||
if ( ! $group_id ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$body['resubscribe'] = true;
|
||||
|
||||
if ( isset( $body['email'] ) ) {
|
||||
if ( ! empty( $group_id ) ) {
|
||||
$api_url = 'https://api.mailerlite.com/api/v2/groups/' . $group_id . '/subscribers';
|
||||
} else {
|
||||
$api_url = 'https://api.mailerlite.com/api/v2/subscribers';
|
||||
}
|
||||
|
||||
$response = $this->mailerlite_rest_call( $api_url, 'POST', $body );
|
||||
$temp = 1;
|
||||
}
|
||||
}
|
||||
|
||||
public function fluentCRM() {
|
||||
$fluentcrm_default = array(
|
||||
'map' => array(),
|
||||
'lists' => array(),
|
||||
'tags' => array(),
|
||||
'doubleOptin' => false,
|
||||
);
|
||||
|
||||
$fluentcrm_args = ( isset( $this->form_args['attributes']['fluentcrm'] ) && is_array( $this->form_args['attributes']['fluentcrm'] ) && isset( $this->form_args['attributes']['fluentcrm'] ) ? $this->form_args['attributes']['fluentcrm'] : $fluentcrm_default );
|
||||
$map = ( isset( $fluentcrm_args['map'] ) && is_array( $fluentcrm_args['map'] ) ? $fluentcrm_args['map'] : array() );
|
||||
$double_optin = ( isset( $fluentcrm_args['doubleOptin'] ) ? $fluentcrm_args['doubleOptin'] : false );
|
||||
$fluent_data = array();
|
||||
$lists = ( isset( $fluentcrm_args['lists'] ) ? $fluentcrm_args['lists'] : array() );
|
||||
$tags = ( isset( $fluentcrm_args['tags'] ) ? $fluentcrm_args['tags'] : array() );
|
||||
|
||||
if ( $double_optin ) {
|
||||
$fluent_data['status'] = 'pending';
|
||||
} else {
|
||||
$fluent_data['status'] = 'subscribed';
|
||||
}
|
||||
if ( ! empty( $lists ) ) {
|
||||
$fluent_data['lists'] = array();
|
||||
foreach ( $lists as $key => $data ) {
|
||||
$fluent_data['lists'][] = $data['value'];
|
||||
}
|
||||
}
|
||||
if ( ! empty( $tags ) ) {
|
||||
$fluent_data['tags'] = array();
|
||||
foreach ( $tags as $key => $data ) {
|
||||
$fluent_data['tags'][] = $data['value'];
|
||||
}
|
||||
}
|
||||
|
||||
$email = false;
|
||||
|
||||
$mapped_attributes = $this->get_mapped_attributes_from_responses( $map );
|
||||
$email = $this->get_email_from_responses( $map );
|
||||
|
||||
$fluent_data = array_merge( $fluent_data, $mapped_attributes );
|
||||
$fluent_data['email'] = $email;
|
||||
|
||||
if ( isset( $fluent_data['email'] ) && ! empty( $fluent_data['email'] ) && function_exists( 'FluentCrmApi' ) ) {
|
||||
$contact_api = FluentCrmApi( 'contacts' );
|
||||
$contact = $contact_api->createOrUpdate( $fluent_data );
|
||||
if ( $double_optin && 'pending' === $contact->status ) {
|
||||
$contact->sendDoubleOptinEmail();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
<?php
|
||||
/**
|
||||
* REST API GetResponse controller customized for Kadence Form
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* REST API controller class.
|
||||
*
|
||||
*/
|
||||
class Kadence_GetResponse_REST_Controller extends WP_REST_Controller {
|
||||
|
||||
/**
|
||||
* Include property name.
|
||||
*/
|
||||
const PROP_END_POINT = 'endpoint';
|
||||
|
||||
/**
|
||||
* Allowed endpoint values to prevent SSRF (only these paths are requested from the configured API base).
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
const ALLOWED_ENDPOINTS = array( 'campaigns', 'tags', 'custom-fields' );
|
||||
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->namespace = 'kb-getresponse/v1';
|
||||
$this->rest_base = 'get';
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the routes for the objects of the controller.
|
||||
*
|
||||
* @see register_rest_route()
|
||||
*/
|
||||
public function register_routes() {
|
||||
register_rest_route(
|
||||
$this->namespace,
|
||||
'/' . $this->rest_base,
|
||||
array(
|
||||
array(
|
||||
'methods' => WP_REST_Server::READABLE,
|
||||
'callback' => array( $this, 'get_items' ),
|
||||
'permission_callback' => array( $this, 'get_items_permission_check' ),
|
||||
'args' => $this->get_collection_params(),
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a given request has access to proxy GetResponse API calls.
|
||||
* Requires manage_options so only admins (who can configure the API key) can trigger server-side requests.
|
||||
*
|
||||
* @param WP_REST_Request $request Full details about the request.
|
||||
*
|
||||
* @return true|WP_Error True if the request has access, WP_Error object otherwise.
|
||||
*/
|
||||
public function get_items_permission_check( $request ) {
|
||||
if ( ! current_user_can( 'manage_options' ) ) {
|
||||
return new WP_Error(
|
||||
'rest_forbidden',
|
||||
__( 'You do not have permission to access GetResponse API data.', 'kadence-blocks' ),
|
||||
array( 'status' => 403 )
|
||||
);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a collection of objects.
|
||||
*
|
||||
* @param WP_REST_Request $request Full details about the request.
|
||||
*
|
||||
* @return WP_REST_Response|WP_Error|Array Response object on success, or WP_Error object on failure.
|
||||
*/
|
||||
public function get_items( $request ) {
|
||||
$api_key = get_option( 'kadence_blocks_getresponse_api_key' );
|
||||
$api_base = get_option( 'kadence_blocks_getresponse_api_endpoint' );
|
||||
$end_point = $request->get_param( self::PROP_END_POINT );
|
||||
|
||||
// Restrict to whitelisted endpoints to prevent SSRF (e.g. requesting arbitrary URLs that echo back auth headers or server IP).
|
||||
if ( empty( $end_point ) || ! in_array( $end_point, self::ALLOWED_ENDPOINTS, true ) ) {
|
||||
return new WP_Error(
|
||||
'rest_invalid_endpoint',
|
||||
__( 'Invalid or disallowed endpoint.', 'kadence-blocks' ),
|
||||
array( 'status' => 400 )
|
||||
);
|
||||
}
|
||||
|
||||
if ( empty( $api_key ) || empty( $api_base ) ) {
|
||||
return rest_ensure_response( array() );
|
||||
}
|
||||
|
||||
$request_url = rtrim( $api_base, '/' ) . '/' . $end_point;
|
||||
|
||||
$request_args = array(
|
||||
'headers' => array(
|
||||
'X-Auth-Token' => 'api-key ' . $api_key,
|
||||
),
|
||||
'timeout' => 10,
|
||||
);
|
||||
$response = wp_safe_remote_get( $request_url, $request_args );
|
||||
|
||||
if ( is_wp_error( $response ) || 200 != (int) wp_remote_retrieve_response_code( $response ) ) {
|
||||
return new WP_Error( 'getresponse_error', __( 'Error fetching data from GetResponse', 'kadence-blocks' ) );
|
||||
}
|
||||
|
||||
$body = json_decode( wp_remote_retrieve_body( $response ), true );
|
||||
|
||||
if ( ! is_array( $body ) ) {
|
||||
return new WP_Error( 'getresponse_error', __( 'Empty data from GetResponse', 'kadence-blocks' ) );
|
||||
}
|
||||
|
||||
return rest_ensure_response( $body );
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the query params for the search results collection.
|
||||
*
|
||||
* @return array Collection parameters.
|
||||
*/
|
||||
public function get_collection_params() {
|
||||
$query_params = parent::get_collection_params();
|
||||
|
||||
$query_params[ self::PROP_END_POINT ] = array(
|
||||
'description' => __( 'Actionable endpoint for api call.', 'kadence-blocks' ),
|
||||
'type' => 'string',
|
||||
);
|
||||
|
||||
return $query_params;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user