Last active
April 25, 2017 14:37
-
-
Save ChVuagniaux/6b10ed3157eaf2a0d50dce5478937841 to your computer and use it in GitHub Desktop.
Cut HTML strings without breaking words and markup
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Cut HTML string before a max number of X chars without cutting a words or breaking the HTML markup. | |
* | |
* Try to cut after a </p> tag after 2/3 of the max length (for avoid to display only the first paraph) and if | |
* this fail Cut after the position of the last char of the last word just before the max length and add '...' | |
* at the end of the string | |
* | |
* usage : StrHelper::splitHtmlString($html, 1000); // For get a string that will never be bigger than 1000 chars | |
* | |
*/ | |
class StrHelper | |
{ | |
/** | |
* Get position of the last char of the last word just before the Word limit | |
* | |
* @param string $string | |
* @param int $maxSize | |
* | |
* @return int | |
*/ | |
public static function getPosLastWord($string, $maxSize) | |
{ | |
if (mb_strlen($string) <= $maxSize) | |
{ | |
return mb_strlen($string); | |
} | |
$words = explode(' ', $string); | |
$length = 0; | |
foreach ($words as $word) | |
{ | |
$wordLength = mb_strlen($word) + 1; | |
if (($length + $wordLength) >= $maxSize) | |
{ | |
return $length; | |
} | |
$length += $wordLength; | |
} | |
return $length; | |
} | |
/** | |
* Create needed HTML tags for close all opened | |
* | |
* @param string $html | |
* | |
* @return string | |
*/ | |
public static function repairString($html) | |
{ | |
$tidy = new Tidy(); | |
return $tidy->repairString($html, [ | |
'output-xml' => true, | |
'input-xml' => true | |
], 'utf8'); | |
} | |
/** | |
* Cut HTML string before a max number of $maxSize chars without cutting a words or breaking the HTML markup. | |
* | |
* Try to cut after a </p> tag after 2/3 of the max length (for avoid to display only the first paraph) and if | |
* this fail Cut after the position of the last char of the last word just before the max length and add '...' | |
* at the end of the string | |
* | |
* @param string $html | |
* @param int $maxSize | |
* | |
* @return string | |
*/ | |
public static function splitHtmlString($html, $maxSize) | |
{ | |
if (mb_strlen($html) <= $maxSize) | |
{ | |
return $html; | |
} | |
$posTagCloseParaph = mb_strpos($html, '</p>', ($maxSize / 3) * 2); | |
if ($posTagCloseParaph !== false && $posTagCloseParaph <= $maxSize) | |
{ | |
return self::repairString(mb_substr($html, 0, $posTagCloseParaph + 4)); | |
} | |
$lastWord = self::getPosLastWord($html, $maxSize); | |
if ($lastWord !== false) | |
{ | |
return self::repairString(mb_substr($html, 0, $lastWord) . '...'); | |
} | |
return $html; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment