diff options
| author | Farbod Zamani <zamani@elan-ev.de> | 2023-04-27 07:09:19 +0000 |
|---|---|---|
| committer | Jan-Hendrik Willms <tleilax+studip@gmail.com> | 2023-04-27 07:09:19 +0000 |
| commit | ba7aae6445affd96fdaddcf7799096524dc000f2 (patch) | |
| tree | 964b2af9aef67e8623d58b7f678c8372ebd9834c /lib/models | |
| parent | b19a47a2a198145154cb38494c779015351274cf (diff) | |
CW: Mapping content after copying structural element
Closes #1153
Merge request studip/studip!1611
Diffstat (limited to 'lib/models')
| -rw-r--r-- | lib/models/Courseware/Container.php | 14 | ||||
| -rw-r--r-- | lib/models/Courseware/StructuralElement.php | 58 |
2 files changed, 59 insertions, 13 deletions
diff --git a/lib/models/Courseware/Container.php b/lib/models/Courseware/Container.php index 1f621e5..088f539 100644 --- a/lib/models/Courseware/Container.php +++ b/lib/models/Courseware/Container.php @@ -104,9 +104,9 @@ class Container extends \SimpleORMap * @param User $user the owner and editor of the new copy of this block * @param StructuralElement $element the structural element this block will be copied into * - * @return Container the copy of this Container + * @return array an array containing the container object and the block maps */ - public function copy(User $user, StructuralElement $element): Container + public function copy(User $user, StructuralElement $element): array { $container = self::build([ 'structural_element_id' => $element->id, @@ -120,24 +120,26 @@ class Container extends \SimpleORMap $container->store(); - $blockMap = $this->copyBlocks($user, $container); + list($blockMapIds, $blockMapObjs) = $this->copyBlocks($user, $container); - $container['payload'] = $container->type->copyPayload($blockMap); + $container['payload'] = $container->type->copyPayload($blockMapIds); $container->store(); - return $container; + return [$container, $blockMapObjs]; } private function copyBlocks(User $user, Container $newContainer): array { $blockMap = []; + $newBlockList = []; foreach ($this->blocks as $block) { $newBlock = $block->copy($user, $newContainer); $blockMap[$block->id] = $newBlock->id; + $newBlockList[$block->id] = $newBlock; } - return $blockMap; + return [$blockMap, $newBlockList]; } } diff --git a/lib/models/Courseware/StructuralElement.php b/lib/models/Courseware/StructuralElement.php index ca5a7b7..3cfca28 100644 --- a/lib/models/Courseware/StructuralElement.php +++ b/lib/models/Courseware/StructuralElement.php @@ -809,16 +809,19 @@ SQL; * * @param User $user this user will be the owner of the copy * @param StructuralElement $parent the target where to copy this instance + * @param string $purpose the purpose of copying this instance + * @param string $recursiveId the optional mapping id for copying child structural elements upon recursive call to this function * * @return StructuralElement the copy of this instance */ - public function copy(User $user, StructuralElement $parent, string $purpose = ''): StructuralElement + public function copy(User $user, StructuralElement $parent, string $purpose = '', string $recursiveId = ''): StructuralElement { $ancestorIds = array_column($parent->findAncestors(), 'id'); $ancestorIds[] = $parent->id; if (in_array($this->id, $ancestorIds)) { throw new \InvalidArgumentException('Cannot copy into descendants.'); } + static $mapping = []; $file_ref_id = $this->copyImage($user, $parent); @@ -840,9 +843,26 @@ SQL; $element->store(); - $this->copyContainers($user, $element); + list($containerMap, $blockMap) = $this->copyContainers($user, $element); - $this->copyChildren($user, $element, $purpose); + $mappingId = $recursiveId === '' ? $this->id . '_' . $element->id : $recursiveId; + if (!isset($mapping[$mappingId])) { + $mapping[$mappingId] = [ + 'elements' => [], + 'containers' => [], + 'blocks' => [], + ]; + } + $mapping[$mappingId]['elements'][$this->id] = $element->id; + $mapping[$mappingId]['containers'] = $mapping[$mappingId]['containers'] + $containerMap; + $mapping[$mappingId]['blocks'] = $mapping[$mappingId]['blocks'] + $blockMap; + + $this->copyChildren($user, $element, $purpose, $mappingId); + + if ($recursiveId === '') { + $this->performMapping($mapping[$mappingId]); + unset($mapping[$mappingId]); + } return $element; } @@ -914,17 +934,22 @@ SQL; return $this; } - private function copyContainers(User $user, StructuralElement $newElement): void + private function copyContainers(User $user, StructuralElement $newElement): array { + $containerMap = []; + $blockMap = []; foreach ($this->containers as $container) { - $container->copy($user, $newElement); + list($newContainer, $blockMapsObjs) = $container->copy($user, $newElement); + $containerMap[$container->id] = $newContainer->id; + $blockMap = $blockMap + $blockMapsObjs; } + return [$containerMap, $blockMap]; } - private function copyChildren(User $user, StructuralElement $newElement, string $purpose = ''): void + private function copyChildren(User $user, StructuralElement $newElement, string $purpose = '', string $recursiveId = ''): void { foreach ($this->children as $child) { - $child->copy($user, $newElement, $purpose); + $child->copy($user, $newElement, $purpose, $recursiveId); } } @@ -1046,4 +1071,23 @@ SQL; return $this->parent->findParentTask(); } + + private function performMapping($mapping) + { + // Blocks mapping. + foreach ($mapping['blocks'] as $oldBlockId => $newBlockObj) { + if ($newBlockObj->type->getType() === \Courseware\BlockTypes\Link::getType()) { + $payload = $newBlockObj->type->getPayload(); + if ($payload['type'] === 'internal' && '' != $payload['target']) { + if (in_array($payload['target'], array_keys($mapping['elements']))) { + $payload['target'] = $mapping['elements'][intval($payload['target'])]; + } else { + $payload['target'] = ''; + } + $newBlockObj->type->setPayload($payload); + $newBlockObj->store(); + } + } + } + } } |
