From a0c7de79b5507de60dddf6ec3721b6aee3afab55 Mon Sep 17 00:00:00 2001 From: Frank Ebbers Date: Fri, 15 Nov 2024 07:59:44 +0100 Subject: [PATCH 01/21] D10+ composer dependencies --- composer.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/composer.json b/composer.json index ac7d1f7f..4d8e4bd8 100644 --- a/composer.json +++ b/composer.json @@ -13,21 +13,21 @@ "php": "^8.1", "phpstan/phpstan": "^2.0", "phpstan/phpstan-deprecation-rules": "^2.0", - "symfony/finder": "^4.2 || ^5.0 || ^6.0 || ^7.0", - "symfony/yaml": "^4.2|| ^5.0 || ^6.0 || ^7.0", + "symfony/finder": "^4.2 || ^7.0", + "symfony/yaml": "^4.2 || ^7.0", "webflo/drupal-finder": "^1.3.1" }, "require-dev": { - "behat/mink": "^1.8", + "behat/mink": "^1.10", "composer/installers": "^1.9", "drupal/core-recommended": "^10", - "drush/drush": "^10.0 || ^11 || ^12 || ^13@beta", - "phpstan/extension-installer": "1.4.3", + "drush/drush": "^11 || ^12 || ^13@beta", + "phpstan/extension-installer": "^1.4.3", "phpstan/phpstan-strict-rules": "^2.0", - "phpunit/phpunit": "^8.5 || ^9 || ^10 || ^11", + "phpunit/phpunit": "^9 || ^10 || ^11", "slevomat/coding-standard": "^7.1", "squizlabs/php_codesniffer": "^3.3", - "symfony/phpunit-bridge": "^4.4 || ^5.4 || ^6.0 || ^7.0" + "symfony/phpunit-bridge": "^6.2 || ^7.0" }, "minimum-stability": "dev", "prefer-stable": true, From 8bf48c3b1c73c20af295cb6b0b8ee176a3a96993 Mon Sep 17 00:00:00 2001 From: Frank Ebbers Date: Fri, 15 Nov 2024 08:01:43 +0100 Subject: [PATCH 02/21] [Compser] D10+ composer dependencies --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 4d8e4bd8..c5b7c46e 100644 --- a/composer.json +++ b/composer.json @@ -13,8 +13,8 @@ "php": "^8.1", "phpstan/phpstan": "^2.0", "phpstan/phpstan-deprecation-rules": "^2.0", - "symfony/finder": "^4.2 || ^7.0", - "symfony/yaml": "^4.2 || ^7.0", + "symfony/finder": "^6.2 || ^7.0", + "symfony/yaml": "^6.2 || ^7.0", "webflo/drupal-finder": "^1.3.1" }, "require-dev": { From b3b513ebce633de613520831440ea8600ea9fdd2 Mon Sep 17 00:00:00 2001 From: Frank Ebbers Date: Fri, 15 Nov 2024 08:05:58 +0100 Subject: [PATCH 03/21] {CI} Drop D9 from testing matrices --- .github/workflows/php.yml | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/.github/workflows/php.yml b/.github/workflows/php.yml index ccf15bcb..ab3774b2 100644 --- a/.github/workflows/php.yml +++ b/.github/workflows/php.yml @@ -47,9 +47,6 @@ jobs: drupal: - "^10" include: - - php-version: "8.1" - drupal: "^9.0" - experimental: false - php-version: "8.3" drupal: "11.x-dev" experimental: true @@ -65,9 +62,6 @@ jobs: extensions: dom, curl, libxml, mbstring, zip, pdo, mysql, pdo_mysql, gd - name: "Set drupal/core to ${{ matrix.drupal }}" run: "composer require drupal/core-recommended:${{ matrix.drupal }} --with-all-dependencies --dev --no-update" - - name: "Add phpspec/prophecy-phpunit" - run: "composer require phpspec/prophecy-phpunit:^2 --dev --no-update" - if: ${{ matrix.drupal == '^9.0' }} - name: "Install dependencies" uses: "ramsey/composer-install@v3" - name: "PHPUnit" @@ -89,9 +83,6 @@ jobs: drupal: - "^10" include: - - php-version: "8.1" - drupal: "^9.0" - experimental: false - php-version: "8.3" drupal: "11.x-dev" experimental: true @@ -165,9 +156,6 @@ jobs: drupal: - "^10" include: - - php-version: "8.1" - drupal: "^9.0" - experimental: false - php-version: "8.3" drupal: "11.x-dev" experimental: true @@ -245,7 +233,6 @@ jobs: cd drupal composer config repositories.0 composer https://packages.drupal.org/8 composer config repositories.1 path $GITHUB_WORKSPACE - - name: "Install Drupal core dependencies" uses: "ramsey/composer-install@v3" with: From 46ad904c1fd974254e360b60ef786676890ae685 Mon Sep 17 00:00:00 2001 From: Frank Ebbers Date: Fri, 15 Nov 2024 08:20:36 +0100 Subject: [PATCH 04/21] {Rules} Drop AccessDeprecatedConstantTest, and \mglaman\PHPStanDrupal\Rules\Deprecations\AccessDeprecatedConstant --- .../Deprecations/AccessDeprecatedConstant.php | 137 ------------------ .../Rules/AccessDeprecatedConstantTest.php | 44 ------ 2 files changed, 181 deletions(-) delete mode 100644 src/Rules/Deprecations/AccessDeprecatedConstant.php delete mode 100644 tests/src/Rules/AccessDeprecatedConstantTest.php diff --git a/src/Rules/Deprecations/AccessDeprecatedConstant.php b/src/Rules/Deprecations/AccessDeprecatedConstant.php deleted file mode 100644 index e47661b3..00000000 --- a/src/Rules/Deprecations/AccessDeprecatedConstant.php +++ /dev/null @@ -1,137 +0,0 @@ - - */ -class AccessDeprecatedConstant implements Rule -{ - /** @var ReflectionProvider */ - private $reflectionProvider; - public function __construct(ReflectionProvider $reflectionProvider) - { - $this->reflectionProvider = $reflectionProvider; - } - - public function getNodeType(): string - { - return Node\Expr\ConstFetch::class; - } - - public function processNode(Node $node, Scope $scope): array - { - if (DeprecatedScopeCheck::inDeprecatedScope($scope)) { - return []; - } - - // nikic/php-parser does not let us access phpdoc comments from deprecated constants, so - // here goes a list of hardcoded core constants. List is available at - // https://api.drupal.org/api/drupal/deprecated/8.9.x?order=object_type&sort=asc&page=5 - $deprecatedConstants = [ - 'DATETIME_STORAGE_TIMEZONE' => 'Deprecated in drupal:8.5.0 and is removed from drupal:9.0.0. Use \Drupal\datetime\Plugin\Field\FieldType\DateTimeItemInterface::STORAGE_TIMEZONE instead.', - 'DATETIME_DATETIME_STORAGE_FORMAT' => 'Deprecated in drupal:8.5.0 and is removed from drupal:9.0.0. Use \Drupal\datetime\Plugin\Field\FieldType\DateTimeItemInterface::DATETIME_STORAGE_FORMAT instead.', - 'DATETIME_DATE_STORAGE_FORMAT' => 'Deprecated in drupal:8.5.0 and is removed from drupal:9.0.0. Use \Drupal\datetime\Plugin\Field\FieldType\DateTimeItemInterface::DATE_STORAGE_FORMAT instead.', - 'DRUPAL_ANONYMOUS_RID' => 'Deprecated in drupal:8.0.0 and is removed from drupal:9.0.0. Use Drupal\Core\Session\AccountInterface::ANONYMOUS_ROLE or \Drupal\user\RoleInterface::ANONYMOUS_ID instead.', - 'DRUPAL_AUTHENTICATED_RID' => 'Deprecated in drupal:8.0.0 and is removed from drupal:9.0.0. Use Drupal\Core\Session\AccountInterface::AUTHENTICATED_ROLE or \Drupal\user\RoleInterface::AUTHENTICATED_ID instead.', - 'REQUEST_TIME' => 'Deprecated in drupal:8.3.0 and is removed from drupal:11.0.0. Use \Drupal::time()->getRequestTime(); ', - 'DRUPAL_PHP_FUNCTION_PATTERN' => 'Deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use \Drupal\Core\Extension\ExtensionDiscovery::PHP_FUNCTION_PATTERN instead.', - 'CONFIG_ACTIVE_DIRECTORY' => 'Deprecated in drupal:8.0.0 and is removed from drupal:9.0.0. Drupal core no longer creates an active directory.', - 'CONFIG_SYNC_DIRECTORY' => 'Deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use \Drupal\Core\Site\Settings::get(\'config_sync_directory\') instead.', - 'CONFIG_STAGING_DIRECTORY' => 'Deprecated in drupal:8.0.0 and is removed from drupal:9.0.0. The staging directory was renamed to sync.', - 'LOCALE_PLURAL_DELIMITER' => 'Deprecated in drupal:8.0.0 and is removed from drupal:9.0.0. Use Drupal\Component\Gettext\PoItem::DELIMITER instead.', - 'FILE_CHMOD_DIRECTORY' => 'Deprecated in drupal:8.0.0 and is removed from drupal:9.0.0. Use \Drupal\Core\File\FileSystem::CHMOD_DIRECTORY.', - 'FILE_CHMOD_FILE' => 'Deprecated in drupal:8.0.0 and is removed from drupal:9.0.0. Use \Drupal\Core\File\FileSystem::CHMOD_FILE.', - 'FILE_CREATE_DIRECTORY' => 'Deprecated in drupal:8.7.0 and is removed from drupal:9.0.0. Use \Drupal\Core\File\FileSystemInterface::CREATE_DIRECTORY.', - 'FILE_MODIFY_PERMISSIONS' => 'Deprecated in drupal:8.7.0 and is removed from drupal:9.0.0. Use \Drupal\Core\File\FileSystemInterface::MODIFY_PERMISSIONS.', - 'FILE_EXISTS_RENAME' => 'Deprecated in drupal:8.7.0 and is removed from drupal:9.0.0. Use \Drupal\Core\File\FileSystemInterface::EXISTS_RENAME.', - 'FILE_EXISTS_REPLACE' => 'Deprecated in drupal:8.7.0 and is removed from drupal:9.0.0. Use \Drupal\Core\File\FileSystemInterface::EXISTS_REPLACE.', - 'FILE_EXISTS_ERROR' => 'Deprecated in drupal:8.7.0 and is removed from drupal:9.0.0. Use \Drupal\Core\File\FileSystemInterface::EXISTS_ERROR.', - 'AGGREGATOR_CLEAR_NEVER' => 'Deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use \Drupal\aggregator\FeedStorageInterface::CLEAR_NEVER instead.', - 'COMMENT_ANONYMOUS_MAYNOT_CONTACT' => 'Deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use \Drupal\comment\CommentInterface::ANONYMOUS_MAYNOT_CONTACT instead.', - 'COMMENT_ANONYMOUS_MAY_CONTACT' => 'Deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use \Drupal\comment\CommentInterface::ANONYMOUS_MAY_CONTACT instead.', - 'COMMENT_ANONYMOUS_MUST_CONTACT' => 'Deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use \Drupal\comment\CommentInterface::ANONYMOUS_MUST_CONTACT instead.', - 'IMAGE_STORAGE_NORMAL' => 'Deprecated in drupal:8.1.0 and is removed from drupal:9.0.0.', - 'IMAGE_STORAGE_OVERRIDE' => 'Deprecated in drupal:8.1.0 and is removed from drupal:9.0.0.', - 'IMAGE_STORAGE_DEFAULT' => 'Deprecated in drupal:8.1.0 and is removed from drupal:9.0.0.', - 'IMAGE_STORAGE_EDITABLE' => 'Deprecated in drupal:8.1.0 and is removed from drupal:9.0.0.', - 'IMAGE_STORAGE_MODULE' => 'Deprecated in drupal:8.1.0 and is removed from drupal:9.0.0.', - 'MENU_MAX_MENU_NAME_LENGTH_UI' => 'Deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use \Drupal\system\MenuStorage::MAX_ID_LENGTH instead.', - 'NODE_NOT_PUBLISHED' => 'Deprecated in drupal:8.?.? and is removed from drupal:9.0.0. Use \Drupal\node\NodeInterface::NOT_PUBLISHED instead.', - 'NODE_PUBLISHED' => 'Deprecated in drupal:8.?.? and is removed from drupal:9.0.0. Use \Drupal\node\NodeInterface::PUBLISHED instead.', - 'NODE_NOT_PROMOTED' => 'Deprecated in drupal:8.?.? and is removed from drupal:9.0.0. Use \Drupal\node\NodeInterface::NOT_PROMOTED instead.', - 'NODE_PROMOTED' => 'Deprecated in drupal:8.?.? and is removed from drupal:9.0.0. Use \Drupal\node\NodeInterface::PROMOTED instead.', - 'NODE_NOT_STICKY' => 'Deprecated in drupal:8.?.? and is removed from drupal:9.0.0. Use \Drupal\node\NodeInterface::NOT_STICKY instead.', - 'NODE_STICKY' => 'Deprecated in drupal:8.?.? and is removed from drupal:9.0.0. Use \Drupal\node\NodeInterface::STICKY instead.', - 'RESPONSIVE_IMAGE_EMPTY_IMAGE' => 'Deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use Drupal\responsive_image\ResponsiveImageStyleInterface::EMPTY_IMAGE instead.', - 'RESPONSIVE_IMAGE_ORIGINAL_IMAGE' => 'Deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use \Drupal\responsive_image\ResponsiveImageStyleInterface::ORIGINAL_IMAGE instead.', - 'DRUPAL_USER_TIMEZONE_DEFAULT' => 'Deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use \Drupal\user\UserInterface::TIMEZONE_DEFAULT instead.', - 'DRUPAL_USER_TIMEZONE_EMPTY' => 'Deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use \Drupal\user\UserInterface::TIMEZONE_EMPTY instead.', - 'DRUPAL_USER_TIMEZONE_SELECT' => 'Deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use \Drupal\user\UserInterface::TIMEZONE_SELECT instead.', - 'TAXONOMY_HIERARCHY_DISABLED' => 'Deprecated in drupal:8.2.0 and is removed from drupal:9.0.0. Use \Drupal\taxonomy\VocabularyInterface::HIERARCHY_DISABLED instead.', - 'TAXONOMY_HIERARCHY_SINGLE' => 'Deprecated in drupal:8.2.0 and is removed from drupal:9.0.0. Use \Drupal\taxonomy\VocabularyInterface::HIERARCHY_SINGLE instead.', - 'TAXONOMY_HIERARCHY_MULTIPLE' => 'Deprecated in drupal:8.2.0 and is removed from drupal:9.0.0. Use \Drupal\taxonomy\VocabularyInterface::HIERARCHY_MULTIPLE instead.', - 'UPDATE_NOT_SECURE' => 'Deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use \Drupal\update\UpdateManagerInterface::NOT_SECURE instead.', - 'UPDATE_REVOKED' => 'Deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use \Drupal\update\UpdateManagerInterface::REVOKED instead.', - 'UPDATE_NOT_SUPPORTED' => 'Deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use \Drupal\update\UpdateManagerInterface::NOT_SUPPORTED instead.', - 'UPDATE_NOT_CURRENT' => 'Deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use \Drupal\update\UpdateManagerInterface::NOT_CURRENT instead.', - 'UPDATE_CURRENT' => 'Deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use \Drupal\update\UpdateManagerInterface::CURRENT instead.', - 'UPDATE_NOT_CHECKED' => 'Deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use \Drupal\update\UpdateFetcherInterface::NOT_CHECKED instead.', - 'UPDATE_UNKNOWN' => 'Deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use \Drupal\update\UpdateFetcherInterface::UNKNOWN instead.', - 'UPDATE_NOT_FETCHED' => 'Deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use \Drupal\update\UpdateFetcherInterface::NOT_FETCHED instead.', - 'UPDATE_FETCH_PENDING' => 'Deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use \Drupal\update\UpdateFetcherInterface::FETCH_PENDING instead.', - 'USERNAME_MAX_LENGTH' => 'Deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use \Drupal\user\UserInterface::USERNAME_MAX_LENGTH instead.', - 'USER_REGISTER_ADMINISTRATORS_ONLY' => 'Deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use \Drupal\user\UserInterface::REGISTER_ADMINISTRATORS_ONLY instead.', - 'USER_REGISTER_VISITORS' => 'Deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use \Drupal\user\UserInterface::REGISTER_VISITORS instead.', - 'USER_REGISTER_VISITORS_ADMINISTRATIVE_APPROVAL' => 'Deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use \Drupal\user\UserInterface::REGISTER_VISITORS_ADMINISTRATIVE_APPROVAL instead.', - ]; - [$major, $minor] = explode('.', Drupal::VERSION, 3); - if ($major === '9') { - if ((int) $minor >= 1) { - $deprecatedConstants = array_merge($deprecatedConstants, [ - 'DRUPAL_MINIMUM_PHP' => 'Deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. Use \Drupal::MINIMUM_PHP instead.', - 'DRUPAL_MINIMUM_PHP_MEMORY_LIMIT' => 'Deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. Use \Drupal::MINIMUM_PHP_MEMORY_LIMIT instead.', - 'DRUPAL_MINIMUM_SUPPORTED_PHP' => 'Deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. Use \Drupal::MINIMUM_SUPPORTED_PHP instead.', - 'DRUPAL_RECOMMENDED_PHP' => 'Deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. Use \Drupal::RECOMMENDED_PHP instead.', - 'PREG_CLASS_CJK' => 'Deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. Use \Drupal\search\SearchTextProcessorInterface::PREG_CLASS_CJK instead.', - 'PREG_CLASS_NUMBERS' => 'Deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. Use \Drupal\search\SearchTextProcessorInterface::PREG_CLASS_NUMBERS', - 'PREG_CLASS_PUNCTUATION' => 'Deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. Use \Drupal\search\SearchTextProcessorInterface::PREG_CLASS_PUNCTUATION', - ]); - } - if ((int) $minor >= 2) { - $deprecatedConstants = array_merge($deprecatedConstants, [ - 'FILE_INSECURE_EXTENSION_REGEX' => 'Deprecated in drupal:9.2.0 and is removed from drupal:10.0.0. Use \Drupal\Core\File\FileSystemInterface::INSECURE_EXTENSION_REGEX.', - ]); - } - if ((int) $minor >= 3) { - $deprecatedConstants = array_merge($deprecatedConstants, [ - 'FILE_STATUS_PERMANENT' => 'Deprecated in drupal:9.3.0 and is removed from drupal:10.0.0. Use \Drupal\file\FileInterface::STATUS_PERMANENT or \Drupal\file\FileInterface::setPermanent().', - 'SCHEMA_UNINSTALLED' => 'Deprecated in drupal:9.3.0 and is removed from drupal:10.0.0. Use \Drupal\Core\Update\UpdateHookRegistry::SCHEMA_UNINSTALLED', - ]); - } - } - - $constantName = $this->reflectionProvider->resolveConstantName($node->name, $scope); - if (isset($deprecatedConstants[$constantName])) { - return [ - RuleErrorBuilder::message( - sprintf('Call to deprecated constant %s: %s', $constantName, $deprecatedConstants[$constantName]) - ) - ->identifier("accessDeprecatedConstant.deprecatedConstantCalled") - ->build() - ]; - } - return []; - } -} diff --git a/tests/src/Rules/AccessDeprecatedConstantTest.php b/tests/src/Rules/AccessDeprecatedConstantTest.php deleted file mode 100644 index 2ca14b79..00000000 --- a/tests/src/Rules/AccessDeprecatedConstantTest.php +++ /dev/null @@ -1,44 +0,0 @@ - - */ -final class AccessDeprecatedConstantTest extends DrupalRuleTestCase -{ - - protected function getRule(): \PHPStan\Rules\Rule - { - return new AccessDeprecatedConstant($this->createReflectionProvider()); - } - - public function testRule(): void - { - [$version] = explode('.', \Drupal::VERSION, 2); - if ($version !== '9') { - self::markTestSkipped('Only tested on Drupal 9.x.x'); - } - - $this->analyse( - [__DIR__ . '/../../fixtures/drupal/modules/phpstan_fixtures/phpstan_fixtures.module'], - [ - [ - 'Call to deprecated constant SCHEMA_UNINSTALLED: Deprecated in drupal:9.3.0 and is removed from drupal:10.0.0. Use \Drupal\Core\Update\UpdateHookRegistry::SCHEMA_UNINSTALLED', - 47 - ], - [ - 'Call to deprecated constant FILE_INSECURE_EXTENSION_REGEX: Deprecated in drupal:9.2.0 and is removed from drupal:10.0.0. Use \Drupal\Core\File\FileSystemInterface::INSECURE_EXTENSION_REGEX.', - 48 - ], - [ - 'Call to deprecated constant PREG_CLASS_PUNCTUATION: Deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. Use \Drupal\search\SearchTextProcessorInterface::PREG_CLASS_PUNCTUATION', - 49 - ], - ], - ); - } -} From 181a5dfb6e4d4dab7202d305968d0d230e9ee5a2 Mon Sep 17 00:00:00 2001 From: Frank Ebbers Date: Fri, 15 Nov 2024 08:36:40 +0100 Subject: [PATCH 05/21] Revert "{Rules} Drop AccessDeprecatedConstantTest, and \mglaman\PHPStanDrupal\Rules\Deprecations\AccessDeprecatedConstant" This reverts commit 46ad904c1fd974254e360b60ef786676890ae685. --- .../Deprecations/AccessDeprecatedConstant.php | 137 ++++++++++++++++++ .../Rules/AccessDeprecatedConstantTest.php | 44 ++++++ 2 files changed, 181 insertions(+) create mode 100644 src/Rules/Deprecations/AccessDeprecatedConstant.php create mode 100644 tests/src/Rules/AccessDeprecatedConstantTest.php diff --git a/src/Rules/Deprecations/AccessDeprecatedConstant.php b/src/Rules/Deprecations/AccessDeprecatedConstant.php new file mode 100644 index 00000000..e47661b3 --- /dev/null +++ b/src/Rules/Deprecations/AccessDeprecatedConstant.php @@ -0,0 +1,137 @@ + + */ +class AccessDeprecatedConstant implements Rule +{ + /** @var ReflectionProvider */ + private $reflectionProvider; + public function __construct(ReflectionProvider $reflectionProvider) + { + $this->reflectionProvider = $reflectionProvider; + } + + public function getNodeType(): string + { + return Node\Expr\ConstFetch::class; + } + + public function processNode(Node $node, Scope $scope): array + { + if (DeprecatedScopeCheck::inDeprecatedScope($scope)) { + return []; + } + + // nikic/php-parser does not let us access phpdoc comments from deprecated constants, so + // here goes a list of hardcoded core constants. List is available at + // https://api.drupal.org/api/drupal/deprecated/8.9.x?order=object_type&sort=asc&page=5 + $deprecatedConstants = [ + 'DATETIME_STORAGE_TIMEZONE' => 'Deprecated in drupal:8.5.0 and is removed from drupal:9.0.0. Use \Drupal\datetime\Plugin\Field\FieldType\DateTimeItemInterface::STORAGE_TIMEZONE instead.', + 'DATETIME_DATETIME_STORAGE_FORMAT' => 'Deprecated in drupal:8.5.0 and is removed from drupal:9.0.0. Use \Drupal\datetime\Plugin\Field\FieldType\DateTimeItemInterface::DATETIME_STORAGE_FORMAT instead.', + 'DATETIME_DATE_STORAGE_FORMAT' => 'Deprecated in drupal:8.5.0 and is removed from drupal:9.0.0. Use \Drupal\datetime\Plugin\Field\FieldType\DateTimeItemInterface::DATE_STORAGE_FORMAT instead.', + 'DRUPAL_ANONYMOUS_RID' => 'Deprecated in drupal:8.0.0 and is removed from drupal:9.0.0. Use Drupal\Core\Session\AccountInterface::ANONYMOUS_ROLE or \Drupal\user\RoleInterface::ANONYMOUS_ID instead.', + 'DRUPAL_AUTHENTICATED_RID' => 'Deprecated in drupal:8.0.0 and is removed from drupal:9.0.0. Use Drupal\Core\Session\AccountInterface::AUTHENTICATED_ROLE or \Drupal\user\RoleInterface::AUTHENTICATED_ID instead.', + 'REQUEST_TIME' => 'Deprecated in drupal:8.3.0 and is removed from drupal:11.0.0. Use \Drupal::time()->getRequestTime(); ', + 'DRUPAL_PHP_FUNCTION_PATTERN' => 'Deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use \Drupal\Core\Extension\ExtensionDiscovery::PHP_FUNCTION_PATTERN instead.', + 'CONFIG_ACTIVE_DIRECTORY' => 'Deprecated in drupal:8.0.0 and is removed from drupal:9.0.0. Drupal core no longer creates an active directory.', + 'CONFIG_SYNC_DIRECTORY' => 'Deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use \Drupal\Core\Site\Settings::get(\'config_sync_directory\') instead.', + 'CONFIG_STAGING_DIRECTORY' => 'Deprecated in drupal:8.0.0 and is removed from drupal:9.0.0. The staging directory was renamed to sync.', + 'LOCALE_PLURAL_DELIMITER' => 'Deprecated in drupal:8.0.0 and is removed from drupal:9.0.0. Use Drupal\Component\Gettext\PoItem::DELIMITER instead.', + 'FILE_CHMOD_DIRECTORY' => 'Deprecated in drupal:8.0.0 and is removed from drupal:9.0.0. Use \Drupal\Core\File\FileSystem::CHMOD_DIRECTORY.', + 'FILE_CHMOD_FILE' => 'Deprecated in drupal:8.0.0 and is removed from drupal:9.0.0. Use \Drupal\Core\File\FileSystem::CHMOD_FILE.', + 'FILE_CREATE_DIRECTORY' => 'Deprecated in drupal:8.7.0 and is removed from drupal:9.0.0. Use \Drupal\Core\File\FileSystemInterface::CREATE_DIRECTORY.', + 'FILE_MODIFY_PERMISSIONS' => 'Deprecated in drupal:8.7.0 and is removed from drupal:9.0.0. Use \Drupal\Core\File\FileSystemInterface::MODIFY_PERMISSIONS.', + 'FILE_EXISTS_RENAME' => 'Deprecated in drupal:8.7.0 and is removed from drupal:9.0.0. Use \Drupal\Core\File\FileSystemInterface::EXISTS_RENAME.', + 'FILE_EXISTS_REPLACE' => 'Deprecated in drupal:8.7.0 and is removed from drupal:9.0.0. Use \Drupal\Core\File\FileSystemInterface::EXISTS_REPLACE.', + 'FILE_EXISTS_ERROR' => 'Deprecated in drupal:8.7.0 and is removed from drupal:9.0.0. Use \Drupal\Core\File\FileSystemInterface::EXISTS_ERROR.', + 'AGGREGATOR_CLEAR_NEVER' => 'Deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use \Drupal\aggregator\FeedStorageInterface::CLEAR_NEVER instead.', + 'COMMENT_ANONYMOUS_MAYNOT_CONTACT' => 'Deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use \Drupal\comment\CommentInterface::ANONYMOUS_MAYNOT_CONTACT instead.', + 'COMMENT_ANONYMOUS_MAY_CONTACT' => 'Deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use \Drupal\comment\CommentInterface::ANONYMOUS_MAY_CONTACT instead.', + 'COMMENT_ANONYMOUS_MUST_CONTACT' => 'Deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use \Drupal\comment\CommentInterface::ANONYMOUS_MUST_CONTACT instead.', + 'IMAGE_STORAGE_NORMAL' => 'Deprecated in drupal:8.1.0 and is removed from drupal:9.0.0.', + 'IMAGE_STORAGE_OVERRIDE' => 'Deprecated in drupal:8.1.0 and is removed from drupal:9.0.0.', + 'IMAGE_STORAGE_DEFAULT' => 'Deprecated in drupal:8.1.0 and is removed from drupal:9.0.0.', + 'IMAGE_STORAGE_EDITABLE' => 'Deprecated in drupal:8.1.0 and is removed from drupal:9.0.0.', + 'IMAGE_STORAGE_MODULE' => 'Deprecated in drupal:8.1.0 and is removed from drupal:9.0.0.', + 'MENU_MAX_MENU_NAME_LENGTH_UI' => 'Deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use \Drupal\system\MenuStorage::MAX_ID_LENGTH instead.', + 'NODE_NOT_PUBLISHED' => 'Deprecated in drupal:8.?.? and is removed from drupal:9.0.0. Use \Drupal\node\NodeInterface::NOT_PUBLISHED instead.', + 'NODE_PUBLISHED' => 'Deprecated in drupal:8.?.? and is removed from drupal:9.0.0. Use \Drupal\node\NodeInterface::PUBLISHED instead.', + 'NODE_NOT_PROMOTED' => 'Deprecated in drupal:8.?.? and is removed from drupal:9.0.0. Use \Drupal\node\NodeInterface::NOT_PROMOTED instead.', + 'NODE_PROMOTED' => 'Deprecated in drupal:8.?.? and is removed from drupal:9.0.0. Use \Drupal\node\NodeInterface::PROMOTED instead.', + 'NODE_NOT_STICKY' => 'Deprecated in drupal:8.?.? and is removed from drupal:9.0.0. Use \Drupal\node\NodeInterface::NOT_STICKY instead.', + 'NODE_STICKY' => 'Deprecated in drupal:8.?.? and is removed from drupal:9.0.0. Use \Drupal\node\NodeInterface::STICKY instead.', + 'RESPONSIVE_IMAGE_EMPTY_IMAGE' => 'Deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use Drupal\responsive_image\ResponsiveImageStyleInterface::EMPTY_IMAGE instead.', + 'RESPONSIVE_IMAGE_ORIGINAL_IMAGE' => 'Deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use \Drupal\responsive_image\ResponsiveImageStyleInterface::ORIGINAL_IMAGE instead.', + 'DRUPAL_USER_TIMEZONE_DEFAULT' => 'Deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use \Drupal\user\UserInterface::TIMEZONE_DEFAULT instead.', + 'DRUPAL_USER_TIMEZONE_EMPTY' => 'Deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use \Drupal\user\UserInterface::TIMEZONE_EMPTY instead.', + 'DRUPAL_USER_TIMEZONE_SELECT' => 'Deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use \Drupal\user\UserInterface::TIMEZONE_SELECT instead.', + 'TAXONOMY_HIERARCHY_DISABLED' => 'Deprecated in drupal:8.2.0 and is removed from drupal:9.0.0. Use \Drupal\taxonomy\VocabularyInterface::HIERARCHY_DISABLED instead.', + 'TAXONOMY_HIERARCHY_SINGLE' => 'Deprecated in drupal:8.2.0 and is removed from drupal:9.0.0. Use \Drupal\taxonomy\VocabularyInterface::HIERARCHY_SINGLE instead.', + 'TAXONOMY_HIERARCHY_MULTIPLE' => 'Deprecated in drupal:8.2.0 and is removed from drupal:9.0.0. Use \Drupal\taxonomy\VocabularyInterface::HIERARCHY_MULTIPLE instead.', + 'UPDATE_NOT_SECURE' => 'Deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use \Drupal\update\UpdateManagerInterface::NOT_SECURE instead.', + 'UPDATE_REVOKED' => 'Deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use \Drupal\update\UpdateManagerInterface::REVOKED instead.', + 'UPDATE_NOT_SUPPORTED' => 'Deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use \Drupal\update\UpdateManagerInterface::NOT_SUPPORTED instead.', + 'UPDATE_NOT_CURRENT' => 'Deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use \Drupal\update\UpdateManagerInterface::NOT_CURRENT instead.', + 'UPDATE_CURRENT' => 'Deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use \Drupal\update\UpdateManagerInterface::CURRENT instead.', + 'UPDATE_NOT_CHECKED' => 'Deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use \Drupal\update\UpdateFetcherInterface::NOT_CHECKED instead.', + 'UPDATE_UNKNOWN' => 'Deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use \Drupal\update\UpdateFetcherInterface::UNKNOWN instead.', + 'UPDATE_NOT_FETCHED' => 'Deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use \Drupal\update\UpdateFetcherInterface::NOT_FETCHED instead.', + 'UPDATE_FETCH_PENDING' => 'Deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use \Drupal\update\UpdateFetcherInterface::FETCH_PENDING instead.', + 'USERNAME_MAX_LENGTH' => 'Deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use \Drupal\user\UserInterface::USERNAME_MAX_LENGTH instead.', + 'USER_REGISTER_ADMINISTRATORS_ONLY' => 'Deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use \Drupal\user\UserInterface::REGISTER_ADMINISTRATORS_ONLY instead.', + 'USER_REGISTER_VISITORS' => 'Deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use \Drupal\user\UserInterface::REGISTER_VISITORS instead.', + 'USER_REGISTER_VISITORS_ADMINISTRATIVE_APPROVAL' => 'Deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use \Drupal\user\UserInterface::REGISTER_VISITORS_ADMINISTRATIVE_APPROVAL instead.', + ]; + [$major, $minor] = explode('.', Drupal::VERSION, 3); + if ($major === '9') { + if ((int) $minor >= 1) { + $deprecatedConstants = array_merge($deprecatedConstants, [ + 'DRUPAL_MINIMUM_PHP' => 'Deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. Use \Drupal::MINIMUM_PHP instead.', + 'DRUPAL_MINIMUM_PHP_MEMORY_LIMIT' => 'Deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. Use \Drupal::MINIMUM_PHP_MEMORY_LIMIT instead.', + 'DRUPAL_MINIMUM_SUPPORTED_PHP' => 'Deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. Use \Drupal::MINIMUM_SUPPORTED_PHP instead.', + 'DRUPAL_RECOMMENDED_PHP' => 'Deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. Use \Drupal::RECOMMENDED_PHP instead.', + 'PREG_CLASS_CJK' => 'Deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. Use \Drupal\search\SearchTextProcessorInterface::PREG_CLASS_CJK instead.', + 'PREG_CLASS_NUMBERS' => 'Deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. Use \Drupal\search\SearchTextProcessorInterface::PREG_CLASS_NUMBERS', + 'PREG_CLASS_PUNCTUATION' => 'Deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. Use \Drupal\search\SearchTextProcessorInterface::PREG_CLASS_PUNCTUATION', + ]); + } + if ((int) $minor >= 2) { + $deprecatedConstants = array_merge($deprecatedConstants, [ + 'FILE_INSECURE_EXTENSION_REGEX' => 'Deprecated in drupal:9.2.0 and is removed from drupal:10.0.0. Use \Drupal\Core\File\FileSystemInterface::INSECURE_EXTENSION_REGEX.', + ]); + } + if ((int) $minor >= 3) { + $deprecatedConstants = array_merge($deprecatedConstants, [ + 'FILE_STATUS_PERMANENT' => 'Deprecated in drupal:9.3.0 and is removed from drupal:10.0.0. Use \Drupal\file\FileInterface::STATUS_PERMANENT or \Drupal\file\FileInterface::setPermanent().', + 'SCHEMA_UNINSTALLED' => 'Deprecated in drupal:9.3.0 and is removed from drupal:10.0.0. Use \Drupal\Core\Update\UpdateHookRegistry::SCHEMA_UNINSTALLED', + ]); + } + } + + $constantName = $this->reflectionProvider->resolveConstantName($node->name, $scope); + if (isset($deprecatedConstants[$constantName])) { + return [ + RuleErrorBuilder::message( + sprintf('Call to deprecated constant %s: %s', $constantName, $deprecatedConstants[$constantName]) + ) + ->identifier("accessDeprecatedConstant.deprecatedConstantCalled") + ->build() + ]; + } + return []; + } +} diff --git a/tests/src/Rules/AccessDeprecatedConstantTest.php b/tests/src/Rules/AccessDeprecatedConstantTest.php new file mode 100644 index 00000000..2ca14b79 --- /dev/null +++ b/tests/src/Rules/AccessDeprecatedConstantTest.php @@ -0,0 +1,44 @@ + + */ +final class AccessDeprecatedConstantTest extends DrupalRuleTestCase +{ + + protected function getRule(): \PHPStan\Rules\Rule + { + return new AccessDeprecatedConstant($this->createReflectionProvider()); + } + + public function testRule(): void + { + [$version] = explode('.', \Drupal::VERSION, 2); + if ($version !== '9') { + self::markTestSkipped('Only tested on Drupal 9.x.x'); + } + + $this->analyse( + [__DIR__ . '/../../fixtures/drupal/modules/phpstan_fixtures/phpstan_fixtures.module'], + [ + [ + 'Call to deprecated constant SCHEMA_UNINSTALLED: Deprecated in drupal:9.3.0 and is removed from drupal:10.0.0. Use \Drupal\Core\Update\UpdateHookRegistry::SCHEMA_UNINSTALLED', + 47 + ], + [ + 'Call to deprecated constant FILE_INSECURE_EXTENSION_REGEX: Deprecated in drupal:9.2.0 and is removed from drupal:10.0.0. Use \Drupal\Core\File\FileSystemInterface::INSECURE_EXTENSION_REGEX.', + 48 + ], + [ + 'Call to deprecated constant PREG_CLASS_PUNCTUATION: Deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. Use \Drupal\search\SearchTextProcessorInterface::PREG_CLASS_PUNCTUATION', + 49 + ], + ], + ); + } +} From 005d2fed80911c252b82b19fb4601e0b8bb313b5 Mon Sep 17 00:00:00 2001 From: Frank Ebbers Date: Fri, 15 Nov 2024 08:42:43 +0100 Subject: [PATCH 06/21] Reapply "{Rules} Drop AccessDeprecatedConstantTest, and \mglaman\PHPStanDrupal\Rules\Deprecations\AccessDeprecatedConstant" This reverts commit 181a5dfb6e4d4dab7202d305968d0d230e9ee5a2. --- .../Deprecations/AccessDeprecatedConstant.php | 137 ------------------ .../Rules/AccessDeprecatedConstantTest.php | 44 ------ 2 files changed, 181 deletions(-) delete mode 100644 src/Rules/Deprecations/AccessDeprecatedConstant.php delete mode 100644 tests/src/Rules/AccessDeprecatedConstantTest.php diff --git a/src/Rules/Deprecations/AccessDeprecatedConstant.php b/src/Rules/Deprecations/AccessDeprecatedConstant.php deleted file mode 100644 index e47661b3..00000000 --- a/src/Rules/Deprecations/AccessDeprecatedConstant.php +++ /dev/null @@ -1,137 +0,0 @@ - - */ -class AccessDeprecatedConstant implements Rule -{ - /** @var ReflectionProvider */ - private $reflectionProvider; - public function __construct(ReflectionProvider $reflectionProvider) - { - $this->reflectionProvider = $reflectionProvider; - } - - public function getNodeType(): string - { - return Node\Expr\ConstFetch::class; - } - - public function processNode(Node $node, Scope $scope): array - { - if (DeprecatedScopeCheck::inDeprecatedScope($scope)) { - return []; - } - - // nikic/php-parser does not let us access phpdoc comments from deprecated constants, so - // here goes a list of hardcoded core constants. List is available at - // https://api.drupal.org/api/drupal/deprecated/8.9.x?order=object_type&sort=asc&page=5 - $deprecatedConstants = [ - 'DATETIME_STORAGE_TIMEZONE' => 'Deprecated in drupal:8.5.0 and is removed from drupal:9.0.0. Use \Drupal\datetime\Plugin\Field\FieldType\DateTimeItemInterface::STORAGE_TIMEZONE instead.', - 'DATETIME_DATETIME_STORAGE_FORMAT' => 'Deprecated in drupal:8.5.0 and is removed from drupal:9.0.0. Use \Drupal\datetime\Plugin\Field\FieldType\DateTimeItemInterface::DATETIME_STORAGE_FORMAT instead.', - 'DATETIME_DATE_STORAGE_FORMAT' => 'Deprecated in drupal:8.5.0 and is removed from drupal:9.0.0. Use \Drupal\datetime\Plugin\Field\FieldType\DateTimeItemInterface::DATE_STORAGE_FORMAT instead.', - 'DRUPAL_ANONYMOUS_RID' => 'Deprecated in drupal:8.0.0 and is removed from drupal:9.0.0. Use Drupal\Core\Session\AccountInterface::ANONYMOUS_ROLE or \Drupal\user\RoleInterface::ANONYMOUS_ID instead.', - 'DRUPAL_AUTHENTICATED_RID' => 'Deprecated in drupal:8.0.0 and is removed from drupal:9.0.0. Use Drupal\Core\Session\AccountInterface::AUTHENTICATED_ROLE or \Drupal\user\RoleInterface::AUTHENTICATED_ID instead.', - 'REQUEST_TIME' => 'Deprecated in drupal:8.3.0 and is removed from drupal:11.0.0. Use \Drupal::time()->getRequestTime(); ', - 'DRUPAL_PHP_FUNCTION_PATTERN' => 'Deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use \Drupal\Core\Extension\ExtensionDiscovery::PHP_FUNCTION_PATTERN instead.', - 'CONFIG_ACTIVE_DIRECTORY' => 'Deprecated in drupal:8.0.0 and is removed from drupal:9.0.0. Drupal core no longer creates an active directory.', - 'CONFIG_SYNC_DIRECTORY' => 'Deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use \Drupal\Core\Site\Settings::get(\'config_sync_directory\') instead.', - 'CONFIG_STAGING_DIRECTORY' => 'Deprecated in drupal:8.0.0 and is removed from drupal:9.0.0. The staging directory was renamed to sync.', - 'LOCALE_PLURAL_DELIMITER' => 'Deprecated in drupal:8.0.0 and is removed from drupal:9.0.0. Use Drupal\Component\Gettext\PoItem::DELIMITER instead.', - 'FILE_CHMOD_DIRECTORY' => 'Deprecated in drupal:8.0.0 and is removed from drupal:9.0.0. Use \Drupal\Core\File\FileSystem::CHMOD_DIRECTORY.', - 'FILE_CHMOD_FILE' => 'Deprecated in drupal:8.0.0 and is removed from drupal:9.0.0. Use \Drupal\Core\File\FileSystem::CHMOD_FILE.', - 'FILE_CREATE_DIRECTORY' => 'Deprecated in drupal:8.7.0 and is removed from drupal:9.0.0. Use \Drupal\Core\File\FileSystemInterface::CREATE_DIRECTORY.', - 'FILE_MODIFY_PERMISSIONS' => 'Deprecated in drupal:8.7.0 and is removed from drupal:9.0.0. Use \Drupal\Core\File\FileSystemInterface::MODIFY_PERMISSIONS.', - 'FILE_EXISTS_RENAME' => 'Deprecated in drupal:8.7.0 and is removed from drupal:9.0.0. Use \Drupal\Core\File\FileSystemInterface::EXISTS_RENAME.', - 'FILE_EXISTS_REPLACE' => 'Deprecated in drupal:8.7.0 and is removed from drupal:9.0.0. Use \Drupal\Core\File\FileSystemInterface::EXISTS_REPLACE.', - 'FILE_EXISTS_ERROR' => 'Deprecated in drupal:8.7.0 and is removed from drupal:9.0.0. Use \Drupal\Core\File\FileSystemInterface::EXISTS_ERROR.', - 'AGGREGATOR_CLEAR_NEVER' => 'Deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use \Drupal\aggregator\FeedStorageInterface::CLEAR_NEVER instead.', - 'COMMENT_ANONYMOUS_MAYNOT_CONTACT' => 'Deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use \Drupal\comment\CommentInterface::ANONYMOUS_MAYNOT_CONTACT instead.', - 'COMMENT_ANONYMOUS_MAY_CONTACT' => 'Deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use \Drupal\comment\CommentInterface::ANONYMOUS_MAY_CONTACT instead.', - 'COMMENT_ANONYMOUS_MUST_CONTACT' => 'Deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use \Drupal\comment\CommentInterface::ANONYMOUS_MUST_CONTACT instead.', - 'IMAGE_STORAGE_NORMAL' => 'Deprecated in drupal:8.1.0 and is removed from drupal:9.0.0.', - 'IMAGE_STORAGE_OVERRIDE' => 'Deprecated in drupal:8.1.0 and is removed from drupal:9.0.0.', - 'IMAGE_STORAGE_DEFAULT' => 'Deprecated in drupal:8.1.0 and is removed from drupal:9.0.0.', - 'IMAGE_STORAGE_EDITABLE' => 'Deprecated in drupal:8.1.0 and is removed from drupal:9.0.0.', - 'IMAGE_STORAGE_MODULE' => 'Deprecated in drupal:8.1.0 and is removed from drupal:9.0.0.', - 'MENU_MAX_MENU_NAME_LENGTH_UI' => 'Deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use \Drupal\system\MenuStorage::MAX_ID_LENGTH instead.', - 'NODE_NOT_PUBLISHED' => 'Deprecated in drupal:8.?.? and is removed from drupal:9.0.0. Use \Drupal\node\NodeInterface::NOT_PUBLISHED instead.', - 'NODE_PUBLISHED' => 'Deprecated in drupal:8.?.? and is removed from drupal:9.0.0. Use \Drupal\node\NodeInterface::PUBLISHED instead.', - 'NODE_NOT_PROMOTED' => 'Deprecated in drupal:8.?.? and is removed from drupal:9.0.0. Use \Drupal\node\NodeInterface::NOT_PROMOTED instead.', - 'NODE_PROMOTED' => 'Deprecated in drupal:8.?.? and is removed from drupal:9.0.0. Use \Drupal\node\NodeInterface::PROMOTED instead.', - 'NODE_NOT_STICKY' => 'Deprecated in drupal:8.?.? and is removed from drupal:9.0.0. Use \Drupal\node\NodeInterface::NOT_STICKY instead.', - 'NODE_STICKY' => 'Deprecated in drupal:8.?.? and is removed from drupal:9.0.0. Use \Drupal\node\NodeInterface::STICKY instead.', - 'RESPONSIVE_IMAGE_EMPTY_IMAGE' => 'Deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use Drupal\responsive_image\ResponsiveImageStyleInterface::EMPTY_IMAGE instead.', - 'RESPONSIVE_IMAGE_ORIGINAL_IMAGE' => 'Deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use \Drupal\responsive_image\ResponsiveImageStyleInterface::ORIGINAL_IMAGE instead.', - 'DRUPAL_USER_TIMEZONE_DEFAULT' => 'Deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use \Drupal\user\UserInterface::TIMEZONE_DEFAULT instead.', - 'DRUPAL_USER_TIMEZONE_EMPTY' => 'Deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use \Drupal\user\UserInterface::TIMEZONE_EMPTY instead.', - 'DRUPAL_USER_TIMEZONE_SELECT' => 'Deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use \Drupal\user\UserInterface::TIMEZONE_SELECT instead.', - 'TAXONOMY_HIERARCHY_DISABLED' => 'Deprecated in drupal:8.2.0 and is removed from drupal:9.0.0. Use \Drupal\taxonomy\VocabularyInterface::HIERARCHY_DISABLED instead.', - 'TAXONOMY_HIERARCHY_SINGLE' => 'Deprecated in drupal:8.2.0 and is removed from drupal:9.0.0. Use \Drupal\taxonomy\VocabularyInterface::HIERARCHY_SINGLE instead.', - 'TAXONOMY_HIERARCHY_MULTIPLE' => 'Deprecated in drupal:8.2.0 and is removed from drupal:9.0.0. Use \Drupal\taxonomy\VocabularyInterface::HIERARCHY_MULTIPLE instead.', - 'UPDATE_NOT_SECURE' => 'Deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use \Drupal\update\UpdateManagerInterface::NOT_SECURE instead.', - 'UPDATE_REVOKED' => 'Deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use \Drupal\update\UpdateManagerInterface::REVOKED instead.', - 'UPDATE_NOT_SUPPORTED' => 'Deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use \Drupal\update\UpdateManagerInterface::NOT_SUPPORTED instead.', - 'UPDATE_NOT_CURRENT' => 'Deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use \Drupal\update\UpdateManagerInterface::NOT_CURRENT instead.', - 'UPDATE_CURRENT' => 'Deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use \Drupal\update\UpdateManagerInterface::CURRENT instead.', - 'UPDATE_NOT_CHECKED' => 'Deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use \Drupal\update\UpdateFetcherInterface::NOT_CHECKED instead.', - 'UPDATE_UNKNOWN' => 'Deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use \Drupal\update\UpdateFetcherInterface::UNKNOWN instead.', - 'UPDATE_NOT_FETCHED' => 'Deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use \Drupal\update\UpdateFetcherInterface::NOT_FETCHED instead.', - 'UPDATE_FETCH_PENDING' => 'Deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use \Drupal\update\UpdateFetcherInterface::FETCH_PENDING instead.', - 'USERNAME_MAX_LENGTH' => 'Deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use \Drupal\user\UserInterface::USERNAME_MAX_LENGTH instead.', - 'USER_REGISTER_ADMINISTRATORS_ONLY' => 'Deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use \Drupal\user\UserInterface::REGISTER_ADMINISTRATORS_ONLY instead.', - 'USER_REGISTER_VISITORS' => 'Deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use \Drupal\user\UserInterface::REGISTER_VISITORS instead.', - 'USER_REGISTER_VISITORS_ADMINISTRATIVE_APPROVAL' => 'Deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use \Drupal\user\UserInterface::REGISTER_VISITORS_ADMINISTRATIVE_APPROVAL instead.', - ]; - [$major, $minor] = explode('.', Drupal::VERSION, 3); - if ($major === '9') { - if ((int) $minor >= 1) { - $deprecatedConstants = array_merge($deprecatedConstants, [ - 'DRUPAL_MINIMUM_PHP' => 'Deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. Use \Drupal::MINIMUM_PHP instead.', - 'DRUPAL_MINIMUM_PHP_MEMORY_LIMIT' => 'Deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. Use \Drupal::MINIMUM_PHP_MEMORY_LIMIT instead.', - 'DRUPAL_MINIMUM_SUPPORTED_PHP' => 'Deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. Use \Drupal::MINIMUM_SUPPORTED_PHP instead.', - 'DRUPAL_RECOMMENDED_PHP' => 'Deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. Use \Drupal::RECOMMENDED_PHP instead.', - 'PREG_CLASS_CJK' => 'Deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. Use \Drupal\search\SearchTextProcessorInterface::PREG_CLASS_CJK instead.', - 'PREG_CLASS_NUMBERS' => 'Deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. Use \Drupal\search\SearchTextProcessorInterface::PREG_CLASS_NUMBERS', - 'PREG_CLASS_PUNCTUATION' => 'Deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. Use \Drupal\search\SearchTextProcessorInterface::PREG_CLASS_PUNCTUATION', - ]); - } - if ((int) $minor >= 2) { - $deprecatedConstants = array_merge($deprecatedConstants, [ - 'FILE_INSECURE_EXTENSION_REGEX' => 'Deprecated in drupal:9.2.0 and is removed from drupal:10.0.0. Use \Drupal\Core\File\FileSystemInterface::INSECURE_EXTENSION_REGEX.', - ]); - } - if ((int) $minor >= 3) { - $deprecatedConstants = array_merge($deprecatedConstants, [ - 'FILE_STATUS_PERMANENT' => 'Deprecated in drupal:9.3.0 and is removed from drupal:10.0.0. Use \Drupal\file\FileInterface::STATUS_PERMANENT or \Drupal\file\FileInterface::setPermanent().', - 'SCHEMA_UNINSTALLED' => 'Deprecated in drupal:9.3.0 and is removed from drupal:10.0.0. Use \Drupal\Core\Update\UpdateHookRegistry::SCHEMA_UNINSTALLED', - ]); - } - } - - $constantName = $this->reflectionProvider->resolveConstantName($node->name, $scope); - if (isset($deprecatedConstants[$constantName])) { - return [ - RuleErrorBuilder::message( - sprintf('Call to deprecated constant %s: %s', $constantName, $deprecatedConstants[$constantName]) - ) - ->identifier("accessDeprecatedConstant.deprecatedConstantCalled") - ->build() - ]; - } - return []; - } -} diff --git a/tests/src/Rules/AccessDeprecatedConstantTest.php b/tests/src/Rules/AccessDeprecatedConstantTest.php deleted file mode 100644 index 2ca14b79..00000000 --- a/tests/src/Rules/AccessDeprecatedConstantTest.php +++ /dev/null @@ -1,44 +0,0 @@ - - */ -final class AccessDeprecatedConstantTest extends DrupalRuleTestCase -{ - - protected function getRule(): \PHPStan\Rules\Rule - { - return new AccessDeprecatedConstant($this->createReflectionProvider()); - } - - public function testRule(): void - { - [$version] = explode('.', \Drupal::VERSION, 2); - if ($version !== '9') { - self::markTestSkipped('Only tested on Drupal 9.x.x'); - } - - $this->analyse( - [__DIR__ . '/../../fixtures/drupal/modules/phpstan_fixtures/phpstan_fixtures.module'], - [ - [ - 'Call to deprecated constant SCHEMA_UNINSTALLED: Deprecated in drupal:9.3.0 and is removed from drupal:10.0.0. Use \Drupal\Core\Update\UpdateHookRegistry::SCHEMA_UNINSTALLED', - 47 - ], - [ - 'Call to deprecated constant FILE_INSECURE_EXTENSION_REGEX: Deprecated in drupal:9.2.0 and is removed from drupal:10.0.0. Use \Drupal\Core\File\FileSystemInterface::INSECURE_EXTENSION_REGEX.', - 48 - ], - [ - 'Call to deprecated constant PREG_CLASS_PUNCTUATION: Deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. Use \Drupal\search\SearchTextProcessorInterface::PREG_CLASS_PUNCTUATION', - 49 - ], - ], - ); - } -} From d1148616cefe440471e14959c16c106df5e9421e Mon Sep 17 00:00:00 2001 From: Frank Ebbers Date: Fri, 15 Nov 2024 08:52:53 +0100 Subject: [PATCH 07/21] {Rules} Drop AccessDeprecatedConstantTest, and \mglaman\PHPStanDrupal\Rules\Deprecations\AccessDeprecatedConstant --- rules.neon | 1 - 1 file changed, 1 deletion(-) diff --git a/rules.neon b/rules.neon index ef7dcc56..40f57f61 100644 --- a/rules.neon +++ b/rules.neon @@ -2,7 +2,6 @@ rules: - mglaman\PHPStanDrupal\Rules\Drupal\Coder\DiscouragedFunctionsRule - mglaman\PHPStanDrupal\Rules\Drupal\GlobalDrupalDependencyInjectionRule - mglaman\PHPStanDrupal\Rules\Drupal\PluginManager\PluginManagerSetsCacheBackendRule - - mglaman\PHPStanDrupal\Rules\Deprecations\AccessDeprecatedConstant - mglaman\PHPStanDrupal\Rules\Deprecations\ConditionManagerCreateInstanceContextConfigurationRule - mglaman\PHPStanDrupal\Rules\Drupal\RenderCallbackRule - mglaman\PHPStanDrupal\Rules\Deprecations\StaticServiceDeprecatedServiceRule From 9a0c2b68d9bc355868a82352330f80db35b0bac1 Mon Sep 17 00:00:00 2001 From: Frank Ebbers Date: Fri, 15 Nov 2024 09:03:34 +0100 Subject: [PATCH 08/21] {Rules} Drop \mglaman\PHPStanDrupal\Tests\Rules\ClassExtendsInternalClassRuleTest::testRule ContentEntityDeleteForm test case and dependencies --- .../src/Form/ExtendsContentEntityDeleteForm.php | 9 --------- .../Rules/ClassExtendsInternalClassRuleTest.php | 15 --------------- 2 files changed, 24 deletions(-) delete mode 100644 tests/fixtures/drupal/modules/phpstan_fixtures/src/Form/ExtendsContentEntityDeleteForm.php diff --git a/tests/fixtures/drupal/modules/phpstan_fixtures/src/Form/ExtendsContentEntityDeleteForm.php b/tests/fixtures/drupal/modules/phpstan_fixtures/src/Form/ExtendsContentEntityDeleteForm.php deleted file mode 100644 index 6187fa57..00000000 --- a/tests/fixtures/drupal/modules/phpstan_fixtures/src/Form/ExtendsContentEntityDeleteForm.php +++ /dev/null @@ -1,9 +0,0 @@ -= '10' || ($version === '9' && (int) $minor >= 4)) - && $path === __DIR__ . '/../../fixtures/drupal/modules/phpstan_fixtures/src/Form/ExtendsContentEntityDeleteForm.php') { - self::markTestSkipped('@internal was removed in 10.0.x and 9.4.x'); - } $this->analyse([$path], $errorMessages); } @@ -128,16 +123,6 @@ public static function pluginData(): \Generator __DIR__ . '/../../fixtures/drupal/modules/phpstan_fixtures/src/Internal/ExtendsPHPStanDrupalModuleWithInternalClassesExternalClass.php', [], ]; - yield 'tip for ContentEntityDeleteForm' => [ - __DIR__ . '/../../fixtures/drupal/modules/phpstan_fixtures/src/Form/ExtendsContentEntityDeleteForm.php', - [ - [ - 'Class Drupal\phpstan_fixtures\Form\ExtendsContentEntityDeleteForm extends @internal class Drupal\Core\Entity\ContentEntityDeleteForm.', - 7, - 'Extend \Drupal\Core\Entity\ContentEntityConfirmFormBase. See https://www.drupal.org/node/2491057' - ] - ], - ]; } private static function cleanDrupalCoreStubs(): void { From c3da1083ab2b5155c0633b2e030a8e25119a2935 Mon Sep 17 00:00:00 2001 From: Frank Ebbers Date: Fri, 15 Nov 2024 09:06:46 +0100 Subject: [PATCH 09/21] [HACK]] Temporarily remove core_baseline test --- .github/workflows/php.yml | 54 --------------------------------------- 1 file changed, 54 deletions(-) diff --git a/.github/workflows/php.yml b/.github/workflows/php.yml index ab3774b2..7515fb60 100644 --- a/.github/workflows/php.yml +++ b/.github/workflows/php.yml @@ -191,57 +191,3 @@ jobs: run: | cd ~/drupal ./vendor/bin/phpstan analyze web/core/modules/dynamic_page_cache --debug - - core_baseline: - needs: - - lint - - tests - continue-on-error: true - runs-on: "ubuntu-latest" - name: "Drupal core HEAD baseline check" - steps: - - name: "Checkout" - uses: "actions/checkout@v4" - - name: "set the version alias for self" - run: | - if [ "${{ github.event_name }}" == 'pull_request' ]; then - echo "VERSION_ALIAS=dev-"${{ github.sha }}"" >> $GITHUB_OUTPUT - else - echo "VERSION_ALIAS=dev-main" >> $GITHUB_OUTPUT - fi - id: branch_alias - - name: determine phpstan cache directory - run: echo PHPSTAN_TMP_DIR=$(php -r "print sys_get_temp_dir() . '/phpstan';") >> $GITHUB_OUTPUT - id: phpstan_tmp_dir - - name: cache phpstan - uses: actions/cache@v4 - with: - path: ${{ steps.phpstan_tmp_dir.outputs.PHPSTAN_TMP_DIR }} - key: ${{ runner.os }}-phpstan-core-baseline - restore-keys: ${{ runner.os }}-phpstan-core-baseline - - name: "Install PHP" - uses: "shivammathur/setup-php@v2" - with: - coverage: "none" - php-version: "8.3" - tools: composer:v2 - extensions: dom, curl, libxml, mbstring, zip, pdo, mysql, pdo_mysql, gd, apcu - - name: "Checkout Drupal core" - run: | - cd ${{ runner.temp }} - git clone https://git.drupalcode.org/project/drupal.git - cd drupal - composer config repositories.0 composer https://packages.drupal.org/8 - composer config repositories.1 path $GITHUB_WORKSPACE - - name: "Install Drupal core dependencies" - uses: "ramsey/composer-install@v3" - with: - working-directory: "${{ runner.temp }}/drupal" - - name: "require phpstan-drupal" - run: | - cd ${{ runner.temp }}/drupal - composer require drupal/core-dev "phpstan/phpstan:^2.0" "phpstan/phpstan-phpunit:^2.0" mglaman/phpstan-drupal "${{ steps.branch_alias.outputs.VERSION_ALIAS }} as 2.99.99" phpstan/extension-installer --with-all-dependencies - - name: "Check baseline" - run: | - cd ${{ runner.temp }}/drupal - ./vendor/bin/phpstan analyze --configuration=core/phpstan.neon.dist From 8cd30d39db777324f2b8fcc489e6a1c35cade826 Mon Sep 17 00:00:00 2001 From: Frank Ebbers Date: Fri, 15 Nov 2024 09:12:26 +0100 Subject: [PATCH 10/21] {Rules} Drop AccessDeprecatedConstantTest, \mglaman\PHPStanDrupal\Rules\Deprecations\AccessDeprecatedConstant and dependencies --- .../drupal/modules/phpstan_fixtures/phpstan_fixtures.module | 6 ------ 1 file changed, 6 deletions(-) diff --git a/tests/fixtures/drupal/modules/phpstan_fixtures/phpstan_fixtures.module b/tests/fixtures/drupal/modules/phpstan_fixtures/phpstan_fixtures.module index 528944d9..ee5ab5af 100644 --- a/tests/fixtures/drupal/modules/phpstan_fixtures/phpstan_fixtures.module +++ b/tests/fixtures/drupal/modules/phpstan_fixtures/phpstan_fixtures.module @@ -43,12 +43,6 @@ function phpstan_fixtures_thing_with_anonymous_class(): void { }; } -function phpstan_fixtures_using_deprecated_constants(): void { - print SCHEMA_UNINSTALLED; - print FILE_INSECURE_EXTENSION_REGEX; - print PREG_CLASS_PUNCTUATION; -} - function phpstan_fixtures_condition_manager_context(): void { $condition_manager = \Drupal::service('plugin.manager.condition'); $configuration = [ From fd49bded5662c89535344ff4ac3cddba8930bd47 Mon Sep 17 00:00:00 2001 From: Frank Ebbers Date: Fri, 15 Nov 2024 09:16:36 +0100 Subject: [PATCH 11/21] {Rules} Drop ConditionManagerCreateInstanceContextConfigurationRuleTest and its rule and related stuff 'n things --- phpstan-baseline.neon | 10 --- rules.neon | 1 - ...CreateInstanceContextConfigurationRule.php | 62 ------------------- .../phpstan_fixtures/phpstan_fixtures.module | 11 ---- ...teInstanceContextConfigurationRuleTest.php | 31 ---------- 5 files changed, 115 deletions(-) delete mode 100644 src/Rules/Deprecations/ConditionManagerCreateInstanceContextConfigurationRule.php delete mode 100644 tests/src/Rules/ConditionManagerCreateInstanceContextConfigurationRuleTest.php diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 6f99c653..a8ddb750 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -34,16 +34,6 @@ parameters: count: 1 path: src/Drupal/DrupalAutoloader.php - - - message: "#^Doing instanceof PHPStan\\\\Type\\\\Constant\\\\ConstantArrayType is error\\-prone and deprecated\\. Use Type\\:\\:getConstantArrays\\(\\) instead\\.$#" - count: 1 - path: src/Rules/Deprecations/ConditionManagerCreateInstanceContextConfigurationRule.php - - - - message: "#^Doing instanceof PHPStan\\\\Type\\\\Constant\\\\ConstantStringType is error\\-prone and deprecated\\. Use Type\\:\\:getConstantStrings\\(\\) instead\\.$#" - count: 1 - path: src/Rules/Deprecations/ConditionManagerCreateInstanceContextConfigurationRule.php - - message: "#^Doing instanceof PHPStan\\\\Type\\\\Constant\\\\ConstantStringType is error\\-prone and deprecated\\. Use Type\\:\\:getConstantStrings\\(\\) instead\\.$#" count: 2 diff --git a/rules.neon b/rules.neon index 40f57f61..db830f11 100644 --- a/rules.neon +++ b/rules.neon @@ -2,7 +2,6 @@ rules: - mglaman\PHPStanDrupal\Rules\Drupal\Coder\DiscouragedFunctionsRule - mglaman\PHPStanDrupal\Rules\Drupal\GlobalDrupalDependencyInjectionRule - mglaman\PHPStanDrupal\Rules\Drupal\PluginManager\PluginManagerSetsCacheBackendRule - - mglaman\PHPStanDrupal\Rules\Deprecations\ConditionManagerCreateInstanceContextConfigurationRule - mglaman\PHPStanDrupal\Rules\Drupal\RenderCallbackRule - mglaman\PHPStanDrupal\Rules\Deprecations\StaticServiceDeprecatedServiceRule - mglaman\PHPStanDrupal\Rules\Deprecations\GetDeprecatedServiceRule diff --git a/src/Rules/Deprecations/ConditionManagerCreateInstanceContextConfigurationRule.php b/src/Rules/Deprecations/ConditionManagerCreateInstanceContextConfigurationRule.php deleted file mode 100644 index 0d037092..00000000 --- a/src/Rules/Deprecations/ConditionManagerCreateInstanceContextConfigurationRule.php +++ /dev/null @@ -1,62 +0,0 @@ - - */ -final class ConditionManagerCreateInstanceContextConfigurationRule implements Rule -{ - public function getNodeType(): string - { - return Node\Expr\MethodCall::class; - } - - public function processNode(Node $node, Scope $scope): array - { - if (!$node->name instanceof Node\Identifier) { - return []; - } - if ($node->name->toString() !== 'createInstance') { - return []; - } - $args = $node->getArgs(); - if (count($args) !== 2) { - return []; - } - $conditionManagerType = new ObjectType(ConditionManager::class); - $type = $scope->getType($node->var); - if (!$conditionManagerType->isSuperTypeOf($type)->yes()) { - return []; - } - $configuration = $args[1]; - $configurationType = $scope->getType($configuration->value); - // Must be an array, return [] and allow parameter inspection rule to report error. - if (!$configurationType instanceof ConstantArrayType) { - return []; - } - - foreach ($configurationType->getKeyTypes() as $keyType) { - if ($keyType instanceof ConstantStringType && $keyType->getValue() === 'context') { - return [ - RuleErrorBuilder::message('Passing context values to plugins via configuration is deprecated in drupal:9.1.0 and will be removed before drupal:10.0.0. Instead, call ::setContextValue() on the plugin itself. See https://www.drupal.org/node/3120980') - ->line($node->getStartLine()) - ->identifier("conditionManagerCreateInstanceContextConfiguration.callSetContextValue") - ->build() - ]; - } - } - - return []; - } -} diff --git a/tests/fixtures/drupal/modules/phpstan_fixtures/phpstan_fixtures.module b/tests/fixtures/drupal/modules/phpstan_fixtures/phpstan_fixtures.module index ee5ab5af..5db81e09 100644 --- a/tests/fixtures/drupal/modules/phpstan_fixtures/phpstan_fixtures.module +++ b/tests/fixtures/drupal/modules/phpstan_fixtures/phpstan_fixtures.module @@ -42,14 +42,3 @@ function phpstan_fixtures_thing_with_anonymous_class(): void { } }; } - -function phpstan_fixtures_condition_manager_context(): void { - $condition_manager = \Drupal::service('plugin.manager.condition'); - $configuration = [ - 'foo' => 'bar', - 'context' => [ - 'entity:type' => 'node', - ], - ]; - $foo = $condition_manager->createInstance('barbaz', $configuration); -} diff --git a/tests/src/Rules/ConditionManagerCreateInstanceContextConfigurationRuleTest.php b/tests/src/Rules/ConditionManagerCreateInstanceContextConfigurationRuleTest.php deleted file mode 100644 index 91075800..00000000 --- a/tests/src/Rules/ConditionManagerCreateInstanceContextConfigurationRuleTest.php +++ /dev/null @@ -1,31 +0,0 @@ -analyse( - [__DIR__ . '/../../fixtures/drupal/modules/phpstan_fixtures/phpstan_fixtures.module'], - [ - [ - 'Passing context values to plugins via configuration is deprecated in drupal:9.1.0 and will be removed before drupal:10.0.0. Instead, call ::setContextValue() on the plugin itself. See https://www.drupal.org/node/3120980', - 60, - ] - ], - ); - } -} From a8c72367276cda9663def9763cfaacce9efac23f Mon Sep 17 00:00:00 2001 From: Frank Ebbers Date: Fri, 15 Nov 2024 09:31:50 +0100 Subject: [PATCH 12/21] {Rules} Drop \mglaman\PHPStanDrupal\Tests\Rules\DeprecatedHookImplementationTest::testRule test for deprecated_field_widget_hooks_field_widget_form_alter and related stuff 'n things --- .../DeprecatedHookImplementation.php | 16 ---------------- .../Rules/DeprecatedHookImplementationTest.php | 15 --------------- .../data/deprecated_field_widget_hooks.module | 11 ----------- 3 files changed, 42 deletions(-) delete mode 100644 tests/src/Rules/data/deprecated_field_widget_hooks.module diff --git a/src/Rules/Deprecations/DeprecatedHookImplementation.php b/src/Rules/Deprecations/DeprecatedHookImplementation.php index 561eb66c..c14be6a8 100644 --- a/src/Rules/Deprecations/DeprecatedHookImplementation.php +++ b/src/Rules/Deprecations/DeprecatedHookImplementation.php @@ -52,22 +52,6 @@ public function processNode(Node $node, Scope $scope) : array $hook_name_node = new Name($hook_name); if (!$this->reflectionProvider->hasFunction($hook_name_node, $scope)) { // @todo replace this hardcoded logic with something more intelligent and extensible. - if ($hook_name === 'hook_field_widget_form_alter') { - return $this->buildError( - $function_name, - $hook_name, - 'useHookFieldWidgetSingleElementFormAlter', - 'in drupal:9.2.0 and is removed from drupal:10.0.0. Use hook_field_widget_single_element_form_alter instead.' - ); - } - if (str_starts_with($hook_name, 'hook_field_widget_') && str_ends_with($hook_name, '_form_alter')) { - return $this->buildError( - $function_name, - 'hook_field_widget_WIDGET_TYPE_form_alter', - 'useHookFieldWidgetWidgetTypeFormAlter', - 'in drupal:9.2.0 and is removed from drupal:10.0.0. Use hook_field_widget_single_element_WIDGET_TYPE_form_alter instead.' - ); - } if ($hook_name === 'hook_field_widget_multivalue_form_alter') { return $this->buildError( $function_name, diff --git a/tests/src/Rules/DeprecatedHookImplementationTest.php b/tests/src/Rules/DeprecatedHookImplementationTest.php index 989e24f2..0d0312ec 100644 --- a/tests/src/Rules/DeprecatedHookImplementationTest.php +++ b/tests/src/Rules/DeprecatedHookImplementationTest.php @@ -35,21 +35,6 @@ public function testRule() : void { 5, ], ]); - [$version] = explode('.', \Drupal::VERSION, 2); - if ($version === '9') { - $this->analyse([__DIR__ . '/data/deprecated_field_widget_hooks.module'], - [ - [ - 'Function deprecated_field_widget_hooks_field_widget_form_alter implements hook_field_widget_form_alter which is deprecated in drupal:9.2.0 and is removed from drupal:10.0.0. Use - hook_field_widget_single_element_form_alter instead.', - 5 - ], - [ - 'Function deprecated_field_widget_hooks_field_widget_textfield_form_alter implements hook_field_widget_WIDGET_TYPE_form_alter which is deprecated in drupal:9.2.0 and is removed from drupal:10.0.0. Use hook_field_widget_single_element_WIDGET_TYPE_form_alter instead.', - 9 - ] - ]); - } } } diff --git a/tests/src/Rules/data/deprecated_field_widget_hooks.module b/tests/src/Rules/data/deprecated_field_widget_hooks.module deleted file mode 100644 index a10c52ef..00000000 --- a/tests/src/Rules/data/deprecated_field_widget_hooks.module +++ /dev/null @@ -1,11 +0,0 @@ - Date: Fri, 15 Nov 2024 11:39:04 +0100 Subject: [PATCH 13/21] {Rules} Drop \mglaman\PHPStanDrupal\Tests\Rules\GetDeprecatedServiceRuleTest::testRuleDrupal8 and \mglaman\PHPStanDrupal\Tests\Rules\GetDeprecatedServiceRuleTest::testRuleDrupal9 and related stuff 'n things --- .../phpstan_fixtures/phpstan_fixtures.module | 5 -- .../EntityManagerInjectedController.php | 32 ------- .../Block/EntityManagerInjectedBlock.php | 46 ---------- .../Rules/GetDeprecatedServiceRuleTest.php | 90 ------------------- 4 files changed, 173 deletions(-) delete mode 100644 tests/fixtures/drupal/modules/phpstan_fixtures/src/Controller/EntityManagerInjectedController.php delete mode 100644 tests/fixtures/drupal/modules/phpstan_fixtures/src/Plugin/Block/EntityManagerInjectedBlock.php delete mode 100644 tests/src/Rules/GetDeprecatedServiceRuleTest.php diff --git a/tests/fixtures/drupal/modules/phpstan_fixtures/phpstan_fixtures.module b/tests/fixtures/drupal/modules/phpstan_fixtures/phpstan_fixtures.module index 5db81e09..e47dba05 100644 --- a/tests/fixtures/drupal/modules/phpstan_fixtures/phpstan_fixtures.module +++ b/tests/fixtures/drupal/modules/phpstan_fixtures/phpstan_fixtures.module @@ -14,11 +14,6 @@ function phpstan_fixtures_MissingReturnRule(): string { } -function phpstan_fixtures_get_app_root(): string { - $app_root = \Drupal::getContainer()->get('app.root'); - return $app_root . '/core/includes/install.inc'; -} - function phpstan_fixtures_module_load_includes_test(): array { $module_handler = \Drupal::moduleHandler(); $module_handler->loadInclude('locale', 'fetch.inc'); diff --git a/tests/fixtures/drupal/modules/phpstan_fixtures/src/Controller/EntityManagerInjectedController.php b/tests/fixtures/drupal/modules/phpstan_fixtures/src/Controller/EntityManagerInjectedController.php deleted file mode 100644 index 4dae8034..00000000 --- a/tests/fixtures/drupal/modules/phpstan_fixtures/src/Controller/EntityManagerInjectedController.php +++ /dev/null @@ -1,32 +0,0 @@ -entityManager = $entity_manager; - } - - public static function create(ContainerInterface $container) - { - return new self( - $container->get('entity.manager') - ); - } - - public function handle() { - $storage = $this->entityManager->getStorage('node'); - return []; - } -} diff --git a/tests/fixtures/drupal/modules/phpstan_fixtures/src/Plugin/Block/EntityManagerInjectedBlock.php b/tests/fixtures/drupal/modules/phpstan_fixtures/src/Plugin/Block/EntityManagerInjectedBlock.php deleted file mode 100644 index d2aaff31..00000000 --- a/tests/fixtures/drupal/modules/phpstan_fixtures/src/Plugin/Block/EntityManagerInjectedBlock.php +++ /dev/null @@ -1,46 +0,0 @@ -entityManager = $entity_manager; - } - - /** - * {@inheritdoc} - */ - public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { - return new static( - $configuration, - $plugin_id, - $plugin_definition, - $container->get('entity.manager') - ); - } - - public function build() - { - $storage = $this->entityManager->getStorage('node'); - return []; - } -} diff --git a/tests/src/Rules/GetDeprecatedServiceRuleTest.php b/tests/src/Rules/GetDeprecatedServiceRuleTest.php deleted file mode 100644 index 4c7c82d9..00000000 --- a/tests/src/Rules/GetDeprecatedServiceRuleTest.php +++ /dev/null @@ -1,90 +0,0 @@ -getByType(ServiceMap::class) - ); - } - - /** - * @dataProvider drupal8Data - * - * @param list $errorMessages - */ - public function testRuleDrupal8(string $path, array $errorMessages): void - { - if (version_compare('9.0.0', \Drupal::VERSION) !== 1) { - self::markTestSkipped('Only tested on Drupal 8.x.x'); - } - $this->analyse([$path], $errorMessages); - } - - /** - * @dataProvider drupal9Data - * - * @param list $errorMessages - */ - public function testRuleDrupal9(string $path, array $errorMessages): void - { - [$version] = explode('.', \Drupal::VERSION, 2); - if ($version !== '9') { - self::markTestSkipped('Only tested on Drupal 9.x.x'); - } - $this->analyse([$path], $errorMessages); - } - - public static function drupal8Data(): \Generator - { - yield [ - __DIR__ . '/../../fixtures/drupal/modules/phpstan_fixtures/src/Plugin/Block/EntityManagerInjectedBlock.php', - [ - [ - 'The "entity.manager" service is deprecated. You should use the \'entity_type.manager\' service instead.', - 37 - ], - ] - ]; - yield [ - __DIR__ . '/../../fixtures/drupal/modules/phpstan_fixtures/src/Controller/EntityManagerInjectedController.php', - [ - [ - 'The "entity.manager" service is deprecated. You should use the \'entity_type.manager\' service instead.', - 24 - ], - ] - ]; - } - - public static function drupal9Data(): \Generator - { - yield [ - __DIR__ . '/../../fixtures/drupal/modules/phpstan_fixtures/phpstan_fixtures.module', - [ - [ - 'The "app.root" service is deprecated in drupal:9.0.0 and is removed from drupal:10.0.0. Use the app.root parameter instead. See https://www.drupal.org/node/3080612', - 18 - ], - ] - ]; - yield [ - __DIR__ . '/../../fixtures/drupal/modules/phpstan_fixtures/src/AppRootParameter.php', - [ - [ - 'The "app.root" service is deprecated in drupal:9.0.0 and is removed from drupal:10.0.0. Use the app.root parameter instead. See https://www.drupal.org/node/3080612', - 17 - ], - ] - ]; - } - - -} From 740166867485246734b6132354d111cc0a649909 Mon Sep 17 00:00:00 2001 From: Frank Ebbers Date: Fri, 15 Nov 2024 11:43:27 +0100 Subject: [PATCH 14/21] [Rule Tests] Adjust linenumber --- tests/src/Rules/LoadIncludesRuleTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/src/Rules/LoadIncludesRuleTest.php b/tests/src/Rules/LoadIncludesRuleTest.php index 2323c47d..5f7ca0fd 100644 --- a/tests/src/Rules/LoadIncludesRuleTest.php +++ b/tests/src/Rules/LoadIncludesRuleTest.php @@ -31,7 +31,7 @@ public static function cases(): \Generator [ [ 'File modules/phpstan_fixtures/phpstan_fixtures.fetch.inc could not be loaded from Drupal\Core\Extension\ModuleHandlerInterface::loadInclude', - 30 + 25, ] ], ]; From 185922c0d252093d0dfe54fdbd5044aebcecd88a Mon Sep 17 00:00:00 2001 From: Frank Ebbers Date: Fri, 15 Nov 2024 11:48:07 +0100 Subject: [PATCH 15/21] {Rules} \mglaman\PHPStanDrupal\Tests\Rules\RequestStackGetMainRequestRuleTest::testRule and the rule and related stuff 'n things --- .../Drupal/RequestStackGetMainRequestRule.php | 61 ------------------- .../RequestStackGetMainRequestRuleTest.php | 43 ------------- tests/src/Rules/data/request-stack.php | 34 ----------- 3 files changed, 138 deletions(-) delete mode 100644 src/Rules/Drupal/RequestStackGetMainRequestRule.php delete mode 100644 tests/src/Rules/RequestStackGetMainRequestRuleTest.php delete mode 100644 tests/src/Rules/data/request-stack.php diff --git a/src/Rules/Drupal/RequestStackGetMainRequestRule.php b/src/Rules/Drupal/RequestStackGetMainRequestRule.php deleted file mode 100644 index 2f8d9734..00000000 --- a/src/Rules/Drupal/RequestStackGetMainRequestRule.php +++ /dev/null @@ -1,61 +0,0 @@ - - */ -final class RequestStackGetMainRequestRule implements Rule -{ - - public function getNodeType(): string - { - return Node\Expr\MethodCall::class; - } - - public function processNode(Node $node, Scope $scope): array - { - if (DeprecatedScopeCheck::inDeprecatedScope($scope)) { - return []; - } - [$major, $minor] = explode('.', Drupal::VERSION, 3); - // Only valid for 9.3 -> 9.5. Deprecated in Drupal 10. - if (($major !== '9' || (int) $minor < 3)) { - return []; - } - if (!$node->name instanceof Node\Identifier) { - return []; - } - $method_name = $node->name->toString(); - if ($method_name !== 'getMasterRequest') { - return []; - } - $type = $scope->getType($node->var); - $symfonyRequestStackType = new ObjectType(SymfonyRequestStack::class); - if ($symfonyRequestStackType->isSuperTypeOf($type)->yes()) { - $message = sprintf( - '%s::getMasterRequest() is deprecated in drupal:9.3.0 and is removed from drupal:10.0.0 for Symfony 6 compatibility. Use the forward compatibility shim class %s and its getMainRequest() method instead.', - SymfonyRequestStack::class, - 'Drupal\Core\Http\RequestStack' - ); - return [ - RuleErrorBuilder::message($message) - ->tip('Change record: https://www.drupal.org/node/3253744') - ->identifier('deprecated.getMasterRequest') - ->build(), - ]; - } - return []; - } -} diff --git a/tests/src/Rules/RequestStackGetMainRequestRuleTest.php b/tests/src/Rules/RequestStackGetMainRequestRuleTest.php deleted file mode 100644 index c76f1f0b..00000000 --- a/tests/src/Rules/RequestStackGetMainRequestRuleTest.php +++ /dev/null @@ -1,43 +0,0 @@ -analyse([__DIR__.'/data/request-stack.php'], []); - } elseif ($version >= '10') { - self::markTestSkipped('Not tested on 10.x.x or higher'); - } else { - $this->analyse( - [__DIR__.'/data/request-stack.php'], - [ - [ - 'Symfony\Component\HttpFoundation\RequestStack::getMasterRequest() is deprecated in drupal:9.3.0 and is removed from drupal:10.0.0 for Symfony 6 compatibility. Use the forward compatibility shim class Drupal\Core\Http\RequestStack and its getMainRequest() method instead.', - 17, - 'Change record: https://www.drupal.org/node/3253744', - ], - [ - 'Symfony\Component\HttpFoundation\RequestStack::getMasterRequest() is deprecated in drupal:9.3.0 and is removed from drupal:10.0.0 for Symfony 6 compatibility. Use the forward compatibility shim class Drupal\Core\Http\RequestStack and its getMainRequest() method instead.', - 29, - 'Change record: https://www.drupal.org/node/3253744', - ], - ] - ); - } - } - -} diff --git a/tests/src/Rules/data/request-stack.php b/tests/src/Rules/data/request-stack.php deleted file mode 100644 index fe24f8c0..00000000 --- a/tests/src/Rules/data/request-stack.php +++ /dev/null @@ -1,34 +0,0 @@ -getStack()->getMasterRequest(); - } -} -class Bar { - public function __construct(\Drupal\Core\Http\RequestStack $stack) - { - } - public function getStack(): \Drupal\Core\Http\RequestStack - { - return new \Drupal\Core\Http\RequestStack(); - } - public function a(): ?Request { - return $this->getStack()->getMasterRequest(); - } - public function b(): ?Request { - return $this->getStack()->getMainRequest(); - } -} From 23f907e41a5b9b997a76dd90e176500b15a94fe5 Mon Sep 17 00:00:00 2001 From: Frank Ebbers Date: Fri, 15 Nov 2024 11:50:27 +0100 Subject: [PATCH 16/21] {Rules} \mglaman\PHPStanDrupal\Tests\Rules\RequestStackGetMainRequestRuleTest::testRule and the rule and related stuff 'n things --- rules.neon | 1 - 1 file changed, 1 deletion(-) diff --git a/rules.neon b/rules.neon index db830f11..f2d0823b 100644 --- a/rules.neon +++ b/rules.neon @@ -13,7 +13,6 @@ rules: - mglaman\PHPStanDrupal\Rules\Drupal\EntityQuery\EntityQueryHasAccessCheckRule - mglaman\PHPStanDrupal\Rules\Deprecations\SymfonyCmfRouteObjectInterfaceConstantsRule - mglaman\PHPStanDrupal\Rules\Deprecations\SymfonyCmfRoutingInClassMethodSignatureRule - - mglaman\PHPStanDrupal\Rules\Drupal\RequestStackGetMainRequestRule - mglaman\PHPStanDrupal\Rules\Drupal\TestClassesProtectedPropertyModulesRule conditionalTags: From bfbf95de7f0f4a7ac7e3e311c6e7b20f08c1de8f Mon Sep 17 00:00:00 2001 From: Frank Ebbers Date: Fri, 15 Nov 2024 11:56:36 +0100 Subject: [PATCH 17/21] {Rules} Dropped \mglaman\PHPStanDrupal\Tests\Rules\SymfonyCmfRouteObjectInterfaceConstantsRuleTest::testRule and the rule, \mglaman\PHPStanDrupal\Tests\Rules\SymfonyCmfRoutingInClassMethodSignatureRuleTest::testRule and the rule, and related stuff 'n things --- rules.neon | 2 - ...nyCmfRouteObjectInterfaceConstantsRule.php | 77 ---------- ...nyCmfRoutingInClassMethodSignatureRule.php | 144 ------------------ ...fRouteObjectInterfaceConstantsRuleTest.php | 53 ------- ...fRoutingInClassMethodSignatureRuleTest.php | 53 ------- tests/src/Rules/data/symfony-cmf-routing.php | 39 ----- 6 files changed, 368 deletions(-) delete mode 100644 src/Rules/Deprecations/SymfonyCmfRouteObjectInterfaceConstantsRule.php delete mode 100644 src/Rules/Deprecations/SymfonyCmfRoutingInClassMethodSignatureRule.php delete mode 100644 tests/src/Rules/SymfonyCmfRouteObjectInterfaceConstantsRuleTest.php delete mode 100644 tests/src/Rules/SymfonyCmfRoutingInClassMethodSignatureRuleTest.php delete mode 100644 tests/src/Rules/data/symfony-cmf-routing.php diff --git a/rules.neon b/rules.neon index f2d0823b..34f4b3b6 100644 --- a/rules.neon +++ b/rules.neon @@ -11,8 +11,6 @@ rules: - mglaman\PHPStanDrupal\Rules\Drupal\ModuleLoadInclude - mglaman\PHPStanDrupal\Rules\Drupal\LoadIncludes - mglaman\PHPStanDrupal\Rules\Drupal\EntityQuery\EntityQueryHasAccessCheckRule - - mglaman\PHPStanDrupal\Rules\Deprecations\SymfonyCmfRouteObjectInterfaceConstantsRule - - mglaman\PHPStanDrupal\Rules\Deprecations\SymfonyCmfRoutingInClassMethodSignatureRule - mglaman\PHPStanDrupal\Rules\Drupal\TestClassesProtectedPropertyModulesRule conditionalTags: diff --git a/src/Rules/Deprecations/SymfonyCmfRouteObjectInterfaceConstantsRule.php b/src/Rules/Deprecations/SymfonyCmfRouteObjectInterfaceConstantsRule.php deleted file mode 100644 index 20a28bb4..00000000 --- a/src/Rules/Deprecations/SymfonyCmfRouteObjectInterfaceConstantsRule.php +++ /dev/null @@ -1,77 +0,0 @@ - - */ -final class SymfonyCmfRouteObjectInterfaceConstantsRule implements Rule -{ - - public function getNodeType(): string - { - return Node\Expr\ClassConstFetch::class; - } - - public function processNode(Node $node, Scope $scope): array - { - if (!$node->name instanceof Node\Identifier) { - return []; - } - if (!$node->class instanceof Node\Name) { - return []; - } - $constantName = $node->name->name; - $className = $node->class; - $classType = $scope->resolveTypeByName($className); - if (!$classType->hasConstant($constantName)->yes()) { - return []; - } - if (DeprecatedScopeCheck::inDeprecatedScope($scope)) { - return []; - } - [$major, $minor] = explode('.', Drupal::VERSION, 3); - if ($major !== '9') { - return []; - } - if ((int) $minor < 1) { - return []; - } - - // @phpstan-ignore-next-line - $cmfRouteObjectInterfaceType = new ObjectType(SymfonyRouteObjectInterface::class); - if (!$classType->isSuperTypeOf($cmfRouteObjectInterfaceType)->yes()) { - return []; - } - - $coreRouteObjectInterfaceType = new ObjectType(RouteObjectInterface::class); - if (!$coreRouteObjectInterfaceType->hasConstant($constantName)->yes()) { - return [ - RuleErrorBuilder::message( - sprintf('The core dependency symfony-cmf/routing is deprecated and %s::%s is not supported.', $className, $constantName) - )->tip('Change record: https://www.drupal.org/node/3151009') - ->identifier('symfonyCmfRouteObjectInterfaceConstants.deprecated') - ->build(), - ]; - } - - return [ - RuleErrorBuilder::message( - sprintf('%s::%s is deprecated and removed in Drupal 10. Use \Drupal\Core\Routing\RouteObjectInterface::%2$s instead.', $className, $constantName) - )->tip('Change record: https://www.drupal.org/node/3151009') - ->identifier('symfonyCmfRouteObjectInterfaceConstants.useRouteObjectInterface') - ->build(), - ]; - } -} diff --git a/src/Rules/Deprecations/SymfonyCmfRoutingInClassMethodSignatureRule.php b/src/Rules/Deprecations/SymfonyCmfRoutingInClassMethodSignatureRule.php deleted file mode 100644 index 16981c53..00000000 --- a/src/Rules/Deprecations/SymfonyCmfRoutingInClassMethodSignatureRule.php +++ /dev/null @@ -1,144 +0,0 @@ - - */ -final class SymfonyCmfRoutingInClassMethodSignatureRule implements Rule -{ - - public function getNodeType(): string - { - return InClassMethodNode::class; - } - - public function processNode(Node $node, Scope $scope): array - { - if (DeprecatedScopeCheck::inDeprecatedScope($scope)) { - return []; - } - [$major, $minor] = explode('.', Drupal::VERSION, 3); - if ($major !== '9' || (int) $minor < 1) { - return []; - } - $method = $node->getMethodReflection(); - - // @phpstan-ignore-next-line - $cmfRouteObjectInterfaceType = new ObjectType(RouteObjectInterface::class); - // @phpstan-ignore-next-line - $cmfRouteProviderInterfaceType = new ObjectType(RouteProviderInterface::class); - // @phpstan-ignore-next-line - $cmfLazyRouteCollectionType = new ObjectType(LazyRouteCollection::class); - - $methodSignature = ParametersAcceptorSelector::selectFromArgs( - $scope, - [], - $method->getVariants() - ); - - $errors = []; - $errorMessage = 'Parameter $%s of method %s() uses deprecated %s and removed in Drupal 10. Use %s instead.'; - foreach ($methodSignature->getParameters() as $parameter) { - foreach ($parameter->getType()->getReferencedClasses() as $referencedClass) { - $referencedClassType = new ObjectType($referencedClass); - if ($cmfRouteObjectInterfaceType->equals($referencedClassType)) { - $errors[] = RuleErrorBuilder::message( - sprintf( - $errorMessage, - $parameter->getName(), - $method->getName(), - $referencedClass, - '\Drupal\Core\Routing\RouteObjectInterface' - ) - )->tip('Change record: https://www.drupal.org/node/3151009') - ->identifier('symfonyCmfRoutingInClassMethodSignature.useRouteObjectInterface') - ->build(); - } elseif ($cmfRouteProviderInterfaceType->equals($referencedClassType)) { - $errors[] = RuleErrorBuilder::message( - sprintf( - $errorMessage, - $parameter->getName(), - $method->getName(), - $referencedClass, - '\Drupal\Core\Routing\RouteProviderInterface' - ) - )->tip('Change record: https://www.drupal.org/node/3151009') - ->identifier('symfonyCmfRoutingInClassMethodSignature.useRouteProviderInterface') - ->build(); - } elseif ($cmfLazyRouteCollectionType->equals($referencedClassType)) { - $errors[] = RuleErrorBuilder::message( - sprintf( - $errorMessage, - $parameter->getName(), - $method->getName(), - $referencedClass, - '\Drupal\Core\Routing\LazyRouteCollection' - ) - )->tip('Change record: https://www.drupal.org/node/3151009') - ->identifier('symfonyCmfRoutingInClassMethodSignature.useLazyRouteCollection') - ->build(); - } - } - } - - $errorMessage = 'Return type of method %s::%s() has typehint with deprecated %s and is removed in Drupal 10. Use %s instead.'; - $returnClasses = $methodSignature->getReturnType()->getReferencedClasses(); - foreach ($returnClasses as $returnClass) { - $returnType = new ObjectType($returnClass); - if ($cmfRouteObjectInterfaceType->equals($returnType)) { - $errors[] = RuleErrorBuilder::message( - sprintf( - $errorMessage, - $method->getDeclaringClass()->getName(), - $method->getName(), - $returnClass, - '\Drupal\Core\Routing\RouteObjectInterface' - ) - )->tip('Change record: https://www.drupal.org/node/3151009') - ->identifier('symfonyCmfRoutingInClassMethodSignature.typehintUseRouteObjectInterface') - ->build(); - } elseif ($cmfRouteProviderInterfaceType->equals($returnType)) { - $errors[] = RuleErrorBuilder::message( - sprintf( - $errorMessage, - $method->getDeclaringClass()->getName(), - $method->getName(), - $returnClass, - '\Drupal\Core\Routing\RouteProviderInterface' - ) - )->tip('Change record: https://www.drupal.org/node/3151009') - ->identifier('symfonyCmfRoutingInClassMethodSignature.typehintUseRouteProviderInterface') - ->build(); - } elseif ($cmfLazyRouteCollectionType->equals($returnType)) { - $errors[] = RuleErrorBuilder::message( - sprintf( - $errorMessage, - $method->getDeclaringClass()->getName(), - $method->getName(), - $returnClass, - '\Drupal\Core\Routing\LazyRouteCollection' - ) - )->tip('Change record: https://www.drupal.org/node/3151009') - ->identifier('symfonyCmfRoutingInClassMethodSignature.typehintUseLazyRouteCollection') - ->build(); - } - } - return $errors; - } -} diff --git a/tests/src/Rules/SymfonyCmfRouteObjectInterfaceConstantsRuleTest.php b/tests/src/Rules/SymfonyCmfRouteObjectInterfaceConstantsRuleTest.php deleted file mode 100644 index 59ba554c..00000000 --- a/tests/src/Rules/SymfonyCmfRouteObjectInterfaceConstantsRuleTest.php +++ /dev/null @@ -1,53 +0,0 @@ -analyse([__DIR__.'/data/symfony-cmf-routing.php'], []); - } elseif ($version >= '10') { - self::markTestSkipped('Not tested on 10.x.x or higher'); - } else { - $this->analyse( - [__DIR__.'/data/symfony-cmf-routing.php'], - [ - [ - 'Symfony\Cmf\Component\Routing\RouteObjectInterface::ROUTE_NAME is deprecated and removed in Drupal 10. Use \Drupal\Core\Routing\RouteObjectInterface::ROUTE_NAME instead.', - 6, - 'Change record: https://www.drupal.org/node/3151009' - ], - [ - 'Symfony\Cmf\Component\Routing\RouteObjectInterface::ROUTE_OBJECT is deprecated and removed in Drupal 10. Use \Drupal\Core\Routing\RouteObjectInterface::ROUTE_OBJECT instead.', - 7, - 'Change record: https://www.drupal.org/node/3151009' - ], - [ - 'Symfony\Cmf\Component\Routing\RouteObjectInterface::CONTROLLER_NAME is deprecated and removed in Drupal 10. Use \Drupal\Core\Routing\RouteObjectInterface::CONTROLLER_NAME instead.', - 8, - 'Change record: https://www.drupal.org/node/3151009' - ], - [ - 'The core dependency symfony-cmf/routing is deprecated and Symfony\Cmf\Component\Routing\RouteObjectInterface::TEMPLATE_NAME is not supported.', - 9, - 'Change record: https://www.drupal.org/node/3151009' - ], - ] - ); - } - } - -} diff --git a/tests/src/Rules/SymfonyCmfRoutingInClassMethodSignatureRuleTest.php b/tests/src/Rules/SymfonyCmfRoutingInClassMethodSignatureRuleTest.php deleted file mode 100644 index 239a1a44..00000000 --- a/tests/src/Rules/SymfonyCmfRoutingInClassMethodSignatureRuleTest.php +++ /dev/null @@ -1,53 +0,0 @@ -analyse([__DIR__.'/data/symfony-cmf-routing.php'], []); - } elseif ($version >= '10') { - self::markTestSkipped('Not tested on 10.x.x or higher'); - } else { - $this->analyse( - [__DIR__.'/data/symfony-cmf-routing.php'], - [ - [ - 'Parameter $object of method a() uses deprecated Symfony\Cmf\Component\Routing\RouteObjectInterface and removed in Drupal 10. Use \Drupal\Core\Routing\RouteObjectInterface instead.', - 10, - 'Change record: https://www.drupal.org/node/3151009' - ], - [ - 'Parameter $provider of method b() uses deprecated Symfony\Cmf\Component\Routing\RouteProviderInterface and removed in Drupal 10. Use \Drupal\Core\Routing\RouteProviderInterface instead.', - 13, - 'Change record: https://www.drupal.org/node/3151009' - ], - [ - 'Return type of method SymfonyCmfRoutingUsage\Foo::b() has typehint with deprecated Symfony\Cmf\Component\Routing\RouteObjectInterface and is removed in Drupal 10. Use \Drupal\Core\Routing\RouteObjectInterface instead.', - 13, - 'Change record: https://www.drupal.org/node/3151009' - ], - [ - 'Parameter $collection of method c() uses deprecated Symfony\Cmf\Component\Routing\LazyRouteCollection and removed in Drupal 10. Use \Drupal\Core\Routing\LazyRouteCollection instead.', - 16, - 'Change record: https://www.drupal.org/node/3151009' - ], - ] - ); - } - } - -} diff --git a/tests/src/Rules/data/symfony-cmf-routing.php b/tests/src/Rules/data/symfony-cmf-routing.php deleted file mode 100644 index c1e98c47..00000000 --- a/tests/src/Rules/data/symfony-cmf-routing.php +++ /dev/null @@ -1,39 +0,0 @@ - Date: Fri, 15 Nov 2024 11:59:55 +0100 Subject: [PATCH 18/21] [Tests] Cleanup --- tests/src/DeprecatedScope/DeprecationHelperScopeTest.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/src/DeprecatedScope/DeprecationHelperScopeTest.php b/tests/src/DeprecatedScope/DeprecationHelperScopeTest.php index 1afcb547..7290c2ce 100644 --- a/tests/src/DeprecatedScope/DeprecationHelperScopeTest.php +++ b/tests/src/DeprecatedScope/DeprecationHelperScopeTest.php @@ -24,9 +24,6 @@ protected function getRule(): Rule public function testCustomScope(): void { [$version] = explode('.', \Drupal::VERSION, 2); - if ($version < '10') { - self::markTestSkipped('Not tested on < Drupal 10'); - } require_once __DIR__ . '/data/deprecated-data-definition.php'; $this->analyse( [__DIR__ . '/data/deprecation-helper-test.php'], From 3cafcbca80487cbddde4450dde52fa8f8541a348 Mon Sep 17 00:00:00 2001 From: Frank Ebbers Date: Fri, 15 Nov 2024 12:01:59 +0100 Subject: [PATCH 19/21] Revert "[HACK]] Temporarily remove core_baseline test" This reverts commit c3da1083ab2b5155c0633b2e030a8e25119a2935. --- .github/workflows/php.yml | 54 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/.github/workflows/php.yml b/.github/workflows/php.yml index 7515fb60..ab3774b2 100644 --- a/.github/workflows/php.yml +++ b/.github/workflows/php.yml @@ -191,3 +191,57 @@ jobs: run: | cd ~/drupal ./vendor/bin/phpstan analyze web/core/modules/dynamic_page_cache --debug + + core_baseline: + needs: + - lint + - tests + continue-on-error: true + runs-on: "ubuntu-latest" + name: "Drupal core HEAD baseline check" + steps: + - name: "Checkout" + uses: "actions/checkout@v4" + - name: "set the version alias for self" + run: | + if [ "${{ github.event_name }}" == 'pull_request' ]; then + echo "VERSION_ALIAS=dev-"${{ github.sha }}"" >> $GITHUB_OUTPUT + else + echo "VERSION_ALIAS=dev-main" >> $GITHUB_OUTPUT + fi + id: branch_alias + - name: determine phpstan cache directory + run: echo PHPSTAN_TMP_DIR=$(php -r "print sys_get_temp_dir() . '/phpstan';") >> $GITHUB_OUTPUT + id: phpstan_tmp_dir + - name: cache phpstan + uses: actions/cache@v4 + with: + path: ${{ steps.phpstan_tmp_dir.outputs.PHPSTAN_TMP_DIR }} + key: ${{ runner.os }}-phpstan-core-baseline + restore-keys: ${{ runner.os }}-phpstan-core-baseline + - name: "Install PHP" + uses: "shivammathur/setup-php@v2" + with: + coverage: "none" + php-version: "8.3" + tools: composer:v2 + extensions: dom, curl, libxml, mbstring, zip, pdo, mysql, pdo_mysql, gd, apcu + - name: "Checkout Drupal core" + run: | + cd ${{ runner.temp }} + git clone https://git.drupalcode.org/project/drupal.git + cd drupal + composer config repositories.0 composer https://packages.drupal.org/8 + composer config repositories.1 path $GITHUB_WORKSPACE + - name: "Install Drupal core dependencies" + uses: "ramsey/composer-install@v3" + with: + working-directory: "${{ runner.temp }}/drupal" + - name: "require phpstan-drupal" + run: | + cd ${{ runner.temp }}/drupal + composer require drupal/core-dev "phpstan/phpstan:^2.0" "phpstan/phpstan-phpunit:^2.0" mglaman/phpstan-drupal "${{ steps.branch_alias.outputs.VERSION_ALIAS }} as 2.99.99" phpstan/extension-installer --with-all-dependencies + - name: "Check baseline" + run: | + cd ${{ runner.temp }}/drupal + ./vendor/bin/phpstan analyze --configuration=core/phpstan.neon.dist From 884ec5ad31779d3ae42f8e56514d1cb765195865 Mon Sep 17 00:00:00 2001 From: Frank Ebbers Date: Fri, 15 Nov 2024 12:10:55 +0100 Subject: [PATCH 20/21] [Composer] Bump dependencies to match core 10.0.0 minimum --- composer.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index c5b7c46e..d93202ae 100644 --- a/composer.json +++ b/composer.json @@ -21,12 +21,12 @@ "behat/mink": "^1.10", "composer/installers": "^1.9", "drupal/core-recommended": "^10", - "drush/drush": "^11 || ^12 || ^13@beta", + "drush/drush": "^11 || ^12 || ^13", "phpstan/extension-installer": "^1.4.3", "phpstan/phpstan-strict-rules": "^2.0", "phpunit/phpunit": "^9 || ^10 || ^11", - "slevomat/coding-standard": "^7.1", - "squizlabs/php_codesniffer": "^3.3", + "slevomat/coding-standard": "^8.6", + "squizlabs/php_codesniffer": "^3.7", "symfony/phpunit-bridge": "^6.2 || ^7.0" }, "minimum-stability": "dev", From f5ed930e13d112d283e4843378b34ab7441920ad Mon Sep 17 00:00:00 2001 From: Frank Ebbers Date: Tue, 19 Nov 2024 16:36:33 +0100 Subject: [PATCH 21/21] Drop CircleCI --- .circleci/config.yml | 148 ----------------------------- .circleci/generate-local-config.sh | 3 - .circleci/run-local-config.sh | 4 - 3 files changed, 155 deletions(-) delete mode 100644 .circleci/config.yml delete mode 100755 .circleci/generate-local-config.sh delete mode 100755 .circleci/run-local-config.sh diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index cba47814..00000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,148 +0,0 @@ -version: 2.1 -defaults: &defaults - docker: - - image: circleci/php:7.4-cli - working_directory: ~/repo -aliases: - - &composer-cache - v4-composer-cache -commands: - start-project: - steps: - - run: sudo apt-get update && sudo apt-get install -y libpng-dev libjpeg62-turbo-dev - - run: - name: Install PHP Extensions - command: sudo docker-php-ext-install gd - - run: - name: Disable Xdebug PHP extension - command: sudo rm /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini - - checkout - - restore_cache: - keys: - - *composer-cache - install-dependencies: - steps: - - run: composer install -n --prefer-dist - - save_cache: - key: *composer-cache - paths: - - ~/.composer/cache - create-drupal-project: - parameters: - project: - type: string - default: 'drupal/recommended-project:^9.0@alpha' - steps: - - run: composer create-project << parameters.project >> /tmp/drupal --no-interaction --prefer-dist --ignore-platform-reqs - - run: composer require zaporylie/composer-drupal-optimizations:^1.1 --dev --working-dir=/tmp/drupal - local-require: - steps: - - run: - name: Add as local - command: | - cd /tmp/drupal - composer require --dev drupal/core-dev:^9.0 - composer config repositories.1 '{"type": "path", "url": "'${CIRCLE_WORKING_DIRECTORY}'", "options": { "symlink": false }}' - composer require --dev mglaman/phpstan-drupal "*" phpstan/extension-installer - cat composer.json - cp ~/repo/tests/fixtures/config/drupal-phpstan.neon /tmp/drupal/phpstan.neon - ./vendor/bin/phpstan --version -jobs: - build: - <<: *defaults - steps: - - start-project - - install-dependencies - - run: - name: phpspec/prophecy-phpunit fix - command: composer require --dev phpspec/prophecy-phpunit:^2 - - run: - name: CodeSniffer - command: ./vendor/bin/phpcs src - - run: - name: PHPStan Analyze - command: php -dmemory_limit=-1 vendor/bin/phpstan.phar - - run: - name: PHPUnit - command: ./vendor/bin/phpunit - test_drupal: - <<: *defaults - steps: - - start-project - - create-drupal-project: - project: 'drupal/legacy-project:^9.0' - - local-require - - run: - name: Run against a file - command: | - cd /tmp/drupal - ./vendor/bin/phpstan analyze core/install.php --debug - - run: - name: Run against a module - command: | - cd /tmp/drupal - ./vendor/bin/phpstan analyze --memory-limit=256M core/modules/dynamic_page_cache --debug - test_drupal_project: - <<: *defaults - steps: - - start-project - - create-drupal-project - - local-require - - run: - name: Run against a file - command: | - cd /tmp/drupal - ./vendor/bin/phpstan analyze web/core/install.php --debug - - run: - name: Run against a module - command: | - cd /tmp/drupal - ./vendor/bin/phpstan analyze --memory-limit=256M web/core/modules/dynamic_page_cache --debug - test_upgrade_status: - <<: *defaults - steps: - - start-project - - create-drupal-project: - project: 'drupal/legacy-project:^9@alpha' - - local-require - # Composer constraints prevent requiring via compser, but this helps test drupalci's phpstan build step as well. - - run: - name: Add upgrade_status - command: | - cd /tmp/drupal - composer require phpstan/phpstan-deprecation-rules drupal/git_deploy - curl -L https://ftp.drupal.org/files/projects/upgrade_status-8.x-1.x-dev.tar.gz | tar -zx -C /tmp/drupal/modules - - run: - name: Start builtin - command: php -S 127.0.0.1:8080 -t /tmp/drupal - background: true - - run: - name: Wait for web server - command: dockerize -wait http://127.0.0.1:8080 -timeout 120s - - run: - name: Upgrade Status PHPUnit - command: | - cp ~/repo/tests/fixtures/config/circleci-phpunit.xml /tmp/drupal/core/phpunit.xml - cd /tmp/drupal - ./vendor/bin/phpunit -c core modules/upgrade_status --debug --stop-on-failure -workflows: - version: 2 - tests: - jobs: - - build - - test_drupal - - test_drupal_project - # - test_upgrade_status - weekly: - triggers: - - schedule: - # Every thursday to run soon after patch and security updates on wednesdays. - cron: "0 0 * * 4" - filters: - branches: - only: - - master - jobs: - - build - - test_drupal - - test_drupal_project diff --git a/.circleci/generate-local-config.sh b/.circleci/generate-local-config.sh deleted file mode 100755 index 204120d9..00000000 --- a/.circleci/generate-local-config.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env bash -# Note: must be run from the root of the project. -circleci config process .circleci/config.yml > .circleci/config_local.yml diff --git a/.circleci/run-local-config.sh b/.circleci/run-local-config.sh deleted file mode 100755 index 5555487a..00000000 --- a/.circleci/run-local-config.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env bash -# Note: must be run from the root of the project. -source .circleci/generate-local-config.sh -circleci local execute --job ${1:-build} --config .circleci/config_local.yml