Skip to content
This repository has been archived by the owner on Jan 8, 2020. It is now read-only.

Session service factories #4268

Merged
136 changes: 136 additions & 0 deletions library/Zend/Session/Service/ContainerAbstractFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/

namespace Zend\Session\Service;

use Zend\ServiceManager\AbstractFactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
use Zend\Session\Container;

/**
* Session container abstract service factory.
*
* Allows creating Container instances, using the Zend\Service\ManagerInterface
* if present. Containers are named in a "session_containers" array in the
* Config service:
*
* <code>
* return array(
* 'session_containers' => array(
* 'auth',
* 'user',
* 'captcha',
* ),
* );
* </code>
*
* Services use the prefix "SessionContainer\\":
*
* <code>
* $container = $services->get('SessionContainer\captcha');
* </code>
*/
class ContainerAbstractFactory implements AbstractFactoryInterface
{
/**
* Cached container configuration
*
* @var array
*/
protected $config;

/**
* @param ServiceLocatorInterface $serviceLocator
* @param string $name
* @param string $requestedName
* @return bool
*/
public function canCreateServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName)
{
$config = $this->getConfig($serviceLocator);
if (!$config) {
return false;
}

$containerName = $this->normalizeContainerName($requestedName);
if (!$containerName) {
return false;
}

return array_key_exists($containerName, $config);
}

/**
* @param ServiceLocatorInterface $serviceLocator
* @param string $name
* @param string $requestedName
* @return Container
*/
public function createServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName)
{
$containerName = substr($requestedName, 17);
$manager = null;

if ($serviceLocator->has('Zend\Session\ManagerInterface')) {
$manager = $serviceLocator->get('Zend\Session\ManagerInterface');
}

return new Container($containerName, $manager);
}

/**
* Retrieve config from service locator, and cache for later
*
* @param ServiceLocatorInterface $serviceLocator
* @return false|array
*/
protected function getConfig(ServiceLocatorInterface $serviceLocator)
{
if (null !== $this->config) {
return $this->config;
}

if (!$serviceLocator->has('Config')) {
$this->config = array();
return false;
}

$config = $serviceLocator->get('Config');
if (!isset($config['session_containers']) || !is_array($config['session_containers'])) {
$this->config = array();
return false;
}

$config = $config['session_containers'];
$config = array_flip($config);

$this->config = array_change_key_case($config);
return $this->config;
}

/**
* Normalize the container name in order to perform a lookup
*
* Strips off the "SessionContainer\" prefix, and lowercases the name.
*
* @param string $name
* @return string
*/
protected function normalizeContainerName($name)
{
$containerName = strtolower($name);
if (18 > strlen($containerName)
|| ('sessioncontainer\\' !== substr($containerName, 0, 17))
) {
return false;
}

return substr($containerName, 17);
}
}
63 changes: 63 additions & 0 deletions library/Zend/Session/Service/SessionConfigFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/

namespace Zend\Session\Service;

use Zend\ServiceManager\Exception\ServiceNotCreatedException;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
use Zend\Session\Config\ConfigInterface;

class SessionConfigFactory implements FactoryInterface
{
/**
* Create session configuration object
*
* Uses "session_config" section of configuration to seed a ConfigInterface
* instance. By default, Zend\Session\Config\SessionConfig will be used, but
* you may also specify a specific implementation variant using the
* "config_class" subkey.
*
* @param ServiceLocatorInterface $services
* @return ConfigInterface
* @throws ServiceNotCreatedException if session_config is missing, or an
* invalid config_class is used
*/
public function createService(ServiceLocatorInterface $services)
{
$config = $services->get('Config');
if (!isset($config['session_config']) || !is_array($config['session_config'])) {
throw new ServiceNotCreatedException(
'Configuration is missing a "session_config" key, or the value of that key is not an array'
);
}
$class = 'Zend\Session\Config\SessionConfig';
$config = $config['session_config'];
if (isset($config['config_class'])) {
if (!class_exists($config['config_class'])) {
throw new ServiceNotCreatedException(sprintf(
'Invalid configuration class "%s" specified in "config_class" session configuration; must be a valid class',
$class
));
}
$class = $config['config_class'];
unset($config['config_class']);
}

$sessionConfig = new $class();
if (!$sessionConfig instanceof ConfigInterface) {
throw new ServiceNotCreatedException(sprintf(
'Invalid configuration class "%s" specified in "config_class" session configuration; must implement Zend\Session\Config\ConfigInterface',
$class
));
}
$sessionConfig->setOptions($config);
return $sessionConfig;
}
}
127 changes: 127 additions & 0 deletions library/Zend/Session/Service/SessionManagerFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/

namespace Zend\Session\Service;

use Zend\ServiceManager\Exception\ServiceNotCreatedException;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
use Zend\Session\Config\ConfigInterface;
use Zend\Session\Container;
use Zend\Session\SaveHandler\SaveHandlerInterface;
use Zend\Session\SessionManager;
use Zend\Session\Storage\StorageInterface;

