Skip to content

Commit

Permalink
Add NoValueObjectInServiceConstructorRule
Browse files Browse the repository at this point in the history
  • Loading branch information
TomasVotruba committed Dec 16, 2024
1 parent 7beae59 commit 7773cbd
Showing 1 changed file with 69 additions and 0 deletions.
69 changes: 69 additions & 0 deletions src/Rules/NoValueObjectInServiceConstructorRule.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?php

declare(strict_types=1);

namespace Symplify\PHPStanRules\Rules;

use PhpParser\Node;
use PhpParser\Node\Name;
use PhpParser\Node\Stmt\ClassMethod;
use PHPStan\Analyser\Scope;
use PHPStan\Rules\Rule;
use PHPStan\Rules\RuleErrorBuilder;

/**
* @implements Rule<ClassMethod>
*/
final class NoValueObjectInServiceConstructorRule implements Rule
{
public function getNodeType(): string
{
return ClassMethod::class;
}

/**
* @param ClassMethod $node
*/
public function processNode(Node $node, Scope $scope): array
{
if ($node->name->toString() !== '__construct') {
return [];
}

if (! $scope->isInClass()) {
return [];
}

$classReflection = $scope->getClassReflection();

// value objects can accept value objects
if ($this->isValueObject($classReflection->getName())) {
return [];
}

$ruleErrors = [];

foreach ($node->params as $param) {
if (! $param->type instanceof Name) {
continue;
}

$paramType = $param->type->toString();
if (! $this->isValueObject($paramType)) {
continue;
}

$ruleErrors[] = RuleErrorBuilder::message(sprintf(
'Value object "%s" cannot be passed to constructor of a service. Pass it as a method argument instead',
$paramType
))->build();
}

return $ruleErrors;
}

private function isValueObject(string $className): bool
{
return preg_match('#(ValueObject|DataObject|Models)#', $className) === 1;
}
}

0 comments on commit 7773cbd

Please sign in to comment.