protected function GlossifyBase::parseTooltipMatch in Glossify 8
Convert terms in text to links.
Parameters
string $text: The HTML text upon which the filter is acting.
array $terms: The terms (array) to be replaced with links. structure: [$termname_lower => [ ['id' => $id], ['name' => $term], ['name_norm' => $termname_lower], ['tip' => $tooltip], ]].
bool $case_sensitivity: Case sensitive replace.
bool $first_only: Replace only first match.
string $displaytype: Type of tooltip/link.
string $urlpattern: URL pattern to create links.
Return value
string The original HTML with the term string replaced by links.
3 calls to GlossifyBase::parseTooltipMatch()
- DummyTooltip::process in tests/
src/ Unit/ GlossifyBaseTest.php - Performs the filter processing.
- NodeTooltip::process in modules/
glossify_node/ src/ Plugin/ Filter/ NodeTooltip.php - Performs the filter processing.
- TaxonomyTooltip::process in modules/
glossify_taxonomy/ src/ Plugin/ Filter/ TaxonomyTooltip.php - Performs the filter processing.
File
- src/
GlossifyBase.php, line 42
Class
- GlossifyBase
- Base implementation of tooltip filter type plugin.
Namespace
Drupal\glossifyCode
protected function parseTooltipMatch($text, array $terms, $case_sensitivity, $first_only, $displaytype, $urlpattern) {
// Create dom document.
$html_dom = Html::load($text);
$xpath = new DOMXPath($html_dom);
$pattern_parts = $replaced = [];
// Transform terms into normalized search pattern.
foreach ($terms as $term) {
$term_norm = preg_replace('/\\s+/', ' ', preg_quote(trim($term->name_norm)));
$term_norm = preg_replace('#/#', '\\/', $term_norm);
$pattern_parts[] = preg_replace('/ /', '\\s+', $term_norm);
}
// Process HTML.
$text_nodes = $xpath
->query('//text()[not(ancestor::a) and not(ancestor::span[@class="glossify-exclude"])]');
foreach ($text_nodes as $original_node) {
$text = $original_node->nodeValue;
$matches = [];
foreach ($pattern_parts as $pattern_part) {
$pattern = '/\\b(' . $pattern_part . ')\\b/';
if (!$case_sensitivity) {
$pattern .= 'i';
}
preg_match_all($pattern, $text, $matches_part, PREG_OFFSET_CAPTURE);
if (count($matches_part[0])) {
foreach ($matches_part[0] as $match_part) {
$matches[$match_part[1]] = $match_part[0];
}
}
}
// Sort by position in text.
ksort($matches);
if (count($matches) > 0) {
$offset = $loop_count = 0;
$parent = $original_node->parentNode;
$refnode = $original_node->nextSibling;
$current_path = $this
->currentPath();
$parent
->removeChild($original_node);
foreach ($matches as $term_pos => $term_txt) {
$loop_count += 1;
$term_txt = preg_replace('/\\s+/', ' ', $term_txt);
$terms_key = $case_sensitivity ? $term_txt : strtolower($term_txt);
// Insert any text before the term instance.
$prefix = substr($text, $offset, $term_pos - $offset);
$parent
->insertBefore($html_dom
->createTextNode($prefix), $refnode);
$dom_fragment = $html_dom
->createDocumentFragment();
if ($current_path == str_replace('[id]', $terms[$terms_key]->id, $urlpattern)) {
// Reinsert the found match if whe are on the page
// this match points to.
$dom_fragment
->appendXML($term_txt);
}
elseif ($first_only && in_array($term_txt, $replaced)) {
// Reinsert the found match if only first match must be parsed.
$dom_fragment
->appendXML($term_txt);
}
else {
$tip = '';
if ($displaytype == 'links' || $displaytype == 'tooltips_links') {
// Insert the matched term instance as link.
if ($displaytype == 'tooltips_links') {
$tip = $this
->sanitizeTip($terms[$terms_key]->tip);
}
if (\Drupal::hasContainer()) {
$tipurl = Url::fromUri('internal:' . str_replace('[id]', $terms[$terms_key]->id, $urlpattern));
}
else {
$tipurl = str_replace('[id]', $terms[$terms_key]->id, $urlpattern);
}
$word_link = [
'#theme' => 'glossify_link',
'#word' => $term_txt,
'#tip' => $tip,
'#tipurl' => $tipurl,
];
$word = $this
->renderLink($word_link);
}
else {
// Has to be 'tooltips'.
// Insert the matched term instance as tooltip.
$tip = $this
->sanitizeTip($terms[$terms_key]->tip);
$word_tip = [
'#theme' => 'glossify_tooltip',
'#word' => $term_txt,
'#tip' => $tip,
];
$word = $this
->renderTip($word_tip);
}
$dom_fragment
->appendXML($word);
$replaced[] = $term_txt;
}
$parent
->insertBefore($dom_fragment, $refnode);
$offset = $term_pos + strlen($term_txt);
// Last match, append remaining text.
if ($loop_count == count($matches)) {
$suffix = substr($text, $offset);
$parent
->insertBefore($html_dom
->createTextNode($suffix), $refnode);
}
}
}
}
return Html::serialize($html_dom);
}