Commit 9bf0a5d4 authored by jeffam's avatar jeffam Committed by Roderik Muit
Browse files

Issue #3262269 by jeffam, roderik, a-fro: Translate error messages

parent 1e5b1f1f
Loading
Loading
Loading
Loading
+11 −4
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@ use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Messenger\MessengerInterface;
use Drupal\Core\Path\PathValidatorInterface;
use Drupal\Core\Render\RendererInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\Url;
use Drupal\Core\Utility\Error;
use Drupal\Core\Utility\Token;
@@ -28,6 +29,7 @@ use Symfony\Component\HttpKernel\Exception\TooManyRequestsHttpException;
class SamlController extends ControllerBase {

  use ExecuteInRenderContextTrait;
  use StringTranslationTrait;

  /**
   * Name of the configuration object containing the setting used by this class.
@@ -334,7 +336,7 @@ class SamlController extends ControllerBase {
    if ($destination) {
      if (UrlHelper::isExternal($destination)) {
        // Disallow redirecting to an external URL after we log in.
        throw new UserVisibleException("Destination URL query parameter must not be external: $destination");
        throw new UserVisibleException('Destination URL query parameter must not be external: @destination', ['@destination' => $destination]);
      }
      $destination_url = $GLOBALS['base_url'] . '/' . $destination;

@@ -491,10 +493,15 @@ class SamlController extends ControllerBase {
    if ($exception instanceof UserVisibleException || $config->get('debug_display_error_details')) {
      // Show the full error on screen; also log, but with lowered severity.
      // Assume we don't need the "while" part for a user visible error because
      // it's likely not fully correct.
      // it's likely to not fully match the detailed message.
      $this->messenger->addError($exception->getMessage());
      if ($exception instanceof UserVisibleException) {
        $this->logger->warning($exception->getOriginalMessage(), $exception->getReplacements());
      }
      else {
        $this->logger->warning($exception->getMessage());
      }
    }
    else {
      // Use the same format for logging as Drupal's ExceptionLoggingSubscriber
      // except also specify where the error was encountered. (The options for
@@ -508,7 +515,7 @@ class SamlController extends ControllerBase {
      $this->logger->critical("%type encountered$while: @message in %function (line %line of %file).", $error);
      // Don't expose the error to prevent information leakage; the user likely
      // can't do much with it anyway. But hint that more details are available.
      $this->messenger->addError("Error encountered{$while}; details have been logged.");
      $this->messenger->addError($this->t("Error encountered{$while}; details have been logged."));
    }

    // Get error URL.
+80 −1
Original line number Diff line number Diff line
@@ -2,7 +2,86 @@

namespace Drupal\samlauth;

use Drupal\Core\StringTranslation\TranslatableMarkup;

/**
 * A RuntimeException that contains messages that are safe to expose to users.
 *
 * The message is translated into Drupal's current active language so that
 * getMessage() returns the translation.
 */
class UserVisibleException extends \RuntimeException {

  /**
   * The original (untranslated template) message passed in to the constructor.
   *
   * @var string
   */
  protected $originalMessage;

  /**
   * The replacement patterns passed into the constructor.
   *
   * @var array
   */
  protected $replacements;

  /**
   * UserVisibleException constructor.
   *
   * @param string $message
   *   Untranslated message which may contain placeholders.
   * @param array $args
   *   (optional) An associative array of replacements to make after
   *   translation. Using '@' for the first character of the keys is encouraged;
   *   '%' may come out strange when being rendered outside of HTML output. See
   *   \Drupal\Component\Render\FormattableMarkup::placeholderFormat() for
   *   details.
   * @param int $code
   *   (optional) The exception code.
   * @param \Throwable|null $previous
   *   (optional) The previous throwable used for the exception chaining.
   *
   * @see \Drupal\Component\Render\FormattableMarkup::placeholderFormat()
   */
class UserVisibleException extends \RuntimeException {}
  public function __construct($message = '', array $args = [], $code = 0, \Throwable $previous = NULL) {
    $this->originalMessage = $message;
    $this->replacements = $args;
    // The getMessage() method must return the translation and is 'final', so
    // we must set the already-translated message.
    $markup = new TranslatableMarkup($message, $args);
    parent::__construct($markup->render(), $code, $previous);
  }

  /**
   * Gets the untranslated message with any placeholders intact.
   *
   * @return string
   *   The untranslated message.
   */
  public function getOriginalMessage() {
    return $this->originalMessage;
  }

  /**
   * Gets the replacements array.
   *
   * @return array
   *   The replacements array.
   */
  public function getReplacements() {
    return $this->replacements;
  }

  /**
   * Updates the translation returned by getMessage().
   *
   * @param string $langcode
   *   The language code to translate the message into.
   */
  public function retranslate($langcode) {
    $markup = new TranslatableMarkup($this->originalMessage, $this->replacements, ['langcode' => $langcode]);
    $this->message = $markup->render();
  }

}