/** * @dataProvider importAssetProvider */ public function testImportAsset($assetHandlers, $absPath, $relPath, $exception = null, $uri = null) { $reflectionClass = new \ReflectionClass(AssetManager::class); $reflectionProperty = $reflectionClass->getProperty('assetHandlers'); $reflectionProperty->setAccessible(true); $reflectionProperty->setValue($this->instance, $assetHandlers); $reflectionClass = new \ReflectionClass(AssetManager::class); $reflectionMethod = $reflectionClass->getMethod('importAsset'); $reflectionMethod->setAccessible(true); if ($exception) { $this->setExpectedException($exception); } if ($uri) { $this->instance->setItemContent($relPath . '/polop.txt'); } $reflectionMethod->invokeArgs($this->instance, [$absPath, $relPath]); if ($uri) { $this->assertEquals($uri . '/polop.txt', $this->instance->getItemContent()); } }
/** * @param $folder * @param \oat\taoQtiItem\model\qti\Resource $qtiItemResource * @param $itemClass * @param array $dependencies * @param array $metadataValues * @param array $metadataInjectors * @param array $metadataGuardians * @param array $metadataClassLookups * @param array $sharedFiles * @param array $createdClass * @return common_report_Report * @throws common_exception_Error */ public function importQtiItem($folder, Resource $qtiItemResource, $itemClass, array $dependencies = array(), array $metadataValues = array(), array $metadataInjectors = array(), array $metadataGuardians = array(), array $metadataClassLookups = array(), array $sharedFiles = array(), &$createdClasses = array()) { try { $qtiService = Service::singleton(); //load the information about resources in the manifest try { $resourceIdentifier = $qtiItemResource->getIdentifier(); // Use the guardians to check whether or not the item has to be imported. foreach ($metadataGuardians as $guardian) { if (isset($metadataValues[$resourceIdentifier]) === true) { if (($guard = $guardian->guard($metadataValues[$resourceIdentifier])) !== false) { \common_Logger::i("Resource '{$resourceIdentifier}' is already stored in the database and will not be imported."); $msg = __('The IMS QTI Item referenced as "%s" in the IMS Manifest file was already stored in the Item Bank.', $resourceIdentifier); $report = common_report_Report::createInfo($msg, $guard); // Simply do not import again. return $report; } } } $targetClass = false; // Use the classLookups to determine where the item has to go. foreach ($metadataClassLookups as $classLookup) { if (isset($metadataValues[$resourceIdentifier]) === true) { \common_Logger::i("Target Class Lookup for resource '{$resourceIdentifier}' ..."); if (($targetClass = $classLookup->lookup($metadataValues[$resourceIdentifier])) !== false) { \common_Logger::i("Class Lookup Successful. Resource '{$resourceIdentifier}' will be stored in RDFS Class '" . $targetClass->getUri() . "'."); if ($classLookup instanceof MetadataClassLookupClassCreator) { $createdClasses = $classLookup->createdClasses(); } break; } } } $qtiFile = $folder . helpers_File::urlToPath($qtiItemResource->getFile()); common_Logger::i('file :: ' . $qtiItemResource->getFile()); $qtiModel = $this->createQtiItemModel($qtiFile); $rdfItem = $this->createRdfItem($targetClass !== false ? $targetClass : $itemClass, $qtiModel); $itemAssetManager = new AssetManager(); $itemAssetManager->setItemContent($qtiModel->toXML()); $itemAssetManager->setSource($folder); /** * Load asset handler following priority handler defined by you * The first applicable will be used to import assets */ /** Portable element handler */ $peHandler = new PortableAssetHandler($qtiModel, dirname($qtiFile)); $itemAssetManager->loadAssetHandler($peHandler); /** Shared stimulus handler */ $sharedStimulusHandler = new SharedStimulusAssetHandler(); $sharedStimulusHandler->setQtiModel($qtiModel)->setItemSource(new ItemMediaResolver($rdfItem, ''))->setSharedFiles($sharedFiles)->setParentPath($rdfItem->getLabel()); $itemAssetManager->loadAssetHandler($sharedStimulusHandler); /** Local storage handler */ $localHandler = new LocalAssetHandler(); $localHandler->setItemSource(new LocalItemSource(array('item' => $rdfItem))); $itemAssetManager->loadAssetHandler($localHandler); $itemAssetManager->importAuxiliaryFiles($qtiItemResource)->importDependencyFiles($qtiItemResource, $dependencies); $itemAssetManager->finalize(); $qtiModel = $this->createQtiItemModel($itemAssetManager->getItemContent(), false); $qtiService->saveDataItemToRdfItem($qtiModel, $rdfItem); // Finally, import metadata. $this->importResourceMetadata($metadataValues, $qtiItemResource, $rdfItem, $metadataInjectors); $eventManager = ServiceManager::getServiceManager()->get(EventManager::CONFIG_ID); $eventManager->trigger(new ItemImported($rdfItem, $qtiModel)); $msg = __('The IMS QTI Item referenced as "%s" in the IMS Manifest file was successfully imported.', $qtiItemResource->getIdentifier()); $report = common_report_Report::createSuccess($msg, $rdfItem); } catch (ParsingException $e) { $message = $e->getUserMessage(); $report = new common_report_Report(common_report_Report::TYPE_ERROR, $message); } catch (ValidationException $ve) { $report = common_report_Report::createFailure(__('IMS QTI Item referenced as "%s" in the IMS Manifest file could not be imported.', $qtiItemResource->getIdentifier())); $report->add($ve->getReport()); } catch (XmlStorageException $e) { $files = array(); $message = __('There are errors in the following shared stimulus : ') . PHP_EOL; /** @var \LibXMLError $error */ foreach ($e->getErrors() as $error) { if (!in_array($error->file, $files)) { $files[] = $error->file; $message .= '- ' . basename($error->file) . ' :' . PHP_EOL; } $message .= $error->message . ' at line : ' . $error->line . PHP_EOL; } $report = new common_report_Report(common_report_Report::TYPE_ERROR, $message); } catch (PortableElementInvalidModelException $pe) { $report = common_report_Report::createFailure(__('IMS QTI Item referenced as "%s" contains a portable element and cannot be imported.', $qtiItemResource->getIdentifier())); $report->add($pe->getReport()); if (isset($rdfItem) && !is_null($rdfItem) && $rdfItem->exists()) { $rdfItem->delete(); } } catch (PortableElementException $e) { // an error occured during a specific item if ($e instanceof common_exception_UserReadableException) { $msg = __('Error on item %1$s : %2$s', $qtiItemResource->getIdentifier(), $e->getUserMessage()); } else { $msg = __('Error on item %s', $qtiItemResource->getIdentifier()); common_Logger::d($e->getMessage()); } $report = new common_report_Report(common_report_Report::TYPE_ERROR, $msg); if (isset($rdfItem) && !is_null($rdfItem) && $rdfItem->exists()) { $rdfItem->delete(); } } catch (Exception $e) { // an error occured during a specific item $report = new common_report_Report(common_report_Report::TYPE_ERROR, __("An unknown error occured while importing the IMS QTI Package.")); if (isset($rdfItem) && !is_null($rdfItem) && $rdfItem->exists()) { $rdfItem->delete(); } common_Logger::e($e->getMessage()); } } catch (ValidationException $ve) { $validationReport = common_report_Report::createFailure("The IMS Manifest file could not be validated"); $validationReport->add($ve->getReport()); $report->setMessage(__("No Items could be imported from the given IMS QTI package.")); $report->setType(common_report_Report::TYPE_ERROR); $report->add($validationReport); } catch (common_exception_UserReadableException $e) { $report = new common_report_Report(common_report_Report::TYPE_ERROR, __($e->getUserMessage())); $report->add($e); } return $report; }