function neighbourhood(AssessmentTestSession $session, array &$average = null) { $start = microtime(); $neighbourhood = $session->getPossibleJumps(); if (is_null($average) === false) { spentTime($start, microtime(), $average); } }
/** * Gets the section map for navigation between test parts, sections and items. * * @param AssessmentTestSession $session * @return array A navigator map (parts, sections, items so on) */ private static function getNavigatorMap(AssessmentTestSession $session) { // get jumps $jumps = $session->getPossibleJumps(); // no jumps, notify linear-mode if (!$jumps->count()) { return NavigationMode::LINEAR; } $jumpsMapInfo = self::getJumpsMap($session, $jumps); $jumpsMap = $jumpsMapInfo['map']; $numberItemsFlagged = $jumpsMapInfo['flagged']; // the active test-part identifier $activePart = $session->getCurrentTestPart()->getIdentifier(); // the active section identifier $activeSection = $session->getCurrentAssessmentSection()->getIdentifier(); $route = $session->getRoute(); $activeItem = $session->getCurrentAssessmentItemRef()->getIdentifier(); if (isset($jumpsMap[$activePart][$activeSection][$activeItem])) { $jumpsMap[$activePart][$activeSection][$activeItem]['active'] = true; } // current position $oldPosition = $route->getPosition(); $route->setPosition($oldPosition); // get config for the sequence number option $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'; $returnValue = array(); $testParts = array(); $testPartIdx = 0; $numberItemsPart = 0; $numberItemsSection = 0; $numberCompletedPart = 0; $numberCompletedSection = 0; $numberPresentedPart = 0; $numberPresentedSection = 0; $numberFlaggedPart = 0; $numberFlaggedSection = 0; $itemPositionPart = 0; $itemPositionSection = 0; $itemPosition = $session->getRoute()->getPosition(); foreach ($jumps as $jump) { $testPart = $jump->getTarget()->getTestPart(); $id = $testPart->getIdentifier(); if (isset($testParts[$id])) { continue; } $sections = array(); if ($testPart->getNavigationMode() == NavigationMode::NONLINEAR) { $firstPositionPart = PHP_INT_MAX; foreach ($testPart->getAssessmentSections() as $sectionId => $section) { $completed = 0; $presented = 0; $flagged = 0; $items = array(); $firstPositionSection = PHP_INT_MAX; $positionInSection = 0; foreach ($section->getSectionParts() as $itemId => $item) { if (isset($jumpsMap[$id][$sectionId][$itemId])) { $jumpInfo = $jumpsMap[$id][$sectionId][$itemId]; $resItem = new \core_kernel_classes_Resource(strstr($item->getHref(), '|', true)); if ($jumpInfo['answered']) { ++$completed; } if ($jumpInfo['viewed']) { ++$presented; } if ($jumpInfo['flagged']) { ++$flagged; } if ($forceTitles) { $label = sprintf($uniqueTitle, ++$positionInSection); } else { $label = $resItem->getLabel(); } $items[] = array_merge(array('id' => $itemId, 'label' => $label), $jumpInfo); $firstPositionPart = min($firstPositionPart, $jumpInfo['position']); $firstPositionSection = min($firstPositionSection, $jumpInfo['position']); } } $sectionData = array('id' => $sectionId, 'active' => $sectionId === $activeSection, 'label' => $section->getTitle(), 'answered' => $completed, 'items' => $items); $sections[] = $sectionData; if ($sectionData['active']) { $numberItemsSection = count($items); $itemPositionSection = $itemPosition - $firstPositionSection; $numberCompletedSection = $completed; $numberPresentedSection = $presented; $numberFlaggedSection = $flagged; } if ($id === $activePart) { $numberItemsPart += count($items); $numberCompletedPart += $completed; $numberPresentedPart += $presented; $numberFlaggedPart += $flagged; } } if ($id === $activePart) { $itemPositionPart = $itemPosition - $firstPositionPart; } } $data = array('id' => $id, 'sections' => $sections, 'active' => $id === $activePart, 'label' => __('Part %d', ++$testPartIdx)); if (empty($sections)) { $item = current(current($jumpsMap[$id])); $data['position'] = $item['position']; $data['itemId'] = key(current($jumpsMap[$id])); } $returnValue[] = $data; $testParts[$id] = false; } return array('map' => $returnValue, 'numberItemsFlagged' => $numberItemsFlagged, 'numberItemsPart' => $numberItemsPart, 'numberItemsSection' => $numberItemsSection, 'numberCompletedPart' => $numberCompletedPart, 'numberCompletedSection' => $numberCompletedSection, 'numberPresentedPart' => $numberPresentedPart, 'numberPresentedSection' => $numberPresentedSection, 'numberFlaggedPart' => $numberFlaggedPart, 'numberFlaggedSection' => $numberFlaggedSection, 'itemPositionPart' => $itemPositionPart, 'itemPositionSection' => $itemPositionSection); }
/** * Build an array where each cell represent a possible Assessment Item a candidate * can jump on during a given $session. Each cell is an array with two keys: * * * 'identifier': The identifier of the Assessment Item the candidate is allowed to jump on. * * 'position': The position in the route of the Assessment Item. * * @param AssessmentTestSession $session A given AssessmentTestSession object. * @return array */ public static function buildPossibleJumps(AssessmentTestSession $session) { $jumps = array(); foreach ($session->getPossibleJumps() as $jumpObject) { $jump = array(); $jump['identifier'] = $jumpObject->getTarget()->getAssessmentItemRef()->getIdentifier(); $jump['position'] = $jumpObject->getPosition(); $jumps[] = $jump; } return $jumps; }