Skip to content

Commit 8fa713a

Browse files
committed
On rule AddAssociationExistsTableClassRule check if setClassName was called (by visitor class)
1 parent f234c0c commit 8fa713a

File tree

5 files changed

+68
-4
lines changed

5 files changed

+68
-4
lines changed

rules.neon

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ parametersSchema:
1616
])
1717

1818
conditionalTags:
19+
CakeDC\PHPStan\Visitor\AddAssociationSetClassNameVisitor:
20+
phpstan.parser.richParserNodeVisitor: %cakeDC.addAssociationExistsTableClassRule%
1921
CakeDC\PHPStan\Rule\Model\AddAssociationExistsTableClassRule:
2022
phpstan.rules.rule: %cakeDC.addAssociationExistsTableClassRule%
2123
CakeDC\PHPStan\Rule\Model\AddAssociationMatchOptionsTypesRule:
@@ -28,6 +30,8 @@ conditionalTags:
2830
phpstan.rules.rule: %cakeDC.ormSelectQueryFindMatchOptionsTypesRule%
2931

3032
services:
33+
-
34+
class: CakeDC\PHPStan\Visitor\AddAssociationSetClassNameVisitor
3135
-
3236
class: CakeDC\PHPStan\Rule\Model\AddAssociationExistsTableClassRule
3337
-

src/Rule/LoadObjectExistsCakeClassRule.php

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,13 @@ public function processNode(Node $node, Scope $scope): array
6666
return [];
6767
}
6868

69-
$inputClassName = $this->getInputClassName(
70-
$details['alias']->value,
71-
$details['options']
72-
);
69+
$inputClassName = $this->getInputClassNameFromNode($node);
70+
if ($inputClassName === null) {
71+
$inputClassName = $this->getInputClassName(
72+
$details['alias']->value,
73+
$details['options']
74+
);
75+
}
7376
if ($this->getTargetClassName($inputClassName)) {
7477
return [];
7578
}
@@ -130,4 +133,13 @@ abstract protected function getTargetClassName(string $name): ?string;
130133
* @return array{'alias': ?\PhpParser\Node\Arg, 'options': ?\PhpParser\Node\Arg, 'sourceMethods':array<string>}|null
131134
*/
132135
abstract protected function getDetails(string $reference, array $args): ?array;
136+
137+
/**
138+
* @param \PhpParser\Node\Expr\MethodCall $node
139+
* @return string|null
140+
*/
141+
protected function getInputClassNameFromNode(MethodCall $node): ?string
142+
{
143+
return null;
144+
}
133145
}

src/Rule/Model/AddAssociationExistsTableClassRule.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616
use Cake\ORM\AssociationCollection;
1717
use CakeDC\PHPStan\Rule\LoadObjectExistsCakeClassRule;
1818
use CakeDC\PHPStan\Utility\CakeNameRegistry;
19+
use CakeDC\PHPStan\Visitor\AddAssociationSetClassNameVisitor;
20+
use PhpParser\Node\Expr;
21+
use PhpParser\Node\Expr\MethodCall;
1922

2023
class AddAssociationExistsTableClassRule extends LoadObjectExistsCakeClassRule
2124
{
@@ -69,4 +72,17 @@ protected function getDetails(string $reference, array $args): ?array
6972

7073
return null;
7174
}
75+
76+
/**
77+
* @inheritDoc
78+
*/
79+
protected function getInputClassNameFromNode(MethodCall $node): ?string
80+
{
81+
$setClassNameValue = $node->getAttribute(AddAssociationSetClassNameVisitor::ATTRIBUTE_NAME);
82+
if ($setClassNameValue instanceof Expr) {
83+
return $this->parseClassNameFromExprTrait($setClassNameValue);
84+
}
85+
86+
return null;
87+
}
7288
}

tests/TestCase/Rule/Model/AddAssociationExistsTableClassRuleTest.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,22 @@ public function testRule(): void
5454
'Call to Cake\ORM\AssociationCollection::load could not find the class for "PalUsers"',
5555
148,
5656
],
57+
[
58+
'Call to CakeDC\PHPStan\Test\TestCase\Rule\Model\Fake\FailingRuleItemsTable::hasOne could not find the class for "Articles"',
59+
187,
60+
],
61+
[
62+
'Call to CakeDC\PHPStan\Test\TestCase\Rule\Model\Fake\FailingRuleItemsTable::hasOne could not find the class for "SomeArticles"',
63+
191,
64+
],
5765
]);
5866
}
67+
68+
/**
69+
* @inheritDoc
70+
*/
71+
public static function getAdditionalConfigFiles(): array
72+
{
73+
return [__DIR__ . '/../../../../extension.neon'];
74+
}
5975
}

tests/TestCase/Rule/Model/Fake/FailingRuleItemsTable.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,5 +179,21 @@ public function initialize(array $config): void
179179
'targetTable' => TableRegistry::getTableLocator()->get('Articles'),
180180
]);
181181
$this->associations()->load(HasOne::class, 'Notes');
182+
$this->hasOne('BakedArticles', [
183+
'cascadeCallbacks' => true,
184+
'conditions' => ['BakedArticles.baked' => 1],
185+
])->setClassName(VeryCustomize00009ArticlesTable::class);
186+
187+
$this->hasOne('CakeArticles', [
188+
'cascadeCallbacks' => true,
189+
'conditions' => ['CakeArticles.category_id' => 10],
190+
])->setClassName('Articles');
191+
$this->hasOne('CakeArticles')
192+
->setFinder('myFinder')
193+
->setClassName('SomeArticles');
194+
$this->associations()->load(HasOne::class, 'CleanArticles', [
195+
'cascadeCallbacks' => true,
196+
'conditions' => ['CleanArticles.clean' => 1],
197+
])->setClassName(VeryCustomize00009ArticlesTable::class);
182198
}
183199
}

0 commit comments

Comments
 (0)