Skip to content

Commit

Permalink
Merge pull request #683 from oat-sa/release-5.51.0
Browse files Browse the repository at this point in the history
Release 5.51.0
  • Loading branch information
krampstudio authored Dec 16, 2016
2 parents 0f278ad + aa36179 commit a183740
Show file tree
Hide file tree
Showing 33 changed files with 1,834 additions and 1,076 deletions.
94 changes: 75 additions & 19 deletions actions/class.RestQtiTests.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,21 @@

use oat\taoQtiTest\models\tasks\ImportQtiTest;
use oat\oatbox\task\Task;
use oat\tao\model\TaskQueueActionTrait;

/**
*
* @author Absar Gilani & Rashid - PCG Team - {[email protected]}
*/
class taoQtiTest_actions_RestQtiTests extends \tao_actions_TaskQueue
class taoQtiTest_actions_RestQtiTests extends \tao_actions_RestController
{
use TaskQueueActionTrait {
getTask as parentGetTask;
getTaskData as traitGetTaskData;
}

const TASK_ID_PARAM = 'id';

private static $accepted_types = array(
'application/zip',
'application/x-zip-compressed',
Expand All @@ -36,12 +44,58 @@ public function index()
{
$this->returnFailure(new \common_exception_NotImplemented('This API does not support this call.'));
}


public function __construct()
{
parent::__construct();
// The service that implements or inherits get/getAll/getRootClass ... for that particular type of resources
$this->service = taoQtiTest_models_classes_CrudQtiTestsService::singleton();
}

/**
* Import file entry point by using $this->service
* Check POST method & get valid uploaded file
*/
public function import()
{
$fileUploadName = "qtiPackage";
if ($this->getRequestMethod() != Request::HTTP_POST) {
throw new \common_exception_NotImplemented('Only post method is accepted to import Qti package.');
}
if(tao_helpers_Http::hasUploadedFile($fileUploadName)) {
$file = tao_helpers_Http::getUploadedFile($fileUploadName);
$mimeType = tao_helpers_File::getMimeType($file['tmp_name']);
if (!in_array($mimeType, self::$accepted_types)) {
$this->returnFailure(new common_exception_BadRequest());
} else {
$report = $this->service->importQtiTest($file['tmp_name']);
if ($report->getType() === common_report_Report::TYPE_SUCCESS) {
$data = array();
foreach ($report as $r) {
$values = $r->getData();
$testid = $values->rdfsResource->getUri();
foreach ($values->items as $item) {
$itemsid[] = $item->getUri();
}
$data[] = array(
'testId' => $testid,
'testItems' => $itemsid);
}
return $this->returnSuccess($data);
} else {
return $this->returnFailure(new common_exception_InconsistentData($report->getMessage()));
}
}
} else {
return $this->returnFailure(new common_exception_BadRequest());
}
}

/**
* Import test package through the task queue.
* Check POST method & get valid uploaded file
*/
public function importDeferred()
{
$fileUploadName = "qtiPackage";
if ($this->getRequestMethod() != Request::HTTP_POST) {
Expand Down Expand Up @@ -89,14 +143,32 @@ public function getStatus()
}
}

/**
* @param $taskId
* @return array
*/
protected function getTaskData($taskId)
{
$data = $this->traitGetTaskData($taskId);
$task = $this->getTask($taskId);
$report = \common_report_Report::jsonUnserialize($task->getReport());
$plainReport = $this->getPlainReport($report);

//the third report is report of import test
if (isset($plainReport[2]) && isset($plainReport[2]->getData()['rdfsResource'])) {
$data['testId'] = $plainReport[2]->getData()['rdfsResource']['uriResource'];
}
return $data;
}

/**
* @param Task $taskId
* @return Task
* @throws common_exception_BadRequest
*/
protected function getTask($taskId)
{
$task = parent::getTask($taskId);
$task = $this->parentGetTask($taskId);
if ($task->getInvocable() !== 'oat\taoQtiTest\models\tasks\ImportQtiTest') {
throw new \common_exception_BadRequest("Wrong task type");
}
Expand Down Expand Up @@ -146,20 +218,4 @@ protected function getTaskReport(Task $task)
}
return $result;
}

/**
* @param $report
* @return array
*/
private function getPlainReport($report)
{
$result = [];
$result[] = $report;
if ($report->hasChildren()) {
foreach ($report as $r) {
$result = array_merge($result, $this->getPlainReport($r));
}
}
return $result;
}
}
48 changes: 48 additions & 0 deletions actions/class.TestRunner.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
use qtism\data\NavigationMode;
use oat\taoQtiItem\helpers\QtiRunner;
use oat\taoQtiTest\models\TestSessionMetaData;
use oat\taoQtiTest\models\QtiTestCompilerIndex;

/**
* Runs a QTI Test.
Expand Down Expand Up @@ -95,6 +96,13 @@ class taoQtiTest_actions_TestRunner extends tao_actions_ServiceModule {
* @var array
*/
private $testMeta;

