Skip to:
Content

BuddyPress.org


Ignore:
Timestamp:
06/25/2015 06:46:16 PM (11 years ago)
Author:
boonebgorges
Message:

The continuing adventures of bp_create_excerpt().

This changeset fixes a bug introduced in [9963] that caused excerpts to be
truncated too much in some cases. It also fixes some potential issues with
multibyte strings when html=true.

Fixes #6517.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/bp-core/bp-core-template.php

    r9962 r9967  
    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 ] ) {
     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                                }
     892                        }
     893
     894                        if ( ! $is_word_boundary ) {
    874895                                continue;
    875896                        }
    876897
    877                         // Convert rpos to negative offset on forward-facing string.
    878                         $pos = -1 - $i;
    879 
    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;
     
    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                        }
    895                 }
    896 
    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                                                 }
     912
     913                        if ( ! $intag ) {
     914                                $spacepos = $pos;
     915                                break;
     916                        }
     917                }
     918
     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 );
    910                 }
     929                }
     930
     931                $truncate = rtrim( mb_substr( $truncate, 0, $spacepos ) );
    911932        }
    912933        $truncate .= $ending;
Note: See TracChangeset for help on using the changeset viewer.