Completed
Push — master ( 07af17...f7b321 )
by Pavel
04:37
created

CrudsEntitiesConfigurator::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 3
cts 3
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 1
crap 1
1
<?php
2
3
namespace ScayTrase\Api\Cruds\DependencyInjection;
4
5
use Doctrine\Common\Persistence\ObjectManager;
6
use Doctrine\ORM\EntityRepository;
7
use ScayTrase\Api\Cruds\Controller\CreateController;
8
use ScayTrase\Api\Cruds\Controller\DeleteController;
9
use ScayTrase\Api\Cruds\Controller\ReadController;
10
use ScayTrase\Api\Cruds\Controller\SearchController;
11
use ScayTrase\Api\Cruds\Controller\UpdateController;
12
use Symfony\Component\DependencyInjection\ContainerBuilder;
13
use Symfony\Component\DependencyInjection\Definition;
14
use Symfony\Component\DependencyInjection\DefinitionDecorator;
15
use Symfony\Component\DependencyInjection\Reference;
16
17
final class CrudsEntitiesConfigurator
18
{
19
    /** @var  ContainerBuilder */
20
    private $container;
21
22
    /**
23
     * CrudsEntitiesConfigurator constructor.
24
     *
25
     * @param ContainerBuilder $container
26
     */
27 2
    public function __construct(ContainerBuilder $container)
28
    {
29 2
        $this->container = $container;
30 2
    }
31
32 2
    public function processEntityConfiguration($name, $config)
33
    {
34 2
        $class      = $config['class'];
35 2
        $actions    = $config['actions'];
36 2
        $prefix     = $config['prefix'];
37 2
        $repository = $config['repository'];
38
39 2
        if (null === $repository) {
40 2
            $repositoryDefinition = new Definition(EntityRepository::class);
41 2
            $repositoryDefinition->setFactory([new Reference('doctrine.orm.entity_manager'), 'getRepository']);
42 2
            $repositoryDefinition->setArguments([$class]);
43 2
        } else {
44
            $repositoryDefinition = new Reference($this->filterReference($repository));
45
        }
46
47 2
        $manager = new Definition(ObjectManager::class);
48 2
        $manager->setFactory([new Reference('doctrine'), 'getManagerForClass']);
49 2
        $manager->setArguments([$class]);
50
51 2
        foreach ($actions as $action => $actionConfig) {
52 2
            if (!$actionConfig['enabled']) {
53
                continue;
54
            }
55
56 2
            $actionConfig['name']       = $name;
57 2
            $actionConfig['class']      = $class;
58 2
            $actionConfig['repository'] = $repositoryDefinition;
59 2
            $actionConfig['path']       = $prefix.$actionConfig['path'];
60 2
            $actionConfig['manager']    = $manager;
61 2
            $function                   = new \ReflectionMethod($this, 'register'.ucfirst($action).'Action');
62 2
            $args                       = [];
63
64 2
            foreach ($function->getParameters() as $parameter) {
65 2
                if (array_key_exists($parameter->getName(), $actionConfig)) {
1 ignored issue
show
Bug introduced by
Consider using $parameter->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
66 2
                    $args[] = $actionConfig[$parameter->getName()];
1 ignored issue
show
Bug introduced by
Consider using $parameter->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
67 2
                } else {
68
                    $args[] = $parameter->getDefaultValue();
69
                }
70 2
            }
71 2
            $function->invokeArgs($this, $args);
72 2
        }
73 2
    }
74
75 2
    public function registerCreateAction($name, $class, $factory, $processor, $path, $manager)
76
    {
77 2
        if (null === $factory) {
78 2
            $factory = new DefinitionDecorator('cruds.factory.reflection');
79 2
            $factory->setArguments([$class, []]);
80 2
        } else {
81
            $factory = new Reference($this->filterReference($factory));
82
        }
83
84 2 View Code Duplication
        if (null === $processor) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
85 2
            $processor = new Reference('cruds.processor.property_access');
86 2
        } else {
87
            $processor = new Reference($this->filterReference($processor));
88
        }
89
90 2
        $definition = new Definition(CreateController::class);
91 2
        $definition->setArguments(
92
            [
93 2
                $processor,
94 2
                $manager,
95 2
                $factory,
96 2
                new Reference('event_dispatcher'),
97
            ]
98 2
        );
99 2
        $definition->setPublic(true);
100
101 2
        $controllerId = $this->normalize('cruds.api.generated.'.$name.'.create_controller');
102 2
        $this->container->setDefinition($controllerId, $definition);
103
104 2
        $this->getLoaderDefinition()->addMethodCall(
105 2
            'addRoute',
106
            [
107 2
                $this->normalize('cruds.api_'.$name.'_create'),
108 2
                $path,
109 2
                $controllerId.':'.CreateController::ACTION,
110 2
                ['POST'],
111
            ]
112 2
        );
113 2
    }
