Skip to main content
Drupal API
User account menu
  • Log in

Breadcrumb

  1. Drupal Core 11.1.x
  2. ClassExtendsInternalClassRule.php

class ClassExtendsInternalClassRule

@implements Rule<Class_>

Hierarchy

  • class \mglaman\PHPStanDrupal\Rules\Classes\ClassExtendsInternalClassRule implements \PHPStan\Rules\Rule

Expanded class hierarchy of ClassExtendsInternalClassRule

File

vendor/mglaman/phpstan-drupal/src/Rules/Classes/ClassExtendsInternalClassRule.php, line 17

Namespace

mglaman\PHPStanDrupal\Rules\Classes
View source
class ClassExtendsInternalClassRule implements Rule {
    
    /**
     * @var ReflectionProvider
     */
    private $reflectionProvider;
    public function __construct(ReflectionProvider $reflectionProvider) {
        $this->reflectionProvider = $reflectionProvider;
    }
    public function getNodeType() : string {
        return Class_::class;
    }
    public function processNode(Node $node, Scope $scope) : array {
        if (!isset($node->extends)) {
            return [];
        }
        $extendedClassName = $node->extends
            ->toString();
        if (!$this->reflectionProvider
            ->hasClass($extendedClassName)) {
            return [];
        }
        $extendedClassReflection = $this->reflectionProvider
            ->getClass($extendedClassName);
        if (!$extendedClassReflection->isInternal()) {
            return [];
        }
        if (!isset($node->namespacedName)) {
            return [
                $this->buildError(null, $extendedClassName)
                    ->build(),
            ];
        }
        $currentClassName = $node->namespacedName
            ->toString();
        if (!NamespaceCheck::isDrupalNamespace($node)) {
            return [
                $this->buildError($currentClassName, $extendedClassName)
                    ->build(),
            ];
        }
        if (NamespaceCheck::isSharedNamespace($node)) {
            return [];
        }
        $errorBuilder = $this->buildError($currentClassName, $extendedClassName);
        if ($extendedClassName === 'Drupal\\Core\\Entity\\ContentEntityDeleteForm') {
            $errorBuilder->tip('Extend \\Drupal\\Core\\Entity\\ContentEntityConfirmFormBase. See https://www.drupal.org/node/2491057');
        }
        elseif ((string) $node->extends
            ->slice(0, 2) === 'Drupal\\Core') {
            $errorBuilder->tip('Read the Drupal core backwards compatibility and internal API policy: https://www.drupal.org/about/core/policies/core-change-policies/drupal-8-and-9-backwards-compatibility-and-internal-api#internal');
        }
        return [
            $errorBuilder->build(),
        ];
    }
    private function buildError(?string $currentClassName, string $extendedClassName) : RuleErrorBuilder {
        return RuleErrorBuilder::message(sprintf('%s extends @internal class %s.', $currentClassName !== null ? sprintf('Class %s', $currentClassName) : 'Anonymous class', $extendedClassName));
    }

}

Members

Title Sort descending Modifiers Object type Summary
ClassExtendsInternalClassRule::$reflectionProvider private property
ClassExtendsInternalClassRule::buildError private function
ClassExtendsInternalClassRule::getNodeType public function
ClassExtendsInternalClassRule::processNode public function
ClassExtendsInternalClassRule::__construct public function

API Navigation

  • Drupal Core 11.1.x
  • Topics
  • Classes
  • Functions
  • Constants
  • Globals
  • Files
  • Namespaces
  • Deprecated
  • Services
RSS feed
Powered by Drupal