Skip to:
Content

bbPress.org

Changeset 6014


Ignore:
Timestamp:
04/29/2016 04:44:11 PM (9 years ago)
Author:
johnjamesjacoby
Message:

Mentions: Refactor the way user mentions are discovered and linked.

  • Adds a filter to bbp_make_clickable
  • Adds filters for for previously hard-coded clickables
  • Adds new filter for at-mention clickable
  • Deprecates previous functions for finding & linking at-mentions

For 2.6 (trunk). Hat-tip to Daniel Cid.

Location:
trunk
Files:
1 added
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/includes/common/formatting.php

    r5951 r6014  
    325325 * @return string Content with converted URIs.
    326326 */
    327 function bbp_make_clickable( $text ) {
    328     $r       = '';
    329     $in_code = false;
    330     $textarr = preg_split( '/(<[^<>]+>)/', $text, -1, PREG_SPLIT_DELIM_CAPTURE ); // split out HTML tags
     327function bbp_make_clickable( $text = '' ) {
     328    $r               = '';
     329    $textarr         = preg_split( '/(<[^<>]+>)/', $text, -1, PREG_SPLIT_DELIM_CAPTURE ); // split out HTML tags
     330    $nested_code_pre = 0; // Keep track of how many levels link is nested inside <pre> or <code>
    331331
    332332    foreach ( $textarr as $piece ) {
    333333
    334         switch ( $piece ) {
    335             case '<code>' :
    336             case '<pre>'  :
    337                 $in_code = true;
    338                 break;
    339             case '</code>' :
    340             case '</pre>'  :
    341                 $in_code = false;
    342                 break;
     334        if ( preg_match( '|^<code[\s>]|i', $piece ) || preg_match( '|^<pre[\s>]|i', $piece ) || preg_match( '|^<script[\s>]|i', $piece ) || preg_match( '|^<style[\s>]|i', $piece ) ) {
     335            $nested_code_pre++;
     336        } elseif ( $nested_code_pre && ( '</code>' === strtolower( $piece ) || '</pre>' === strtolower( $piece ) || '</script>' === strtolower( $piece ) || '</style>' === strtolower( $piece ) ) ) {
     337            $nested_code_pre--;
    343338        }
    344339
    345         if ( $in_code || empty( $piece ) || ( $piece[0] === '<' && ! preg_match('|^<\s*[\w]{1,20}+://|', $piece) ) ) {
     340        if ( $nested_code_pre || empty( $piece ) || ( $piece[0] === '<' && ! preg_match( '|^<\s*[\w]{1,20}+://|', $piece ) ) ) {
    346341            $r .= $piece;
    347342            continue;
     
    359354            }
    360355        } else {
    361             $ret = " $piece "; // Pad with whitespace to simplify the regexes
    362 
    363             $url_clickable = '~
    364                 ([\\s(<.,;:!?])                                # 1: Leading whitespace, or punctuation
    365                 (                                              # 2: URL
    366                     [\\w]{1,20}+://                            # Scheme and hier-part prefix
    367                     (?=\S{1,2000}\s)                           # Limit to URLs less than about 2000 characters long
    368                     [\\w\\x80-\\xff#%\\~/@\\[\\]*(+=&$-]*+     # Non-punctuation URL character
    369                     (?:                                        # Unroll the Loop: Only allow puctuation URL character if followed by a non-punctuation URL character
    370                         [\'.,;:!?)]                            # Punctuation URL character
    371                         [\\w\\x80-\\xff#%\\~/@\\[\\]*(+=&$-]++ # Non-punctuation URL character
    372                     )*
    373                 )
    374                 (\)?)                                          # 3: Trailing closing parenthesis (for parethesis balancing post processing)
    375             ~xS';
    376 
    377             // The regex is a non-anchored pattern and does not have a single fixed starting character.
    378             // Tell PCRE to spend more time optimizing since, when used on a page load, it will probably be used several times.
    379 
    380             $ret = preg_replace_callback( $url_clickable, '_make_url_clickable_cb', $ret );
    381 
    382             $ret = preg_replace_callback( '#([\s>])((www|ftp)\.[\w\\x80-\\xff\#$%&~/.\-;:=,?@\[\]+]+)#is', '_make_web_ftp_clickable_cb', $ret );
    383             $ret = preg_replace_callback( '#([\s>])([.0-9a-z_+-]+)@(([0-9a-z-]+\.)+[0-9a-z]{2,})#i', '_make_email_clickable_cb', $ret );
    384 
     356            $ret = " {$piece} "; // Pad with whitespace to simplify the regexes
     357            $ret = apply_filters( 'bbp_make_clickable', $ret );
    385358            $ret = substr( $ret, 1, -1 ); // Remove our whitespace padding.
    386359            $r .= $ret;
     
    389362
    390363    // Cleanup of accidental links within links
    391     $r = preg_replace( '#(<a( [^>]+?>|>))<a [^>]+?>([^>]+?)</a></a>#i', "$1$3</a>", $r );
    392     return $r;
    393 }
     364    return preg_replace( '#(<a([ \r\n\t]+[^>]+?>|>))<a [^>]+?>([^>]+?)</a></a>#i', "$1$3</a>", $r );
     365}
     366
     367/**
     368 * Make URLs clickable in content areas
     369 *
     370 * @since 2.6.0
     371 *
     372 * @param  string $text
     373 * @return string
     374 */
     375function bbp_make_urls_clickable( $text = '' ) {
     376    $url_clickable = '~
     377        ([\\s(<.,;:!?])                                # 1: Leading whitespace, or punctuation
     378        (                                              # 2: URL
     379            [\\w]{1,20}+://                            # Scheme and hier-part prefix
     380            (?=\S{1,2000}\s)                           # Limit to URLs less than about 2000 characters long
     381            [\\w\\x80-\\xff#%\\~/@\\[\\]*(+=&$-]*+     # Non-punctuation URL character
     382            (?:                                        # Unroll the Loop: Only allow puctuation URL character if followed by a non-punctuation URL character
     383                [\'.,;:!?)]                            # Punctuation URL character
     384                [\\w\\x80-\\xff#%\\~/@\\[\\]*(+=&$-]++ # Non-punctuation URL character
     385            )*
     386        )
     387        (\)?)                                          # 3: Trailing closing parenthesis (for parethesis balancing post processing)
     388    ~xS';
     389
     390    // The regex is a non-anchored pattern and does not have a single fixed starting character.
     391    // Tell PCRE to spend more time optimizing since, when used on a page load, it will probably be used several times.
     392    return preg_replace_callback( $url_clickable, '_make_url_clickable_cb', $text );
     393}
     394
     395/**
     396 * Make FTP clickable in content areas
     397 *
     398 * @since 2.6.0
     399 *
     400 * @see make_clickable()
     401 *
     402 * @param  string $text
     403 * @return string
     404 */
     405function bbp_make_ftps_clickable( $text = '' ) {
     406    return preg_replace_callback( '#([\s>])((www|ftp)\.[\w\\x80-\\xff\#$%&~/.\-;:=,?@\[\]+]+)#is', '_make_web_ftp_clickable_cb', $text );
     407}
     408
     409/**
     410 * Make emails clickable in content areas
     411 *
     412 * @since 2.6.0
     413 *
     414 * @see make_clickable()
     415 *
     416 * @param  string $text
     417 * @return string
     418 */
     419function bbp_make_emails_clickable( $text = '' ) {
     420    return preg_replace_callback( '#([\s>])([.0-9a-z_+-]+)@(([0-9a-z-]+\.)+[0-9a-z]{2,})#i', '_make_email_clickable_cb', $text );
     421}
     422
     423/**
     424 * Make mentions clickable in content areas
     425 *
     426 * @since 2.6.0
     427 *
     428 * @see make_clickable()
     429 *
     430 * @param  string $text
     431 * @return string
     432 */
     433function bbp_make_mentions_clickable( $text = '' ) {
     434    return preg_replace_callback( '#([\s>])@([0-9a-zA-Z-_]+)#i', 'bbp_make_mentions_clickable_callback', $text );
     435}
     436
     437/**
     438 * Callback to convert mention matchs to HTML A tag.
     439 *
     440 * @since 2.6.0
     441 *
     442 * @param array $matches Single Regex Match.
     443 *
     444 * @return string HTML A tag with link to user profile.
     445 */
     446function bbp_make_mentions_clickable_callback( $matches = array() ) {
     447
     448    // Get user; bail if not found
     449    $user = get_user_by( 'slug', $matches[2] );
     450    if ( empty( $user ) || bbp_is_user_inactive( $user->ID ) ) {
     451        return $matches[0];
     452    }
     453
     454    // Create the link to the user's profile
     455    $url    = bbp_get_user_profile_url( $user->ID );
     456    $anchor = '<a href="%1$s" rel="nofollow">@%2$s</a>';
     457    $link   = sprintf( $anchor, esc_url( $url ), esc_html( $user->user_nicename ) );
     458
     459    return $matches[1] . $link;
     460}
  • trunk/src/includes/core/filters.php

    r5951 r6014  
    143143// Run filters on reply content
    144144add_filter( 'bbp_get_reply_content', 'bbp_make_clickable', 4    );
    145 add_filter( 'bbp_get_reply_content', 'bbp_mention_filter', 5    );
    146145add_filter( 'bbp_get_reply_content', 'wptexturize',        6    );
    147146add_filter( 'bbp_get_reply_content', 'convert_chars',      8    );
     
    154153// Run filters on topic content
    155154add_filter( 'bbp_get_topic_content', 'bbp_make_clickable', 4    );
    156 add_filter( 'bbp_get_topic_content', 'bbp_mention_filter', 5    );
    157155add_filter( 'bbp_get_topic_content', 'wptexturize',        6    );
    158156add_filter( 'bbp_get_topic_content', 'convert_chars',      8    );
     
    260258add_filter( 'bbp_map_meta_caps', 'bbp_map_reply_meta_caps',     10, 4 ); // Replies
    261259
     260// Clickables
     261add_filter( 'bbp_make_clickable', 'bbp_make_urls_clickable',      2 ); // https://bbpress.org
     262add_filter( 'bbp_make_clickable', 'bbp_make_ftps_clickable',      4 ); // ftps://bbpress.org
     263add_filter( 'bbp_make_clickable', 'bbp_make_emails_clickable',    6 ); // jjj@bbpress.org
     264add_filter( 'bbp_make_clickable', 'bbp_make_mentions_clickable',  8 ); // @jjj
     265
    262266/** Deprecated ****************************************************************/
    263267
  • trunk/src/includes/core/functions.php

    r5951 r6014  
    328328 *
    329329 * @since 2.4.0 bbPress (r4997)
     330 * @deprecated 2.6.0 bbp_make_clickable()
    330331 *
    331332 * @return string Pattern to match usernames with
     
    339340 *
    340341 * @since 2.2.0 bbPress (r4323)
     342 * @deprecated 2.6.0 bbp_make_clickable()
    341343 *
    342344 * @param string $content The content
     
    360362 *
    361363 * @since 2.2.0 bbPress (r4323)
     364 * @deprecated 2.6.0 bbp_make_clickable()
    362365 *
    363366 * @uses bbp_find_mentions() To get usernames in content areas
Note: See TracChangeset for help on using the changeset viewer.