setGetSharedLibraries(false); $assetParser->setGetXinclude(true); $xincludeLoader = new XIncludeLoader($qtiItem, $resolver); $xincludeLoader->load(); $packedAssets = []; foreach ($assetParser->extract() as $type => $assets) { foreach ($assets as $key => $assetUrl) { if ($this->isBlacklisted($assetUrl)) { continue; } $packedAsset = $this->resolve($resolver, $assetUrl, $type); $replacement = $this->getReplacementName($packedAsset); $packedAsset->setReplacedBy($replacement); if ($type != 'xinclude') { if ($this->getQtiItemAssetReplacer()->shouldBeReplaced($packedAsset)) { $packedAsset = $this->replaceWithExternalSource($packedAsset, $qtiItem); } else { $this->copyAssetFileToPublicDirectory($publicDirectory, $packedAsset); } } $packedAssets[$assetUrl] = $packedAsset; } } return $packedAssets; } private function replaceWithExternalSource(PackedAsset $packedAsset, Item $qtiItem): PackedAsset { $qtiItemAssetReplacer = $this->getQtiItemAssetReplacer(); return $qtiItemAssetReplacer->replace( $packedAsset, $qtiItem->getIdentifier() ); } private function isBlacklisted(string $assetUrl): bool { return $this->getServiceLocator() ->get(QtiItemCompilerAssetBlacklist::SERVICE_ID) ->isBlacklisted($assetUrl); } private function resolve(ItemMediaResolver $resolver, string $assetUrl, string $type): PackedAsset { $mediaAsset = $resolver->resolve($assetUrl); $mediaSource = $mediaAsset->getMediaSource(); if ($mediaSource instanceof HttpSource) { return new PackedAsset($type, $mediaAsset, $assetUrl); } $fileInfo = $mediaSource->getFileInfo($mediaAsset->getMediaIdentifier()); if (isset($fileInfo['link'])) { $link = $fileInfo['link']; } elseif (isset($fileInfo['filePath'])) { $link = $fileInfo['filePath']; } else { throw new InvalidArgumentException(sprintf('Item asset %s cannot be resolved.', $assetUrl)); } return new PackedAsset($type, $mediaAsset, $link); } private function getReplacementName(PackedAsset $packedAsset): string { $link = $packedAsset->getMediaAsset()->getMediaIdentifier(); return uniqid() . '_' . $packedAsset->getMediaAsset()->getMediaSource()->getBaseName($link); } private function copyAssetFileToPublicDirectory(Directory $publicDirectory, PackedAsset $packedAsset): bool { $mediaAsset = $packedAsset->getMediaAsset(); $mediaSource = $mediaAsset->getMediaSource(); $content = $mediaSource->getFileStream($mediaAsset->getMediaIdentifier()); $this->logInfo(sprintf( 'Copying %s reference %s to file %s', $packedAsset->getType(), $mediaAsset->getMediaIdentifier(), $packedAsset->getReplacedBy() )); return $publicDirectory->getFile($packedAsset->getReplacedBy())->write($content); } private function getQtiItemAssetReplacer(): QtiItemAssetReplacer { return $this->getServiceLocator()->get(QtiItemAssetReplacer::SERVICE_ID); } }