Skip to:
Content

BuddyPress.org

Ticket #6517: 6517.diff

File 6517.diff, 2.6 KB (added by boonebgorges, 5 years ago)
  • src/bp-core/bp-core-template.php

    diff --git src/bp-core/bp-core-template.php src/bp-core/bp-core-template.php
    index f6c88ed..5cebddf 100644
    function bp_create_excerpt( $text, $length = 225, $options = array() ) { 
    813813                $truncate    = '';
    814814
    815815                // Find all the tags and HTML comments and put them in a stack for later use
    816                 preg_match_all( '/(<\/?([\w!].+?)[^>]*>)?([^<>]*)/', $text, $tags, PREG_SET_ORDER );
     816                preg_match_all( '/(<\/?([\w+!]+)[^>]*>)?([^<>]*)/', $text, $tags, PREG_SET_ORDER );
    817817
    818818                foreach ( $tags as $tag ) {
    819819                        // Process tags that need to be closed
    function bp_create_excerpt( $text, $length = 225, $options = array() ) { 
    865865
    866866        // If $exact is false, we can't break on words
    867867        if ( empty( $r['exact'] ) ) {
    868                 $spacepos = mb_strrpos( $truncate, ' ' );
     868                // Find the position of the last space character not part of a tag.
     869                preg_match_all( '/<[a-z\!\/][^>]*>/', $truncate, $truncate_tags, PREG_OFFSET_CAPTURE );
     870                $rtruncate = strrev( $truncate );
     871                $spacepos = false;
     872                for ( $i = strlen( $rtruncate ) - 1; $i >= 0; $i-- ) {
     873                        if ( ' ' !== $rtruncate[ $i ] ) {
     874                                continue;
     875                        }
     876
     877                        // Convert rpos to negative offset on forward-facing string.
     878                        $pos = -1 - $i;
     879
     880                        // If there are no tags in the string, the first space found is the right one.
     881                        if ( empty( $truncate_tags[0] ) ) {
     882                                $spacepos = $pos;
     883                                break;
     884                        }
     885
     886                        // Look at each tag to see if the space is inside of it.
     887                        foreach ( $truncate_tags[0] as $truncate_tag ) {
     888                                $start = $truncate_tag[1];
     889                                $end   = $start + strlen( $truncate_tag[0] );
     890                                if ( $pos > $start && $pos < $end ) {
     891                                        $spacepos = $pos;
     892                                        break 2;
     893                                }
     894                        }
     895                }
     896
    869897                if ( false !== $spacepos ) {
    870898                        if ( $r['html'] ) {
    871899                                $bits = mb_substr( $truncate, $spacepos );
  • tests/phpunit/testcases/core/template/bpCreateExcerpt.php

    diff --git tests/phpunit/testcases/core/template/bpCreateExcerpt.php tests/phpunit/testcases/core/template/bpCreateExcerpt.php
    index 94e7308..70fce82 100644
    class BP_Tests_Core_Template_BPCreateExcerpt extends BP_UnitTestCase { 
    6161                        'ending' => '',
    6262                ) ) );
    6363        }
     64
     65        /**
     66         * @ticket BP6517
     67         */
     68        public function test_string_should_not_be_cut_mid_tag_when_exact_is_false() {
     69                $text = '<p><span>Foo</span> <a href="http://example.com">Bar</a> Baz.</p><p>Foo Bar Baz</p>';
     70                $actual = bp_create_excerpt( $text, 7, array(
     71                        'html' => true,
     72                        'ending' => '',
     73                        'exact' => false,
     74                ) );
     75                $this->assertSame( '<p><span>Foo</span> <a href="http://example.com">Bar</a></p>', $actual );
     76        }
    6477}