-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLazyFieldSetRegistry.php
117 lines (100 loc) · 3.7 KB
/
LazyFieldSetRegistry.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
<?php
declare(strict_types=1);
/*
* This file is part of the RollerworksSearch package.
*
* (c) Sebastiaan Stok <[email protected]>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace Rollerworks\Component\Search;
use Psr\Container\ContainerInterface;
use Rollerworks\Component\Search\Exception\InvalidArgumentException;
use Rollerworks\Component\Search\Loader\ClosureContainer;
/**
* LazyFieldSetRegistry tries to lazily load the FieldSetConfigurator
* from s PSR-11 compatible Container or by FQCN.
*
* @author Sebastiaan Stok <[email protected]>
*/
final class LazyFieldSetRegistry implements FieldSetRegistry
{
private $container;
/**
* @var FieldSetConfigurator[]
*/
private $configurators = [];
/**
* @var array
*/
private $serviceIds;
/**
* Constructor.
*
* Note you don't have to register the Configurator when it has no constructor
* or setter dependencies. You can simple use the FQCN of the configurator class,
* and will be initialized upon first usage.
*
* @param ContainerInterface $container A Service locator able to lazily load
* the FieldSet configurators
* @param array $serviceIds Configurator name (FQCN) to service-id mapping
*/
public function __construct(ContainerInterface $container, array $serviceIds)
{
$this->container = $container;
$this->serviceIds = $serviceIds;
}
/**
* Creates a new LazyFieldSetRegistry with easy factories for loading.
*
* @param \Closure[] $configurators an array of lazy loading configurators.
* The Closure when called is expected to return
* a FieldSetConfiguratorInterface object
*/
public static function create(array $configurators = []): self
{
$names = array_keys($configurators);
return new self(new ClosureContainer($configurators), array_combine($names, $names));
}
/**
* Returns a FieldSetConfigurator by name.
*
* @param string $name The name of the FieldSet configurator
*
* @throws InvalidArgumentException if the configurator can not be retrieved
*/
public function getConfigurator(string $name): FieldSetConfigurator
{
if (! isset($this->configurators[$name])) {
if (isset($this->serviceIds[$name])) {
$configurator = $this->container->get($this->serviceIds[$name]);
} elseif (class_exists($name)) {
// Support fully-qualified class names.
$configurator = new $name();
} else {
throw new InvalidArgumentException(\sprintf('Could not load FieldSet configurator "%s".', $name));
}
if (! $configurator instanceof FieldSetConfigurator) {
throw new InvalidArgumentException(\sprintf('Configurator class "%s" is expected to be an instance of ' . FieldSetConfigurator::class, $name));
}
$this->configurators[$name] = $configurator;
}
return $this->configurators[$name];
}
/**
* Returns whether the given FieldSetConfigurator is supported.
*
* @param string $name The name of the FieldSet configurator
*/
public function hasConfigurator(string $name): bool
{
if (isset($this->configurators[$name])) {
return true;
}
if (isset($this->serviceIds[$name])) {
return true;
}
return class_exists($name) && \in_array(FieldSetConfigurator::class, class_implements($name), true);
}
}