221 lines
6.8 KiB
PHP
221 lines
6.8 KiB
PHP
|
<?php
|
||
|
|
||
|
/**
|
||
|
* This program is free software; you can redistribute it and/or
|
||
|
* 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-2021 (original work) Open Assessment Technologies SA;
|
||
|
*/
|
||
|
|
||
|
declare(strict_types=1);
|
||
|
|
||
|
namespace oat\taoMediaManager\model;
|
||
|
|
||
|
use common_Exception;
|
||
|
use common_report_Report as Report;
|
||
|
use core_kernel_classes_Class;
|
||
|
use core_kernel_classes_Container;
|
||
|
use core_kernel_classes_EmptyProperty;
|
||
|
use core_kernel_classes_Literal;
|
||
|
use core_kernel_classes_Property;
|
||
|
use core_kernel_classes_Resource;
|
||
|
use oat\oatbox\service\ServiceManager;
|
||
|
use oat\taoMediaManager\model\export\service\MediaResourcePreparer;
|
||
|
use oat\taoMediaManager\model\export\service\SharedStimulusCSSExporter;
|
||
|
use oat\taoMediaManager\model\fileManagement\FileManagement;
|
||
|
use tao_helpers_Export;
|
||
|
use tao_models_classes_export_ExportHandler;
|
||
|
use ZipArchive;
|
||
|
|
||
|
/**
|
||
|
* Service methods to manage the Media
|
||
|
*
|
||
|
* @access public
|
||
|
* @author Antoine Robin, <antoine.robin@vesperiagroup.com>
|
||
|
* @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;
|
||
|
}
|
||
|
}
|