+ */ +class SessionHandlerFactory +{ + /** + * @param \Redis|\RedisArray|\RedisCluster|\Predis\ClientInterface|RedisProxy|RedisClusterProxy|\Memcached|\PDO|string $connection Connection or DSN + */ + public static function createHandler($connection): AbstractSessionHandler + { + if (!\is_string($connection) && !\is_object($connection)) { + throw new \TypeError(sprintf('Argument 1 passed to %s() must be a string or a connection object, %s given.', __METHOD__, \gettype($connection))); + } + + switch (true) { + case $connection instanceof \Redis: + case $connection instanceof \RedisArray: + case $connection instanceof \RedisCluster: + case $connection instanceof \Predis\ClientInterface: + case $connection instanceof RedisProxy: + case $connection instanceof RedisClusterProxy: + return new RedisSessionHandler($connection); + + case $connection instanceof \Memcached: + return new MemcachedSessionHandler($connection); + + case $connection instanceof \PDO: + return new PdoSessionHandler($connection); + + case !\is_string($connection): + throw new \InvalidArgumentException(sprintf('Unsupported Connection: %s.', \get_class($connection))); + case 0 === strpos($connection, 'file://'): + return new StrictSessionHandler(new NativeFileSessionHandler(substr($connection, 7))); + + case 0 === strpos($connection, 'redis://'): + case 0 === strpos($connection, 'rediss://'): + case 0 === strpos($connection, 'memcached://'): + if (!class_exists(AbstractAdapter::class)) { + throw new InvalidArgumentException(sprintf('Unsupported DSN "%s". Try running "composer require symfony/cache".', $this->dsn)); + } + $connection = AbstractAdapter::createConnection($connection, ['lazy' => true]); + + return 0 === strpos($connection, 'memcached://') ? new MemcachedSessionHandler($connection) : new RedisSessionHandler($connection); + + case 0 === strpos($connection, 'pdo_oci://'): + if (!class_exists(DriverManager::class)) { + throw new \InvalidArgumentException(sprintf('Unsupported DSN "%s". Try running "composer require doctrine/dbal".', $connection)); + } + $connection = DriverManager::getConnection(['url' => $connection])->getWrappedConnection(); + // no break; + + case 0 === strpos($connection, 'mssql://'): + case 0 === strpos($connection, 'mysql://'): + case 0 === strpos($connection, 'mysql2://'): + case 0 === strpos($connection, 'pgsql://'): + case 0 === strpos($connection, 'postgres://'): + case 0 === strpos($connection, 'postgresql://'): + case 0 === strpos($connection, 'sqlsrv://'): + case 0 === strpos($connection, 'sqlite://'): + case 0 === strpos($connection, 'sqlite3://'): + return new PdoSessionHandler($connection); + } + + throw new \InvalidArgumentException(sprintf('Unsupported Connection: %s.', $connection)); + } +} diff --git a/src/Symfony/Component/Lock/Store/StoreFactory.php b/src/Symfony/Component/Lock/Store/StoreFactory.php index 255a72a736912..8fea94551c07c 100644 --- a/src/Symfony/Component/Lock/Store/StoreFactory.php +++ b/src/Symfony/Component/Lock/Store/StoreFactory.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Lock\Store; +use Doctrine\DBAL\Connection; use Symfony\Component\Cache\Adapter\AbstractAdapter; use Symfony\Component\Cache\Traits\RedisClusterProxy; use Symfony\Component\Cache\Traits\RedisProxy; @@ -25,59 +26,74 @@ class StoreFactory { /** - * @param \Redis|\RedisArray|\RedisCluster|\Predis\ClientInterface|\Memcached|\Zookeeper|string $connection Connection or DSN or Store short name + * @param \Redis|\RedisArray|\RedisCluster|\Predis\ClientInterface|RedisProxy|RedisClusterProxy|\Memcached|\PDO|Connection|\Zookeeper|string $connection Connection or DSN or Store short name * * @return PersistingStoreInterface */ public static function createStore($connection) { - if ( - $connection instanceof \Redis || - $connection instanceof \RedisArray || - $connection instanceof \RedisCluster || - $connection instanceof \Predis\ClientInterface || - $connection instanceof RedisProxy || - $connection instanceof RedisClusterProxy - ) { - return new RedisStore($connection); - } - if ($connection instanceof \Memcached) { - return new MemcachedStore($connection); - } - if ($connection instanceof \Zookeeper) { - return new ZookeeperStore($connection); - } - if (!\is_string($connection)) { - throw new InvalidArgumentException(sprintf('Unsupported Connection: %s.', \get_class($connection))); + if (!\is_string($connection) && !\is_object($connection)) { + throw new \TypeError(sprintf('Argument 1 passed to %s() must be a string or a connection object, %s given.', __METHOD__, \gettype($connection))); } switch (true) { + case $connection instanceof \Redis: + case $connection instanceof \RedisArray: + case $connection instanceof \RedisCluster: + case $connection instanceof \Predis\ClientInterface: + case $connection instanceof RedisProxy: + case $connection instanceof RedisClusterProxy: + return new RedisStore($connection); + + case $connection instanceof \Memcached: + return new MemcachedStore($connection); + + case $connection instanceof \PDO: + case $connection instanceof Connection: + return new PdoStore($connection); + + case $connection instanceof \Zookeeper: + return new ZookeeperStore($connection); + + case !\is_string($connection): + throw new InvalidArgumentException(sprintf('Unsupported Connection: %s.', \get_class($connection))); case 'flock' === $connection: return new FlockStore(); + case 0 === strpos($connection, 'flock://'): return new FlockStore(substr($connection, 8)); + case 'semaphore' === $connection: return new SemaphoreStore(); - case 0 === strpos($connection, 'redis://') && class_exists(AbstractAdapter::class): - case 0 === strpos($connection, 'rediss://') && class_exists(AbstractAdapter::class): - return new RedisStore(AbstractAdapter::createConnection($connection, ['lazy' => true])); - case 0 === strpos($connection, 'memcached://') && class_exists(AbstractAdapter::class): - return new MemcachedStore(AbstractAdapter::createConnection($connection, ['lazy' => true])); - case 0 === strpos($connection, 'sqlite:'): + + case 0 === strpos($connection, 'redis://'): + case 0 === strpos($connection, 'rediss://'): + case 0 === strpos($connection, 'memcached://'): + if (!class_exists(AbstractAdapter::class)) { + throw new InvalidArgumentException(sprintf('Unsupported DSN "%s". Try running "composer require symfony/cache".', $this->dsn)); + } + $connection = AbstractAdapter::createConnection($connection, ['lazy' => true]); + + return 0 === strpos($connection, 'memcached://') ? new MemcachedStore($connection) : new RedisStore($connection); + + case 0 === strpos($connection, 'mssql://'): case 0 === strpos($connection, 'mysql:'): - case 0 === strpos($connection, 'pgsql:'): - case 0 === strpos($connection, 'oci:'): - case 0 === strpos($connection, 'sqlsrv:'): - case 0 === strpos($connection, 'sqlite3://'): case 0 === strpos($connection, 'mysql2://'): + case 0 === strpos($connection, 'oci:'): + case 0 === strpos($connection, 'oci8://'): + case 0 === strpos($connection, 'pdo_oci://'): + case 0 === strpos($connection, 'pgsql:'): case 0 === strpos($connection, 'postgres://'): case 0 === strpos($connection, 'postgresql://'): - case 0 === strpos($connection, 'mssql://'): + case 0 === strpos($connection, 'sqlsrv:'): + case 0 === strpos($connection, 'sqlite:'): + case 0 === strpos($connection, 'sqlite3://'): return new PdoStore($connection); + case 0 === strpos($connection, 'zookeeper://'): return new ZookeeperStore(ZookeeperStore::createConnection($connection)); - default: - throw new InvalidArgumentException(sprintf('Unsupported Connection: %s.', $connection)); } + + throw new InvalidArgumentException(sprintf('Unsupported Connection: %s.', $connection)); } }