diff --git a/src/Plugin/WebformHandler/RemotePostWebformHandler.php b/src/Plugin/WebformHandler/RemotePostWebformHandler.php index c94d5c935..399779a20 100644 --- a/src/Plugin/WebformHandler/RemotePostWebformHandler.php +++ b/src/Plugin/WebformHandler/RemotePostWebformHandler.php @@ -4,6 +4,7 @@ namespace Drupal\webform\Plugin\WebformHandler; use Drupal\Core\Config\ConfigFactoryInterface; use Drupal\Core\Logger\LoggerChannelFactoryInterface; +use Drupal\Core\Messenger\MessengerInterface; use Drupal\Core\Routing\TrustedRedirectResponse; use Drupal\Core\Serialization\Yaml; use Drupal\Core\Extension\ModuleHandlerInterface; @@ -193,10 +194,10 @@ class RemotePostWebformHandler extends WebformHandlerBase { 'draft_updated_custom_data' => '', 'converted_url' => '', 'converted_custom_data' => '', - // Custom error response messages. + // Custom response messages. 'message' => '', 'messages' => [], - // Custom error response redirect URL. + // Custom response redirect URL. 'error_url' => '', ]; } @@ -348,7 +349,7 @@ class RemotePostWebformHandler extends WebformHandlerBase { $form['additional']['message'] = [ '#type' => 'webform_html_editor', '#title' => $this->t('Custom error response message'), - '#description' => $this->t('This message is displayed when the response status code is not 2xx'), + '#description' => $this->t('This message is displayed when the response status code is not 2xx.') . '

' . $this->t('Defaults to: %value', ['%value' => $this->messageManager->render(WebformMessageManagerInterface::SUBMISSION_EXCEPTION_MESSAGE)]), '#default_value' => $this->configuration['message'], ]; $form['additional']['messages_token'] = [ @@ -358,8 +359,8 @@ class RemotePostWebformHandler extends WebformHandlerBase { ]; $form['additional']['messages'] = [ '#type' => 'webform_multiple', - '#title' => $this->t('Custom error response messages'), - '#description' => $this->t('Enter custom response messages for specific status codes.') . '
' . $this->t('Defaults to: %value', ['%value' => $this->messageManager->render(WebformMessageManagerInterface::SUBMISSION_EXCEPTION_MESSAGE)]), + '#title' => $this->t('Custom response messages'), + '#description' => $this->t('Enter custom response messages for specific status codes.'), '#empty_items' => 0, '#no_items_message' => $this->t('No error response messages entered. Please add messages below.'), '#add' => FALSE, @@ -368,6 +369,9 @@ class RemotePostWebformHandler extends WebformHandlerBase { '#type' => 'webform_select_other', '#title' => $this->t('Response status code'), '#options' => [ + '200' => $this->t('200 OK'), + '201' => $this->t('201 Created'), + '204' => $this->t('204 No Content'), '400' => $this->t('400 Bad Request'), '401' => $this->t('401 Unauthorized'), '403' => $this->t('403 Forbidden'), @@ -517,11 +521,12 @@ class RemotePostWebformHandler extends WebformHandlerBase { } // Display submission exception if response code is not 2xx. - $status_code = $response->getStatusCode(); - if ($status_code < 200 || $status_code >= 300) { - $message = $this->t('Remote post request return @status_code status code.', ['@status_code' => $status_code]); + if ($this->responseHasError($response)) { + $message = $this->t('Remote post request return @status_code status code.', ['@status_code' => $response->getStatusCode()]); $this->handleError($state, $message, $request_url, $request_method, $request_type, $request_options, $response); return; + } else { + $this->displayCustomResponseMessage($response, FALSE); } // If debugging is enabled, display the request and response. @@ -1036,18 +1041,7 @@ class RemotePostWebformHandler extends WebformHandlerBase { ->error('@form webform remote @type post (@state) to @url failed. @message', $context); // Display custom or default exception message. - if ($custom_response_message = $this->getCustomResponseMessage($response)) { - $token_data = [ - 'webform_handler' => [ - $this->getHandlerId() => $this->getResponseData($response), - ], - ]; - $build_message = [ - '#markup' => $this->replaceTokens($custom_response_message, $this->getWebform(), $token_data), - ]; - $this->messenger()->addError(\Drupal::service('renderer')->renderPlain($build_message)); - } - else { + if (!$this->displayCustomResponseMessage($response, TRUE)) { $this->messageManager->display(WebformMessageManagerInterface::SUBMISSION_EXCEPTION_MESSAGE, 'error'); } @@ -1069,15 +1063,17 @@ class RemotePostWebformHandler extends WebformHandlerBase { } /** - * Get custom custom response message. + * Get custom response message. * * @param \Psr\Http\Message\ResponseInterface|null $response * The response returned by the remote server. + * @param bool $default + * Display the default message. Defaults to TRUE. * * @return string - * A custom custom response message. + * A custom response message. */ - protected function getCustomResponseMessage($response) { + protected function getCustomResponseMessage($response, $default = TRUE) { if ($response instanceof ResponseInterface) { $status_code = $response->getStatusCode(); foreach ($this->configuration['messages'] as $message_item) { @@ -1086,7 +1082,52 @@ class RemotePostWebformHandler extends WebformHandlerBase { } } } - return (!empty($this->configuration['message'])) ? $this->configuration['message'] : ''; + return ($default && !empty($this->configuration['message'])) ? $this->configuration['message'] : ''; + } + + /** + * Display custom response message. + * + * @param \Psr\Http\Message\ResponseInterface|null $response + * The response returned by the remote server. + * @param bool $default + * Display the default message. Defaults to TRUE. + * + * @return bool + * TRUE if custom response message is displayed. + */ + protected function displayCustomResponseMessage($response, $default = TRUE) { + $custom_response_message = $this->getCustomResponseMessage($response, $default); + if (!$custom_response_message) { + return FALSE; + } + + $token_data = [ + 'webform_handler' => [ + $this->getHandlerId() => $this->getResponseData($response), + ], + ]; + $build_message = [ + '#markup' => $this->replaceTokens($custom_response_message, $this->getWebform(), $token_data), + ]; + $message = \Drupal::service('renderer')->renderPlain($build_message); + $type = ($this->responseHasError($response)) ? MessengerInterface::TYPE_ERROR : MessengerInterface::TYPE_STATUS; + $this->messenger()->addMessage($message, $type); + return TRUE; + } + + /** + * Determine if response has an error status code. + * + * @param \Psr\Http\Message\ResponseInterface|null $response + * The response returned by the remote server. + * + * @return bool + * TRUE if response status code reflects an unsuccessful value. + */ + protected function responseHasError($response) { + $status_code = $response->getStatusCode(); + return $status_code < 200 || $status_code >= 300; } /** diff --git a/tests/modules/webform_test_handler_remote_post/config/install/webform.webform.test_handler_remote_post.yml b/tests/modules/webform_test_handler_remote_post/config/install/webform.webform.test_handler_remote_post.yml index c7a8abc4e..cecdc4cd7 100644 --- a/tests/modules/webform_test_handler_remote_post/config/install/webform.webform.test_handler_remote_post.yml +++ b/tests/modules/webform_test_handler_remote_post/config/install/webform.webform.test_handler_remote_post.yml @@ -20,6 +20,7 @@ elements: | '#type': select '#options': 200: '200 OK' + 201: '201 Completed' 401: '401 Unauthorized' 404: '404 Not Found' 500: '500 Internal Server Error' @@ -38,7 +39,7 @@ elements: | '#title': 'Confirmation number' '#type': value '#value': '[webform:handler:remote_post:completed:confirmation_number]' - + css: '' javascript: '' settings: @@ -129,7 +130,7 @@ settings: confirmation_title: '' confirmation_message: |

Your confirmation number is [webform_submission:values:confirmation_number].

- + confirmation_url: '' confirmation_attributes: { } confirmation_back: true @@ -238,43 +239,45 @@ handlers: confirmation_number: confirmation_number custom_data: | custom_data: true - + custom_options: | headers: 'Accept-Language': '[webform_submission:langcode]' custom_header: 'true' - + cast: false debug: true completed_url: 'http://webform-test-handler-remote-post/completed' completed_custom_data: | custom_completed: true - + updated_url: 'http://webform-test-handler-remote-post/updated' updated_custom_data: | custom_updated: true - + deleted_url: 'http://webform-test-handler-remote-post/deleted' deleted_custom_data: | custom_deleted: true - + draft_created_url: 'http://webform-test-handler-remote-post/draft_created' draft_created_custom_data: | custom_draft_created: true - + draft_updated_url: 'http://webform-test-handler-remote-post/draft_updated' draft_updated_custom_data: | custom_draft_updated: true - + converted_url: 'http://webform-test-handler-remote-post/converted' converted_custom_data: | custom_converted: true - + message: '' messages: - code: 401 message: 'This is a message token [webform:handler:remote_post:message]' - code: 404 message: 'This is a custom 404 not found message.' + - code: 200 + message: 'This is a custom 200 success message.' error_url: '' variants: { } diff --git a/tests/modules/webform_test_handler_remote_post/src/WebformTestHandlerRemotePostClient.php b/tests/modules/webform_test_handler_remote_post/src/WebformTestHandlerRemotePostClient.php index ace37b4ec..a4fffe411 100644 --- a/tests/modules/webform_test_handler_remote_post/src/WebformTestHandlerRemotePostClient.php +++ b/tests/modules/webform_test_handler_remote_post/src/WebformTestHandlerRemotePostClient.php @@ -61,6 +61,18 @@ class WebformTestHandlerRemotePostClient extends Client { ]; return new Response($status, $headers, Json::encode($json)); + case 201: + $status = 201; + $headers = ['Content-Type' => ['application/json']]; + $json = [ + 'method' => $method, + 'status' => 'success', + 'message' => (string) new FormattableMarkup('Process @type request.', ['@type' => $operation]), + 'options' => $options, + 'confirmation_number' => $random->name(20, TRUE), + ]; + return new Response($status, $headers, Json::encode($json)); + // 200 OK. case 200: default: diff --git a/tests/src/Functional/Handler/WebformHandlerRemotePostTest.php b/tests/src/Functional/Handler/WebformHandlerRemotePostTest.php index a02cf4974..22de03043 100644 --- a/tests/src/Functional/Handler/WebformHandlerRemotePostTest.php +++ b/tests/src/Functional/Handler/WebformHandlerRemotePostTest.php @@ -72,7 +72,7 @@ options: response_type: '200' first_name: John last_name: Smith"); - $this->assertRaw('Processed completed request.'); + $this->assertRaw('This is a custom 200 success message.'); // Check confirmation number is set via the // [webform:handler:remote_post:completed:confirmation_number] token. @@ -144,10 +144,19 @@ options: $this->assertRaw("sid: '$sid'"); $this->assertNoRaw('Unable to process this submission. Please contact the site administrator.'); + // Check 200 Success Error. + $this->postSubmission($webform, ['response_type' => '200']); + $this->assertRaw('This is a custom 200 success message.'); + $this->assertRaw('Processed completed request.'); + $this->assertRaw('messages--status'); + $this->assertNoRaw('messages--error'); + // Check 500 Internal Server Error. $this->postSubmission($webform, ['response_type' => '500']); $this->assertRaw('Failed to process completed request.'); $this->assertRaw('Unable to process this submission. Please contact the site administrator.'); + $this->assertRaw('messages--error'); + $this->assertNoRaw('messages--status'); // Check default custom response message. $handler = $webform->getHandler('remote_post'); @@ -160,11 +169,21 @@ options: $this->assertNoRaw('Unable to process this submission. Please contact the site administrator.'); $this->assertRaw('This is a custom response message'); + // Check 201 Completed with no custom message. + $this->postSubmission($webform, ['response_type' => '201']); + + $this->assertNoRaw('Processed created request.'); + $this->assertNoRaw('This is a custom 404 not found message.'); + $this->assertNoRaw('messages--status'); + $this->assertNoRaw('messages--error'); + // Check 404 Not Found with custom message. $this->postSubmission($webform, ['response_type' => '404']); $this->assertRaw('File not found'); $this->assertNoRaw('Unable to process this submission. Please contact the site administrator.'); $this->assertRaw('This is a custom 404 not found message.'); + $this->assertRaw('messages--error'); + $this->assertNoRaw('messages--status'); // Check 401 Unauthorized with custom message and token. $this->postSubmission($webform, ['response_type' => '401']);