# MockFileSessionStorage

class MockFileSessionStorage extends MockArraySessionStorage

MockFileSessionStorage is used to mock sessions for functional testing when done in a single PHP process.

No PHP session is actually started since a session can be initialized and shutdown only once per PHP execution cycle and this class does not pollute any session related globals, including session_() functions or session. PHP ini directives.

## Properties

`protected string` | `$id` |  | from MockArraySessionStorage
`protected string` | `$name` |  | from MockArraySessionStorage
`protected bool` | `$started` |  | from MockArraySessionStorage
`protected bool` | `$closed` |  | from MockArraySessionStorage
`protected array` | `$data` |  | from MockArraySessionStorage
`protected MetadataBag` | `$metadataBag` |  | from MockArraySessionStorage
`protected array|SessionBagInterface[]` | `$bags` |  | from MockArraySessionStorage

## Methods

`public` | `` | `__construct(string $savePath = null, string $name = 'MOCKSESSID', MetadataBag $metaBag = null)` | No description |
`public` | `` | `setSessionData(array $array)` | No description | from MockArraySessionStorage
`public` | `bool` | `start()` | Starts the session. |
`public` | `bool` | `regenerate(bool $destroy = false, int $lifetime = null)` | Regenerates id that represents this storage. |
`public` | `string` | `getId()` | Returns the session ID. | from MockArraySessionStorage
`public` | `` | `setId(string $id)` | Sets the session ID. | from MockArraySessionStorage
`public` | `mixed` | `getName()` | Returns the session name. | from MockArraySessionStorage
`public` | `` | `setName(string $name)` | Sets the session name. | from MockArraySessionStorage
`public` | `` | `save()` | Force the session to be saved and closed. |
`public` | `` | `clear()` | Clear all session data in memory. | from MockArraySessionStorage
`public` | `` | `registerBag(SessionBagInterface $bag)` | Registers a SessionBagInterface for use. | from MockArraySessionStorage
`public` | `SessionBagInterface` | `getBag(string $name)` | Gets a SessionBagInterface by name. | from MockArraySessionStorage
`public` | `bool` | `isStarted()` | Checks if the session is started. | from MockArraySessionStorage
`public` | `` | `setMetadataBag(MetadataBag $bag = null)` | No description | from MockArraySessionStorage
`public` | `MetadataBag` | `getMetadataBag()` | Gets the MetadataBag. | from MockArraySessionStorage
`protected` | `string` | `generateId()` | Generates a session ID. | from MockArraySessionStorage
`protected` | `` | `loadSession()` | No description | from MockArraySessionStorage

## Details

at line 34

### `__construct()`

`public __construct(string $savePath = null, string $name = 'MOCKSESSID', MetadataBag $metaBag = null)`

#### Parameters

`string` | `$savePath` | Path of directory to save session files
`string` | `$name` |
`MetadataBag` | `$metaBag` |

in MockArraySessionStorage at line 71

### `setSessionData()`

`public setSessionData(array $array)`

#### Parameters

`array` | `$array` |

at line 52

### `start()`

`public bool start()`

Starts the session.

#### Return Value

`bool` | True if started

#### Exceptions

RuntimeException | if something goes wrong starting the session

at line 72

### `regenerate()`

`public bool regenerate(bool $destroy = false, int $lifetime = null)`

Regenerates id that represents this storage.

This method must invoke session_regenerate_id($destroy) unless this interface is used for a storage object designed for unit or functional testing where a real PHP session would interfere with testing.

Note regenerate+destroy should not clear the session data in memory only delete the session data from persistent storage.

Care: When regenerating the session ID no locking is involved in PHP's session design. See https://bugs.php.net/bug.php?id=61470 for a discussion. So you must make sure the regenerated session is saved BEFORE sending the headers with the new ID. Symfony's HttpKernel offers a listener for this. See Symfony\Component\HttpKernel\EventListener\SaveSessionListener. Otherwise session data could get lost again for concurrent requests with the new ID. One result could be that you get logged out after just logging in.

#### Parameters

`bool` | `$destroy` | Destroy session when regenerating?
`int` | `$lifetime` | Sets the cookie lifetime for the session cookie. A null value will leave the system settings unchanged, 0 sets the cookie to expire with browser session. Time is in seconds, and is not a Unix timestamp.

#### Return Value

`bool` | True if session regenerated, false if error

#### Exceptions

RuntimeException | If an error occurs while regenerating this storage

in MockArraySessionStorage at line 112

### `getId()`

`public string getId()`

Returns the session ID.

#### Return Value

`string` | The session ID or empty

in MockArraySessionStorage at line 120

### `setId()`

`public setId(string $id)`

Sets the session ID.

#### Parameters

`string` | `$id` |

in MockArraySessionStorage at line 132

### `getName()`

`public mixed getName()`

Returns the session name.

#### Return Value

`mixed` | The session name

in MockArraySessionStorage at line 140

### `setName()`

`public setName(string $name)`

Sets the session name.

#### Parameters

`string` | `$name` |

at line 88

### `save()`

`public save()`

Force the session to be saved and closed.

