Completed
Push — integration-tests ( aca6ec )
by Cy
01:46
created

getVersionedRedisSentinelManagerClass()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 16
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 16
rs 9.4285
cc 3
eloc 10
nc 4
nop 0
1
<?php
2
3
namespace Monospice\LaravelRedisSentinel;
4
5
use Illuminate\Broadcasting\Broadcasters\RedisBroadcaster;
6
use Illuminate\Contracts\Broadcasting\Factory as BroadcastFactory;
7
use Illuminate\Cache\RedisStore;
8
use Illuminate\Queue\Connectors\RedisConnector;
9
use Illuminate\Session\CacheBasedSessionHandler;
10
use Illuminate\Support\Arr;
11
use Illuminate\Support\ServiceProvider;
12
use Monospice\LaravelRedisSentinel\Configuration\Loader as ConfigurationLoader;
13
use Monospice\LaravelRedisSentinel\Contracts\Factory;
14
use Monospice\LaravelRedisSentinel\Horizon\HorizonServiceProvider;
15
use Monospice\LaravelRedisSentinel\RedisSentinelManager;
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     https://github.com/monospice/laravel-redis-sentinel-drivers
26
 */
27
class RedisSentinelServiceProvider extends ServiceProvider
28
{
29
    /**
30
     * Loads the package's configuration and provides configuration values.
31
     *
32
     * @var ConfigurationLoader
33
     */
34
    protected $config;
35
36
    /**
37
     * Boot the service by registering extensions with Laravel's cache, queue,
38
     * and session managers for the "redis-sentinel" driver.
39
     *
40
     * @return void
41
     */
42
    public function boot()
43
    {
44
        $this->bootComponentDrivers();
45
46
        // If we want Laravel's Redis API to use Sentinel, we'll remove the
47
        // "redis" service from the deferred services in the container:
48
        if ($this->config->shouldOverrideLaravelRedisApi) {
49
            $this->removeDeferredRedisServices();
50
        }
51
52
        if ($this->config->horizonAvailable) {
53
            $horizon = new HorizonServiceProvider($this->app, $this->config);
54
            $horizon->register();
55
        }
56
    }
57
58
    /**
59
     * Bind the "redis-sentinel" database driver to the application service
60
     * container.
61
     *
62
     * @return void
63
     */
64
    public function register()
65
    {
66
        $this->config = ConfigurationLoader::load($this->app);
0 ignored issues
show
Documentation introduced by
$this->app is of type object<Illuminate\Contra...Foundation\Application>, but the function expects a object<Illuminate\Founda...avel\Lumen\Application>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
67
68
        $this->registerServices();
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->config->shouldOverrideLaravelRedisApi) {
74
            $this->registerOverrides();
75
        }
76
    }
77
78
    /**
79
     * Register the core Redis Sentinel connection manager.
80
     *
81
     * @return void
82
     */
83
    protected function registerServices()
84
    {
85 View Code Duplication
        $this->app->singleton('redis-sentinel', function ($app) {
0 ignored issues
show
Unused Code introduced by
The parameter $app is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
86
            $class = $this->config->getVersionedRedisSentinelManagerClass();
87
            $config = $this->config->get('database.redis-sentinel', [ ]);
88
            $driver = Arr::pull($config, 'client', 'predis');
89
90
            return new RedisSentinelManager(new $class($driver, $config));
91
        });
92
93
        $this->app->singleton('redis-sentinel.manager', function ($app) {
94
            return $app->make('redis-sentinel')->getVersionedManager();
95
        });
96
97
        $this->app->alias('redis-sentinel', Factory::class);
98
    }
99
100
    /**
101
     * Replace the standard Laravel Redis service with the Redis Sentinel
102
     * database driver so all Redis operations use Sentinel connections.
103
     *
104
     * @return void
105
     */
106
    protected function registerOverrides()
