Skip to content

Commit 46059c6

Browse files
add missing files
1 parent 1bda826 commit 46059c6

File tree

11 files changed

+458
-0
lines changed

11 files changed

+458
-0
lines changed

Annotation/EventListener.php

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?php
2+
3+
4+
namespace SimonMarx\Symfony\Bundles\ServiceAnnotations\Annotation;
5+
6+
use Doctrine\Common\Annotations\Annotation\Target;
7+
8+
/**
9+
* @Annotation
10+
* @Target("CLASS")
11+
*/
12+
class EventListener
13+
{
14+
private string $eventTag;
15+
private string $event;
16+
private array $attributes = [];
17+
18+
public function __construct(array $values = [])
19+
{
20+
$this->event = $values['event'] ?? $values['value'];
21+
$this->eventTag = $values['eventTag'] ?? 'kernel.event_listener';
22+
23+
unset($values['value']);
24+
unset($values['name']);
25+
26+
$this->attributes['event'] = $this->event;
27+
$this->attributes = $values;
28+
}
29+
30+
public function getEvent(): string
31+
{
32+
return $this->event;
33+
}
34+
35+
public function getEventTag(): string
36+
{
37+
return $this->eventTag;
38+
}
39+
40+
public function getAttributes(): array
41+
{
42+
return $this->attributes;
43+
}
44+
}

Annotation/NotShared.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
4+
namespace SimonMarx\Symfony\Bundles\ServiceAnnotations\Annotation;
5+
6+
use Doctrine\Common\Annotations\Annotation\Target;
7+
8+
/**
9+
* @Annotation
10+
* @Target("CLASS")
11+
*/
12+
class NotShared
13+
{
14+
15+
}

Annotation/ParentService.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
4+
namespace SimonMarx\Symfony\Bundles\ServiceAnnotations\Annotation;
5+
6+
use Doctrine\Common\Annotations\Annotation\Target;
7+
8+
/**
9+
* @Annotation
10+
* @Target("CLASS")
11+
*/
12+
class ParentService
13+
{
14+
private string $parent;
15+
16+
public function __construct(array $values = [])
17+
{
18+
$this->parent = $values['parent'] ?? $values['value'];
19+
}
20+
21+
public function getParent(): string
22+
{
23+
return $this->parent;
24+
}
25+
}

