示例#1
0
 static function preg_replace_dom(DOMNode $dom, array $exclude = array())
 {
     if (empty($dom->childNodes)) {
         return;
     }
     foreach ($dom->childNodes as $node) {
         // if the node is in the exclude list, skip it and its children
         if (in_array($node->nodeName, $exclude)) {
             continue;
         }
         if ($node instanceof DOMText) {
             $totalcount = 0;
             // try and match all glossary words we have in the
             foreach (self::$glossary as &$data) {
                 $data_offset = $data->ref;
                 if (empty($data->inuse) || !$data->inuse) {
                     continue;
                 }
                 $replace = "XXX_GLOSSARY_" . $data_offset . "_\$1_XXX";
                 $count = 0;
                 // UNCOMMENT and CHANGE $data->limit to $base_data->limit to make sure that alt words
                 // share the same count and the main word.
                 //$base_data = $data;
                 //if ($data->base_offset > -1)
                 //	$base_data = self::$glossary[$data->base_offset];
                 $node->nodeValue = preg_replace_callback($data->regex, function ($match) use($data_offset) {
                     return "XXX_GLOSSARY_" . base64_encode($data_offset) . "_" . base64_encode($match[0]) . "_XXX";
                     //return str_replace('$1', $match[0], $replace);
                 }, $node->nodeValue, $data->limit, $count);
                 if ($count) {
                     $data->limit -= $count;
                     $totalcount += $count;
                 }
             }
             if ($totalcount) {
                 $runs = 0;
                 // run counter incase it goes wrong and gets carried away
                 // temp node that we are working on
                 $temp = $node;
                 // find tag in node text
                 if (function_exists("mb_strpos")) {
                     $pos = mb_strpos($temp->nodeValue, "XXX_GLOSSARY_");
                 } else {
                     $pos = strpos($temp->nodeValue, "XXX_GLOSSARY_");
                 }
                 while ($pos !== FALSE && $runs++ < 50) {
                     // split the text node around the match
                     $new = $temp->splitText($pos);
                     // remove match text from split text and retrieve info
                     list($elem, $new->nodeValue) = explode("_XXX", $new->nodeValue, 2);
                     // parse the info found
                     $elem = substr($elem, 13);
                     list($elem, $text) = explode("_", $elem, 2);
                     $elem = base64_decode($elem);
                     $text = base64_decode($text);
                     // lookup info we saved earlier
                     $data_offset = self::$glo_ref[$elem];
                     $info = self::$glossary[$data_offset];
                     // build link element
                     $link_elem = FSS_Glossary::$cdom->createElement('a', $text);
                     $link_elem->setAttribute("href", $info->href);
                     $link_elem->setAttribute("class", 'fss_glossary_word');
                     $link_elem->setAttribute("ref", $info->ref);
                     $link_elem->setAttribute("context", FSS_Glossary::$context);
                     // insert link element before 2nd part of text split
                     $temp->parentNode->insertBefore($link_elem, $new);
                     // copy the new node over the old temp one
                     $temp = $new;
                     // find the text again
                     if (function_exists("mb_strpos")) {
                         $pos = mb_strpos($temp->nodeValue, "XXX_GLOSSARY_");
                     } else {
                         $pos = strpos($temp->nodeValue, "XXX_GLOSSARY_");
                     }
                 }
             }
         } else {
             FSS_Glossary::preg_replace_dom($node, $exclude);
         }
     }
 }