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(),
120 return $this->
append($resource, $result, $info_resolver, RevisionStatus::PUBLISHED);
126 bool $keep_original =
false,
129 $resource = $this->resource_repository->blank(
130 $this->primary_storage_handler->getIdentificationGenerator()->getUniqueResourceIdentification(),
138 RevisionStatus::PUBLISHED,
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(
204 RevisionStatus::PUBLISHED
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(
271 RevisionStatus::PUBLISHED,
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()];
484 if ($revision->getStatus() === RevisionStatus::PUBLISHED) {
487 $revision->setStatus(RevisionStatus::PUBLISHED);
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');
536 $this->stakeholder_repository->deregister($resource->
getIdentification(), $stakeholder);
537 $sucessful = $stakeholder->resourceHasBeenDeleted($resource->
getIdentification());
544 $sucessful = $s->resourceHasBeenDeleted($resource->
getIdentification()) && $sucessful;
548 $this->deleteRevision($resource, $revision);
551 $this->storage_handler_factory->getHandlerForResource($resource)->deleteResource($resource);
552 $this->resource_repository->delete($resource);
560 if ($reveision_to_delete !==
null) {
561 $this->deleteRevision($resource, $reveision_to_delete);
563 $this->store($resource);
569 string $path_inside_container,
571 $revision =
$container->getCurrentRevisionIncludingDraft();
572 $stream = $this->extractStream($revision);
576 $zip = new \ZipArchive();
577 $zip->open($stream->getMetadata()[
'uri']);
578 $path_inside_container = $this->ensurePathInZIP($zip, $path_inside_container,
false);
582 $this->storage_handler_factory->getHandlerForRevision($revision)->clearFlavours($revision);
583 $revision->getInformation()->setSize(filesize($stream->getMetadata()[
'uri']));
584 $this->storeRevision($revision);
587 }
catch (\Throwable) {
607 $root = array_shift(
$parts);
608 $root = $root ===
'' ? array_shift(
$parts) : $root;
611 if ($zip->locateName($root .
'/') !==
false) {
613 } elseif ($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 .
'/');
629 return rtrim((
string) $path_inside_container,
'/') .
'/' .
$filename;
634 string $path_inside_container,
636 $revision =
$container->getCurrentRevisionIncludingDraft();
637 $stream = $this->extractStream($revision);
641 $zip = new \ZipArchive();
642 $zip->open($stream->getMetadata()[
'uri']);
644 $return = $zip->deleteName($path_inside_container);
646 for ($i = 0; $i < $zip->numFiles; $i++) {
647 $path = $zip->getNameIndex($i);
648 if (
$path ===
false) {
651 if (str_starts_with(
$path, $path_inside_container)) {
652 $zip->deleteIndex($i);
659 $this->storage_handler_factory->getHandlerForRevision($revision)->clearFlavours($revision);
660 $revision->getInformation()->setSize(filesize($stream->getMetadata()[
'uri']));
661 $this->storeRevision($revision);
664 }
catch (\Throwable) {
665 $this->storage_handler_factory->getHandlerForRevision($revision)->clearFlavours($revision);
673 string $parent_path_inside_container,
675 $revision =
$container->getCurrentRevisionIncludingDraft();
676 $stream = $this->extractStream($revision);
680 $zip = new \ZipArchive();
681 $zip->open($stream->getMetadata()[
'uri']);
683 $parent_path_inside_container = $this->ensurePathInZIP($zip, $parent_path_inside_container,
false);
685 $path_inside_zip = rtrim($parent_path_inside_container,
'/') .
'/' . $result->
getName();
687 $return = $zip->addFile(
694 $this->storage_handler_factory->getHandlerForRevision($revision)->clearFlavours($revision);
695 $revision->getInformation()->setSize(filesize($stream->getMetadata()[
'uri']));
696 $this->storeRevision($revision);
699 }
catch (\Throwable) {
709 string $path_inside_container,
711 $revision =
$container->getCurrentRevisionIncludingDraft();
712 $revision_stream = $this->extractStream($revision);
715 $zip = new \ZipArchive();
716 $zip->open($revision_stream->getMetadata()[
'uri']);
718 $path_inside_container = $this->ensurePathInZIP($zip, $path_inside_container,
true);
720 $return = $zip->addFromString(
721 $path_inside_container,
727 $this->storage_handler_factory->getHandlerForRevision($revision)->clearFlavours($revision);
728 $revision->getInformation()->setSize(filesize($revision_stream->getMetadata()[
'uri']));
729 $this->storeRevision($revision);
732 }
catch (\Throwable) {
742 $this->storage_handler_factory->getHandlerForResource($resource)->deleteRevision($revision);
743 }
catch (\Throwable) {
746 $this->information_repository->delete($revision->
getInformation(), $revision);
747 $this->revision_repository->delete($revision);
753 $revisions = $this->revision_repository->get($resource);
756 foreach ($revisions->getAll(
true) as $i => $revision) {
757 $information = $this->information_repository->get($revision);
758 $revision->setInformation($information);
763 foreach ($this->stakeholder_repository->getStakeholders($resource->
getIdentification()) as $s) {
782 $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'))