213 lines
6.6 KiB
PHP
213 lines
6.6 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) 2020 (original work) Open Assessment Technologies SA;
|
||
|
*/
|
||
|
|
||
|
namespace oat\taoRevision\model;
|
||
|
|
||
|
use common_Exception;
|
||
|
use common_Logger;
|
||
|
use oat\generis\model\fileReference\FileReferenceSerializer;
|
||
|
use oat\generis\model\GenerisRdf;
|
||
|
use oat\generis\model\OntologyAwareTrait;
|
||
|
use oat\generis\model\OntologyRdfs;
|
||
|
use oat\oatbox\filesystem\Directory;
|
||
|
use oat\oatbox\filesystem\File;
|
||
|
use oat\oatbox\filesystem\FileSystemService;
|
||
|
use oat\oatbox\service\ConfigurableService;
|
||
|
use core_kernel_classes_ContainerCollection as TriplesCollection;
|
||
|
use core_kernel_classes_Resource as Resource;
|
||
|
use core_kernel_classes_Triple as Triple;
|
||
|
use core_kernel_persistence_smoothsql_SmoothModel as Model;
|
||
|
use oat\taoMediaManager\model\fileManagement\FileSourceSerializer;
|
||
|
use oat\taoMediaManager\model\MediaService;
|
||
|
|
||
|
/**
|
||
|
* Class TriplesManagerService
|
||
|
* @package oat\taoRevision\model
|
||
|
*/
|
||
|
class TriplesManagerService extends ConfigurableService
|
||
|
{
|
||
|
use OntologyAwareTrait;
|
||
|
|
||
|
public const SERVICE_ID = 'taoRevision/triples';
|
||
|
|
||
|
/**
|
||
|
* @return FileReferenceSerializer
|
||
|
*/
|
||
|
protected function getFileRefSerializer()
|
||
|
{
|
||
|
return $this->getServiceLocator()->get(FileReferenceSerializer::SERVICE_ID);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param Triple $triple
|
||
|
*/
|
||
|
public function deleteTripleDependencies(Triple $triple)
|
||
|
{
|
||
|
if (!$this->isFileReference($triple)) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
$referencer = $this->getFileRefSerializer();
|
||
|
$this->serializeAsset($triple);
|
||
|
$source = $referencer->unserialize($triple->object);
|
||
|
|
||
|
if ($source instanceof Directory) {
|
||
|
$source->deleteSelf();
|
||
|
} elseif ($source instanceof File) {
|
||
|
$source->delete();
|
||
|
}
|
||
|
|
||
|
$referencer->cleanUp($triple->object);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param Resource $resource
|
||
|
* @param Model|null $model
|
||
|
*/
|
||
|
public function deleteTriplesFor(Resource $resource, Model $model = null)
|
||
|
{
|
||
|
$triples = $model
|
||
|
? $model->getRdfsInterface()->getResourceImplementation()->getRdfTriples($resource)
|
||
|
: $resource->getRdfTriples();
|
||
|
|
||
|
foreach ($triples as $triple) {
|
||
|
$this->deleteTripleDependencies($triple);
|
||
|
}
|
||
|
|
||
|
$resource->delete();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param TriplesCollection $triples
|
||
|
* @param array $propertyFilesystemMap
|
||
|
*
|
||
|
* @return array
|
||
|
* @throws common_Exception
|
||
|
*/
|
||
|
public function cloneTriples(TriplesCollection $triples, array $propertyFilesystemMap = [])
|
||
|
{
|
||
|
$clones = [];
|
||
|
foreach ($triples as $original) {
|
||
|
$triple = clone $original;
|
||
|
if ($this->isFileReference($triple)) {
|
||
|
$targetFileSystem = $propertyFilesystemMap[$triple->predicate] ?? null;
|
||
|
$this->serializeAsset($triple);
|
||
|
$triple->object = $this->cloneFile($triple->object, $targetFileSystem);
|
||
|
}
|
||
|
$clones[] = $triple;
|
||
|
}
|
||
|
|
||
|
return $clones;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param $fileUri
|
||
|
* @param null $targetFileSystemId
|
||
|
*
|
||
|
* @return string
|
||
|
* @throws \common_Exception
|
||
|
* @throws \tao_models_classes_FileNotFoundException
|
||
|
*/
|
||
|
protected function cloneFile($fileUri, $targetFileSystemId = null)
|
||
|
{
|
||
|
$referencer = $this->getFileRefSerializer();
|
||
|
$flySystemService = $this->getServiceLocator()->get(FileSystemService::SERVICE_ID);
|
||
|
|
||
|
$source = $referencer->unserialize($fileUri);
|
||
|
$targetFileSystemId = !$targetFileSystemId ? $source->getFileSystemId() : $targetFileSystemId;
|
||
|
$destinationPath = $flySystemService->getDirectory($targetFileSystemId)->getDirectory(uniqid('', true));
|
||
|
|
||
|
if ($source instanceof Directory) {
|
||
|
common_Logger::i('clone directory ' . $fileUri);
|
||
|
foreach ($source->getFlyIterator(Directory::ITERATOR_FILE | Directory::ITERATOR_RECURSIVE) as $file) {
|
||
|
$destinationPath->getFile($source->getRelPath($file))->write($file->readStream());
|
||
|
}
|
||
|
$destination = $destinationPath;
|
||
|
} elseif ($source instanceof File) {
|
||
|
common_Logger::i('clone file ' . $fileUri);
|
||
|
$destination = $destinationPath->getFile($source->getBasename());
|
||
|
$destination->write($source->readStream());
|
||
|
}
|
||
|
|
||
|
return $referencer->serialize($destination);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param TriplesCollection $triples
|
||
|
*
|
||
|
* @return array
|
||
|
*/
|
||
|
public function getPropertyStorageMap(TriplesCollection $triples)
|
||
|
{
|
||
|
$map = [];
|
||
|
|
||
|
foreach ($triples as $triple) {
|
||
|
if ($this->isFileReference($triple)) {
|
||
|
$this->serializeAsset($triple);
|
||
|
$source = $this->getFileRefSerializer()->unserialize($triple->object);
|
||
|
$map[$triple->predicate] = $source->getFileSystemId();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return $map;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param Triple $triple
|
||
|
*
|
||
|
* @return bool
|
||
|
*/
|
||
|
protected function isFileReference(Triple $triple)
|
||
|
{
|
||
|
$property = $this->getProperty($triple->predicate);
|
||
|
$range = $property->getRange();
|
||
|
|
||
|
$uri = $property->getUri();
|
||
|
|
||
|
if ($uri == MediaService::PROPERTY_LINK) {
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
if ($range === null) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
switch ($range->getUri()) {
|
||
|
case GenerisRdf::CLASS_GENERIS_FILE:
|
||
|
return true;
|
||
|
case OntologyRdfs::RDFS_RESOURCE:
|
||
|
$object = $this->getResource($triple->object);
|
||
|
return $object->hasType($this->getClass(GenerisRdf::CLASS_GENERIS_FILE));
|
||
|
default:
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private function serializeAsset(Triple $triple): void
|
||
|
{
|
||
|
$this->getFileSourceSerializer()->serialize($triple);
|
||
|
}
|
||
|
|
||
|
private function getFileSourceSerializer(): FileSourceSerializer
|
||
|
{
|
||
|
return $this->getServiceLocator()->get(FileSourceSerializer::class);
|
||
|
}
|
||
|
}
|