From 416d1a8ddcecec8dd65da0d8d42baeca9085b044 Mon Sep 17 00:00:00 2001 From: Jonathan Desrosiers Date: Thu, 24 Aug 2023 14:21:36 +0000 Subject: [PATCH 001/184] Build/Test Tools: Implicitly pass secrets to the called workflow. This ensures the Hosting Test results API key is present for reporting results. Follow up to [56439] and [56440]. See #30462. git-svn-id: https://develop.svn.wordpress.org/trunk@56443 602fd350-edb4-49c9-b593-d223f7449a82 --- .github/workflows/phpunit-tests.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/phpunit-tests.yml b/.github/workflows/phpunit-tests.yml index 3b616e1c485a3..9c399d51ed791 100644 --- a/.github/workflows/phpunit-tests.yml +++ b/.github/workflows/phpunit-tests.yml @@ -39,6 +39,7 @@ jobs: uses: WordPress/wordpress-develop/.github/workflows/phpunit-tests-run.yml@trunk permissions: contents: read + secrets: inherit if: ${{ github.repository == 'WordPress/wordpress-develop' || github.event_name == 'pull_request' }} strategy: fail-fast: false @@ -90,6 +91,7 @@ jobs: uses: WordPress/wordpress-develop/.github/workflows/phpunit-tests-run.yml@trunk permissions: contents: read + secrets: inherit if: ${{ github.repository == 'WordPress/wordpress-develop' || github.event_name == 'pull_request' }} strategy: fail-fast: false From c63e32fe8a5fecf844bc4fe3f1a6a5bb2390d265 Mon Sep 17 00:00:00 2001 From: Aaron Jorbin Date: Thu, 24 Aug 2023 14:33:28 +0000 Subject: [PATCH 002/184] Build/Tests: Tests_Formatting_MakeClickable should use data providors Removes the foreach loops from the tests by moving the in-test data sets into data providers and combines the URL data sets into one data provider to test with one test method. By using a data providor, all the tests run rather than stopping at the first failure in this group. Fixes #57660. Props hellofromTonya. git-svn-id: https://develop.svn.wordpress.org/trunk@56444 602fd350-edb4-49c9-b593-d223f7449a82 --- .../tests/formatting/makeClickable.php | 703 ++++++++++-------- 1 file changed, 377 insertions(+), 326 deletions(-) diff --git a/tests/phpunit/tests/formatting/makeClickable.php b/tests/phpunit/tests/formatting/makeClickable.php index 0c6236c8592ca..658689605956f 100644 --- a/tests/phpunit/tests/formatting/makeClickable.php +++ b/tests/phpunit/tests/formatting/makeClickable.php @@ -11,369 +11,420 @@ public function test_mailto_xss() { $this->assertSame( $in, make_clickable( $in ) ); } - public function test_valid_mailto() { - $valid_emails = array( - 'foo@example.com', - 'foo.bar@example.com', - 'Foo.Bar@a.b.c.d.example.com', - '0@example.com', - 'foo@example-example.com', - ); - foreach ( $valid_emails as $email ) { - $this->assertSame( '' . $email . '', make_clickable( $email ) ); - } - } - - public function test_invalid_mailto() { - $invalid_emails = array( - 'foo', - 'foo@', - 'foo@@example.com', - '@example.com', - 'foo @example.com', - 'foo@example', - ); - foreach ( $invalid_emails as $email ) { - $this->assertSame( $email, make_clickable( $email ) ); - } - } - /** - * Tests that make_clickable() will not link trailing periods, commas, - * and (semi-)colons in URLs with protocol (i.e. http://wordpress.org). + * @dataProvider data_valid_mailto + * + * @param string $email Email to test. */ - public function test_strip_trailing_with_protocol() { - $urls_before = array( - 'http://wordpress.org/hello.html', - 'There was a spoon named http://wordpress.org. Alice!', - 'There was a spoon named http://wordpress.org, said Alice.', - 'There was a spoon named http://wordpress.org; said Alice.', - 'There was a spoon named http://wordpress.org: said Alice.', - 'There was a spoon named (http://wordpress.org) said Alice.', - ); - $urls_expected = array( - 'http://wordpress.org/hello.html', - 'There was a spoon named http://wordpress.org. Alice!', - 'There was a spoon named http://wordpress.org, said Alice.', - 'There was a spoon named http://wordpress.org; said Alice.', - 'There was a spoon named http://wordpress.org: said Alice.', - 'There was a spoon named (http://wordpress.org) said Alice.', - ); - - foreach ( $urls_before as $key => $url ) { - $this->assertSame( $urls_expected[ $key ], make_clickable( $url ) ); - } + public function test_valid_mailto( $email ) { + $this->assertSame( '' . $email . '', make_clickable( $email ) ); } /** - * Tests that make_clickable() will not link trailing periods, commas, - * and (semi-)colons in URLs with protocol (i.e. http://wordpress.org). + * Data provider. + * + * @return array */ - public function test_strip_trailing_with_protocol_nothing_afterwards() { - $urls_before = array( - 'http://wordpress.org/hello.html', - 'There was a spoon named http://wordpress.org.', - 'There was a spoon named http://wordpress.org,', - 'There was a spoon named http://wordpress.org;', - 'There was a spoon named http://wordpress.org:', - 'There was a spoon named (http://wordpress.org)', - 'There was a spoon named (http://wordpress.org)x', - ); - $urls_expected = array( - 'http://wordpress.org/hello.html', - 'There was a spoon named http://wordpress.org.', - 'There was a spoon named http://wordpress.org,', - 'There was a spoon named http://wordpress.org;', - 'There was a spoon named http://wordpress.org:', - 'There was a spoon named (http://wordpress.org)', - 'There was a spoon named (http://wordpress.org)x', + public function data_valid_mailto() { + return array( + array( 'foo@example.com' ), + array( 'foo.bar@example.com' ), + array( 'Foo.Bar@a.b.c.d.example.com' ), + array( '0@example.com' ), + array( 'foo@example-example.com' ), ); - - foreach ( $urls_before as $key => $url ) { - $this->assertSame( $urls_expected[ $key ], make_clickable( $url ) ); - } } /** - * Tests that make_clickable() will not link trailing periods, commas, - * and (semi-)colons in URLs without protocol (i.e. www.wordpress.org). + * @dataProvider data_invalid_mailto + * + * @param string $email Email to test. */ - public function test_strip_trailing_without_protocol() { - $urls_before = array( - 'www.wordpress.org', - 'There was a spoon named www.wordpress.org. Alice!', - 'There was a spoon named www.wordpress.org, said Alice.', - 'There was a spoon named www.wordpress.org; said Alice.', - 'There was a spoon named www.wordpress.org: said Alice.', - 'There was a spoon named www.wordpress.org) said Alice.', - ); - $urls_expected = array( - 'http://www.wordpress.org', - 'There was a spoon named http://www.wordpress.org. Alice!', - 'There was a spoon named http://www.wordpress.org, said Alice.', - 'There was a spoon named http://www.wordpress.org; said Alice.', - 'There was a spoon named http://www.wordpress.org: said Alice.', - 'There was a spoon named http://www.wordpress.org) said Alice.', - ); - - foreach ( $urls_before as $key => $url ) { - $this->assertSame( $urls_expected[ $key ], make_clickable( $url ) ); - } + public function test_invalid_mailto( $email ) { + $this->assertSame( $email, make_clickable( $email ) ); } /** - * Tests that make_clickable() will not link trailing periods, commas, - * and (semi-)colons in URLs without protocol (i.e. www.wordpress.org). + * Data provider. + * + * @return array */ - public function test_strip_trailing_without_protocol_nothing_afterwards() { - $urls_before = array( - 'www.wordpress.org', - 'There was a spoon named www.wordpress.org.', - 'There was a spoon named www.wordpress.org,', - 'There was a spoon named www.wordpress.org;', - 'There was a spoon named www.wordpress.org:', - 'There was a spoon named www.wordpress.org)', - ); - $urls_expected = array( - 'http://www.wordpress.org', - 'There was a spoon named http://www.wordpress.org.', - 'There was a spoon named http://www.wordpress.org,', - 'There was a spoon named http://www.wordpress.org;', - 'There was a spoon named http://www.wordpress.org:', - 'There was a spoon named http://www.wordpress.org)', + public function data_invalid_mailto() { + return array( + array( 'foo' ), + array( 'foo@' ), + array( 'foo@@example.com' ), + array( '@example.com' ), + array( 'foo @example.com' ), + array( 'foo@example' ), ); - - foreach ( $urls_before as $key => $url ) { - $this->assertSame( $urls_expected[ $key ], make_clickable( $url ) ); - } } /** * @ticket 4570 - */ - public function test_iri() { - $urls_before = array( - 'http://www.詹姆斯.com/', - 'http://bg.wikipedia.org/Баба', - 'http://example.com/?a=баба&b=дядо', - ); - $urls_expected = array( - 'http://www.詹姆斯.com/', - 'http://bg.wikipedia.org/Баба', - 'http://example.com/?a=баба&b=дядо', - ); - foreach ( $urls_before as $key => $url ) { - $this->assertSame( $urls_expected[ $key ], make_clickable( $url ) ); - } - } - - /** * @ticket 10990 + * @ticket 11211 + * @ticket 14993 + * @ticket 16892 + * + * @dataProvider data_urls + * + * @param string $text Content to test. + * @param string $expected Expected results. */ - public function test_brackets_in_urls() { - $urls_before = array( - 'http://en.wikipedia.org/wiki/PC_Tools_(Central_Point_Software)', - '(http://en.wikipedia.org/wiki/PC_Tools_(Central_Point_Software))', - 'blah http://en.wikipedia.org/wiki/PC_Tools_(Central_Point_Software) blah', - 'blah (http://en.wikipedia.org/wiki/PC_Tools_(Central_Point_Software)) blah', - 'blah blah blah http://en.wikipedia.org/wiki/PC_Tools_(Central_Point_Software) blah blah', - 'blah blah blah http://en.wikipedia.org/wiki/PC_Tools_(Central_Point_Software)) blah blah', - 'blah blah (http://en.wikipedia.org/wiki/PC_Tools_(Central_Point_Software)) blah blah', - 'blah blah http://en.wikipedia.org/wiki/PC_Tools_(Central_Point_Software).) blah blah', - 'blah blah http://en.wikipedia.org/wiki/PC_Tools_(Central_Point_Software).)moreurl blah blah', - 'In his famous speech “You and Your research” (here: - http://www.cs.virginia.edu/~robins/YouAndYourResearch.html) - Richard Hamming wrote about people getting more done with their doors closed, but', - ); - $urls_expected = array( - 'http://en.wikipedia.org/wiki/PC_Tools_(Central_Point_Software)', - '(http://en.wikipedia.org/wiki/PC_Tools_(Central_Point_Software))', - 'blah http://en.wikipedia.org/wiki/PC_Tools_(Central_Point_Software) blah', - 'blah (http://en.wikipedia.org/wiki/PC_Tools_(Central_Point_Software)) blah', - 'blah blah blah http://en.wikipedia.org/wiki/PC_Tools_(Central_Point_Software) blah blah', - 'blah blah blah http://en.wikipedia.org/wiki/PC_Tools_(Central_Point_Software)) blah blah', - 'blah blah (http://en.wikipedia.org/wiki/PC_Tools_(Central_Point_Software)) blah blah', - 'blah blah http://en.wikipedia.org/wiki/PC_Tools_(Central_Point_Software).) blah blah', - 'blah blah http://en.wikipedia.org/wiki/PC_Tools_(Central_Point_Software).)moreurl blah blah', - 'In his famous speech “You and Your research” (here: - http://www.cs.virginia.edu/~robins/YouAndYourResearch.html) - Richard Hamming wrote about people getting more done with their doors closed, but', - ); - foreach ( $urls_before as $key => $url ) { - $this->assertSame( $urls_expected[ $key ], make_clickable( $url ) ); - } + public function test_urls( $text, $expected ) { + $this->assertSame( $expected, make_clickable( $text ) ); } /** - * Based on real comments which were incorrectly linked. + * Data provider. * - * @ticket 11211 + * @return array */ - public function test_real_world_examples() { - $urls_before = array( - 'Example: WordPress, test (some text), I love example.com (http://example.org), it is brilliant', - 'Example: WordPress, test (some text), I love example.com (http://example.com), it is brilliant', - 'Some text followed by a bracketed link with a trailing elipsis (http://example.com)...', - 'In his famous speech “You and Your research” (here: http://www.cs.virginia.edu/~robins/YouAndYourResearch.html) Richard Hamming wrote about people getting more done with their doors closed...', - ); - $urls_expected = array( - 'Example: WordPress, test (some text), I love example.com (http://example.org), it is brilliant', - 'Example: WordPress, test (some text), I love example.com (http://example.com), it is brilliant', - 'Some text followed by a bracketed link with a trailing elipsis (http://example.com)...', - 'In his famous speech “You and Your research” (here: http://www.cs.virginia.edu/~robins/YouAndYourResearch.html) Richard Hamming wrote about people getting more done with their doors closed...', - ); - foreach ( $urls_before as $key => $url ) { - $this->assertSame( $urls_expected[ $key ], make_clickable( $url ) ); - } - } + public function data_urls() { + return array( + // Does not link trailing periods, commas, and (semi-)colons in URLs with protocol (i.e. http://wordpress.org). + 'URL only' => array( + 'text' => 'http://wordpress.org/hello.html', + 'expected' => 'http://wordpress.org/hello.html', + ), + 'URL. with more content after' => array( + 'text' => 'There was a spoon named http://wordpress.org. Alice!', + 'expected' => 'There was a spoon named http://wordpress.org. Alice!', + ), + 'URL, with more content after' => array( + 'text' => 'There was a spoon named http://wordpress.org, said Alice.', + 'expected' => 'There was a spoon named http://wordpress.org, said Alice.', + ), + 'URL; with more content after' => array( + 'text' => 'There was a spoon named http://wordpress.org; said Alice.', + 'expected' => 'There was a spoon named http://wordpress.org; said Alice.', + ), + 'URL: with more content after' => array( + 'text' => 'There was a spoon named http://wordpress.org: said Alice.', + 'expected' => 'There was a spoon named http://wordpress.org: said Alice.', + ), + 'URL) with more content after' => array( + 'text' => 'There was a spoon named (http://wordpress.org) said Alice.', + 'expected' => 'There was a spoon named (http://wordpress.org) said Alice.', + ), - /** - * @ticket 14993 - */ - public function test_twitter_hash_bang() { - $urls_before = array( - 'http://twitter.com/#!/wordpress/status/25907440233', - 'This is a really good tweet http://twitter.com/#!/wordpress/status/25907440233 !', - 'This is a really good tweet http://twitter.com/#!/wordpress/status/25907440233!', - ); - $urls_expected = array( - 'http://twitter.com/#!/wordpress/status/25907440233', - 'This is a really good tweet http://twitter.com/#!/wordpress/status/25907440233 !', - 'This is a really good tweet http://twitter.com/#!/wordpress/status/25907440233!', - ); - foreach ( $urls_before as $key => $url ) { - $this->assertSame( $urls_expected[ $key ], make_clickable( $url ) ); - } - } + // Does not link trailing periods, commas, and (semi-)colons in URLs with protocol (i.e. http://wordpress.org) with nothing afterwards. + 'URL.' => array( + 'text' => 'There was a spoon named http://wordpress.org.', + 'expected' => 'There was a spoon named http://wordpress.org.', + ), + 'URL,' => array( + 'text' => 'There was a spoon named http://wordpress.org,', + 'expected' => 'There was a spoon named http://wordpress.org,', + ), + 'URL;' => array( + 'text' => 'There was a spoon named http://wordpress.org;', + 'expected' => 'There was a spoon named http://wordpress.org;', + ), + 'URL:' => array( + 'text' => 'There was a spoon named http://wordpress.org:', + 'expected' => 'There was a spoon named http://wordpress.org:', + ), + 'URL)' => array( + 'text' => 'There was a spoon named (http://wordpress.org)', + 'expected' => 'There was a spoon named (http://wordpress.org)', + ), + 'URL)x' => array( + 'text' => 'There was a spoon named (http://wordpress.org)x', + 'expected' => 'There was a spoon named (http://wordpress.org)x', + ), - public function test_wrapped_in_angles() { - $before = array( - 'URL wrapped in angle brackets ', - 'URL wrapped in angle brackets with padding < http://example.com/ >', - 'mailto wrapped in angle brackets ', - ); - $expected = array( - 'URL wrapped in angle brackets <http://example.com/>', - 'URL wrapped in angle brackets with padding < http://example.com/ >', - 'mailto wrapped in angle brackets ', - ); - foreach ( $before as $key => $url ) { - $this->assertSame( $expected[ $key ], make_clickable( $url ) ); - } - } + // Strip trailing without protocol: will not link trailing periods, commas, and (semi-)colons in URLs without protocol (i.e. www.wordpress.org). + 'No protocol www.URL. with content after' => array( + 'text' => 'There was a spoon named www.wordpress.org. Alice!', + 'expected' => 'There was a spoon named http://www.wordpress.org. Alice!', + ), + 'No protocol www.URL, with content after' => array( + 'text' => 'There was a spoon named www.wordpress.org, said Alice.', + 'expected' => 'There was a spoon named http://www.wordpress.org, said Alice.', + ), + 'No protocol www.URL; with content after' => array( + 'text' => 'There was a spoon named www.wordpress.org; said Alice.', + 'expected' => 'There was a spoon named http://www.wordpress.org; said Alice.', + ), + 'No protocol www.URL: with content after' => array( + 'text' => 'There was a spoon named www.wordpress.org: said Alice.', + 'expected' => 'There was a spoon named http://www.wordpress.org: said Alice.', + ), + 'No protocol www.URL) with content after' => array( + 'text' => 'There was a spoon named www.wordpress.org) said Alice.', + 'expected' => 'There was a spoon named http://www.wordpress.org) said Alice.', + ), - public function test_preceded_by_punctuation() { - $before = array( - 'Comma then URL,http://example.com/', - 'Period then URL.http://example.com/', - 'Semi-colon then URL;http://example.com/', - 'Colon then URL:http://example.com/', - 'Exclamation mark then URL!http://example.com/', - 'Question mark then URL?http://example.com/', - ); - $expected = array( - 'Comma then URL,http://example.com/', - 'Period then URL.http://example.com/', - 'Semi-colon then URL;http://example.com/', - 'Colon then URL:http://example.com/', - 'Exclamation mark then URL!http://example.com/', - 'Question mark then URL?http://example.com/', - ); - foreach ( $before as $key => $url ) { - $this->assertSame( $expected[ $key ], make_clickable( $url ) ); - } - } + // Should not link trailing periods, commas, and (semi-)colons in URLs without protocol (i.e. www.wordpress.org). + 'No protocol www.URL' => array( + 'text' => 'www.wordpress.org', + 'expected' => 'http://www.wordpress.org', + ), + 'No protocol www.URL.' => array( + 'text' => 'There was a spoon named www.wordpress.org.', + 'expected' => 'There was a spoon named http://www.wordpress.org.', + ), + 'No protocol www.URL,' => array( + 'text' => 'There was a spoon named www.wordpress.org,', + 'expected' => 'There was a spoon named http://www.wordpress.org,', + ), + 'No protocol www.URL;' => array( + 'text' => 'There was a spoon named www.wordpress.org;', + 'expected' => 'There was a spoon named http://www.wordpress.org;', + ), + 'No protocol www.URL:' => array( + 'text' => 'There was a spoon named www.wordpress.org:', + 'expected' => 'There was a spoon named http://www.wordpress.org:', + ), + 'No protocol www.URL)' => array( + 'text' => 'There was a spoon named www.wordpress.org)', + 'expected' => 'There was a spoon named http://www.wordpress.org)', + ), - public function test_dont_break_attributes() { - $urls_before = array( - ":)", - "(:))", - "http://trunk.domain/testing#something (:))", - "http://trunk.domain/testing#something - (:))", - " ", - 'Look at this image!', - ); - $urls_expected = array( - ":)", - "(:))", - "http://trunk.domain/testing#something (:))", - "http://trunk.domain/testing#something - (:))", - " ", - 'Look at this image!', - ); - foreach ( $urls_before as $key => $url ) { - $this->assertSame( $urls_expected[ $key ], make_clickable( $url ) ); - } - } + // @ticket 4570 + // Test IRI. + 'IRI in domain' => array( + 'text' => 'http://www.詹姆斯.com/', + 'expected' => 'http://www.詹姆斯.com/', + ), + 'IRI in path' => array( + 'text' => 'http://bg.wikipedia.org/Баба', + 'expected' => 'http://bg.wikipedia.org/Баба', + ), + 'IRI in query string' => array( + 'text' => 'http://example.com/?a=баба&b=дядо', + 'expected' => 'http://example.com/?a=баба&b=дядо', + ), - /** - * @ticket 23756 - */ - public function test_no_links_inside_pre_or_code() { - $before = array( - '
http://wordpress.org
', - 'http://wordpress.org', - '
http://wordpress.org
', - 'http://wordpress.org', - 'http://wordpress.org', - 'http://wordpress.org', - 'URL before pre http://wordpress.org
http://wordpress.org
', - 'URL before code http://wordpress.orghttp://wordpress.org', - 'URL after pre
http://wordpress.org
http://wordpress.org', - 'URL after code http://wordpress.orghttp://wordpress.org', - 'URL before and after pre http://wordpress.org
http://wordpress.org
http://wordpress.org', - 'URL before and after code http://wordpress.orghttp://wordpress.orghttp://wordpress.org', - 'code inside pre
http://wordpress.org http://wordpress.org http://wordpress.org
', - ); + // @ticket 10990 + // Test URLS with brackets (within the URL). + 'URL with brackets in path' => array( + 'text' => 'http://en.wikipedia.org/wiki/PC_Tools_(Central_Point_Software)', + 'expected' => 'http://en.wikipedia.org/wiki/PC_Tools_(Central_Point_Software)', + ), + '(URL with brackets in path)' => array( + 'text' => '(http://en.wikipedia.org/wiki/PC_Tools_(Central_Point_Software))', + 'expected' => '(http://en.wikipedia.org/wiki/PC_Tools_(Central_Point_Software))', + ), + 'URL with brackets in path: word before and after' => array( + 'text' => 'blah http://en.wikipedia.org/wiki/PC_Tools_(Central_Point_Software) blah', + 'expected' => 'blah http://en.wikipedia.org/wiki/PC_Tools_(Central_Point_Software) blah', + ), + 'URL with brackets in path: trailing ) blah' => array( + 'text' => 'blah (http://en.wikipedia.org/wiki/PC_Tools_(Central_Point_Software)) blah', + 'expected' => 'blah (http://en.wikipedia.org/wiki/PC_Tools_(Central_Point_Software)) blah', + ), + 'URL with brackets in path: within content' => array( + 'text' => 'blah blah blah http://en.wikipedia.org/wiki/PC_Tools_(Central_Point_Software) blah blah', + 'expected' => 'blah blah blah http://en.wikipedia.org/wiki/PC_Tools_(Central_Point_Software) blah blah', + ), + 'URL with brackets in path: trailing ) within content' => array( + 'text' => 'blah blah blah http://en.wikipedia.org/wiki/PC_Tools_(Central_Point_Software)) blah blah', + 'expected' => 'blah blah blah http://en.wikipedia.org/wiki/PC_Tools_(Central_Point_Software)) blah blah', + ), + '(URL with brackets in path) within content' => array( + 'text' => 'blah blah (http://en.wikipedia.org/wiki/PC_Tools_(Central_Point_Software)) blah blah', + 'expected' => 'blah blah (http://en.wikipedia.org/wiki/PC_Tools_(Central_Point_Software)) blah blah', + ), + 'URL with brackets in path: trailing .)' => array( + 'text' => 'blah blah http://en.wikipedia.org/wiki/PC_Tools_(Central_Point_Software).) blah blah', + 'expected' => 'blah blah http://en.wikipedia.org/wiki/PC_Tools_(Central_Point_Software).) blah blah', + ), + 'URL with brackets in path: trailing .)moreurl' => array( + 'text' => 'blah blah http://en.wikipedia.org/wiki/PC_Tools_(Central_Point_Software).)moreurl blah blah', + 'expected' => 'blah blah http://en.wikipedia.org/wiki/PC_Tools_(Central_Point_Software).)moreurl blah blah', + ), + 'multiline content with URL with brackets in path' => array( + 'text' => 'In his famous speech “You and Your research” (here: + http://www.cs.virginia.edu/~robins/YouAndYourResearch.html) + Richard Hamming wrote about people getting more done with their doors closed, but', + 'expected' => 'In his famous speech “You and Your research” (here: + http://www.cs.virginia.edu/~robins/YouAndYourResearch.html) + Richard Hamming wrote about people getting more done with their doors closed, but', + ), - $expected = array( - '
http://wordpress.org
', - 'http://wordpress.org', - '
http://wordpress.org
', - 'http://wordpress.org', - 'http://wordpress.org', - 'http://wordpress.org', - 'URL before pre http://wordpress.org
http://wordpress.org
', - 'URL before code http://wordpress.orghttp://wordpress.org', - 'URL after pre
http://wordpress.org
http://wordpress.org', - 'URL after code http://wordpress.orghttp://wordpress.org', - 'URL before and after pre http://wordpress.org
http://wordpress.org
http://wordpress.org', - 'URL before and after code http://wordpress.orghttp://wordpress.orghttp://wordpress.org', - 'code inside pre
http://wordpress.org http://wordpress.org http://wordpress.org
', - ); + // @ticket 11211 + // Test with real comments which were incorrectly linked. + 'real world: example.com text (.org URL)' => array( + 'text' => 'Example: WordPress, test (some text), I love example.com (http://example.org), it is brilliant', + 'expected' => 'Example: WordPress, test (some text), I love example.com (http://example.org), it is brilliant', + ), + 'real world: example.com text (.com URL)' => array( + 'text' => 'Example: WordPress, test (some text), I love example.com (http://example.com), it is brilliant', + 'expected' => 'Example: WordPress, test (some text), I love example.com (http://example.com), it is brilliant', + ), + 'real world: (URL)...' => array( + 'text' => 'Some text followed by a bracketed link with a trailing elipsis (http://example.com)...', + 'expected' => 'Some text followed by a bracketed link with a trailing elipsis (http://example.com)...', + ), + 'real world: (here: URL)' => array( + 'text' => 'In his famous speech “You and Your research” (here: http://www.cs.virginia.edu/~robins/YouAndYourResearch.html) Richard Hamming wrote about people getting more done with their doors closed...', + 'expected' => 'In his famous speech “You and Your research” (here: http://www.cs.virginia.edu/~robins/YouAndYourResearch.html) Richard Hamming wrote about people getting more done with their doors closed...', + ), - foreach ( $before as $key => $url ) { - $this->assertSame( $expected[ $key ], make_clickable( $url ) ); - } - } + // @ticket 14993 + // Test Twitter hash bang URL. + 'Twitter hash bang URL' => array( + 'text' => 'http://twitter.com/#!/wordpress/status/25907440233', + 'expected' => 'http://twitter.com/#!/wordpress/status/25907440233', + ), + 'Twitter hash bang URL in sentence' => array( + 'text' => 'This is a really good tweet http://twitter.com/#!/wordpress/status/25907440233 !', + 'expected' => 'This is a really good tweet http://twitter.com/#!/wordpress/status/25907440233 !', + ), + 'Twitter hash bang in sentence with trailing !' => array( + 'text' => 'This is a really good tweet http://twitter.com/#!/wordpress/status/25907440233!', + 'expected' => 'This is a really good tweet http://twitter.com/#!/wordpress/status/25907440233!', + ), - /** - * @ticket 16892 - */ - public function test_click_inside_html() { - $urls_before = array( - 'http://example.com', - '

http://example.com/

', - ); - $urls_expected = array( - 'http://example.com', - '

http://example.com/

', - ); - foreach ( $urls_before as $key => $url ) { - $this->assertSame( $urls_expected[ $key ], make_clickable( $url ) ); - } - } + // Test URLs wrapped in angled brackets, i.e. < >. + '' => array( + 'text' => 'URL wrapped in angle brackets ', + 'expected' => 'URL wrapped in angle brackets <http://example.com/>', + ), + '< URL >' => array( + 'text' => 'URL wrapped in angle brackets with padding < http://example.com/ >', + 'expected' => 'URL wrapped in angle brackets with padding < http://example.com/ >', + ), + '' => array( + 'text' => 'mailto wrapped in angle brackets ', + 'expected' => 'mailto wrapped in angle brackets ', + ), + + // Test URLs preceded by punctuation. + ',URL' => array( + 'text' => 'Comma then URL,http://example.com/', + 'expected' => 'Comma then URL,http://example.com/', + ), + '.URL' => array( + 'text' => 'Period then URL.http://example.com/', + 'expected' => 'Period then URL.http://example.com/', + ), + ';URL' => array( + 'text' => 'Semi-colon then URL;http://example.com/', + 'expected' => 'Semi-colon then URL;http://example.com/', + ), + ':URL' => array( + 'text' => 'Colon then URL:http://example.com/', + 'expected' => 'Colon then URL:http://example.com/', + ), + '!URL' => array( + 'text' => 'Exclamation mark then URL!http://example.com/', + 'expected' => 'Exclamation mark then URL!http://example.com/', + ), + '?URL' => array( + 'text' => 'Question mark then URL?http://example.com/', + 'expected' => 'Question mark then URL?http://example.com/', + ), + + // Test it doesn't break tag attributes. + '' => array( + 'text' => ":)", + 'expected' => ":)", + ), + '()' => array( + 'text' => "(:))", + 'expected' => "(:))", + ), + 'URL ()' => array( + 'text' => "http://trunk.domain/testing#something (:))", + 'expected' => "http://trunk.domain/testing#something (:))", + ), + 'multiline URL ()' => array( + 'text' => "http://trunk.domain/testing#something + (:))", + 'expected' => "http://trunk.domain/testing#something + (:))", + ), + '' => array( + 'text' => " ", + 'expected' => " ", + ), + '' => array( + 'text' => 'Look at this image!', + 'expected' => 'Look at this image!', + ), + + // Test doesn't add links within
 or  elements.
+			'Does not add link within 
'             => array(
+				'text'     => '
http://wordpress.org
', + 'expected' => '
http://wordpress.org
', + ), + 'Does not add link within ' => array( + 'text' => 'http://wordpress.org', + 'expected' => 'http://wordpress.org', + ), + 'Does not add link within
' => array(
+				'text'     => '
http://wordpress.org
', + 'expected' => '
http://wordpress.org
', + ), + 'Does not add link within ' => array( + 'text' => 'http://wordpress.org', + 'expected' => 'http://wordpress.org', + ), + 'Adds link within ' => array( + 'text' => 'http://wordpress.org', + 'expected' => 'http://wordpress.org', + ), + 'Adds link within ' => array( + 'text' => 'http://wordpress.org', + 'expected' => 'http://wordpress.org', + ), + 'Adds link to URL before
, but does not add link within 
' => array(
+				'text'     => 'URL before pre http://wordpress.org
http://wordpress.org
', + 'expected' => 'URL before pre http://wordpress.org
http://wordpress.org
', + ), + 'Adds link to URL before , but does not add link within ' => array( + 'text' => 'URL before code http://wordpress.orghttp://wordpress.org', + 'expected' => 'URL before code http://wordpress.orghttp://wordpress.org', + ), + 'Does not add link to
, but does add link to URL after 
' => array(
+				'text'     => 'URL after pre 
http://wordpress.org
http://wordpress.org', + 'expected' => 'URL after pre
http://wordpress.org
http://wordpress.org', + ), + 'Does not add link within , but does add link to URL after ' => array( + 'text' => 'URL after code http://wordpress.orghttp://wordpress.org', + 'expected' => 'URL after code http://wordpress.orghttp://wordpress.org', + ), + 'Adds link to before and after URLs, but does not add link within
' => array(
+				'text'     => 'URL before and after pre http://wordpress.org
http://wordpress.org
http://wordpress.org', + 'expected' => 'URL before and after pre http://wordpress.org
http://wordpress.org
http://wordpress.org', + ), + 'Adds link to before and after URLs, but does not add link within ' => array( + 'text' => 'URL before and after code http://wordpress.orghttp://wordpress.orghttp://wordpress.org', + 'expected' => 'URL before and after code http://wordpress.orghttp://wordpress.orghttp://wordpress.org', + ), + 'Does not add links within nested
URL URL 
' => array( + 'text' => 'code inside pre
http://wordpress.org http://wordpress.org http://wordpress.org
', + 'expected' => 'code inside pre
http://wordpress.org http://wordpress.org http://wordpress.org
', + ), - public function test_no_links_within_links() { - $in = array( - 'Some text with a link http://example.com', - // 'This is already a link www.wordpress.org', // Fails in 3.3.1 too. + // @ticket 16892 + // Test adds link inside of HTML elements. + 'URL' => array( + 'text' => 'http://example.com', + 'expected' => 'http://example.com', + ), + '

URL

' => array( + 'text' => '

http://example.com/

', + 'expected' => '

http://example.com/

', + ), + + // Test does not add links within the element. + 'URL' => array( + 'text' => 'Some text with a link http://example.com', + 'expected' => 'Some text with a link http://example.com', + ), + /* + Fails in 3.3.1 too. + 'text www.URL' => array( + 'text' => 'This is already a link www.wordpress.org', + 'expected' => 'This is already a link www.wordpress.org', + ), + */ ); - foreach ( $in as $text ) { - $this->assertSame( $text, make_clickable( $text ) ); - } } /** From 81423c3ea63531c8c9ff7591295825eabd7a5b99 Mon Sep 17 00:00:00 2001 From: flixos90 Date: Thu, 24 Aug 2023 14:40:01 +0000 Subject: [PATCH 003/184] Options, Meta APIs: Introduce `prime_options()` to load multiple options with a single database request. WordPress's `get_option()` function generally relies on making individual database requests for each option, however with the majority of options (in most cases) being autoloaded, i.e. fetched once with a single database request and then stored in (memory) cache. As part of a greater effort to reduce the amount of options that are unnecessarily autoloaded, this changeset introduces an alternative way to retrieve multiple options in a performant manner, with a single database request. This provides a reasonable alternative for e.g. plugins that use several options which only need to be loaded in a few specific screens. Specifically, this changeset introduces the following functions: * `prime_options( $options )` is the foundation to load multiple specific options with a single database request. Only options that aren't already cached (in `alloptions` or an individual cache) are retrieved from the database. * `prime_options_by_group( $option_group )` is a convenience wrapper function for the above which allows to prime all options of a specific option group (as configured via `register_setting()`). * `get_options( $options )` is another wrapper function which first primes the requested options and then returns them in an associative array, calling `get_option()` for each of them. Props mukesh27, joemcgill, costdev, olliejones. Fixes #58962. git-svn-id: https://develop.svn.wordpress.org/trunk@56445 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/option.php | 111 +++++++++++++++ tests/phpunit/tests/option/getOptions.php | 91 ++++++++++++ tests/phpunit/tests/option/primeOptions.php | 130 ++++++++++++++++++ .../tests/option/primeOptionsByGroup.php | 75 ++++++++++ 4 files changed, 407 insertions(+) create mode 100644 tests/phpunit/tests/option/getOptions.php create mode 100644 tests/phpunit/tests/option/primeOptions.php create mode 100644 tests/phpunit/tests/option/primeOptionsByGroup.php diff --git a/src/wp-includes/option.php b/src/wp-includes/option.php index abeb0ae2f7ca9..93f70f7b504c2 100644 --- a/src/wp-includes/option.php +++ b/src/wp-includes/option.php @@ -253,6 +253,117 @@ function get_option( $option, $default_value = false ) { return apply_filters( "option_{$option}", maybe_unserialize( $value ), $option ); } +/** + * Primes specific options into the cache with a single database query. + * + * Only options that do not already exist in cache will be primed. + * + * @since 6.4.0 + * + * @global wpdb $wpdb WordPress database abstraction object. + * + * @param array $options An array of option names to be primed. + */ +function prime_options( $options ) { + $alloptions = wp_load_alloptions(); + $cached_options = wp_cache_get_multiple( $options, 'options' ); + + // Filter options that are not in the cache. + $options_to_prime = array(); + foreach ( $options as $option ) { + if ( ( ! isset( $cached_options[ $option ] ) || ! $cached_options[ $option ] ) && ! isset( $alloptions[ $option ] ) ) { + $options_to_prime[] = $option; + } + } + + // Bail early if there are no options to be primed. + if ( empty( $options_to_prime ) ) { + return; + } + + global $wpdb; + $results = $wpdb->get_results( + $wpdb->prepare( + sprintf( + "SELECT option_name, option_value FROM $wpdb->options WHERE option_name IN (%s)", + implode( ',', array_fill( 0, count( $options_to_prime ), '%s' ) ) + ), + $options_to_prime + ) + ); + + $options_found = array(); + foreach ( $results as $result ) { + $options_found[ $result->option_name ] = maybe_unserialize( $result->option_value ); + } + wp_cache_set_multiple( $options_found, 'options' ); + + // If all options were found, no need to update `notoptions` cache. + if ( count( $options_found ) === count( $options_to_prime ) ) { + return; + } + + $options_not_found = array_diff( $options_to_prime, array_keys( $options_found ) ); + + $notoptions = wp_cache_get( 'notoptions', 'options' ); + + if ( ! is_array( $notoptions ) ) { + $notoptions = array(); + } + + // Add the options that were not found to the cache. + $update_notoptions = false; + foreach ( $options_not_found as $option_name ) { + if ( ! isset( $notoptions[ $option_name ] ) ) { + $notoptions[ $option_name ] = true; + $update_notoptions = true; + } + } + + // Only update the cache if it was modified. + if ( $update_notoptions ) { + wp_cache_set( 'notoptions', $notoptions, 'options' ); + } +} + +/** + * Primes all options registered with a specific option group. + * + * @since 6.4.0 + * + * @global array $new_allowed_options + * + * @param string $option_group The option group to prime options for. + */ +function prime_options_by_group( $option_group ) { + global $new_allowed_options; + + if ( isset( $new_allowed_options[ $option_group ] ) ) { + prime_options( $new_allowed_options[ $option_group ] ); + } +} + +/** + * Retrieves multiple options. + * + * Options are primed as necessary first in order to use a single database query at most. + * + * @since 6.4.0 + * + * @param array $options An array of option names to retrieve. + * @return array An array of key-value pairs for the requested options. + */ +function get_options( $options ) { + prime_options( $options ); + + $result = array(); + foreach ( $options as $option ) { + $result[ $option ] = get_option( $option ); + } + + return $result; +} + /** * Protects WordPress special option from being modified. * diff --git a/tests/phpunit/tests/option/getOptions.php b/tests/phpunit/tests/option/getOptions.php new file mode 100644 index 0000000000000..7435dce1882d1 --- /dev/null +++ b/tests/phpunit/tests/option/getOptions.php @@ -0,0 +1,91 @@ +assertFalse( wp_cache_get( $option, 'options' ), "$option was not deleted from the cache." ); + } + + // Call the get_options function to retrieve the options. + $options = get_options( array( 'option1', 'option2' ) ); + + // Check that options are now in the cache. + foreach ( $options_to_prime as $option ) { + $this->assertSame( wp_cache_get( $option, 'options' ), get_option( $option ), "$option was not primed." ); + } + + // Check that the retrieved options are correct. + $this->assertSame( get_option( 'option1' ), $options['option1'], 'Retrieved option1 does not match expected value.' ); + $this->assertSame( get_option( 'option2' ), $options['option2'], 'Retrieved option2 does not match expected value.' ); + } + + /** + * Tests get_options() with an empty input array. + * + * @ticket 58962 + */ + public function test_get_options_with_empty_array() { + // Call the get_options function with an empty array. + $options = get_options( array() ); + + // Make sure the result is an empty array. + $this->assertIsArray( $options, 'An array should have been returned.' ); + $this->assertEmpty( $options, 'No options should have been returned.' ); + } + + /** + * Tests get_options() with options that include some nonexistent options. + */ + public function test_get_options_with_nonexistent_options() { + // Create some options to prime. + $options_to_prime = array( + 'option1', + ); + + // Make sure options are not in cache or database initially. + $this->assertFalse( wp_cache_get( 'option1', 'options' ), 'option1 was not deleted from the cache.' ); + $this->assertFalse( wp_cache_get( 'nonexistent_option', 'options' ), 'nonexistent_option was not deleted from the cache.' ); + + // Call the get_options function with an array that includes a nonexistent option. + $options = get_options( array( 'option1', 'nonexistent_option' ) ); + + // Check that the retrieved options are correct. + $this->assertSame( get_option( 'option1' ), $options['option1'], 'Retrieved option1 does not match expected value.' ); + + // Check that options are present in the notoptions cache. + $new_notoptions = wp_cache_get( 'notoptions', 'options' ); + foreach ( $options_to_prime as $option ) { + $this->assertTrue( isset( $new_notoptions[ $option ] ), "$option was not added to the notoptions cache." ); + } + + // Check that the nonexistent option is in the result array. + $this->assertArrayHasKey( 'nonexistent_option', $options, 'Result array should not contain nonexistent_option.' ); + + $this->assertFalse( $options['nonexistent_option'], 'nonexistent_option is present in option.' ); + } +} diff --git a/tests/phpunit/tests/option/primeOptions.php b/tests/phpunit/tests/option/primeOptions.php new file mode 100644 index 0000000000000..6798d33f04d1d --- /dev/null +++ b/tests/phpunit/tests/option/primeOptions.php @@ -0,0 +1,130 @@ +assertFalse( wp_cache_get( $option, 'options' ), "$option was not deleted from the cache." ); + } + + // Call the prime_options function to prime the options. + prime_options( $options_to_prime ); + + // Store the initial database query count. + $initial_query_count = get_num_queries(); + + // Check that options are only in the 'options' cache group. + foreach ( $options_to_prime as $option ) { + $this->assertSame( + wp_cache_get( $option, 'options' ), + get_option( $option ), + "$option was not primed to the 'options' cache group." + ); + + $this->assertFalse( + wp_cache_get( $option, 'notoptions' ), + get_option( $option ), + "$option was primed to the 'notoptions' cache group." + ); + } + + // Ensure no additional database queries were made. + $this->assertSame( + $initial_query_count, + get_num_queries(), + 'Additional database queries were made.' + ); + } + + /** + * Tests prime_options() with options that do not exist in the database. + * + * @ticket 58962 + */ + public function test_prime_options_with_nonexistent_options() { + // Create some options to prime. + $options_to_prime = array( + 'option1', + 'option2', + ); + + /* + * Set values for the options, + * clear the cache for the options, + * check options are not in cache initially. + */ + foreach ( $options_to_prime as $option ) { + $this->assertFalse( wp_cache_get( $option, 'options' ), "$option was not deleted from the cache." ); + } + + // Call the prime_options function to prime the options. + prime_options( $options_to_prime ); + + // Check that options are not in the cache or database. + foreach ( $options_to_prime as $option ) { + $this->assertFalse( wp_cache_get( $option, 'options' ), "$option was not deleted from the cache." ); + } + + // Check that options are present in the notoptions cache. + $new_notoptions = wp_cache_get( 'notoptions', 'options' ); + $this->assertIsArray( $new_notoptions, 'The notoptions cache should be an array.' ); + foreach ( $options_to_prime as $option ) { + $this->assertArrayHasKey( $option, $new_notoptions, "$option was not added to the notoptions cache." ); + } + } + + /** + * Tests prime_options() with an empty array. + * + * @ticket 58962 + */ + public function test_prime_options_with_empty_array() { + $alloptions = wp_load_alloptions(); + $notoptions = wp_cache_get( 'notoptions', 'options' ); + + prime_options( array() ); + + $this->assertSame( $alloptions, wp_cache_get( 'alloptions', 'options' ), 'The alloptions cache was modified.' ); + $this->assertSame( $notoptions, wp_cache_get( 'notoptions', 'options' ), 'The notoptions cache was modified.' ); + } + + /** + * Tests that prime_options handles an empty "notoptions" cache. + * + * @ticket 58962 + */ + public function test_prime_options_handles_empty_notoptions_cache() { + wp_cache_delete( 'notoptions', 'options' ); + + prime_options( array( 'nonexistent_option' ) ); + + $notoptions = wp_cache_get( 'notoptions', 'options' ); + $this->assertIsArray( $notoptions, 'The notoptions cache should be an array.' ); + $this->assertArrayHasKey( 'nonexistent_option', $notoptions, 'nonexistent_option was not added to notoptions.' ); + } +} diff --git a/tests/phpunit/tests/option/primeOptionsByGroup.php b/tests/phpunit/tests/option/primeOptionsByGroup.php new file mode 100644 index 0000000000000..9d6819664c1bc --- /dev/null +++ b/tests/phpunit/tests/option/primeOptionsByGroup.php @@ -0,0 +1,75 @@ + array( + 'option1', + 'option2', + ), + 'group2' => array( + 'option3', + ), + ); + + $options_to_prime = array( + 'option1', + 'option2', + 'option3', + ); + + /* + * Set values for the options, + * clear the cache for the options, + * check options are not in cache initially. + */ + foreach ( $options_to_prime as $option ) { + update_option( $option, "value_$option", false ); + wp_cache_delete( $option, 'options' ); + $this->assertFalse( wp_cache_get( $option, 'options' ), "$option was not deleted from the cache." ); + } + + // Call the prime_options_by_group function to prime the options. + prime_options_by_group( 'group1' ); + + // Check that options are now in the cache. + $this->assertSame( get_option( 'option1' ), wp_cache_get( 'option1', 'options' ), 'option1 was not primed.' ); + $this->assertSame( get_option( 'option2' ), wp_cache_get( 'option2', 'options' ), 'option2 was not primed.' ); + + // Make sure option3 is still not in cache. + $this->assertFalse( wp_cache_get( 'option3', 'options' ), 'option3 was not deleted from the cache.' ); + } + + /** + * Tests prime_options_by_group() with a nonexistent option group. + * + * @ticket 58962 + */ + public function test_prime_options_by_group_with_nonexistent_group() { + // Make sure options are not in cache or database initially. + $this->assertFalse( wp_cache_get( 'option1', 'options' ), 'option1 was not deleted from the cache.' ); + $this->assertFalse( wp_cache_get( 'option2', 'options' ), 'option2 was not deleted from the cache.' ); + + // Call the prime_options_by_group function with a nonexistent group. + prime_options_by_group( 'nonexistent_group' ); + + // Check that options are still not in the cache or database. + $this->assertFalse( wp_cache_get( 'option1', 'options' ), 'option1 was not deleted from the cache.' ); + $this->assertFalse( wp_cache_get( 'option2', 'options' ), 'option2 was not deleted from the cache.' ); + } +} From 2cdaf29678b2a978b6fb9a730b051237cf40d3b4 Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Thu, 24 Aug 2023 15:25:24 +0000 Subject: [PATCH 004/184] Plugins: Correctly display spaces in new plugins search results. Ensures the encoded search term in the input field is correctly decoded again. Follow-up to [53844] and [54904]. Props adhun, nithi22, huzaifaalmesbah, deepakvijayan, zunaid321, iammehedi1. Fixes #59143. git-svn-id: https://develop.svn.wordpress.org/trunk@56446 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-admin/includes/plugin-install.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-admin/includes/plugin-install.php b/src/wp-admin/includes/plugin-install.php index e2c8de32f883e..8bb1b61072d0b 100644 --- a/src/wp-admin/includes/plugin-install.php +++ b/src/wp-admin/includes/plugin-install.php @@ -316,7 +316,7 @@ function install_dashboard() { */ function install_search_form( $deprecated = true ) { $type = isset( $_REQUEST['type'] ) ? wp_unslash( $_REQUEST['type'] ) : 'term'; - $term = isset( $_REQUEST['s'] ) ? wp_unslash( $_REQUEST['s'] ) : ''; + $term = isset( $_REQUEST['s'] ) ? urldecode( wp_unslash( $_REQUEST['s'] ) ) : ''; ?>
From 40df0ec5e2976da0e1ab4fb45788964ca04fb661 Mon Sep 17 00:00:00 2001 From: Peter Wilson Date: Thu, 24 Aug 2023 15:32:09 +0000 Subject: [PATCH 005/184] Bundled Theme: Twenty Nineteen: Improve social media icon dimension attributes. Set the default width and height attributes of the SVG social icons to match the dimensions used within the CSS. This increases the attributes to 32px x 32 px. Props crunnells, mukesh27, laurelfulford, tahmidulkarim, jordanpak. Fixes #45950. git-svn-id: https://develop.svn.wordpress.org/trunk@56447 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-content/themes/twentynineteen/inc/icon-functions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-content/themes/twentynineteen/inc/icon-functions.php b/src/wp-content/themes/twentynineteen/inc/icon-functions.php index 76dba55094fb8..900bcb665f57b 100644 --- a/src/wp-content/themes/twentynineteen/inc/icon-functions.php +++ b/src/wp-content/themes/twentynineteen/inc/icon-functions.php @@ -40,7 +40,7 @@ function twentynineteen_get_social_link_svg( $uri, $size = 24 ) { function twentynineteen_nav_menu_social_icons( $item_output, $item, $depth, $args ) { // Change SVG icon inside social links menu if there is supported URL. if ( 'social' === $args->theme_location ) { - $svg = twentynineteen_get_social_link_svg( $item->url, 26 ); + $svg = twentynineteen_get_social_link_svg( $item->url, 32 ); if ( empty( $svg ) ) { $svg = twentynineteen_get_icon_svg( 'link' ); } From c10caf93d5ece0b73bd25d9ecad431ebc6891b41 Mon Sep 17 00:00:00 2001 From: Joe McGill Date: Thu, 24 Aug 2023 15:55:27 +0000 Subject: [PATCH 006/184] Rewrite Rules: Prevent stampedes when flush_rewrite_rules() is called This ensures that the `rewrite_rules` option is not emptied until the new value has been recalculated and the option is updated. The logic for refreshing the option value is moved to a new private method named `WP_Rewrite::refresh_rewrite_rules` which is used by both the `flush_rules` and `refresh_rewrite_rules` methods. Props iCaleb, joemcgill, flixos90, mukesh27. Fixes #58998. git-svn-id: https://develop.svn.wordpress.org/trunk@56448 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/class-wp-rewrite.php | 34 ++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/src/wp-includes/class-wp-rewrite.php b/src/wp-includes/class-wp-rewrite.php index 1f25b03adaf9c..150eabcbd8de1 100644 --- a/src/wp-includes/class-wp-rewrite.php +++ b/src/wp-includes/class-wp-rewrite.php @@ -1490,18 +1490,35 @@ public function rewrite_rules() { public function wp_rewrite_rules() { $this->rules = get_option( 'rewrite_rules' ); if ( empty( $this->rules ) ) { - $this->matches = 'matches'; - $this->rewrite_rules(); - if ( ! did_action( 'wp_loaded' ) ) { - add_action( 'wp_loaded', array( $this, 'flush_rules' ) ); - return $this->rules; - } - update_option( 'rewrite_rules', $this->rules ); + $this->refresh_rewrite_rules(); } return $this->rules; } + /** + * Refreshes the rewrite rules, saving the fresh value to the database. + * If the `wp_loaded` action has not occurred yet, will postpone saving to the database. + * + * @since 6.4.0 + */ + private function refresh_rewrite_rules() { + $this->rules = ''; + $this->matches = 'matches'; + + $this->rewrite_rules(); + + if ( ! did_action( 'wp_loaded' ) ) { + /* + * Is not safe to save the results right now, as the rules may be partial. + * Need to give all rules the chance to register. + */ + add_action( 'wp_loaded', array( $this, 'flush_rules' ) ); + } else { + update_option( 'rewrite_rules', $this->rules ); + } + } + /** * Retrieves mod_rewrite-formatted rewrite rules to write to .htaccess. * @@ -1864,8 +1881,7 @@ public function flush_rules( $hard = true ) { unset( $do_hard_later ); } - update_option( 'rewrite_rules', '' ); - $this->wp_rewrite_rules(); + $this->refresh_rewrite_rules(); /** * Filters whether a "hard" rewrite rule flush should be performed when requested. From b21d72b39ddcf624ecdc2142aeb9a601e7e61ca5 Mon Sep 17 00:00:00 2001 From: Joe Dolson Date: Thu, 24 Aug 2023 15:56:34 +0000 Subject: [PATCH 007/184] Menus: Fix proximity of controls to Save and Delete menus. Move the position of the Save and Delete buttons in menu editing so they are immediate neighbors, improving the proximity of related controls. Props 90lines, sabernhardt, costdev. See #56594. git-svn-id: https://develop.svn.wordpress.org/trunk@56449 602fd350-edb4-49c9-b593-d223f7449a82 --- .env | 2 +- src/wp-admin/css/list-tables.css | 6 +++--- src/wp-admin/css/nav-menus.css | 15 ++++----------- .../includes/class-wp-comments-list-table.php | 4 ++-- .../includes/class-wp-links-list-table.php | 4 ++-- src/wp-admin/includes/class-wp-list-table.php | 6 +++--- .../includes/class-wp-media-list-table.php | 4 ++-- .../includes/class-wp-ms-sites-list-table.php | 6 +++--- .../includes/class-wp-ms-themes-list-table.php | 4 ++-- .../includes/class-wp-ms-users-list-table.php | 4 ++-- .../includes/class-wp-plugins-list-table.php | 4 ++-- .../includes/class-wp-posts-list-table.php | 4 ++-- .../includes/class-wp-privacy-requests-table.php | 4 ++-- .../includes/class-wp-terms-list-table.php | 4 ++-- .../includes/class-wp-users-list-table.php | 4 ++-- src/wp-admin/nav-menus.php | 8 ++++---- src/wp-admin/update-core.php | 4 ++-- 17 files changed, 40 insertions(+), 47 deletions(-) diff --git a/.env b/.env index d393c9b324216..42ebc5b924722 100644 --- a/.env +++ b/.env @@ -12,7 +12,7 @@ LOCAL_PORT=8889 # Where to run WordPress from. Valid options are 'src' and 'build'. -LOCAL_DIR=src +LOCAL_DIR=build # The PHP version to use. Valid options are 'latest', and '{version}-fpm'. LOCAL_PHP=latest diff --git a/src/wp-admin/css/list-tables.css b/src/wp-admin/css/list-tables.css index 3f0519e561f4e..cc8c4743ee58e 100644 --- a/src/wp-admin/css/list-tables.css +++ b/src/wp-admin/css/list-tables.css @@ -570,7 +570,7 @@ th.sorted.desc:hover .sorting-indicator.asc:before { position: relative; } -.check-column .label-covers-full-cell { +.check-column label { width: 100%; height: 100%; display: block; @@ -579,12 +579,12 @@ th.sorted.desc:hover .sorting-indicator.asc:before { left: 0; } -.check-column .label-covers-full-cell + input { +.check-column input { position: relative; z-index: 1; } -.check-column .label-covers-full-cell:hover + input { +.check-column:hover input { box-shadow: 0 0 0 1px #2271b1; } diff --git a/src/wp-admin/css/nav-menus.css b/src/wp-admin/css/nav-menus.css index d85b57b5b4ea7..4fd178dbb0177 100644 --- a/src/wp-admin/css/nav-menus.css +++ b/src/wp-admin/css/nav-menus.css @@ -837,20 +837,13 @@ body.menu-max-depth-11 { min-width: 1280px !important; } /* Major/minor publishing actions (classes) */ .nav-menus-php .major-publishing-actions { - clear: both; padding: 10px 0; - line-height: 2.15384615; -} - -.nav-menus-php .major-publishing-actions .publishing-action { - text-align: right; - float: right; + display: flex; + align-items: center; } -/* Same as the Publish Meta Box #delete-action */ -.nav-menus-php .delete-action { - float: left; - line-height: 2.1; +.nav-menus-php .major-publishing-actions > * { + margin-right: 10px; } .nav-menus-php .major-publishing-actions .form-invalid { diff --git a/src/wp-admin/includes/class-wp-comments-list-table.php b/src/wp-admin/includes/class-wp-comments-list-table.php index 7d87ae9aabdc4..8b4be36c9959f 100644 --- a/src/wp-admin/includes/class-wp-comments-list-table.php +++ b/src/wp-admin/includes/class-wp-comments-list-table.php @@ -895,7 +895,8 @@ public function column_cb( $item ) { if ( $this->user_can ) { ?> -