19declare(strict_types=1);
37use ILIAS\ResourceStorage\Preloader\SecureString;
96 $this->primary_storage_handler = $this->storage_handler_factory->getPrimary();
115 $resource = $this->resource_repository->blank(
116 $this->primary_storage_handler->getIdentificationGenerator()->getUniqueResourceIdentification(),
126 bool $keep_original =
false,
129 $resource = $this->resource_repository->blank(
130 $this->primary_storage_handler->getIdentificationGenerator()->getUniqueResourceIdentification(),
145 $resource = $this->resource_repository->blank(
146 $this->primary_storage_handler->getIdentificationGenerator()->getUniqueResourceIdentification(),
149 $resource->
setStorageID($this->primary_storage_handler->getID());
167 throw new \LogicException(
168 'You can not replace a draft revision with a published, you must publish the current revision first'
172 $new_revision = $this->revision_repository->blankFromUpload($info_resolver, $resource, $result, $status);
175 $clone_revision = $this->buildDraftReplacementRevision($resource, $new_revision, $info_resolver);
176 $resource->replaceRevision($clone_revision);
178 $new_revision = $this->populateRevisionInfo($new_revision, $info_resolver);
179 $resource->addRevision($new_revision);
182 $resource->setStorageID(
183 $resource->getStorageID() ===
'' ? $this->primary_storage_handler->getID() : $resource->getStorageID()
198 throw new \LogicException(
'You can not replace a draft revision, you must publish it first');
200 $revision = $this->revision_repository->blankFromUpload(
206 $revision = $this->populateRevisionInfo($revision, $info_resolver);
208 foreach ($resource->getAllRevisionsIncludingDraft() as $existing_revision) {
209 $this->deleteRevision($resource, $existing_revision);
212 $resource->addRevision($revision);
213 $resource->setStorageID(
214 $resource->getStorageID() ===
'' ? $this->primary_storage_handler->getID() : $resource->getStorageID()
225 bool $keep_original =
false,
230 throw new \LogicException(
231 'You can not replace a draft revision with a published, you must publish the current revision first'
235 $new_revision = $this->revision_repository->blankFromStream(
244 $clone_revision = $this->buildDraftReplacementRevision($resource, $new_revision, $info_resolver);
245 $resource->replaceRevision($clone_revision);
247 $new_revision = $this->populateRevisionInfo($new_revision, $info_resolver);
248 $resource->addRevision($new_revision);
251 $resource->setStorageID(
252 $resource->getStorageID() ===
'' ? $this->primary_storage_handler->getID() : $resource->getStorageID()
262 bool $keep_original =
false,
265 throw new \LogicException(
'You can not replace a draft revision, you must publish it first');
267 $revision = $this->revision_repository->blankFromStream(
274 $revision = $this->populateRevisionInfo($revision, $info_resolver);
276 foreach ($resource->getAllRevisionsIncludingDraft() as $existing_revision) {
277 $this->deleteRevision($resource, $existing_revision);
280 $resource->addRevision($revision);
281 $resource->setStorageID(
282 $resource->getStorageID() ===
'' ? $this->primary_storage_handler->getID() : $resource->getStorageID()
293 throw new \LogicException(
'You can not replace a draft revision, you must publish it first');
295 $existing_revision = $resource->getSpecificRevision($revision_number);
298 $resource->getMaxRevision(
false) + 1,
302 $cloned_revision = $this->revision_repository->blankFromClone(
308 $this->populateRevisionInfo($cloned_revision, $info_resolver);
310 $resource->addRevision($cloned_revision);
311 $resource->setStorageID(
312 $resource->getStorageID() ===
'' ? $this->primary_storage_handler->getID() : $resource->getStorageID()
324 $current_revision = $resource->getCurrentRevisionIncludingDraft();
327 $this->extractStream($new_revision)
329 $stream_replacement = $this->populateRevisionInfo($stream_replacement, $info_resolver);
330 $stream_replacement->setVersionNumber($current_revision->getVersionNumber());
333 return $stream_replacement;
341 return $this->resource_repository->has($identification);
351 $this->file_name_policy->check($revision->getInformation()->getSuffix());
354 $r = $this->lock_handler->lockTables(
356 $this->resource_repository->getNamesForLocking(),
357 $this->revision_repository->getNamesForLocking(),
358 $this->information_repository->getNamesForLocking(),
359 $this->stakeholder_repository->getNamesForLocking()
361 function () use ($resource):
void {
362 $this->resource_repository->store($resource);
365 $this->storeRevision($revision, $resource);
369 $this->stakeholder_repository->register($resource->getIdentification(), $stakeholder);
382 $new_resource = $this->newBlank($resource->
getType());
384 $stakeholder = clone $stakeholder;
385 $new_resource->addStakeholder($stakeholder);
393 $existing_revision->getVersionNumber(),
397 $existing_revision = $this->stream_access->populateRevision($existing_revision);
400 $new_resource->getIdentification(),
401 $existing_revision->maybeStreamResolver()->getStream(),
405 $this->populateRevisionInfo($cloned_revision, $info_resolver);
406 $cloned_revision->setVersionNumber($existing_revision->getVersionNumber());
408 $new_resource->addRevision($cloned_revision);
410 $this->store($new_resource);
411 return $new_resource;
421 ? $this->primary_storage_handler
422 : $this->storage_handler_factory->getHandlerForRevision($revision);
426 $this->file_name_policy->check($revision->
getInformation()->getSuffix());
427 $storage_handler->storeUpload($revision);
430 $storage_handler->storeStream($revision);
433 $storage_handler->cloneRevision($revision);
436 $storage_handler->streamReplacement($revision);
438 $this->revision_repository->store($revision);
439 $this->information_repository->store($revision->
getInformation(), $revision);
442 if ($resource !==
null) {
445 $replace_revision->setOwnerId($revision->
getOwnerId());
446 $replace_revision->setTitle($revision->
getTitle());
447 $replace_revision->setStatus($revision->
getStatus());
449 $replace_revision->setStorageID($revision->
getStorageID());
461 if (isset($this->resource_cache[$identification->serialize()])) {
462 return $this->resource_cache[$identification->serialize()];
464 $resource = $this->resource_repository->get($identification);
466 if ($this->auto_migrate && $resource->
getStorageID() !== $this->primary_storage_handler->getID()) {
470 $migrator->migrate($resource, $this->primary_storage_handler->getID());
471 $resource->
setStorageID($this->primary_storage_handler->getID());
474 $this->resource_cache[$identification->serialize()] = $this->populateNakedResourceWithRevisionsAndStakeholders(
478 return $this->resource_cache[$identification->serialize()];
488 $this->store($resource);
499 $this->store($resource);
507 return Streams::ofReattachableResource($revision->getStream()->detach());
509 return Streams::ofReattachableResource(fopen($revision->getUpload()->getPath(),
'rb'));
511 return $revision->getRevisionToClone()->getStream();
514 return $this->storage_handler_factory->getHandlerForRevision(
516 )->getStream($revision);
519 return $this->storage_handler_factory->getHandlerForResource(
521 )->getStream($revision);
523 throw new \LogicException(
'This revision type is not supported');
535 $this->stakeholder_repository->deregister($resource->
getIdentification(), $stakeholder);
536 $sucessful = $stakeholder->resourceHasBeenDeleted($resource->
getIdentification());
543 $sucessful = $s->resourceHasBeenDeleted($resource->
getIdentification()) && $sucessful;
547 $this->deleteRevision($resource, $revision);
550 $this->storage_handler_factory->getHandlerForResource($resource)->deleteResource($resource);
551 $this->resource_repository->delete($resource);
559 if ($reveision_to_delete !==
null) {
560 $this->deleteRevision($resource, $reveision_to_delete);
562 $this->store($resource);
568 string $path_inside_container,
570 $revision =
$container->getCurrentRevisionIncludingDraft();
571 $stream = $this->extractStream($revision);
575 $zip = new \ZipArchive();
576 $zip->open($stream->getMetadata()[
'uri']);
577 $path_inside_container = $this->ensurePathInZIP($zip, $path_inside_container,
false);
581 $this->storage_handler_factory->getHandlerForRevision($revision)->clearFlavours($revision);
582 $revision->getInformation()->setSize(filesize($stream->getMetadata()[
'uri']));
583 $this->storeRevision($revision);
586 }
catch (\Throwable) {
605 if (in_array(
$path, [
'.',
'/',
''],
true)) {
611 $root = array_shift(
$parts);
615 if ($zip->locateName($root .
'/') ===
false
616 && $zip->locateName(
'/' . $root .
'/') ===
false
618 $zip->addEmptyDir($root);
621 $path_inside_container = $root;
622 foreach (
$parts as $part) {
623 $path_inside_container .=
'/' . $part;
624 if ($zip->locateName($path_inside_container .
'/') ===
false) {
625 $zip->addEmptyDir($path_inside_container .
'/');
630 return $path_inside_container .
'/';
633 return $path_inside_container .
'/' .
$filename;
638 string $path_inside_container,
640 $revision =
$container->getCurrentRevisionIncludingDraft();
641 $stream = $this->extractStream($revision);
645 $zip = new \ZipArchive();
646 $zip->open($stream->getMetadata()[
'uri']);
648 $return = $zip->deleteName($path_inside_container);
650 for ($i = 0; $i < $zip->numFiles; $i++) {
651 $path = $zip->getNameIndex($i);
652 if (
$path ===
false) {
655 if (str_starts_with(
$path, $path_inside_container)) {
656 $zip->deleteIndex($i);
663 $this->storage_handler_factory->getHandlerForRevision($revision)->clearFlavours($revision);
664 $revision->getInformation()->setSize(filesize($stream->getMetadata()[
'uri']));
665 $this->storeRevision($revision);
668 }
catch (\Throwable) {
669 $this->storage_handler_factory->getHandlerForRevision($revision)->clearFlavours($revision);
677 string $parent_path_inside_container,
679 $revision =
$container->getCurrentRevisionIncludingDraft();
680 $stream = $this->extractStream($revision);
684 $zip = new \ZipArchive();
685 $zip->open($stream->getMetadata()[
'uri']);
687 $parent_path_inside_container = $this->ensurePathInZIP($zip, $parent_path_inside_container,
false);
689 $path_inside_zip = rtrim($parent_path_inside_container,
'/') .
'/' . $result->
getName();
691 $return = $zip->addFile(
698 $this->storage_handler_factory->getHandlerForRevision($revision)->clearFlavours($revision);
699 $revision->getInformation()->setSize(filesize($stream->getMetadata()[
'uri']));
700 $this->storeRevision($revision);
703 }
catch (\Throwable) {
713 string $path_inside_container,
715 $revision =
$container->getCurrentRevisionIncludingDraft();
716 $revision_stream = $this->extractStream($revision);
719 $zip = new \ZipArchive();
720 $zip->open($revision_stream->getMetadata()[
'uri']);
722 $path_inside_container = $this->ensurePathInZIP($zip, $path_inside_container,
true);
724 $return = $zip->addFromString(
725 $path_inside_container,
731 $this->storage_handler_factory->getHandlerForRevision($revision)->clearFlavours($revision);
732 $revision->getInformation()->setSize(filesize($revision_stream->getMetadata()[
'uri']));
733 $this->storeRevision($revision);
736 }
catch (\Throwable) {
746 $this->storage_handler_factory->getHandlerForResource($resource)->deleteRevision($revision);
747 }
catch (\Throwable) {
750 $this->information_repository->delete($revision->
getInformation(), $revision);
751 $this->revision_repository->delete($revision);
757 $revisions = $this->revision_repository->get($resource);
760 foreach ($revisions->getAll(
true) as $revision) {
761 $information = $this->information_repository->get($revision);
762 $revision->setInformation($information);
767 foreach ($this->stakeholder_repository->getStakeholders($resource->
getIdentification()) as $s) {
786 $revision->setOwnerId($info_resolver->
getOwnerId());
Stream factory which enables the user to create streams without the knowledge of the concrete class.
Class ResourceIdentification.
Class FileNamePolicyException.
Class NoneFileNamePolicy.
getStakeholderRepository()
getInformationRepository()
ensurePathInZIP(\ZipArchive $zip, string $path, bool $is_file)
StakeholderRepository $stakeholder_repository
@readonly
newFromStream(FileStream $stream, InfoResolver $info_resolver, bool $keep_original=false, ResourceType $type=ResourceType::SINGLE_FILE)
newBlank(ResourceType $type=ResourceType::SINGLE_FILE)
appendFromStream(StorableResource $resource, FileStream $stream, InfoResolver $info_resolver, RevisionStatus $status, bool $keep_original=false,)
addUploadToContainer(StorableContainerResource $container, UploadResult $result, string $parent_path_inside_container,)
replaceWithStream(StorableResource $resource, FileStream $stream, InfoResolver $info_resolver, bool $keep_original=false,)
unpublish(StorableResource $resource)
populateRevisionInfo(Revision $revision, InfoResolver $info_resolver)
addStreamToContainer(StorableContainerResource $container, FileStream $stream, string $path_inside_container,)
ResourceRepository $resource_repository
@readonly
appendFromRevision(StorableResource $resource, int $revision_number)
extractStream(Revision $revision)
publish(StorableResource $resource)
populateNakedResourceWithRevisionsAndStakeholders(StorableResource $resource)
RevisionRepository $revision_repository
@readonly
storeRevision(Revision $revision, ?StorableResource $resource=null)
@description Store one Revision
__construct(private StorageHandlerFactory $storage_handler_factory, Repositories $repositories, private LockHandler $lock_handler, private StreamAccess $stream_access, protected FileNamePolicy $file_name_policy=new NoneFileNamePolicy())
ResourceBuilder constructor.
createDirectoryInsideContainer(StorableContainerResource $container, string $path_inside_container,)
store(StorableResource $resource)
@description after you have modified a resource, you can store it here
removePathInsideContainer(StorableContainerResource $container, string $path_inside_container,)
has(ResourceIdentification $identification)
@description check if a resource exists
deleteRevision(StorableResource $resource, Revision $revision)
replaceWithUpload(StorableResource $resource, UploadResult $result, InfoResolver $info_resolver)
@inheritDoc
removeRevision(StorableResource $resource, int $revision_number)
append(StorableResource $resource, UploadResult $result, InfoResolver $info_resolver, RevisionStatus $status)
StorageHandler $primary_storage_handler
buildDraftReplacementRevision(StorableResource $resource, Revision $new_revision, InfoResolver $info_resolver)
InformationRepository $information_repository
@readonly
clone(StorableResource $resource)
@description Clone anexisting resource with all it's revisions, stakeholders and information
Class UploadedFileRevision.
Class UploadedFileRevision.
Class StorageHandlerFactory.
The base interface for all filesystem streams.
Interface FileNamePolicy.
Interface ResourceRepository.
Interface StorageResource.
setRevisions(RevisionCollection $collection)
addStakeholder(ResourceStakeholder $s)
replaceRevision(Revision $revision)
removeRevision(Revision $revision)
removeStakeholder(ResourceStakeholder $s)
getCurrentRevisionIncludingDraft()
setStorageID(string $storage_id)
getSpecificRevision(int $number)
getAllRevisionsIncludingDraft()
Class RevisionARRepository.
setInformation(Information $information)
Interface StakeholderRepository.
Interface ResourceStakeholder.
Class FileResourceHandler.
if($clientAssertionType !='urn:ietf:params:oauth:client-assertion-type:jwt-bearer'|| $grantType !='client_credentials') $parts
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
if(!file_exists('../ilias.ini.php'))