Source for file string.php

Documentation is available at string.php

  1. <?php
  2. /**
  3.  * @package     Joomla.Platform
  4.  * @subpackage  HTML
  5.  *
  6.  * @copyright   Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
  7.  * @license     GNU General Public License version 2 or later; see LICENSE
  8.  */
  9.  
  10. defined('JPATH_PLATFORM'or die;
  11.  
  12. /**
  13.  * HTML helper class for rendering manipulated strings.
  14.  *
  15.  * @package     Joomla.Platform
  16.  * @subpackage  HTML
  17.  * @since       1.6
  18.  */
  19. abstract class JHtmlString
  20. {
  21.     /**
  22.      * Truncates text blocks over the specified character limit and closes
  23.      * all open HTML tags. The method will optionally not truncate an individual
  24.      * word, it will find the first space that is within the limit and
  25.      * truncate at that point. This method is UTF-8 safe.
  26.      *
  27.      * @param   string   $text       The text to truncate.
  28.      * @param   integer  $length     The maximum length of the text.
  29.      * @param   boolean  $noSplit    Don't split a word if that is where the cutoff occurs (default: true).
  30.      * @param   boolean  $allowHtml  Allow HTML tags in the output, and close any open tags (default: true).
  31.      *
  32.      * @return  string   The truncated text.
  33.      *
  34.      * @since   1.6
  35.      */
  36.     public static function truncate($text$length 0$noSplit true$allowHtml true)
  37.     {
  38.         // Assume a lone open tag is invalid HTML.
  39.         if ($length == && substr($text01== '<')
  40.         {
  41.             return '...';
  42.         }
  43.  
  44.         // Check if HTML tags are allowed.
  45.         if (!$allowHtml)
  46.         {
  47.             // Deal with spacing issues in the input.
  48.             $text str_replace('>''> '$text);
  49.             $text str_replace(array('&nbsp;''&#160;')' '$text);
  50.             $text JString::trim(preg_replace('#\s+#mui'' '$text));
  51.  
  52.             // Strip the tags from the input and decode entities.
  53.             $text strip_tags($text);
  54.             $text html_entity_decode($textENT_QUOTES'UTF-8');
  55.  
  56.             // Remove remaining extra spaces.
  57.             $text str_replace('&nbsp;'' '$text);
  58.             $text JString::trim(preg_replace('#\s+#mui'' '$text));
  59.         }
  60.  
  61.         // Whether or not allowing HTML, truncate the item text if it is too long.
  62.         if ($length && JString::strlen($text$length)
  63.         {
  64.             $tmp trim(JString::substr($text0$length));
  65.  
  66.             if (substr($tmp01== '<' && strpos($tmp'>'=== false)
  67.             {
  68.                 return '...';
  69.             }
  70.  
  71.             // $noSplit true means that we do not allow splitting of words.
  72.             if ($noSplit)
  73.             {
  74.                 // Find the position of the last space within the allowed length.
  75.                 $offset JString::strrpos($tmp' ');
  76.                 $tmp JString::substr($tmp0$offset 1);
  77.  
  78.                 // If there are no spaces and the string is longer than the maximum
  79.                 // we need to just use the ellipsis. In that case we are done.
  80.                 if ($offset === false && strlen($text$length)
  81.                 {
  82.                     return '...';
  83.                 }
  84.  
  85.                 if (JString::strlen($tmp$length 3)
  86.                 {
  87.                     $tmp trim(JString::substr($tmp0JString::strrpos($tmp' ')));
  88.                 }
  89.             }
  90.  
  91.             if ($allowHtml)
  92.             {
  93.                 // Put all opened tags into an array
  94.                 preg_match_all("#<([a-z][a-z0-9]*)\b.*?(?!/)>#i"$tmp$result);
  95.                 $openedTags $result[1];
  96.  
  97.                 // Some tags self close so they do not need a separate close tag.
  98.                 $openedTags array_diff($openedTagsarray("img""hr""br"));
  99.                 $openedTags array_values($openedTags);
  100.  
  101.                 // Put all closed tags into an array
  102.                 preg_match_all("#</([a-z]+)>#iU"$tmp$result);
  103.                 $closedTags $result[1];
  104.  
  105.                 $numOpened count($openedTags);
  106.  
  107.                 // All tags are closed so trim the text and finish.
  108.                 if (count($closedTags== $numOpened)
  109.                 {
  110.                     return trim($tmp'...';
  111.                 }
  112.  
  113.                 // Closing tags need to be in the reverse order of opening tags.
  114.                 $openedTags array_reverse($openedTags);
  115.  
  116.                 // Close tags
  117.                 for ($i 0$i $numOpened$i++)
  118.                 {
  119.                     if (!in_array($openedTags[$i]$closedTags))
  120.                     {
  121.                         $tmp .= "</" $openedTags[$i">";
  122.                     }
  123.                     else
  124.                     {
  125.                         unset($closedTags[array_search($openedTags[$i]$closedTags)]);
  126.                     }
  127.                 }
  128.             }
  129.  
  130.             if ($tmp === false || strlen($textstrlen($tmp))
  131.             {
  132.                 $text trim($tmp'...';
  133.             }
  134.         }
  135.  
  136.         // Clean up any internal spaces created by the processing.
  137.         $text str_replace(' </''</'$text);
  138.         $text str_replace(' ...''...'$text);
  139.  
  140.         return $text;
  141.     }
  142.  
  143.     /**
  144.     * Method to extend the truncate method to more complex situations
  145.     *
  146.     * The goal is to get the proper length plain text string with as much of
  147.     * the html intact as possible with all tags properly closed.
  148.     *
  149.     * @param   string   $html       The content of the introtext to be truncated
  150.     * @param   integer  $maxLength  The maximum number of characters to render
  151.     * @param   boolean  $noSplit    Don't split a word if that is where the cutoff occurs (default: true).
  152.     *
  153.     * @return  string  The truncated string. If the string is truncated an ellipsis
  154.     *                   (...) will be appended.
  155.     *
  156.     * @note    If a maximum length of 3 or less is selected and the text has more than
  157.     *           that number of characters an ellipsis will be displayed.
  158.     *           This method will not create valid HTML from malformed HTML.
  159.     *
  160.     * @since   3.1
  161.     */
  162.     public static function truncateComplex($html$maxLength 0$noSplit true)
  163.     {
  164.         // Start with some basic rules.
  165.         $baseLength strlen($html);
  166.  
  167.         // If the original HTML string is shorter than the $maxLength do nothing and return that.
  168.         if ($baseLength <= $maxLength || $maxLength == 0)
  169.         {
  170.             return $html;
  171.         }
  172.  
  173.         // Take care of short simple cases.
  174.         if ($maxLength <= && substr($html01!= '<' && strpos(substr($html0$maxLength 1)'<'=== false && $baseLength $maxLength)
  175.         {
  176.             return '...';
  177.         }
  178.  
  179.         // Deal with maximum length of 1 where the string starts with a tag.
  180.         if ($maxLength == && substr($html01== '<')
  181.         {
  182.             $endTagPos strlen(strstr($html'>'true));
  183.             $tag substr($html1$endTagPos);
  184.  
  185.             $l $endTagPos 1;
  186.  
  187.             if ($noSplit)
  188.             {
  189.                 return substr($html0$l'</' $tag '...';
  190.             }
  191.  
  192.             // TODO: $character doesn't seem to be used...
  193.             $character substr(strip_tags($html)01);
  194.  
  195.             return substr($html0$l'</' $tag '...';
  196.         }
  197.  
  198.         // First get the truncated plain text string. This is the rendered text we want to end up with.
  199.         $ptString JHtml::_('string.truncate'$html$maxLength$noSplit$allowHtml false);
  200.  
  201.         // It's all HTML, just return it.
  202.         if (strlen($ptString== 0)
  203.         {
  204.                 return $html;
  205.         }
  206.  
  207.         // If the plain text is shorter than the max length the variable will not end in ...
  208.         // In that case we use the whole string.
  209.         if (substr($ptString-3!= '...')
  210.         {
  211.                 return $html;
  212.         }
  213.  
  214.         // Regular truncate gives us the ellipsis but we want to go back for text and tags.
  215.         if ($ptString == '...')
  216.         {
  217.             $stripped substr(strip_tags($html)0$maxLength);
  218.             $ptString JHtml::_('string.truncate'$stripped$maxLength$noSplit$allowHtml false);
  219.         }
  220.  
  221.         // We need to trim the ellipsis that truncate adds.
  222.         $ptString rtrim($ptString'.');
  223.  
  224.         // Now deal with more complex truncation.
  225.         while ($maxLength <= $baseLength)
  226.         {
  227.             // Get the truncated string assuming HTML is allowed.
  228.             $htmlString JHtml::_('string.truncate'$html$maxLength$noSplit$allowHtml true);
  229.  
  230.             if ($htmlString == '...' && strlen($ptString$maxLength)
  231.             {
  232.                 return $htmlString;
  233.             }
  234.  
  235.             $htmlString rtrim($htmlString'.');
  236.  
  237.             // Now get the plain text from the HTML string and trim it.
  238.             $htmlStringToPtString JHtml::_('string.truncate'$htmlString$maxLength$noSplit$allowHtml false);
  239.             $htmlStringToPtString rtrim($htmlStringToPtString'.');
  240.  
  241.             // If the new plain text string matches the original plain text string we are done.
  242.             if ($ptString == $htmlStringToPtString)
  243.             {
  244.                 return $htmlString '...';
  245.             }
  246.  
  247.             // Get the number of HTML tag characters in the first $maxLength characters
  248.             $diffLength strlen($ptStringstrlen($htmlStringToPtString);
  249.  
  250.             if ($diffLength <= 0)
  251.             {
  252.                 return $htmlString '...';
  253.             }
  254.  
  255.             // Set new $maxlength that adjusts for the HTML tags
  256.             $maxLength += $diffLength;
  257.         }
  258.     }
  259.  
  260.     /**
  261.      * Abridges text strings over the specified character limit. The
  262.      * behavior will insert an ellipsis into the text replacing a section
  263.      * of variable size to ensure the string does not exceed the defined
  264.      * maximum length. This method is UTF-8 safe.
  265.      *
  266.      * For example, it transforms "Really long title" to "Really...title".
  267.      *
  268.      * Note that this method does not scan for HTML tags so will potentially break them.
  269.      *
  270.      * @param   string   $text    The text to abridge.
  271.      * @param   integer  $length  The maximum length of the text (default is 50).
  272.      * @param   integer  $intro   The maximum length of the intro text (default is 30).
  273.      *
  274.      * @return  string   The abridged text.
  275.      *
  276.      * @since   1.6
  277.      */
  278.     public static function abridge($text$length 50$intro 30)
  279.     {
  280.         // Abridge the item text if it is too long.
  281.         if (JString::strlen($text$length)
  282.         {
  283.             // Determine the remaining text length.
  284.             $remainder $length ($intro 3);
  285.  
  286.             // Extract the beginning and ending text sections.
  287.             $beg JString::substr($text0$intro);
  288.             $end JString::substr($textJString::strlen($text$remainder);
  289.  
  290.             // Build the resulting string.
  291.             $text $beg '...' $end;
  292.         }
  293.  
  294.         return $text;
  295.     }
  296. }

Documentation generated on Tue, 19 Nov 2013 15:14:32 +0100 by phpDocumentor 1.4.3