Annotation/ServiceCall.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
3+
4+
namespace SimonMarx\Symfony\Bundles\ServiceAnnotations\Annotation;
5+
6+
use Doctrine\Common\Annotations\Annotation\Target;
7+
8+
/**
9+
* @Annotation
10+
* @Target("METHOD")
11+
*/
12+
class ServiceCall
13+
{
14+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
4+
namespace SimonMarx\Symfony\Bundles\ServiceAnnotations\DependencyInjection\Compiler;
5+
6+
7+
use SimonMarx\Symfony\Bundles\ServiceAnnotations\Annotation\NotShared;
8+
use SimonMarx\Symfony\Bundles\ServiceAnnotations\Utils\CompilerPassServiceAnnotationTrait;
9+
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
10+
use Symfony\Component\DependencyInjection\ContainerBuilder;
11+
12+
class DefinitionManipulationPass implements CompilerPassInterface
13+
{
14+
use CompilerPassServiceAnnotationTrait;
15+
16+
public function process(ContainerBuilder $container)
17+
{
18+
foreach ($container->getDefinitions() as $definition) {
19+
if (
20+
false === $this->definitionHasValidClass($definition)
21+
|| false === $this->definitionHasAnnotation($definition, NotShared::class)
22+
) {
23+
continue;
24+
}
25+
26+
$definition->setShared(false);
27+
}
28+
}
29+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<?php
2+
3+
4+
namespace SimonMarx\Symfony\Bundles\ServiceAnnotations\DependencyInjection\Compiler;
5+
6+
use ReflectionProperty;
7+
use SimonMarx\Symfony\Bundles\ServiceAnnotations\Annotation\ParentService;
8+
use SimonMarx\Symfony\Bundles\ServiceAnnotations\Utils\CompilerPassServiceAnnotationTrait;
9+
use SimonMarx\Symfony\Bundles\ServiceAnnotations\Utils\ObjectCloner;
10+
use SimonMarx\Symfony\Bundles\ServiceAnnotations\Utils\ObjectClonerContext;
11+
use SimonMarx\Symfony\Bundles\ServiceAnnotations\Utils\ReflectionCacheTrait;
12+
use Symfony\Component\DependencyInjection\ChildDefinition;
13+
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
14+
use Symfony\Component\DependencyInjection\ContainerBuilder;
15+
use Symfony\Component\DependencyInjection\Definition;
16+
17+
class ParentServicePass implements CompilerPassInterface
18+
{
19+
use ReflectionCacheTrait;
20+
use CompilerPassServiceAnnotationTrait;
21+
22+
public function process(ContainerBuilder $container)
23+
{
24+
foreach ($container->getDefinitions() as $serviceId => $definition) {
25+
if (
26+
false === $this->definitionHasValidClass($definition)
27+
|| false === $this->definitionHasAnnotation($definition, ParentService::class)
28+
) {
29+
continue;
30+
}
31+
32+
/** @var ParentService $parentAnnotation */
33+
$parentAnnotation = $this->findDefinitionAnnotation($definition, ParentService::class);
34+
35+
if (null === $parentAnnotation) {
36+
continue;
37+
}
38+
39+
if ($definition instanceof ChildDefinition) {
40+
$definition->setParent($parentAnnotation->getParent());
41+
} else {
42+
/** @var ChildDefinition $childDefinition */
43+
$childDefinition = ObjectCloner::clone(
44+
$definition,
45+
ChildDefinition::class,
46+
new ObjectClonerContext([
47+
ObjectClonerContext::CONSTRUCT => ['parent' => $parentAnnotation->getParent()]
48+
])
49+
);
50+
51+
$container->removeDefinition($serviceId);
52+
$container->setDefinition($serviceId, $childDefinition);
53+
}
54+
}
55+
}
56+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?php
2+
3+
4+
namespace SimonMarx\Symfony\Bundles\ServiceAnnotations\DependencyInjection\Compiler;
5+
6+
7+
use App\Repository\ContextRepository\UserContextRepository;
8+
use SimonMarx\Symfony\Bundles\ServiceAnnotations\Annotation\ServiceCall;
9+
use SimonMarx\Symfony\Bundles\ServiceAnnotations\Utils\CompilerPassServiceAnnotationTrait;
10+
use SimonMarx\Symfony\Bundles\ServiceAnnotations\Utils\ReflectionCacheTrait;
11+
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
12+
use Symfony\Component\DependencyInjection\ContainerBuilder;
13+
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
14+
use Symfony\Component\DependencyInjection\Reference;
15+
16+
class ServiceCallPass implements CompilerPassInterface
17+
{
18+
use ReflectionCacheTrait;
19+
use CompilerPassServiceAnnotationTrait;
20+
21+
public function process(ContainerBuilder $container)
22+
{
23+
foreach ($container->getDefinitions() as $serviceId => $definition) {
24+
if (false === $this->definitionHasValidClass($definition)) {
25+
continue;
26+
}
27+
28+
$rc = $this->getClassReflection($definition->getClass());
29+
30+
foreach ($rc->getMethods() as $method) {
31+
if ($annotation = $this->annotationReader->getMethodAnnotation($method, ServiceCall::class)) {
32+
$parameters = [];
33+
foreach ($method->getParameters() as $parameter) {
34+
if (null === $parameter->getClass()) {
35+
$value = $parameter->getDefaultValue();
36+
\settype($value, $parameter->getType());
37+
} else {
38+
$value = $parameter->getClass()->getName();
39+
}
40+
41+
try {
42+
$container->findDefinition($value);
43+
$value = new Reference($value);
44+
} catch (ServiceNotFoundException $serviceNotFoundException) {
45+
}
46+
47+
$parameters[$parameter->getPosition()] = $value;
48+
}
49+
50+
$definition->addMethodCall($method->getName(), $parameters);
51+
}
52+
}
53+
}
54+
}
55+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
4+
namespace SimonMarx\Symfony\Bundles\ServiceAnnotations\Exception;
5+
6+
7+
use Exception;
8+
9+
class InvalidCloneConfigurationException extends Exception
10+
{
11+
12+
}

Utils/InstanceOfInjectionTrait.php

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<?php
2+
3+
4+
namespace SimonMarx\Symfony\Bundles\ServiceAnnotations\Utils;
5+
6+
7+
use App\Serializer\Normalizer\DateTimeNormalizer;
8+
use Symfony\Component\DependencyInjection\ChildDefinition;
9+
use Symfony\Component\DependencyInjection\ContainerBuilder;
10+
use Symfony\Component\DependencyInjection\Definition;
11+
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
12+
13+
trait InstanceOfInjectionTrait
14+
{
15+
private function checkDefinitionHasInstanceOfConfigurations(ContainerBuilder $container, Definition $definition)
16+
{
17+
$instanceOfConditionals = $definition->getInstanceofConditionals();
18+
$autoconfiguredInstanceof = $definition->isAutoconfigured() ? $container->getAutoconfiguredInstanceof() : [];
19+
20+
if (\count($autoconfiguredInstanceof) === 0 && \count($instanceOfConditionals) === 0) {
21+
return false;
22+
}
23+
24+
$instanceOfClasses = \array_keys($autoconfiguredInstanceof);
25+
26+
if ($definition->getClass() === DateTimeNormalizer::class) {
27+
foreach ($instanceOfClasses as $instanceOfClass) {
28+
$rc = $container->getReflectionClass($definition->getClass());
29+
30+
if (
31+
(\class_exists($instanceOfClass) && $rc->isSubclassOf($instanceOfClass))
32+
|| (\interface_exists($instanceOfClass) && $rc->implementsInterface($instanceOfClass))
33+
) {
34+
return false === $definition instanceof ChildDefinition;
35+
}
36+
}
37+
}
38+
39+
return false;
40+
}
41+
42+
private function mergeConditionals(array $autoconfiguredInstanceof, array $instanceofConditionals, ContainerBuilder $container): array
43+
{
44+
// make each value an array of ChildDefinition
45+
$conditionals = array_map(function ($childDef) {
46+
return [$childDef];
47+
}, $autoconfiguredInstanceof);
48+
49+
foreach ($instanceofConditionals as $interface => $instanceofDef) {
50+
// make sure the interface/class exists (but don't validate automaticInstanceofConditionals)
51+
if (!$container->getReflectionClass($interface)) {
52+
throw new RuntimeException(sprintf('"%s" is set as an "instanceof" conditional, but it does not exist.', $interface));
53+
}
54+
55+
if (!isset($autoconfiguredInstanceof[$interface])) {
56+
$conditionals[$interface] = [];
57+
}
58+
59+
$conditionals[$interface][] = $instanceofDef;
60+
}
61+
62+
return $conditionals;
63+
}
64+
}

0 commit comments

Comments
 (0)