setServiceLocator($serviceLocator); $this->resourceIterator = new \core_kernel_classes_ResourceIterator($classes); /** @var ResultServerService $resultService */ $this->resultService = $this->getServiceLocator()->get(ResultServerService::SERVICE_ID); $this->ensureNotEmpty(); $this->ensureValidResult(); } /** * (non-PHPdoc) * @see Iterator::rewind() */ function rewind() { if (!$this->unmoved) { $this->resourceIterator->rewind(); $this->ensureNotEmpty(); $this->unmoved = true; } } /** * (non-PHPdoc) * @see Iterator::current() */ function current() { $deliveryExecution = ServiceProxy::singleton()->getDeliveryExecution($this->instanceCache[$this->currentInstance]); return $this->createDocument($deliveryExecution); } /** * (non-PHPdoc) * @see Iterator::key() */ function key() { return $this->resourceIterator->key() . '#' . $this->currentInstance; } /** * (non-PHPdoc) * @see Iterator::next() */ function next() { $this->unmoved = false; if ($this->valid()) { $this->currentInstance++; if (!isset($this->instanceCache[$this->currentInstance])) { // try to load next block (unless we know it's empty) $remainingInstances = !$this->endOfResource && $this->load($this->resourceIterator->current(), $this->currentInstance); // endOfClass or failed loading if (!$remainingInstances) { $this->resourceIterator->next(); $this->ensureNotEmpty(); } } $this->ensureValidResult(); } } /** * While there are remaining classes there are instances to load * * (non-PHPdoc) * @see Iterator::valid() */ function valid() { return $this->resourceIterator->valid(); } // Helpers /** * Ensure the class iterator is pointin to a non empty class * Loads the first resource block to test this */ protected function ensureNotEmpty() { $this->currentInstance = 0; while ($this->resourceIterator->valid() && !$this->load($this->resourceIterator->current(), 0)) { $this->resourceIterator->next(); } } /** * Ensure the current item is valid result */ protected function ensureValidResult() { try { $deliveryExecution = ServiceProxy::singleton()->getDeliveryExecution($this->instanceCache[$this->currentInstance]); $deliveryExecution->getDelivery(); } catch (\common_exception_NotFound $e) { $message = 'Skip result ' . $deliveryExecution->getIdentifier() . ' with message ' . $e->getMessage(); \common_Logger::e($message); $this->next(); } catch (\Exception $e) { \common_Logger::e($e->getMessage()); $this->next(); } } /** * @param \core_kernel_classes_Resource $delivery * @param $offset * @return bool * @throws \common_exception_Error */ protected function load(\core_kernel_classes_Resource $delivery, $offset) { $options = [ 'recursive' => true, 'offset' => $offset, 'limit' => self::CACHE_SIZE ]; $resultsImplementation = $this->resultService->getResultStorage(null); $this->instanceCache = []; $results = $resultsImplementation->getResultByDelivery([$delivery->getUri()], $options); foreach ($results as $result) { $id = isset($result['deliveryResultIdentifier']) ? $result['deliveryResultIdentifier'] : null; if ($id) { $this->instanceCache[$offset] = $id; $offset++; } } $this->endOfResource = count($results) < self::CACHE_SIZE; return count($results) > 0; } /** * @param DeliveryExecution $execution * @return IndexDocument * @throws \common_Exception * @throws \common_exception_NotFound * @throws \oat\oatbox\extension\script\MissingOptionException */ protected function createDocument(DeliveryExecution $execution) { /** @var ResultCustomFieldsService $customFieldService */ $customFieldService = $this->getServiceLocator()->get(ResultCustomFieldsService::SERVICE_ID); $customBody = $customFieldService->getCustomFields($execution); $user = UserHelper::getUser($execution->getUserIdentifier()); $userName = UserHelper::getUserName($user, true); $body = [ 'label' => $execution->getLabel(), ResultsWatcher::INDEX_DELIVERY => $execution->getDelivery()->getUri(), 'type' => ResultService::DELIVERY_RESULT_CLASS_URI, ResultsWatcher::INDEX_TEST_TAKER => $user->getIdentifier(), ResultsWatcher::INDEX_TEST_TAKER_NAME => $userName, ResultsWatcher::INDEX_DELIVERY_EXECUTION => $execution->getIdentifier(), ]; $body = array_merge($body, $customBody); $document = [ 'id' => $execution->getIdentifier(), 'body' => $body ]; /** @var IndexService $indexService */ $indexService = $this->getServiceLocator()->get(IndexService::SERVICE_ID); return $indexService->createDocumentFromArray($document); } }