Skip to content

Commit a305692

Browse files
committed
Extract inverse values builders into services
1 parent 63c91dd commit a305692

17 files changed

Lines changed: 301 additions & 76 deletions

config/services.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
use Sofascore\PurgatoryBundle\Cache\Configuration\ConfigurationLoader;
99
use Sofascore\PurgatoryBundle\Cache\PropertyResolver\AssociationResolver;
1010
use Sofascore\PurgatoryBundle\Cache\PropertyResolver\EmbeddableResolver;
11+
use Sofascore\PurgatoryBundle\Cache\PropertyResolver\InverseValuesBuilder\CompoundInverseValuesBuilder;
12+
use Sofascore\PurgatoryBundle\Cache\PropertyResolver\InverseValuesBuilder\DynamicInverseValuesBuilder;
13+
use Sofascore\PurgatoryBundle\Cache\PropertyResolver\InverseValuesBuilder\PropertyInverseValuesBuilder;
1114
use Sofascore\PurgatoryBundle\Cache\PropertyResolver\MethodResolver;
1215
use Sofascore\PurgatoryBundle\Cache\PropertyResolver\PropertyResolver;
1316
use Sofascore\PurgatoryBundle\Cache\RouteMetadata\AttributeMetadataProvider;
@@ -93,6 +96,7 @@
9396
->tag('purgatory.subscription_resolver')
9497
->args([
9598
service('property_info.reflection_extractor'),
99+
tagged_locator('purgatory.inverse_values_builder', defaultIndexMethod: 'for'),
96100
])
97101

98102
->set('sofascore.purgatory.subscription_resolver.embeddable', EmbeddableResolver::class)
@@ -101,6 +105,18 @@
101105
service('doctrine'),
102106
])
103107

