Make WordPress Core


Ignore:
Timestamp:
07/23/2015 04:49:25 AM (10 years ago)
Author:
pento
Message:

Shortcodes: Improve the reliablity of shortcodes inside HTML tags.

Merge of [33359] to the 4.0 branch.

Props miqrogroove.

See #15694.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/4.0/src/wp-includes/formatting.php

    r32189 r33381  
    406406    $pee = str_replace(array("\r\n", "\r"), "\n", $pee); // cross-platform newlines
    407407
     408    // Strip newlines from all elements.
     409    $pee = wp_replace_in_html_tags( $pee, array( "\n" => " " ) );
     410
    408411    if ( strpos( $pee, '<option' ) !== false ) {
    409412        // no P/BR around option
     
    458461
    459462    return $pee;
     463}
     464
     465/**
     466 * Replace characters or phrases within HTML elements only.
     467 *
     468 * @since 4.2.3
     469 *
     470 * @param string $haystack The text which has to be formatted.
     471 * @param array $replace_pairs In the form array('from' => 'to', ...).
     472 * @return string The formatted text.
     473 */
     474function wp_replace_in_html_tags( $haystack, $replace_pairs ) {
     475    // Find all elements.
     476    $comments =
     477          '!'           // Start of comment, after the <.
     478        . '(?:'         // Unroll the loop: Consume everything until --> is found.
     479        .     '-(?!->)' // Dash not followed by end of comment.
     480        .     '[^\-]*+' // Consume non-dashes.
     481        . ')*+'         // Loop possessively.
     482        . '(?:-->)?';   // End of comment. If not found, match all input.
     483
     484    $regex =
     485          '/('              // Capture the entire match.
     486        .     '<'           // Find start of element.
     487        .     '(?(?=!--)'   // Is this a comment?
     488        .         $comments // Find end of comment.
     489        .     '|'
     490        .         '[^>]*>?' // Find end of element. If not found, match all input.
     491        .     ')'
     492        . ')/s';
     493
     494    $textarr = preg_split( $regex, $haystack, -1, PREG_SPLIT_DELIM_CAPTURE );
     495    $changed = false;
     496
     497    // Optimize when searching for one item.
     498    if ( 1 === count( $replace_pairs ) ) {
     499        // Extract $needle and $replace.
     500        foreach ( $replace_pairs as $needle => $replace );
     501
     502        // Loop through delimeters (elements) only.
     503        for ( $i = 1, $c = count( $textarr ); $i < $c; $i += 2 ) {
     504            if ( false !== strpos( $textarr[$i], $needle ) ) {
     505                $textarr[$i] = str_replace( $needle, $replace, $textarr[$i] );
     506                $changed = true;
     507            }
     508        }
     509    } else {
     510        // Extract all $needles.
     511        $needles = array_keys( $replace_pairs );
     512
     513        // Loop through delimeters (elements) only.
     514        for ( $i = 1, $c = count( $textarr ); $i < $c; $i += 2 ) {
     515            foreach ( $needles as $needle ) {
     516                if ( false !== strpos( $textarr[$i], $needle ) ) {
     517                    $textarr[$i] = strtr( $textarr[$i], $replace_pairs );
     518                    $changed = true;
     519                    // After one strtr() break out of the foreach loop and look at next element.
     520                    break;
     521                }
     522            }
     523        }
     524    }
     525
     526    if ( $changed ) {
     527        $haystack = implode( $textarr );
     528    }
     529
     530    return $haystack;
    460531}
    461532
Note: See TracChangeset for help on using the changeset viewer.