From 76d13120eaf0bb6ed5661baa898b13cc6d35b111 Mon Sep 17 00:00:00 2001
From: Robin Appelman <icewind@owncloud.com>
Date: Tue, 28 May 2013 00:50:00 +0200
Subject: [PATCH] Abstract the session away in a class

---
 lib/session/internal.php      | 39 ++++++++++++++++++++++
 lib/session/memory.php        | 63 +++++++++++++++++++++++++++++++++++
 lib/session/session.php       | 48 ++++++++++++++++++++++++++
 tests/lib/session/memory.php  | 16 +++++++++
 tests/lib/session/session.php | 55 ++++++++++++++++++++++++++++++
 5 files changed, 221 insertions(+)
 create mode 100644 lib/session/internal.php
 create mode 100644 lib/session/memory.php
 create mode 100644 lib/session/session.php
 create mode 100644 tests/lib/session/memory.php
 create mode 100644 tests/lib/session/session.php

diff --git a/lib/session/internal.php b/lib/session/internal.php
new file mode 100644
index 0000000000..713a154ecc
--- /dev/null
+++ b/lib/session/internal.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ * Copyright (c) 2013 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OC\Session;
+
+/**
+ * Class Internal
+ *
+ * wrap php's internal session handling into the Session interface
+ *
+ * @package OC\Session
+ */
+class Internal extends Memory {
+	public function __construct($name) {
+		session_write_close();
+		session_name($name);
+		if (@session_start()) {
+			throw new \Exception('Failed to start session');
+		}
+		$this->data = $_SESSION;
+	}
+
+	public function __destruct() {
+		$_SESSION = $this->data;
+		session_write_close();
+	}
+
+	public function clear() {
+		session_unset();
+		@session_regenerate_id(true);
+		@session_start();
+		$this->data = $_SESSION = array();
+	}
+}
diff --git a/lib/session/memory.php b/lib/session/memory.php
new file mode 100644
index 0000000000..4202ddfd2f
--- /dev/null
+++ b/lib/session/memory.php
@@ -0,0 +1,63 @@
+<?php
+/**
+ * Copyright (c) 2013 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OC\Session;
+
+/**
+ * Class Internal
+ *
+ * store session data in an in-memory array, not persistance
+ *
+ * @package OC\Session
+ */
+class Memory implements Session {
+	protected $data;
+
+	public function __construct($name) {
+		//no need to use $name since all data is already scoped to this instance
+		$this->data = array();
+	}
+
+	/**
+	 * @param string $key
+	 * @param mixed $value
+	 */
+	public function set($key, $value) {
+		$this->data[$key] = $value;
+	}
+
+	/**
+	 * @param string $key
+	 * @return mixed
+	 */
+	public function get($key) {
+		if (!$this->exists($key)) {
+			return null;
+		}
+		return $this->data[$key];
+	}
+
+	/**
+	 * @param string $key
+	 * @return bool
+	 */
+	public function exists($key) {
+		return isset($this->data[$key]);
+	}
+
+	/**
+	 * @param string $key
+	 */
+	public function remove($key) {
+		unset($this->data[$key]);
+	}
+
+	public function clear() {
+		$this->data = array();
+	}
+}
diff --git a/lib/session/session.php b/lib/session/session.php
new file mode 100644
index 0000000000..3dce3b7f5b
--- /dev/null
+++ b/lib/session/session.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ * Copyright (c) 2013 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OC\Session;
+
+interface Session {
+	/**
+	 * $name serves as a namespace for the session keys
+	 *
+	 * @param string $name
+	 */
+	public function __construct($name);
+
+	/**
+	 * @param string $key
+	 * @param mixed $value
+	 */
+	public function set($key, $value);
+
+	/**
+	 * @param string $key
+	 * @return mixed should return null if $key does not exist
+	 */
+	public function get($key);
+
+	/**
+	 * @param string $key
+	 * @return bool
+	 */
+	public function exists($key);
+
+	/**
+	 * should not throw any errors if $key does not exist
+	 *
+	 * @param string $key
+	 */
+	public function remove($key);
+
+	/**
+	 * removes all entries within the cache namespace
+	 */
+	public function clear();
+}
diff --git a/tests/lib/session/memory.php b/tests/lib/session/memory.php
new file mode 100644
index 0000000000..2dc236b73b
--- /dev/null
+++ b/tests/lib/session/memory.php
@@ -0,0 +1,16 @@
+<?php
+
+/**
+ * Copyright (c) 2013 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace Test\Session;
+
+class Memory extends Session {
+	public function setUp() {
+		$this->instance = new \OC\Session\Memory(uniqid());
+	}
+}
diff --git a/tests/lib/session/session.php b/tests/lib/session/session.php
new file mode 100644
index 0000000000..be28251608
--- /dev/null
+++ b/tests/lib/session/session.php
@@ -0,0 +1,55 @@
+<?php
+
+/**
+ * Copyright (c) 2013 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace Test\Session;
+
+abstract class Session extends \PHPUnit_Framework_TestCase {
+	/**
+	 * @var \OC\Session\Session
+	 */
+	protected $instance;
+
+	public function tearDown() {
+		$this->instance->clear();
+	}
+
+	public function testNotExistsEmpty() {
+		$this->assertFalse($this->instance->exists('foo'));
+	}
+
+	public function testExistsAfterSet() {
+		$this->instance->set('foo', 1);
+		$this->assertTrue($this->instance->exists('foo'));
+	}
+
+	public function testNotExistsAfterRemove() {
+		$this->instance->set('foo', 1);
+		$this->instance->remove('foo');
+		$this->assertFalse($this->instance->exists('foo'));
+	}
+
+	public function testGetNonExisting() {
+		$this->assertNull($this->instance->get('foo'));
+	}
+
+	public function testGetAfterSet() {
+		$this->instance->set('foo', 'bar');
+		$this->assertEquals('bar', $this->instance->get(('foo')));
+	}
+
+	public function testRemoveNonExisting() {
+		$this->instance->remove('foo');
+	}
+
+	public function testNotExistsAfterClear() {
+		$this->instance->set('foo', 1);
+		$this->instance->clear();
+		$this->assertFalse($this->instance->exists('foo'));
+	}
+}
-- 
GitLab