Skip to content

Commit 124d6ef

Browse files
mleuteneggersaas-archiproAndrea Sciutto
authored
add: support for dot notations in DataObject Relations (#14) (#21)
* feat: add support for dot notations in DataObject Relations (#14) * feat: add support for dot notations in DataObject Relations * feat: add tests for relationships --------- Co-authored-by: Andrea Sciutto <andrea@archipro.co.nz> * nolog: fix config --------- Co-authored-by: saas-archipro <124836169+saas-archipro@users.noreply.github.com> Co-authored-by: Andrea Sciutto <andrea@archipro.co.nz>
1 parent 84dbc09 commit 124d6ef

File tree

3 files changed

+118
-2
lines changed

3 files changed

+118
-2
lines changed

src/Reflection/MethodClassReflectionExtension.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,8 +147,12 @@ private function createMethods(ClassReflection $classReflection): array
147147
}
148148
}
149149
// Ignore parameters
150-
$type = explode('(', $type, 2);
151-
$type = $type[0];
150+
$type = explode('(', $type, 2)[0];
151+
152+
// Ignore dot notation such as 'MyClass::class.MyField'
153+
$type = explode('.', $type, 2)[0];
154+
155+
152156
$componentMethodClass = new $componentClass($methodName, $classReflection, new ObjectType($type));
153157
$methods[strtolower($methodName)] = $componentMethodClass;
154158
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
3+
namespace Syntro\SilverstripePHPStan\Tests\Reflection;
4+
5+
use MethodClassReflectionReturnTypesNamespace\Team;
6+
use PHPStan\Testing\TypeInferenceTestCase;
7+
use SilverStripe\Core\Config\Config;
8+
9+
class MethodClassReflectionExtensionTest extends TypeInferenceTestCase
10+
{
11+
/**
12+
* @return iterable<mixed>
13+
*/
14+
public function dataFileAsserts(): iterable
15+
{
16+
// path to a file with actual asserts of expected types:
17+
require_once(__DIR__ . '/data/method-class-reflection.php');
18+
yield from $this->gatherAssertTypes(__DIR__ . '/data/method-class-reflection.php');
19+
}
20+
21+
/**
22+
* @dataProvider dataFileAsserts
23+
*/
24+
public function testFileAsserts(
25+
string $assertType,
26+
string $file,
27+
...$args
28+
): void {
29+
$this->assertFileAsserts($assertType, $file, ...$args);
30+
}
31+
32+
public static function getAdditionalConfigFiles(): array
33+
{
34+
// path to your project's phpstan.neon, or extension.neon in case of custom extension packages
35+
return [
36+
__DIR__ . '/../../phpstan.neon'
37+
];
38+
}
39+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
<?php
2+
// @codingStandardsIgnoreStart
3+
namespace MethodClassReflectionReturnTypesNamespace;
4+
5+
// SilverStripe
6+
use SilverStripe\Core\Config\Config;
7+
use SilverStripe\ORM\DataObject;
8+
use Syntro\SilverstripePHPStan\ClassHelper;
9+
use function PHPStan\Testing\assertType;
10+
11+
/**
12+
* setting up relations in the Classes doesn't get picked up
13+
* Need to add to the config manually
14+
* @return void
15+
*/
16+
function initDbRelations() {
17+
Config::modify()->merge(Team::class, 'has_many', [
18+
'Players' => Player::class,
19+
'WinningPlayers' => Player::class . '.WinningTeam'
20+
]);
21+
22+
Config::modify()->merge(Player::class, 'has_one', [
23+
'Team' => Team::class,
24+
'WinningTeam' => Team::class . '.WinningPlayers'
25+
]);
26+
27+
Config::modify()->merge(Coach::class, 'belongs_to', [
28+
'Team' => Team::class,
29+
'WinningTeam' => Team::class . '.WinningCoach',
30+
]);
31+
}
32+
33+
initDbRelations();
34+
35+
class Foo
36+
{
37+
public function doFoo(): void
38+
{
39+
40+
41+
$player = new Player;
42+
// Standard has_one
43+
assertType(Team::class, $player->Team());
44+
// Has one with a custom relation name
45+
assertType(Team::class, $player->WinningTeam());
46+
47+
$team = new Team();
48+
// Standard has_one
49+
assertType( sprintf('%s<%s>', ClassHelper::HasManyList, Player::class), $team->Players());
50+
// Has one with a custom relation name
51+
assertType( sprintf('%s<%s>', ClassHelper::HasManyList, Player::class), $team->WinningPlayers());
52+
53+
$coach = new Coach();
54+
assertType(Team::class, $coach->Team());
55+
// Has one with a custom relation name
56+
assertType(Team::class, $coach->WinningTeam());
57+
die();
58+
}
59+
}
60+
61+
class Team extends DataObject
62+
{
63+
64+
}
65+
66+
class Player extends DataObject
67+
{
68+
}
69+
70+
class Coach extends DataObject
71+
{
72+
}
73+
// @codingStandardsIgnoreEnd

0 commit comments

Comments
 (0)