getOption(self::OPTION_ASSEMBLY_FILES_READER) instanceof AssemblyFilesReaderInterface) { throw new InvalidArgumentException(sprintf('%s option value must be an instance of %s', self::OPTION_ASSEMBLY_FILES_READER, AssemblyFilesReaderInterface::class)); } $this->rdfExporter = $this->getOption(self::OPTION_RDF_EXPORTER); if (!$this->rdfExporter instanceof tao_models_classes_export_RdfExporter) { throw new InvalidArgumentException('%s option value must be an instance of %s', self::OPTION_RDF_EXPORTER, tao_models_classes_export_RdfExporter::class); } } /** * Export Compiled Delivery * * Exports a delivery into its compiled form. In case of the $fsExportPath argument is set, * the compiled delivery will be stored in the 'taoDelivery' shared file system, at $fsExportPath location. * * @param core_kernel_classes_Resource $compiledDelivery * @param string $outputTestFormat Format compiled test file in output assembly package. * * @return string The path to the compiled delivery on the local file system OR the 'taoDelivery' shared file system, depending on whether $fsExportPath is set. * * @throws common_Exception * @throws core_kernel_classes_EmptyProperty */ public function exportCompiledDelivery(core_kernel_classes_Resource $compiledDelivery, $outputTestFormat) { $this->logDebug("Exporting Delivery Assembly '" . $compiledDelivery->getUri() . "'..."); $fileName = tao_helpers_Display::textCleaner($compiledDelivery->getLabel()) . '.zip'; $path = tao_helpers_File::concat([tao_helpers_Export::getExportPath(), $fileName]); if (!tao_helpers_File::securityCheck($path, true)) { throw new Exception('Unauthorized file name'); } // If such a target zip file exists, remove it from local filesystem. It prevents some synchronicity issues // to occur while dealing with ZIP Archives (not explained yet). if (file_exists($path)) { unlink($path); } $zipArchive = new ZipArchive(); if ($zipArchive->open($path, ZipArchive::CREATE) !== true) { throw new Exception('Unable to create archive at ' . $path); } $this->setupCompiledTestConverter($outputTestFormat); $this->doExportCompiledDelivery($path, $compiledDelivery, $zipArchive); $zipArchive->close(); return $path; } /** * Do Export Compiled Delivery * * Method containing the main behavior of exporting a compiled delivery into a ZIP archive. * * For developers wanting to override this method, the following information has to be taken into account: * * - The value of the $zipArgive argument is an already open ZipArchive object. * - The method must keep the archive open after its execution (calling code will take care of it). * * @param $path * @param core_kernel_classes_Resource $compiledDelivery * @param ZipArchive $zipArchive * @throws common_Exception * @throws core_kernel_classes_EmptyProperty */ protected function doExportCompiledDelivery($path, core_kernel_classes_Resource $compiledDelivery, ZipArchive $zipArchive) { $taoDeliveryVersion = common_ext_ExtensionsManager::singleton()->getInstalledVersion('taoDelivery'); $data = [ 'dir' => [], 'label' => $compiledDelivery->getLabel(), 'version' => $taoDeliveryVersion ]; $directories = $compiledDelivery->getPropertyValues($this->getProperty(DeliveryAssemblyService::PROPERTY_DELIVERY_DIRECTORY)); foreach ($directories as $id) { $directory = $this->getServiceLocator()->get(ServiceFileStorage::SERVICE_ID)->getDirectoryById($id); foreach ($this->getAssemblyFilesReader()->getFiles($directory) as $filePath => $fileStream) { tao_helpers_File::addFilesToZip($zipArchive, $fileStream, $filePath); } $data['dir'][$id] = $directory->getPrefix(); } $runtime = $compiledDelivery->getOnePropertyValue( $this->getProperty(DeliveryAssemblyService::PROPERTY_DELIVERY_RUNTIME) ); $serviceCall = $runtime instanceof core_kernel_classes_Resource ? tao_models_classes_service_ServiceCall::fromResource($runtime) : tao_models_classes_service_ServiceCall::fromString((string)$runtime); $data['runtime'] = base64_encode(json_encode($serviceCall)); $rdfData = $this->rdfExporter->getRdfString([$compiledDelivery]); if (!$zipArchive->addFromString(self::DELIVERY_RDF_FILENAME, $rdfData)) { throw new common_Exception('Unable to add metadata to exported delivery assembly'); } $data['meta'] = self::DELIVERY_RDF_FILENAME; $content = json_encode($data); if (!$zipArchive->addFromString(self::MANIFEST_FILENAME, $content)) { $zipArchive->close(); unlink($path); throw new common_Exception('Unable to add manifest to exported delivery assembly'); } } /** * @param string $outputTestFormat * @return void * * @throws UnsupportedCompiledTestFormatException */ private function setupCompiledTestConverter($outputTestFormat) { /** @var CompiledTestConverterFactory $compiledTestConverterFactory */ $compiledTestConverterFactory = $this->getServiceLocator()->get(CompiledTestConverterFactory::class); $converter = $compiledTestConverterFactory->createConverter($outputTestFormat); if ($converter) { $this->getAssemblyFilesReader()->setCompiledTestConverter($converter); } } /** * @return AssemblyFilesReaderInterface */ private function getAssemblyFilesReader() { if (!$this->assemblyFilesReader instanceof AssemblyFilesReaderInterface) { $this->assemblyFilesReader = $this->getOption(self::OPTION_ASSEMBLY_FILES_READER); } return $this->assemblyFilesReader; } }