1|0)[\'"]?\s*)?'; $tags = array( array('@@i', ''), array('@\[raw' . $shortcode_flag . '\]@i', '[/raw]'), array('@@i', '') ); $is_excerpt_stripping_enabled = !defined('RAW_HTML_KEEP_RAW_IN_EXCERPTS') || !constant('RAW_HTML_KEEP_RAW_IN_EXCERPTS'); foreach ($tags as $tag_pair){ list($start_regex, $end_tag) = $tag_pair; //Find the start tag $offset = 0; while( preg_match($start_regex, $text, $matches, PREG_OFFSET_CAPTURE, $offset) === 1 ) { $start = $matches[0][1]; $content_start = $start + strlen($matches[0][0]); //find the end tag $fin = stripos($text, $end_tag, $content_start); //break if there's no end tag if ($fin == false) break; //extract the content between the tags $content = substr($text, $content_start,$fin-$content_start); if ( $is_excerpt_stripping_enabled && ( (array_search('get_the_excerpt', $wp_current_filter) !== false) || (array_search('the_excerpt', $wp_current_filter) !== false) ) ){ //Strip out the raw blocks when displaying an excerpt $replacement = ''; } else { //Store the content and replace it with a marker if ( $keep_tags ){ $wsh_raw_parts[]=$matches[0][0].$content.$end_tag; } else { $wsh_raw_parts[]=$content; } $index = count($wsh_raw_parts) - 1; $replacement = "!RAWBLOCK" . $index . "!"; $wsh_raw_run_shortcodes[$index] = isset($matches['shortcodes']) && (intval($matches['shortcodes'][0]) == 1); } $text = substr_replace($text, $replacement, $start, $fin+strlen($end_tag)-$start ); //Continue searching after the marker. $offset = $start + strlen($replacement); //Have we reached the end of the string yet? if ($offset >= strlen($text)) break; } } return $text; } /** * Replace the placeholders created by wsh_extract_exclusions() with the original content. * * @global array $wsh_raw_parts Used to check if there is anything to insert. * * @param string $text The input content to filter. * @param callable|string $placeholder_callback Optional. The callback that will be used to process each placeholder. * @return string Filtered content. */ function wsh_insert_exclusions($text, $placeholder_callback = 'wsh_insertion_callback'){ global $wsh_raw_parts; if(!isset($wsh_raw_parts)) return $text; return preg_replace_callback('/(

)?!RAWBLOCK(?P\d+?)!(\s*?<\/p>)?/', $placeholder_callback, $text); } /** * Get the original content associated with a placeholder. * * @param array $matches Regex matches for a specific placeholder. @see wsh_insert_exclusions() * @return string Original content. */ function wsh_get_block_from_matches($matches) { global $wsh_raw_parts; $index = wsh_get_index_from_matches($matches); if ( $index === null ) { return '{Invalid RAW block}'; } return $wsh_raw_parts[$index]; } /** * @param array $matches * @return int|null */ function wsh_get_index_from_matches($matches) { $index = null; if ( isset($matches['index']) ) { $index = intval($matches['index']); } else if ( isset($matches[2]) ) { $index = intval($matches[2]); } return $index; } /** * Regex callback for wsh_insert_exclusions. Returns the extracted content * corresponding to a matched placeholder. * * @param array $matches Regex matches. * @return string Replacement string for this match. */ function wsh_insertion_callback($matches){ $openingParagraph = isset($matches[1]) ? $matches[1] : ''; $closingParagraph = isset($matches[3]) ? $matches[3] : ''; $code = wsh_get_block_from_matches($matches); //Optionally execute shortcodes inside [raw]...[/raw] tags. global $wsh_raw_run_shortcodes; $index = wsh_get_index_from_matches($matches); $run_shortcodes = ($index !== null) && !empty($wsh_raw_run_shortcodes[$index]); if ( $run_shortcodes ) { $code = do_shortcode($code); } //If the [raw] block is wrapped in its own paragraph, strip the

...

tags. If there's //only one of

|

tag present, keep it - it's probably part of a larger paragraph. if ( empty($openingParagraph) || empty($closingParagraph) ) { $code = $openingParagraph . $code . $closingParagraph; } return $code; } function wsh_setup_content_filters() { //Extract the tagged content before WP can get to it, then re-insert it later. add_filter('the_content', 'wsh_extract_exclusions', 2); //A workaround for WP-Syntax. If we run our insertion callback at the normal, extra-late //priority, WP-Syntax will see the wrong content when it runs its own content substitution hook. //We adapt to that by running our callback slightly earlier than WP-Syntax's. $wp_syntax_priority = has_filter('the_content', 'wp_syntax_after_filter'); if ( $wp_syntax_priority === false && class_exists('WP_Syntax') ) { //Newer versions of WP-Syntax use a class with static methods instead of plain functions. $wp_syntax_priority = has_filter('the_content', array('WP_Syntax', 'afterFilter')); } if ( $wp_syntax_priority !== false ) { $rawhtml_priority = $wp_syntax_priority - 1; } else { $rawhtml_priority = 1001; } add_filter('the_content', 'wsh_insert_exclusions', $rawhtml_priority); //Support GoodLayers themes and their page builder. add_filter('gdlr_the_content', 'wsh_extract_exclusions', 2); add_filter('gdlr_the_content', 'wsh_insert_exclusions', $rawhtml_priority); } add_action('plugins_loaded', 'wsh_setup_content_filters', 11); /* * WordPress can also mangle code when initializing the post/page editor. * To prevent this, we override the the_editor_content filter in almost * the same way that we did the_content. */ function wsh_extract_exclusions_for_editor($text){ return wsh_extract_exclusions($text, true); } function wsh_insert_exclusions_for_editor($text){ return wsh_insert_exclusions($text, 'wsh_insertion_callback_for_editor'); } function wsh_insertion_callback_for_editor($matches){ $code = wsh_get_block_from_matches($matches); if ( !function_exists('format_for_editor') || has_filter('the_editor_content', 'format_for_editor') ) { $code = htmlspecialchars($code, ENT_NOQUOTES); } return $code; } add_filter('the_editor_content', 'wsh_extract_exclusions_for_editor', 2); add_filter('the_editor_content', 'wsh_insert_exclusions_for_editor', 1001);