diff --git a/core/lib/Drupal/Component/Utility/SafeMarkup.php b/core/lib/Drupal/Component/Utility/SafeMarkup.php index 69d12fe..fe4211b 100644 --- a/core/lib/Drupal/Component/Utility/SafeMarkup.php +++ b/core/lib/Drupal/Component/Utility/SafeMarkup.php @@ -329,4 +329,55 @@ public static function replace($search, $replace, $subject) { } } + /** + * Truncates an HTML string safely to a number of rendered text characters. + * + * Functions similarly to \Drupal\Component\Utility\Unicode::truncate(), + * but strips HTML tags prior to truncating and counts HTML entities (e.g., + * '&') as a single character. + * + * This function is intended for use on output, when it is desired to + * view truncated plain text (e.g., log messages in a list) in an HTML + * display. Because HTML entities are encoded after truncation, the + * returned string may contain more string characters than $max_length, so + * this is not a reliable function to use for truncating strings to a + * storage imposed maximum length. + * + * @param string $string + * The string to truncate. HTML tags are stripped prior to truncation. HTML + * entities are decoded prior to truncation and re-encoded after. + * @param int $max_length + * An upper limit on the returned text length when viewed as HTML, + * including trailing ellipsis if $add_ellipsis is TRUE. For purposes of + * this limit, each HTML entity is counted as a single character, so the + * returned string length may be longer. + * @param bool $wordsafe + * If TRUE, attempt to truncate on a word boundary. See Unicode::truncate() + * for details. + * @param bool $add_ellipsis + * If TRUE, add '...' to the end of the truncated string (defaults to + * FALSE). The text length will still fall within $max_length. + * @param int $min_wordsafe_length + * If $wordsafe is TRUE, the minimum acceptable length for truncation (before + * adding an ellipsis, if $add_ellipsis is TRUE). See Unicode::truncate() + * for details. + * + * @return string + * The truncated string, encoded for HTML display. + */ + public static function truncate($string, $max_length, $wordsafe = FALSE, $add_ellipsis = FALSE, $min_wordsafe_length = 1) { + // Strip tags prior to truncation, so that truncation doesn't need to + // handle unclosed tags, and retains the maximum allowable text characters. + $string = strip_tags($string); + + // Decode entities, so that truncation sees them as a single character. + $string = htmlspecialchars_decode($string, ENT_QUOTES); + + // Truncate. + $string = Unicode::truncate($string, $max_length, $wordsafe, $add_ellipsis, $min_wordsafe_length); + + // Re-encode entities. + return static::checkPlain($string); + } + } diff --git a/core/lib/Drupal/Component/Utility/Unicode.php b/core/lib/Drupal/Component/Utility/Unicode.php index 7691e00..4938b0d 100644 --- a/core/lib/Drupal/Component/Utility/Unicode.php +++ b/core/lib/Drupal/Component/Utility/Unicode.php @@ -508,7 +508,7 @@ public static function substr($text, $start, $length = NULL) { * @param bool $add_ellipsis * If TRUE, add '...' to the end of the truncated string (defaults to * FALSE). The string length will still fall within $max_length. - * @param bool $min_wordsafe_length + * @param int $min_wordsafe_length * If $wordsafe is TRUE, the minimum acceptable length for truncation (before * adding an ellipsis, if $add_ellipsis is TRUE). Has no effect if $wordsafe * is FALSE. This can be used to prevent having a very short resulting string diff --git a/core/modules/dblog/src/Controller/DbLogController.php b/core/modules/dblog/src/Controller/DbLogController.php index 2e2eccf..fd22e46 100644 --- a/core/modules/dblog/src/Controller/DbLogController.php +++ b/core/modules/dblog/src/Controller/DbLogController.php @@ -185,9 +185,7 @@ public function overview() { $message = $this->formatMessage($dblog); if ($message && isset($dblog->wid)) { // Truncate link_text to 56 chars of message. - // @todo Reevaluate the SafeMarkup::set() in - // https://www.drupal.org/node/2399261. - $log_text = SafeMarkup::set(Unicode::truncate(Xss::filter($message, array()), 56, TRUE, TRUE)); + $log_text = SafeMarkup::truncate($message, 56, TRUE, TRUE); $message = $this->l($log_text, new Url('dblog.event', array('event_id' => $dblog->wid), array( 'attributes' => array( // Provide a title for the link for useful hover hints.