114
115 2 View Code Duplication
    public function registerReadAction($name, $path, $repository)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
116
    {
117 2
        $definition = new Definition(ReadController::class);
118 2
        $definition->setArguments(
119
            [
120 2
                $repository,
121 2
                new Reference('event_dispatcher'),
122
            ]
123 2
        );
124
125 2
        $controllerId = $this->normalize('cruds.api_'.$name.'_read_controller');
126 2
        $this->container->setDefinition($controllerId, $definition);
127
128 2
        $this->getLoaderDefinition()->addMethodCall(
129 2
            'addRoute',
130
            [
131 2
                $this->normalize('cruds.api_'.$name.'_read'),
132 2
                $path,
133 2
                $controllerId.':'.ReadController::ACTION,
134 2
                ['GET'],
135
            ]
136 2
        );
137 2
    }
138
139 2
    public function registerUpdateAction($name, $path, $repository, $processor, $manager)
140
    {
141 2 View Code Duplication
        if (null === $processor) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
142 2
            $processor = new Reference('cruds.processor.property_access');
143 2
        } else {
144
            $processor = new Reference($this->filterReference($processor));
145
        }
146
147 2
        $definition = new Definition(UpdateController::class);
148 2
        $definition->setArguments(
149
            [
150 2
                $repository,
151 2
                $processor,
152 2
                $manager,
153 2
                new Reference('event_dispatcher'),
154
            ]
155 2
        );
156
157 2
        $controllerId = $this->normalize('cruds.api_'.$name.'_update_controller');
158 2
        $this->container->setDefinition($controllerId, $definition);
159
160 2
        $this->getLoaderDefinition()->addMethodCall(
161 2
            'addRoute',
162
            [
163 2
                $this->normalize('cruds.api_'.$name.'_update'),
164 2
                $path,
165 2
                $controllerId.':'.UpdateController::ACTION,
166 2
                ['POST'],
167
            ]
168 2
        );
169 2
    }
170
171 2 View Code Duplication
    public function registerDeleteAction($name, $path, $repository, $manager)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
172
    {
173 2
        $definition = new Definition(DeleteController::class);
174 2
        $definition->setArguments(
175
            [
176 2
                $repository,
177 2
                $manager,
178 2
                new Reference('event_dispatcher'),
179
            ]
180 2
        );
181
182 2
        $controllerId = $this->normalize('cruds.api_'.$name.'_delete_controller');
183 2
        $this->container->setDefinition($controllerId, $definition);
184
185 2
        $this->getLoaderDefinition()->addMethodCall(
186 2
            'addRoute',
187
            [
188 2
                $this->normalize('cruds.api_'.$name.'_delete'),
189 2
                $path,
190 2
                $controllerId.':'.DeleteController::ACTION,
191 2
                ['POST'],
192
            ]
193 2
        );
194 2
    }
195
196 2
    public function registerSearchAction($name, $path, $class, $repository, array $criteria = [])
197
    {
198 2
        $filterArray = [];
199 2
        foreach ($criteria as $filter => $reference) {
200 2
            $filterArray[$filter] = new Reference($this->filterReference($reference));
201 2
        }
202
203 2
        $definition = new Definition(SearchController::class);
204 2
        $definition->setArguments(
205
            [
206 2
                $class,
207 2
                $repository,
208 2
                $filterArray,
209 2
                new Reference('event_dispatcher'),
210
            ]
211 2
        );
212
213 2
        $controllerId = $this->normalize('cruds.api_'.$name.'_search_controller');
214 2
        $this->container->setDefinition($controllerId, $definition);
215
216 2
        $this->getLoaderDefinition()->addMethodCall(
217 2
            'addRoute',
218
            [
219 2
                $this->normalize('cruds.api_'.$name.'_search'),
220 2
                $path,
221 2
                $controllerId.':'.SearchController::ACTION,
222 2
                ['GET', 'POST'],
223
            ]
224 2
        );
225 2
    }
226
227 2
    private function getLoaderDefinition()
228
    {
229 2
        return $this->container->getDefinition('cruds.api.router_loader');
230
    }
231
232
    /**
233
     * @param string $name
234
     *
235
     * @return string
236
     */
237 2
    private function normalize($name)
238
    {
239 2
        return str_replace('-', '_', $name);
240
    }
241
242
    /**
243
     * @param string $reference
244
     *
245
     * @return string
246
     */
247 2
    private function filterReference($reference)
248
    {
249 2
        return ltrim($reference, '@');
250
    }
251
}
252