Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions config/services.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
use Sofascore\PurgatoryBundle\Cache\Configuration\ConfigurationLoader;
use Sofascore\PurgatoryBundle\Cache\PropertyResolver\AssociationResolver;
use Sofascore\PurgatoryBundle\Cache\PropertyResolver\EmbeddableResolver;
use Sofascore\PurgatoryBundle\Cache\PropertyResolver\InverseValuesBuilder\CompoundInverseValuesBuilder;
use Sofascore\PurgatoryBundle\Cache\PropertyResolver\InverseValuesBuilder\DynamicInverseValuesBuilder;
use Sofascore\PurgatoryBundle\Cache\PropertyResolver\InverseValuesBuilder\PropertyInverseValuesBuilder;
use Sofascore\PurgatoryBundle\Cache\PropertyResolver\MethodResolver;
use Sofascore\PurgatoryBundle\Cache\PropertyResolver\PropertyResolver;
use Sofascore\PurgatoryBundle\Cache\RouteMetadata\AttributeMetadataProvider;
Expand Down Expand Up @@ -93,6 +96,7 @@
->tag('purgatory.subscription_resolver')
->args([
service('property_info.reflection_extractor'),
tagged_locator('purgatory.inverse_values_builder', defaultIndexMethod: 'for'),
])

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

->set('sofascore.purgatory.inverse_values_builder.compound', CompoundInverseValuesBuilder::class)
->tag('purgatory.inverse_values_builder')
->args([
tagged_locator('purgatory.inverse_values_builder', defaultIndexMethod: 'for'),
])

->set('sofascore.purgatory.inverse_values_builder.dynamic', DynamicInverseValuesBuilder::class)
->tag('purgatory.inverse_values_builder')

->set('sofascore.purgatory.inverse_values_builder.property', PropertyInverseValuesBuilder::class)
->tag('purgatory.inverse_values_builder')

