1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Monospice\LaravelRedisSentinel; |
4
|
|
|
|
5
|
|
|
use Illuminate\Cache\CacheManager; |
6
|
|
|
use Illuminate\Cache\RedisStore; |
7
|
|
|
use Illuminate\Queue\QueueManager; |
8
|
|
|
use Illuminate\Queue\Connectors\RedisConnector; |
9
|
|
|
use Illuminate\Session\CacheBasedSessionHandler; |
10
|
|
|
use Illuminate\Session\SessionManager; |
11
|
|
|
use Illuminate\Support\Arr; |
12
|
|
|
use Illuminate\Support\ServiceProvider; |
13
|
|
|
use Monospice\LaravelRedisSentinel\RedisSentinelManager; |
14
|
|
|
use Monospice\LaravelRedisSentinel\Manager; |
15
|
|
|
|
16
|
|
|
/** |
17
|
|
|
* Registers the "redis-sentinel" driver as an available driver for Laravel's |
18
|
|
|
* cache, session, and queue services and loads the appropriate configuration. |
19
|
|
|
* |
20
|
|
|
* @category Package |
21
|
|
|
* @package Monospice\LaravelRedisSentinel |
22
|
|
|
* @author Cy Rossignol <[email protected]> |
23
|
|
|
* @license See LICENSE file |
24
|
|
|
* @link http://github.com/monospice/laravel-redis-sentinel-drivers |
25
|
|
|
*/ |
26
|
|
|
class RedisSentinelServiceProvider extends ServiceProvider |
27
|
|
|
{ |
28
|
|
|
/** |
29
|
|
|
* Boot the service by registering extensions with Laravel's cache, queue, |
30
|
|
|
* and session managers for the "redis-sentinel" driver. |
31
|
|
|
* |
32
|
|
|
* @return void |
33
|
|
|
*/ |
34
|
|
|
public function boot() |
35
|
|
|
{ |
36
|
|
|
$this->addRedisSentinelCacheDriver($this->app->make('cache')); |
37
|
|
|
$this->addRedisSentinelQueueConnector($this->app->make('queue')); |
38
|
|
|
|
39
|
|
|
// Lumen removed session support since version 5.2, so we'll only bind |
40
|
|
|
// the Sentinel session handler if we're running Laravel. |
41
|
|
|
if (! $this->isLumenApplication()) { |
42
|
|
|
$this->addRedisSentinelSessionHandler($this->app->make('session')); |
43
|
|
|
} |
44
|
|
|
|
45
|
|
|
// If we want Laravel's Redis API to use Sentinel, we'll remove the |
46
|
|
|
// "redis" service from the list of deferred services in the container: |
47
|
|
|
if ($this->shouldOverrideLaravelApi()) { |
48
|
|
|
$this->removeDeferredRedisServices(); |
49
|
|
|
} |
50
|
|
|
} |
51
|
|
|
|
52
|
|
|
/** |
53
|
|
|
* Bind the "redis-sentinel" database driver to the application service |
54
|
|
|
* container. |
55
|
|
|
* |
56
|
|
|
* @return void |
57
|
|
|
*/ |
58
|
|
|
public function register() |
59
|
|
|
{ |
60
|
|
|
$class = $this->getVersionedRedisSentinelManagerClass(); |
61
|
|
|
|
62
|
|
|
$this->app->singleton('redis-sentinel', function ($app) use ($class) { |
63
|
|
|
$config = $app->make('config')->get('database.redis-sentinel'); |
64
|
|
|
$driver = Arr::pull($config, 'client', 'predis'); |
65
|
|
|
|
66
|
|
|
return new RedisSentinelManager(new $class($driver, $config)); |
67
|
|
|
}); |
68
|
|
|
|
69
|
|
|
// If we want Laravel's Redis API to use Sentinel, we'll return an |
70
|
|
|
// instance of the RedisSentinelManager when requesting the "redis" |
71
|
|
|
// service: |
72
|
|
|
if ($this->shouldOverrideLaravelApi()) { |
73
|
|
|
$this->registerOverrides(); |
74
|
|
|
} |
75
|
|
|
} |
76
|
|
|
|
77
|
|
|
/** |
78
|
|
|
* Replace the standard Laravel Redis service with the Redis Sentinel |
79
|
|
|
* database driver so all Redis operations use Sentinel connections. |
80
|
|
|
* |
81
|
|
|
* @return void |
82
|
|
|
*/ |
83
|
|
|
protected function registerOverrides() |
84
|
|
|
{ |
85
|
|
|
$this->app->singleton('redis', function ($app) { |
86
|
|
|
return $app->make('redis-sentinel'); |
87
|
|
|
}); |
88
|
|
|
|
89
|
|
|
$this->app->bind('redis.connection', function ($app) { |
90
|
|
|
return $app->make('redis-sentinel')->connection(); |
91
|
|
|
}); |
92
|
|
|
} |
93
|
|
|
|
94
|
|
|
/** |
95
|
|
|
* Remove the standard Laravel Redis service from the bound deferred |
96
|
|
|
* services so they don't overwrite Redis Sentinel registrations. |
97
|
|
|
* |
98
|
|
|
* @return void |
99
|
|
|
*/ |
100
|
|
|
protected function removeDeferredRedisServices() |
101
|
|
|
{ |
102
|
|
|
if ($this->isLumenApplication()) { |
103
|
|
|
return; |
104
|
|
|
} |
105
|
|
|
|
106
|
|
|
$deferredServices = $this->app->getDeferredServices(); |
107
|
|
|
|
108
|
|
|
unset($deferredServices['redis']); |
109
|
|
|
unset($deferredServices['redis.connection']); |
110
|
|
|
|
111
|
|
|
$this->app->setDeferredServices($deferredServices); |
112
|
|
|
} |
113
|
|
|
|
114
|
|
|
/** |
115
|
|
|
* Add "redis-sentinel" as an available driver option to the Laravel cache |
116
|
|
|
* manager. |
117
|
|
|
* |
118
|
|
|
* @param CacheManager $cache The Laravel cache manager |
119
|
|
|
* |
120
|
|
|
* @return void |
121
|
|
|
*/ |
122
|
|
|
protected function addRedisSentinelCacheDriver(CacheManager $cache) |
123
|
|
|
{ |
124
|
|
|
$cache->extend('redis-sentinel', function ($app, $conf) use ($cache) { |
125
|
|
|
$redis = $app->make('redis-sentinel')->getVersionedManager(); |
126
|
|
|
$prefix = $app->make('config')->get('cache.prefix'); |
127
|
|
|
$connection = Arr::get($conf, 'connection', 'default'); |
128
|
|
|
$store = new RedisStore($redis, $prefix, $connection); |
129
|
|
|
|
130
|
|
|
return $cache->repository($store); |
131
|
|
|
}); |
132
|
|
|
} |
133
|
|
|
|
134
|
|
|
/** |
135
|
|
|
* Add "redis-sentinel" as an available driver option to the Laravel |
136
|
|
|
* session manager. |
137
|
|
|
* |
138
|
|
|
* @param SessionManager $session The Laravel session manager |
139
|
|
|
* |
140
|
|
|
* @return void |
141
|
|
|
*/ |
142
|
|
|
protected function addRedisSentinelSessionHandler(SessionManager $session) |
143
|
|
|
{ |
144
|
|
|
$session->extend('redis-sentinel', function ($app) { |
145
|
|
|
$config = $app->make('config'); |
146
|
|
|
|
147
|
|
|
$cacheDriver = clone $app->make('cache')->driver('redis-sentinel'); |
148
|
|
|
$minutes = $config->get('session.lifetime'); |
149
|
|
|
$connection = $config->get('session.connection'); |
150
|
|
|
|
151
|
|
|
$cacheDriver->getStore()->setConnection($connection); |
152
|
|
|
|
153
|
|
|
return new CacheBasedSessionHandler($cacheDriver, $minutes); |
154
|
|
|
}); |
155
|
|
|
} |
156
|
|
|
|
157
|
|
|
/** |
158
|
|
|
* Add "redis-sentinel" as an available queue connection driver option to |
159
|
|
|
* the Laravel queue manager. |
160
|
|
|
* |
161
|
|
|
* @param QueueManager $queue The Laravel queue manager |
162
|
|
|
* |
163
|
|
|
* @return void |
164
|
|
|
*/ |
165
|
|
|
protected function addRedisSentinelQueueConnector(QueueManager $queue) |
166
|
|
|
{ |
167
|
|
|
$queue->extend('redis-sentinel', function () { |
168
|
|
|
$redis = $this->app->make('redis-sentinel')->getVersionedManager(); |
169
|
|
|
|
170
|
|
|
return new RedisConnector($redis); |
171
|
|
|
}); |
172
|
|
|
} |
173
|
|
|
|
174
|
|
|
/** |
175
|
|
|
* Determine whether this package should replace Laravel's Redis API |
176
|
|
|
* ("Redis" facade and "redis" service binding). |
177
|
|
|
* |
178
|
|
|
* @return bool True if "database.redis.driver" configuration option is |
179
|
|
|
* set to "sentinel" |
180
|
|
|
*/ |
181
|
|
|
protected function shouldOverrideLaravelApi() |
182
|
|
|
{ |
183
|
|
|
$driver = $this->app->make('config')->get('database.redis.driver'); |
184
|
|
|
|
185
|
|
|
return $driver === 'sentinel'; |
186
|
|
|
} |
187
|
|
|
|
188
|
|
|
/** |
189
|
|
|
* Get the fully-qualified class name of the RedisSentinelManager class |
190
|
|
|
* for the current version of Laravel or Lumen. |
191
|
|
|
* |
192
|
|
|
* @return string The class name of the appropriate RedisSentinelManager |
193
|
|
|
* with its namespace |
194
|
|
|
*/ |
195
|
|
|
protected function getVersionedRedisSentinelManagerClass() |
196
|
|
|
{ |
197
|
|
|
if ($this->isLumenApplication()) { |
198
|
|
|
$appVersion = substr($this->app->version(), 7, 3); |
199
|
|
|
$frameworkVersion = '5.4'; |
200
|
|
|
} else { |
201
|
|
|
$appVersion = \Illuminate\Foundation\Application::VERSION; |
202
|
|
|
$frameworkVersion = '5.4.20'; |
203
|
|
|
} |
204
|
|
|
|
205
|
|
|
if (version_compare($appVersion, $frameworkVersion, 'lt')) { |
206
|
|
|
return Manager\Laravel540RedisSentinelManager::class; |
207
|
|
|
} |
208
|
|
|
|
209
|
|
|
return Manager\Laravel5420RedisSentinelManager::class; |
210
|
|
|
} |
211
|
|
|
|
212
|
|
|
/** |
213
|
|
|
* Determine if the current application runs the Lumen framework instead of |
214
|
|
|
* Laravel. |
215
|
|
|
* |
216
|
|
|
* @return bool True if running Lumen |
217
|
|
|
*/ |
218
|
|
|
protected function isLumenApplication() |
219
|
|
|
{ |
220
|
|
|
return $this->app instanceof \Laravel\Lumen\Application; |
|
|
|
|
221
|
|
|
} |
222
|
|
|
} |
223
|
|
|
|
This error could be the result of:
1. Missing dependencies
PHP Analyzer uses your
composer.json
file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects thecomposer.json
to be in the root folder of your repository.Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the
require
orrequire-dev
section?2. Missing use statement
PHP does not complain about undefined classes in
ìnstanceof
checks. For example, the following PHP code will work perfectly fine:If you have not tested against this specific condition, such errors might go unnoticed.