1<?php
2/* Icinga Web 2 | (c) 2014 Icinga Development Team | GPLv2+ */
3
4namespace Icinga\Web\Session;
5
6use Icinga\Exception\NotImplementedError;
7
8/**
9 * Base class for handling sessions
10 */
11abstract class Session extends SessionNamespace
12{
13    /**
14     * Container for session namespaces
15     *
16     * @var array
17     */
18    protected $namespaces = array();
19
20    /**
21     * The identifiers of all namespaces removed from this session
22     *
23     * @var array
24     */
25    protected $removedNamespaces = array();
26
27    /**
28     * Read all values from the underlying session implementation
29     */
30    abstract public function read();
31
32    /**
33     * Persists changes to the underlying session implementation
34     */
35    public function write()
36    {
37        throw new NotImplementedError('You are required to implement write() in your session implementation');
38    }
39
40    /**
41     * Return whether a session exists
42     *
43     * @return  bool
44     */
45    abstract public function exists();
46
47    /**
48     * Purge session
49     */
50    abstract public function purge();
51
52    /**
53     * Assign a new session id to this session.
54     */
55    abstract public function refreshId();
56
57    /**
58     * Return the id of this session
59     *
60     * @return  string
61     */
62    abstract public function getId();
63
64    /**
65     * Get or create a new session namespace
66     *
67     * @param   string      $identifier     The namespace's identifier
68     *
69     * @return  SessionNamespace
70     */
71    public function getNamespace($identifier)
72    {
73        if (!isset($this->namespaces[$identifier])) {
74            if (in_array($identifier, $this->removedNamespaces, true)) {
75                unset($this->removedNamespaces[array_search($identifier, $this->removedNamespaces, true)]);
76            }
77
78            $this->namespaces[$identifier] = new SessionNamespace();
79        }
80
81        return $this->namespaces[$identifier];
82    }
83
84    /**
85     * Return whether the given session namespace exists
86     *
87     * @param   string      $identifier     The namespace's identifier to check
88     *
89     * @return  bool
90     */
91    public function hasNamespace($identifier)
92    {
93        return isset($this->namespaces[$identifier]);
94    }
95
96    /**
97     * Remove the given session namespace
98     *
99     * @param   string      $identifier     The identifier of the namespace to remove
100     */
101    public function removeNamespace($identifier)
102    {
103        unset($this->namespaces[$identifier]);
104        $this->removedNamespaces[] = $identifier;
105    }
106
107    /**
108     * Return whether the session has changed
109     *
110     * @return  bool
111     */
112    public function hasChanged()
113    {
114        return parent::hasChanged() || false === empty($this->namespaces) || false === empty($this->removedNamespaces);
115    }
116
117    /**
118     * Clear all values and namespaces from the session cache
119     */
120    public function clear()
121    {
122        parent::clear();
123        $this->namespaces = array();
124        $this->removedNamespaces = array();
125    }
126}
127