From 04966aa03b9854fcb32f4aea9c1e2f285ea197e3 Mon Sep 17 00:00:00 2001
From: Alex Pott <alex.a.pott@googlemail.com>
Date: Tue, 27 Oct 2015 12:46:40 +0000
Subject: [PATCH] =?UTF-8?q?Issue=20#2578377=20by=20YesCT,=20jhodgdon,=20G?=
 =?UTF-8?q?=C3=A1bor=20Hojtsy,=20alexpott,=20herom,=20xjm:=20Make=20transl?=
 =?UTF-8?q?atable=20docs=20consolidated=20and=20better=20for=20developers?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 core/includes/bootstrap.inc                   | 71 ++++++---------
 .../StringTranslationTrait.php                | 36 +++++++-
 .../StringTranslation/TranslatableMarkup.php  | 87 ++++++++++++++++---
 .../TranslationInterface.php                  | 36 +++++---
 .../StringTranslation/TranslationManager.php  |  2 +-
 core/misc/drupal.js                           |  2 +-
 .../TranslationManagerTest.php                |  2 +-
 7 files changed, 159 insertions(+), 77 deletions(-)

diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc
index 019beafa7216..289d5a935057 100644
--- a/core/includes/bootstrap.inc
+++ b/core/includes/bootstrap.inc
@@ -258,56 +258,39 @@ function drupal_get_path($type, $name) {
 /**
  * Translates a string to the current language or to a given language.
  *
- * The t() function serves two purposes. First, at run-time it translates
- * user-visible text into the appropriate language. Second, various mechanisms
- * that figure out what text needs to be translated work off t() -- the text
- * inside t() calls is added to the database of strings to be translated.
- * These strings are expected to be in English, so the first argument should
- * always be in English. To allow the site to be localized, it is important that
- * all human-readable text that will be displayed on the site or sent to a user
- * is passed through the t() function, or a related function. See the
- * @link https://www.drupal.org/node/322729 Localization API @endlink pages for
- * more information, including recommendations on how to break up or not
- * break up strings for translation.
- *
- * @section sec_translating_vars Translating Variables
- * You should never use t() to translate variables, such as calling t($text)
- * unless the text that the variable holds has been passed through t()
- * elsewhere (e.g., $text is one of several translated literal strings in an
- * array). It is especially important never to call t($user_text) where
- * $user_text is some text that a user entered - doing that can lead to
- * cross-site scripting and other security problems. However, you can use
- * variable substitution in your string, to put variable text such as user
- * names or link URLs into translated text. Variable substitution looks like
- * this:
- * @code
- * $text = t("@name's blog", array('@name' => $account->getDisplayName()));
- * @endcode
- * Basically, you can put variables like @name into your string, and t() will
- * substitute their sanitized values at translation time. (See the
- * Localization API pages referenced above and the documentation of
- * \Drupal\Component\Utility\SafeMarkup::format() for details about how to
- * define variables in your string.). Translators can then rearrange the string
- * as necessary for the language (e.g., in Spanish, it might be "blog de
- * @name").
- *
- * @param $string
- *   A string containing the English string to translate.
- * @param $args
- *   An associative array of replacements to make after translation. Based
- *   on the first character of the key, the value is escaped and/or themed.
- *   See \Drupal\Component\Utility\SafeMarkup::format() for details.
- * @param $options
- *   An associative array of additional options, with the following elements:
- *   - 'langcode' (defaults to the current language): The language code to
+ * In order for strings to be localized, make them available in one of the ways
+ * supported by the
+ * @link https://www.drupal.org/node/322729 Localization API @endlink. When
+ * possible, use the \Drupal\Core\StringTranslation\StringTranslationTrait
+ * $this->t(). Otherwise create a new
+ * \Drupal\Core\StringTranslation\TranslatableMarkup object directly.
+ *
+ * See \Drupal\Core\StringTranslation\TranslatableMarkup::__construct() for
+ * important security information and usage guidelines.
+ *
+ * @param string $string
+ *   A string containing the English text to translate.
+ * @param array $args
+ *   (optional) An associative array of replacements to make after translation.
+ *   Based on the first character of the key, the value is escaped and/or
+ *   themed. See
+ *   \Drupal\Component\Render\FormattableMarkup::placeholderFormat() for
+ *   details.
+ * @param array $options
+ *   (optional) An associative array of additional options, with the following
+ *   elements:
+ *   - 'langcode' (defaults to the current language): A language code, to
  *     translate to a language other than what is used to display the page.
  *   - 'context' (defaults to the empty context): The context the source string
  *     belongs to.
  *
  * @return \Drupal\Core\StringTranslation\TranslatableMarkup
- *   An object that, when cast to a string, will yield the translated string.
+ *   An object that, when cast to a string, returns the translated string.
+ *
+ * @see \Drupal\Component\Render\FormattableMarkup::placeholderFormat()
+ * @see \Drupal\Core\StringTranslation\StringTranslationTrait::t()
+ * @see \Drupal\Core\StringTranslation\TranslatableMarkup::__construct()
  *
- * @see \Drupal\Component\Utility\SafeMarkup::format()
  * @ingroup sanitization
  */
 function t($string, array $args = array(), array $options = array()) {
diff --git a/core/lib/Drupal/Core/StringTranslation/StringTranslationTrait.php b/core/lib/Drupal/Core/StringTranslation/StringTranslationTrait.php
index 53e1f6f54cfd..aae4d4535ae6 100644
--- a/core/lib/Drupal/Core/StringTranslation/StringTranslationTrait.php
+++ b/core/lib/Drupal/Core/StringTranslation/StringTranslationTrait.php
@@ -36,11 +36,39 @@ trait StringTranslationTrait {
   /**
    * Translates a string to the current language or to a given language.
    *
-   * See the t() documentation for details.
+   * See \Drupal\Core\StringTranslation\TranslatableMarkup::__construct() for
+   * important security information and usage guidelines.
    *
-   * Never call $this->t($user_text) where $user_text is text that a user
-   * entered; doing so can lead to cross-site scripting and other security
-   * problems.
+   * In order for strings to be localized, make them available in one of the
+   * ways supported by the
+   * @link https://www.drupal.org/node/322729 Localization API @endlink. When
+   * possible, use the \Drupal\Core\StringTranslation\StringTranslationTrait
+   * $this->t(). Otherwise create a new
+   * \Drupal\Core\StringTranslation\TranslatableMarkup object.
+   *
+   * @param string $string
+   *   A string containing the English text to translate.
+   * @param array $args
+   *   (optional) An associative array of replacements to make after
+   *   translation. Based on the first character of the key, the value is
+   *   escaped and/or themed. See
+   *   \Drupal\Component\Render\FormattableMarkup::placeholderFormat() for
+   *   details.
+   * @param array $options
+   *   (optional) An associative array of additional options, with the following
+   *   elements:
+   *   - 'langcode' (defaults to the current language): A language code, to
+   *     translate to a language other than what is used to display the page.
+   *   - 'context' (defaults to the empty context): The context the source
+   *     string belongs to.
+   *
+   * @return \Drupal\Core\StringTranslation\TranslatableMarkup
+   *   An object that, when cast to a string, returns the translated string.
+   *
+   * @see \Drupal\Component\Render\FormattableMarkup::placeholderFormat()
+   * @see \Drupal\Core\StringTranslation\TranslatableMarkup::__construct()
+   *
+   * @ingroup sanitization
    */
   protected function t($string, array $args = array(), array $options = array()) {
     return $this->getStringTranslation()->translate($string, $args, $options);
diff --git a/core/lib/Drupal/Core/StringTranslation/TranslatableMarkup.php b/core/lib/Drupal/Core/StringTranslation/TranslatableMarkup.php
index 13d3a64b2eb9..024c3a42a303 100644
--- a/core/lib/Drupal/Core/StringTranslation/TranslatableMarkup.php
+++ b/core/lib/Drupal/Core/StringTranslation/TranslatableMarkup.php
@@ -13,13 +13,13 @@
 /**
  * Provides translatable markup class.
  *
- * This class delays translation until rendering.
+ * This object, when cast to a string, will return the formatted, translated
+ * string. Avoid casting it to a string yourself, because it is preferable to
+ * let the rendering system do the cast as late as possible in the rendering
+ * process, so that this object itself can be put, untranslated, into render
+ * caches and thus the cache can be shared between different language contexts.
  *
- * This is useful for using translation in very low level subsystems like entity
- * definition and stream wrappers.
- *
- * @see \Drupal\Component\Render\FormattableMarkup::placeholderFormat()
- * @see \Drupal\Core\StringTranslation\TranslationManager::translate()
+ * @see \Drupal\Component\Render\FormattableMarkup
  * @see \Drupal\Core\StringTranslation\TranslationManager::translateString()
  * @see \Drupal\Core\Annotation\Translation
  */
@@ -58,17 +58,75 @@ class TranslatableMarkup extends FormattableMarkup {
   /**
    * Constructs a new class instance.
    *
-   * Parses values passed into this class through the t() function in Drupal and
-   * handles an optional context for the string.
+   * When possible, use the
+   * \Drupal\Core\StringTranslation\StringTranslationTrait $this->t(). Otherwise
+   * create a new \Drupal\Core\StringTranslation\TranslatableMarkup object
+   * directly.
+   *
+   * Calling the trait's t() method or instantiating a new TranslatableMarkup
+   * object serves two purposes:
+   * - At run-time it translates user-visible text into the appropriate
+   *   language.
+   * - Static analyzers detect calls to t() and new TranslatableMarkup, and add
+   *   the first argument (the string to be translated) to the database of
+   *   strings that need translation. These strings are expected to be in
+   *   English, so the first argument should always be in English.
+   * To allow the site to be localized, it is important that all human-readable
+   * text that will be displayed on the site or sent to a user is made available
+   * in one of the ways supported by the
+   * @link https://www.drupal.org/node/322729 Localization API @endlink.
+   * See the @link https://www.drupal.org/node/322729 Localization API @endlink
+   * pages for more information, including recommendations on how to break up or
+   * not break up strings for translation.
+   *
+   * @section sec_translating_vars Translating Variables
+   * $string should always be an English literal string.
+   *
+   * $string should never contain a variable, such as:
+   * @code
+   * new TranslatableMarkup($text)
+   * @endcode
+   * There are several reasons for this:
+   * - Using a variable for $string that is user input is a security risk.
+   * - Using a variable for $string that has even guaranteed safe text (for
+   *   example, user interface text provided literally in code), will not be
+   *   picked up by the localization static text processor. (The parameter could
+   *   be a variable if the entire string in $text has been passed into t() or
+   *   new TranslatableMarkup() elsewhere as the first argument, but that
+   *   strategy is not recommended.)
+   *
+   * It is especially important never to call new TranslatableMarkup($user_text)
+   * or t($user_text) where $user_text is some text that a user entered -- doing
+   * that can lead to cross-site scripting and other security problems. However,
+   * you can use variable substitution in your string, to put variable text such
+   * as user names or link URLs into translated text. Variable substitution
+   * looks like this:
+   * @code
+   * new TranslatableMarkup("@name's blog", array('@name' => $account->getDisplayName()));
+   * @endcode
+   * Basically, you can put placeholders like @name into your string, and the
+   * method will substitute the sanitized values at translation time. (See the
+   * Localization API pages referenced above and the documentation of
+   * \Drupal\Component\Render\FormattableMarkup::placeholderFormat()
+   * for details about how to safely and correctly define variables in your
+   * string.) Translators can then rearrange the string as necessary for the
+   * language (e.g., in Spanish, it might be "blog de @name").
    *
    * @param string $string
-   *   The string that is to be translated.
+   *   A string containing the English text to translate.
    * @param array $arguments
-   *   (optional) An array with placeholder replacements, keyed by placeholder.
-   *   See \Drupal\Component\Render\FormattableMarkup::placeholderFormat() for
-   *   additional information about placeholders.
+   *   (optional) An associative array of replacements to make after
+   *   translation. Based on the first character of the key, the value is
+   *   escaped and/or themed. See
+   *   \Drupal\Component\Render\FormattableMarkup::placeholderFormat() for
+   *   details.
    * @param array $options
-   *   (optional) An array of additional options.
+   *   (optional) An associative array of additional options, with the following
+   *   elements:
+   *   - 'langcode' (defaults to the current language): A language code, to
+   *     translate to a language other than what is used to display the page.
+   *   - 'context' (defaults to the empty context): The context the source
+   *     string belongs to.
    * @param \Drupal\Core\StringTranslation\TranslationInterface $string_translation
    *   (optional) The string translation service.
    *
@@ -76,6 +134,9 @@ class TranslatableMarkup extends FormattableMarkup {
    *   Exception thrown when $string is not a string.
    *
    * @see \Drupal\Component\Render\FormattableMarkup::placeholderFormat()
+   * @see \Drupal\Core\StringTranslation\StringTranslationTrait::t()
+   *
+   * @ingroup sanitization
    */
   public function __construct($string, array $arguments = array(), array $options = array(), TranslationInterface $string_translation = NULL) {
     if (!is_string($string)) {
diff --git a/core/lib/Drupal/Core/StringTranslation/TranslationInterface.php b/core/lib/Drupal/Core/StringTranslation/TranslationInterface.php
index 1944ecbc3fde..cbee36f72fa8 100644
--- a/core/lib/Drupal/Core/StringTranslation/TranslationInterface.php
+++ b/core/lib/Drupal/Core/StringTranslation/TranslationInterface.php
@@ -17,26 +17,36 @@ interface TranslationInterface {
   /**
    * Translates a string to the current language or to a given language.
    *
-   * Never call translate($user_text) where $user_text is text that a user
-   * entered; doing so can lead to cross-site scripting and other security
-   * problems.
+   * Never call this translate() method directly. In order for strings to be
+   * localized, make them available in one of the ways supported by the
+   * @link https://www.drupal.org/node/322729 Localization API @endlink. When
+   * possible, use the \Drupal\Core\StringTranslation\StringTranslationTrait
+   * $this->t(). Otherwise create a new
+   * \Drupal\Core\StringTranslation\TranslatableMarkup object.
    *
    * @param string $string
-   *   A string containing the English string to translate.
+   *   A string containing the English text to translate.
    * @param array $args
-   *   An associative array of replacements to make after translation. Based
-   *   on the first character of the key, the value is escaped and/or themed.
-   *   See \Drupal\Component\Utility\SafeMarkup::format() for details.
+   *   (optional) An associative array of replacements to make after
+   *   translation. Based on the first character of the key, the value is
+   *   escaped and/or themed. See
+   *   \Drupal\Component\Render\FormattableMarkup::placeholderFormat() for
+   *   details.
    * @param array $options
-   *   An associative array of additional options, with the following elements:
-   *   - 'langcode': The language code to translate to a language other than
-   *      what is used to display the page.
-   *   - 'context': The context the source string belongs to.
+   *   (optional) An associative array of additional options, with the following
+   *   elements:
+   *   - 'langcode' (defaults to the current language): A language code, to
+   *     translate to a language other than what is used to display the page.
+   *   - 'context' (defaults to the empty context): The context the source
+   *     string belongs to.
    *
    * @return \Drupal\Core\StringTranslation\TranslatableMarkup
-   *   An object that, when cast to a string, will yield the translated string.
+   *   An object that, when cast to a string, returns the translated string.
    *
-   * @see \Drupal\Component\Utility\SafeMarkup::format()
+   * @see \Drupal\Component\Render\FormattableMarkup::placeholderFormat()
+   * @see \Drupal\Core\StringTranslation\TranslatableMarkup::__construct()
+   *
+   * @ingroup sanitization
    */
   public function translate($string, array $args = array(), array $options = array());
 
diff --git a/core/lib/Drupal/Core/StringTranslation/TranslationManager.php b/core/lib/Drupal/Core/StringTranslation/TranslationManager.php
index 9d3966b02c1b..e9962d6eb527 100644
--- a/core/lib/Drupal/Core/StringTranslation/TranslationManager.php
+++ b/core/lib/Drupal/Core/StringTranslation/TranslationManager.php
@@ -123,7 +123,7 @@ public function translateString(TranslatableMarkup $translated_string) {
    * Translates a string to the current language or to a given language.
    *
    * @param string $string
-   *   A string containing the English string to translate.
+   *   A string containing the English text to translate.
    * @param array $options
    *   An associative array of additional options, with the following elements:
    *   - 'langcode': The language code to translate to a language other than
diff --git a/core/misc/drupal.js b/core/misc/drupal.js
index f1f7d6f5dcc8..f19fc431499f 100644
--- a/core/misc/drupal.js
+++ b/core/misc/drupal.js
@@ -362,7 +362,7 @@ if (window.jQuery) {
    * See the documentation of the server-side t() function for further details.
    *
    * @param {string} str
-   *   A string containing the English string to translate.
+   *   A string containing the English text to translate.
    * @param {Object.<string, string>} [args]
    *   An object of replacements pairs to make after translation. Incidences
    *   of any key in this array are replaced with the corresponding value.
diff --git a/core/tests/Drupal/Tests/Core/StringTranslation/TranslationManagerTest.php b/core/tests/Drupal/Tests/Core/StringTranslation/TranslationManagerTest.php
index 305963daaa91..1a99bbf3a801 100644
--- a/core/tests/Drupal/Tests/Core/StringTranslation/TranslationManagerTest.php
+++ b/core/tests/Drupal/Tests/Core/StringTranslation/TranslationManagerTest.php
@@ -66,7 +66,7 @@ public function testFormatPlural($count, $singular, $plural, array $args = array
    * Tests translation using placeholders.
    *
    * @param string $string
-   *   A string containing the English string to translate.
+   *   A string containing the English text to translate.
    * @param array $args
    *   An associative array of replacements to make after translation.
    * @param string $expected_string
-- 
GitLab