public function __invoke($params) { $service = new PortableElementService(); $service->setServiceLocator(ServiceManager::getServiceManager()); $sourceDirectory = $this->getSourceDirectory(); if (empty($sourceDirectory)) { return $this->createFailure('the source directory is empty'); } if (!is_readable($sourceDirectory)) { return $this->createFailure('the source directory does not exists or is not readable ' . $sourceDirectory); } try { $model = $service->getValidPortableElementFromDirectorySource($sourceDirectory); if (!empty($params)) { $minRequiredVersion = $params[0]; // if the minimal required version number string "x.y.z" is given in the parameter, the new target version should be equal or higher than it if (version_compare($model->getVersion(), $minRequiredVersion) < 0) { return $this->createFailure('the version in manifest "' . $model->getVersion() . '" cannot be lower than the given minimum required version "' . $minRequiredVersion . '"', $model); } } $service->registerFromDirectorySource($sourceDirectory); } catch (PortableElementVersionIncompatibilityException $e) { return $this->createFailure('incompatible version: ' . $e->getMessage(), $model); } return Report::createSuccess('registered portable element "' . $model->getTypeIdentifier() . '" in version "' . $model->getVersion() . '""'); }
/** * @dataProvider validImportProvider */ public function testValidImport($model, $name, $version, $package) { $result = $this->instance->import($package); $portableElements = $this->getPortableElements($model); $this->assertEquals(ksort($result->toArray()), ksort($portableElements[$name][$version])); $pciRegistry = $this->getRegistry($model); // $this->assertTrue($pciRegistry->unregister($result)); }
protected function getService() { if (!$this->service) { $this->service = new PortableElementService(); $this->service->setServiceLocator($this->getServiceManager()); } return $this->service; }
/** * @return PortableElementService */ public function getService() { if (!$this->service) { $this->service = new PortableElementService(); $this->service->setServiceLocator($this->getServiceLocator()); } return $this->service; }
/** * Re-register a portable element from its source directory * The list of portable elements to re-register is configure in the config file {TAO_ROOT}/config/taoQtiItem/debug_portable_element.conf.php * e.g. return [ 'myPci1' => 'qtiItemPci/views/js/pciCreator/dev/myPci1/', 'myPci2' => '/home/sam/dev/pcis/myPci2/' ]; * * @param ItemCreatorLoad $event * @throws \common_Exception * @throws \common_ext_ExtensionException */ public static function reloadPortableDevDirectory(ItemCreatorLoad $event) { $customInteractionDirs = \common_ext_ExtensionsManager::singleton()->getExtensionById('taoQtiItem')->getConfig('debug_portable_element'); if (is_array($customInteractionDirs)) { $service = new PortableElementService(); $service->setServiceLocator(ServiceManager::getServiceManager()); foreach ($customInteractionDirs as $path) { if (is_dir(ROOT_PATH . $path)) { $sourceDir = ROOT_PATH . $path; } else { if (is_dir($path)) { $sourceDir = $path; } else { throw new \common_Exception('No directory found on path ' . $path); } } $service->registerFromDirectorySource($sourceDir); \common_Logger::i('Re-registered portable element from the source ' . $sourceDir); } } }
public function testExport() { $packageValid = dirname(__FILE__) . '/samples/package/likertScaleInteraction_v1.0.0'; $pciModel = new PciModel('likertScaleInteraction', '1.0.0'); $pciModel->exchangeArray(json_decode(file_get_contents($packageValid . DIRECTORY_SEPARATOR . PciModel::PCI_MANIFEST), true)); $service = new PortableElementService(); $service->setServiceLocator(ServiceManager::getServiceManager()); $reflectionClass = new \ReflectionClass(PortableElementService::class); $reflectionMethod = $reflectionClass->getMethod('getRegistry'); $reflectionMethod->setAccessible(true); $registry = $reflectionMethod->invoke($service, new PciModel()); $registry->setSource($packageValid); $registry->register($pciModel); $exportDirectory = $registry->export($pciModel); $parser = new PortableElementPackageParser($exportDirectory); $parser->setModel(new PciModel()); $source = $parser->extract(); $original = $this->fillArrayWithFileNodes(new \DirectoryIterator($packageValid)); $exported = $this->fillArrayWithFileNodes(new \DirectoryIterator($source)); $this->assertEquals(preg_replace('/\\s+/', '', file_get_contents($packageValid . DIRECTORY_SEPARATOR . PciModel::PCI_MANIFEST)), preg_replace('/\\s+/', '', file_get_contents($source . DIRECTORY_SEPARATOR . PciModel::PCI_MANIFEST))); $this->assertTrue(empty($this->array_diff_assoc_recursive($original, $exported))); $registry->unregister($pciModel); \tao_helpers_File::delTree($source); }
/** * Overriden export from QTI items. * * @see taoItems_models_classes_ItemExporter::export() * @param array $options An array of options. * @return \common_report_Report * @throws ExportException * @throws \common_Exception * @throws \common_exception_Error * @throws \core_kernel_persistence_Exception * @throws PortableElementInvalidAssetException */ public function export($options = array()) { $report = \common_report_Report::createSuccess(); $asApip = isset($options['apip']) && $options['apip'] === true; $lang = \common_session_SessionManager::getSession()->getDataLanguage(); $basePath = $this->buildBasePath(); if (is_null($this->getItemModel())) { throw new ExportException('', 'No Item Model found for item : ' . $this->getItem()->getUri()); } $dataFile = (string) $this->getItemModel()->getOnePropertyValue(new core_kernel_classes_Property(TAO_ITEM_MODEL_DATAFILE_PROPERTY)); $resolver = new ItemMediaResolver($this->getItem(), $lang); $replacementList = array(); $modelsAssets = $this->getPortableElementAssets($this->getItem(), $lang); $service = new PortableElementService(); $service->setServiceLocator(ServiceManager::getServiceManager()); $portableElementsToExport = $portableAssetsToExport = []; foreach ($modelsAssets as $key => $portableElements) { /** @var $element */ foreach ($portableElements as $element) { if (!$element instanceof Element) { continue; } try { $object = $service->retrieve($key, $element->getTypeIdentifier()); } catch (PortableElementException $e) { $message = __('Fail to export item') . ' (' . $this->getItem()->getLabel() . '): ' . $e->getMessage(); return \common_report_Report::createFailure($message); } $portableElementsToExport[$element->getTypeIdentifier()] = $object; $files = $object->getModel()->getValidator()->getAssets($object, 'runtime'); $baseUrl = $basePath . DIRECTORY_SEPARATOR . $object->getTypeIdentifier(); $portableAssetsToExport[$object->getTypeIdentifier()] = []; foreach ($files as $url) { try { // Skip shared libraries into portable element if (strpos($url, './') !== 0) { \common_Logger::i('Shared libraries skipped : ' . $url); $portableAssetsToExport[$object->getTypeIdentifier()][$url] = $url; continue; } $stream = $service->getFileStream($object, $url); $replacement = $this->copyAssetFile($stream, $baseUrl, $url, $replacementList); $portableAssetToExport = preg_replace('/^(.\\/)(.*)/', $object->getTypeIdentifier() . "/\$2", $replacement); $portableAssetsToExport[$object->getTypeIdentifier()][$url] = $portableAssetToExport; \common_Logger::i('File copied: "' . $url . '" for portable element ' . $object->getTypeIdentifier()); } catch (\tao_models_classes_FileNotFoundException $e) { \common_Logger::i($e->getMessage()); $report->setMessage('Missing resource for ' . $url); $report->setType(\common_report_Report::TYPE_ERROR); } } } } $assets = $this->getAssets($this->getItem(), $lang); foreach ($assets as $assetUrl) { try { $mediaAsset = $resolver->resolve($assetUrl); $mediaSource = $mediaAsset->getMediaSource(); if (!$mediaSource instanceof HttpSource) { $link = $mediaAsset->getMediaIdentifier(); $stream = $mediaSource->getFileStream($link); $baseName = $mediaSource instanceof LocalItemSource ? $link : 'assets/' . $mediaSource->getBaseName($link); $replacement = $this->copyAssetFile($stream, $basePath, $baseName, $replacementList); $replacementList[$assetUrl] = $replacement; } } catch (\tao_models_classes_FileNotFoundException $e) { $replacementList[$assetUrl] = ''; $report->setMessage('Missing resource for ' . $assetUrl); $report->setType(\common_report_Report::TYPE_ERROR); } } $xml = Service::singleton()->getXmlByRdfItem($this->getItem()); $dom = new DOMDocument('1.0', 'UTF-8'); $dom->preserveWhiteSpace = false; $dom->formatOutput = true; if ($dom->loadXML($xml) === true) { $xpath = new \DOMXPath($dom); $attributeNodes = $xpath->query('//@*'); $portableEntryNodes = $xpath->query("//*[local-name()='entry']") ?: []; unset($xpath); foreach ($attributeNodes as $node) { if (isset($replacementList[$node->value])) { $node->value = $replacementList[$node->value]; } } foreach ($portableEntryNodes as $node) { $node->nodeValue = strtr(htmlentities($node->nodeValue, ENT_XML1), $replacementList); } $this->exportPortableAssets($dom, 'portableCustomInteraction', 'customInteractionTypeIdentifier', 'pci', $portableElementsToExport, $portableAssetsToExport); $this->exportPortableAssets($dom, 'portableInfoControl', 'infoControlTypeIdentifier', 'pic', $portableElementsToExport, $portableAssetsToExport); } else { throw new ExportException($this->getItem()->getLabel(), 'Unable to load XML'); } $dom->preserveWhiteSpace = true; $dom->formatOutput = true; if (($content = $dom->saveXML()) === false) { throw new ExportException($this->getItem()->getLabel(), 'Unable to save XML'); } // Possibility to delegate (if necessary) some item content post-processing to sub-classes. $content = $this->itemContentPostProcessing($content); // add xml file $this->getZip()->addFromString($basePath . '/' . $dataFile, $content); if (!$report->getMessage()) { $report->setMessage(__('Item ' . $this->getItem()->getLabel() . ' exported.')); } return $report; }