107
    {
108
        $this->app->singleton('redis', function ($app) {
109
            return $app->make('redis-sentinel');
110
        });
111
112
        $this->app->bind('redis.connection', function ($app) {
113
            return $app->make('redis-sentinel.manager')->connection();
114
        });
115
    }
116
117
    /**
118
     * Extend each of the Laravel services this package supports with the
119
     * corresponding 'redis-sentinel' driver.
120
     *
121
     * @return void
122
     */
123
    protected function bootComponentDrivers()
124
    {
125
        $this->addRedisSentinelBroadcaster();
126
        $this->addRedisSentinelCacheStore();
127
128
        // This package's Horizon service provider will set up the queue
129
        // connector a bit differently, so we don't need to do it twice:
130
        if (! $this->config->horizonAvailable) {
131
            $this->addRedisSentinelQueueConnector();
132
        }
133
134
        // Since version 5.2, Lumen does not include support for sessions by
135
        // default, so we'll only register the session handler if enabled:
136
        if ($this->config->supportsSessions) {
137
            $this->addRedisSentinelSessionHandler();
138
        }
139
    }
140
141
    /**
142
     * Remove the standard Laravel Redis service from the bound deferred
143
     * services so they don't overwrite Redis Sentinel registrations.
144
     *
145
     * @return void
146
     */
147
    protected function removeDeferredRedisServices()
148
    {
149
        if ($this->config->isLumen) {
150
            return;
151
        }
152
153
        $deferredServices = $this->app->getDeferredServices();
154
155
        unset($deferredServices['redis']);
156
        unset($deferredServices['redis.connection']);
157
158
        $this->app->setDeferredServices($deferredServices);
159
    }
160
161
    /**
162
     * Add "redis-sentinel" as an available broadcaster option to the Laravel
163
     * event broadcasting manager.
164
     *
165
     * @return void
166
     */
167
    protected function addRedisSentinelBroadcaster()
168
    {
169
        $this->app->make(BroadcastFactory::class)
170
            ->extend('redis-sentinel', function ($app, $conf) {
171
                $redis = $app->make('redis-sentinel.manager');
172
                $connection = Arr::get($conf, 'connection', 'default');
173
174
                return new RedisBroadcaster($redis, $connection);
175
            });
176
    }
177
178
    /**
179
     * Add "redis-sentinel" as an available cache store option to the Laravel
180
     * cache manager.
181
     *
182
     * @return void
183
     */
184
    protected function addRedisSentinelCacheStore()
185
    {
186
        $cache = $this->app->make('cache');
187
188
        $cache->extend('redis-sentinel', function ($app, $conf) use ($cache) {
189
            $redis = $app->make('redis-sentinel.manager');
190
            $prefix = $app->make('config')->get('cache.prefix');
191
            $connection = Arr::get($conf, 'connection', 'default');
192
            $store = new RedisStore($redis, $prefix, $connection);
193
194
            return $cache->repository($store);
195
        });
196
    }
197
198
    /**
199
     * Add "redis-sentinel" as an available driver option to the Laravel
200
     * session manager.
201
     *
202
     * @return void
203
     */
204
    protected function addRedisSentinelSessionHandler()
205
    {
206
        $this->app->make('session')->extend('redis-sentinel', function ($app) {
207
            $cacheDriver = clone $app->make('cache')->driver('redis-sentinel');
208
            $minutes = $this->config->get('session.lifetime');
209
            $connection = $this->config->get('session.connection');
210
211
            $cacheDriver->getStore()->setConnection($connection);
212
213
            return new CacheBasedSessionHandler($cacheDriver, $minutes);
214
        });
215
    }
216
217
    /**
218
     * Add "redis-sentinel" as an available queue connection driver option to
219
     * the Laravel queue manager.
220
     *
221
     * @return void
222
     */
223 View Code Duplication
    protected function addRedisSentinelQueueConnector()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
224
    {
225
        $this->app->make('queue')->extend('redis-sentinel', function () {
226
            $redis = $this->app->make('redis-sentinel.manager');
227
228
            return new RedisConnector($redis);
229
        });
230
    }
231
}
232