From 518828838b140048bc31f9f3760cd00c3da06c17 Mon Sep 17 00:00:00 2001 From: = Date: Mon, 7 Dec 2015 13:55:12 +0100 Subject: [PATCH] Added AbstractStorage::exists() and AbstractStorage::delete(). --- README.md | 4 +-- .../binary/TemporaryQtiBinaryStorage.php | 19 +++++++++- .../storage/common/AbstractStorage.php | 36 +++++++++++++++++++ .../binary/TemporaryQtiBinaryStorageTest.php | 26 +++++++++++++- 4 files changed, 81 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 3391aaa61..b32cc5810 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ An IMS QTI (Question & Test Interoperability) Software Development Kit for PHP 5.3 and higher supporting a wide range of features described by the [IMS QTI specification family](http://www.imsglobal.org/question). -__This implementation of QTI is under constant enhancement. The API of the master branch might change at any time. See release 2.0.0 for the last stable version.__ +__This implementation of QTI is under constant enhancement. The API of the master branch might change at any time. See release 3.x.x. for the last stable version.__ ## Features @@ -26,7 +26,7 @@ __This implementation of QTI is under constant enhancement. The API of the maste * Nice and Clean API for QTI Document manipulation/traversal * PreConditions and Branching * Response/Outcome Processing -* Unit Testing Driven from PHP 5.3 to 5.6 +* Unit Testing Driven from PHP 5.3 to 7.0 ## Installation (developers) diff --git a/src/qtism/runtime/storage/binary/TemporaryQtiBinaryStorage.php b/src/qtism/runtime/storage/binary/TemporaryQtiBinaryStorage.php index 4d8fc697a..3a2eeff59 100644 --- a/src/qtism/runtime/storage/binary/TemporaryQtiBinaryStorage.php +++ b/src/qtism/runtime/storage/binary/TemporaryQtiBinaryStorage.php @@ -77,7 +77,7 @@ protected function getRetrievalStream($sessionId) $read = @file_get_contents($path); if ($read === false || strlen($read) === 0) { - $msg = "An error occured while retrieving the binary stream at '${path}'."; + $msg = "An error occured while retrieving the binary stream at '${path}'. Nothing could be read. The file is empty or missing."; throw new RuntimeException($msg); } @@ -91,4 +91,21 @@ protected function createBinaryStreamAccess(IStream $stream) { return new QtiBinaryStreamAccess($stream, new FileSystemFileManager()); } + + /** + * @see \qtism\runtime\storage\binary\AbstractStorage::exists() + */ + public function exists($sessionId) + { + $path = sys_get_temp_dir() . DIRECTORY_SEPARATOR . md5($sessionId) . '.bin'; + return @is_readable($path); + } + + /** + * @see \qtism\runtime\storage\binary\AbstractStorage::delete() + */ + public function delete($sessionId) + { + return @unlink(sys_get_temp_dir() . DIRECTORY_SEPARATOR . md5($sessionId) . '.bin'); + } } diff --git a/src/qtism/runtime/storage/common/AbstractStorage.php b/src/qtism/runtime/storage/common/AbstractStorage.php index 392c69d2f..98cfe9686 100644 --- a/src/qtism/runtime/storage/common/AbstractStorage.php +++ b/src/qtism/runtime/storage/common/AbstractStorage.php @@ -89,6 +89,9 @@ protected function getManager() * If $sessionId is not provided, the AssessmentTestSession Storage Service implementation * must generate its own session ID. The ID generation algorithm is free, depending * on implementation needs. + * + * Instantiating the AssessmentTestSession does not mean it is persisted. If you want + * to persist its state, call the persist() method. * * @param \qtism\data\AssessmentTest $test The test definition to be instantiated. * @param string $sessionId (optional) A $sessionId to be used to identify the instantiated AssessmentTest. If not given, an ID will be generated by the storage implementation. @@ -112,4 +115,37 @@ abstract public function persist(AssessmentTestSession $assessmentTestSession); * @throws \qtism\runtime\storage\common\StorageException If an error occurs while retrieving the AssessmentTestSession object. */ abstract public function retrieve(AssessmentTest $assessmentTest, $sessionId); + + /** + * Whether or not an AssessmentTestSession object exits in persistence. + * + * This method allows you to know whether or not an AssessmentTestSession object + * with a given $sessionId exists in the current storage. + * + * @param string $sessionId + * @return boolean + * @throws \qtism\runtime\storage\common\StorageException If an error occurs while determining whether the AssessmentTestSession object exists in the storage. + */ + abstract public function exists($sessionId); + + /** + * Delete an AssessmentTestSession object from persistence. + * + * This method enables you to delete an AssessmentTestSession object bound to + * a given $sessionId from the storage. + * + * If an AssessmentTestSession object is effectively bound to $sessionId in the + * persistent storage, and is deleted successfully, this method returns true. + * + * However, if no AssessmentTestSession object could be found for $sessionId while deleting under + * normal circumstances, the method returns false. + * + * Finally, if an unexpected error occurs while deleting the AssessmentTestSession object, a StorageException + * is thrown. + * + * @param string $sessionId + * @return boolean + * @throws \qtism\runtime\storage\common\StorageException If an error occurs while deleting the AssessmentTestSession object. + */ + abstract public function delete($sessionId); } diff --git a/test/qtismtest/runtime/storage/binary/TemporaryQtiBinaryStorageTest.php b/test/qtismtest/runtime/storage/binary/TemporaryQtiBinaryStorageTest.php index 4580141e2..864238749 100644 --- a/test/qtismtest/runtime/storage/binary/TemporaryQtiBinaryStorageTest.php +++ b/test/qtismtest/runtime/storage/binary/TemporaryQtiBinaryStorageTest.php @@ -23,6 +23,7 @@ use qtism\runtime\tests\AssessmentTestSessionState; use qtism\data\storage\xml\XmlCompactDocument; use qtism\runtime\storage\binary\TemporaryQtiBinaryStorage; +use qtism\runtime\storage\common\StorageException; use \DateTime; use \DateTimeZone; @@ -38,6 +39,10 @@ public function testTemporaryQtiBinaryStorage() { $storage = new TemporaryQtiBinaryStorage($sessionManager, new BinaryAssessmentTestSeeker($doc->getDocumentComponent())); $session = $storage->instantiate($test); $sessionId = $session->getSessionId(); + + // Instantiating the test session does not mean it is persisted. At the moment, + // it is not persistent yet. + $this->assertFalse($storage->exists($sessionId)); $this->assertInstanceOf('qtism\\runtime\\tests\\AssessmentTestSession', $session); $this->assertEquals(AssessmentTestSessionState::INITIAL, $session->getState()); @@ -48,6 +53,11 @@ public function testTemporaryQtiBinaryStorage() { // A little bit of noisy persistence... $storage->persist($session); + + // Now the test is persisted, we can try to know whether it exists in storage. + $this->assertTrue($storage->exists($sessionId)); + + // Let's retrive the session from storage. $session = $storage->retrieve($test, $sessionId); $this->assertEquals(AssessmentTestSessionState::INTERACTING, $session->getState()); @@ -557,8 +567,22 @@ public function testNonLinear() { $session->beginTestSession(); $sessionId = $session->getSessionId(); + // It's instantiated, but not persisted. + + // Fun test #1, delete the non-persisted test session. + $this->assertFalse($storage->delete($sessionId)); + $storage->persist($session); - $session = $storage->retrieve($test, $sessionId); + + // Fun test#2, delete the persisted test session. + $this->assertTrue($storage->delete($sessionId)); + + // Fun test#3, retrieve an unexisting test session. + try { + $session = $storage->retrieve($test, $sessionId); + } catch (StorageException $e) { + $this->assertTrue(true, "An Exception should be thrown because the test session does not exist anymore."); + } } public function testFiles() {