155 lines
5.0 KiB
PHP
155 lines
5.0 KiB
PHP
<?php
|
|
|
|
/**
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; under version 2
|
|
* of the License (non-upgradable).
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*
|
|
* Copyright (c) 2019 (original work) Open Assessment Technologies SA ;
|
|
*/
|
|
|
|
/**
|
|
* @author Péter Halász <peter@taotesting.com>
|
|
*/
|
|
|
|
namespace oat\taoQtiTest\models\runner;
|
|
|
|
use oat\oatbox\service\ConfigurableService;
|
|
use oat\taoQtiTest\models\runner\map\RunnerMap;
|
|
|
|
/**
|
|
* Service class for the offline version of Qti Test Runner
|
|
*/
|
|
class OfflineQtiRunnerService extends ConfigurableService
|
|
{
|
|
const SERVICE_ID = 'taoQtiTest/OfflineQtiRunnerService';
|
|
|
|
/**
|
|
* Returns an array of items, containing also confident data, like branching and response processing rules
|
|
*
|
|
* @param RunnerServiceContext $serviceContext
|
|
* @return array
|
|
* @throws \common_Exception
|
|
* @throws \common_exception_Error
|
|
* @throws \common_exception_InconsistentData
|
|
* @throws \common_exception_InvalidArgumentType
|
|
*/
|
|
public function getItems(RunnerServiceContext $serviceContext)
|
|
{
|
|
$this->getRunnerService()->assertQtiRunnerServiceContext($serviceContext);
|
|
|
|
$runnerService = $this->getRunnerService();
|
|
$testMap = $runnerService->getTestMap($serviceContext);
|
|
$items = [];
|
|
|
|
foreach ($this->getItemIdentifiersFromTestMap($testMap) as $itemIdentifier) {
|
|
$itemRef = $runnerService->getItemHref($serviceContext, $itemIdentifier);
|
|
|
|
$itemState = $runnerService->getItemState($serviceContext, $itemIdentifier);
|
|
|
|
if (is_array($itemState) && (0 === count($itemState))) {
|
|
$itemState = null;
|
|
}
|
|
|
|
/** @var QtiRunnerServiceContext $serviceContext */
|
|
$items[$itemIdentifier] = [
|
|
'baseUrl' => $runnerService->getItemPublicUrl($serviceContext, $itemRef),
|
|
'itemData' => $this->getItemData($serviceContext, $itemRef),
|
|
'itemState' => $itemState,
|
|
'itemIdentifier' => $itemIdentifier,
|
|
'portableElements' => $runnerService->getItemPortableElements($serviceContext, $itemRef),
|
|
];
|
|
}
|
|
|
|
return $items;
|
|
}
|
|
|
|
/**
|
|
* Returns the itemData, extending with the variable elements
|
|
*
|
|
* @param RunnerServiceContext $context
|
|
* @param string $itemRef
|
|
* @return array
|
|
* @throws \common_exception_InvalidArgumentType
|
|
* @throws \common_Exception
|
|
*/
|
|
private function getItemData(RunnerServiceContext $context, $itemRef)
|
|
{
|
|
$this->getRunnerService()->assertQtiRunnerServiceContext($context);
|
|
|
|
$itemData = $this->getRunnerService()->getItemData($context, $itemRef);
|
|
$itemDataVariable = $this->getRunnerService()->getItemVariableElementsData($context, $itemRef);
|
|
$responses = $itemData['data']['responses'];
|
|
|
|
foreach (array_keys($responses) as $responseId) {
|
|
if (array_key_exists($responseId, $itemDataVariable)) {
|
|
$itemData['data']['responses'][$responseId] = array_merge(...[
|
|
$responses[$responseId],
|
|
$itemDataVariable[$responseId],
|
|
]);
|
|
}
|
|
}
|
|
|
|
return $itemData;
|
|
}
|
|
|
|
/**
|
|
* Returns the item identifiers
|
|
*
|
|
* @param array $testMap
|
|
* @return array
|
|
*/
|
|
private function getItemIdentifiersFromTestMap($testMap)
|
|
{
|
|
return $this->getSubIdentifiersRecursively($testMap, [
|
|
RunnerMap::MAP_ATTRIBUTE_PARTS,
|
|
RunnerMap::MAP_ATTRIBUTE_SECTIONS,
|
|
RunnerMap::MAP_ATTRIBUTE_ITEMS,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Calls itself recursively to return identifiers from nested arrays
|
|
*
|
|
* @param $array
|
|
* @param $identifiers
|
|
* @return array
|
|
*/
|
|
private function getSubIdentifiersRecursively($array, $identifiers)
|
|
{
|
|
$identifier = array_shift($identifiers);
|
|
if (count($identifiers) > 0) {
|
|
$result = [];
|
|
|
|
foreach ($array[$identifier] as $key => $value) {
|
|
$result[] = $this->getSubIdentifiersRecursively(
|
|
$array[$identifier][$key],
|
|
$identifiers
|
|
);
|
|
}
|
|
|
|
return array_merge(...$result);
|
|
}
|
|
|
|
return array_keys($array[$identifier]);
|
|
}
|
|
|
|
/**
|
|
* @return ConfigurableService|QtiRunnerService
|
|
*/
|
|
private function getRunnerService()
|
|
{
|
|
return $this->getServiceLocator()->get(QtiRunnerService::SERVICE_ID);
|
|
}
|
|
}
|