diff --git a/composer.json b/composer.json index 3dedc135..d439fb79 100644 --- a/composer.json +++ b/composer.json @@ -18,7 +18,8 @@ "psy/psysh": "@stable", "laravel/framework": "5.7.*||5.8.*", "orchestra/testbench": "~3.7||~3.8", - "league/flysystem-aws-s3-v3": "~1.0" + "league/flysystem-aws-s3-v3": "~1.0", + "predis/predis": "^1.1" }, "autoload": { "psr-4": { diff --git a/src/Exceptions/PhpRedisNotInstalledException.php b/src/Exceptions/PhpRedisNotInstalledException.php new file mode 100644 index 00000000..6c9da3e7 --- /dev/null +++ b/src/Exceptions/PhpRedisNotInstalledException.php @@ -0,0 +1,8 @@ +redis->getOption($this->redis->client()::OPT_PREFIX); - $hashes = $hashes ?: $this->redis->scan(null, $redis_prefix.'tenants:*'); - - return array_map(function ($tenant) use ($redis_prefix) { - // Left strip $redis_prefix from $tenant - if (substr($tenant, 0, strlen($redis_prefix)) == $redis_prefix) { - $tenant = substr($tenant, strlen($redis_prefix)); + if (! $hashes) { + // Apparently, the PREFIX is applied to all functions except scan(). + // Therefore, if the `tenancy` Redis connection has a prefix set + // (and PhpRedis is used), prepend the prefix to the search. + $redis_prefix = ''; + if (config('database.redis.client') === 'phpredis') { + $redis_prefix = $this->redis->getOption($this->redis->client()::OPT_PREFIX); } - + $hashes = array_map(function ($hash) use ($redis_prefix) { + // Left strip $redis_prefix from $hash + return substr($hash, strlen($redis_prefix)); + }, $this->redis->scan(null, $redis_prefix.'tenants:*')); + } + + return array_map(function ($tenant) { return $this->redis->hgetall($tenant); }, $hashes); } diff --git a/src/Traits/BootstrapsTenancy.php b/src/Traits/BootstrapsTenancy.php index d09be0ff..05e4f66d 100644 --- a/src/Traits/BootstrapsTenancy.php +++ b/src/Traits/BootstrapsTenancy.php @@ -5,6 +5,8 @@ namespace Stancl\Tenancy\Traits; use Stancl\Tenancy\CacheManager; use Illuminate\Support\Facades\Redis; use Illuminate\Support\Facades\Storage; +use Symfony\Component\Debug\Exception\FatalThrowableError; +use Stancl\Tenancy\Exceptions\PhpRedisNotInstalledException; trait BootstrapsTenancy { @@ -13,7 +15,9 @@ trait BootstrapsTenancy public function bootstrap() { $this->switchDatabaseConnection(); - $this->setPhpRedisPrefix($this->app['config']['tenancy.redis.prefixed_connections']); + if ($this->app['config']['tenancy.redis.multitenant']) { + $this->setPhpRedisPrefix($this->app['config']['tenancy.redis.prefixed_connections']); + } $this->tagCache(); $this->suffixFilesystemRootPaths(); } @@ -28,7 +32,11 @@ trait BootstrapsTenancy foreach ($connections as $connection) { $prefix = $this->app['config']['tenancy.redis.prefix_base'] . $this->tenant['uuid']; $client = Redis::connection($connection)->client(); - $client->setOption($client::OPT_PREFIX, $prefix); + try { + $client->setOption($client::OPT_PREFIX, $prefix); + } catch (\Exception $e) { + throw new PhpRedisNotInstalledException(); + } } } diff --git a/src/config/tenancy.php b/src/config/tenancy.php index f1d9207f..c85dbabc 100644 --- a/src/config/tenancy.php +++ b/src/config/tenancy.php @@ -12,6 +12,7 @@ return [ 'suffix' => '', ], 'redis' => [ + 'multitenant' => true, 'prefix_base' => 'tenant', 'prefixed_connections' => [ 'default', diff --git a/tests/BootstrapsTenancyTest.php b/tests/BootstrapsTenancyTest.php index 6fdab20c..9c171c16 100644 --- a/tests/BootstrapsTenancyTest.php +++ b/tests/BootstrapsTenancyTest.php @@ -3,6 +3,8 @@ namespace Stancl\Tenancy\Tests; use Illuminate\Support\Facades\Redis; +use Illuminate\Support\Facades\Config; +use Stancl\Tenancy\Exceptions\PhpRedisNotInstalledException; class BootstrapsTenancyTest extends TestCase { @@ -30,6 +32,26 @@ class BootstrapsTenancyTest extends TestCase } } + /** @test */ + public function predis_is_supported() + { + Config::set('database.redis.client', 'predis'); + Config::set('tenancy.redis.multitenant', false); + + // assert no exception is thrown from initializing tenancy + $this->assertNotNull($this->initTenancy()); + } + + /** @test */ + public function predis_is_not_supported_without_disabling_redis_multitenancy() + { + Config::set('database.redis.client', 'predis'); + + // todo + $this->expectException(PhpRedisNotInstalledException::class); + $this->initTenancy(); + } + /** @test */ public function filesystem_is_suffixed() { diff --git a/tests/TestCase.php b/tests/TestCase.php index a802367c..1cc19ad1 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -36,7 +36,7 @@ abstract class TestCase extends \Orchestra\Testbench\TestCase public function initTenancy($domain = 'localhost') { - tenancy()->init($domain); + return tenancy()->init($domain); } /**