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

Conversation

weierophinney
Copy link
Member

This pull request provides ServiceManager factories for the Zend\Session component. It includes the following:

  • A new Zend\Session\Storage\Factory class for creating instances of storage adapters. This is completely de-coupled from the ServiceManager.
  • Zend\Session\Service namespace with the following:
    • SessionConfigFactory, for instantiating a session configuration object. This utilizes the session_config key of the Config service. If a config_class subkey is available, the class name it defines will be used as the configuration class. The entire session_config array is passed to the configuration class's setOptions() method. This factory should be assigned to the service name Zend\Session\Config\ConfigInterface.

    • StorageFactory, for instantiating a storage instance. It utilizes the session_storage key of the Config service, and expects it to be in the format:

      array(
          'type' => 'ShortName Or FQCN of Storage Class',
          'options' => array(/* any valid options for the given storage class */),
      )

      The type and options are passed to Zend\Session\Storage\Factory to create and return an instance. This factory should be assigned to the service name Zend\Session\Storage\StorageInterface.

    • SessionManagerFactory, for instantiating a Zend\Session\SessionManager instance. If any of the services Zend\Session\Config\ConfigInterface, Zend\Session\Storage\StorageInterface, or Zend\Session\SaveHandler\SaveHandlerInterface are present, they will be used to instantiate the SessionManager instance. This service should be assigned to the service name Zend\Session\ManagerInterface.

    • ContainerAbstractFactory, for instantiating Zend\Session\Container instances. It uses the session_containers key of the Config service, and expects the value of that key to be an array of container names. If a Zend\Session\ManagerInterface service is present, it will be used to instantiate Container instances. Container service names MUST be prefixed with SessionContainer\ for the factory to match. This means that the following definition:

      'session_containers' => array(
        'foo',
        'Captcha',
      )

      defines the services SessionContainer\foo and SessionContainer\Captcha.

All factories are completely opt-in, and Zend\ServiceManager has been added as an optional dependency.

As a full example of configuration:

return array(
    'service_manager' => array(
        'factories' => array(
            'Zend\Session\Config\ConfigInterface' => 'Zend\Session\Service\SessionConfigFactory',
            'Zend\Session\Storage\StorageInterface' => 'Zend\Session\Service\SessionStorageFactory',
            'Zend\Session\ManagerInterface' => 'Zend\Session\Service\SessionManagerFactory',
        ),
        'abstract_factories' => array(
            'Zend\Session\Service\ContainerAbstractFactory',
        ),
    ),
    'session_config' => array(
        'remember_me_seconds' => 1800,
        'name' => 'my_app',
    ),
    'session_storage' => array(
        'type' => 'SessionArrayStorage',
        'options' => array(), // Likely don't want to seed it
    ),
    'session_containers' => array(
        'Captcha',
        'User',
        'FlashMessages',
    ),
);

You would then retrieve services within factories as follows:

$user = $services->get('SessionContainer\User');
$messages = $services->get('SessionContainer\FlashMessages');

$manager = $services->get('Zend\Session\ManagerInterface');

- Uses "session_config" key, assigned to an array of options, to create
  a Zend\Session\Config\ConfigInterface instance.
- By default, uses SessionConfig as ConfigInterface implementation.
- A "config_class" subkey can be used to specify a specific
  ConfigInterface implementation to use.
- Consumes ConfigInterface, StorageInterface, and SaveHandlerInterface
  services in order to create a SessionManager instance. Services do not
  need to be present, as null values will be used by default if not
  found.
- Marshals arguments from Config service
- Proxies to Zend\Session\Storage\Factory for actual creation
- Save handler factory will not be provided by the framework at this
  time.
- Provide an array of container names in "session_containers"
  configuration.
- Uses `Zend\Session\ManagerInterface` service, if available, when
  instantiating containers.
- Session container services must be prefixed with "SessionContainer\\"
- s/SessionConfig/SessionContainer/
@weierophinney
Copy link
Member Author

