/** * @param core_kernel_classes_Resource $item the item to pack * @param string $lang * @param Item $qtiItem * @param \oat\oatbox\filesystem\Directory $directory * @return ItemPack $itemPack * @throws common_Exception */ public function packQtiItem($item, $lang, $qtiItem, Directory $directory) { //use the QtiParser to transform the QTI XML into an assoc array representation try { //build the ItemPack from the parsed data if ($this->replaceXinclude) { $resolver = new ItemMediaResolver($item, $lang); $xincludeLoader = new XIncludeLoader($qtiItem, $resolver); $xincludeLoader->load(true); } $itemPack = new ItemPack(self::$itemType, $qtiItem->toArray()); $itemPack->setAssetEncoders($this->getAssetEncoders()); $assetParser = new AssetParser($qtiItem, $directory); $assetParser->setDeepParsing($this->isNestedResourcesInclusion()); $assetParser->setGetXinclude(!$this->replaceXinclude); $storageDirectory = new \tao_models_classes_service_StorageDirectory($item->getUri(), $directory->getFileSystemId(), $directory->getPrefix() . '/' . $lang); $storageDirectory->setServiceLocator($directory->getServiceLocator()); foreach ($assetParser->extract($itemPack) as $type => $assets) { $resolver = new ItemMediaResolver($item, $lang); foreach ($assets as &$asset) { $mediaAsset = $resolver->resolve($asset); $mediaSource = $mediaAsset->getMediaSource(); $asset = $mediaSource->getBaseName($mediaAsset->getMediaIdentifier()); } $itemPack->setAssets($type, $assets, $storageDirectory); } } catch (common_Exception $e) { throw new common_Exception('Unable to pack item ' . $item->getUri() . ' : ' . $e->getMessage()); } return $itemPack; }
/** * Store a file referenced by $qtiResource into the final $testContent folder. If the path provided * by $qtiResource contains sub-directories, they will be created before copying the file (even * if $copy = false). * * @param Directory $testContent The pointer to the TAO Test Content folder. * @param oat\taoQtiItem\model\qti\Resource|string $qtiResource The QTI resource to be copied into $testContent. If given as a string, it must be the relative (to the IMS QTI Package) path to the resource file. * @param string $origin The path to the directory (root folder of extracted IMS QTI package) containing the QTI resource to be copied. * @param boolean $copy If set to false, the file will not be actually copied. * @param string $rename A new filename e.g. 'file.css' to be used at storage time. * @return string The path were the file was copied/has to be copied (depending on the $copy argument). * @throws InvalidArgumentException If one of the above arguments is invalid. * @throws common_Exception If the copy fails. */ public static function storeQtiResource(Directory $testContent, $qtiResource, $origin, $copy = true, $rename = '') { $fss = ServiceManager::getServiceManager()->get(FileSystemService::SERVICE_ID); $fs = $fss->getFileSystem($testContent->getFileSystem()->getId()); $contentPath = $testContent->getPrefix(); $ds = DIRECTORY_SEPARATOR; $contentPath = rtrim($contentPath, $ds); if ($qtiResource instanceof Resource) { $filePath = $qtiResource->getFile(); } else { if (is_string($qtiResource) === true) { $filePath = $qtiResource; } else { throw new InvalidArgumentException("The 'qtiResource' argument must be a string or a taoQTI_models_classes_QTI_Resource object."); } } $resourcePathinfo = pathinfo($filePath); if (empty($resourcePathinfo['dirname']) === false && $resourcePathinfo['dirname'] !== '.') { // The resource file is not at the root of the archive but in a sub-folder. // Let's copy it in the same way into the Test Content folder. $breadCrumb = $contentPath . $ds . str_replace('/', $ds, $resourcePathinfo['dirname']); $breadCrumb = rtrim($breadCrumb, $ds); $finalName = empty($rename) === true ? $resourcePathinfo['filename'] . '.' . $resourcePathinfo['extension'] : $rename; $finalPath = $breadCrumb . $ds . $finalName; } else { // The resource file is at the root of the archive. // Overwrite template test.xml (created by self::createContent() method above) file with the new one. $finalName = empty($rename) === true ? $resourcePathinfo['filename'] . '.' . $resourcePathinfo['extension'] : $rename; $finalPath = $contentPath . $ds . $finalName; } if ($copy === true) { $origin = str_replace('/', $ds, $origin); $origin = rtrim($origin, $ds); $sourcePath = $origin . $ds . str_replace('/', $ds, $filePath); if (is_readable($sourcePath) === false) { throw new common_Exception("An error occured while copying the QTI resource from '{$sourcePath}' to '{$finalPath}'."); } $fh = fopen($sourcePath, 'r'); $success = $fs->writeStream($finalPath, $fh); fclose($fh); if (!$success) { throw new common_Exception("An error occured while copying the QTI resource from '{$sourcePath}' to '{$finalPath}'."); } } return $finalPath; }
/** * Lookup and extract assets from a stylesheet element * @param Element $element the stylesheet element */ private function extractStyleSheet(Element $element) { if ($element instanceof StyleSheet) { $href = $element->attr('href'); $this->addAsset('css', $href); $parsedUrl = parse_url($href); if ($this->isDeepParsing() && array_key_exists('path', $parsedUrl) && !array_key_exists('host', $parsedUrl)) { $file = $this->directory->getFile($parsedUrl['path']); if ($file->exists()) { $this->loadStyleSheetAsset($file->read()); } } } }
/** * * @param $id * @return \oat\oatbox\filesystem\Directory */ public function getDirectory($id) { $directory = new Directory($id, ''); $directory->setServiceLocator($this->getServiceLocator()); return $directory; }
/** * @param core_kernel_classes_Resource $item * @param string $lang * @param Directory $publicDirectory * @return qti\Item * @throws taoItems_models_classes_CompilationFailedException */ protected function retrieveAssets(core_kernel_classes_Resource $item, $lang, Directory $publicDirectory) { $qtiItem = Service::singleton()->getDataItemByRdfItem($item, $lang); $assetParser = new AssetParser($qtiItem, $publicDirectory); $assetParser->setGetSharedLibraries(false); $assetParser->setGetXinclude(false); $resolver = new ItemMediaResolver($item, $lang); $replacementList = array(); foreach ($assetParser->extract() as $type => $assets) { foreach ($assets as $assetUrl) { foreach (self::$BLACKLIST as $blacklist) { if (preg_match($blacklist, $assetUrl) === 1) { continue 2; } } $mediaAsset = $resolver->resolve($assetUrl); $mediaSource = $mediaAsset->getMediaSource(); $basename = $mediaSource->getBaseName($mediaAsset->getMediaIdentifier()); $replacement = $basename; $count = 0; while (in_array($replacement, $replacementList)) { $dot = strrpos($basename, '.'); $replacement = $dot !== false ? substr($basename, 0, $dot) . '_' . $count . substr($basename, $dot) : $basename . $count; $count++; } $replacementList[$assetUrl] = $replacement; $tmpfile = $mediaSource->download($mediaAsset->getMediaIdentifier()); $fh = fopen($tmpfile, 'r'); $publicDirectory->writeStream($lang . '/' . $replacement, $fh); fclose($fh); unlink($tmpfile); //$fileStream = $mediaSource->getFileStream($mediaAsset->getMediaIdentifier()); //$publicDirectory->writeStream($lang.'/'.$replacement, $fileStream); } } $dom = new \DOMDocument('1.0', 'UTF-8'); if ($dom->loadXML($qtiItem->toXml()) === true) { $xpath = new \DOMXPath($dom); $attributeNodes = $xpath->query('//@*'); foreach ($attributeNodes as $node) { if (isset($replacementList[$node->value])) { $node->value = $replacementList[$node->value]; } } $attributeNodes = $xpath->query("//*[local-name()='entry']") ?: []; unset($xpath); foreach ($attributeNodes as $node) { $node->nodeValue = strtr(htmlentities($node->nodeValue, ENT_XML1), $replacementList); } } else { throw new taoItems_models_classes_CompilationFailedException('Unable to load XML'); } $qtiParser = new Parser($dom->saveXML()); $assetRetrievedQtiItem = $qtiParser->load(); //loadxinclude $xincludeLoader = new XIncludeLoader($assetRetrievedQtiItem, $resolver); $xincludeLoader->load(true); return $assetRetrievedQtiItem; }
/** * @deprecated Should not be called * * @return Filesystem */ public function getFlySystem() { return parent::getFilesystem(); }