->set('sofascore.purgatory.configuration_loader', ConfigurationLoader::class)
->args([
service('sofascore.purgatory.purge_subscription_provider'),
Expand Down
15 changes: 15 additions & 0 deletions psalm-baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,21 @@
<code><![CDATA[require $cache->getPath()]]></code>
</UnresolvableInclude>
</file>
<file src="src/Cache/PropertyResolver/InverseValuesBuilder/CompoundInverseValuesBuilder.php">
<InvalidArgument>
<code><![CDATA[array_map(
fn (ValuesInterface $values): ValuesInterface => $this->getInverseValuesBuilderFor($values)
?->build($values, $associationClass, $associationTarget)
?? $values,
$values->getValues(),
)]]></code>
</InvalidArgument>
</file>
<file src="src/Cache/PropertyResolver/InverseValuesBuilder/DynamicInverseValuesBuilder.php">
<PossiblyUndefinedArrayOffset>
<code><![CDATA[$alias]]></code>
</PossiblyUndefinedArrayOffset>
</file>
<file src="src/Cache/RouteMetadata/AttributeMetadataProvider.php">
<PossiblyUndefinedArrayOffset>
<code><![CDATA[$method]]></code>
Expand Down
14 changes: 1 addition & 13 deletions src/Attribute/RouteParamValue/CompoundValues.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
use Sofascore\PurgatoryBundle\Attribute\PurgeOn;
use Sofascore\PurgatoryBundle\Exception\InvalidArgumentException;

final class CompoundValues extends AbstractValues implements InverseValuesAwareInterface
final class CompoundValues extends AbstractValues
{
/**
* @var non-empty-list<ValuesInterface>
Expand Down Expand Up @@ -60,18 +60,6 @@ public function toArray(): array
];
}

public function buildInverseValuesFor(string $association): ValuesInterface
{
return new self(
...array_map(
static fn (ValuesInterface $values): ValuesInterface => $values instanceof InverseValuesAwareInterface
? $values->buildInverseValuesFor($association)
: $values,
$this->values,
),
);
}

public static function type(): string
{
return 'compound';
Expand Down
10 changes: 1 addition & 9 deletions src/Attribute/RouteParamValue/DynamicValues.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace Sofascore\PurgatoryBundle\Attribute\RouteParamValue;

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

public function buildInverseValuesFor(string $association): ValuesInterface
{
return new self(
alias: $this->alias,
arg: null !== $this->arg ? \sprintf('%s?.%s', $association, $this->arg) : $association,
);
}

public static function type(): string
{
return 'dynamic';
Expand Down
10 changes: 0 additions & 10 deletions src/Attribute/RouteParamValue/InverseValuesAwareInterface.php

This file was deleted.

12 changes: 1 addition & 11 deletions src/Attribute/RouteParamValue/PropertyValues.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace Sofascore\PurgatoryBundle\Attribute\RouteParamValue;

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

public function buildInverseValuesFor(string $association): ValuesInterface
{
return new self(
...array_map(
static fn (string $property): string => \sprintf('%s?.%s', $association, $property),
$this->properties,
),
);
}

public static function type(): string
{
return 'property';
Expand Down
24 changes: 20 additions & 4 deletions src/Cache/PropertyResolver/AssociationResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@
use Doctrine\ORM\Mapping\ClassMetadata as ORMClassMetadata;
use Doctrine\ORM\Mapping\OneToOneOwningSideMapping;
use Doctrine\Persistence\Mapping\ClassMetadata;
use Sofascore\PurgatoryBundle\Attribute\RouteParamValue\InverseValuesAwareInterface;
use Psr\Container\ContainerInterface;
use Sofascore\PurgatoryBundle\Attribute\RouteParamValue\ValuesInterface;
use Sofascore\PurgatoryBundle\Cache\PropertyResolver\InverseValuesBuilder\InverseValuesBuilderInterface;
use Sofascore\PurgatoryBundle\Cache\RouteMetadata\RouteMetadata;
use Sofascore\PurgatoryBundle\Cache\Subscription\PurgeSubscription;
use Sofascore\PurgatoryBundle\Exception\PropertyNotAccessibleException;
Expand All @@ -21,6 +22,7 @@ final class AssociationResolver implements SubscriptionResolverInterface
{
public function __construct(
private readonly PropertyReadInfoExtractorInterface $extractor,
private readonly ContainerInterface $inverseValuesBuilderLocator,
) {
}

Expand Down Expand Up @@ -68,7 +70,9 @@ public function resolveSubscription(
/** @var array<string, ValuesInterface> $inverseRouteParams */
$inverseRouteParams = [];
foreach ($routeParams as $routeParam => $values) {
$inverseRouteParams[$routeParam] = $this->getInverseValuesFor($values, $associationTarget);
$inverseRouteParams[$routeParam] = $this->getInverseValuesBuilderFor($values)
?->build($values, $associationClass, $associationTarget)
?? $values;
}

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

private function getInverseValuesFor(ValuesInterface $values, string $associationTarget): ValuesInterface
/**
* @template T of ValuesInterface
*
* @param T $values
*
* @return ?InverseValuesBuilderInterface<T>
*/
private function getInverseValuesBuilderFor(ValuesInterface $values): ?InverseValuesBuilderInterface
{
return $values instanceof InverseValuesAwareInterface ? $values->buildInverseValuesFor($associationTarget) : $values;
/** @var ?InverseValuesBuilderInterface<T> $builder */
$builder = $this->inverseValuesBuilderLocator->has($type = $values::type())
? $this->inverseValuesBuilderLocator->get($type)
: null;

return $builder;
}

private function createGetter(string $class, string $property): string
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php

declare(strict_types=1);

namespace Sofascore\PurgatoryBundle\Cache\PropertyResolver\InverseValuesBuilder;

use Psr\Container\ContainerInterface;
use Sofascore\PurgatoryBundle\Attribute\RouteParamValue\CompoundValues;
use Sofascore\PurgatoryBundle\Attribute\RouteParamValue\ValuesInterface;

/**
* @implements InverseValuesBuilderInterface<CompoundValues>
*/
final class CompoundInverseValuesBuilder implements InverseValuesBuilderInterface
{
public function __construct(
private readonly ContainerInterface $inverseValuesBuilderLocator,
) {
}

public static function for(): string
{
return CompoundValues::type();
}

public function build(ValuesInterface $values, string $associationClass, string $associationTarget): ValuesInterface
{
return new CompoundValues(
...array_map(
fn (ValuesInterface $values): ValuesInterface => $this->getInverseValuesBuilderFor($values)
?->build($values, $associationClass, $associationTarget)
?? $values,
$values->getValues(),
),
);
}

/**
* @template T of ValuesInterface
*
* @param T $values
*
* @return ?InverseValuesBuilderInterface<T>
*/
private function getInverseValuesBuilderFor(ValuesInterface $values): ?InverseValuesBuilderInterface
{
/** @var ?InverseValuesBuilderInterface<T> $builder */
$builder = $this->inverseValuesBuilderLocator->has($type = $values::type())
? $this->inverseValuesBuilderLocator->get($type)
: null;

return $builder;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

declare(strict_types=1);

namespace Sofascore\PurgatoryBundle\Cache\PropertyResolver\InverseValuesBuilder;

use Sofascore\PurgatoryBundle\Attribute\RouteParamValue\DynamicValues;
use Sofascore\PurgatoryBundle\Attribute\RouteParamValue\ValuesInterface;

/**
* @implements InverseValuesBuilderInterface<DynamicValues>
*/
final class DynamicInverseValuesBuilder implements InverseValuesBuilderInterface
{
public static function for(): string
{
return DynamicValues::type();
}

public function build(ValuesInterface $values, string $associationClass, string $associationTarget): ValuesInterface
{
/** @var string $alias */
[$alias, $arg] = $values->getValues();

return new DynamicValues(
alias: $alias,
arg: null !== $arg ? \sprintf('%s?.%s', $associationTarget, $arg) : $associationTarget,
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

declare(strict_types=1);

namespace Sofascore\PurgatoryBundle\Cache\PropertyResolver\InverseValuesBuilder;

use Sofascore\PurgatoryBundle\Attribute\RouteParamValue\ValuesInterface;

/**
* @template T of ValuesInterface
*/
interface InverseValuesBuilderInterface
{
public static function for(): string;

/**
* @param T $values
*
* @return T
*/
public function build(ValuesInterface $values, string $associationClass, string $associationTarget): ValuesInterface;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

declare(strict_types=1);

namespace Sofascore\PurgatoryBundle\Cache\PropertyResolver\InverseValuesBuilder;

use Sofascore\PurgatoryBundle\Attribute\RouteParamValue\PropertyValues;
use Sofascore\PurgatoryBundle\Attribute\RouteParamValue\ValuesInterface;

/**
* @implements InverseValuesBuilderInterface<PropertyValues>
*/
final class PropertyInverseValuesBuilder implements InverseValuesBuilderInterface
{
public static function for(): string
{
return PropertyValues::type();
}

public function build(ValuesInterface $values, string $associationClass, string $associationTarget): ValuesInterface
{
return new PropertyValues(...array_map(
static fn (string $property): string => \sprintf('%s?.%s', $associationTarget, $property),
$values->getValues(),
));
}
}
4 changes: 4 additions & 0 deletions src/DependencyInjection/PurgatoryExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Sofascore\PurgatoryBundle\Attribute\AsExpressionLanguageFunction;
use Sofascore\PurgatoryBundle\Attribute\AsRouteParamService;
use Sofascore\PurgatoryBundle\Attribute\PurgeOn;
use Sofascore\PurgatoryBundle\Cache\PropertyResolver\InverseValuesBuilder\InverseValuesBuilderInterface;
use Sofascore\PurgatoryBundle\Cache\PropertyResolver\SubscriptionResolverInterface;
use Sofascore\PurgatoryBundle\Cache\TargetResolver\TargetResolverInterface;
use Sofascore\PurgatoryBundle\Exception\LogicException;
Expand Down Expand Up @@ -183,6 +184,9 @@ static function (ChildDefinition $definition, AsExpressionLanguageFunction $attr
$container->registerForAutoconfiguration(SubscriptionResolverInterface::class)
->addTag('purgatory.subscription_resolver');

$container->registerForAutoconfiguration(InverseValuesBuilderInterface::class)
->addTag('purgatory.inverse_values_builder');

$container->registerForAutoconfiguration(TargetResolverInterface::class)
->addTag('purgatory.target_resolver');

Expand Down
28 changes: 0 additions & 28 deletions tests/Attribute/RouteParamValue/CompoundValuesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,9 @@
use PHPUnit\Framework\Attributes\TestWith;
use PHPUnit\Framework\TestCase;
use Sofascore\PurgatoryBundle\Attribute\RouteParamValue\CompoundValues;
use Sofascore\PurgatoryBundle\Attribute\RouteParamValue\DynamicValues;
use Sofascore\PurgatoryBundle\Attribute\RouteParamValue\EnumValues;
use Sofascore\PurgatoryBundle\Attribute\RouteParamValue\PropertyValues;
use Sofascore\PurgatoryBundle\Attribute\RouteParamValue\RawValues;
use Sofascore\PurgatoryBundle\Exception\InvalidArgumentException;
use Sofascore\PurgatoryBundle\Tests\Fixtures\DummyIntEnum;

#[CoversClass(CompoundValues::class)]
final class CompoundValuesTest extends TestCase
Expand Down Expand Up @@ -49,29 +46,4 @@ public function testToArray(): void
],
], $compoundValues->toArray());
}

public function testBuildInverseValuesFor(): void
{
$compoundValues = new CompoundValues(
new DynamicValues('alias'),
new DynamicValues('alias', arg: 'obj'),
new EnumValues(DummyIntEnum::class),
new PropertyValues('obj'),
new RawValues(1, null, 'str'),
);

self::assertEquals(
expected: new CompoundValues(
new DynamicValues('alias', arg: 'association'),
new DynamicValues(
alias: 'alias',
arg: 'association?.obj',
),
new EnumValues(DummyIntEnum::class),
new PropertyValues('association?.obj'),
new RawValues(1, null, 'str'),
),
actual: $compoundValues->buildInverseValuesFor('association'),
);
}
}
Loading
Loading