Skip to content

Commit 4159d1c

Browse files
authored
Merge pull request #62 from CakeDC/feature/improve-disallow-entity-array-access-rule
DisallowEntityArrayAccessRule ignore custom keys
2 parents 75baabb + ec4fe65 commit 4159d1c

File tree

5 files changed

+44
-12
lines changed

5 files changed

+44
-12
lines changed

rules.neon

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ parameters:
55
addBehaviorExistsClassRule: true
66
tableGetMatchOptionsTypesRule: true
77
ormSelectQueryFindMatchOptionsTypesRule: true
8-
disallowEntityArrayAccessRule: false
8+
disallowEntityArrayAccessRule: true
99
getMailerExistsClassRule: true
1010
loadComponentExistsClassRule: true
1111
controllerMethodMustBeUsedRule: true

src/Rule/Model/DisallowEntityArrayAccessRule.php

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,22 @@
66
use Cake\Datasource\EntityInterface;
77
use PhpParser\Node;
88
use PhpParser\Node\Expr\ArrayDimFetch;
9+
use PhpParser\Node\Scalar\String_;
910
use PHPStan\Analyser\Scope;
1011
use PHPStan\Rules\Rule;
1112
use PHPStan\Rules\RuleErrorBuilder;
1213

1314
class DisallowEntityArrayAccessRule implements Rule
1415
{
16+
/**
17+
* @var list<string>
18+
*/
19+
protected array $allowedKeys = [
20+
'_matchingData',
21+
'_joinData',
22+
'_ids',
23+
];
24+
1525
/**
1626
* @inheritDoc
1727
*/
@@ -38,9 +48,13 @@ public function processNode(Node $node, Scope $scope): array
3848
return [];
3949
}
4050

51+
if ($node->dim instanceof String_ && in_array($node->dim->value, $this->allowedKeys, true)) {
52+
return [];
53+
}
54+
4155
return [
4256
RuleErrorBuilder::message(sprintf(
43-
'Array access to entity to %s is not allowed, access as object instead',
57+
'Array access to entity %s is not allowed, access as object instead',
4458
$reflection->getName(),
4559
))
4660
->identifier('cake.entity.arrayAccess')

tests/TestCase/Rule/Model/DisallowEntityArrayAccessRuleTest.php

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,24 +38,28 @@ public function testRule(): void
3838
// each error consists of the asserted error message, and the asserted error file line
3939
$this->analyse([__DIR__ . '/Fake/FailingEntityUseLogic.php'], [
4040
[
41-
'Array access to entity to App\Model\Entity\Note is not allowed, access as object instead',
42-
23, // asserted error line
41+
'Array access to entity App\Model\Entity\Note is not allowed, access as object instead',
42+
24, // asserted error line
4343
],
4444
[
45-
'Array access to entity to App\Model\Entity\Note is not allowed, access as object instead',
46-
24, // asserted error line
45+
'Array access to entity App\Model\Entity\Note is not allowed, access as object instead',
46+
25, // asserted error line
47+
],
48+
[
49+
'Array access to entity App\Model\Entity\Note is not allowed, access as object instead',
50+
27, // asserted error line
4751
],
4852
[
49-
'Array access to entity to Cake\Datasource\EntityInterface is not allowed, access as object instead',
50-
29,
53+
'Array access to entity Cake\Datasource\EntityInterface is not allowed, access as object instead',
54+
36,
5155
],
5256
[
53-
'Array access to entity to App\Model\Entity\User is not allowed, access as object instead',
54-
31, // asserted error line
57+
'Array access to entity App\Model\Entity\User is not allowed, access as object instead',
58+
38, // asserted error line
5559
],
5660
[
57-
'Array access to entity to App\Model\Entity\Note is not allowed, access as object instead',
58-
37, // asserted error line
61+
'Array access to entity App\Model\Entity\Note is not allowed, access as object instead',
62+
44, // asserted error line
5963
],
6064
]);
6165
}

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
namespace CakeDC\PHPStan\Test\TestCase\Rule\Model\Fake;
55

6+
use App\Model\Entity\Note;
67
use Cake\ORM\Locator\LocatorAwareTrait;
78
use SplFixedArray;
89

@@ -23,6 +24,12 @@ public function execute(): array
2324
$note = $entity['note'];
2425
$notable = 'Notable ' . $entity['note'];
2526
$noted = $entity->note;
27+
$note2 = $entity[Note::FIELD_NOTE];
28+
$matching = $entity['_matchingData'];//allowed access to _matchingData
29+
$matchingUser = $entity['_matchingData']['Users'];//allowed access to _matchingData
30+
$joinData = $entity['_joinData'];//allowed access to _matchingData
31+
$joinDataPosts = $entity['_joinData']['Posts'];//allowed access to _matchingData
32+
$ids = $entity['_ids'];//allowed access to _matchingData
2633

2734
//Unknown entity
2835
$unknown = $this->fetchTable('UnknownRecords')->get(20);
@@ -39,6 +46,12 @@ public function execute(): array
3946
'noted' => $noted,
4047
'notable' => $notable,
4148
'date' => $date,
49+
'note2' => $note2,
50+
'matchingData' => $matching,
51+
'matchingUser' => $matchingUser,
52+
'joinData' => $joinData,
53+
'joinDataPosts' => $joinDataPosts,
54+
'ids' => $ids,
4255
];
4356
}
4457
}

tests/test_app/Model/Entity/Note.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,5 @@
1515
*/
1616
class Note extends Entity
1717
{
18+
public const FIELD_NOTE = 'note';
1819
}

0 commit comments

Comments
 (0)