You are here

public function FilterOnomasticon::processChildren in Onomasticon 8

Same name and namespace in other branches
  1. 2.x src/Plugin/Filter/FilterOnomasticon.php \Drupal\onomasticon\Plugin\Filter\FilterOnomasticon::processChildren()

Traverses the DOM tree (recursive). If current DOMNode element has children, this function calls itself. #text nodes never have any children, there Onomasticon filter is applied.

Parameters

$dom \DOMNode:

1 call to FilterOnomasticon::processChildren()
FilterOnomasticon::process in src/Plugin/Filter/FilterOnomasticon.php
Main filter function as expected by Drupal.

File

src/Plugin/Filter/FilterOnomasticon.php, line 186

Class

FilterOnomasticon
Plugin annotation @Filter( id = "filter_onomasticon", title = @Translation("Onomasticon Filter"), description = @Translation("Adds glossary information to words."), type = Drupal\filter\Plugin\FilterInterface::TYPE_MARKUP_LANGUAGE, settings…

Namespace

Drupal\onomasticon\Plugin\Filter

Code

public function processChildren($dom) {
  if ($dom
    ->hasChildNodes()) {

    // Children present, this can't be a #text node.
    // Add the tag name to the tree, so we know the
    // hierarchy.
    $this->htmlTree[] = $dom->nodeName;

    // Recursive call on first child.
    foreach ($dom->childNodes as $child) {
      $this
        ->processChildren($child);
    }
  }
  else {

    // No children present => end of tree branch.
    if ($dom->nodeName == '#text' && !$dom
      ->isWhitespaceInElementContent()) {

      // Element is of type #text and has content.
      // First check tree for ancestor tags not allowed.
      $disabled_tags = explode(' ', $this->settings['onomasticon_disabled']);

      // Sanitize user input
      $disabled_tags = array_map(function ($tag) {
        return preg_replace("/[^a-z1-6]*/", "", strtolower(trim($tag)));
      }, $disabled_tags);

      // Add Onomasticon tag and anchor tag.
      $disabled_tags[] = $this->settings['onomasticon_tag'];
      $disabled_tags[] = 'a';
      $disabled_tags[] = 'nonomasticon';

      // Required for CKEditor plugin.
      $disabled_tags = array_unique($disabled_tags);

      // Find the bad boys.
      $bad_tags = array_intersect($disabled_tags, $this->htmlTree);
      if (count($bad_tags) == 0) {

        // To avoid double replacements, check if this element
        // has been processed already. DomNodePath is unique.
        if (!in_array($dom
          ->getNodePath(), $this->processedPaths)) {

          // Element has not been processed yet. Let's do this!
          // Original nodeValue (textContent).
          $text_orig = $dom->nodeValue;

          // Processed text, Onomasticon has been applied.
          $text_repl = $this
            ->replaceTerms($text_orig);

          // Did the filter find anything?
          if ($text_orig !== $text_repl) {

            // Indeed, let's save the information for later.
            $this->htmlReplacements[] = array(
              'dom' => $dom,
              'html' => $text_repl,
            );
          }

          // Add element to processed items.
          $this->processedPaths[] = $dom
            ->getNodePath();
        }
      }
    }

    // End of branch reached. Look for sibling elements.
    if (empty($dom->nextSibling)) {

      // No nextSibling found, last child element of parent.
      // Take a step back in tree and
      array_pop($this->htmlTree);
      $parent = $dom;

      // Reverse traverse the tree until there are no
      // more siblings left to process.
      while (!empty($parent->parentNode) && empty($parent->nextSibling) && count($this->htmlTree) > 0) {
        array_pop($this->htmlTree);
        $parent = $parent->parentNode;
      }
    }
  }
}