symphonycms/symphony-2 — pull request #2135 by designermonkey (2014-07-21 22:35:20+00:00)
Title: Cookies sessions

# Symphony Sessions and Cookies

Here be some major changes to the way sessions and cookies are handled by Symphony. So major, that they are a complete rewrite from the bottom up.

~~I have tried to maintain backwards compatibility as much as possible, but only testing will prove this for us.~~

I gave up trying to maintain backwards compatibility, as it was too much of a headache to yet again monkey patch Symphony. This needs to be a clean break.

## Cookie as was

Nothing is handled via the old `Cookie` class anymore. This means that sessions, and the use of the `$_SESSION` global do not intrinsically rely on that class being instantiated.

I have left a mock `Cookie` class in place so that any extensions which used it can still create a cookie, which will be mapped through to the new handlers.

## What has changed

Well, everything. Here are the highlights...

### Session and DatabaseSessionHandler

There are two new classes available to the system, whcih separate the two concerns of session handling.

- `Session` - This class handles the instantiation of a PHP session, and the adding and removing of data from the session. It does this by extending a new `Container` class, to provide methods of access. More on the container shortly.

Session data is stored in an array local to the `Session` class, and is accessible all the way through the lifecycle of the application as such:

```
Symphony::Session()->all(); // returns all the session names and values
Symphony::Session()->get('property'); // returns value
Symphony::Session()['property']; // also returns value
Symphony::Session()->property; // also returns value

Symphony::Session()->set('property', $value); // sets the property
Symphony::Session()['property'] = $value; // also sets the property
Symphony::Session()->property = $value; // also sets the property
```

Only at the end of the application cycle is the session data saved to the `$_SESSION` global.

The `$_SESSION` global is still accessible to the developer. Anything stored via the above methods will not be visible during the cycle, but this doesn't mean that anything stored in `$_SESSION` will be lost; It all gets persisted in the database. Only the data stored via the above methods will be available again via those methods. Anything stored directly in `$_SESSION` will only be available that way.

- `DatabaseSessionHandler` - This class abstracts out the meat of the session handling. It is configured in the configuration (where else?), and allows you to theoretically move your session handling to Redis, as long as you provide a class for it.

As mentioned previously, the entire `$_SESSION` global is persisted into the database. Within it is any developer session data, and a key of Symphony specific session data, all serialised as it was previously.

Timeouts are handled differently, as the seconds time from epoch is stored, rather than now, as this fits the column name more correctly. Garbage collection takes this into account though.

### Flash!

*vroooom!* No, seriously. Flash messaging is available. What this means is that messages can be stored in the session for this request + the next request. They can be persisted to remain available for another request if required.

This hopefully will help with events, for example, where a developer can redirect to another page, and maintain the event messages to be displayed on that page. Currently, an event can succeed, but any knowledge of that success is lost in the redirect. (This is still work to do by the way).

Check out the `SessionFlash` class, available in Symphony as `Symphony::Flash()`.

### Cookies

We now have proper cookie support. Only at the end of the application lifecycle are the cookies sent as a header.

Any cookies that are already set, and have their value changed, will of course not have any extra settings added to them before they are sent.

```
Symphony::Cookies()->all(); // returns all the cookie names and values that are set
Symphony::Cookies()->get('cookie_name') // returns value
Symphony::Cookies()['cookie_name'] // also returns value
Symphony::Cookies()->cookie_name // also returns value

Symphony::Cookies()->set('name', $value) // $value can be array of cookie settings, or a single value which will use Symphony cookie default settings
```