Skip to:
Content

BuddyPress.org

Ticket #6517: 6517.2.diff

File 6517.2.diff, 4.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 5cebddf..f1c833a 100644
    function bp_create_excerpt( $text, $length = 225, $options = array() ) { 
    866866        // If $exact is false, we can't break on words
    867867        if ( empty( $r['exact'] ) ) {
    868868                // 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;
     869                preg_match_all( '/<[a-z\!\/][^>]*>/', $truncate, $_truncate_tags, PREG_OFFSET_CAPTURE );
     870
     871                // Rekey tags by the string index of their last character.
     872                $truncate_tags = array();
     873                if ( ! empty( $_truncate_tags[0] ) ) {
     874                        foreach ( $_truncate_tags[0] as $_tt ) {
     875                                $_tt['start'] = $_tt[1];
     876                                $_tt['end']   = $_tt[1] + strlen( $_tt[0] );
     877                                $truncate_tags[ $_tt['end'] ] = $_tt;
     878                        }
     879                }
     880
     881                $truncate_length = mb_strlen( $truncate );
     882                $spacepos = $truncate_length + 1;
     883                for ( $pos = $truncate_length - 1; $pos >= 0; $pos-- ) {
     884                        // Word boundaries are spaces and the close of HTML tags, when the tag is preceded by a space.
     885                        $is_word_boundary = ' ' === $truncate[ $pos ];
     886                        if ( ! $is_word_boundary && isset( $truncate_tags[ $pos - 1 ] ) ) {
     887                                $preceding_tag    = $truncate_tags[ $pos - 1 ];
     888                                if ( ' ' === $truncate[ $preceding_tag['start'] - 1 ] ) {
     889                                        $is_word_boundary = true;
     890                                        break;
     891                                }
    875892                        }
    876893
    877                         // Convert rpos to negative offset on forward-facing string.
    878                         $pos = -1 - $i;
     894                        if ( ! $is_word_boundary ) {
     895                                continue;
     896                        }
    879897
    880898                        // If there are no tags in the string, the first space found is the right one.
    881                         if ( empty( $truncate_tags[0] ) ) {
     899                        if ( empty( $truncate_tags ) ) {
    882900                                $spacepos = $pos;
    883901                                break;
    884902                        }
    885903
    886904                        // 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;
     905                        $intag = false;
     906                        foreach ( $truncate_tags as $tt ) {
     907                                if ( $pos > $tt['start'] && $pos < $tt['end'] ) {
     908                                        $intag = true;
     909                                        break;
    893910                                }
    894911                        }
     912
     913                        if ( ! $intag ) {
     914                                $spacepos = $pos;
     915                                break;
     916                        }
    895917                }
    896918
    897                 if ( false !== $spacepos ) {
    898                         if ( $r['html'] ) {
    899                                 $bits = mb_substr( $truncate, $spacepos );
    900                                 preg_match_all( '/<\/([a-z]+)>/', $bits, $droppedTags, PREG_SET_ORDER );
    901                                 if ( !empty( $droppedTags ) ) {
    902                                         foreach ( $droppedTags as $closingTag ) {
    903                                                 if ( !in_array( $closingTag[1], $openTags ) ) {
    904                                                         array_unshift( $openTags, $closingTag[1] );
    905                                                 }
     919                if ( $r['html'] ) {
     920                        $bits = mb_substr( $truncate, $spacepos );
     921                        preg_match_all( '/<\/([a-z]+)>/', $bits, $droppedTags, PREG_SET_ORDER );
     922                        if ( !empty( $droppedTags ) ) {
     923                                foreach ( $droppedTags as $closingTag ) {
     924                                        if ( !in_array( $closingTag[1], $openTags ) ) {
     925                                                array_unshift( $openTags, $closingTag[1] );
    906926                                        }
    907927                                }
    908928                        }
    909                         $truncate = mb_substr( $truncate, 0, $spacepos );
    910929                }
     930
     931                $truncate = rtrim( mb_substr( $truncate, 0, $spacepos ) );
    911932        }
    912933        $truncate .= $ending;
    913934
  • tests/phpunit/testcases/core/template/bpCreateExcerpt.php

    diff --git tests/phpunit/testcases/core/template/bpCreateExcerpt.php tests/phpunit/testcases/core/template/bpCreateExcerpt.php
    index 70fce82..7340d5d 100644
    class BP_Tests_Core_Template_BPCreateExcerpt extends BP_UnitTestCase { 
    5151        }
    5252
    5353        /**
     54         * @ticket BP6517
     55         */
     56        public function test_exact_false_should_properly_account_for_accented_characters() {
     57                $text = 'Toutes les connaissances que les hommes avaient mis sur Internet lui étaient accessible. Les grandes bibliothÚques du monde entier n’avaient plus de secret pour lui. Il pouvait apprendre trÚs vite, beaucoup plus vite que n’importe quel humain.
     58Il avait appris toutes les connaissances du monde entier, visiter tout les pays. C’est lui qui avait fait en sorte qu’Internet se déploie ainsi.';
     59                $expected = 'Toutes les connaissances que les hommes avaient mis sur Internet lui étaient accessible. Les';
     60                $this->assertSame( $expected, bp_create_excerpt( $text, 98, array(
     61                        'ending' => '',
     62                        'exact' => false,
     63                ) ) );
     64        }
     65
     66        /**
    5467         * @ticket BP6254
    5568         */
    5669        public function test_should_trim_too_long_first_word_to_max_characters_even_when_exact_is_false() {