This method must invoke session_write_close() unless this interface is used for a storage object design for unit or functional testing where a real PHP session would interfere with testing, in which case it should actually persist the session data if required.

#### Exceptions

RuntimeException | if the session is saved without being started, or if the session is already closed

in MockArraySessionStorage at line 161

### `clear()`

`public clear()`

Clear all session data in memory.

in MockArraySessionStorage at line 178

### `registerBag()`

`public registerBag(SessionBagInterface $bag)`

Registers a SessionBagInterface for use.

#### Parameters

`SessionBagInterface` | `$bag` |

in MockArraySessionStorage at line 186

### `getBag()`

`public SessionBagInterface getBag(string $name)`

Gets a SessionBagInterface by name.

#### Parameters

`string` | `$name` |

#### Return Value

`SessionBagInterface` |

#### Exceptions

InvalidArgumentException | If the bag does not exist

in MockArraySessionStorage at line 202

### `isStarted()`

`public bool isStarted()`

Checks if the session is started.

#### Return Value

`bool` | True if started, false otherwise

in MockArraySessionStorage at line 207

### `setMetadataBag()`

`public setMetadataBag(MetadataBag $bag = null)`

#### Parameters

`MetadataBag` | `$bag` |

in MockArraySessionStorage at line 221

### `getMetadataBag()`

`public MetadataBag getMetadataBag()`

Gets the MetadataBag.

#### Return Value

`MetadataBag` |

in MockArraySessionStorage at line 234

### `generateId()`

`protected string generateId()`

Generates a session ID.

This doesn't need to be particularly cryptographically secure since this is just a mock.

#### Return Value

`string` |

in MockArraySessionStorage at line 239

### `loadSession()`

`protected loadSession()`

## Source code

    <?php

    /*
     * This file is part of the Symfony package.
     *
     * (c) Fabien Potencier <fabien@symfony.com>
     *
     * For the full copyright and license information, please view the LICENSE
     * file that was distributed with this source code.
     */

    namespace Symfony\Component\HttpFoundation\Session\Storage;

    /**
     * MockFileSessionStorage is used to mock sessions for
     * functional testing when done in a single PHP process.
     *
     * No PHP session is actually started since a session can be initialized
     * and shutdown only once per PHP execution cycle and this class does
     * not pollute any session related globals, including session_*() functions
     * or session.* PHP ini directives.
     *
     * @author Drak <drak@zikula.org>
     */
    class MockFileSessionStorage extends MockArraySessionStorage
    {
        private $savePath;

        /**
         * @param string      $savePath Path of directory to save session files
         * @param string      $name     Session name
         * @param MetadataBag $metaBag  MetadataBag instance
         */
        public function __construct(string $savePath = null, string $name = 'MOCKSESSID', MetadataBag $metaBag = null)
        {
            if (null === $savePath) {
                $savePath = sys_get_temp_dir();
            }

            if (!is_dir($savePath) && !@mkdir($savePath, 0777, true) && !is_dir($savePath)) {
                throw new \RuntimeException(sprintf('Session Storage was not able to create directory "%s"', $savePath));
            }

            $this->savePath = $savePath;

            parent::__construct($name, $metaBag);
        }

        /**
         * {@inheritdoc}
         */
        public function start()
        {
            if ($this->started) {
                return true;
            }

            if (!$this->id) {
                $this->id = $this->generateId();
            }

            $this->read();

            $this->started = true;

            return true;
        }

        /**
         * {@inheritdoc}
         */
        public function regenerate($destroy = false, $lifetime = null)
        {
            if (!$this->started) {
                $this->start();
            }

            if ($destroy) {
                $this->destroy();
            }

            return parent::regenerate($destroy, $lifetime);
        }

        /**
         * {@inheritdoc}
         */
        public function save()
        {
            if (!$this->started) {
                throw new \RuntimeException('Trying to save a session that was not started yet or was already closed');
            }

            $data = $this->data;

            foreach ($this->bags as $bag) {
                if (empty($data[$key = $bag->getStorageKey()])) {
                    unset($data[$key]);
                }
            }
            if (array($key = $this->metadataBag->getStorageKey()) === array_keys($data)) {
                unset($data[$key]);
            }

            try {
                if ($data) {
                    file_put_contents($this->getFilePath(), serialize($data));
                } else {
                    $this->destroy();
                }
            } finally {
                $this->data = $data;
            }

            // this is needed for Silex, where the session object is re-used across requests
            // in functional tests. In Symfony, the container is rebooted, so we don't have
            // this issue
            $this->started = false;
        }

        /**
         * Deletes a session from persistent storage.
         * Deliberately leaves session data in memory intact.
         */
        private function destroy()
        {
            if (is_file($this->getFilePath())) {
                unlink($this->getFilePath());
            }
        }

        /**
         * Calculate path to file.
         *
         * @return string File path
         */
        private function getFilePath()
        {
            return $this->savePath.'/'.$this->id.'.mocksess';
        }

        /**
         * Reads session from storage and loads session.
         */
        private function read()
        {
            $filePath = $this->getFilePath();
            $this->data = is_readable($filePath) && is_file($filePath) ? unserialize(file_get_contents($filePath)) : array();

            $this->loadSession();
        }
    }