Completed
Push — master ( 300eda...15c856 )
by Rafael
09:26
created

resolveObjectRealInterfaceExtensions()   B

Complexity

Conditions 7
Paths 7

Size

Total Lines 14
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 14
rs 8.2222
c 0
b 0
f 0
cc 7
eloc 11
nc 7
nop 1
1
<?php
2
/*******************************************************************************
3
 *  This file is part of the GraphQL Bundle package.
4
 *
5
 *  (c) YnloUltratech <[email protected]>
6
 *
7
 *  For the full copyright and license information, please view the LICENSE
8
 *  file that was distributed with this source code.
9
 ******************************************************************************/
10
11
namespace Ynlo\GraphQLBundle\Definition\Plugin;
12
13
use Symfony\Component\DependencyInjection\ContainerInterface;
14
use Ynlo\GraphQLBundle\Definition\DefinitionInterface;
15
use Ynlo\GraphQLBundle\Definition\HasExtensionsInterface;
16
use Ynlo\GraphQLBundle\Definition\InterfaceDefinition;
17
use Ynlo\GraphQLBundle\Definition\ObjectDefinition;
18
use Ynlo\GraphQLBundle\Definition\Registry\Endpoint;
19
use Ynlo\GraphQLBundle\Util\ClassUtils;
20
21
/**
22
 * This plugin automatically load CRUD extensions
23
 * based on object interfaces and registered interfaces
24
 */
25
class CRUDExtensionResolverPlugin extends AbstractDefinitionPlugin
26
{
27
    protected $container;
28
29
    public function __construct(ContainerInterface $container)
30
    {
31
        $this->container = $container;
32
    }
33
34
    /**
35
     * {@inheritDoc}
36
     */
37
    public function getName(): string
38
    {
39
        return 'extension';
40
    }
41
42
    /**
43
     * {@inheritDoc}
44
     */
45
    public function configure(DefinitionInterface $definition, Endpoint $endpoint, array $config): void
46
    {
47
        if ($definition instanceof InterfaceDefinition && $definition->getImplementors()) {
48
            $this->resolveInterfaceExtension($definition, $endpoint);
49
        }
50
51
        if ($definition instanceof ObjectDefinition) {
52
            $this->resolveObjectRealInterfaceExtensions($definition);
53
        }
54
    }
55
56
    /**
57
     * Using naming convention resolve CRUD extension for given interface definition and automatically register this extension
58
     * for all interface implementors
59
     *
60
     * @param InterfaceDefinition $definition
61
     * @param Endpoint            $endpoint
62
     */
63
    protected function resolveInterfaceExtension(InterfaceDefinition $definition, Endpoint $endpoint)
64
    {
65
        $bundleNamespace = ClassUtils::relatedBundleNamespace($definition->getClass());
66
        $extensionClass = ClassUtils::applyNamingConvention($bundleNamespace, 'Extension', null, $definition->getName().'Extension');
67
        if (class_exists($extensionClass)) {
68
            foreach ($definition->getImplementors() as $implementor) {
69
                $object = $endpoint->getType($implementor);
70
                if ($object instanceof HasExtensionsInterface) {
71
                    $object->addExtension($extensionClass);
72
                }
73
            }
74
        }
75
    }
76
77
    /**
78
     * Using naming convention resolve all extensions for given object
79
     * based on implemented interfaces.
80
     *
81
     * This method use PHP real interfaces instead of registered interface types.
82
     *
83
     * @param ObjectDefinition $definition
84
     *
85
     * @throws \ReflectionException
86
     */
87
    protected function resolveObjectRealInterfaceExtensions(ObjectDefinition $definition)
88
    {
89
        $class = $definition->getClass();
90
91
        if (class_exists($class)) {
92
            $refClass = new \ReflectionClass($definition->getClass());
93
            if ($interfaces = $refClass->getInterfaceNames()) {
94
                foreach ($interfaces as $interface) {
95
                    $bundleNamespace = ClassUtils::relatedBundleNamespace($interface);
96
                    if (preg_match('/(\w+)Interface?$/', $interface, $matches)) {
97
                        $extensionClass = ClassUtils::applyNamingConvention($bundleNamespace, 'Extension', null, $matches[1].'Extension');
98
                        if (class_exists($extensionClass)) {
99
                            if ($definition instanceof HasExtensionsInterface) {
100
                                $definition->addExtension($extensionClass);
101
                            }
102
                        }
103
                    }
104
                }
105
            }
106
        }
107
    }
108
}
109