/**
* The index of compiled items.
*
* @var QtiTestCompilerIndex
*/
private $itemIndex;

/**
* Testr session metadata manager
Expand Down Expand Up @@ -222,6 +230,24 @@ protected function getTestMeta() {
return $this->testMeta;
}

/**
* @return QtiTestCompilerIndex
*/
protected function getItemIndex()
{
return $this->itemIndex;
}

/**
* @param QtiTestCompilerIndex $itemIndex
* @return taoQtiTest_actions_TestRunner
*/
protected function setItemIndex($itemIndex)
{
$this->itemIndex = $itemIndex;
return $this;
}

/**
* Print an error report into the response.
* After you have called this method, you must prevent other actions to be processed and must close the response.
Expand Down Expand Up @@ -288,6 +314,7 @@ protected function beforeAction($notifyError = true) {
$sessionStateService->resumeSession($session);

$this->retrieveTestMeta();
$this->retrieveItemIndex();

// Prevent anything to be cached by the client.
taoQtiTest_helpers_TestRunnerUtils::noHttpClientCache();
Expand Down Expand Up @@ -324,6 +351,7 @@ protected function afterAction($withContext = true) {
// Build assessment test context.
$ctx = taoQtiTest_helpers_TestRunnerUtils::buildAssessmentTestContext($this->getTestSession(),
$this->getTestMeta(),
$this->getItemIndex(),
$this->getRequestParameter('QtiTestDefinition'),
$this->getRequestParameter('QtiTestCompilation'),
$this->getRequestParameter('standalone'),
Expand Down Expand Up @@ -848,6 +876,7 @@ protected function retrieveTestSession() {
* into the private compilation directory.
*
* @return array
* @throws common_exception_InconsistentData
*/
protected function retrieveTestMeta()
{
Expand All @@ -865,6 +894,25 @@ protected function retrieveTestMeta()
$this->setTestMeta($meta);
}

/**
* Retrieves the index of compiled items.
*/
protected function retrieveItemIndex()
{
$this->setItemIndex(new QtiTestCompilerIndex());
try {
$directories = $this->getCompilationDirectory();
/** @var tao_models_classes_service_StorageDirectory $privateDirectory */
$privateDirectory = $directories['private'];
$data = $privateDirectory->read(TAOQTITEST_COMPILED_INDEX);
if ($data) {
$this->getItemIndex()->unserialize($data);
}
} catch(\Exception $e) {
\common_Logger::i('Ignoring file not found exception for Items Index');
}
}

