/** * Resolve a taomedia url to a media asset * * @param string $url * @throws \Exception * @return \oat\tao\model\media\MediaAsset */ public function resolve($url) { $urlParts = parse_url($url); if (isset($urlParts['scheme']) && $urlParts['scheme'] === MediaService::SCHEME_NAME && isset($urlParts['host'])) { $mediaService = new MediaService(); $mediaSource = $mediaService->getMediaSource($urlParts['host']); $mediaId = isset($urlParts['path']) ? trim($urlParts['path'], '/') : ''; return new MediaAsset($mediaSource, $mediaId); } elseif (isset($urlParts['scheme']) && in_array($urlParts['scheme'], array('http', 'https'))) { return new MediaAsset(new HttpSource(), $url); } else { throw new TaoMediaException('Cannot resolve ' . $url); } }
/** * MediaAssetHandler constructor. * Retrieve shared storage * */ public function __construct() { $sources = MediaService::singleton()->getWritableSources(); $this->sharedStorage = array_shift($sources); return $this; }
public function getMediaSources() { $exclude = ''; if ($this->hasRequestParameter('exclude')) { $exclude = $this->getRequestParameter('exclude'); } // get the config media Sources $sources = array_keys(MediaService::singleton()->getBrowsableSources()); $mediaSources = array(); if ($exclude !== 'local') { $mediaSources[] = array('root' => 'local', 'path' => '/'); } foreach ($sources as $source) { if ($source !== $exclude) { $mediaSources[] = array('root' => $source, 'path' => 'taomedia://' . $source . '/'); } } $this->returnJson($mediaSources); }
/** * * @param string $initialVersion * @return string $versionUpdatedTo */ public function update($initialVersion) { $currentVersion = $initialVersion; //migrate from 0.1 to 0.1.1 if ($currentVersion == '0.1') { // mediaSources set in 0.2 $currentVersion = '0.1.1'; } if ($currentVersion == '0.1.1') { FileManager::setFileManagementModel(new SimpleFileManagement()); // mediaSources unset in 0.2 $currentVersion = '0.1.2'; } if ($currentVersion == '0.1.2') { //add alt text to media manager $file = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'alt_text.rdf'; $adapter = new \tao_helpers_data_GenerisAdapterRdf(); if ($adapter->import($file)) { $currentVersion = '0.1.3'; } else { \common_Logger::w('Import failed for ' . $file); } } if ($currentVersion == '0.1.3') { OntologyUpdater::correctModelId(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'alt_text.rdf'); $currentVersion = '0.1.4'; } if ($currentVersion == '0.1.4') { //modify config files due to the new interfaces relation $tao = \common_ext_ExtensionsManager::singleton()->getExtensionById('tao'); $tao->unsetConfig('mediaManagementSources'); $tao->unsetConfig('mediaBrowserSources'); TaoMediaService::singleton()->addMediaSource(new MediaSource()); //modify links in item content $service = \taoItems_models_classes_ItemsService::singleton(); $items = $service->getAllByModel('http://www.tao.lu/Ontologies/TAOItem.rdf#QTI'); foreach ($items as $item) { $itemContent = $service->getItemContent($item); $itemContent = preg_replace_callback('/src="mediamanager\\/([^"]+)"/', function ($matches) { $mediaClass = MediaService::singleton()->getRootClass(); $medias = $mediaClass->searchInstances(array(MEDIA_LINK => $matches[1]), array('recursive' => true)); $media = array_pop($medias); $uri = ''; if (!is_null($media) && $media->exists()) { $uri = \tao_helpers_Uri::encode($media->getUri()); } return 'src="taomedia://mediamanager/' . $uri . '"'; }, $itemContent); $itemContent = preg_replace_callback('/src="local\\/([^"]+)"/', function ($matches) { return 'src="' . $matches[1] . '"'; }, $itemContent); $service->setItemContent($item, $itemContent); } $currentVersion = '0.2.0'; } if ($currentVersion === '0.2.0') { $accessService = \funcAcl_models_classes_AccessService::singleton(); //revoke access right to back office $backOffice = new \core_kernel_classes_Resource('http://www.tao.lu/Ontologies/TAO.rdf#BackOfficeRole'); $accessService->revokeExtensionAccess($backOffice, 'taoMediaManager'); //grant access right to media manager $mediaManager = new \core_kernel_classes_Resource('http://www.tao.lu/Ontologies/TAOMedia.rdf#MediaManagerRole'); $accessService->grantExtensionAccess($mediaManager, 'taoMediaManager'); $currentVersion = '0.2.1'; } if ($currentVersion === '0.2.1') { //include mediamanager into globalmanager $mediaManager = new \core_kernel_classes_Resource('http://www.tao.lu/Ontologies/TAOMedia.rdf#MediaManagerRole'); $globalManager = new \core_kernel_Classes_Resource('http://www.tao.lu/Ontologies/TAO.rdf#GlobalManagerRole'); \tao_models_classes_RoleService::singleton()->includeRole($globalManager, $mediaManager); $currentVersion = '0.2.2'; } if ($currentVersion === '0.2.2') { //copy file from /media to data/taoMediaManager/media and delete /media $dataPath = FILES_PATH . 'taoMediaManager' . DIRECTORY_SEPARATOR . 'media' . DIRECTORY_SEPARATOR; $dir = dirname(dirname(__DIR__)) . '/media'; if (file_exists($dir)) { if (\tao_helpers_File::copy($dir, $dataPath)) { $it = new \RecursiveDirectoryIterator($dir, \RecursiveDirectoryIterator::SKIP_DOTS); $files = new \RecursiveIteratorIterator($it, \RecursiveIteratorIterator::CHILD_FIRST); foreach ($files as $file) { if ($file->isDir()) { rmdir($file->getRealPath()); } else { unlink($file->getRealPath()); } } rmdir($dir); $currentVersion = '0.2.3'; } } else { $currentVersion = '0.2.3'; } } if ($currentVersion === '0.2.3') { $accessService = \funcAcl_models_classes_AccessService::singleton(); //grant access to item author $itemAuthor = new \core_kernel_classes_Resource('http://www.tao.lu/Ontologies/TAOItem.rdf#ItemAuthor'); $accessService->grantExtensionAccess($itemAuthor, 'taoMediaManager'); $currentVersion = '0.2.4'; } if ($currentVersion === '0.2.4') { $mediaClass = MediaService::singleton()->getRootClass(); $fileManager = FileManager::getFileManagementModel(); foreach ($mediaClass->getInstances(true) as $media) { $fileLink = $media->getUniquePropertyValue(new \core_kernel_classes_Property(MEDIA_LINK)); $fileLink = $fileLink instanceof \core_kernel_classes_Resource ? $fileLink->getUri() : (string) $fileLink; $filePath = $fileManager->retrieveFile($fileLink); $mimeType = \tao_helpers_File::getMimeType($filePath); $mimeType = $mimeType === 'application/xhtml+xml' ? 'application/qti+xml' : $mimeType; $media->setPropertyValue(new \core_kernel_classes_Property(MEDIA_MIME_TYPE), $mimeType); } $currentVersion = '0.2.5'; } if ($currentVersion === '0.2.5') { $fileManager = FileManager::getFileManagementModel(); $iterator = new \core_kernel_classes_ResourceIterator(array(MediaService::singleton()->getRootClass())); foreach ($iterator as $media) { $fileLink = $media->getUniquePropertyValue(new \core_kernel_classes_Property(MEDIA_LINK)); $fileLink = $fileLink instanceof \core_kernel_classes_Resource ? $fileLink->getUri() : (string) $fileLink; $filePath = $fileManager->retrieveFile($fileLink); try { SharedStimulusImporter::isValidSharedStimulus($filePath); $media->editPropertyValues(new \core_kernel_classes_Property(MEDIA_MIME_TYPE), 'application/qti+xml'); } catch (\Exception $e) { $mimeType = \tao_helpers_File::getMimeType($filePath); $media->editPropertyValues(new \core_kernel_classes_Property(MEDIA_MIME_TYPE), $mimeType); } } $currentVersion = '0.3.0'; } $this->skip('0.3.0', '0.5.1'); }
/** * @param $folder * @param \taoQtiTest_models_classes_QtiResource $qtiItemResource * @param $itemClass * @param bool|false $extractApip * @param array $dependencies * @return common_report_Report * @throws common_exception_Error */ public function importQtiItem($folder, Resource $qtiItemResource, $itemClass, $extractApip = false, $dependencies = array()) { try { //load the information about resources in the manifest $itemService = taoItems_models_classes_ItemsService::singleton(); $qtiService = Service::singleton(); // The metadata import feature needs a DOM representation of the manifest. $domManifest = new DOMDocument('1.0', 'UTF-8'); $domManifest->load($folder . 'imsmanifest.xml'); $metadataMapping = $qtiService->getMetadataRegistry()->getMapping(); $metadataInjectors = array(); $metadataGuardians = array(); $metadataClassLookups = array(); $metadataValues = array(); foreach ($metadataMapping['injectors'] as $injector) { $metadataInjectors[] = new $injector(); } foreach ($metadataMapping['guardians'] as $guardian) { $metadataGuardians[] = new $guardian(); } foreach ($metadataMapping['classLookups'] as $classLookup) { $metadataClassLookups[] = new $classLookup(); } foreach ($metadataMapping['extractors'] as $extractor) { $metadataExtractor = new $extractor(); $metadataValues = array_merge($metadataValues, $metadataExtractor->extract($domManifest)); } $sources = MediaService::singleton()->getWritableSources(); $sharedStorage = array_shift($sources); $sharedFiles = array(); 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) { $msg = __('The IMS QTI Item referenced as "%s" in the IMS Manifest file was already stored in the Item Bank.', $qtiItemResource->getIdentifier()); $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) { if (($targetClass = $classLookup->lookup($metadataValues[$resourceIdentifier])) !== false) { break; } } } $qtiFile = $folder . $qtiItemResource->getFile(); $qtiModel = $this->createQtiItemModel($qtiFile); $rdfItem = $this->createRdfItem($targetClass !== false ? $targetClass : $itemClass, $qtiModel); $name = $rdfItem->getLabel(); $itemContent = $itemService->getItemContent($rdfItem); $xincluded = array(); foreach ($qtiModel->getBody()->getComposingElements('oat\\taoQtiItem\\model\\qti\\Xinclude') as $xincludeEle) { $xincluded[] = $xincludeEle->attr('href'); } $local = new LocalItemSource(array('item' => $rdfItem)); foreach ($qtiItemResource->getAuxiliaryFiles() as $auxResource) { // file on FS $auxFile = $folder . str_replace('/', DIRECTORY_SEPARATOR, $auxResource); // rel path in item $auxPath = str_replace(DIRECTORY_SEPARATOR, '/', helpers_File::getRelPath($qtiFile, $auxFile)); if (!empty($sharedStorage) && in_array($auxPath, $xincluded)) { $md5 = md5_file($auxFile); if (isset($sharedFiles[$md5])) { $info = $sharedFiles[$md5]; \common_Logger::i('Auxiliary file \'' . $auxPath . '\' linked to shared storage.'); } else { // TODO cleanup sharedstimulus import/export // move to taoQti item or library // validate the shared stimulus SharedStimulusImporter::isValidSharedStimulus($auxFile); // embed assets in the shared stimulus $newXmlFile = SharedStimulusPackageImporter::embedAssets($auxFile); $info = $sharedStorage->add($newXmlFile, basename($auxFile), $name); if (method_exists($sharedStorage, 'forceMimeType')) { // add() does not return link, so we need to parse it $resolver = new ItemMediaResolver($rdfItem, ''); $asset = $resolver->resolve($info['uri']); $sharedStorage->forceMimeType($asset->getMediaIdentifier(), 'application/qti+xml'); } $sharedFiles[$md5] = $info; \common_Logger::i('Auxiliary file \'' . $auxPath . '\' added to shared storage.'); } } else { // store locally, in a safe directory $safePath = ''; if (dirname($auxPath) !== '.') { $safePath = str_replace('../', '', dirname($auxPath)) . '/'; } $info = $local->add($auxFile, basename($auxFile), $safePath); \common_Logger::i('Auxiliary file \'' . $auxPath . '\' copied.'); } // replace uri if changed if ($auxPath != ltrim($info['uri'], '/')) { $itemContent = str_replace($auxPath, $info['uri'], $itemContent); } } foreach ($qtiItemResource->getDependencies() as $dependency) { // file on FS if (isset($dependencies[$dependency])) { $auxFile = $dependencies[$dependency]->getFile(); $auxFile = $folder . str_replace('/', DIRECTORY_SEPARATOR, $auxFile); // rel path in item $auxPath = str_replace(DIRECTORY_SEPARATOR, '/', helpers_File::getRelPath($qtiFile, $auxFile)); if (!empty($sharedStorage) && in_array($auxPath, $xincluded)) { $md5 = md5_file($auxFile); if (isset($sharedFiles[$md5])) { $info = $sharedFiles[$md5]; \common_Logger::i('Auxiliary file \'' . $auxPath . '\' linked to shared storage.'); } else { // TODO cleanup sharedstimulus import/export // move to taoQti item or library // validate the shared stimulus SharedStimulusImporter::isValidSharedStimulus($auxFile); // embed assets in the shared stimulus $newXmlFile = SharedStimulusPackageImporter::embedAssets($auxFile); $info = $sharedStorage->add($newXmlFile, basename($auxFile), $name); if (method_exists($sharedStorage, 'forceMimeType')) { // add() does not return link, so we need to parse it $resolver = new ItemMediaResolver($rdfItem, ''); $asset = $resolver->resolve($info['uri']); $sharedStorage->forceMimeType($asset->getMediaIdentifier(), 'application/qti+xml'); } $sharedFiles[$md5] = $info; \common_Logger::i('Auxiliary file \'' . $auxPath . '\' added to shared storage.'); } } else { // store locally, in a safe directory $safePath = ''; if (dirname($auxPath) !== '.') { $safePath = str_replace('../', '', dirname($auxPath)) . '/'; } $info = $local->add($auxFile, basename($auxFile), $safePath); \common_Logger::i('Auxiliary file \'' . $auxPath . '\' copied.'); } // replace uri if changed if ($auxPath != ltrim($info['uri'], '/')) { $itemContent = str_replace($auxPath, $info['uri'], $itemContent); } } } // Finally, import metadata. $this->importItemMetadata($metadataValues, $qtiItemResource, $rdfItem, $metadataInjectors); // And Apip if wanted if ($extractApip) { $this->storeApip($qtiFile, $rdfItem); } $itemService->setItemContent($rdfItem, $itemContent); $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) { $report = new common_report_Report(common_report_Report::TYPE_ERROR, $e->getUserMessage()); } 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 (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.")); 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; }
* modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; under version 2 * of the License (non-upgradable). * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * Copyright (c) 2014 (original work) Open Assessment Technologies SA (under the project TAO-PRODUCT); * * */ use oat\tao\model\media\MediaService; use oat\taoMediaManager\model\fileManagement\FileManager; use oat\taoMediaManager\model\fileManagement\TaoFileManagement; use oat\taoMediaManager\model\MediaSource; $dataPath = FILES_PATH . 'taoMediaManager' . DIRECTORY_SEPARATOR . 'media' . DIRECTORY_SEPARATOR; if (file_exists($dataPath)) { helpers_File::emptyDirectory($dataPath); } $source = tao_models_classes_FileSourceService::singleton()->addLocalSource('MediaManager', $dataPath); $config = array('uri' => $source->getUri()); FileManager::setFileManagementModel(new TaoFileManagement($config)); $mediaManager = new MediaSource(); MediaService::singleton()->addMediaSource($mediaManager);
* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * Copyright (c) 2014 (original work) Open Assessment Technologies SA (under the project TAO-PRODUCT); * * */ use oat\tao\model\media\MediaService; use oat\taoMediaManager\model\fileManagement\FileManager; //remove possible /media folder in taoMediaManager $dir = dirname(dirname(__DIR__)) . '/media'; if (file_exists($dir)) { $it = new \RecursiveDirectoryIterator($dir, \RecursiveDirectoryIterator::SKIP_DOTS); $files = new \RecursiveIteratorIterator($it, \RecursiveIteratorIterator::CHILD_FIRST); foreach ($files as $file) { if ($file->isDir()) { rmdir($file->getRealPath()); } else { unlink($file->getRealPath()); } } rmdir($dir); } MediaService::singleton()->removeMediaSource('mediamanager'); \common_ext_ExtensionsManager::singleton()->getExtensionById('taoMediaManager')->unsetConfig(FileManager::CONFIG_KEY);