Skip to content

Commit 70dbe1d

Browse files
committed
Add support for Lumen 5.4+
Signed-off-by: Cy Rossignol <[email protected]>
1 parent 2e5e26d commit 70dbe1d

8 files changed

+215
-39
lines changed

composer.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "monospice/laravel-redis-sentinel-drivers",
3-
"description": "Laravel configuration wrapper for highly-available Redis Sentinel replication.",
4-
"keywords": ["redis", "sentinel", "laravel"],
3+
"description": "Redis Sentinel integration for Laravel and Lumen.",
4+
"keywords": ["redis", "sentinel", "laravel", "lumen"],
55
"type": "library",
66
"license": "MIT",
77
"authors": [
@@ -13,6 +13,7 @@
1313
"require": {
1414
"php": ">=5.6.4",
1515
"illuminate/cache": "^5.4",
16+
"illuminate/contracts": "^5.4",
1617
"illuminate/queue": "^5.4",
1718
"illuminate/redis": "^5.4",
1819
"illuminate/session": "^5.4",
@@ -22,6 +23,7 @@
2223
},
2324
"require-dev": {
2425
"laravel/framework": "^5.4",
26+
"laravel/lumen-framework": "^5.4",
2527
"mockery/mockery": "0.9.*",
2628
"phpunit/phpunit": "^4.8"
2729
},

src/RedisSentinelServiceProvider.php

Lines changed: 49 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
use Illuminate\Cache\CacheManager;
66
use Illuminate\Cache\RedisStore;
7-
use Illuminate\Foundation\Application;
87
use Illuminate\Queue\QueueManager;
98
use Illuminate\Queue\Connectors\RedisConnector;
109
use Illuminate\Session\CacheBasedSessionHandler;
@@ -35,18 +34,18 @@ class RedisSentinelServiceProvider extends ServiceProvider
3534
public function boot()
3635
{
3736
$this->addRedisSentinelCacheDriver($this->app->make('cache'));
38-
$this->addRedisSentinelSessionHandler($this->app->make('session'));
3937
$this->addRedisSentinelQueueConnector($this->app->make('queue'));
4038

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+
4145
// If we want Laravel's Redis API to use Sentinel, we'll remove the
4246
// "redis" service from the list of deferred services in the container:
4347
if ($this->shouldOverrideLaravelApi()) {
44-
$deferredServices = $this->app->getDeferredServices();
45-
46-
unset($deferredServices['redis']);
47-
unset($deferredServices['redis.connection']);
48-
49-
$this->app->setDeferredServices($deferredServices);
48+
$this->removeDeferredRedisServices();
5049
}
5150
}
5251

@@ -77,7 +76,7 @@ public function register()
7776

7877
/**
7978
* Replace the standard Laravel Redis service with the Redis Sentinel
80-
* database driver so all redis operations use Sentinel connections.
79+
* database driver so all Redis operations use Sentinel connections.
8180
*
8281
* @return void
8382
*/
@@ -92,6 +91,26 @@ protected function registerOverrides()
9291
});
9392
}
9493

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+
95114
/**
96115
* Add "redis-sentinel" as an available driver option to the Laravel cache
97116
* manager.
@@ -168,17 +187,36 @@ protected function shouldOverrideLaravelApi()
168187

169188
/**
170189
* Get the fully-qualified class name of the RedisSentinelManager class
171-
* for the current version of Laravel.
190+
* for the current version of Laravel or Lumen.
172191
*
173192
* @return string The class name of the appropriate RedisSentinelManager
174193
* with its namespace
175194
*/
176195
protected function getVersionedRedisSentinelManagerClass()
177196
{
178-
if (version_compare(Application::VERSION, '5.4.20', 'lt')) {
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')) {
179206
return Manager\Laravel540RedisSentinelManager::class;
180207
}
181208

182209
return Manager\Laravel5420RedisSentinelManager::class;
183210
}
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+
}
184222
}

