You are here

function _glossify_to_links in Glossify 7.4

Convert terms in text to links.

Parameters

$text: The HTML text upon which the filter is acting.

$terms: The terms (strings) to be replaced with links.

$type: 'taxonomy' for linking to taxonomy terms. 'content' for linking to nodes.

Return value

The original HTML with the term string replaced by links.

2 calls to _glossify_to_links()
_glossify_content_process in ./glossify.module
Content filter process callback for the glossify filter.
_glossify_taxonomy_process in ./glossify.module
Taxonomy filter process callback for the glossify filter.

File

./glossify.module, line 258
Glossify module.

Code

function _glossify_to_links($text, $terms, $type, $case_sensitivity, $first_only, $tooltips) {
  static $recursion_protection = FALSE;
  if ($recursion_protection) {
    return $text;
  }
  $recursion_protection = TRUE;

  //create dom document
  $html_dom = filter_dom_load($text);
  $xpath = new DOMXPath($html_dom);
  $pattern = array();
  $matched = array();

  //transform terms into normalized search pattern
  foreach ($terms as $term) {
    $term_norm = preg_replace('/\\s+/u', ' ', preg_quote(trim($term->name)));
    $term_norm = preg_replace('#/#u', '\\/', $term_norm);
    $pattern[] = preg_replace('/ /u', '\\s+', $term_norm);
  }
  $pattern = '/\\b(' . implode('|', $pattern) . ')\\b/u';
  if (!$case_sensitivity) {
    $pattern .= 'i';
  }

  //process HTML
  $text_nodes = $xpath
    ->query('//text()[not(ancestor::a)]');
  foreach ($text_nodes as $original_node) {
    $text = $original_node->nodeValue;
    $hitcount = preg_match_all($pattern, $text, $matches, PREG_OFFSET_CAPTURE);
    if ($hitcount > 0) {
      $offset = 0;
      $parent = $original_node->parentNode;
      $refnode = $original_node->nextSibling;
      $parent
        ->removeChild($original_node);
      foreach ($matches[0] as $i => $match) {
        $term_txt = $match[0];
        $term_pos = $match[1];
        $term_norm = preg_replace('/\\s+/u', ' ', $term_txt);

        // insert any text before the term instance
        $prefix = substr($text, $offset, $term_pos - $offset);
        $parent
          ->insertBefore($html_dom
          ->createTextNode($prefix), $refnode);

        // insert the actual term instance as a link
        $link = $html_dom
          ->createDocumentFragment();
        if ($first_only && in_array($case_sensitivity ? $match[0] : drupal_strtolower($match[0]), $matched)) {
          $link
            ->appendXML($term_txt);
        }
        else {
          $tip = $tooltips ? check_markup($terms[drupal_strtolower($term_norm)]->tip, $terms[drupal_strtolower($term_norm)]->format) : '';
          $link
            ->appendXML(theme('glossify_links', array(
            'type' => $type,
            'id' => $terms[drupal_strtolower($term_norm)]->id,
            'text' => $term_txt,
            'tip' => $tip,
          )));
          $matched[] = $case_sensitivity ? $match[0] : drupal_strtolower($match[0]);
        }
        $parent
          ->insertBefore($link, $refnode);
        $offset = $term_pos + strlen($term_txt);

        // last match, append remaining text
        if ($i == $hitcount - 1) {
          $suffix = substr($text, $offset);
          $parent
            ->insertBefore($html_dom
            ->createTextNode($suffix), $refnode);
        }
      }
    }
  }
  $recursion_protection = FALSE;
  return filter_dom_serialize($html_dom);
}