models/classes/SessionStateService.php
protected function getSessionProgress(\taoQtiTest_helpers_TestSession $session)
    {
        if ($session->isRunning() !== false) {
            $config = \common_ext_ExtensionsManager::singleton()->getExtensionById('taoQtiTest')->getConfig('testRunner');
            $categories = [];
            if (isset($config['progress-indicator']) && $config['progress-indicator'] == 'categories') {
                $categories = $config['progress-categories'];
            }
            $route = $session->getRoute();
            $routeItems = $route->getAllRouteItems();
            $offset = $route->getRouteItemPosition($routeItems[0]);
            $offsetPart = 0;
            $offsetSection = 0;
            $lastPart = null;
            $lastSection = null;

            $positions = [];
            $lengthParts = [];
            $lengthSections = [];
            $sectionIndex = 0;
            $partIndex = 0;

            // compute positions from the test map
            /** @var RouteItem $routeItem */
            foreach ($routeItems as $routeItem) {
                $testPart = $routeItem->getTestPart();
                $partId = $testPart->getIdentifier();
                if ($lastPart != $partId) {
                    $offsetPart = 0;
                    $lastPart = $partId;
                    $partIndex ++;
                }

                $section = $routeItem->getAssessmentSection();
                $sectionId = $section->getIdentifier();
                if ($lastSection != $sectionId) {
                    $offsetSection = 0;
                    $lastSection = $sectionId;
                    $sectionIndex ++;
                }

                $offset ++;
                $offsetSection ++;

                if ($categories && $config['progress-indicator-scope'] == 'testPart') {
                    /** @var AssessmentItemRef $assessmentItemRef */
                    $assessmentItemRef = $routeItem->getAssessmentItemRef();
                    $assessmenCategories = $assessmentItemRef->getCategories()->getArrayCopy();
                    if (array_intersect($categories, $assessmenCategories)) {
                        $offsetPart ++;
                    }
                }
                $lengthParts[$partIndex] = $offsetPart;
                $lengthSections[$sectionIndex] = $offsetSection;

                $positions[] = [
                    'test' => $offset,
                    'part' => $offsetPart,
                    'partId' => $partIndex,
                    'section' => $offsetSection,
                    'sectionId' => $sectionIndex,
                ];
            }

            $progress = $positions[$route->getPosition()];

            $catService = $this->getServiceManager()->get(CatService::SERVICE_ID);
            $currentItem = $route->current();
            if ($catService->isAdaptive($session, $currentItem->getAssessmentItemRef())) {
                $testSessionService = $this->getServiceManager()->get(TestSessionService::SERVICE_ID);
                $testSessionData = $testSessionService->getTestSessionDataById($session->getSessionId());
                $sectionItems = $catService->getShadowTest($session, $testSessionData['compilation']['private'], $currentItem);
                $currentItem = $catService->getCurrentCatItemId($session, $testSessionData['compilation']['private'], $currentItem);
                $positionInSection = array_search($currentItem, $sectionItems);
                
                // When in an adaptive section, the actual section is just a placeholder that is dynamically
                // replaced by the adaptive content. To set the right position, just grab the offset within
                // this dynamic content and add it to the placeholder position.
                $progress['test'] += $positionInSection;
                $progress['part'] += $positionInSection;
                $progress['section'] += $positionInSection;
                $lengthSections[$progress['sectionId']] = count($sectionItems);
            }

            return [
                'test' => $progress['test'],
                'testPart' => $progress['part'],
                'testSection' => $progress['section'],
                'testLength' => $session->getRouteCount(),
                'testPartLength' => $lengthParts[$progress['partId']],
                'testSectionLength' => $lengthSections[$progress['sectionId']],
            ];
        }
        return false;
    }
protected function getSessionProgress(\taoQtiTest_helpers_TestSession $session)
    {
        if ($session->isRunning() !== false) {
            $config = \common_ext_ExtensionsManager::singleton()->getExtensionById('taoQtiTest')->getConfig('testRunner');
            $categories = [];
            if (isset($config['progress-indicator']) && $config['progress-indicator'] == 'categories') {
                $categories = $config['progress-categories'];
            }
            $route = $session->getRoute();
            $routeItems = $route->getAllRouteItems();
            $offset = $route->getRouteItemPosition($routeItems[0]);
            $offsetPart = 0;
            $offsetSection = 0;
            $lastPart = null;
            $lastSection = null;

            $positions = [];
            $lengthParts = [];
            $lengthSections = [];
            $sectionIndex = 0;
            $partIndex = 0;

            // compute positions from the test map
            /** @var RouteItem $routeItem */
            foreach ($routeItems as $routeItem) {
                $testPart = $routeItem->getTestPart();
                $partId = $testPart->getIdentifier();
                if ($lastPart != $partId) {
                    $offsetPart = 0;
                    $lastPart = $partId;
                    $partIndex ++;
                }

                $section = $routeItem->getAssessmentSection();
                $sectionId = $section->getIdentifier();
                if ($lastSection != $sectionId) {
                    $offsetSection = 0;
                    $lastSection = $sectionId;
                    $sectionIndex ++;
                }

                $offset ++;
                $offsetSection ++;

                if ($categories && $config['progress-indicator-scope'] == 'testPart') {
                    /** @var AssessmentItemRef $assessmentItemRef */
                    $assessmentItemRef = $routeItem->getAssessmentItemRef();
                    $assessmenCategories = $assessmentItemRef->getCategories()->getArrayCopy();
                    if (array_intersect($categories, $assessmenCategories)) {
                        $offsetPart ++;
                    }
                }
                $lengthParts[$partIndex] = $offsetPart;
                $lengthSections[$sectionIndex] = $offsetSection;

                $positions[] = [
                    'test' => $offset,
                    'part' => $offsetPart,
                    'partId' => $partIndex,
                    'section' => $offsetSection,
                    'sectionId' => $sectionIndex,
                ];
            }

            $progress = $positions[$route->getPosition()];

            $catService = $this->getServiceManager()->get(CatService::SERVICE_ID);
            $currentItem = $route->current();
            if ($catService->isAdaptive($session, $currentItem->getAssessmentItemRef())) {
                $testSessionService = $this->getServiceManager()->get(TestSessionService::SERVICE_ID);
                $testSessionData = $testSessionService->getTestSessionDataById($session->getSessionId());
                $sectionItems = $catService->getShadowTest($session, $testSessionData['compilation']['private'], $currentItem);
                $currentItem = $catService->getCurrentCatItemId($session, $testSessionData['compilation']['private'], $currentItem);
                $positionInSection = array_search($currentItem, $sectionItems);
                
                // When in an adaptive section, the actual section is just a placeholder that is dynamically
                // replaced by the adaptive content. To set the right position, just grab the offset within
                // this dynamic content and add it to the placeholder position.
                $progress['test'] += $positionInSection;
                $progress['part'] += $positionInSection;
                $progress['section'] += $positionInSection;
                $lengthSections[$progress['sectionId']] = count($sectionItems);
            }

            return [
                'test' => $progress['test'],
                'testPart' => $progress['part'],
                'testSection' => $progress['section'],
                'testLength' => $session->getRouteCount(),
                'testPartLength' => $lengthParts[$progress['partId']],
                'testSectionLength' => $lengthSections[$progress['sectionId']],
            ];
        }
        return false;
    }
Gets the current progress inside a delivery execution
@param \taoQtiTest_helpers_TestSession $session
@return array|bool