/** * Callback function for comparing sequence blocks. * The applied criterion for comparison is the </pre>"orderInSequence</pre> property. * * @param CurriculumInventorySequenceBlockInterface $a * @param CurriculumInventorySequenceBlockInterface $b * @return int One of -1, 0, 1. */ public static function compareSequenceBlocksWithOrderedStrategy(CurriculumInventorySequenceBlockInterface $a, CurriculumInventorySequenceBlockInterface $b) { if ($a->getOrderInSequence() === $b->getOrderInSequence()) { return 0; } return $a->getOrderInSequence() > $b->getOrderInSequence() ? 1 : -1; }
/** * Recursively copies nested sequence blocks for rollover. * * @param CurriculumInventorySequenceBlockInterface $block The block to copy. * @param CurriculumInventoryReportInterface $newReport The new report to roll over into. * @param CurriculumInventoryAcademicLevelInterface[] $newLevels A map of new academic levels, indexed by level. * @param CurriculumInventorySequenceBlockInterface|null $newParent The new parent block for this copy. */ protected function rolloverSequenceBlock(CurriculumInventorySequenceBlockInterface $block, CurriculumInventoryReportInterface $newReport, array $newLevels, CurriculumInventorySequenceBlockInterface $newParent = null) { /* @var CurriculumInventorySequenceBlockInterface $newBlock */ $newBlock = $this->sequenceBlockManager->create(); $newBlock->setReport($newReport); $newBlock->setAcademicLevel($newLevels[$block->getAcademicLevel()->getLevel()]); $newBlock->setDescription($block->getDescription()); $newBlock->setEndDate($block->getEndDate()); $newBlock->setStartDate($block->getStartDate()); $newBlock->setChildSequenceOrder($block->getChildSequenceOrder()); $newBlock->setDuration($block->getDuration()); $newBlock->setTitle($block->getTitle()); $newBlock->setOrderInSequence($block->getOrderInSequence()); $newBlock->setMinimum($block->getMinimum()); $newBlock->setMaximum($block->getMaximum()); $newBlock->setTrack($block->hasTrack()); $newBlock->setRequired($block->getRequired()); if ($newParent) { $newBlock->setParent($newParent); $newParent->addChild($newBlock); } $newReport->addSequenceBlock($newBlock); $this->sequenceBlockManager->update($newBlock, false, false); foreach ($block->getChildren() as $child) { $this->rolloverSequenceBlock($child, $newReport, $newLevels, $newBlock); } }
/** * Reorder the entire sequence if on of the blocks changes position. * @param int $oldValue * @param CurriculumInventorySequenceBlockInterface $block * @param ManagerInterface $manager * @throws \OutOfRangeException */ protected function reorderBlocksInSequenceOnOrderChange($oldValue, CurriculumInventorySequenceBlockInterface $block, ManagerInterface $manager) { $parent = $block->getParent(); if (!$parent) { return; } if ($parent->getChildSequenceOrder() !== CurriculumInventorySequenceBlockInterface::ORDERED) { return; } $newValue = $block->getOrderInSequence(); $blocks = $parent->getChildrenAsSortedList(); $blocks = array_filter($blocks, function ($sibling) use($block) { return $sibling->getId() !== $block->getId(); }); $blocks = array_values($blocks); $minRange = 1; $maxRange = count($blocks) + 1; if ($newValue < $minRange || $newValue > $maxRange) { throw new \OutOfRangeException("The given order-in-sequence value {$newValue} falls outside the range {$minRange} - {$maxRange}."); } if ($oldValue === $newValue) { return; } array_splice($blocks, $block->getOrderInSequence() - 1, 0, [$block]); for ($i = 0, $n = count($blocks); $i < $n; $i++) { /* @var CurriculumInventorySequenceBlockInterface $current */ $current = $blocks[$i]; $j = $i + 1; if ($current->getId() !== $block && $current->getOrderInSequence() !== $j) { $current->setOrderInSequence($j); $manager->update($current, false, false); } } }