From 6cccfb4c5474a5330426a4351f8d4b2e44a7881b Mon Sep 17 00:00:00 2001 From: Anton Vlasenko Date: Wed, 12 Jul 2023 19:28:08 +0200 Subject: [PATCH 01/30] Add Gutenberg coding standards package. --- .../gutenberg-coding-standards/.gitignore | 5 + .../.phpcs.xml.dist | 96 ++++++++ .../GuardedFunctionAndClassNamesSniff.php | 222 ++++++++++++++++++ .../GuardedFunctionAndClassNamesUnitTest.inc | 26 ++ .../GuardedFunctionAndClassNamesUnitTest.php | 36 +++ .../Gutenberg/ruleset.xml | 8 + .../gutenberg-coding-standards/README.md | 3 + .../Tests/bootstrap.php | 86 +++++++ .../gutenberg-coding-standards/composer.json | 69 ++++++ .../phpunit.xml.dist | 16 ++ 10 files changed, 567 insertions(+) create mode 100644 lib/experimental/packages/gutenberg/gutenberg-coding-standards/.gitignore create mode 100644 lib/experimental/packages/gutenberg/gutenberg-coding-standards/.phpcs.xml.dist create mode 100644 lib/experimental/packages/gutenberg/gutenberg-coding-standards/Gutenberg/Sniffs/CodeAnalysis/GuardedFunctionAndClassNamesSniff.php create mode 100644 lib/experimental/packages/gutenberg/gutenberg-coding-standards/Gutenberg/Tests/CodeAnalysis/GuardedFunctionAndClassNamesUnitTest.inc create mode 100644 lib/experimental/packages/gutenberg/gutenberg-coding-standards/Gutenberg/Tests/CodeAnalysis/GuardedFunctionAndClassNamesUnitTest.php create mode 100644 lib/experimental/packages/gutenberg/gutenberg-coding-standards/Gutenberg/ruleset.xml create mode 100644 lib/experimental/packages/gutenberg/gutenberg-coding-standards/README.md create mode 100644 lib/experimental/packages/gutenberg/gutenberg-coding-standards/Tests/bootstrap.php create mode 100644 lib/experimental/packages/gutenberg/gutenberg-coding-standards/composer.json create mode 100644 lib/experimental/packages/gutenberg/gutenberg-coding-standards/phpunit.xml.dist diff --git a/lib/experimental/packages/gutenberg/gutenberg-coding-standards/.gitignore b/lib/experimental/packages/gutenberg/gutenberg-coding-standards/.gitignore new file mode 100644 index 00000000000000..bfec4c3c303b1f --- /dev/null +++ b/lib/experimental/packages/gutenberg/gutenberg-coding-standards/.gitignore @@ -0,0 +1,5 @@ +vendor +composer.lock +phpunit.xml +phpcs.xml +.phpcs.xml diff --git a/lib/experimental/packages/gutenberg/gutenberg-coding-standards/.phpcs.xml.dist b/lib/experimental/packages/gutenberg/gutenberg-coding-standards/.phpcs.xml.dist new file mode 100644 index 00000000000000..51dca55464c3a2 --- /dev/null +++ b/lib/experimental/packages/gutenberg/gutenberg-coding-standards/.phpcs.xml.dist @@ -0,0 +1,96 @@ + + + + The Coding standard for the Gutenberg Coding Standards itself. + + + + . + + + */vendor/* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + /WordPress/Sniffs/NamingConventions/ValidHookNameSniff\.php$ + /WordPress/Sniffs/Security/(EscapeOutput|NonceVerification|ValidatedSanitizedInput)Sniff\.php$ + + + + + + + + + + + + + diff --git a/lib/experimental/packages/gutenberg/gutenberg-coding-standards/Gutenberg/Sniffs/CodeAnalysis/GuardedFunctionAndClassNamesSniff.php b/lib/experimental/packages/gutenberg/gutenberg-coding-standards/Gutenberg/Sniffs/CodeAnalysis/GuardedFunctionAndClassNamesSniff.php new file mode 100644 index 00000000000000..5fe0b7af63079c --- /dev/null +++ b/lib/experimental/packages/gutenberg/gutenberg-coding-standards/Gutenberg/Sniffs/CodeAnalysis/GuardedFunctionAndClassNamesSniff.php @@ -0,0 +1,222 @@ +onRegisterEvent(); + + return array( T_FUNCTION, T_CLASS ); + } + + /** + * Processes function and class tokens. + * + * @param File $phpcsFile The file being scanned. + * @param int $stackPtr The position of the current token + * in the stack passed in $tokens. + * + * @return void + */ + public function process( File $phpcsFile, $stackPtr ) { + $tokens = $phpcsFile->getTokens(); + $token = $tokens[ $stackPtr ]; + + if ( 'T_FUNCTION' === $token['type'] ) { + $this->processFunctionToken( $phpcsFile, $stackPtr ); + return; + } + + if ( 'T_CLASS' === $token['type'] ) { + $this->processClassToken( $phpcsFile, $stackPtr ); + } + } + + /** + * Functions should be wrapped with !function_exists() to avoid fatal errors. + * E.g.: + * if ( ! function_exists( 'wp_get_navigation' ) ) { + * function wp_get_navigation( $slug ) { ... } + * } + * + * @param File $phpcsFile The file being scanned. + * @param int $stackPointer The position of the current token + * in the stack passed in $tokens. + * + * @return void + */ + private function processFunctionToken( File $phpcsFile, $stackPointer ) { + $tokens = $phpcsFile->getTokens(); + $functionToken = $phpcsFile->findNext( T_STRING, $stackPointer ); + + $wrappingTokensToCheck = array( + T_CLASS, + T_INTERFACE, + T_TRAIT, + ); + + foreach ( $wrappingTokensToCheck as $wrappingTokenToCheck ) { + if ( false !== $phpcsFile->getCondition( $functionToken, $wrappingTokenToCheck, false ) ) { + // This sniff only processes functions, not class methods. + return; + } + } + + $name = $tokens[ $functionToken ]['content']; + foreach ( $this->functionsWhiteList as $functionRegExp ) { + if ( preg_match( $functionRegExp, $name ) ) { + // Ignore whitelisted function names. + return; + } + } + + $errorMessage = sprintf( 'The "%s()" function should be guarded against redeclaration.', $name ); + + $wrappingIfToken = $phpcsFile->getCondition( $functionToken, T_IF, false ); + if ( false === $wrappingIfToken ) { + $phpcsFile->addError( $errorMessage, $functionToken, 'FunctionNotGuardedAgainstRedeclaration' ); + + return; + } + + $content = $phpcsFile->getTokensAsString( $wrappingIfToken, $functionToken - $wrappingIfToken ); + + $regexp = sprintf( '/if\s*\(\s*!\s*function_exists\s*\(\s*(\'|")%s(\'|")/', preg_quote( $name, '/' ) ); + $result = preg_match( $regexp, $content ); + if ( 1 !== $result ) { + $phpcsFile->addError( $errorMessage, $functionToken, 'FunctionNotGuardedAgainstRedeclaration' ); + } + } + + /** + * Classes should be wrapped with !function_exists() to avoid fatal errors. + * E.g.: + * if ( class_exists( 'WP_Navigation' ) ) { + * return; + * } + * + * Alternatively: + * + * if ( ! class_exists( 'WP_Navigation' ) ) { + * class WP_Navigation { ... } + * } + * + * @param File $phpcsFile The file being scanned. + * @param int $stackPointer The position of the current token + * in the stack passed in $tokens. + * + * @return void + */ + private function processClassToken( File $phpcsFile, $stackPointer ) { + $tokens = $phpcsFile->getTokens(); + $classToken = $phpcsFile->findNext( T_STRING, $stackPointer ); + $className = $tokens[ $classToken ]['content']; + + foreach ( $this->classesWhiteList as $classnameRegExp ) { + if ( preg_match( $classnameRegExp, $className ) ) { + // Ignore whitelisted class names. + return; + } + } + + $errorMessage = sprintf( 'The "%s" class should be guarded against redeclaration.', $className ); + + $wrappingIfToken = $phpcsFile->getCondition( $classToken, T_IF, false ); + if ( false !== $wrappingIfToken ) { + $endOfWrappingIfToken = $phpcsFile->findEndOfStatement( $wrappingIfToken ); + $content = $phpcsFile->getTokensAsString( $wrappingIfToken, $endOfWrappingIfToken - $wrappingIfToken ); + $regexp = sprintf( '/if\s*\(\s*!\s*class_exists\s*\(\s*(\'|")%s(\'|")/', preg_quote( $className, '/' ) ); + $result = preg_match( $regexp, $content ); + if ( 1 === $result ) { + return; + } + } + + $previousIfToken = $phpcsFile->findPrevious( T_IF, $classToken ); + if ( false === $previousIfToken ) { + $phpcsFile->addError( $errorMessage, $classToken, 'ClassNotGuardedAgainstRedeclaration' ); + + return; + } + + $endOfPreviousIfToken = $phpcsFile->findEndOfStatement( $previousIfToken ); + $content = $phpcsFile->getTokensAsString( $previousIfToken, $endOfPreviousIfToken - $previousIfToken ); + $regexp = sprintf( '/if\s*\(\s*class_exists\s*\(\s*(\'|")%s(\'|")/', preg_quote( $className, '/' ) ); + $result = preg_match( $regexp, $content ); + + if ( 1 === $result ) { + $returnToken = $phpcsFile->findNext( T_RETURN, $previousIfToken, $endOfPreviousIfToken ); + if ( false !== $returnToken ) { + return; + } + } + + $phpcsFile->addError( $errorMessage, $classToken, 'ClassNotGuardedAgainstRedeclaration' ); + } + + /** + * The purpose of this method is to sanitize the input data + * after the properties have been set. + */ + private function onRegisterEvent() { + $this->functionsWhiteList = self::sanitize( $this->functionsWhiteList ); + $this->classesWhiteList = self::sanitize( $this->classesWhiteList ); + } + + /** + * Input data needs to be sanitized. + * + * @param array $values The values being sanitized. + * + * @return array + */ + private static function sanitize( $values ) { + $values = array_map( 'trim', $values ); + + return array_filter( $values ); + } +} diff --git a/lib/experimental/packages/gutenberg/gutenberg-coding-standards/Gutenberg/Tests/CodeAnalysis/GuardedFunctionAndClassNamesUnitTest.inc b/lib/experimental/packages/gutenberg/gutenberg-coding-standards/Gutenberg/Tests/CodeAnalysis/GuardedFunctionAndClassNamesUnitTest.inc new file mode 100644 index 00000000000000..5db9946d68ae31 --- /dev/null +++ b/lib/experimental/packages/gutenberg/gutenberg-coding-standards/Gutenberg/Tests/CodeAnalysis/GuardedFunctionAndClassNamesUnitTest.inc @@ -0,0 +1,26 @@ + => + */ + public function getErrorList() { + return array( + 17 => 1, + 25 => 1, + ); + } + + /** + * Returns the lines where warnings should occur. + * + * @return array => + */ + public function getWarningList() { + return array(); + } +} diff --git a/lib/experimental/packages/gutenberg/gutenberg-coding-standards/Gutenberg/ruleset.xml b/lib/experimental/packages/gutenberg/gutenberg-coding-standards/Gutenberg/ruleset.xml new file mode 100644 index 00000000000000..e899c9bed05286 --- /dev/null +++ b/lib/experimental/packages/gutenberg/gutenberg-coding-standards/Gutenberg/ruleset.xml @@ -0,0 +1,8 @@ + + + + Gutenberg Coding Standards + + + + diff --git a/lib/experimental/packages/gutenberg/gutenberg-coding-standards/README.md b/lib/experimental/packages/gutenberg/gutenberg-coding-standards/README.md new file mode 100644 index 00000000000000..51f6574fa20534 --- /dev/null +++ b/lib/experimental/packages/gutenberg/gutenberg-coding-standards/README.md @@ -0,0 +1,3 @@ +# Gutenberg Coding Standards for Gutenberg + +This project is a collection of [PHP_CodeSniffer](https://github.com/squizlabs/PHP_CodeSniffer) rules (sniffs) to validate code developed for Gutenberg. It ensures code quality and adherence to coding conventions. \ No newline at end of file diff --git a/lib/experimental/packages/gutenberg/gutenberg-coding-standards/Tests/bootstrap.php b/lib/experimental/packages/gutenberg/gutenberg-coding-standards/Tests/bootstrap.php new file mode 100644 index 00000000000000..185a94c070e067 --- /dev/null +++ b/lib/experimental/packages/gutenberg/gutenberg-coding-standards/Tests/bootstrap.php @@ -0,0 +1,86 @@ + true, +); + +$allStandards = PHP_CodeSniffer\Util\Standards::getInstalledStandards(); +$allStandards[] = 'Generic'; + +$standardsToIgnore = array(); +foreach ( $allStandards as $standard ) { + if ( isset( $gbcsStandards[ $standard ] ) === true ) { + continue; + } + + $standardsToIgnore[] = $standard; +} + +$standardsToIgnoreString = implode( ',', $standardsToIgnore ); + +// phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.runtime_configuration_putenv -- This is not production, but test code. +putenv( "PHPCS_IGNORE_TESTS={$standardsToIgnoreString}" ); + +// Clean up. +unset( $ds, $phpcsDir, $composerPHPCSPath, $allStandards, $standardsToIgnore, $standard, $standardsToIgnoreString ); \ No newline at end of file diff --git a/lib/experimental/packages/gutenberg/gutenberg-coding-standards/composer.json b/lib/experimental/packages/gutenberg/gutenberg-coding-standards/composer.json new file mode 100644 index 00000000000000..b300de12b03162 --- /dev/null +++ b/lib/experimental/packages/gutenberg/gutenberg-coding-standards/composer.json @@ -0,0 +1,69 @@ +{ + "name": "gutenberg-coding-standards/gbcs", + "type": "phpcodesniffer-standard", + "description": "PHP_CodeSniffer rules (sniffs) to enforce Gutenberg coding conventions", + "keywords": [ + "phpcs", + "standards", + "static analysis", + "Gutenberg" + ], + "license": "MIT", + "authors": [ + { + "name": "Contributors", + "homepage": "https://github.com/anton-vlasenko/Gutenberg-Coding-Standards/graphs/contributors" + } + ], + "require": { + "php": ">=5.4", + "ext-filter": "*", + "squizlabs/php_codesniffer": "^3.7.2" + }, + "require-dev": { + "phpcompatibility/php-compatibility": "^9.0", + "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0", + "php-parallel-lint/php-parallel-lint": "^1.3.2", + "php-parallel-lint/php-console-highlighter": "^1.0.0", + "dealerdirect/phpcodesniffer-composer-installer": "*" + }, + "suggest": { + "ext-mbstring": "For improved results" + }, + "config": { + "allow-plugins": { + "dealerdirect/phpcodesniffer-composer-installer": true + } + }, + "scripts": { + "lint": [ + "@php ./vendor/php-parallel-lint/php-parallel-lint/parallel-lint . -e php --show-deprecated --exclude vendor --exclude .git" + ], + "check-cs": [ + "@php ./vendor/squizlabs/php_codesniffer/bin/phpcs" + ], + "fix-cs": [ + "@php ./vendor/squizlabs/php_codesniffer/bin/phpcbf" + ], + "run-tests": [ + "@php ./vendor/phpunit/phpunit/phpunit -c phpunit.xml.dist --filter Gutenberg ./vendor/squizlabs/php_codesniffer/tests/AllTests.php" + ], + "check-all": [ + "@lint", + "@check-cs", + "@run-tests" + ] + }, + "scripts-descriptions": { + "lint": "Lint PHP files against parse errors.", + "check-cs": "Run the PHPCS script against the entire codebase.", + "fix-cs": "Run the PHPCBF script to fix all the autofixable violations on the codebase.", + "run-tests": "Run all the unit tests for the Gutenberg Coding Standards sniffs.", + "check-all": "Run all checks (lint, phpcs) and tests." + }, + "support": { + "issues": "https://github.com/anton-vlasenko/Gutenberg-Coding-Standards/issues", + "wiki": "https://github.com/anton-vlasenko/Gutenberg-Coding-Standards/wiki", + "source": "https://github.com/anton-vlasenko/Gutenberg-Coding-Standards" + } +} diff --git a/lib/experimental/packages/gutenberg/gutenberg-coding-standards/phpunit.xml.dist b/lib/experimental/packages/gutenberg/gutenberg-coding-standards/phpunit.xml.dist new file mode 100644 index 00000000000000..0e9d9cb5b75071 --- /dev/null +++ b/lib/experimental/packages/gutenberg/gutenberg-coding-standards/phpunit.xml.dist @@ -0,0 +1,16 @@ + + + + + + ./Gutenberg/Tests/ + + + + From 81b0852f37d76edb704960d5bc943e347a57b85e Mon Sep 17 00:00:00 2001 From: Anton Vlasenko Date: Wed, 12 Jul 2023 19:53:06 +0200 Subject: [PATCH 02/30] Fix contributors. --- .../gutenberg/gutenberg-coding-standards/composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/experimental/packages/gutenberg/gutenberg-coding-standards/composer.json b/lib/experimental/packages/gutenberg/gutenberg-coding-standards/composer.json index b300de12b03162..d5419d2facb61e 100644 --- a/lib/experimental/packages/gutenberg/gutenberg-coding-standards/composer.json +++ b/lib/experimental/packages/gutenberg/gutenberg-coding-standards/composer.json @@ -1,5 +1,5 @@ { - "name": "gutenberg-coding-standards/gbcs", + "name": "gutenberg/gutenberg-coding-standards", "type": "phpcodesniffer-standard", "description": "PHP_CodeSniffer rules (sniffs) to enforce Gutenberg coding conventions", "keywords": [ @@ -12,7 +12,7 @@ "authors": [ { "name": "Contributors", - "homepage": "https://github.com/anton-vlasenko/Gutenberg-Coding-Standards/graphs/contributors" + "homepage": "https://github.com/WordPress/gutenberg/graphs/contributors" } ], "require": { From 6ebaf07a920283b87380d20960959e39b706513a Mon Sep 17 00:00:00 2001 From: Anton Vlasenko Date: Wed, 12 Jul 2023 21:50:13 +0200 Subject: [PATCH 03/30] Fix package names. --- .../CodeAnalysis/GuardedFunctionAndClassNamesSniff.php | 6 +++--- .../CodeAnalysis/GuardedFunctionAndClassNamesUnitTest.php | 2 +- .../gutenberg-coding-standards/Tests/bootstrap.php | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/experimental/packages/gutenberg/gutenberg-coding-standards/Gutenberg/Sniffs/CodeAnalysis/GuardedFunctionAndClassNamesSniff.php b/lib/experimental/packages/gutenberg/gutenberg-coding-standards/Gutenberg/Sniffs/CodeAnalysis/GuardedFunctionAndClassNamesSniff.php index 5fe0b7af63079c..75560463e26f6f 100644 --- a/lib/experimental/packages/gutenberg/gutenberg-coding-standards/Gutenberg/Sniffs/CodeAnalysis/GuardedFunctionAndClassNamesSniff.php +++ b/lib/experimental/packages/gutenberg/gutenberg-coding-standards/Gutenberg/Sniffs/CodeAnalysis/GuardedFunctionAndClassNamesSniff.php @@ -2,8 +2,8 @@ /** * Gutenberg Coding Standards. * - * @package gutenberg-coding-standards/gbcs - * @link https://github.com/anton-vlasenko/Gutenberg-Coding-Standards + * @package gutenberg/gutenberg-coding-standards + * @link https://github.com/WordPress/gutenberg * @license https://opensource.org/licenses/MIT MIT */ @@ -21,7 +21,7 @@ * * @link https://github.com/WordPress/gutenberg/blob/trunk/lib/README.md#wrap-functions-and-classes-with--function_exists-and--class_exists * - * @package gutenberg-coding-standards/gbcs + * @package gutenberg/gutenberg-coding-standards * * @since 1.0.0 */ diff --git a/lib/experimental/packages/gutenberg/gutenberg-coding-standards/Gutenberg/Tests/CodeAnalysis/GuardedFunctionAndClassNamesUnitTest.php b/lib/experimental/packages/gutenberg/gutenberg-coding-standards/Gutenberg/Tests/CodeAnalysis/GuardedFunctionAndClassNamesUnitTest.php index 1551895fdcb492..c7c2fc29816592 100644 --- a/lib/experimental/packages/gutenberg/gutenberg-coding-standards/Gutenberg/Tests/CodeAnalysis/GuardedFunctionAndClassNamesUnitTest.php +++ b/lib/experimental/packages/gutenberg/gutenberg-coding-standards/Gutenberg/Tests/CodeAnalysis/GuardedFunctionAndClassNamesUnitTest.php @@ -3,7 +3,7 @@ * Unit test class for Gutenberg Coding Standard. * * @package gutenberg-coding-standards/gbc - * @link https://github.com/anton-vlasenko/Gutenberg-Coding-Standards + * @link https://github.com/WordPress/gutenberg * @license https://opensource.org/licenses/MIT MIT */ diff --git a/lib/experimental/packages/gutenberg/gutenberg-coding-standards/Tests/bootstrap.php b/lib/experimental/packages/gutenberg/gutenberg-coding-standards/Tests/bootstrap.php index 185a94c070e067..f28528bc1b9726 100644 --- a/lib/experimental/packages/gutenberg/gutenberg-coding-standards/Tests/bootstrap.php +++ b/lib/experimental/packages/gutenberg/gutenberg-coding-standards/Tests/bootstrap.php @@ -9,8 +9,8 @@ * - Load the Composer autoload file. * - Automatically limit the testing to the WordPressCS tests. * - * @package gutenberg-coding-standards/gbcs - * @link https://github.com/anton-vlasenko/Gutenberg-Coding-Standards + * @package gutenberg/gutenberg-coding-standards + * @link https://github.com/WordPress/gutenberg * @license https://opensource.org/licenses/MIT MIT */ @@ -83,4 +83,4 @@ putenv( "PHPCS_IGNORE_TESTS={$standardsToIgnoreString}" ); // Clean up. -unset( $ds, $phpcsDir, $composerPHPCSPath, $allStandards, $standardsToIgnore, $standard, $standardsToIgnoreString ); \ No newline at end of file +unset( $ds, $phpcsDir, $composerPHPCSPath, $allStandards, $standardsToIgnore, $standard, $standardsToIgnoreString ); From 887fab88c11335c9cdcea0cbde2f1b0c60f416fe Mon Sep 17 00:00:00 2001 From: Anton Vlasenko Date: Wed, 12 Jul 2023 21:52:33 +0200 Subject: [PATCH 04/30] Remove unneccessary section. --- .../gutenberg/gutenberg-coding-standards/composer.json | 5 ----- 1 file changed, 5 deletions(-) diff --git a/lib/experimental/packages/gutenberg/gutenberg-coding-standards/composer.json b/lib/experimental/packages/gutenberg/gutenberg-coding-standards/composer.json index d5419d2facb61e..243198b94bb06f 100644 --- a/lib/experimental/packages/gutenberg/gutenberg-coding-standards/composer.json +++ b/lib/experimental/packages/gutenberg/gutenberg-coding-standards/composer.json @@ -60,10 +60,5 @@ "fix-cs": "Run the PHPCBF script to fix all the autofixable violations on the codebase.", "run-tests": "Run all the unit tests for the Gutenberg Coding Standards sniffs.", "check-all": "Run all checks (lint, phpcs) and tests." - }, - "support": { - "issues": "https://github.com/anton-vlasenko/Gutenberg-Coding-Standards/issues", - "wiki": "https://github.com/anton-vlasenko/Gutenberg-Coding-Standards/wiki", - "source": "https://github.com/anton-vlasenko/Gutenberg-Coding-Standards" } } From d91104d0730199aabc8d603892ecd1ec3b4816c2 Mon Sep 17 00:00:00 2001 From: Anton Vlasenko Date: Wed, 12 Jul 2023 21:52:56 +0200 Subject: [PATCH 05/30] Add Gutenberg coding standards package as a composer dependency. --- composer.json | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 3f16ba495a94ca..ab8a4cf55b49c4 100644 --- a/composer.json +++ b/composer.json @@ -32,8 +32,18 @@ "wp-coding-standards/wpcs": "^2.2", "sirbrillig/phpcs-variable-analysis": "^2.8", "spatie/phpunit-watcher": "^1.23", - "yoast/phpunit-polyfills": "^1.0" + "yoast/phpunit-polyfills": "^1.0", + "gutenberg/gutenberg-coding-standards": "@dev" }, + "repositories": [ + { + "type": "path", + "url": "./lib/experimental/packages/gutenberg/gutenberg-coding-standards", + "options": { + "symlink": false + } + } + ], "require": { "composer/installers": "~1.0" }, From 3e7fa247a0632cf6c29a6940fb1c5b97c9e814db Mon Sep 17 00:00:00 2001 From: Anton Vlasenko Date: Wed, 12 Jul 2023 21:57:03 +0200 Subject: [PATCH 06/30] Add myself as a code owner of the coding standards package. --- .github/CODEOWNERS | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 4008efa1b4d4e1..7cd07d819ea57b 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -136,6 +136,7 @@ /lib/experimental/rest-api.php @timothybjacobs /lib/experimental/class-wp-rest-* @timothybjacobs /lib/experimental/class-wp-rest-block-editor-settings-controller.php @timothybjacobs @spacedmonkey @geriux +/lib/experimental/packages/gutenberg/gutenberg-coding-standards @anton-vlasenko # Native /packages/components/src/mobile/global-styles-context @geriux From 37a7273b8910f3e054f4a33070d39d1f9b3345f2 Mon Sep 17 00:00:00 2001 From: Anton Vlasenko Date: Mon, 17 Jul 2023 13:37:30 +0200 Subject: [PATCH 07/30] Exclude gutenberg coding standards from PHPCS checks. --- phpcs.xml.dist | 1 + 1 file changed, 1 insertion(+) diff --git a/phpcs.xml.dist b/phpcs.xml.dist index 6f40a38522ad6c..7e47ff7a4f7de5 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -50,6 +50,7 @@ ./vendor/* + ./lib/experimental/packages/gutenberg/gutenberg-coding-standards/* From 4e12b717e34b906e20233b11e3aa7fcc092cfa16 Mon Sep 17 00:00:00 2001 From: Anton Vlasenko Date: Mon, 17 Jul 2023 14:18:42 +0200 Subject: [PATCH 08/30] Add the rule to phpcs.xml.dist. --- phpcs.xml.dist | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/phpcs.xml.dist b/phpcs.xml.dist index 7e47ff7a4f7de5..b6cf32675f1b18 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -110,4 +110,20 @@ /phpunit/* + + + + ./phpunit/* + ./packages/* + ./bin/generate-gutenberg-php + + + + + + + + + + From e2f7e906a65d1a751097a8a46b7934ce9c32cd8b Mon Sep 17 00:00:00 2001 From: Anton Vlasenko Date: Mon, 17 Jul 2023 14:39:04 +0200 Subject: [PATCH 09/30] Guard functions and classes. --- ...-rest-block-editor-settings-controller.php | 4 ++ lib/experimental/kses.php | 41 ++++++++++--------- 2 files changed, 26 insertions(+), 19 deletions(-) diff --git a/lib/experimental/class-wp-rest-block-editor-settings-controller.php b/lib/experimental/class-wp-rest-block-editor-settings-controller.php index 52dd328fc7f2db..2da5124abebdd7 100644 --- a/lib/experimental/class-wp-rest-block-editor-settings-controller.php +++ b/lib/experimental/class-wp-rest-block-editor-settings-controller.php @@ -6,6 +6,10 @@ * @subpackage REST_API */ +if ( ! class_exists( 'WP_REST_Block_Editor_Settings_Controller' ) ) { + return; +} + /** * Core class used to retrieve the block editor settings via the REST API. * diff --git a/lib/experimental/kses.php b/lib/experimental/kses.php index 115fa3a7d2284c..f625a889d9c77f 100644 --- a/lib/experimental/kses.php +++ b/lib/experimental/kses.php @@ -66,24 +66,27 @@ function gutenberg_override_core_kses_init_filters() { add_action( 'init', 'gutenberg_override_core_kses_init_filters', 20 ); add_action( 'set_current_user', 'gutenberg_override_core_kses_init_filters' ); -/** - * See https://github.com/WordPress/wordpress-develop/pull/4108 - * - * Mark CSS safe if it contains a "filter: url('#wp-duotone-...')" rule. - * - * This function should not be backported to core. - * - * @param bool $allow_css Whether the CSS is allowed. - * @param string $css_test_string The CSS to test. - */ -function allow_filter_in_styles( $allow_css, $css_test_string ) { - if ( preg_match( - "/^filter:\s*url\((['\"]?)#wp-duotone-[-a-zA-Z0-9]+\\1\)(\s+!important)?$/", - $css_test_string - ) ) { - return true; +if ( ! function_exists( 'wp_get_block_css_selector' ) ) { + /** + * See https://github.com/WordPress/wordpress-develop/pull/4108 + * + * Mark CSS safe if it contains a "filter: url('#wp-duotone-...')" rule. + * + * This function should not be backported to core. + * + * @param bool $allow_css Whether the CSS is allowed. + * @param string $css_test_string The CSS to test. + */ + function allow_filter_in_styles( $allow_css, $css_test_string ) { + if ( preg_match( + "/^filter:\s*url\((['\"]?)#wp-duotone-[-a-zA-Z0-9]+\\1\)(\s+!important)?$/", + $css_test_string + ) ) { + return true; + } + + return $allow_css; } - return $allow_css; -} -add_filter( 'safecss_filter_attr_allow_css', 'allow_filter_in_styles', 10, 2 ); + add_filter( 'safecss_filter_attr_allow_css', 'allow_filter_in_styles', 10, 2 ); +} From 1cc8f775b56eb7ccc0e89360a1904790cc9b8cf2 Mon Sep 17 00:00:00 2001 From: Anton Vlasenko Date: Mon, 17 Jul 2023 14:40:23 +0200 Subject: [PATCH 10/30] Guard functions and classes. --- .../class-wp-rest-block-editor-settings-controller.php | 2 +- lib/experimental/kses.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/experimental/class-wp-rest-block-editor-settings-controller.php b/lib/experimental/class-wp-rest-block-editor-settings-controller.php index 2da5124abebdd7..510ae573e3de8e 100644 --- a/lib/experimental/class-wp-rest-block-editor-settings-controller.php +++ b/lib/experimental/class-wp-rest-block-editor-settings-controller.php @@ -6,7 +6,7 @@ * @subpackage REST_API */ -if ( ! class_exists( 'WP_REST_Block_Editor_Settings_Controller' ) ) { +if ( class_exists( 'WP_REST_Block_Editor_Settings_Controller' ) ) { return; } diff --git a/lib/experimental/kses.php b/lib/experimental/kses.php index f625a889d9c77f..b68b7f85b8b849 100644 --- a/lib/experimental/kses.php +++ b/lib/experimental/kses.php @@ -66,7 +66,7 @@ function gutenberg_override_core_kses_init_filters() { add_action( 'init', 'gutenberg_override_core_kses_init_filters', 20 ); add_action( 'set_current_user', 'gutenberg_override_core_kses_init_filters' ); -if ( ! function_exists( 'wp_get_block_css_selector' ) ) { +if ( ! function_exists( 'allow_filter_in_styles' ) ) { /** * See https://github.com/WordPress/wordpress-develop/pull/4108 * From 7db4995ccaa92da9f3b3b31ac833c781513890b8 Mon Sep 17 00:00:00 2001 From: Anton Vlasenko Date: Mon, 17 Jul 2023 14:41:48 +0200 Subject: [PATCH 11/30] Fix CS. --- lib/experimental/kses.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/experimental/kses.php b/lib/experimental/kses.php index b68b7f85b8b849..9bcdf022d84835 100644 --- a/lib/experimental/kses.php +++ b/lib/experimental/kses.php @@ -74,7 +74,7 @@ function gutenberg_override_core_kses_init_filters() { * * This function should not be backported to core. * - * @param bool $allow_css Whether the CSS is allowed. + * @param bool $allow_css Whether the CSS is allowed. * @param string $css_test_string The CSS to test. */ function allow_filter_in_styles( $allow_css, $css_test_string ) { From 835399ba0347e7f6673850a752459752593085cf Mon Sep 17 00:00:00 2001 From: Anton Vlasenko Date: Mon, 17 Jul 2023 15:06:10 +0200 Subject: [PATCH 12/30] Guard functions and classes. --- lib/experiments-page.php | 42 +++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/lib/experiments-page.php b/lib/experiments-page.php index de1d3dbce71a14..ea298784aec0c9 100644 --- a/lib/experiments-page.php +++ b/lib/experiments-page.php @@ -5,26 +5,28 @@ * @package gutenberg */ -/** - * The main entry point for the Gutenberg experiments page. - * - * @since 6.3.0 - */ -function the_gutenberg_experiments() { - ?> -
-

- -
- - - -
-
- +
+

+ +
+ + + +
+
+ Date: Mon, 17 Jul 2023 15:07:20 +0200 Subject: [PATCH 13/30] Guard functions and classes. --- lib/experimental/class--wp-editors.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/experimental/class--wp-editors.php b/lib/experimental/class--wp-editors.php index bc49ea80a99421..41062db75c0700 100644 --- a/lib/experimental/class--wp-editors.php +++ b/lib/experimental/class--wp-editors.php @@ -8,6 +8,10 @@ // phpcs:disable PEAR.NamingConventions.ValidClassName.StartWithCapital +if ( class_exists( '_WP_Editors' ) ) { + return; +} + /** * Placeholder class. * Used to disable loading of TinyMCE assets. From a44857106e5735d6b042853efb157431c9ac5a4f Mon Sep 17 00:00:00 2001 From: Anton Vlasenko Date: Mon, 17 Jul 2023 15:09:47 +0200 Subject: [PATCH 14/30] Guard functions and classes. --- lib/experimental/rest-api.php | 37 +++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/lib/experimental/rest-api.php b/lib/experimental/rest-api.php index 2fc7a7af576f82..00090e3c02d88f 100644 --- a/lib/experimental/rest-api.php +++ b/lib/experimental/rest-api.php @@ -102,23 +102,26 @@ function gutenberg_auto_draft_get_sample_permalink( $permalink, $id, $title, $na } add_filter( 'get_sample_permalink', 'gutenberg_auto_draft_get_sample_permalink', 10, 5 ); -/** - * Hook in to the template and template part post types and decorate - * the rest endpoint with the revision count. - * - * When merging to core, this can be removed once Gutenberg_REST_Template_Revision_Count is - * merged with WP_REST_Template_Controller. - * - * @param array $args Current registered post type args. - * @param string $post_type Name of post type. - * - * @return array - */ -function wp_api_template_revision_args( $args, $post_type ) { - if ( 'wp_template' === $post_type || 'wp_template_part' === $post_type ) { - $args['rest_controller_class'] = 'Gutenberg_REST_Template_Revision_Count'; +if ( ! function_exists( 'wp_api_template_revision_args' ) ) { + /** + * Hook in to the template and template part post types and decorate + * the rest endpoint with the revision count. + * + * When merging to core, this can be removed once Gutenberg_REST_Template_Revision_Count is + * merged with WP_REST_Template_Controller. + * + * @param array $args Current registered post type args. + * @param string $post_type Name of post type. + * + * @return array + */ + function wp_api_template_revision_args( $args, $post_type ) { + if ( 'wp_template' === $post_type || 'wp_template_part' === $post_type ) { + $args['rest_controller_class'] = 'Gutenberg_REST_Template_Revision_Count'; + } + + return $args; } - return $args; + add_filter( 'register_post_type_args', 'wp_api_template_revision_args', 10, 2 ); } -add_filter( 'register_post_type_args', 'wp_api_template_revision_args', 10, 2 ); From 4c44f1d3f9a0252d683d93fca2f8988038ded6df Mon Sep 17 00:00:00 2001 From: Anton Vlasenko Date: Mon, 17 Jul 2023 15:10:51 +0200 Subject: [PATCH 15/30] Guard functions and classes. --- lib/experimental/class-wp-rest-customizer-nonces.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/experimental/class-wp-rest-customizer-nonces.php b/lib/experimental/class-wp-rest-customizer-nonces.php index 4fc35209ae99de..15c587295557d8 100644 --- a/lib/experimental/class-wp-rest-customizer-nonces.php +++ b/lib/experimental/class-wp-rest-customizer-nonces.php @@ -5,6 +5,10 @@ * @package gutenberg */ +if ( class_exists( 'WP_Rest_Customizer_Nonces' ) ) { + return; +} + /** * Class that returns the customizer "save" nonce that's required for the * batch save operation using the customizer API endpoint. From 3b3e1475145cb7a84c55be298982125e4044f5fa Mon Sep 17 00:00:00 2001 From: Anton Vlasenko Date: Mon, 17 Jul 2023 15:30:44 +0200 Subject: [PATCH 16/30] Guard functions and classes. --- lib/compat/wordpress-6.3/rest-api.php | 39 ++++++++++++++------------- 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/lib/compat/wordpress-6.3/rest-api.php b/lib/compat/wordpress-6.3/rest-api.php index 90898c0b71e246..238869b1cd846e 100644 --- a/lib/compat/wordpress-6.3/rest-api.php +++ b/lib/compat/wordpress-6.3/rest-api.php @@ -24,12 +24,12 @@ function gutenberg_update_templates_template_parts_rest_controller( $args, $post_type ) { if ( in_array( $post_type, array( 'wp_template', 'wp_template_part' ), true ) ) { $template_edit_link = 'site-editor.php?' . build_query( - array( - 'postType' => $post_type, - 'postId' => '%s', - 'canvas' => 'edit', - ) - ); + array( + 'postType' => $post_type, + 'postId' => '%s', + 'canvas' => 'edit', + ) + ); $args['_edit_link'] = $template_edit_link; } @@ -39,12 +39,12 @@ function gutenberg_update_templates_template_parts_rest_controller( $args, $post if ( 'wp_navigation' === $post_type ) { $navigation_edit_link = 'site-editor.php?' . build_query( - array( - 'postId' => '%s', - 'postType' => 'wp_navigation', - 'canvas' => 'edit', - ) - ); + array( + 'postId' => '%s', + 'postType' => 'wp_navigation', + 'canvas' => 'edit', + ) + ); $args['_edit_link'] = $navigation_edit_link; } @@ -52,12 +52,13 @@ function gutenberg_update_templates_template_parts_rest_controller( $args, $post } add_filter( 'register_post_type_args', 'gutenberg_update_templates_template_parts_rest_controller', 10, 2 ); -/** - * Add the `modified` value to the `wp_template` schema. - * - * @since 6.3.0 Added 'modified' property and response value. - */ -function add_modified_wp_template_schema() { +if ( ! function_exists( 'add_modified_wp_template_schema' ) ) { + /** + * Add the `modified` value to the `wp_template` schema. + * + * @since 6.3.0 Added 'modified' property and response value. + */ + function add_modified_wp_template_schema() { register_rest_field( array( 'wp_template', 'wp_template_part' ), 'modified', @@ -76,10 +77,12 @@ function add_modified_wp_template_schema() { return mysql_to_rfc3339( $post->post_modified ); } } + return null; }, ) ); + } } add_filter( 'rest_api_init', 'add_modified_wp_template_schema' ); From eee04734132432afaef266f23a028e3000bf38f3 Mon Sep 17 00:00:00 2001 From: Anton Vlasenko Date: Mon, 17 Jul 2023 15:31:27 +0200 Subject: [PATCH 17/30] Guard functions and classes. --- .../interactivity-api/class-wp-directive-context.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/experimental/interactivity-api/class-wp-directive-context.php b/lib/experimental/interactivity-api/class-wp-directive-context.php index 7186922d137a89..6e28db83509f52 100644 --- a/lib/experimental/interactivity-api/class-wp-directive-context.php +++ b/lib/experimental/interactivity-api/class-wp-directive-context.php @@ -6,6 +6,10 @@ * @subpackage Interactivity API */ +if ( class_exists( 'WP_Directive_Context' ) ) { + return; +} + /** * This is a data structure to hold the current context. * From f9c87465c67bd7a849f291546819460b88497e39 Mon Sep 17 00:00:00 2001 From: Anton Vlasenko Date: Mon, 17 Jul 2023 15:41:19 +0200 Subject: [PATCH 18/30] Guard functions and classes. --- .../class-wp-directive-processor.php | 4 +++ .../class-wp-interactivity-store.php | 4 +++ lib/experimental/interactivity-api/store.php | 25 +++++++++++-------- 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/lib/experimental/interactivity-api/class-wp-directive-processor.php b/lib/experimental/interactivity-api/class-wp-directive-processor.php index 69c72a222fdc71..e57000b3663ce4 100644 --- a/lib/experimental/interactivity-api/class-wp-directive-processor.php +++ b/lib/experimental/interactivity-api/class-wp-directive-processor.php @@ -6,6 +6,10 @@ * @subpackage Interactivity API */ +if ( class_exists( 'WP_Directive_Processor' ) ) { + return; +} + /** * This processor is built on top of the HTML Tag Processor and augments its * capabilities to process the Interactivity API directives. diff --git a/lib/experimental/interactivity-api/class-wp-interactivity-store.php b/lib/experimental/interactivity-api/class-wp-interactivity-store.php index fe96af4786d3bf..8b43dbb6d9e248 100644 --- a/lib/experimental/interactivity-api/class-wp-interactivity-store.php +++ b/lib/experimental/interactivity-api/class-wp-interactivity-store.php @@ -9,6 +9,10 @@ * @subpackage Interactivity API */ +if ( class_exists( 'WP_Interactivity_Store' ) ) { + return; +} + /** * Manages the initial state of the Interactivity API store in the server and * its serialization so it can be restored in the browser upon hydration. diff --git a/lib/experimental/interactivity-api/store.php b/lib/experimental/interactivity-api/store.php index 5e793514e54c90..f2d6838aa043ab 100644 --- a/lib/experimental/interactivity-api/store.php +++ b/lib/experimental/interactivity-api/store.php @@ -6,18 +6,21 @@ * @subpackage Interactivity API */ -/** - * Merge data with the existing store. - * - * @param array $data Data that will be merged with the existing store. - * - * @return $data The current store data. - */ -function wp_store( $data = null ) { - if ( $data ) { - WP_Interactivity_Store::merge_data( $data ); +if ( ! function_exists( 'wp_store' ) ) { + /** + * Merge data with the existing store. + * + * @param array $data Data that will be merged with the existing store. + * + * @return $data The current store data. + */ + function wp_store( $data = null ) { + if ( $data ) { + WP_Interactivity_Store::merge_data( $data ); + } + + return WP_Interactivity_Store::get_data(); } - return WP_Interactivity_Store::get_data(); } /** From 4f50af3dd998f836647b29ef3cb7ffe8536cbf7c Mon Sep 17 00:00:00 2001 From: Anton Vlasenko Date: Mon, 17 Jul 2023 15:45:25 +0200 Subject: [PATCH 19/30] Guard functions and classes. --- lib/compat/wordpress-6.3/kses.php | 33 +++++++++++++++++-------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/lib/compat/wordpress-6.3/kses.php b/lib/compat/wordpress-6.3/kses.php index 23eee580f831ab..3e8f1bd44ec0be 100644 --- a/lib/compat/wordpress-6.3/kses.php +++ b/lib/compat/wordpress-6.3/kses.php @@ -7,21 +7,24 @@ * @package gutenberg */ -/** - * Mark CSS safe if it contains grid functions - * - * This function should not be backported to core. - * - * @param bool $allow_css Whether the CSS is allowed. - * @param string $css_test_string The CSS to test. - */ -function allow_grid_functions_in_styles( $allow_css, $css_test_string ) { - if ( preg_match( - '/^grid-template-columns:\s*repeat\([0-9,a-z-\s\(\)]*\)$/', - $css_test_string - ) ) { - return true; +if ( ! function_exists( 'allow_grid_functions_in_styles' ) ) { + /** + * Mark CSS safe if it contains grid functions + * + * This function should not be backported to core. + * + * @param bool $allow_css Whether the CSS is allowed. + * @param string $css_test_string The CSS to test. + */ + function allow_grid_functions_in_styles( $allow_css, $css_test_string ) { + if ( preg_match( + '/^grid-template-columns:\s*repeat\([0-9,a-z-\s\(\)]*\)$/', + $css_test_string + ) ) { + return true; + } + + return $allow_css; } - return $allow_css; } add_filter( 'safecss_filter_attr_allow_css', 'allow_grid_functions_in_styles', 10, 2 ); From 46814430db48a70f7d302b2a997b4ffcac2d93b0 Mon Sep 17 00:00:00 2001 From: Anton Vlasenko Date: Mon, 17 Jul 2023 16:21:44 +0200 Subject: [PATCH 20/30] Guard functions and classes. --- lib/compat/wordpress-6.3/kses.php | 2 +- lib/compat/wordpress-6.3/theme-previews.php | 21 +++++++++++---------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/lib/compat/wordpress-6.3/kses.php b/lib/compat/wordpress-6.3/kses.php index 3e8f1bd44ec0be..d259f037504fc7 100644 --- a/lib/compat/wordpress-6.3/kses.php +++ b/lib/compat/wordpress-6.3/kses.php @@ -13,7 +13,7 @@ * * This function should not be backported to core. * - * @param bool $allow_css Whether the CSS is allowed. + * @param bool $allow_css Whether the CSS is allowed. * @param string $css_test_string The CSS to test. */ function allow_grid_functions_in_styles( $allow_css, $css_test_string ) { diff --git a/lib/compat/wordpress-6.3/theme-previews.php b/lib/compat/wordpress-6.3/theme-previews.php index 26153d74878b58..f279fa96aca62a 100644 --- a/lib/compat/wordpress-6.3/theme-previews.php +++ b/lib/compat/wordpress-6.3/theme-previews.php @@ -51,14 +51,15 @@ function gutenberg_attach_theme_preview_middleware() { ); } -/** - * Temporary function to add a live preview button to block themes. - * Remove when https://core.trac.wordpress.org/ticket/58190 lands. - */ -function add_live_preview_button() { - global $pagenow; - if ( 'themes.php' === $pagenow ) { - ?> +if ( ! function_exists( 'add_live_preview_button' ) ) { + /** + * Temporary function to add a live preview button to block themes. + * Remove when https://core.trac.wordpress.org/ticket/58190 lands. + */ + function add_live_preview_button() { + global $pagenow; + if ( 'themes.php' === $pagenow ) { + ?> - Date: Mon, 17 Jul 2023 16:25:38 +0200 Subject: [PATCH 21/30] Guard functions and classes. --- lib/compat/wordpress-6.3/theme-previews.php | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/lib/compat/wordpress-6.3/theme-previews.php b/lib/compat/wordpress-6.3/theme-previews.php index f279fa96aca62a..e885d389b94fe0 100644 --- a/lib/compat/wordpress-6.3/theme-previews.php +++ b/lib/compat/wordpress-6.3/theme-previews.php @@ -101,16 +101,18 @@ function addLivePreviewButton() { } } -/** - * Adds a nonce for the theme activation link. - */ -function block_theme_activate_nonce() { - $nonce_handle = 'switch-theme_' . gutenberg_get_theme_preview_path(); - ?> +if ( ! function_exists( 'block_theme_activate_nonce' ) ) { + /** + * Adds a nonce for the theme activation link. + */ + function block_theme_activate_nonce() { + $nonce_handle = 'switch-theme_' . gutenberg_get_theme_preview_path(); + ?> - Date: Mon, 17 Jul 2023 16:50:43 +0200 Subject: [PATCH 22/30] Guard functions and classes. --- .../wordpress-6.2/html-api/class-wp-html-text-replacement.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/compat/wordpress-6.2/html-api/class-wp-html-text-replacement.php b/lib/compat/wordpress-6.2/html-api/class-wp-html-text-replacement.php index 912b4a56a5eb42..b3f70c8e7c57f4 100644 --- a/lib/compat/wordpress-6.2/html-api/class-wp-html-text-replacement.php +++ b/lib/compat/wordpress-6.2/html-api/class-wp-html-text-replacement.php @@ -7,6 +7,10 @@ * @since 6.2.0 */ +if ( class_exists( 'WP_HTML_Text_Replacement' ) ) { + return; +} + /** * Data structure used to replace existing content from start to end that allows to drastically improve performance. * From f3da1815150cb59a9f16a6ed08b907105c33f485 Mon Sep 17 00:00:00 2001 From: Anton Vlasenko Date: Mon, 17 Jul 2023 17:17:42 +0200 Subject: [PATCH 23/30] Guard functions and classes. --- .../wordpress-6.2/html-api/class-wp-html-attribute-token.php | 4 ++++ lib/compat/wordpress-6.2/html-api/class-wp-html-span.php | 4 ++++ .../wordpress-6.2/html-api/class-wp-html-tag-processor.php | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/lib/compat/wordpress-6.2/html-api/class-wp-html-attribute-token.php b/lib/compat/wordpress-6.2/html-api/class-wp-html-attribute-token.php index 2c52164a979f02..cc03c1441ee042 100644 --- a/lib/compat/wordpress-6.2/html-api/class-wp-html-attribute-token.php +++ b/lib/compat/wordpress-6.2/html-api/class-wp-html-attribute-token.php @@ -7,6 +7,10 @@ * @since 6.2.0 */ +if ( class_exists( 'WP_HTML_Attribute_Token' ) ) { + return; +} + /** * Data structure for the attribute token that allows to drastically improve performance. * diff --git a/lib/compat/wordpress-6.2/html-api/class-wp-html-span.php b/lib/compat/wordpress-6.2/html-api/class-wp-html-span.php index d92778cd3a2223..e38bc551923170 100644 --- a/lib/compat/wordpress-6.2/html-api/class-wp-html-span.php +++ b/lib/compat/wordpress-6.2/html-api/class-wp-html-span.php @@ -7,6 +7,10 @@ * @since 6.2.0 */ +if ( class_exists( 'WP_HTML_Span' ) ) { + return; +} + /** * Represents a textual span inside an HTML document. * diff --git a/lib/compat/wordpress-6.2/html-api/class-wp-html-tag-processor.php b/lib/compat/wordpress-6.2/html-api/class-wp-html-tag-processor.php index 7edb67f9f0423e..d61180074f608d 100644 --- a/lib/compat/wordpress-6.2/html-api/class-wp-html-tag-processor.php +++ b/lib/compat/wordpress-6.2/html-api/class-wp-html-tag-processor.php @@ -26,6 +26,10 @@ * @since 6.2.0 */ +if ( class_exists( 'WP_HTML_Tag_Processor' ) ) { + return; +} + /** * Modifies attributes in an HTML document for tags matching a query. * From 686d3e036ad0f9c3b5dfa4f2cee2c8b1a4a69926 Mon Sep 17 00:00:00 2001 From: Anton Vlasenko Date: Mon, 17 Jul 2023 17:26:07 +0200 Subject: [PATCH 24/30] Guard functions and classes. --- lib/compat/wordpress-6.2/rest-api.php | 70 ++++++++++++++------------- 1 file changed, 37 insertions(+), 33 deletions(-) diff --git a/lib/compat/wordpress-6.2/rest-api.php b/lib/compat/wordpress-6.2/rest-api.php index c0f098fa6893ac..e7198dffbc4355 100644 --- a/lib/compat/wordpress-6.2/rest-api.php +++ b/lib/compat/wordpress-6.2/rest-api.php @@ -91,43 +91,47 @@ function gutenberg_modify_rest_sidebars_response( $response ) { } add_filter( 'rest_prepare_sidebar', 'gutenberg_modify_rest_sidebars_response' ); - -/** - * Add the `block_types` value to the `pattern-directory-item` schema. - * - * @since 6.2.0 Added 'block_types' property. - */ -function add_block_pattern_block_types_schema() { - register_rest_field( - 'pattern-directory-item', - 'block_types', - array( - 'schema' => array( - 'description' => __( 'The block types which can use this pattern.', 'gutenberg' ), - 'type' => 'array', - 'uniqueItems' => true, - 'items' => array( 'type' => 'string' ), - 'context' => array( 'view', 'embed' ), - ), - ) - ); +if ( ! function_exists( 'add_block_pattern_block_types_schema' ) ) { + /** + * Add the `block_types` value to the `pattern-directory-item` schema. + * + * @since 6.2.0 Added 'block_types' property. + */ + function add_block_pattern_block_types_schema() { + register_rest_field( + 'pattern-directory-item', + 'block_types', + array( + 'schema' => array( + 'description' => __( 'The block types which can use this pattern.', 'gutenberg' ), + 'type' => 'array', + 'uniqueItems' => true, + 'items' => array( 'type' => 'string' ), + 'context' => array( 'view', 'embed' ), + ), + ) + ); + } } add_filter( 'rest_api_init', 'add_block_pattern_block_types_schema' ); -/** - * Add the `block_types` value into the API response. - * - * @since 6.2.0 Added 'block_types' property. - * - * @param WP_REST_Response $response The response object. - * @param object $raw_pattern The unprepared pattern. - */ -function filter_block_pattern_response( $response, $raw_pattern ) { - $data = $response->get_data(); - $data['block_types'] = array_map( 'sanitize_text_field', $raw_pattern->meta->wpop_block_types ); - $response->set_data( $data ); - return $response; +if ( ! function_exists( 'filter_block_pattern_response' ) ) { + /** + * Add the `block_types` value into the API response. + * + * @since 6.2.0 Added 'block_types' property. + * + * @param WP_REST_Response $response The response object. + * @param object $raw_pattern The unprepared pattern. + */ + function filter_block_pattern_response( $response, $raw_pattern ) { + $data = $response->get_data(); + $data['block_types'] = array_map( 'sanitize_text_field', $raw_pattern->meta->wpop_block_types ); + $response->set_data( $data ); + + return $response; + } } add_filter( 'rest_prepare_block_pattern', 'filter_block_pattern_response', 10, 2 ); From 51e7ebe6b9aaf5ec6a1b30db7417c537b83d9efe Mon Sep 17 00:00:00 2001 From: Anton Vlasenko Date: Mon, 17 Jul 2023 17:33:10 +0200 Subject: [PATCH 25/30] Revert code style changes back. --- lib/compat/wordpress-6.2/rest-api.php | 1 - lib/compat/wordpress-6.3/kses.php | 1 - lib/compat/wordpress-6.3/rest-api.php | 1 - lib/experimental/interactivity-api/store.php | 1 - lib/experimental/kses.php | 4 +--- lib/experimental/rest-api.php | 4 +--- 6 files changed, 2 insertions(+), 10 deletions(-) diff --git a/lib/compat/wordpress-6.2/rest-api.php b/lib/compat/wordpress-6.2/rest-api.php index e7198dffbc4355..97f7daecdff2f7 100644 --- a/lib/compat/wordpress-6.2/rest-api.php +++ b/lib/compat/wordpress-6.2/rest-api.php @@ -129,7 +129,6 @@ function filter_block_pattern_response( $response, $raw_pattern ) { $data = $response->get_data(); $data['block_types'] = array_map( 'sanitize_text_field', $raw_pattern->meta->wpop_block_types ); $response->set_data( $data ); - return $response; } } diff --git a/lib/compat/wordpress-6.3/kses.php b/lib/compat/wordpress-6.3/kses.php index d259f037504fc7..b0b7356d2dac1c 100644 --- a/lib/compat/wordpress-6.3/kses.php +++ b/lib/compat/wordpress-6.3/kses.php @@ -23,7 +23,6 @@ function allow_grid_functions_in_styles( $allow_css, $css_test_string ) { ) ) { return true; } - return $allow_css; } } diff --git a/lib/compat/wordpress-6.3/rest-api.php b/lib/compat/wordpress-6.3/rest-api.php index 238869b1cd846e..67f98e1ec7fcdf 100644 --- a/lib/compat/wordpress-6.3/rest-api.php +++ b/lib/compat/wordpress-6.3/rest-api.php @@ -77,7 +77,6 @@ function add_modified_wp_template_schema() { return mysql_to_rfc3339( $post->post_modified ); } } - return null; }, ) diff --git a/lib/experimental/interactivity-api/store.php b/lib/experimental/interactivity-api/store.php index f2d6838aa043ab..05c8b35f780d4f 100644 --- a/lib/experimental/interactivity-api/store.php +++ b/lib/experimental/interactivity-api/store.php @@ -18,7 +18,6 @@ function wp_store( $data = null ) { if ( $data ) { WP_Interactivity_Store::merge_data( $data ); } - return WP_Interactivity_Store::get_data(); } } diff --git a/lib/experimental/kses.php b/lib/experimental/kses.php index 9bcdf022d84835..6fa8ca641772a2 100644 --- a/lib/experimental/kses.php +++ b/lib/experimental/kses.php @@ -84,9 +84,7 @@ function allow_filter_in_styles( $allow_css, $css_test_string ) { ) ) { return true; } - return $allow_css; } - - add_filter( 'safecss_filter_attr_allow_css', 'allow_filter_in_styles', 10, 2 ); } +add_filter( 'safecss_filter_attr_allow_css', 'allow_filter_in_styles', 10, 2 ); diff --git a/lib/experimental/rest-api.php b/lib/experimental/rest-api.php index 00090e3c02d88f..7c6a9bf74d7395 100644 --- a/lib/experimental/rest-api.php +++ b/lib/experimental/rest-api.php @@ -119,9 +119,7 @@ function wp_api_template_revision_args( $args, $post_type ) { if ( 'wp_template' === $post_type || 'wp_template_part' === $post_type ) { $args['rest_controller_class'] = 'Gutenberg_REST_Template_Revision_Count'; } - return $args; } - - add_filter( 'register_post_type_args', 'wp_api_template_revision_args', 10, 2 ); } +add_filter( 'register_post_type_args', 'wp_api_template_revision_args', 10, 2 ); From ad92156a773c682c0749aa5b28a3bcccc89ed382 Mon Sep 17 00:00:00 2001 From: Anton Vlasenko Date: Tue, 18 Jul 2023 18:31:42 +0200 Subject: [PATCH 26/30] Fix cs errors. --- .../gutenberg-coding-standards/.phpcs.xml.dist | 10 +--------- .../CodeAnalysis/GuardedFunctionAndClassNamesSniff.php | 1 - .../GuardedFunctionAndClassNamesUnitTest.php | 3 +++ .../gutenberg/gutenberg-coding-standards/composer.json | 3 ++- 4 files changed, 6 insertions(+), 11 deletions(-) diff --git a/lib/experimental/packages/gutenberg/gutenberg-coding-standards/.phpcs.xml.dist b/lib/experimental/packages/gutenberg/gutenberg-coding-standards/.phpcs.xml.dist index 51dca55464c3a2..d6862f9a00fa9e 100644 --- a/lib/experimental/packages/gutenberg/gutenberg-coding-standards/.phpcs.xml.dist +++ b/lib/experimental/packages/gutenberg/gutenberg-coding-standards/.phpcs.xml.dist @@ -51,7 +51,7 @@ - +
@@ -72,14 +72,6 @@ - - - - /WordPress/Sniffs/NamingConventions/ValidHookNameSniff\.php$ - /WordPress/Sniffs/Security/(EscapeOutput|NonceVerification|ValidatedSanitizedInput)Sniff\.php$ - - - ./vendor/* - ./lib/experimental/packages/gutenberg/gutenberg-coding-standards/* + ./test/php/gutenberg-coding-standards/* diff --git a/lib/experimental/packages/gutenberg/gutenberg-coding-standards/.gitignore b/test/php/gutenberg-coding-standards/.gitignore similarity index 100% rename from lib/experimental/packages/gutenberg/gutenberg-coding-standards/.gitignore rename to test/php/gutenberg-coding-standards/.gitignore diff --git a/lib/experimental/packages/gutenberg/gutenberg-coding-standards/.phpcs.xml.dist b/test/php/gutenberg-coding-standards/.phpcs.xml.dist similarity index 100% rename from lib/experimental/packages/gutenberg/gutenberg-coding-standards/.phpcs.xml.dist rename to test/php/gutenberg-coding-standards/.phpcs.xml.dist diff --git a/lib/experimental/packages/gutenberg/gutenberg-coding-standards/Gutenberg/Sniffs/CodeAnalysis/GuardedFunctionAndClassNamesSniff.php b/test/php/gutenberg-coding-standards/Gutenberg/Sniffs/CodeAnalysis/GuardedFunctionAndClassNamesSniff.php similarity index 100% rename from lib/experimental/packages/gutenberg/gutenberg-coding-standards/Gutenberg/Sniffs/CodeAnalysis/GuardedFunctionAndClassNamesSniff.php rename to test/php/gutenberg-coding-standards/Gutenberg/Sniffs/CodeAnalysis/GuardedFunctionAndClassNamesSniff.php diff --git a/lib/experimental/packages/gutenberg/gutenberg-coding-standards/Gutenberg/Tests/CodeAnalysis/GuardedFunctionAndClassNamesUnitTest.inc b/test/php/gutenberg-coding-standards/Gutenberg/Tests/CodeAnalysis/GuardedFunctionAndClassNamesUnitTest.inc similarity index 100% rename from lib/experimental/packages/gutenberg/gutenberg-coding-standards/Gutenberg/Tests/CodeAnalysis/GuardedFunctionAndClassNamesUnitTest.inc rename to test/php/gutenberg-coding-standards/Gutenberg/Tests/CodeAnalysis/GuardedFunctionAndClassNamesUnitTest.inc diff --git a/lib/experimental/packages/gutenberg/gutenberg-coding-standards/Gutenberg/Tests/CodeAnalysis/GuardedFunctionAndClassNamesUnitTest.php b/test/php/gutenberg-coding-standards/Gutenberg/Tests/CodeAnalysis/GuardedFunctionAndClassNamesUnitTest.php similarity index 100% rename from lib/experimental/packages/gutenberg/gutenberg-coding-standards/Gutenberg/Tests/CodeAnalysis/GuardedFunctionAndClassNamesUnitTest.php rename to test/php/gutenberg-coding-standards/Gutenberg/Tests/CodeAnalysis/GuardedFunctionAndClassNamesUnitTest.php diff --git a/lib/experimental/packages/gutenberg/gutenberg-coding-standards/Gutenberg/ruleset.xml b/test/php/gutenberg-coding-standards/Gutenberg/ruleset.xml similarity index 100% rename from lib/experimental/packages/gutenberg/gutenberg-coding-standards/Gutenberg/ruleset.xml rename to test/php/gutenberg-coding-standards/Gutenberg/ruleset.xml diff --git a/lib/experimental/packages/gutenberg/gutenberg-coding-standards/README.md b/test/php/gutenberg-coding-standards/README.md similarity index 100% rename from lib/experimental/packages/gutenberg/gutenberg-coding-standards/README.md rename to test/php/gutenberg-coding-standards/README.md diff --git a/lib/experimental/packages/gutenberg/gutenberg-coding-standards/Tests/bootstrap.php b/test/php/gutenberg-coding-standards/Tests/bootstrap.php similarity index 100% rename from lib/experimental/packages/gutenberg/gutenberg-coding-standards/Tests/bootstrap.php rename to test/php/gutenberg-coding-standards/Tests/bootstrap.php diff --git a/lib/experimental/packages/gutenberg/gutenberg-coding-standards/composer.json b/test/php/gutenberg-coding-standards/composer.json similarity index 100% rename from lib/experimental/packages/gutenberg/gutenberg-coding-standards/composer.json rename to test/php/gutenberg-coding-standards/composer.json diff --git a/lib/experimental/packages/gutenberg/gutenberg-coding-standards/phpunit.xml.dist b/test/php/gutenberg-coding-standards/phpunit.xml.dist similarity index 100% rename from lib/experimental/packages/gutenberg/gutenberg-coding-standards/phpunit.xml.dist rename to test/php/gutenberg-coding-standards/phpunit.xml.dist From 27dc135b0ab888ff9a297459c0c387c497185f98 Mon Sep 17 00:00:00 2001 From: Anton Vlasenko Date: Thu, 20 Jul 2023 15:45:21 +0200 Subject: [PATCH 28/30] Don't whitelist "WP.+Gutenberg" classes. Let's be more strict to porevent potential issues. --- lib/class-wp-duotone-gutenberg.php | 4 ++++ lib/class-wp-theme-json-data-gutenberg.php | 4 ++++ lib/class-wp-theme-json-gutenberg.php | 4 ++++ lib/class-wp-theme-json-resolver-gutenberg.php | 4 ++++ phpcs.xml.dist | 1 - 5 files changed, 16 insertions(+), 1 deletion(-) diff --git a/lib/class-wp-duotone-gutenberg.php b/lib/class-wp-duotone-gutenberg.php index 816f7e414ad793..41120a882ed235 100644 --- a/lib/class-wp-duotone-gutenberg.php +++ b/lib/class-wp-duotone-gutenberg.php @@ -32,6 +32,10 @@ * @since 6.3.0 */ +if ( class_exists( 'WP_Duotone_Gutenberg' ) ) { + return; +} + /** * Manages duotone block supports and global styles. * diff --git a/lib/class-wp-theme-json-data-gutenberg.php b/lib/class-wp-theme-json-data-gutenberg.php index 2e5ea474346a92..db0737ebea08b6 100644 --- a/lib/class-wp-theme-json-data-gutenberg.php +++ b/lib/class-wp-theme-json-data-gutenberg.php @@ -6,6 +6,10 @@ * @since 6.1.0 */ +if ( class_exists( 'WP_Theme_JSON_Data_Gutenberg' ) ) { + return; +} + /** * Class to provide access to update a theme.json structure. */ diff --git a/lib/class-wp-theme-json-gutenberg.php b/lib/class-wp-theme-json-gutenberg.php index 0745ee06b84a23..60e69632eedb62 100644 --- a/lib/class-wp-theme-json-gutenberg.php +++ b/lib/class-wp-theme-json-gutenberg.php @@ -6,6 +6,10 @@ * @since 5.8.0 */ +if ( class_exists( 'WP_Theme_JSON_Gutenberg' ) ) { + return; +} + /** * Class that encapsulates the processing of structures that adhere to the theme.json spec. * diff --git a/lib/class-wp-theme-json-resolver-gutenberg.php b/lib/class-wp-theme-json-resolver-gutenberg.php index 1e825e3c6bbe4f..39721742946cd1 100644 --- a/lib/class-wp-theme-json-resolver-gutenberg.php +++ b/lib/class-wp-theme-json-resolver-gutenberg.php @@ -6,6 +6,10 @@ * @since 5.8.0 */ +if ( class_exists( 'WP_Theme_JSON_Resolver_Gutenberg' ) ) { + return; +} + /** * Class that abstracts the processing of the different data sources * for site-level config and offers an API to work with them. diff --git a/phpcs.xml.dist b/phpcs.xml.dist index 63d76b074b4fdb..d66a7d2d46516b 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -122,7 +122,6 @@ - From a088af5a39d3c617b60af39c55c7595e0986ceab Mon Sep 17 00:00:00 2001 From: Anton Vlasenko Date: Thu, 20 Jul 2023 15:56:09 +0200 Subject: [PATCH 29/30] Update code owners. --- .github/CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 7cd07d819ea57b..a324657fad6f7d 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -82,6 +82,7 @@ /packages/scripts @gziolo @ntwb @nerrad @ajitbohra @ryanwelcher /packages/stylelint-config @ntwb /test/e2e @kevin940726 @Mamaduka +/test/php/gutenberg-coding-standards @anton-vlasenko # UI Components /packages/components @ajitbohra @@ -136,7 +137,6 @@ /lib/experimental/rest-api.php @timothybjacobs /lib/experimental/class-wp-rest-* @timothybjacobs /lib/experimental/class-wp-rest-block-editor-settings-controller.php @timothybjacobs @spacedmonkey @geriux -/lib/experimental/packages/gutenberg/gutenberg-coding-standards @anton-vlasenko # Native /packages/components/src/mobile/global-styles-context @geriux From 4457480ee542c048fd36943d8fb22d443df6f3f9 Mon Sep 17 00:00:00 2001 From: Anton Vlasenko Date: Thu, 20 Jul 2023 15:58:20 +0200 Subject: [PATCH 30/30] Fix indents. --- lib/compat/wordpress-6.3/rest-api.php | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/lib/compat/wordpress-6.3/rest-api.php b/lib/compat/wordpress-6.3/rest-api.php index 67f98e1ec7fcdf..ecb8f52392fef9 100644 --- a/lib/compat/wordpress-6.3/rest-api.php +++ b/lib/compat/wordpress-6.3/rest-api.php @@ -24,12 +24,12 @@ function gutenberg_update_templates_template_parts_rest_controller( $args, $post_type ) { if ( in_array( $post_type, array( 'wp_template', 'wp_template_part' ), true ) ) { $template_edit_link = 'site-editor.php?' . build_query( - array( - 'postType' => $post_type, - 'postId' => '%s', - 'canvas' => 'edit', - ) - ); + array( + 'postType' => $post_type, + 'postId' => '%s', + 'canvas' => 'edit', + ) + ); $args['_edit_link'] = $template_edit_link; } @@ -39,12 +39,12 @@ function gutenberg_update_templates_template_parts_rest_controller( $args, $post if ( 'wp_navigation' === $post_type ) { $navigation_edit_link = 'site-editor.php?' . build_query( - array( - 'postId' => '%s', - 'postType' => 'wp_navigation', - 'canvas' => 'edit', - ) - ); + array( + 'postId' => '%s', + 'postType' => 'wp_navigation', + 'canvas' => 'edit', + ) + ); $args['_edit_link'] = $navigation_edit_link; }