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
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;
}
......
......@@ -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];
}
}
......@@ -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();
}
}
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment