1: <?php
2:
3: /*
4: * This file is part of the Symfony package.
5: *
6: * (c) Fabien Potencier <fabien@symfony.com>
7: *
8: * For the full copyright and license information, please view the LICENSE
9: * file that was distributed with this source code.
10: */
11:
12: namespace Symfony\Component\HttpFoundation\Session\Storage;
13:
14: /**
15: * MockFileSessionStorage is used to mock sessions for
16: * functional testing when done in a single PHP process.
17: *
18: * No PHP session is actually started since a session can be initialized
19: * and shutdown only once per PHP execution cycle and this class does
20: * not pollute any session related globals, including session_*() functions
21: * or session.* PHP ini directives.
22: *
23: * @author Drak <drak@zikula.org>
24: */
25: class MockFileSessionStorage extends MockArraySessionStorage
26: {
27: /**
28: * @var string
29: */
30: private $savePath;
31:
32: /**
33: * Constructor.
34: *
35: * @param string $savePath Path of directory to save session files.
36: * @param string $name Session name.
37: * @param MetadataBag $metaBag MetadataBag instance.
38: */
39: public function __construct($savePath = null, $name = 'MOCKSESSID', MetadataBag $metaBag = null)
40: {
41: if (null === $savePath) {
42: $savePath = sys_get_temp_dir();
43: }
44:
45: if (!is_dir($savePath)) {
46: mkdir($savePath, 0777, true);
47: }
48:
49: $this->savePath = $savePath;
50:
51: parent::__construct($name, $metaBag);
52: }
53:
54: /**
55: * {@inheritdoc}
56: */
57: public function start()
58: {
59: if ($this->started) {
60: return true;
61: }
62:
63: if (!$this->id) {
64: $this->id = $this->generateId();
65: }
66:
67: $this->read();
68:
69: $this->started = true;
70:
71: return true;
72: }
73:
74: /**
75: * {@inheritdoc}
76: */
77: public function regenerate($destroy = false, $lifetime = null)
78: {
79: if (!$this->started) {
80: $this->start();
81: }
82:
83: if ($destroy) {
84: $this->destroy();
85: }
86:
87: return parent::regenerate($destroy, $lifetime);
88: }
89:
90: /**
91: * {@inheritdoc}
92: */
93: public function save()
94: {
95: if (!$this->started) {
96: throw new \RuntimeException("Trying to save a session that was not started yet or was already closed");
97: }
98:
99: file_put_contents($this->getFilePath(), serialize($this->data));
100:
101: // this is needed for Silex, where the session object is re-used across requests
102: // in functional tests. In Symfony, the container is rebooted, so we don't have
103: // this issue
104: $this->started = false;
105: }
106:
107: /**
108: * Deletes a session from persistent storage.
109: * Deliberately leaves session data in memory intact.
110: */
111: private function destroy()
112: {
113: if (is_file($this->getFilePath())) {
114: unlink($this->getFilePath());
115: }
116: }
117:
118: /**
119: * Calculate path to file.
120: *
121: * @return string File path
122: */
123: private function getFilePath()
124: {
125: return $this->savePath.'/'.$this->id.'.mocksess';
126: }
127:
128: /**
129: * Reads session from storage and loads session.
130: */
131: private function read()
132: {
133: $filePath = $this->getFilePath();
134: $this->data = is_readable($filePath) && is_file($filePath) ? unserialize(file_get_contents($filePath)) : array();
135:
136: $this->loadSession();
137: }
138: }
139: