get_name();
$api_key_source = $settings[ "{$name}_api_key_source" ];
if ( 'custom' === $api_key_source ) {
return $settings[ "{$name}_custom_api_{$param}" ];
}
$options = get_option( 'sellkit' );
if ( isset( $options[ "{$name}_api_{$param}" ] ) ) {
return $options[ "{$name}_api_{$param}" ];
}
return '';
}
/**
* Maps the values in field mapping control of this action, to the form fields.\
* Usually called inside of "create_subscriber_object" method.
*
* @return array
*
* @access protected
* @since 1.5.0
*/
protected function get_field_mappings() {
$field_mappings = $this->ajax_handler->form['settings'][ $this->get_name() . '_fields_mapping' ];
$fields_repeater = $this->ajax_handler->form['settings']['fields'];
$form_fields = $this->ajax_handler->form_data['fields'];
$mapped_fields = [];
foreach ( $field_mappings as $item ) {
// Send warning about fields that are required by remote endpoint, but are missing or unrequired in the form.
$is_remote_required = array_key_exists( $item['remote_field'], $this->get_default_remote_fields()['required'] );
if ( $is_remote_required ) {
$field_index = array_search( $item['local_field'], array_column( $fields_repeater, '_id' ), true );
$is_local_exist = false !== $field_index;
$remote_label = $this->get_default_remote_fields()['required'][ $item['remote_field'] ];
if ( ! $is_local_exist ) {
$this->ajax_handler->add_response( 'admin_errors', $this->get_absent_require_notice( $remote_label ) );
} else {
$field_setting = $fields_repeater[ $field_index ];
$is_local_required = $field_setting['required'] && 'true' === $field_setting['required'];
if ( ! $is_local_required ) {
$this->ajax_handler->add_response( 'admin_errors', $this->get_make_require_notice( $remote_label ) );
}
}
}
// Go on with mapping process.
if ( empty( $item['local_field'] ) || empty( $item['remote_field'] ) ) {
continue;
}
$mapped_fields[ $item['remote_field'] ] = $form_fields[ $item['local_field'] ];
}
return $mapped_fields;
}
/**
* Send a GET request.
*
* @param string $endpoint The piece of URL to append to base URL.
* @param array $request_args Additional data to append to current request arguments.
* @return array The result of request, inside three keys "code", "body", "errors".
*
* @access protected
* @since 1.5.0
*/
protected function send_get( $endpoint, $additional_args = [] ) {
$args = array_merge( $this->get_get_request_args(), $additional_args );
$response = wp_remote_get( $this->get_base_url() . $endpoint, $args );
return [
'code' => (int) wp_remote_retrieve_response_code( $response ),
'body' => json_decode( wp_remote_retrieve_body( $response ), true ),
];
}
/**
* Send a POST request.
*
* @param string $endpoint The piece of URL to append to base URL.
* @param array $request_args Additional data to append to current request arguments.
* @param string $admin_error_key Key of admin_errors(if any) inside AJAX handler's response array.
* @return array The result of request, inside three keys "code", "body", "errors".
*
* @access protected
* @since 1.5.0
*/
protected function send_post( $endpoint, $request_args = [], $admin_error_key = '' ) {
$response = wp_remote_post( $this->get_base_url() . $endpoint, $request_args );
$this->handle_errors( $response, $admin_error_key );
return [
'code' => (int) wp_remote_retrieve_response_code( $response ),
'body' => json_decode( wp_remote_retrieve_body( $response ), true ),
];
}
/**
* Accepts the response of a remote request, collect its errors and loads them on AJAX response.
*
* @param array|\WP_Error $response The response of a remote request.
* @param string $admin_error_key Key of admin_errors(if any) inside AJAX handler's response array.
*
* @access private
* @since 1.5.0
*/
private function handle_errors( $response, $admin_error_key ) {
$error = '';
$message_desc = esc_html__( ' (issued by endpoint)', 'sellkit' );
if ( is_wp_error( $response ) ) {
$error = implode( "
{$this->get_title()}: ", $response->get_error_messages() );
$this->ajax_handler->add_response( 'admin_errors', $error . $message_desc, $admin_error_key );
return;
}
$code = (int) wp_remote_retrieve_response_code( $response );
if ( ( $code < 200 || $code >= 300 ) ) {
$error = sprintf(
/* translators: 1: Action name, 2: response code, 3: error message (an unknown English string) */
esc_html__( '%1$s: Request error-%2$s -- %3$s', 'sellkit' ),
$this->get_title(),
$code,
wp_remote_retrieve_response_message( $response )
);
}
if ( ! empty( $error ) ) {
$this->ajax_handler->add_response( 'admin_errors', $error . $message_desc, $admin_error_key );
}
}
/**
* Get Client IP Address.
*
* @return string
*
* @since 1.5.0
* @access public
* @static
*/
public static function get_client_ip() {
$ip_address = '';
$server_headers = [
'HTTP_CLIENT_IP',
'HTTP_X_FORWARDED_FOR',
'HTTP_X_FORWARDED',
'HTTP_FORWARDED_FOR',
'HTTP_FORWARDED',
'REMOTE_ADDR',
];
// phpcs:disable WordPress.Security.ValidatedSanitizedInput
foreach ( $server_headers as $header ) {
if ( isset( $_SERVER[ $header ] ) ) {
$ip_address = $_SERVER[ $header ];
break;
}
}
// phpcs:enable
return $ip_address;
}
/**
* Ready made method that creates controls assocciated with API key of this CRM action.
*
* @param object $widget Widget instance.
* @param string $list_name Name of this CRM action's list (Account, Form, Campaign, etc.)
*
* @access protected
* @since 1.5.0
*/
protected function add_api_controls( $widget, $list_name ) {
$action = $this->get_name();
$widget->add_control( "{$action}_api_key_source",
[
'label' => esc_html__( 'API key', 'sellkit' ),
'type' => 'select',
'default' => 'default',
'render_type' => 'ui',
'options' => [
'default' => esc_html__( 'Default', 'sellkit' ),
'custom' => esc_html__( 'Custom', 'sellkit' ),
],
]
);
$hint = sprintf(
/* translators: 1: html tag, 2: Action name, 3: html tags, 4: html tags */
esc_html__( '%1$sSet your %2$s API key in %3$s Sellkit Settings %4$s.', 'sellkit' ),
'',
$this->get_title(),
sprintf( '', admin_url() . 'admin.php?page=sellkit-settings&crm=' . $this->get_name() . '#/' ),
''
);
$widget->add_control( "{$action}_api_key_msg",
[
'type' => 'raw_html',
'raw' => $hint,
'condition' => [ "{$action}_api_key_source" => 'default' ],
]
);
$widget->add_control( "{$action}_custom_api_key",
[
'label' => esc_html__( 'Custom API Key', 'sellkit' ),
'type' => 'text',
'render_type' => 'ui',
/* translators: Action name */
'description' => sprintf( esc_html__( 'Enter your %s API key for only this form.', 'sellkit' ), $this->get_title() ),
'condition' => [ "{$action}_api_key_source" => 'custom' ],
]
);
$widget->add_control( "{$action}_list",
[
'label' => $list_name,
'type' => 'select',
'render_type' => 'ui',
'conditions' => [
'relation' => 'or',
'terms' => [
[
'name' => "{$action}_custom_api_key",
'operator' => '!==',
'value' => '',
],
[
'name' => "{$action}_api_key_source",
'operator' => '=',
'value' => 'default',
],
],
],
]
);
}
/**
* Ready made method that creates controls assocciated with field mapping for this CRM action.
*
* @param object $widget Widget instance.
*
* @access protected
* @since 1.5.0
*/
protected function add_field_mapping_controls( $widget ) {
$action = $this->get_name();
$repeater = new Repeater();
$repeater->add_control( 'remote_field',
[
'label' => $this->get_title() . ' ' . esc_html__( 'Field', 'sellkit' ),
'type' => 'select',
'render_type' => 'ui',
'label_block' => false,
'options' => array_merge(
$this->get_default_remote_fields()['required'],
$this->get_default_remote_fields()['optional']
),
]
);
$repeater->add_control( 'local_field',
[
'label' => esc_html__( 'Form Field', 'sellkit' ),
'type' => 'select',
'render_type' => 'ui',
]
);
$defaults = [];
foreach ( $this->get_default_remote_fields()['required'] as $key => $value ) {
$defaults[] = [
'remote_field' => $key,
'is_required' => true,
];
}
$widget->add_control( "{$action}_fields_mapping",
[
'label' => esc_html__( 'Field Mapping', 'sellkit' ),
'type' => 'repeater',
'separator' => 'before',
'fields' => $repeater->get_controls(),
'default' => $defaults,
'conditions' => [
'terms' => [
[
'name' => "{$action}_list",
'operator' => '!in',
'value' => [ 'none', 'fetching', 'noList' ],
],
],
],
]
);
}
/**
* Ready made method that creates the control assocciated with tags for this CRM action.
*
* @param object $widget Widget instance.
*
* @access protected
* @since 1.5.0
*/
protected function add_tag_control( $widget ) {
$action = $this->get_name();
$widget->add_control( "{$action}_tags",
[
'label' => esc_html__( 'Tags', 'sellkit' ),
'type' => 'select2',
'multiple' => true,
'label_block' => true,
'render_type' => 'ui',
'conditions' => [
'terms' => [
[
'name' => "{$action}_list",
'operator' => '!in',
'value' => [ 'none', 'fetching', 'noList' ],
],
],
],
]
);
}
/**
* Creates and returns a text that notifies the user that a field should be made required.
*
* @param string $field_label Label of the field.
* @return string
*
* @access protected
* @since 1.5.0
*/
protected function get_make_require_notice( $field_label ) {
return sprintf(
/* translators: 1: Action name 2: Field name */
esc_attr__( '%1$s: %2$s is required by api endpoint, but the corresponding field is not made required in your form.', 'sellkit' ),
$this->get_title(),
$field_label
);
}
/**
* Creates and returns a text that notifies the user that a remote-required field is mapped to none of local form fields.
*
* @param string $field_label Label of the field.
* @return string
*
* @access protected
* @since 1.5.0
*/
protected function get_absent_require_notice( $field_label ) {
return sprintf(
/* translators: 1: Action name 2: Field name */
esc_attr__( '%1$s: %2$s is required by api endpoint, but it is not mapped to any field in your form.', 'sellkit' ),
$this->get_title(),
$field_label
);
}
/**
* Creates and returns a text that notifies the user that not a valid list is selected fo this CRM action.
*
* @param string $list_name Label of the list (Account, Form, Campaign, etc.).
* @return string
*
* @access protected
* @since 1.5.0
*/
protected function get_invalid_list_message( $list_name ) {
return sprintf(
/* translators: 1: Action name 2: List name */
esc_html__( '%1$s: Invalid %2$s is selected.', 'sellkit' ),
$this->get_title(),
$list_name
);
}
}