Completed
Branch 2.x (1080d0)
by Cy
04:46
created

getVersionedRedisSentinelManagerClass()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 8
rs 9.4285
cc 2
eloc 4
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\Foundation\Application;
8
use Illuminate\Queue\QueueManager;
9
use Illuminate\Queue\Connectors\RedisConnector;
10
use Illuminate\Session\CacheBasedSessionHandler;
11
use Illuminate\Session\SessionManager;
12
use Illuminate\Support\Arr;
13
use Illuminate\Support\ServiceProvider;
14
use Monospice\LaravelRedisSentinel\RedisSentinelManager;
15
use Monospice\LaravelRedisSentinel\Manager;
16
17
/**
18
 * Registers the "redis-sentinel" driver as an available driver for Laravel's
19
 * cache, session, and queue services and loads the appropriate configuration.
20
 *
21
 * @category Package
22
 * @package  Monospice\LaravelRedisSentinel
23
 * @author   Cy Rossignol <[email protected]>
24
 * @license  See LICENSE file
25
 * @link     http://github.com/monospice/laravel-redis-sentinel-drivers
26
 */
27
class RedisSentinelServiceProvider extends ServiceProvider
28
{
29
    /**
30
     * Boot the service by registering extensions with Laravel's cache, queue,
31
     * and session managers for the "redis-sentinel" driver.
32
     *
33
     * @return void
34
     */
35
    public function boot()
36
    {
37
        $this->addRedisSentinelCacheDriver($this->app->make('cache'));
38
        $this->addRedisSentinelSessionHandler($this->app->make('session'));
39
        $this->addRedisSentinelQueueConnector($this->app->make('queue'));
40
41
        // If we want Laravel's Redis API to use Sentinel, we'll remove the
42
        // "redis" service from the list of deferred services in the container:
43
        if ($this->shouldOverrideLaravelApi()) {
44
            $deferredServices = $this->app->getDeferredServices();
45
46
            unset($deferredServices['redis']);
47
            unset($deferredServices['redis.connection']);
48
49
            $this->app->setDeferredServices($deferredServices);
50
        }
51
    }
52
53
    /**
54
     * Bind the "redis-sentinel" database driver to the application service
55
     * container.
56
     *
57
     * @return void
58
     */
59
    public function register()
60
    {
61
        $class = $this->getVersionedRedisSentinelManagerClass();
62
63
        $this->app->singleton('redis-sentinel', function ($app) use ($class) {
64
            $config = $app->make('config')->get('database.redis-sentinel');
65
            $driver = Arr::pull($config, 'client', 'predis');
66
67
            return new RedisSentinelManager(new $class($driver, $config));
68
        });
69
70
        // If we want Laravel's Redis API to use Sentinel, we'll return an
71
        // instance of the RedisSentinelManager when requesting the "redis"
72
        // service:
73
        if ($this->shouldOverrideLaravelApi()) {
74
            $this->registerOverrides();
75
        }
76
    }
77
78
    /**
79
     * Replace the standard Laravel Redis service with the Redis Sentinel
80
     * database driver so all redis operations use Sentinel connections.
81
     *
82
     * @return void
83
     */
84
    protected function registerOverrides()
85
    {
86
        $this->app->singleton('redis', function ($app) {
87
            return $app->make('redis-sentinel');
88
        });
89
90
        $this->app->bind('redis.connection', function ($app) {
91
            return $app->make('redis-sentinel')->connection();
92
        });
93
    }
94
95
    /**
96
     * Add "redis-sentinel" as an available driver option to the Laravel cache
97
     * manager.
98
     *
99
     * @param CacheManager $cache The Laravel cache manager
100
     *
101
     * @return void
102
     */
103
    protected function addRedisSentinelCacheDriver(CacheManager $cache)
104
    {
105
        $cache->extend('redis-sentinel', function ($app, $conf) use ($cache) {
106
            $redis = $app->make('redis-sentinel')->getVersionedManager();
107
            $prefix = $app->make('config')->get('cache.prefix');
108
            $connection = Arr::get($conf, 'connection', 'default');
109
            $store = new RedisStore($redis, $prefix, $connection);
110
111
            return $cache->repository($store);
112
        });
113
    }
114
115
    /**
116
     * Add "redis-sentinel" as an available driver option to the Laravel
117
     * session manager.
118
     *
119
     * @param SessionManager $session The Laravel session manager
120
     *
121
     * @return void
122
     */
123
    protected function addRedisSentinelSessionHandler(SessionManager $session)
124
    {
125
        $session->extend('redis-sentinel', function ($app) {
126
            $config = $app->make('config');
127
128
            $cacheDriver = clone $app->make('cache')->driver('redis-sentinel');
129
            $minutes = $config->get('session.lifetime');
130
            $connection = $config->get('session.connection');
131
132
            $cacheDriver->getStore()->setConnection($connection);
133
134
            return new CacheBasedSessionHandler($cacheDriver, $minutes);
135
        });
136
    }
137
138
    /**
139
     * Add "redis-sentinel" as an available queue connection driver option to
140
     * the Laravel queue manager.
141
     *
142
     * @param QueueManager $queue The Laravel queue manager
143
     *
144
     * @return void
145
     */
146
    protected function addRedisSentinelQueueConnector(QueueManager $queue)
147
    {
148
        $queue->extend('redis-sentinel', function () {
149
            $redis = $this->app->make('redis-sentinel')->getVersionedManager();
150
151
            return new RedisConnector($redis);
152
        });
153
    }
154
155
    /**
156
     * Determine whether this package should replace Laravel's Redis API
157
     * ("Redis" facade and "redis" service binding).
158
     *
159
     * @return bool True if "database.redis.driver" configuration option is
160
     * set to "sentinel"
161
     */
162
    protected function shouldOverrideLaravelApi()
163
    {
164
        $driver = $this->app->make('config')->get('database.redis.driver');
165
166
        return $driver === 'sentinel';
167
    }
168
169
    /**
170
     * Get the fully-qualified class name of the RedisSentinelManager class
171
     * for the current version of Laravel.
172
     *
173
     * @return string The class name of the appropriate RedisSentinelManager
174
     * with its namespace
175
     */
176
    protected function getVersionedRedisSentinelManagerClass()
177
    {
178
        if (version_compare(Application::VERSION, '5.4.20', 'lt')) {
179
            return Manager\Laravel540RedisSentinelManager::class;
180
        }
181
182
        return Manager\Laravel5420RedisSentinelManager::class;
183
    }
184
}
185