|
1
|
|
|
<?php |
|
2
|
|
|
/** |
|
3
|
|
|
* YAWIK |
|
4
|
|
|
* |
|
5
|
|
|
* @filesource |
|
6
|
|
|
* @license MIT |
|
7
|
|
|
* @copyright 2013 - 2016 Cross Solution <http://cross-solution.de> |
|
8
|
|
|
*/ |
|
9
|
|
|
|
|
10
|
|
|
/** */ |
|
11
|
|
|
namespace Core\Factory; |
|
12
|
|
|
|
|
13
|
|
|
use Interop\Container\ContainerInterface; |
|
14
|
|
|
use Interop\Container\Exception\ContainerException; |
|
15
|
|
|
use Zend\ServiceManager\AbstractFactoryInterface; |
|
16
|
|
|
use Zend\ServiceManager\Exception\ServiceNotCreatedException; |
|
17
|
|
|
use Zend\ServiceManager\Exception\ServiceNotFoundException; |
|
18
|
|
|
use Zend\ServiceManager\ServiceLocatorInterface; |
|
19
|
|
|
use Zend\Stdlib\AbstractOptions; |
|
20
|
|
|
|
|
21
|
|
|
/** |
|
22
|
|
|
* Creates options instances from configuration specifications. |
|
23
|
|
|
* |
|
24
|
|
|
* @author Mathias Gelhausen <[email protected]> |
|
25
|
|
|
* @since 0.23 |
|
26
|
|
|
*/ |
|
27
|
|
|
class OptionsAbstractFactory implements AbstractFactoryInterface |
|
28
|
|
|
{ |
|
29
|
|
|
|
|
30
|
|
|
/** |
|
31
|
|
|
* Simple mode handles only skalar values, arrays and POPOs. |
|
32
|
|
|
*/ |
|
33
|
|
|
const MODE_SIMPLE = 'simple'; |
|
34
|
|
|
|
|
35
|
|
|
/** |
|
36
|
|
|
* Nested mode is able to handle other options instances as an option value. |
|
37
|
|
|
*/ |
|
38
|
|
|
const MODE_NESTED = 'nested'; |
|
39
|
|
|
|
|
40
|
|
|
/** |
|
41
|
|
|
* The configuration specification of all creatable options instances. |
|
42
|
|
|
* |
|
43
|
|
|
* The format is |
|
44
|
|
|
* <pre> |
|
45
|
|
|
* [ |
|
46
|
|
|
* 'ServiceNameOfTheOptionsInstance' => [ |
|
47
|
|
|
* 'class' => 'FQCN of the options class.', |
|
48
|
|
|
* 'mode' => SIMPLE or NESTED (optional, default SIMPLE) |
|
49
|
|
|
* 'options' => [ |
|
50
|
|
|
* 'simpleSkalar' => 'value', |
|
51
|
|
|
* 'simpleArray' => [ 'someArray' ], |
|
52
|
|
|
* 'nestedOptions' => [ |
|
53
|
|
|
* '__class__' => 'FQCN of the nested options class.', |
|
54
|
|
|
* 'someValue' => 'skalar' |
|
55
|
|
|
* ], |
|
56
|
|
|
* ], |
|
57
|
|
|
* ], |
|
58
|
|
|
* ]; |
|
59
|
|
|
* |
|
60
|
|
|
* @var array |
|
61
|
|
|
*/ |
|
62
|
|
|
protected $optionsConfig; |
|
63
|
|
|
|
|
64
|
|
|
/** |
|
65
|
|
|
* Create an object |
|
66
|
|
|
* |
|
67
|
|
|
* @param ContainerInterface $container |
|
68
|
|
|
* @param string $requestedName |
|
69
|
|
|
* @param null|array $options |
|
70
|
|
|
* |
|
71
|
|
|
* @return object |
|
72
|
|
|
* @throws ServiceNotFoundException if unable to resolve the service. |
|
73
|
|
|
* @throws ServiceNotCreatedException if an exception is raised when |
|
74
|
|
|
* creating a service. |
|
75
|
|
|
* @throws ContainerException if any other error occurs |
|
76
|
|
|
*/ |
|
77
|
|
|
public function __invoke(ContainerInterface $container, $requestedName, array $options = null) |
|
78
|
|
|
{ |
|
79
|
|
|
return new $requestedName(); |
|
80
|
|
|
} |
|
81
|
|
|
|
|
82
|
|
|
/** |
|
83
|
|
|
* Can the factory create an instance for the service? |
|
84
|
|
|
* |
|
85
|
|
|
* @param ContainerInterface $container |
|
86
|
|
|
* @param string $requestedName |
|
87
|
|
|
* |
|
88
|
|
|
* @return bool |
|
89
|
|
|
*/ |
|
90
|
|
|
public function canCreate(ContainerInterface $container, $requestedName) |
|
|
|
|
|
|
91
|
|
|
{ |
|
92
|
|
|
return class_exists($requestedName); |
|
93
|
|
|
} |
|
94
|
|
|
|
|
95
|
|
|
|
|
96
|
|
|
/** |
|
97
|
|
|
* Determines if we can create an options instance with name. |
|
98
|
|
|
* |
|
99
|
|
|
* @param ServiceLocatorInterface $serviceLocator |
|
100
|
|
|
* @param string $name |
|
101
|
|
|
* @param string $requestedName |
|
102
|
|
|
* |
|
103
|
|
|
* @return bool |
|
104
|
|
|
*/ |
|
105
|
|
|
public function canCreateServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName) |
|
106
|
|
|
{ |
|
107
|
|
|
// Load options config specifications the first time this method is called. |
|
108
|
|
|
if (null === $this->optionsConfig) { |
|
109
|
|
|
$mainConfig = $serviceLocator->get('config'); |
|
110
|
|
|
$this->optionsConfig = isset($mainConfig['options']) ? $mainConfig['options'] : []; |
|
111
|
|
|
} |
|
112
|
|
|
|
|
113
|
|
|
return false !== $this->getOptionsConfig($requestedName, $name); |
|
114
|
|
|
} |
|
115
|
|
|
|
|
116
|
|
|
/** |
|
117
|
|
|
* Creates an options instance with name. |
|
118
|
|
|
* |
|
119
|
|
|
* @param ServiceLocatorInterface $serviceLocator |
|
120
|
|
|
* @param string $name |
|
121
|
|
|
* @param string $requestedName |
|
122
|
|
|
* |
|
123
|
|
|
* @return AbstractOptions |
|
124
|
|
|
* @throws \InvalidArgumentException |
|
125
|
|
|
*/ |
|
126
|
|
|
public function createServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName) |
|
127
|
|
|
{ |
|
128
|
|
|
$config = $this->getOptionsConfig($requestedName, $name); |
|
129
|
|
|
|
|
130
|
|
|
if (!isset($config['class'])) { |
|
131
|
|
|
throw new \InvalidArgumentException(sprintf( |
|
132
|
|
|
'Missing index "class" from the config array for options "%s"', |
|
133
|
|
|
$requestedName |
|
134
|
|
|
)); |
|
135
|
|
|
} |
|
136
|
|
|
|
|
137
|
|
|
$className = $config['class']; |
|
138
|
|
|
$mode = isset($config['mode']) ? $config['mode'] : self::MODE_SIMPLE; |
|
139
|
|
|
$options = isset($config['options']) ? $config['options'] : []; |
|
140
|
|
|
|
|
141
|
|
|
if (self::MODE_SIMPLE == $mode) { |
|
142
|
|
|
return new $className($options); |
|
143
|
|
|
} |
|
144
|
|
|
|
|
145
|
|
|
if (self::MODE_NESTED == $mode) { |
|
146
|
|
|
return $this->createNestedOptions($className, $options); |
|
147
|
|
|
|
|
148
|
|
|
} |
|
149
|
|
|
|
|
150
|
|
|
throw new \InvalidArgumentException(sprintf('Unknown mode "%s".', $mode)); |
|
151
|
|
|
} |
|
152
|
|
|
|
|
153
|
|
|
|
|
154
|
|
|
/** |
|
155
|
|
|
* Creates a nested options instance. |
|
156
|
|
|
* |
|
157
|
|
|
* @param string $className |
|
158
|
|
|
* @param array $options |
|
159
|
|
|
* |
|
160
|
|
|
* @return AbstractOptions |
|
161
|
|
|
*/ |
|
162
|
|
|
protected function createNestedOptions($className, $options) |
|
163
|
|
|
{ |
|
164
|
|
|
$class = new $className(); |
|
165
|
|
|
|
|
166
|
|
|
foreach ($options as $key => $spec) { |
|
167
|
|
|
if (is_array($spec) && array_key_exists('__class__', $spec)) { |
|
168
|
|
|
$nestedClassName = $spec['__class__']; |
|
169
|
|
|
unset($spec['__class__']); |
|
170
|
|
|
$spec = $this->createNestedOptions($nestedClassName, $spec); |
|
171
|
|
|
} |
|
172
|
|
|
|
|
173
|
|
|
$class->{$key} = $spec; |
|
174
|
|
|
} |
|
175
|
|
|
|
|
176
|
|
|
return $class; |
|
177
|
|
|
} |
|
178
|
|
|
|
|
179
|
|
|
/** |
|
180
|
|
|
* Gets the configuration for a specific options instance. |
|
181
|
|
|
* |
|
182
|
|
|
* Returns FALSE if configuration cannot be found. |
|
183
|
|
|
* |
|
184
|
|
|
* @param string $fullName |
|
185
|
|
|
* @param string $normalizedName |
|
186
|
|
|
* |
|
187
|
|
|
* @return array|bool |
|
188
|
|
|
*/ |
|
189
|
|
|
protected function getOptionsConfig($fullName, $normalizedName) |
|
190
|
|
|
{ |
|
191
|
|
|
if (array_key_exists($fullName, $this->optionsConfig)) { |
|
192
|
|
|
return $this->optionsConfig[$fullName]; |
|
193
|
|
|
} |
|
194
|
|
|
|
|
195
|
|
|
if (array_key_exists($normalizedName, $this->optionsConfig)) { |
|
196
|
|
|
return $this->optionsConfig[$normalizedName]; |
|
197
|
|
|
} |
|
198
|
|
|
|
|
199
|
|
|
return false; |
|
200
|
|
|
} |
|
201
|
|
|
} |
This check examines a number of code elements and verifies that they conform to the given naming conventions.
You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.