Completed
Push — 2.x ( ae70d4...c1417c )
by Cy
04:39
created

removeDeferredRedisServices()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 13
rs 9.4285
cc 2
eloc 7
nc 2
nop 0
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;
0 ignored issues
show
Bug introduced by
The class Laravel\Lumen\Application does not exist. Did you forget a USE statement, or did you not list all dependencies?

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 the composer.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 or require-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 ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
221
    }
222
}
223