Make WordPress Core


Ignore:
Timestamp:
07/22/2015 05:43:35 AM (11 years ago)
Author:
pento
Message:

Shortcodes: Improve the reliablity of shortcodes inside HTML tags.

Merge of [33359] to the 4.2 branch.

Props miqrogroove.

See #15694.

File:
1 edited

Legend:

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

    r33326 r33360  
    422422        $pee = str_replace(array("\r\n", "\r"), "\n", $pee);
    423423
     424        // Strip newlines from all elements.
     425        $pee = wp_replace_in_html_tags( $pee, array( "\n" => " " ) );
     426
    424427        // Collapse line breaks before and after <option> elements so they don't get autop'd.
    425428        if ( strpos( $pee, '<option' ) !== false ) {
     
    508511
    509512        return $pee;
     513}
     514
     515/**
     516 * Replace characters or phrases within HTML elements only.
     517 *
     518 * @since 4.2.3
     519 *
     520 * @param string $haystack The text which has to be formatted.
     521 * @param array $replace_pairs In the form array('from' => 'to', ...).
     522 * @return string The formatted text.
     523 */
     524function wp_replace_in_html_tags( $haystack, $replace_pairs ) {
     525        // Find all elements.
     526        $comments =
     527                  '!'           // Start of comment, after the <.
     528                . '(?:'         // Unroll the loop: Consume everything until --> is found.
     529                .     '-(?!->)' // Dash not followed by end of comment.
     530                .     '[^\-]*+' // Consume non-dashes.
     531                . ')*+'         // Loop possessively.
     532                . '(?:-->)?';   // End of comment. If not found, match all input.
     533
     534        $regex =
     535                  '/('              // Capture the entire match.
     536                .     '<'           // Find start of element.
     537                .     '(?(?=!--)'   // Is this a comment?
     538                .         $comments // Find end of comment.
     539                .     '|'
     540                .         '[^>]*>?' // Find end of element. If not found, match all input.
     541                .     ')'
     542                . ')/s';
     543
     544        $textarr = preg_split( $regex, $haystack, -1, PREG_SPLIT_DELIM_CAPTURE );
     545        $changed = false;
     546
     547        // Optimize when searching for one item.
     548        if ( 1 === count( $replace_pairs ) ) {
     549                // Extract $needle and $replace.
     550                foreach ( $replace_pairs as $needle => $replace );
     551
     552                // Loop through delimeters (elements) only.
     553                for ( $i = 1, $c = count( $textarr ); $i < $c; $i += 2 ) {
     554                        if ( false !== strpos( $textarr[$i], $needle ) ) {
     555                                $textarr[$i] = str_replace( $needle, $replace, $textarr[$i] );
     556                                $changed = true;
     557                        }
     558                }
     559        } else {
     560                // Extract all $needles.
     561                $needles = array_keys( $replace_pairs );
     562
     563                // Loop through delimeters (elements) only.
     564                for ( $i = 1, $c = count( $textarr ); $i < $c; $i += 2 ) {
     565                        foreach ( $needles as $needle ) {
     566                                if ( false !== strpos( $textarr[$i], $needle ) ) {
     567                                        $textarr[$i] = strtr( $textarr[$i], $replace_pairs );
     568                                        $changed = true;
     569                                        // After one strtr() break out of the foreach loop and look at next element.
     570                                        break;
     571                                }
     572                        }
     573                }
     574        }
     575
     576        if ( $changed ) {
     577                $haystack = implode( $textarr );
     578        }
     579
     580        return $haystack;
    510581}
    511582
Note: See TracChangeset for help on using the changeset viewer.