/** * @group bbp_make_clickable_misses * @group bbp_make_clickable_multiple * @covers ::bbp_make_clickable */ public function test_bbp_make_clickable_multiple_mention_misses() { $u1 = $this->factory->user->create(array('user_login' => 'foobarbaz', 'user_nicename' => 'foobarbaz')); $u2 = $this->factory->user->create(array('user_login' => 'foo2', 'user_nicename' => 'foo2')); // Create the link to the user's profile $user_1 = get_userdata($u1); $url_1 = bbp_get_user_profile_url($user_1->ID); $anchor_1 = '<a href="%1$s" rel="nofollow">@%2$s</a>'; $name_1 = $user_1->user_nicename; $link_1 = sprintf($anchor_1, esc_url($url_1), esc_html($name_1)); $user_2 = get_userdata($u2); $url_2 = bbp_get_user_profile_url($user_2->ID); $anchor_2 = '<a href="%1$s" rel="nofollow">@%2$s</a>'; $name_2 = $user_2->user_nicename; $link_2 = sprintf($anchor_2, esc_url($url_2), esc_html($name_2)); // Multiples $at_name_in_mailto = sprintf("Send messages to @%s, @non1, @%s, @non2.", $link_1, $link_2); $at_name_in_mailto_final = sprintf("Send messages to @%s, @non1, @%s, @non2.", $link_1, $link_2); $this->assertEquals($at_name_in_mailto_final, bbp_make_clickable($at_name_in_mailto)); }
/** * Convert plaintext URI to HTML links. * * Converts URI, www and ftp, and email addresses. Finishes by fixing links * within links. * * This custom version of WordPress's make_clickable() skips links inside of * pre and code tags. * * @since 2.4.0 bbPress (r4941) * * @param string $text Content to convert URIs. * @return string Content with converted URIs. */ function bbp_make_clickable($text = '') { $r = ''; $textarr = preg_split('/(<[^<>]+>)/', $text, -1, PREG_SPLIT_DELIM_CAPTURE); // split out HTML tags $nested_code_pre = 0; // Keep track of how many levels link is nested inside <pre> or <code> foreach ($textarr as $piece) { 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)) { $nested_code_pre++; } elseif ($nested_code_pre && ('</code>' === strtolower($piece) || '</pre>' === strtolower($piece) || '</script>' === strtolower($piece) || '</style>' === strtolower($piece))) { $nested_code_pre--; } if ($nested_code_pre || empty($piece) || $piece[0] === '<' && !preg_match('|^<\\s*[\\w]{1,20}+://|', $piece)) { $r .= $piece; continue; } // Long strings might contain expensive edge cases ... if (10000 < strlen($piece)) { // ... break it up foreach (_split_str_by_whitespace($piece, 2100) as $chunk) { // 2100: Extra room for scheme and leading and trailing paretheses if (2101 < strlen($chunk)) { $r .= $chunk; // Too big, no whitespace: bail. } else { $r .= bbp_make_clickable($chunk); } } } else { $ret = " {$piece} "; // Pad with whitespace to simplify the regexes $ret = apply_filters('bbp_make_clickable', $ret, $text); $ret = substr($ret, 1, -1); // Remove our whitespace padding. $r .= $ret; } } // Cleanup of accidental links within links return preg_replace('#(<a([ \\r\\n\\t]+[^>]+?>|>))<a [^>]+?>([^>]+?)</a></a>#i', "\$1\$3</a>", $r); }