* @package taoMediaManager */ class ZipExporter implements tao_models_classes_export_ExportHandler { /** * @inheritDoc */ public function getLabel() { return __('Zip'); } /** * @inheritDoc */ public function getExportForm(core_kernel_classes_Resource $resource) { return (new ZipExportForm(['resource' => $resource])) ->getForm(); } /** * @inheritDoc */ public function export($formValues, $destPath) { if (!isset($formValues['filename'])) { return Report::createFailure('Missing filename for export using ' . __CLASS__); } if (!isset($formValues['id'])) { return Report::createFailure('No id for export using ' . __CLASS__); } $report = Report::createSuccess(); $report->setData($this->processExport($formValues)); $report->setMessage(__('Media successfully exported.')); return $report; } private function processExport(array $formValues): string { $class = new core_kernel_classes_Class($formValues['id']); $exportClasses = []; if ($class->isClass()) { $exportData = [ $class->getLabel() => $this->getClassResources($class) ]; foreach ($class->getSubClasses(true) as $subClass) { $instances = $this->getClassResources($subClass); if (count($instances) === 0) { continue; } $exportData[$subClass->getLabel()] = $instances; $exportClasses[$subClass->getLabel()] = $this->normalizeClassName($subClass, $exportClasses); } } else { $exportData = [$class->getLabel() => [$class]]; } $safePath = $this->getSavePath($formValues['filename']); return $this->createZipFile($safePath, $exportClasses, $exportData); } private function normalizeClassName(core_kernel_classes_Class $class, array $exportClasses): string { $parents = $class->getParentClasses(); $parent = array_shift($parents); return array_key_exists($parent->getLabel(), $exportClasses) ? $exportClasses[$parent->getLabel()] . '/' . $class->getLabel() : $class->getLabel(); } private function getSavePath(string $unsafePath): string { $pathInfo = pathinfo($unsafePath); $safePath = $pathInfo['filename']; if (array_key_exists('extension', $pathInfo)) { $safePath .= '.' . $pathInfo['extension']; } return $safePath; } protected function createZipFile($filename, array $exportClasses = [], array $exportFiles = []): string { $zip = new ZipArchive(); $baseDir = tao_helpers_Export::getExportPath(); $path = $baseDir . '/' . $filename . '.zip'; if ($zip->open($path, ZipArchive::CREATE) !== true) { throw new common_Exception('Unable to create zipfile ' . $path); } if ($zip->numFiles === 0) { foreach ($exportFiles as $label => $files) { $archivePath = ''; /** @var $class core_kernel_classes_Class */ if (array_key_exists($label, $exportClasses)) { $archivePath = $exportClasses[$label] . '/'; $zip->addEmptyDir($archivePath); } //create the directory /** @var core_kernel_classes_Resource $fileResource */ foreach ($files as $fileResource) { $link = $this->getResourceLink($fileResource); $fileContent = $this->getFileManagement() ->getFileStream($link); $preparedFileContent = $this->getMediaResourcePreparer()->prepare($fileResource, $fileContent); $zip->addFromString($archivePath . $fileResource->getLabel(), $preparedFileContent); $this->getSharedStimulusCSSExporter()->pack($fileResource, $link, $zip); } } } $zip->close(); return $path; } public function getServiceManager() { return ServiceManager::getServiceManager(); } private function getFileManagement(): FileManagement { return $this->getServiceManager()->get(FileManagement::SERVICE_ID); } private function getMediaResourcePreparer(): MediaResourcePreparer { return $this->getServiceManager()->get(MediaResourcePreparer::class); } private function getSharedStimulusCSSExporter(): SharedStimulusCSSExporter { return $this->getServiceManager()->get(SharedStimulusCSSExporter::class); } private function getClassResources(core_kernel_classes_Class $class): array { return $class->getInstances(); } /** * @return core_kernel_classes_Container|string * * @throws core_kernel_classes_EmptyProperty * @throws common_Exception */ private function getResourceLink(core_kernel_classes_Resource $resource) { $link = $resource->getUniquePropertyValue(new core_kernel_classes_Property(MediaService::PROPERTY_LINK)); return $link instanceof core_kernel_classes_Literal ? $link->literal : $link; } }