From 6ff1f9a72fe627847466e6aaf26af9ea1d21df90 Mon Sep 17 00:00:00 2001 From: Sukhendu Sekhar Guria Date: Tue, 28 Jan 2025 14:39:34 +0530 Subject: [PATCH 1/3] Add filters to make_clickable callback functions --- src/wp-includes/default-filters.php | 5 ++ src/wp-includes/formatting.php | 89 +++++++++++++------ .../tests/formatting/makeClickableFilters.php | 72 +++++++++++++++ 3 files changed, 141 insertions(+), 25 deletions(-) create mode 100644 tests/phpunit/tests/formatting/makeClickableFilters.php diff --git a/src/wp-includes/default-filters.php b/src/wp-includes/default-filters.php index 54883b840d7f4..07bdace1d57d7 100644 --- a/src/wp-includes/default-filters.php +++ b/src/wp-includes/default-filters.php @@ -185,6 +185,11 @@ add_filter( $filter, 'shortcode_unautop' ); } +// Clickable content filters +add_filter( 'make_clickable', 'make_url_clickable', 2 ); +add_filter( 'make_clickable', 'make_ftp_clickable', 4 ); +add_filter( 'make_clickable', 'make_email_clickable', 6 ); + // Format for RSS. add_filter( 'term_name_rss', 'convert_chars' ); diff --git a/src/wp-includes/formatting.php b/src/wp-includes/formatting.php index 3ecc352528fec..7d6c65932f3ab 100644 --- a/src/wp-includes/formatting.php +++ b/src/wp-includes/formatting.php @@ -3106,31 +3106,7 @@ function make_clickable( $text ) { } } else { $ret = " $piece "; // Pad with whitespace to simplify the regexes. - - $url_clickable = '~ - ([\\s(<.,;:!?]) # 1: Leading whitespace, or punctuation. - ( # 2: URL. - [\\w]{1,20}+:// # Scheme and hier-part prefix. - (?=\S{1,2000}\s) # Limit to URLs less than about 2000 characters long. - [\\w\\x80-\\xff#%\\~/@\\[\\]*(+=&$-]*+ # Non-punctuation URL character. - (?: # Unroll the Loop: Only allow punctuation URL character if followed by a non-punctuation URL character. - [\'.,;:!?)] # Punctuation URL character. - [\\w\\x80-\\xff#%\\~/@\\[\\]*(+=&$-]++ # Non-punctuation URL character. - )* - ) - (\)?) # 3: Trailing closing parenthesis (for parenthesis balancing post processing). - (\\.\\w{2,6})? # 4: Allowing file extensions (e.g., .jpg, .png). - ~xS'; - /* - * The regex is a non-anchored pattern and does not have a single fixed starting character. - * Tell PCRE to spend more time optimizing since, when used on a page load, it will probably be used several times. - */ - - $ret = preg_replace_callback( $url_clickable, '_make_url_clickable_cb', $ret ); - - $ret = preg_replace_callback( '#([\s>])((www|ftp)\.[\w\\x80-\\xff\#$%&~/.\-;:=,?@\[\]+]+)#is', '_make_web_ftp_clickable_cb', $ret ); - $ret = preg_replace_callback( '#([\s>])([.0-9a-z_+-]+)@(([0-9a-z-]+\.)+[0-9a-z]{2,})#i', '_make_email_clickable_cb', $ret ); - + $ret = apply_filters( 'make_clickable', $ret ); $ret = substr( $ret, 1, -1 ); // Remove our whitespace padding. $r .= $ret; } @@ -3140,6 +3116,69 @@ function make_clickable( $text ) { return preg_replace( '#(]+?>|>))]+?>([^>]+?)#i', '$1$3', $r ); } +/** + * Converts URLs in text into clickable links. + * + * @since 6.8.0 + * @access private + * + * @param string $text The text to be processed. + * @return string Text with converted URLs. + */ +function make_url_clickable( $text ) { + $url_clickable = '~ + ([\\s(<.,;:!?]) # 1: Leading whitespace, or punctuation + ( # 2: URL + [\\w]{1,20}+:// # Scheme and hier-part prefix + (?=\S{1,2000}\s) # Limit to URLs less than about 2000 characters long + [\\w\\x80-\\xff#%\\~/@\\[\\]*(+=&$-]*+ # Non-punctuation URL character + (?: # Unroll the Loop: Only allow puctuation URL character if followed by a non-punctuation URL character + [\'.,;:!?)] # Punctuation URL character + [\\w\\x80-\\xff#%\\~/@\\[\\]*(+=&$-]++ # Non-punctuation URL character + )* + ) + (\)?) # 3: Trailing closing parenthesis (for parethesis balancing post processing) + ~xS'; + + // The regex is a non-anchored pattern and does not have a single fixed starting character. + // Tell PCRE to spend more time optimizing since, when used on a page load, it will probably be used several times. + return preg_replace_callback( $url_clickable, '_make_url_clickable_cb', $text ); +} + +/** + * Converts FTP and www addresses in text into clickable links. + * + * @since 6.8.0 + * @access private + * + * @param string $text The text to be processed. + * @return string Text with converted FTP and www addresses. + */ +function make_ftp_clickable( $text ) { + return preg_replace_callback( + '#([\s>])((www|ftp)\.[\w\\x80-\\xff\#$%&~/.\-;:=,?@\[\]+]+)#is', + '_make_web_ftp_clickable_cb', + $text + ); +} + +/** + * Converts email addresses in text into clickable links. + * + * @since 6.8.0 + * @access private + * + * @param string $text The text to be processed. + * @return string Text with converted email addresses. + */ +function make_email_clickable( $text ) { + return preg_replace_callback( + '#([\s>])([.0-9a-z_+-]+)@(([0-9a-z-]+\.)+[0-9a-z]{2,})#i', + '_make_email_clickable_cb', + $text + ); +} + /** * Breaks a string into chunks by splitting at whitespace characters. * diff --git a/tests/phpunit/tests/formatting/makeClickableFilters.php b/tests/phpunit/tests/formatting/makeClickableFilters.php new file mode 100644 index 0000000000000..9471b4fb6e518 --- /dev/null +++ b/tests/phpunit/tests/formatting/makeClickableFilters.php @@ -0,0 +1,72 @@ +test@example.com'; + + $this->assertSame( $expected, make_clickable( $text ) ); + } + + /** + * @ticket 32787 + */ + public function test_remove_email_filter() { + remove_filter( 'make_clickable', 'make_email_clickable', 6 ); + + $text = 'Visit http://wordpress.org and test@example.com'; + $expected = 'Visit http://wordpress.org and test@example.com'; + + $this->assertSame( $expected, make_clickable( $text ) ); + } + + /** + * @ticket 32787 + */ + public function test_remove_ftp_filter() { + remove_filter( 'make_clickable', 'make_ftp_clickable', 4 ); + + $text = 'Visit ftp.wordpress.org and http://wordpress.org'; + $expected = 'Visit ftp.wordpress.org and http://wordpress.org'; + + $this->assertSame( $expected, make_clickable( $text ) ); + } + + /** + * @ticket 32787 + */ + public function test_remove_all_filters() { + remove_all_filters( 'make_clickable' ); + + $text = 'Visit http://wordpress.org, ftp.wordpress.org and test@example.com'; + $expected = 'Visit http://wordpress.org, ftp.wordpress.org and test@example.com'; + + $this->assertSame( $expected, make_clickable( $text ) ); + } +} From c71aa0f7e798370f7134b620122e8bfcef3593fa Mon Sep 17 00:00:00 2001 From: Sukhendu Sekhar Guria Date: Tue, 28 Jan 2025 14:42:45 +0530 Subject: [PATCH 2/3] Fix PHPCS Errors --- tests/phpunit/tests/formatting/makeClickableFilters.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/phpunit/tests/formatting/makeClickableFilters.php b/tests/phpunit/tests/formatting/makeClickableFilters.php index 9471b4fb6e518..63c21a1e15005 100644 --- a/tests/phpunit/tests/formatting/makeClickableFilters.php +++ b/tests/phpunit/tests/formatting/makeClickableFilters.php @@ -17,10 +17,10 @@ public function set_up() { add_filter( 'make_clickable', 'make_email_clickable', 6 ); } - public function tear_down() { - parent::tear_down(); - remove_all_filters( 'make_clickable' ); - } + public function tear_down() { + parent::tear_down(); + remove_all_filters( 'make_clickable' ); + } /** * @ticket 32787 From 5bb3c4600d67f0a615bd3bbcd1ae3c72b74df4d8 Mon Sep 17 00:00:00 2001 From: Sukhendu Sekhar Guria Date: Tue, 28 Jan 2025 14:45:28 +0530 Subject: [PATCH 3/3] Fix PHPCS Errors --- src/wp-includes/default-filters.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wp-includes/default-filters.php b/src/wp-includes/default-filters.php index 07bdace1d57d7..6b6ebf87450a3 100644 --- a/src/wp-includes/default-filters.php +++ b/src/wp-includes/default-filters.php @@ -186,8 +186,8 @@ } // Clickable content filters -add_filter( 'make_clickable', 'make_url_clickable', 2 ); -add_filter( 'make_clickable', 'make_ftp_clickable', 4 ); +add_filter( 'make_clickable', 'make_url_clickable', 2 ); +add_filter( 'make_clickable', 'make_ftp_clickable', 4 ); add_filter( 'make_clickable', 'make_email_clickable', 6 ); // Format for RSS.