1
|
|
|
<?php |
2
|
|
|
declare(strict_types = 1); |
3
|
|
|
|
4
|
|
|
namespace Mikemirten\Bundle\JsonApiBundle\DependencyInjection; |
5
|
|
|
|
6
|
|
|
use Symfony\Component\Config\FileLocator; |
7
|
|
|
use Symfony\Component\Config\Loader\LoaderInterface; |
8
|
|
|
use Symfony\Component\DependencyInjection\Definition; |
9
|
|
|
use Symfony\Component\DependencyInjection\DefinitionDecorator; |
10
|
|
|
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; |
11
|
|
|
use Symfony\Component\DependencyInjection\Reference; |
12
|
|
|
use Symfony\Component\HttpKernel\DependencyInjection\Extension; |
13
|
|
|
use Symfony\Component\DependencyInjection\ContainerBuilder; |
14
|
|
|
|
15
|
|
|
class JsonApiExtension extends Extension |
16
|
|
|
{ |
17
|
|
|
const ALIAS = 'mrtn_json_api'; |
18
|
|
|
|
19
|
|
|
/** |
20
|
|
|
* Configuration loader |
21
|
|
|
* |
22
|
|
|
* @var LoaderInterface |
23
|
|
|
*/ |
24
|
|
|
protected $loader; |
25
|
|
|
|
26
|
|
|
/** |
27
|
|
|
* JsonApiExtension constructor. |
28
|
2 |
|
* |
29
|
|
|
* @param LoaderInterface $loader |
30
|
2 |
|
*/ |
31
|
2 |
|
public function __construct(LoaderInterface $loader = null) |
32
|
|
|
{ |
33
|
|
|
$this->loader = $loader; |
34
|
|
|
} |
35
|
|
|
|
36
|
2 |
|
/** |
37
|
|
|
* {@inheritdoc} |
38
|
2 |
|
*/ |
39
|
2 |
|
public function load(array $configs, ContainerBuilder $container) |
40
|
|
|
{ |
41
|
2 |
|
$configuration = new JsonApiConfiguration(); |
42
|
|
|
$config = $this->processConfiguration($configuration, $configs); |
43
|
2 |
|
|
44
|
2 |
|
$loader = $this->loader ?? new YamlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config')); |
45
|
2 |
|
|
46
|
2 |
|
$loader->load('services.yml'); |
47
|
|
|
$loader->load('hydrator.yml'); |
48
|
2 |
|
$loader->load('mapper.yml'); |
49
|
2 |
|
$loader->load('http_client.yml'); |
50
|
|
|
|
51
|
2 |
|
if (! empty($config['mappers'])) { |
52
|
|
|
$this->createMappers($config['mappers'], $container); |
53
|
|
|
} |
54
|
|
|
|
55
|
|
|
if (! empty($config['http_clients'])) { |
56
|
|
|
$this->createResourceClients($config['http_clients'], $container); |
57
|
|
|
} |
58
|
|
|
} |
59
|
2 |
|
|
60
|
|
|
/** |
61
|
2 |
|
* Create mappers |
62
|
|
|
* |
63
|
2 |
|
* @param array $config |
64
|
|
|
* @param ContainerBuilder $container |
65
|
2 |
|
*/ |
66
|
2 |
|
protected function createMappers(array $config, ContainerBuilder $container) |
67
|
|
|
{ |
68
|
2 |
|
$handlers = $this->findMappingHandlers($container); |
69
|
|
|
|
70
|
2 |
|
foreach ($config as $name => $mapperDefinition) |
71
|
|
|
{ |
72
|
|
|
$mapper = new DefinitionDecorator('mrtn_json_api.object_mapper.abstract'); |
|
|
|
|
73
|
|
|
$mapper->addTag('mrtn_json_api.object_mapper', ['alias' => $name]); |
74
|
2 |
|
|
75
|
2 |
View Code Duplication |
foreach ($mapperDefinition['handlers'] as $handlerName) |
|
|
|
|
76
|
|
|
{ |
77
|
|
|
if (! isset($handlers[$handlerName])) { |
78
|
|
|
throw new \LogicException(sprintf('Mapping handler with name "%s" has not been registered as a service.', $handlerName)); |
79
|
2 |
|
} |
80
|
|
|
|
81
|
2 |
|
$mapper->addMethodCall('addHandler', [ |
82
|
|
|
new Reference($handlers[$handlerName]) |
83
|
|
|
]); |
84
|
|
|
} |
85
|
|
|
|
86
|
|
|
$container->setDefinition('mrtn_json_api.object_mapper.' . $name, $mapper); |
87
|
|
|
} |
88
|
|
|
} |
89
|
2 |
|
|
90
|
|
|
/** |
91
|
2 |
|
* Find mapping handler registered in container |
92
|
|
|
* |
93
|
2 |
|
* @param ContainerBuilder $container |
94
|
|
|
* @return array |
95
|
2 |
|
*/ |
96
|
|
|
protected function findMappingHandlers(ContainerBuilder $container): array |
97
|
2 |
|
{ |
98
|
|
|
$handlers = $container->findTaggedServiceIds('mrtn_json_api.object_mapper.handler'); |
99
|
2 |
|
|
100
|
|
|
$found = []; |
101
|
|
|
|
102
|
|
|
foreach ($handlers as $id => $tags) |
103
|
2 |
|
{ |
104
|
|
|
foreach ($tags as $tag) |
105
|
|
|
{ |
106
|
|
|
if (! isset($tag['alias'])) { |
107
|
2 |
|
continue; |
108
|
|
|
} |
109
|
|
|
|
110
|
|
|
$found[$tag['alias']] = $id; |
111
|
|
|
} |
112
|
|
|
} |
113
|
1 |
|
|
114
|
|
|
return $found; |
115
|
1 |
|
} |
116
|
|
|
|
117
|
|
|
/** |
118
|
|
|
* Create resources-based clients |
119
|
|
|
* |
120
|
|
|
* @param array $config |
121
|
|
|
* @param ContainerBuilder $container |
122
|
|
|
*/ |
123
|
|
|
protected function createResourceClients(array $config, ContainerBuilder $container): void |
124
|
|
|
{ |
125
|
|
|
$repositoryClass = $container->getParameter('mrtn_json_api.route_repository.class'); |
126
|
|
|
$clientClass = $container->getParameter('mrtn_json_api.resource_http_client.class'); |
127
|
|
|
|
128
|
|
|
foreach ($config as $name => $definition) |
129
|
|
|
{ |
130
|
|
|
$routes = $this->createRoutesDefinition($definition['resources']); |
131
|
|
|
|
132
|
|
|
$repository = new Definition($repositoryClass, [$definition['base_url'], $routes]); |
133
|
|
|
$repository->setPublic(false); |
134
|
|
|
|
135
|
|
|
$client = new Definition($clientClass, [ |
136
|
|
|
new Reference('mrtn_json_api.http_client'), |
137
|
|
|
new Reference('mrtn_json_api.route_repository.' . $name) |
138
|
|
|
]); |
139
|
|
|
|
140
|
|
|
$container->setDefinition('mrtn_json_api.route_repository.' . $name, $repository); |
141
|
|
|
$container->setDefinition('mrtn_json_api.http_client.' . $name, $client); |
142
|
|
|
} |
143
|
|
|
} |
144
|
|
|
|
145
|
|
|
/** |
146
|
|
|
* Create definition of routes for a route repository by a collection of endpoints |
147
|
|
|
* |
148
|
|
|
* @param array $resources |
149
|
|
|
* @return array |
150
|
|
|
*/ |
151
|
|
|
protected function createRoutesDefinition(array $resources): array |
152
|
|
|
{ |
153
|
|
|
$definition = []; |
154
|
|
|
|
155
|
|
|
foreach ($resources as $name => $resource) |
156
|
|
|
{ |
157
|
|
|
$methods = array_keys($resource['methods']); |
158
|
|
|
$methods = array_map('strtoupper', $methods); |
159
|
|
|
|
160
|
|
|
$definition[$name] = [ |
161
|
|
|
'path' => trim($resource['path']), |
162
|
|
|
'methods' => array_map('trim', $methods) |
163
|
|
|
]; |
164
|
|
|
} |
165
|
|
|
|
166
|
|
|
return $definition; |
167
|
|
|
} |
168
|
|
|
|
169
|
|
|
/** |
170
|
|
|
* {@inheritdoc} |
171
|
|
|
*/ |
172
|
|
|
public function getAlias() |
173
|
|
|
{ |
174
|
|
|
return self::ALIAS; |
175
|
|
|
} |
176
|
|
|
} |
This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.