1
|
|
|
<?php |
2
|
|
|
namespace EventEspresso\core\services\container; |
3
|
|
|
|
4
|
|
|
use EventEspresso\core\exceptions\InvalidClassException; |
5
|
|
|
use EventEspresso\core\exceptions\InvalidIdentifierException; |
6
|
|
|
use EventEspresso\core\services\container\exceptions\InstantiationException; |
7
|
|
|
|
8
|
|
|
if ( ! defined('EVENT_ESPRESSO_VERSION')) { |
9
|
|
|
exit('No direct script access allowed'); |
10
|
|
|
} |
11
|
|
|
|
12
|
|
|
|
13
|
|
|
|
14
|
|
|
/** |
15
|
|
|
* Class CoffeeMaker |
16
|
|
|
* Abstract Parent class for CoffeeMakers which are responsible |
17
|
|
|
* for building objects that are requested from the CoffeeShop |
18
|
|
|
* |
19
|
|
|
* @package Event Espresso |
20
|
|
|
* @author Brent Christensen |
21
|
|
|
* @since 4.9.1 |
22
|
|
|
*/ |
23
|
|
|
abstract class CoffeeMaker implements CoffeeMakerInterface |
24
|
|
|
{ |
25
|
|
|
|
26
|
|
|
/** |
27
|
|
|
* Indicates that CoffeeMaker should construct a NEW entity instance from the provided arguments (if given) |
28
|
|
|
*/ |
29
|
|
|
const BREW_NEW = 'new'; |
30
|
|
|
|
31
|
|
|
/** |
32
|
|
|
* Indicates that CoffeeMaker should always return a SHARED instance |
33
|
|
|
*/ |
34
|
|
|
const BREW_SHARED = 'shared'; |
35
|
|
|
|
36
|
|
|
/** |
37
|
|
|
* Indicates that CoffeeMaker should only load the file/class/interface but NOT instantiate |
38
|
|
|
*/ |
39
|
|
|
const BREW_LOAD_ONLY = 'load_only'; |
40
|
|
|
|
41
|
|
|
|
42
|
|
|
/** |
43
|
|
|
* @var CoffeePotInterface $coffee_pot |
44
|
|
|
*/ |
45
|
|
|
private $coffee_pot; |
46
|
|
|
|
47
|
|
|
/** |
48
|
|
|
* @var DependencyInjector $injector |
49
|
|
|
*/ |
50
|
|
|
private $injector; |
51
|
|
|
|
52
|
|
|
|
53
|
|
|
|
54
|
|
|
/** |
55
|
|
|
* @return array |
56
|
|
|
*/ |
57
|
|
|
public static function getTypes() |
58
|
|
|
{ |
59
|
|
|
return (array)apply_filters( |
60
|
|
|
'FHEE__EventEspresso\core\services\container\CoffeeMaker__getTypes', |
61
|
|
|
array( |
62
|
|
|
CoffeeMaker::BREW_NEW, |
63
|
|
|
CoffeeMaker::BREW_SHARED, |
64
|
|
|
CoffeeMaker::BREW_LOAD_ONLY, |
65
|
|
|
) |
66
|
|
|
); |
67
|
|
|
} |
68
|
|
|
|
69
|
|
|
|
70
|
|
|
|
71
|
|
|
/** |
72
|
|
|
* @param $type |
73
|
|
|
*/ |
74
|
|
View Code Duplication |
public static function validateType($type) |
|
|
|
|
75
|
|
|
{ |
76
|
|
|
$types = CoffeeMaker::getTypes(); |
77
|
|
|
if ( ! in_array($type, $types)) { |
78
|
|
|
throw new InvalidIdentifierException( |
79
|
|
|
is_object($type) ? get_class($type) : gettype($type), |
80
|
|
|
__( |
81
|
|
|
'recipe type (one of the class constants on \EventEspresso\core\services\container\CoffeeMaker)', |
82
|
|
|
'event_espresso' |
83
|
|
|
) |
84
|
|
|
); |
85
|
|
|
} |
86
|
|
|
return $type; |
87
|
|
|
} |
88
|
|
|
|
89
|
|
|
|
90
|
|
|
|
91
|
|
|
/** |
92
|
|
|
* CoffeeMaker constructor. |
93
|
|
|
* |
94
|
|
|
* @param CoffeePotInterface $coffee_pot |
95
|
|
|
* @param InjectorInterface $injector |
96
|
|
|
*/ |
97
|
|
|
public function __construct(CoffeePotInterface $coffee_pot, InjectorInterface $injector) |
98
|
|
|
{ |
99
|
|
|
$this->coffee_pot = $coffee_pot; |
100
|
|
|
$this->injector = $injector; |
|
|
|
|
101
|
|
|
} |
102
|
|
|
|
103
|
|
|
|
104
|
|
|
|
105
|
|
|
/** |
106
|
|
|
* @return \EventEspresso\core\services\container\CoffeePotInterface |
107
|
|
|
*/ |
108
|
|
|
protected function coffeePot() |
109
|
|
|
{ |
110
|
|
|
return $this->coffee_pot; |
111
|
|
|
} |
112
|
|
|
|
113
|
|
|
|
114
|
|
|
|
115
|
|
|
/** |
116
|
|
|
* @return \EventEspresso\core\services\container\DependencyInjector |
117
|
|
|
*/ |
118
|
|
|
protected function injector() |
119
|
|
|
{ |
120
|
|
|
return $this->injector; |
121
|
|
|
} |
122
|
|
|
|
123
|
|
|
|
124
|
|
|
|
125
|
|
|
/** |
126
|
|
|
* Examines the constructor to determine which method should be used for instantiation |
127
|
|
|
* |
128
|
|
|
* @param \ReflectionClass $reflector |
129
|
|
|
* @return mixed |
130
|
|
|
*/ |
131
|
|
|
protected function resolveInstantiationMethod(\ReflectionClass $reflector) |
132
|
|
|
{ |
133
|
|
|
if ($reflector->getConstructor() === null) { |
134
|
|
|
return 'NewInstance'; |
135
|
|
|
} else if ($reflector->isInstantiable()) { |
136
|
|
|
return 'NewInstanceArgs'; |
137
|
|
|
} else if (method_exists($reflector->getName(), 'instance')) { |
138
|
|
|
return 'instance'; |
139
|
|
|
} else if (method_exists($reflector->getName(), 'new_instance')) { |
140
|
|
|
return 'new_instance'; |
141
|
|
|
} else if (method_exists($reflector->getName(), 'new_instance_from_db')) { |
142
|
|
|
return 'new_instance_from_db'; |
143
|
|
|
} else { |
144
|
|
|
throw new InstantiationException($reflector->getName()); |
145
|
|
|
} |
146
|
|
|
} |
147
|
|
|
|
148
|
|
|
|
149
|
|
|
|
150
|
|
|
/** |
151
|
|
|
* Ensures files for classes that are not PSR-4 compatible are loaded |
152
|
|
|
* and then verifies that classes exist where applicable |
153
|
|
|
* |
154
|
|
|
* @param RecipeInterface $recipe |
155
|
|
|
* @throws InvalidClassException |
156
|
|
|
*/ |
157
|
|
|
protected function resolveClassAndFilepath(RecipeInterface $recipe) |
158
|
|
|
{ |
159
|
|
|
$paths = $recipe->paths(); |
160
|
|
|
if ( ! empty($paths)) { |
161
|
|
|
foreach ($paths as $path) { |
162
|
|
|
if (strpos($path, '*') === false && is_readable($path)) { |
163
|
|
|
require_once($path); |
164
|
|
|
} |
165
|
|
|
} |
166
|
|
|
} |
167
|
|
|
// re: using "false" for class_exists() second param: |
168
|
|
|
// if a class name is not already known to PHP, then class_exists() will run through |
169
|
|
|
// all of the registered spl_autoload functions until it either finds the class, |
170
|
|
|
// or gets to the end of the registered spl_autoload functions. |
171
|
|
|
// When the second parameter is true, it will also attempt to load the class file, |
172
|
|
|
// but it will also trigger an error if the class can not be loaded. |
173
|
|
|
// We don't want that extra error in the mix, so we have set the second param to "false" |
174
|
|
|
if ($recipe->type() !== CoffeeMaker::BREW_LOAD_ONLY && ! class_exists($recipe->fqcn(), false)) { |
175
|
|
|
throw new InvalidClassException($recipe->identifier()); |
176
|
|
|
} |
177
|
|
|
} |
178
|
|
|
|
179
|
|
|
|
180
|
|
|
|
181
|
|
|
|
182
|
|
|
} |
183
|
|
|
// End of file CoffeeMaker.php |
184
|
|
|
// Location: /CoffeeMaker.php |
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.