function word_link_replace_text in Word Link 8
Same name and namespace in other branches
- 7 word_link.module \word_link_replace_text()
Find and replace defined word to link.
2 calls to word_link_replace_text()
- word_link_comment_view in ./
word_link.module - Implements hook_comment_view().
- word_link_node_view in ./
word_link.module - Implements hook_node_view().
File
- ./
word_link.module, line 187 - This module allows users to replace previously defined words to the links.
Code
function word_link_replace_text($words, $subject, $langcode = NULL) {
// Get disallowed html tags and explode it to array.
$disallowed_tags = variable_get('word_link_tags_except', NULL);
$disallowed_tags = preg_split('/\\s+|<|>/', $disallowed_tags, -1, PREG_SPLIT_NO_EMPTY);
if (!empty($disallowed_tags)) {
foreach ($disallowed_tags as $ancestor) {
$not[] = 'and not(ancestor::' . $ancestor . ')';
}
$not = implode(' ', $not);
}
else {
$not = '';
}
// Get word link limit.
$limit = variable_get('word_link_limit', 0);
$preg_limit = $limit == 0 ? -1 : $limit;
$current_path = current_path();
$path = drupal_strtolower(drupal_container()
->get('path.alias_manager')
->getPathAlias($current_path, $langcode));
foreach ($words as $word) {
$url = drupal_container()
->get('path.alias_manager')
->getPathAlias($word->url, $langcode);
$match = FALSE;
if (!empty($word->except)) {
$match = drupal_match_path($path, $word->except);
if ($path != $current_path) {
$match = $match || drupal_match_path($current_path, $word->except);
}
}
$visibility = empty($word->except) ? FALSE : $word->visibility;
if ($url != $path && !$match && !$visibility || $url != $path && $visibility && $match) {
// Build a link.
$pattern = '$0';
if (strpos($word->url, 'http://') === 0 || strpos($word->url, 'https://') === 0) {
$replace[] = l($pattern, $word->url, array(
'attributes' => array_filter(array(
'class' => array(
$word->class,
),
'title' => $word->url_title,
'target' => '_blank',
)),
'external' => TRUE,
));
}
else {
$replace[] = l($pattern, $word->url, array(
'attributes' => array_filter(array(
'class' => array(
$word->class,
),
'title' => $word->url_title,
)),
));
}
$pattern = '/((\\b)|(?<=\\W))(' . preg_quote($word->text, '/') . ')(?!(<\\/a>)|(".*>)|[\'"&’^])\\b/u';
if ($word->case_sensitive) {
$search[] = $pattern;
}
else {
$search[] = $pattern . 'i';
}
}
}
if (isset($search) && isset($replace)) {
$dom = new DOMDocument();
$subject = str_replace('&', '&#38;', preg_replace('/&(?![a-z])/u', '&', $subject));
// Comment <iframe> tag because it can cause error.
$subject = str_replace(array(
'<iframe',
'</iframe>',
), array(
'<!--word_link<iframe',
'</iframe>word_link-->',
), $subject);
libxml_use_internal_errors(TRUE);
$dom
->loadHTML(mb_convert_encoding(htmlspecialchars_decode($subject), 'HTML-ENTITIES', 'UTF-8'));
$xpath = new DOMXPath($dom);
if ($limit != 0) {
$counts = array_fill(0, count($search), 0);
foreach ($xpath
->query('//text()[not(ancestor::a) ' . $not . ']') as $node) {
$replaced = $node->wholeText;
$del = array_filter($counts);
foreach ($del as $key => $val) {
if ($val >= $limit) {
unset($search[$key], $replace[$key]);
}
}
foreach ($search as $id => $search_word) {
$new_preg_limit = $preg_limit - $counts[$id];
$replaced = preg_replace($search_word, $replace[$id], $replaced, $new_preg_limit, $count);
$counts[$id] += $count;
}
$new_node = $dom
->createDocumentFragment();
$new_node
->appendXML($replaced);
$node->parentNode
->replaceChild($new_node, $node);
}
}
else {
foreach ($xpath
->query('//text()[not(ancestor::a) ' . $not . ']') as $node) {
$replaced = preg_replace($search, $replace, $node->wholeText);
$new_node = $dom
->createDocumentFragment();
$new_node
->appendXML($replaced);
$node->parentNode
->replaceChild($new_node, $node);
}
}
// Get only the body tag with its contents, then trim the body tag
// itself to get only the original content.
$subject = drupal_substr($dom
->saveXML($xpath
->query('//body')
->item(0)), 6, -7);
}
return str_replace(array(
'<!--word_link<iframe',
'</iframe>word_link-->',
), array(
'<iframe',
'</iframe>',
), $subject);
}