$matchData[0], 'offset' => $matchData[1], 'id' => $termMapping[$i], ); } } } } // Sort by offset in descending order usort($result, function($a, $b) { return $a['offset'] > $b['offset'] ? -1 : 1; }); return $result; } function filter( $html, $terms, $type ) { $doc = DOMDocument::loadHTML($html); // Stack will be used to avoid recursive functions $stack = new SplStack; $stack->push($doc); while (!$stack->isEmpty()) { $node = $stack->pop(); if ($node->nodeType == XML_TEXT_NODE && $node->parentNode instanceof DOMElement) { // $node represents text node // and it's inside a tag (second condition in the statement above) // Check that this text is not wrapped in tag // as we don't want to wrap it twice if ($node->parentNode->tagName != 'a') { $matches = matchTerms($node->wholeText, $terms); foreach ($matches as $match) { // Create new link element in the DOM $link = $doc->createElement('a', $match['text']); if ( $type == "species" ) { $link->setAttribute('href', '/species/' . $match['id'] . '/'); $link->setAttribute('rel', '/species/' . $match['id'] . '/?hover=true'); $link->setAttribute('class', 'link_species'); } else { $link->setAttribute('href', '/glossary/' . $match['id'] . '/'); $link->setAttribute('rel', '/glossary/' . $match['id'] . '/?hover=true'); $link->setAttribute('class', 'link_glossary'); } // Save the text after the link $remainingText = $node->splitText($match['offset'] + strlen($match['text'])); // Save the text before the link $linkText = $node->splitText($match['offset']); // Replace $linkText with $link node // i.e. 'something' becomes 'something' $node->parentNode->replaceChild($link, $linkText); } } } if ($node->hasChildNodes()) { foreach ($node->childNodes as $childNode) { $stack->push($childNode); } } } $body = $doc->getElementsByTagName('body'); return $doc->saveHTML($body->item(0)); } function convert( $string ) { $search = array( "'", """, " " ); $replace = array( '"', '"', ' ' ); return str_replace( $search, $replace, $string ); } /* ######################################################### process the post... */ function run_filter( $post_id ) { global $wpdb; /* get the glossary terms */ $results = $wpdb->get_results( 'SELECT post_title AS list, post_name AS slug FROM wp_posts WHERE post_status="publish" AND post_type="glossary" AND post_parent>0' ); $glossary_terms = array(); foreach ( $results as $row ) $glossary_terms[$row->slug] = '(?:' . preg_quote( trim( strip_tags ( convert( $row->list ) ) ), '/' ) . ')'; /* get the species terms */ $results = $wpdb->get_results( 'SELECT posts.post_name AS slug, posts.id AS post_id, meta1.meta_value AS genus, meta2.meta_value AS species FROM wp_posts posts LEFT OUTER JOIN wp_postmeta meta1 ON posts.id = meta1.post_id AND meta1.meta_key = "genus" LEFT OUTER JOIN wp_postmeta meta2 ON posts.id = meta2.post_id AND meta2.meta_key = "species" WHERE posts.post_type = "species"' ); $species_terms = array(); foreach ( $results as $row ) { if ( isset( $row->genus ) && isset( $row->species ) ) { $genus = preg_quote( trim( strip_tags( convert( $row->genus ) ) ), '/' ); $species = preg_quote( trim( strip_tags ( convert( $row->species ) ) ), '/' ); $genus_initial = preg_quote( substr( trim( strip_tags( convert( $row->genus ) ) ), 0, 1 ) ); $id = $row->slug; if ( ctype_alpha( $genus_initial ) ) $pattern = '(?:' . $genus . '|' . $genus_initial . '\.) ' . $species; else $pattern = '(?:' . $genus . ') ' . $species; $species_terms[$id] = $pattern; } } $species_terms = array_unique( $species_terms ); $categories = get_category_by_slug('article'); $category_id = $categories->term_id; $post = wp_get_single_post( $post_id ); $updated = $post; if ( $post->post_type == "species" || ( $post->post_type == "post" && in_array( $category_id, get_the_category( $post_id ), true ) ) ) { $updated->post_content = filter( $post->post_content, $species_terms, "species" ); $updated->post_content = filter( $post->post_content, $glossary_terms, "glossary" ); wp_update_post( $updated ); if ( $post->post_type == "species" ) { $meta = get_post_custom( $post_id ); $values_to_filter = array( "distribution", "habitat", "max_size", "aquarium_size", "maintenance", "water_chemistry", "diet", "behaviour", "dimorphism", "reproduction", "misc_notes" ); foreach ( $meta as $key => $val ) { if ( isset( $val ) && isset( $val[0] ) && !empty( $val[0] ) ) { if ( in_array( $key, $values_to_filter ) ) { $updated_meta = filter( $val[0], $species_terms, "species" ); $updated_meta = filter( $updated_meta, $glossary_terms, "glossary" ); update_post_meta( $post_id, $key, $updated_meta ); } } } } } else if ( $post->post_type == "post" ) { $updated->post_content = filter_species( $post->post_content ); wp_update_post( $updated ); } } ?>