class SessionManagerFactory implements FactoryInterface
{
/**
* Default configuration for manager behavior
*
* @var array
*/
protected $defaultManagerConfig = array(
'enable_default_container_manager' => true,
);

/**
* Create session manager object
*
* Will consume any combination (or zero) of the following services, when
* present, to construct the SessionManager instance:
*
* - Zend\Session\Config\ConfigInterface
* - Zend\Session\Storage\StorageInterface
* - Zend\Session\SaveHandler\SaveHandlerInterface
*
* The first two have corresponding factories inside this namespace. The
* last, however, does not, due to the differences in implementations, and
* the fact that save handlers will often be written in userland. As such
* if you wish to attach a save handler to the manager, you will need to
* write your own factory, and assign it to the service name
* "Zend\Session\SaveHandler\SaveHandlerInterface", (or alias that name
* to your own service).
*
* You can configure limited behaviors via the "session_manager" key of the
* Config service. Currently, these include:
*
* - enable_default_container_manager: whether to inject the created instance
* as the default manager for Container instances. The default value for
* this is true; set it to false to disable.
*
* @param ServiceLocatorInterface $services
* @return SessionManager
* @throws ServiceNotCreatedException if any collaborators are not of the
* correct type
*/
public function createService(ServiceLocatorInterface $services)
{
$config = null;
$storage = null;
$saveHandler = null;
$managerConfig = $this->defaultManagerConfig;

if ($services->has('Zend\Session\Config\ConfigInterface')) {
$config = $services->get('Zend\Session\Config\ConfigInterface');
if (!$config instanceof ConfigInterface) {
throw new ServiceNotCreatedException(sprintf(
'SessionManager requires that the %s service implement %s; received "%s"',
'Zend\Session\Config\ConfigInterface',
'Zend\Session\Config\ConfigInterface',
(is_object($config) ? get_class($config) : gettype($config))
));
}
}

if ($services->has('Zend\Session\Storage\StorageInterface')) {
$storage = $services->get('Zend\Session\Storage\StorageInterface');
if (!$storage instanceof StorageInterface) {
throw new ServiceNotCreatedException(sprintf(
'SessionManager requires that the %s service implement %s; received "%s"',
'Zend\Session\Storage\StorageInterface',
'Zend\Session\Storage\StorageInterface',
(is_object($storage) ? get_class($storage) : gettype($storage))
));
}
}

if ($services->has('Zend\Session\SaveHandler\SaveHandlerInterface')) {
$saveHandler = $services->get('Zend\Session\SaveHandler\SaveHandlerInterface');
if (!$saveHandler instanceof SaveHandlerInterface) {
throw new ServiceNotCreatedException(sprintf(
'SessionManager requires that the %s service implement %s; received "%s"',
'Zend\Session\SaveHandler\SaveHandlerInterface',
'Zend\Session\SaveHandler\SaveHandlerInterface',
(is_object($saveHandler) ? get_class($saveHandler) : gettype($saveHandler))
));
}
}

$manager = new SessionManager($config, $storage, $saveHandler);

// Get session manager configuration, if any, and merge with default configuration
if ($services->has('Config')) {
$configService = $services->get('Config');
if (isset($configService['session_manager'])
&& is_array($configService['session_manager'])
) {
$managerConfig = array_merge($managerConfig, $configService['session_manager']);
}
}

// If configuration enables the session manager as the default manager for container
// instances, do so.
if (isset($managerConfig['enable_default_container_manager'])
&& $managerConfig['enable_default_container_manager']
) {
Container::setDefaultManager($manager);
}

return $manager;
}
}
63 changes: 63 additions & 0 deletions library/Zend/Session/Service/StorageFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/

namespace Zend\Session\Service;

use Zend\ServiceManager\Exception\ServiceNotCreatedException;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
use Zend\Session\Storage\Exception as SessionException;
use Zend\Session\Storage\Factory;
use Zend\Session\Storage\StorageInterface;

class StorageFactory implements FactoryInterface
{
/**
* Create session storage object
*
* Uses "session_storage" section of configuration to seed a StorageInterface
* instance. That array should contain the key "type", specifying the storage
* type to use, and optionally "options", containing any options to be used in
* creating the StorageInterface instance.
*
* @param ServiceLocatorInterface $services
* @return StorageInterface
* @throws ServiceNotCreatedException if session_storage is missing, or the
* factory cannot create the storage instance.
*/
public function createService(ServiceLocatorInterface $services)
{
$config = $services->get('Config');
if (!isset($config['session_storage']) || !is_array($config['session_storage'])) {
throw new ServiceNotCreatedException(
'Configuration is missing a "session_storage" key, or the value of that key is not an array'
);
}

$config = $config['session_storage'];
if (!isset($config['type'])) {
throw new ServiceNotCreatedException(
'"session_storage" configuration is missing a "type" key'
);
}
$type = $config['type'];
$options = isset($config['options']) ? $config['options'] : array();

try {
$storage = Factory::factory($type, $options);
} catch (SessionException $e) {
throw new ServiceNotCreatedException(sprintf(
'Factory is unable to create StorageInterface instance: %s',
$e->getMessage()
), $e->getCode(), $e);
}

return $storage;
}
}
Loading