108+
->set('sofascore.purgatory.inverse_values_builder.compound', CompoundInverseValuesBuilder::class)
109+
->tag('purgatory.inverse_values_builder')
110+
->args([
111+
tagged_locator('purgatory.inverse_values_builder', defaultIndexMethod: 'for'),
112+
])
113+
114+
->set('sofascore.purgatory.inverse_values_builder.dynamic', DynamicInverseValuesBuilder::class)
115+
->tag('purgatory.inverse_values_builder')
116+
117+
->set('sofascore.purgatory.inverse_values_builder.property', PropertyInverseValuesBuilder::class)
118+
->tag('purgatory.inverse_values_builder')
119+
104120
->set('sofascore.purgatory.configuration_loader', ConfigurationLoader::class)
105121
->args([
106122
service('sofascore.purgatory.purge_subscription_provider'),

psalm-baseline.xml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,21 @@
88
<code><![CDATA[require $cache->getPath()]]></code>
99
</UnresolvableInclude>
1010
</file>
11+
<file src="src/Cache/PropertyResolver/InverseValuesBuilder/CompoundInverseValuesBuilder.php">
12+
<InvalidArgument>
13+
<code><![CDATA[array_map(
14+
fn (ValuesInterface $values): ValuesInterface => $this->getInverseValuesBuilderFor($values)
15+
?->build($values, $associationClass, $associationTarget)
16+
?? $values,
17+
$values->getValues(),
18+
)]]></code>
19+
</InvalidArgument>
20+
</file>
21+
<file src="src/Cache/PropertyResolver/InverseValuesBuilder/DynamicInverseValuesBuilder.php">
22+
<PossiblyUndefinedArrayOffset>
23+
<code><![CDATA[$alias]]></code>
24+
</PossiblyUndefinedArrayOffset>
25+
</file>
1126
<file src="src/Cache/RouteMetadata/AttributeMetadataProvider.php">
1227
<PossiblyUndefinedArrayOffset>
1328
<code><![CDATA[$method]]></code>

src/Attribute/RouteParamValue/CompoundValues.php

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
use Sofascore\PurgatoryBundle\Attribute\PurgeOn;
88
use Sofascore\PurgatoryBundle\Exception\InvalidArgumentException;
99

10-
final class CompoundValues extends AbstractValues implements InverseValuesAwareInterface
10+
final class CompoundValues extends AbstractValues
1111
{
1212
/**
1313
* @var non-empty-list<ValuesInterface>
@@ -60,18 +60,6 @@ public function toArray(): array
6060
];
6161
}
6262

63-
public function buildInverseValuesFor(string $association): ValuesInterface
64-
{
65-
return new self(
66-
...array_map(
67-
static fn (ValuesInterface $values): ValuesInterface => $values instanceof InverseValuesAwareInterface
68-
? $values->buildInverseValuesFor($association)
69-
: $values,
70-
$this->values,
71-
),
72-
);
73-
}
74-
7563
public static function type(): string
7664
{
7765
return 'compound';

src/Attribute/RouteParamValue/DynamicValues.php

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
namespace Sofascore\PurgatoryBundle\Attribute\RouteParamValue;
66

7-
final class DynamicValues extends AbstractValues implements InverseValuesAwareInterface
7+
final class DynamicValues extends AbstractValues
88
{
99
/**
1010
* @param string $alias Alias defined in {@see AsRouteParamService} attribute
@@ -23,14 +23,6 @@ public function getValues(): array
2323
return [$this->alias, $this->arg];
2424
}
2525

26-
public function buildInverseValuesFor(string $association): ValuesInterface
27-
{
28-
return new self(
29-
alias: $this->alias,
30-
arg: null !== $this->arg ? \sprintf('%s?.%s', $association, $this->arg) : $association,
31-
);
32-
}
33-
3426
public static function type(): string
3527
{
3628
return 'dynamic';

src/Attribute/RouteParamValue/InverseValuesAwareInterface.php

Lines changed: 0 additions & 10 deletions
This file was deleted.

src/Attribute/RouteParamValue/PropertyValues.php

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
namespace Sofascore\PurgatoryBundle\Attribute\RouteParamValue;
66

7-
final class PropertyValues extends AbstractValues implements InverseValuesAwareInterface
7+
final class PropertyValues extends AbstractValues
88
{
99
/** @var non-empty-list<string> */
1010
private readonly array $properties;
@@ -24,16 +24,6 @@ public function getValues(): array
2424
return $this->properties;
2525
}
2626

27-
public function buildInverseValuesFor(string $association): ValuesInterface
28-
{
29-
return new self(
30-
...array_map(
31-
static fn (string $property): string => \sprintf('%s?.%s', $association, $property),
32-
$this->properties,
33-
),
34-
);
35-
}
36-
3727
public static function type(): string
3828
{
3929
return 'property';

src/Cache/PropertyResolver/AssociationResolver.php

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@
88
use Doctrine\ORM\Mapping\ClassMetadata as ORMClassMetadata;
99
use Doctrine\ORM\Mapping\OneToOneOwningSideMapping;
1010
use Doctrine\Persistence\Mapping\ClassMetadata;
11-
use Sofascore\PurgatoryBundle\Attribute\RouteParamValue\InverseValuesAwareInterface;
11+
use Psr\Container\ContainerInterface;
1212
use Sofascore\PurgatoryBundle\Attribute\RouteParamValue\ValuesInterface;
13+
use Sofascore\PurgatoryBundle\Cache\PropertyResolver\InverseValuesBuilder\InverseValuesBuilderInterface;
1314
use Sofascore\PurgatoryBundle\Cache\RouteMetadata\RouteMetadata;
1415
use Sofascore\PurgatoryBundle\Cache\Subscription\PurgeSubscription;
1516
use Sofascore\PurgatoryBundle\Exception\PropertyNotAccessibleException;
@@ -21,6 +22,7 @@ final class AssociationResolver implements SubscriptionResolverInterface
2122
{
2223
public function __construct(
2324
private readonly PropertyReadInfoExtractorInterface $extractor,
25+
private readonly ContainerInterface $inverseValuesBuilderLocator,
2426
) {
2527
}
2628

@@ -68,7 +70,9 @@ public function resolveSubscription(
6870
/** @var array<string, ValuesInterface> $inverseRouteParams */
6971
$inverseRouteParams = [];
7072
foreach ($routeParams as $routeParam => $values) {
71-
$inverseRouteParams[$routeParam] = $this->getInverseValuesFor($values, $associationTarget);
73+
$inverseRouteParams[$routeParam] = $this->getInverseValuesBuilderFor($values)
74+
?->build($values, $associationClass, $associationTarget)
75+
?? $values;
7276
}
7377

7478
if (null !== $if = $routeMetadata->purgeOn->if) {
@@ -91,9 +95,21 @@ class: $associationClass,
9195
return true;
9296
}
9397

94-
private function getInverseValuesFor(ValuesInterface $values, string $associationTarget): ValuesInterface
98+
/**
99+
* @template T of ValuesInterface
100+
*
101+
* @param T $values
102+
*
103+
* @return ?InverseValuesBuilderInterface<T>
104+
*/
105+
private function getInverseValuesBuilderFor(ValuesInterface $values): ?InverseValuesBuilderInterface
95106
{
96-
return $values instanceof InverseValuesAwareInterface ? $values->buildInverseValuesFor($associationTarget) : $values;
107+
/** @var ?InverseValuesBuilderInterface<T> $builder */
108+
$builder = $this->inverseValuesBuilderLocator->has($type = $values::type())
109+
? $this->inverseValuesBuilderLocator->get($type)
110+
: null;
111+
112+
return $builder;
97113
}
98114

99115
private function createGetter(string $class, string $property): string
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Sofascore\PurgatoryBundle\Cache\PropertyResolver\InverseValuesBuilder;
6+
7+
use Psr\Container\ContainerInterface;
8+
use Sofascore\PurgatoryBundle\Attribute\RouteParamValue\CompoundValues;
9+
use Sofascore\PurgatoryBundle\Attribute\RouteParamValue\ValuesInterface;
10+
11+
/**
12+
* @implements InverseValuesBuilderInterface<CompoundValues>
13+
*/
14+
final class CompoundInverseValuesBuilder implements InverseValuesBuilderInterface
15+
{
16+
public function __construct(
17+
private readonly ContainerInterface $inverseValuesBuilderLocator,
18+
) {
19+
}
20+
21+
public static function for(): string
22+
{
23+
return CompoundValues::type();
24+
}
25+
26+
public function build(ValuesInterface $values, string $associationClass, string $associationTarget): ValuesInterface
27+
{
28+
return new CompoundValues(
29+
...array_map(
30+
fn (ValuesInterface $values): ValuesInterface => $this->getInverseValuesBuilderFor($values)
31+
?->build($values, $associationClass, $associationTarget)
32+
?? $values,
33+
$values->getValues(),
34+
),
35+
);
36+
}
37+
38+
/**
39+
* @template T of ValuesInterface
40+
*
41+
* @param T $values
42+
*
43+
* @return ?InverseValuesBuilderInterface<T>
44+
*/
45+
private function getInverseValuesBuilderFor(ValuesInterface $values): ?InverseValuesBuilderInterface
46+
{
47+
/** @var ?InverseValuesBuilderInterface<T> $builder */
48+
$builder = $this->inverseValuesBuilderLocator->has($type = $values::type())
49+
? $this->inverseValuesBuilderLocator->get($type)
50+
: null;
51+
52+
return $builder;
53+
}
54+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Sofascore\PurgatoryBundle\Cache\PropertyResolver\InverseValuesBuilder;
6+
7+
use Sofascore\PurgatoryBundle\Attribute\RouteParamValue\DynamicValues;
8+
use Sofascore\PurgatoryBundle\Attribute\RouteParamValue\ValuesInterface;
9+
10+
/**
11+
* @implements InverseValuesBuilderInterface<DynamicValues>
12+
*/
13+
final class DynamicInverseValuesBuilder implements InverseValuesBuilderInterface
14+
{
15+
public static function for(): string
16+
{
17+
return DynamicValues::type();
18+
}
19+
20+
public function build(ValuesInterface $values, string $associationClass, string $associationTarget): ValuesInterface
21+
{
22+
/** @var string $alias */
23+
[$alias, $arg] = $values->getValues();
24+
25+
return new DynamicValues(
26+
alias: $alias,
27+
arg: null !== $arg ? \sprintf('%s?.%s', $associationTarget, $arg) : $associationTarget,
28+
);
29+
}
30+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Sofascore\PurgatoryBundle\Cache\PropertyResolver\InverseValuesBuilder;
6+
7+
use Sofascore\PurgatoryBundle\Attribute\RouteParamValue\ValuesInterface;
8+
9+
/**
10+
* @template T of ValuesInterface
11+
*/
12+
interface InverseValuesBuilderInterface
13+
{
14+
public static function for(): string;
15+
16+
/**
17+
* @param T $values
18+
*
19+
* @return T
20+
*/
21+
public function build(ValuesInterface $values, string $associationClass, string $associationTarget): ValuesInterface;
22+
}

0 commit comments

Comments
 (0)