Skip to content

Instantly share code, notes, and snippets.

@ChVuagniaux
Last active April 25, 2017 14:37
Show Gist options
  • Save ChVuagniaux/6b10ed3157eaf2a0d50dce5478937841 to your computer and use it in GitHub Desktop.
Save ChVuagniaux/6b10ed3157eaf2a0d50dce5478937841 to your computer and use it in GitHub Desktop.
Cut HTML strings without breaking words and markup
<?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