Skip to content

Commit 7b41adf

Browse files
committed
Shortcodes: Improve the reliablity of shortcodes inside HTML tags.
Props miqrogroove. See #15694. git-svn-id: https://develop.svn.wordpress.org/trunk@33359 602fd350-edb4-49c9-b593-d223f7449a82
1 parent 7439dd7 commit 7b41adf

6 files changed

Lines changed: 717 additions & 40 deletions

File tree

src/wp-includes/class-wp-embed.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ public function run_shortcode( $content ) {
5959
add_shortcode( 'embed', array( $this, 'shortcode' ) );
6060

6161
// Do the shortcode (only the [embed] one is registered)
62-
$content = do_shortcode( $content );
62+
$content = do_shortcode( $content, true );
6363

6464
// Put the original shortcodes back
6565
$shortcode_tags = $orig_shortcode_tags;
@@ -318,6 +318,10 @@ public function cache_oembed( $post_ID ) {
318318
* @return string Potentially modified $content.
319319
*/
320320
public function autoembed( $content ) {
321+
// Strip newlines from all elements.
322+
$content = wp_replace_in_html_tags( $content, array( "\n" => " " ) );
323+
324+
// Find URLs that are on their own line.
321325
return preg_replace_callback( '|^(\s*)(https?://[^\s"]+)(\s*)$|im', array( $this, 'autoembed_callback' ), $content );
322326
}
323327

src/wp-includes/formatting.php

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -504,6 +504,9 @@ function wpautop( $pee, $br = true ) {
504504
// Standardize newline characters to "\n".
505505
$pee = str_replace(array("\r\n", "\r"), "\n", $pee);
506506

507+
// Strip newlines from all elements.
508+
$pee = wp_replace_in_html_tags( $pee, array( "\n" => " " ) );
509+
507510
// Collapse line breaks before and after <option> elements so they don't get autop'd.
508511
if ( strpos( $pee, '<option' ) !== false ) {
509512
$pee = preg_replace( '|\s*<option|', '<option', $pee );
@@ -592,6 +595,74 @@ function wpautop( $pee, $br = true ) {
592595
return $pee;
593596
}
594597

598+
/**
599+
* Replace characters or phrases within HTML elements only.
600+
*
601+
* @since 4.2.3
602+
*
603+
* @param string $haystack The text which has to be formatted.
604+
* @param array $replace_pairs In the form array('from' => 'to', ...).
605+
* @return string The formatted text.
606+
*/
607+
function wp_replace_in_html_tags( $haystack, $replace_pairs ) {
608+
// Find all elements.
609+
$comments =
610+
'!' // Start of comment, after the <.
611+
. '(?:' // Unroll the loop: Consume everything until --> is found.
612+
. '-(?!->)' // Dash not followed by end of comment.
613+
. '[^\-]*+' // Consume non-dashes.
614+
. ')*+' // Loop possessively.
615+
. '(?:-->)?'; // End of comment. If not found, match all input.
616+
617+
$regex =
618+
'/(' // Capture the entire match.
619+
. '<' // Find start of element.
620+
. '(?(?=!--)' // Is this a comment?
621+
. $comments // Find end of comment.
622+
. '|'
623+
. '[^>]*>?' // Find end of element. If not found, match all input.
624+
. ')'
625+
. ')/s';
626+
627+
$textarr = preg_split( $regex, $haystack, -1, PREG_SPLIT_DELIM_CAPTURE );
628+
$changed = false;
629+
630+
// Optimize when searching for one item.
631+
if ( 1 === count( $replace_pairs ) ) {
632+
// Extract $needle and $replace.
633+
foreach ( $replace_pairs as $needle => $replace );
634+
635+
// Loop through delimeters (elements) only.
636+
for ( $i = 1, $c = count( $textarr ); $i < $c; $i += 2 ) {
637+
if ( false !== strpos( $textarr[$i], $needle ) ) {
638+
$textarr[$i] = str_replace( $needle, $replace, $textarr[$i] );
639+
$changed = true;
640+
}
641+
}
642+
} else {
643+
// Extract all $needles.
644+
$needles = array_keys( $replace_pairs );
645+
646+
// Loop through delimeters (elements) only.
647+
for ( $i = 1, $c = count( $textarr ); $i < $c; $i += 2 ) {
648+
foreach ( $needles as $needle ) {
649+
if ( false !== strpos( $textarr[$i], $needle ) ) {
650+
$textarr[$i] = strtr( $textarr[$i], $replace_pairs );
651+
$changed = true;
652+
// After one strtr() break out of the foreach loop and look at next element.
653+
break;
654+
}
655+
}
656+
}
657+
}
658+
659+
if ( $changed ) {
660+
$haystack = implode( $textarr );
661+
}
662+
663+
return $haystack;
664+
}
665+
595666
/**
596667
* Newline preservation help function for wpautop
597668
*

0 commit comments

Comments
 (0)