protected function handleAssessmentTestSessionException(AssessmentTestSessionException $e) {
switch ($e->getCode()) {
case AssessmentTestSessionException::ASSESSMENT_TEST_DURATION_OVERFLOW:
Expand Down
29 changes: 27 additions & 2 deletions config/default/testRunner.conf.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,26 @@
*/
'test-taker-review-region' => 'left',

/**
* Show legend on review panel
*
* @type string
*/
'test-taker-review-show-legend' => true,

/**
* Show review panel open on launch
*
* @type string
*/
'test-taker-review-default-open' => true,

/**
* Use item title instead of item label.
* @type string
*/
'test-taker-review-use-title' => true,

/**
* Forces a unique title for all test items.
* @type string
Expand Down Expand Up @@ -372,8 +392,9 @@
],
'itemThemeSwitcher' => [
'toggle' => 'T',
'loop' => 'Y',
'select' => 'U'
'up' => 'ArrowUp',
'down' => 'ArrowDown',
'select' => 'Enter'
],
'review' => [
'toggle' => 'R',
Expand All @@ -388,6 +409,10 @@
],
'previous' => [
'trigger' => 'K'
],
'dialog' => [
'accept' => 'Enter',
'reject' => 'Esc'
]
],
);
32 changes: 26 additions & 6 deletions helpers/class.TestRunnerUtils.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
use qtism\runtime\tests\Jump;
use qtism\runtime\tests\RouteItem;
use oat\taoQtiTest\models\ExtendedStateService;
use oat\taoQtiTest\models\QtiTestCompilerIndex;
use qtism\common\datatypes\QtiString;

/**
Expand Down Expand Up @@ -383,13 +384,14 @@ static public function buildPossibleJumps(AssessmentTestSession $session) {
*
* @param AssessmentTestSession $session A given AssessmentTestSession object.
* @param array $testMeta An associative array containing meta-data about the test definition taken by the candidate.
* @param QtiTestCompilerIndex $itemIndex
* @param string $qtiTestDefinitionUri The URI of a reference to an Assessment Test definition in the knowledge base.
* @param string $qtiTestCompilationUri The Uri of a reference to an Assessment Test compilation in the knowledge base.
* @param string $standalone
* @param string $compilationDirs An array containing respectively the private and public compilation directories.
* @return array The context of the candidate session.
*/
static public function buildAssessmentTestContext(AssessmentTestSession $session, array $testMeta, $qtiTestDefinitionUri, $qtiTestCompilationUri, $standalone, $compilationDirs) {
static public function buildAssessmentTestContext(AssessmentTestSession $session, array $testMeta, $itemIndex, $qtiTestDefinitionUri, $qtiTestCompilationUri, $standalone, $compilationDirs) {
$context = array();

// The state of the test session.
Expand Down Expand Up @@ -483,7 +485,7 @@ static public function buildAssessmentTestContext(AssessmentTestSession $session
// The test review screen setup
if (!empty($config['test-taker-review']) && $context['considerProgress']) {
// The navigation map in order to build the test navigator
$navigator = self::getNavigatorMap($session);
$navigator = self::getNavigatorMap($session, $itemIndex);
if ($navigator !== NavigationMode::LINEAR) {
$context['navigatorMap'] = $navigator['map'];
$context['itemFlagged'] = self::getItemFlag($session, $context['itemPosition']);
Expand Down Expand Up @@ -763,7 +765,9 @@ static private function getJumpsMap(AssessmentTestSession $session, $jumps) {
foreach ($jumps as $jump) {
$routeItem = $jump->getTarget();
$partId = $routeItem->getTestPart()->getIdentifier();
$sectionId = key(current($routeItem->getAssessmentSections()));
$sections = $routeItem->getAssessmentSections();
$sections->rewind();
$sectionId = key(current($sections));
$itemId = $routeItem->getAssessmentItemRef()->getIdentifier();

$jumpsMap[$partId][$sectionId][$itemId] = self::getItemInfo($session, $jump);
Expand All @@ -782,9 +786,10 @@ static private function getJumpsMap(AssessmentTestSession $session, $jumps) {
* Gets the section map for navigation between test parts, sections and items.
*
* @param AssessmentTestSession $session
* @param QtiTestCompilerIndex $itemIndex
* @return array A navigator map (parts, sections, items so on)
*/
static private function getNavigatorMap(AssessmentTestSession $session) {
static private function getNavigatorMap(AssessmentTestSession $session, $itemIndex) {

// get jumps
$jumps = $session->getPossibleJumps();
Expand Down Expand Up @@ -821,6 +826,8 @@ static private function getNavigatorMap(AssessmentTestSession $session) {
$config = common_ext_ExtensionsManager::singleton()->getExtensionById('taoQtiTest')->getConfig('testRunner');
$forceTitles = !empty($config['test-taker-review-force-title']);
$uniqueTitle = isset($config['test-taker-review-item-title']) ? $config['test-taker-review-item-title'] : '%d';
$useTitle = !empty($config['test-taker-review-use-title']);
$language = \common_session_SessionManager::getSession()->getInterfaceLanguage();

$returnValue = array();
$testParts = array();
Expand Down Expand Up @@ -862,7 +869,8 @@ static private function getNavigatorMap(AssessmentTestSession $session) {

if (isset($jumpsMap[$id][$sectionId][$itemId])) {
$jumpInfo = $jumpsMap[$id][$sectionId][$itemId];
$resItem = new \core_kernel_classes_Resource(strstr($item->getHref(), '|', true));
$itemUri = strstr($item->getHref(), '|', true);
$resItem = new \core_kernel_classes_Resource($itemUri);
if ($jumpInfo['answered']) {
++$completed;
}
Expand All @@ -875,7 +883,19 @@ static private function getNavigatorMap(AssessmentTestSession $session) {
if ($forceTitles) {
$label = sprintf($uniqueTitle, ++$positionInSection);
} else {
$label = $resItem->getLabel();
if ($useTitle) {
$label = $itemIndex->getItemValue($itemUri, $language, 'title');
} else {
$label = '';
}

if (!$label) {
$label = $itemIndex->getItemValue($itemUri, $language, 'label');
}

if (!$label) {
$label = $resItem->getLabel();
}
}
$items[] = array_merge(
array(
Expand Down
3 changes: 2 additions & 1 deletion includes/constants.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,10 @@
'TAOQTITEST_FILENAME' => 'tao-qtitest-testdefinition.xml',
'TAOQTITEST_COMPILED_FILENAME' => 'compact-test.php',
'TAOQTITEST_COMPILED_META_FILENAME' => 'test-meta.php',
'TAOQTITEST_COMPILED_INDEX' => 'test-index.json',
'TAOQTITEST_REMOTE_FOLDER' => 'tao-qtitest-remote',
'TAOQTITEST_RENDERING_STATE_NAME' => 'taoQtiTestState',
'TAOQTITEST_BASE_PATH_NAME' => 'taoQtiBasePath',
'TAOQTITEST_PLACEHOLDER_BASE_URI' => 'tao://qti-directory',
'TAOQTITEST_VIEWS_NAME' => 'taoQtiViews'
);
);
Loading

0 comments on commit a183740

Please sign in to comment.