Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/lsi 3472/visualize assessment test session #389

Open
wants to merge 4 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions bin/qtisdk
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
#!/usr/bin/env php
<?php
use qtism\cli\Cli;
use qtism\cli\CompactTest;
use qtism\cli\Render;
use qtism\cli\AssessmentTestSessionDump;
use cli as CliTools;

if (!ini_get('date.timezone')) {
Expand All @@ -18,7 +20,7 @@ foreach (array(__DIR__ . '/../../../autoload.php', __DIR__ . '/../vendor/autoloa
if (!defined('QTISDK_COMPOSER_INSTALL')) {
fwrite(STDERR,
'You need to set up the project dependencies using the following commands:' . PHP_EOL .
'wget http://getcomposer.org/composer.phar' . PHP_EOL .
'wget https://getcomposer.org/composer.phar' . PHP_EOL .
'php composer.phar install' . PHP_EOL
);
exit(Cli::EXIT_FAILURE);
Expand All @@ -30,13 +32,21 @@ require QTISDK_COMPOSER_INSTALL;
CliTools\Colors::enable(false);

// Execute main entry point.
$availableModules = array('render');
$availableModules = array('render', 'dump');
$requestedModuleName = (isset($argv[1])) ? $argv[1] : '';
$module = strtolower($requestedModuleName);
switch ($module) {
case 'render':
Render::main();
break;

case 'dump':
AssessmentTestSessionDump::main();
break;

case 'compact':
CompactTest::main();
break;
default:
CliTools\err("%RUnknown module '{$requestedModuleName}'. Available modules are: " . implode(',', $availableModules) . '.%n');
exit(Cli::EXIT_FAILURE);
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"league/flysystem": "^1.0|2.1.1|^3.0",
"league/mime-type-detection": "^1.0",
"oat-sa/lib-beeme": "0.2.0",
"wp-cli/php-cli-tools": "0.10.3"
"wp-cli/php-cli-tools": "0.11.22"
},
"require-dev": {
"phpunit/phpunit": "~9|~7",
Expand Down
140 changes: 140 additions & 0 deletions src/qtism/cli/AssessmentTestSessionDump.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
<?php

namespace qtism\cli;

use cli\Arguments;
use qtism\common\datatypes\files\FileSystemFileManager;
use qtism\common\storage\MemoryStream;
use qtism\data\AssessmentTest;
use qtism\data\storage\xml\XmlCompactDocument;
use qtism\data\storage\xml\XmlStorageException;
use qtism\runtime\common\OutcomeVariable;
use qtism\runtime\common\TemplateVariable;
use qtism\runtime\common\Variable;
use qtism\runtime\storage\binary\LocalQtiBinaryStorage;
use qtism\runtime\storage\common\StorageException;
use qtism\runtime\tests\AssessmentItemSession;
use qtism\runtime\tests\AssessmentItemSessionState;
use qtism\runtime\tests\AssessmentTestSessionState;
use qtism\runtime\tests\SessionManager;
use qtism\runtime\tests\TimeConstraint;

class AssessmentTestSessionDump extends Cli
{

/**
* @inheritDoc
*/
protected function run(): void
{
$arguments = $this->getArguments();

try {
$compactDoc = new XmlCompactDocument();
$compactDoc->load($arguments['xml']);

/** @var AssessmentTest $test */
$test = $compactDoc->getDocumentComponent();
$sessionManager = new SessionManager(new FileSystemFileManager());

$sessionId = 'dump-qtism-session-id';
$storage = new LocalQtiBinaryStorage($sessionManager, $test);
$stream = new MemoryStream(base64_decode($arguments['session']));
$storage->setStream($stream, $sessionId);
$session = $storage->retrieve($sessionId);

$this->out("Assessment Test Session Dump");
$this->out("============================");
$this->out('');

$this->out("Test Identifier: " . $session->getAssessmentTest()->getIdentifier());
$this->out("Test Title: " . $session->getAssessmentTest()->getTitle());
$this->out("Test Tool Name: " . $session->getAssessmentTest()->getToolName());
$this->out("Test Tool Version: " . $session->getAssessmentTest()->getToolVersion());
$this->out("Session State: " . AssessmentTestSessionState::getNameByConstant($session->getState()));
$this->out('');

$this->out("Assessment Item Sessions");
$this->out('========================');

/** @var AssessmentItemSession $itemSession */
foreach ($session->getAssessmentItemSessionStore()->getAllAssessmentItemSessions() as $itemSession) {
$this->out("Assessment Item Identifier: " . $itemSession->getAssessmentItem()->getIdentifier());
$this->out("Assessment Item Title: " . $itemSession->getAssessmentItem()->getTitle());
$this->out("Assessment Item Label: " . $itemSession->getAssessmentItem()->getLabel());
$this->out("Assessment Item Session State: " . AssessmentItemSessionState::getNameByConstant($itemSession->getState()));

/** @var Variable $variable */
foreach ($itemSession as $variable) {
$lastPart = $variable->getIdentifier() . ': ' . $variable->getValue();
$firstPart = 'Response Variable';

if ($variable instanceof OutcomeVariable) {
$firstPart = 'Outcome Variable';
} elseif ($variable instanceof TemplateVariable) {
$firstPart = 'TemplateVariable';
}

$this->out("${firstPart} ${lastPart}");
}

$this->out('');
}

$this->out("Duration by Location");
$this->out("====================");

$durationStore = $session->getDurationStore();
foreach ($durationStore as $variable) {
echo 'Identifier: ' . $variable->getIdentifier() . ' / Time: ' . $variable->getValue() . "\n";
}

} catch (XmlStorageException $e) {
$this->fail('XML Compact Test document could not be read.');
} catch (StorageException $e) {
$this->fail('The session could not be rebuilt.');
}

}

/**
* @inheritDoc
*/
protected function setupArguments(): Arguments
{
$arguments = new Arguments(['strict' => false]);

// -- Options
// Session option.
$arguments->addOption(
['session'],
[
'description' => 'The base64 session string to dump.',
]
);

// XML option.
$arguments->addOption(
['xml'],
[
'description' => 'The path to the related XML Compact Test file.',
]
);

return $arguments;
}

/**
* @inheritDoc
*/
protected function checkArguments(): void
{
$arguments = $this->getArguments();

if ($arguments['xml'] === null) {
$this->fail('Please provide the --xml argument.');
} else if ($arguments['session'] === null) {
$this->fail('Please provide the --session argument.');
}
}
}
65 changes: 65 additions & 0 deletions src/qtism/cli/CompactTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?php

namespace qtism\cli;

use cli\Arguments;
use qtism\data\storage\xml\XmlCompactDocument;
use qtism\data\storage\xml\XmlDocument;
use qtism\data\storage\xml\XmlStorageException;
use ReflectionException;

class CompactTest extends Cli
{

protected function run()
{
$arguments = $this->getArguments();

$doc = new XmlDocument();
try {
$doc->load($arguments['input']);
$compactDoc = XmlCompactDocument::createFromXmlAssessmentTestDocument($doc);
$compactDoc->save($arguments['output']);

} catch (XmlStorageException $e) {
$this->fail('Input XML Test document could not be read.');
} catch (ReflectionException $e) {
$this->fail('An unexpected error occurred.');
}
}

protected function setupArguments(): Arguments
{
$arguments = new Arguments(['strict' => false]);

// -- Options
// Session option.
$arguments->addOption(
['input'],
[
'description' => 'The input QTI test file.',
]
);

// XML option.
$arguments->addOption(
['output'],
[
'description' => 'The output QTI compact test file.',
]
);

return $arguments;
}

protected function checkArguments()
{
$arguments = $this->getArguments();

if ($arguments['input'] === null) {
$this->fail('Please provide the --input argument.');
} else if ($arguments['output'] === null) {
$this->fail('Please provide the --output argument.');
}
}
}
6 changes: 3 additions & 3 deletions src/qtism/cli/Render.php
Original file line number Diff line number Diff line change
Expand Up @@ -280,14 +280,14 @@ private function runGoldilocks(XmlDocument $doc, GoldilocksRenderingEngine $rend
$body = substr($body, 0, strlen('</div>') * -1);
$body = "<body {$body}</body>{$nl}";
} else {
$body = $xml->saveXml($xml->documentElement) . {$nl};
$body = $xml->saveXml($xml->documentElement) . $nl;
}

if ($arguments['document'] === true) {
$footer = "</html>\n";
}
} else {
$body = $xml->saveXml($xml->documentElement) . {$nl};
$body = $xml->saveXml($xml->documentElement) . $nl;
}

// Indent body...
Expand Down Expand Up @@ -358,7 +358,7 @@ private function runXhtml(XmlDocument $doc, XhtmlRenderingEngine $renderer): str
$footer .= "</html>\n";
}

$body = $xml->saveXml($xml->documentElement) . {$nl};
$body = $xml->saveXml($xml->documentElement) . $nl;

// Indent body...
$indentBody = '';
Expand Down
13 changes: 13 additions & 0 deletions src/qtism/runtime/storage/binary/LocalQtiBinaryStorage.php
Original file line number Diff line number Diff line change
Expand Up @@ -170,4 +170,17 @@ public function delete(AssessmentTestSession $assessmentTestSession): bool

return @unlink($this->getPath() . DIRECTORY_SEPARATOR . md5($assessmentTestSession->getSessionId()) . '.bin');
}

/**
* Set the $stream value manually for a given $sessionId.
*
* @param MemoryStream $stream
* @param string $sessionId
* @return void
*/
public function setStream(MemoryStream $stream, string $sessionId): void
{
$path = $this->getPath() . DIRECTORY_SEPARATOR . md5($sessionId) . '.bin';
@file_put_contents($path, $stream->getBinary());
}
}
Loading