Ping @mwillbanks -- this is what we discussed on IRC yesterday.

- per php-cs-fixer
* @category Zend
* @package Zend_Session
* @subpackage UnitTests
* @group Zend_Session
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

only @group

@mwillbanks
Copy link
Contributor

@weierophinney Here is the feedback that I have on this now that I've had some time to look into it all.

  • Session Container Factories: I'm slightly curious on the use case for the containers to be honest. It seems like it may save a line or two of code. Do we plan to incorporate this into the framework where sessions are already leveraged?
    • Container itself: One area that I think is missing is the ability within the implementation is that there is no option to be able to setDefaultManager on the Container. Setting a default manager to Container is semi-important due to incorporation with several other tools. Sure it can be done manually but this provides far more convenience.

- Passes created `SessionManager` instance to
  `Container::setDefaultManager()`
- New Config service key, "session_manager"
  - single key for now: "enable_default_container_manager". Defaults to
    true, meaning "inject the Container". Set to false to disable this
    behavior.
@weierophinney
Copy link
Member Author

@mwillbanks I've incorporated your feedback. At this ime:

  • The SessionManagerFactory now injects itself as the default manager for Container instances. You can disable this, if desired, by setting 'session_manager' => array('enable_default_container_manager' => false) via configuration.

As for the Container factories, the primary use case goes away when the default settings are used. However, if you disable the default manager functionality, this abstract factory would simplify usage of containers associated with the SessionManager service, as you would no longer need to retrieve the SessionManager prior to creating your Container instances.

The secondary use case is still present, however: IoC. Basically, you can then treat the Container instances as services, which ensures that injection of the SessionManager is appropriately done, and breaks you of the habit of instantiating the Containers directly.

I'm unsure if we should modify existing code to use these services. A quick check shows that the following components use Containers:

  • ProgressBar
  • CSRF validator
  • Authentication (session storage)
  • Captcha
  • Cache (session storage adapter)
  • FlashMessenger
  • PRG and File PRG plugins

The latter three could easily be updated to pull named containers, as they are managed by a plugin manager already. The Cache session storage adapter could be as well, as we have a proposed abstract factory for storage adapters. The CSRF validator falls under this as well, since we have a Validator plugin manager and factory. That leaves Authentication, CAPTCHA, and ProgressBar as outliers, however.

Question: should I update those components that we can with this PR, or wait until this one is merged?

Ideally, I'd like to get this into 2.2.0, as this, and the Log and Cache factories, have been much requested since 2.0.

@mwillbanks
Copy link
Contributor

@weierophinney i think we can update those components at a later time and get this in first. Looks like travis had some issues with it on 5.4.

@weierophinney
Copy link
Member Author

@mwillbanks The failures on 5.4 are due to issues with Travis-CI properly resolving the path to the downloaded php-cs-fixer.phar file; since it cannot resolve, it reports an error.

mwillbanks pushed a commit that referenced this pull request Apr 24, 2013
@mwillbanks mwillbanks merged commit 16d642c into zendframework:develop Apr 24, 2013
@rumeau
Copy link

rumeau commented Jul 10, 2013

Im using thies factories to intitiate my Session Manager, the problem is that when i initialize the Session Manager onBoostrap, the Session Upload Progress var is removed from the $_SESSION var.

Im using the SessionArrayStorage the upload progress key is always removed. I also tried disabling the initialization but then my session object gets invalid as the upload progress key is not processed by the SessionArrayStorage so my session is lost after the upload.

Is the Session Manager compatible with session upload progress?.

@weierophinney
Copy link
Member Author

@rumeau Can you please open a new issue instead of a comment thread inside a closed PR? :) This will allow us to track it separately.

Thanks in advance!

weierophinney added a commit to zendframework/zend-session that referenced this pull request May 15, 2015
gianarb pushed a commit to zendframework/zend-session that referenced this pull request May 15, 2015
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants