diff --git a/inc/integrations/api/form-request-data.php b/inc/integrations/api/form-request-data.php index 2431cb99b..503533eaa 100644 --- a/inc/integrations/api/form-request-data.php +++ b/inc/integrations/api/form-request-data.php @@ -108,7 +108,7 @@ class Form_Data_Request { * Constructor. * * @access public - * @param \WP_REST_Request|mixed $request Request Data. + * @param \WP_REST_Request $request Request Data. * @since 2.0.3 */ public function __construct( $request = null ) { @@ -118,11 +118,21 @@ public function __construct( $request = null ) { } $this->request = $request; - $form_data = $request->get_param( 'form_data' ); - $form_data = json_decode( $form_data, true ); + if ( ! empty( $request->get_param( 'form_data' ) ) ) { + $form_data = $request->get_param( 'form_data' ); + $form_data = json_decode( $form_data, true ); + $this->request_data = $this->sanitize_request_data( $form_data ); + } else { + $body = json_decode( $request->get_body(), true ); + if ( null !== $body ) { + $this->request_data = $this->sanitize_request_data( $body ); + } else { + $this->error_code = Form_Data_Response::ERROR_MALFORMED_REQUEST; + } + } + - $this->request_data = $this->sanitize_request_data( $form_data ); $this->form_options = new Form_Settings_Data( array() ); } diff --git a/inc/integrations/api/form-response-data.php b/inc/integrations/api/form-response-data.php index c2be56dae..bd45925ab 100644 --- a/inc/integrations/api/form-response-data.php +++ b/inc/integrations/api/form-response-data.php @@ -30,6 +30,7 @@ class Form_Data_Response { const ERROR_MISSING_FILE_FIELD_OPTION = '16'; const ERROR_AUTORESPONDER_MISSING_EMAIL_FIELD = '17'; const ERROR_AUTORESPONDER_COULD_NOT_SEND = '18'; + const ERROR_MALFORMED_REQUEST = '19'; // Request validation errors. const ERROR_MISSING_DATA = '101'; @@ -151,7 +152,7 @@ public function set_reasons( $reasons ) { /** * Set success message. - * + * * @param string $message The message. * @since 2.4 */ @@ -356,6 +357,7 @@ public static function get_error_code_message( $error_code ) { self::ERROR_AUTORESPONDER_MISSING_EMAIL_FIELD => __( 'The email field is missing from the Form Block with Autoresponder activated.', 'otter-blocks' ), self::ERROR_AUTORESPONDER_COULD_NOT_SEND => __( 'The email from Autoresponder could not be sent.', 'otter-blocks' ), self::ERROR_FILE_MISSING_BINARY => __( 'The file data is missing.', 'otter-blocks' ), + self::ERROR_MALFORMED_REQUEST => __( 'The request is malformed.', 'otter-blocks' ), ); if ( ! isset( $error_messages[ $error_code ] ) ) { diff --git a/inc/integrations/class-form-utils.php b/inc/integrations/class-form-utils.php index 86a1f6094..611308b9c 100644 --- a/inc/integrations/class-form-utils.php +++ b/inc/integrations/class-form-utils.php @@ -40,9 +40,14 @@ public static function generate_test_email() { 'eight', 'nine', 'ten', + 'eleven', + 'twelve', + 'thirteen', + 'fourteen', + 'fifteen', ); - $name_1 = $words[ wp_rand( 0, count( $words ) ) ]; + $name_1 = $words[ wp_rand( 0, count( $words ) - 1 ) ]; $name_2 = $words[ wp_rand( 2, count( $words ) ) - 1 ]; return "Otter-Form-successfully-connected.delete-on-confirmation.$name_1.$name_2@otter-blocks.com"; diff --git a/inc/integrations/interfaces/interface-form-subscribe-service.php b/inc/integrations/interfaces/interface-form-subscribe-service.php index 8f3b482e9..d14785f0c 100644 --- a/inc/integrations/interfaces/interface-form-subscribe-service.php +++ b/inc/integrations/interfaces/interface-form-subscribe-service.php @@ -51,10 +51,10 @@ public function extract_data_from_integration( $wp_options_form ); public static function validate_api_key( $api_key ); /** - * Test if the service is set up by registering a random email address on the contact list. + * Make a request that add the email to the contact list. * - * @return mixed - * @since 2.0.3 + * @param string $email The email address. + * @return array|\WP_Error The response from Mailchimp. */ - public function test_subscription(); + public function make_subscribe_request( $email ); } diff --git a/inc/integrations/providers/class-mailchimp.php b/inc/integrations/providers/class-mailchimp.php index 80ffea446..88bab3def 100644 --- a/inc/integrations/providers/class-mailchimp.php +++ b/inc/integrations/providers/class-mailchimp.php @@ -111,7 +111,7 @@ function( $item ) { * @param string $email The email address. * @return array|\WP_Error The response from Mailchimp. */ - private function make_subscribe_request( $email ) { + public function make_subscribe_request( $email ) { $user_status = $this->get_new_user_status_mailchimp( $this->list_id ); $url = 'https://' . $this->server_name . '.api.mailchimp.com/3.0/lists/' . $this->list_id . '/members/' . md5( strtolower( $email ) ); @@ -161,23 +161,6 @@ public function subscribe( $form_data ) { return $form_data; } - /** - * Test the subscription by registering a random generated email. - * - * @return Form_Data_Request - * @since 2.0.3 - */ - public function test_subscription() { - $req = new Form_Data_Request(); - $response = $this->make_subscribe_request( Form_Utils::generate_test_email() ); - - if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) { - $req->set_error( Form_Data_Response::get_error_code_message( Form_Data_Response::ERROR_PROVIDER_SUBSCRIBE_ERROR ) ); - } - - return $req; - } - /** * Set the API Key. * diff --git a/inc/integrations/providers/class-sendinblue.php b/inc/integrations/providers/class-sendinblue.php index 63f8a4cd3..267d4f0f1 100644 --- a/inc/integrations/providers/class-sendinblue.php +++ b/inc/integrations/providers/class-sendinblue.php @@ -154,22 +154,6 @@ public function subscribe( $form_data ) { return $form_data; } - /** - * Test the subscription by registering a random generated email. - * - * @return Form_Data_Request - */ - public function test_subscription() { - $req = new Form_Data_Request(); - $response = $this->make_subscribe_request( Form_Utils::generate_test_email() ); - - if ( is_wp_error( $response ) || 400 === wp_remote_retrieve_response_code( $response ) ) { - $req->set_error( Form_Data_Response::get_error_code_message( Form_Data_Response::ERROR_PROVIDER_SUBSCRIBE_ERROR ) ); - } - - return $req; - } - /** * Set the API Key * diff --git a/inc/server/class-form-server.php b/inc/server/class-form-server.php index a5f351685..b2c940a5e 100644 --- a/inc/server/class-form-server.php +++ b/inc/server/class-form-server.php @@ -199,7 +199,7 @@ public function register_routes() { * @since 2.0.3 */ public function editor( $request ) { - $data = new Form_Data_Request( json_decode( $request->get_body(), true ) ); + $data = new Form_Data_Request( $request ); $res = new Form_Data_Response(); $form_options = Form_Settings_Data::get_form_setting_from_wordpress_options( $data->get_payload_field( 'formOption' ) ); @@ -212,6 +212,10 @@ public function editor( $request ) { } $provider_handlers = Form_Providers::$instance->get_provider_handlers( $provider, 'editor' ); + if ( $data->has_error() ) { + return $res->set_code( $data->get_error_code() )->build_response(); + } + if ( $provider_handlers && Form_Providers::provider_has_handler( $provider_handlers, $data->get( 'handler' ) ) ) { // Send the data to the provider. return $provider_handlers[ $data->get( 'handler' ) ]( $data ); @@ -651,7 +655,13 @@ public function test_subscription_service( $form_data ) { if ( $valid_api_key['valid'] ) { if ( $form_options->has_list_id() ) { $service->set_api_key( $form_options->get_api_key() )->set_list_id( $form_options->get_list_id() ); - $res = $service->test_subscription(); + $response = $service->make_subscribe_request( Form_Utils::generate_test_email() ); + + if ( is_wp_error( $response ) ) { + $res->set_error( Form_Data_Response::ERROR_RUNTIME_ERROR, $response->get_error_message() ); + } else { + $res->mark_as_success(); + } } else { $res->set_error( __( 'Contact list ID is missing!', 'otter-blocks' ) ); } diff --git a/src/blocks/blocks/form/edit.js b/src/blocks/blocks/form/edit.js index b9d029969..c81f35d06 100644 --- a/src/blocks/blocks/form/edit.js +++ b/src/blocks/blocks/form/edit.js @@ -553,7 +553,7 @@ const Edit = ({ } else { createNotice( 'error', - res?.error, + res?.error ?? res?.reasons?.join( '. ' ) ?? __( 'An error has occurred.', 'otter-blocks' ), { isDismissible: true, type: 'snackbar', diff --git a/src/blocks/test/e2e/blocks/form.spec.js b/src/blocks/test/e2e/blocks/form.spec.js index e8805aede..c897f50a6 100644 --- a/src/blocks/test/e2e/blocks/form.spec.js +++ b/src/blocks/test/e2e/blocks/form.spec.js @@ -273,4 +273,26 @@ test.describe( 'Form Block', () => { // check for a element with the attribute data-redirect-url await expect( await page.$( `[data-redirect="${REDIRECT_URL}"]` ) ).toBeTruthy(); }); + + test( 'errors on invalid API Key for Market Integration', async({ page, editor, browser }) => { + + await editor.insertBlock({ name: 'themeisle-blocks/form' }); + + let formBlock = ( await editor.getBlocks() ).find( ( block ) => 'themeisle-blocks/form' === block.name ); + + expect( formBlock ).toBeTruthy(); + + const { clientId } = formBlock; + + await page.click( `#block-${clientId} > div > fieldset > ul > li:nth-child(1) > button` ); + + await page.getByRole( 'button', { name: 'Marketing Integration' }).click(); + + // Select the Mailchimp option on the select with label Provider + await page.getByLabel( 'Provider' ).selectOption( 'mailchimp' ); + + await page.getByLabel( 'API Key' ).fill( 'invalid-api-key' ); + + await expect( page.getByLabel( 'Dismiss this notice' ) ).toBeVisible(); + }); });