tests/RedisSentinelFacadeTest.php

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,29 @@
22

33
namespace Monospice\LaravelRedisSentinel\Tests;
44

5-
use Illuminate\Foundation\Application;
65
use Mockery;
76
use Monospice\LaravelRedisSentinel\RedisSentinel;
87
use Monospice\LaravelRedisSentinel\RedisSentinelManager;
8+
use Monospice\LaravelRedisSentinel\Tests\Support\ApplicationFactory;
99
use PHPUnit_Framework_TestCase as TestCase;
1010

1111
class RedisSentinelFacadeTest extends TestCase
1212
{
13+
/**
14+
* Run this cleanup after each test.
15+
*
16+
* @return void
17+
*/
18+
public function tearDown()
19+
{
20+
Mockery::close();
21+
}
22+
1323
public function testResolvesFacadeServiceFromContainer()
1424
{
1525
$service = RedisSentinelManager::class;
26+
$app = ApplicationFactory::make();
1627

17-
$app = new Application();
1828
$app->singleton('redis-sentinel', function () use ($service) {
1929
return Mockery::mock($service);
2030
});

tests/RedisSentinelManagerTest.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,16 @@ public function setUp()
3838
$this->manager = new RedisSentinelManager($this->versionedManagerMock);
3939
}
4040

41+
/**
42+
* Run this cleanup after each test.
43+
*
44+
* @return void
45+
*/
46+
public function tearDown()
47+
{
48+
Mockery::close();
49+
}
50+
4151
public function testIsInitializable()
4252
{
4353
$this->assertInstanceOf(RedisSentinelManager::class, $this->manager);

tests/RedisSentinelServiceProviderTest.php

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,20 @@
22

33
namespace Monospice\LaravelRedisSentinel\Tests;
44

5-
use Illuminate\Cache\CacheServiceProvider;
65
use Illuminate\Config\Repository as ConfigRepository;
76
use Illuminate\Contracts\Redis\Factory as RedisFactory;
8-
use Illuminate\Foundation\Application;
9-
use Illuminate\Queue\QueueServiceProvider;
107
use Illuminate\Redis\RedisManager;
11-
use Illuminate\Redis\RedisServiceProvider;
12-
use Illuminate\Session\SessionServiceProvider;
138
use Monospice\LaravelRedisSentinel\RedisSentinelManager;
149
use Monospice\LaravelRedisSentinel\RedisSentinelServiceProvider;
10+
use Monospice\LaravelRedisSentinel\Tests\Support\ApplicationFactory;
1511
use PHPUnit_Framework_TestCase as TestCase;
1612

1713
class RedisSentinelServiceProviderTest extends TestCase
1814
{
1915
/**
20-
* An instance of the Laravel application container
16+
* An instance of the Laravel or Lumen application container.
2117
*
22-
* @var Application
18+
* @var \Illuminate\Contracts\Container\Container
2319
*/
2420
protected $app;
2521

@@ -37,16 +33,9 @@ class RedisSentinelServiceProviderTest extends TestCase
3733
*/
3834
public function setUp()
3935
{
40-
$this->app = new Application();
36+
$this->app = ApplicationFactory::make();
4137

42-
$this->app->config = new ConfigRepository(
43-
require(__DIR__ . '/stubs/config.php')
44-
);
45-
46-
$this->app->register(new CacheServiceProvider($this->app));
47-
$this->app->register(new QueueServiceProvider($this->app));
48-
$this->app->register(new RedisServiceProvider($this->app));
49-
$this->app->register(new SessionServiceProvider($this->app));
38+
$this->app->config->set(require(__DIR__ . '/stubs/config.php'));
5039

5140
$this->provider = new RedisSentinelServiceProvider($this->app);
5241
}
@@ -83,6 +72,7 @@ public function testRegisterPreservesStandardRedisApi()
8372

8473
public function testRegisterOverridesStandardRedisApi()
8574
{
75+
$this->app->config->set('database.redis.driver', 'sentinel');
8676
$this->provider->register();
8777
$this->provider->boot();
8878

@@ -112,6 +102,10 @@ public function testBootExtendsSessionHandlers()
112102
$this->provider->register();
113103
$this->provider->boot();
114104

115-
$this->assertNotNull($this->app->session->driver('redis-sentinel'));
105+
if (ApplicationFactory::isLumen()) {
106+
$this->assertFalse($this->app->bound('session'));
107+
} else {
108+
$this->assertNotNull($this->app->session->driver('redis-sentinel'));
109+
}
116110
}
117111
}

tests/Support/ApplicationFactory.php

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
<?php
2+
3+
namespace Monospice\LaravelRedisSentinel\Tests\Support;
4+
5+
use Illuminate\Cache\CacheServiceProvider;
6+
use Illuminate\Config\Repository as ConfigRepository;
7+
use Illuminate\Queue\QueueServiceProvider;
8+
use Illuminate\Redis\RedisServiceProvider;
9+
use Illuminate\Session\SessionServiceProvider;
10+
11+
class ApplicationFactory
12+
{
13+
/**
14+
* Bootstrap a Laravel or Lumen application to run tests against.
15+
*
16+
* @param bool $configure If TRUE, configure default application components
17+
* for tests
18+
*
19+
* @return \Illuminate\Contracts\Container\Container The appropriate
20+
* application instance for the framework under test
21+
*/
22+
public static function make($configure = true)
23+
{
24+
if (static::isLumen()) {
25+
return static::makeLumenApplication($configure);
26+
}
27+
28+
return static::makeLaravelApplication($configure);
29+
}
30+
31+
/**
32+
* Get the version of the Laravel framework used by the package under test.
33+
*
34+
* @return string The version string of the framework
35+
*/
36+
public static function getApplicationVersion()
37+
{
38+
if (static::isLumen()) {
39+
return substr(static::makeLumenApplication()->version(), 7, 3);
40+
}
41+
42+
return \Illuminate\Foundation\Application::VERSION;
43+
}
44+
45+
/**
46+
* Bootstrap a Laravel application instance to run tests against.
47+
*
48+
* @param bool $configure If TRUE, configure default application components
49+
* for tests
50+
*
51+
* @return \Illuminate\Foundation\Application The Laravel application
52+
* instance
53+
*/
54+
public static function makeLaravelApplication($configure = true)
55+
{
56+
$app = new \Illuminate\Foundation\Application();
57+
$app->register(new CacheServiceProvider($app));
58+
$app->register(new QueueServiceProvider($app));
59+
$app->register(new SessionServiceProvider($app));
60+
$app->register(new RedisServiceProvider($app));
61+
62+
$app->config = new ConfigRepository();
63+
64+
return $app;
65+
}
66+
67+
/**
68+
* Bootstrap a Lumen application instance to run tests against.
69+
*
70+
* @param bool $configure If TRUE, configure default application components
71+
* for tests
72+
*
73+
* @return \Laravel\Lumen\Application The Lumen application instance
74+
*/
75+
public static function makeLumenApplication($configure = true)
76+
{
77+
// Set the base path so the application doesn't attempt to use the
78+
// package's config directory as the application config directory
79+
// during tests:
80+
$app = new \Laravel\Lumen\Application(__DIR__ . '/..');
81+
82+
if ($configure) {
83+
$app->register(RedisServiceProvider::class);
84+
$app->configure('database');
85+
$app->configure('cache');
86+
$app->configure('queue');
87+
}
88+
89+
return $app;
90+
}
91+
92+
/**
93+
* Determine if the test is running against a Laravel or Lumen framework.
94+
*
95+
* @return bool True if running the test against Lumen
96+
*/
97+
public static function isLumen()
98+
{
99+
return class_exists('Laravel\Lumen\Application');
100+
}
101+
}

0 commit comments

Comments
 (0)