Skip to content

Instantly share code, notes, and snippets.

@nghuuphuoc
Created April 3, 2014 04:36
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save nghuuphuoc/9948331 to your computer and use it in GitHub Desktop.
Highlight a keyword without breaking tag
// $value is the original string
// $keyword is the searching keyword
function highlight($value, $keyword) {
try {
$dom = new DomDocument();
@$dom->loadHtml($value);
$xpath = new DomXpath($dom);
$upper = strtoupper(addslashes($keyword));
$lower = strtolower(addslashes($keyword));
// Support i-case sensitive using translate method provided by XPath 1.0
$query = '//*[contains(translate(., "' . $upper . '", "' . $lower . '"), "' . $lower . '")]';
$elements = $xpath->query($query);
foreach ($elements as $element) {
foreach ($element->childNodes as $child) {
if (!$child instanceof DomText) {
continue;
}
$fragment = $dom->createDocumentFragment();
$text = $child->textContent;
while (($pos = stripos($text, $keyword)) !== false) {
$fragment->appendChild(new DomText(substr($text, 0, $pos)));
$word = substr($text, $pos, strlen($keyword));
// Create a SPAN element
$highlight = $dom->createElement('span');
$highlight->appendChild(new DomText($word));
$highlight->setAttribute('class', 'coreFiltersHighlight');
$fragment->appendChild($highlight);
$text = substr($text, $pos + strlen($keyword));
}
if (!empty($text)) {
$fragment->appendChild(new DomText($text));
}
// Replace the text node element with the new one that contains the SPAN tag
$element->replaceChild($fragment, $child);
}
}
return $dom->saveXml($dom->getElementsByTagName('body')->item(0)->firstChild);
} catch (Exception $ex) {
return preg_replace('/(?![^<>]*>)' . preg_quote($keyword, '/') . '/i', '<span class="highlight">' . $keyword . '</span>', $value);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment