1 | <?php |
||
61 | class Loader |
||
62 | { |
||
63 | /** |
||
64 | * The path to the package's default configuration file. |
||
65 | * |
||
66 | * @var string |
||
67 | */ |
||
68 | const CONFIG_PATH = __DIR__ . '/../../config/redis-sentinel.php'; |
||
69 | |||
70 | /** |
||
71 | * Indicates whether the current application runs the Lumen framework. |
||
72 | * |
||
73 | * @var bool |
||
74 | */ |
||
75 | public $isLumen; |
||
76 | |||
77 | /** |
||
78 | * Indicates whether the current application supports sessions. |
||
79 | * |
||
80 | * @var bool |
||
81 | */ |
||
82 | public $supportsSessions; |
||
83 | |||
84 | /** |
||
85 | * The current application instance that provides context and services |
||
86 | * used to load the appropriate configuration. |
||
87 | * |
||
88 | * @var Container |
||
89 | */ |
||
90 | private $app; |
||
91 | |||
92 | /** |
||
93 | * Used to fetch and set application configuration values. |
||
94 | * |
||
95 | * @var \Illuminate\Contracts\Config\Repository |
||
96 | */ |
||
97 | private $config; |
||
98 | |||
99 | /** |
||
100 | * Contains the set of configuration values used to configure the package |
||
101 | * as loaded from "config/redis-sentinel.php". Empty when the application's |
||
102 | * standard config files provide all the values needed to configure the |
||
103 | * package (such as when a developer provides a custom config). |
||
104 | * |
||
105 | * @var array |
||
106 | */ |
||
107 | private $packageConfig; |
||
108 | |||
109 | /** |
||
110 | * Initialize the configuration loader. Any actual loading occurs when |
||
111 | * calling the 'loadConfiguration()' method. |
||
112 | * |
||
113 | * @param Container $app The current application instance that provides |
||
114 | * context and services needed to load the appropriate configuration. |
||
115 | */ |
||
116 | public function __construct(Container $app) |
||
126 | |||
127 | /** |
||
128 | * Create an instance of the loader and load the configuration in one step. |
||
129 | * |
||
130 | * @param Container $app The current application instance that provides |
||
131 | * context and services needed to load the appropriate configuration. |
||
132 | * |
||
133 | * @return self An initialized instance of this class |
||
134 | */ |
||
135 | public static function load(Container $app) |
||
142 | |||
143 | /** |
||
144 | * Load the package configuration. |
||
145 | * |
||
146 | * @return void |
||
147 | */ |
||
148 | public function loadConfiguration() |
||
160 | |||
161 | /** |
||
162 | * Determine whether the package should override Laravel's standard Redis |
||
163 | * API ("Redis" facade and "redis" service binding). |
||
164 | * |
||
165 | * @return bool TRUE if the package should override Laravel's standard |
||
166 | * Redis API |
||
167 | */ |
||
168 | public function shouldOverrideLaravelRedisApi() |
||
172 | |||
173 | /** |
||
174 | * Determine if the package should automatically configure itself. |
||
175 | * |
||
176 | * Developers may set the value of "redis-sentinel.load_config" to FALSE to |
||
177 | * disable the package's automatic configuration. This class also sets this |
||
178 | * value to FALSE after loading the package configuration to skip the auto- |
||
179 | * configuration when the application cached its configuration values (via |
||
180 | * "artisan config:cache", for example). |
||
181 | * |
||
182 | * @return bool TRUE if the package should load its configuration |
||
183 | */ |
||
184 | protected function shouldLoadConfiguration() |
||
192 | |||
193 | /** |
||
194 | * Configure the Lumen components that this package depends on. |
||
195 | * |
||
196 | * Lumen lazily loads many of its components. We must instruct Lumen to |
||
197 | * load the configuration for components that this class configures so |
||
198 | * that the values are accessible and so that the framework does not |
||
199 | * revert the configuration settings that this class changes when one of |
||
200 | * the components initializes later. |
||
201 | * |
||
202 | * @return void |
||
203 | */ |
||
204 | protected function configureLumenComponents() |
||
210 | |||
211 | /** |
||
212 | * Reconcile the package configuration and use it to set the appropriate |
||
213 | * configuration values for other application components. |
||
214 | * |
||
215 | * @return void |
||
216 | */ |
||
217 | protected function loadPackageConfiguration() |
||
231 | |||
232 | /** |
||
233 | * Set the application configuration value for the specified key with the |
||
234 | * value from the package configuration. |
||
235 | * |
||
236 | * @param string $configKey The key of the config value to set. Should |
||
237 | * correspond to a key in the package's configuration. |
||
238 | * @param bool $checkExists If TRUE, don't set the value if the key |
||
239 | * already exists in the application configuration. |
||
240 | * |
||
241 | * @return void |
||
242 | */ |
||
243 | protected function setConfigurationFor($configKey, $checkExists = true) |
||
253 | |||
254 | /** |
||
255 | * Set the application session configuration as specified by the package's |
||
256 | * configuration if the app supports sessions. |
||
257 | * |
||
258 | * @return void |
||
259 | */ |
||
260 | protected function setSessionConfiguration() |
||
271 | |||
272 | /** |
||
273 | * Get the package configuration for the specified key. |
||
274 | * |
||
275 | * @param string $configKey The key of the configuration value to get |
||
276 | * |
||
277 | * @return mixed The value of the configuration with the specified key |
||
278 | */ |
||
279 | protected function getPackageConfigurationFor($configKey) |
||
287 | |||
288 | /** |
||
289 | * Merge the package's default configuration with the override config file |
||
290 | * supplied by the developer, if any. |
||
291 | * |
||
292 | * @return void |
||
293 | */ |
||
294 | protected function mergePackageConfiguration() |
||
301 | |||
302 | /** |
||
303 | * Parse Redis Sentinel connection host definitions to create single host |
||
304 | * entries for host definitions that specify multiple hosts. |
||
305 | * |
||
306 | * To support environment-based configuration using the package's default |
||
307 | * configuration, developers need a way to specifiy multiple Sentinel hosts |
||
308 | * using environment variables. The package supports this requirement by |
||
309 | * allowing developers to provide a comma-delimited string of hosts in a |
||
310 | * "*_HOST" environment variable: |
||
311 | * |
||
312 | * REDIS_HOST=sentinel1.example.com,sentinel2.example.com |
||
313 | * |
||
314 | * Before parsing the connection configuration, the connection config would |
||
315 | * contain the following value if using the environment variable above: |
||
316 | * |
||
317 | * 'connection' => [ |
||
318 | * [ |
||
319 | * 'host' => 'sentinel1.example.com,sentinel2.example.com', |
||
320 | * 'port' => 26379, |
||
321 | * ] |
||
322 | * ] |
||
323 | * |
||
324 | * This method will convert the connection configuration to: |
||
325 | * |
||
326 | * 'connection' => [ |
||
327 | * [ |
||
328 | * 'host' => 'sentinel1.example.com', |
||
329 | * 'port' => 26379, |
||
330 | * ], |
||
331 | * [ |
||
332 | * 'host' => 'sentinel2.example.com', |
||
333 | * 'port' => 26379, |
||
334 | * ] |
||
335 | * ] |
||
336 | * |
||
337 | * @return void |
||
338 | */ |
||
339 | protected function normalizeHosts() |
||
357 | |||
358 | /** |
||
359 | * Create single host entries for any host definitions that specify |
||
360 | * multiple hosts in the provided connection configuration. |
||
361 | * |
||
362 | * @param array $connection The connection config which contains the host |
||
363 | * definitions for a single Redis Sentinel connection |
||
364 | * |
||
365 | * @return array The normalized connection configuration values |
||
366 | */ |
||
367 | protected function normalizeConnectionHosts(array $connection) |
||
382 | |||
383 | /** |
||
384 | * Parse the provided host definition into multiple host definitions if it |
||
385 | * specifies more than one host. |
||
386 | * |
||
387 | * @param array|string $host The host definition from a Redis Sentinel |
||
388 | * connection |
||
389 | * |
||
390 | * @return array One or more host definitions parsed from the provided |
||
391 | * host definition |
||
392 | */ |
||
393 | protected function normalizeHost($host) |
||
405 | |||
406 | /** |
||
407 | * Parse a host definition in the form of an array into multiple host |
||
408 | * definitions if it specifies more than one host. |
||
409 | * |
||
410 | * @param array $hostArray The host definition from a Redis Sentinel |
||
411 | * connection |
||
412 | * |
||
413 | * @return array One or more host definitions parsed from the provided |
||
414 | * host definition |
||
415 | */ |
||
416 | protected function normalizeHostArray(array $hostArray) |
||
426 | |||
427 | /** |
||
428 | * Parse a host definition in the form of a string into multiple host |
||
429 | * definitions it it specifies more than one host. |
||
430 | * |
||
431 | * @param string $hostString The host definition from a Redis Sentinel |
||
432 | * connection |
||
433 | * @param int $port The port number to use for the resulting host |
||
434 | * definitions if the parsed host definition doesn't contain port numbers |
||
435 | * |
||
436 | * @return array One or more host definitions parsed from the provided |
||
437 | * host definition |
||
438 | */ |
||
439 | protected function normalizeHostString($hostString, $port = 26379) |
||
455 | |||
456 | /** |
||
457 | * Remove the package's configuration from the application configuration |
||
458 | * repository. |
||
459 | * |
||
460 | * This package's configuration contains partial elements from several |
||
461 | * other component configurations. By default, the package removes its |
||
462 | * configuration after merging the values into each of the appropriate |
||
463 | * config locations for the components it initializes. This behavior |
||
464 | * prevents the artisan "config:cache" command from saving unnecessary |
||
465 | * configuration values to the cache file. |
||
466 | * |
||
467 | * @return void |
||
468 | */ |
||
469 | protected function cleanPackageConfiguration() |
||
480 | } |
||
481 |
Let’s take a look at an example:
In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.
Available Fixes
Change the type-hint for the parameter:
Add an additional type-check:
Add the method to the interface: