Skip to content
Snippets Groups Projects
Commit ba7aae64 authored by Farbod Zamani's avatar Farbod Zamani Committed by Jan-Hendrik Willms
Browse files

CW: Mapping content after copying structural element

Closes #1153

Merge request studip/studip!1611
parent b19a47a2
No related branches found
No related tags found
No related merge requests found
...@@ -45,7 +45,7 @@ class ContainersCopy extends NonJsonApiController ...@@ -45,7 +45,7 @@ class ContainersCopy extends NonJsonApiController
private function copyContainer(\User $user, \Courseware\Container $remote_container, \Courseware\StructuralElement $element) private function copyContainer(\User $user, \Courseware\Container $remote_container, \Courseware\StructuralElement $element)
{ {
$container = $remote_container->copy($user, $element); list($container, $blockMapObjs) = $remote_container->copy($user, $element);
return $container; return $container;
} }
......
...@@ -104,9 +104,9 @@ class Container extends \SimpleORMap ...@@ -104,9 +104,9 @@ class Container extends \SimpleORMap
* @param User $user the owner and editor of the new copy of this block * @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 * @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([ $container = self::build([
'structural_element_id' => $element->id, 'structural_element_id' => $element->id,
...@@ -120,24 +120,26 @@ class Container extends \SimpleORMap ...@@ -120,24 +120,26 @@ class Container extends \SimpleORMap
$container->store(); $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(); $container->store();
return $container; return [$container, $blockMapObjs];
} }
private function copyBlocks(User $user, Container $newContainer): array private function copyBlocks(User $user, Container $newContainer): array
{ {
$blockMap = []; $blockMap = [];
$newBlockList = [];
foreach ($this->blocks as $block) { foreach ($this->blocks as $block) {
$newBlock = $block->copy($user, $newContainer); $newBlock = $block->copy($user, $newContainer);
$blockMap[$block->id] = $newBlock->id; $blockMap[$block->id] = $newBlock->id;
$newBlockList[$block->id] = $newBlock;
} }
return $blockMap; return [$blockMap, $newBlockList];
} }
} }
...@@ -809,16 +809,19 @@ SQL; ...@@ -809,16 +809,19 @@ SQL;
* *
* @param User $user this user will be the owner of the copy * @param User $user this user will be the owner of the copy
* @param StructuralElement $parent the target where to copy this instance * @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 * @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 = array_column($parent->findAncestors(), 'id');
$ancestorIds[] = $parent->id; $ancestorIds[] = $parent->id;
if (in_array($this->id, $ancestorIds)) { if (in_array($this->id, $ancestorIds)) {
throw new \InvalidArgumentException('Cannot copy into descendants.'); throw new \InvalidArgumentException('Cannot copy into descendants.');
} }
static $mapping = [];
$file_ref_id = $this->copyImage($user, $parent); $file_ref_id = $this->copyImage($user, $parent);
...@@ -840,9 +843,26 @@ SQL; ...@@ -840,9 +843,26 @@ SQL;
$element->store(); $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; return $element;
} }
...@@ -914,17 +934,22 @@ SQL; ...@@ -914,17 +934,22 @@ SQL;
return $this; 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) { 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) { foreach ($this->children as $child) {
$child->copy($user, $newElement, $purpose); $child->copy($user, $newElement, $purpose, $recursiveId);
} }
} }
...@@ -1046,4 +1071,23 @@ SQL; ...@@ -1046,4 +1071,23 @@ SQL;
return $this->parent->findParentTask(); 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();
}
}
}
}
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment