From c3d09fd6015a4041d191a62f4ce5f5011784a5e7 Mon Sep 17 00:00:00 2001 From: Johannes Meyer Date: Wed, 26 Jul 2023 17:04:50 +0200 Subject: [PATCH] Introduce `Icinga\Module\Businessprocess\Common\Sort` --- library/Businessprocess/Common/Sort.php | 154 ++++++++++++++++++++++++ 1 file changed, 154 insertions(+) create mode 100644 library/Businessprocess/Common/Sort.php diff --git a/library/Businessprocess/Common/Sort.php b/library/Businessprocess/Common/Sort.php new file mode 100644 index 0000000..3b0f6d4 --- /dev/null +++ b/library/Businessprocess/Common/Sort.php @@ -0,0 +1,154 @@ +sort; + } + + /** + * Set the sort specification + * + * @param string $sort + * + * @return $this + * + * @throws InvalidArgumentException When sorting according to the specified specification is not possible + */ + public function setSort(string $sort): self + { + list($sortBy, $direction) = Str::symmetricSplit($sort, ' ', 2, 'asc'); + + switch ($sortBy) { + case 'manual': + if ($direction === 'asc') { + $this->sortFn = function (array &$nodes) { + $firstNode = reset($nodes); + if ($firstNode instanceof BpNode && $firstNode->getDisplay() > 0) { + $nodes = self::applyManualSorting($nodes); + } + + // Child nodes don't need to be ordered in this case, their implicit order is significant + }; + } else { + $this->sortFn = function (array &$nodes) { + $firstNode = reset($nodes); + if ($firstNode instanceof BpNode && $firstNode->getDisplay() > 0) { + uasort($nodes, function (BpNode $a, BpNode $b) { + return $b->getDisplay() <=> $a->getDisplay(); + }); + } else { + $nodes = array_reverse($nodes); + } + }; + } + + break; + case 'display_name': + if ($direction === 'asc') { + $this->sortFn = function (array &$nodes) { + uasort($nodes, function (Node $a, Node $b) { + return strnatcasecmp( + $a->getAlias() ?? $a->getName(), + $b->getAlias() ?? $b->getName() + ); + }); + }; + } else { + $this->sortFn = function (array &$nodes) { + uasort($nodes, function (Node $a, Node $b) { + return strnatcasecmp( + $b->getAlias() ?? $b->getName(), + $a->getAlias() ?? $a->getName() + ); + }); + }; + } + + break; + case 'state': + if ($direction === 'asc') { + $this->sortFn = function (array &$nodes) { + uasort($nodes, function (Node $a, Node $b) { + return $a->getSortingState() <=> $b->getSortingState(); + }); + }; + } else { + $this->sortFn = function (array &$nodes) { + uasort($nodes, function (Node $a, Node $b) { + return $b->getSortingState() <=> $a->getSortingState(); + }); + }; + } + + break; + default: + throw new InvalidArgumentException(sprintf( + "Can't sort by %s. It's only possible to sort by manual order, display_name or state", + $sortBy + )); + } + + $this->sort = $sort; + + return $this; + } + + /** + * Sort the given nodes as specified by {@see setSort()} + * + * If {@see setSort()} has not been called yet, the default sort specification is used + * + * @param array $nodes + * + * @return array + */ + public function sort(array $nodes): array + { + if (empty($nodes)) { + return $nodes; + } + + if ($this->sortFn !== null) { + call_user_func_array($this->sortFn, [&$nodes]); + } + + return $nodes; + } + + /** + * Apply manual sort order on the given process nodes + * + * @param array $bpNodes + * + * @return array + */ + public static function applyManualSorting(array $bpNodes): array + { + uasort($bpNodes, function (BpNode $a, BpNode $b) { + return $a->getDisplay() <=> $b->getDisplay(); + }); + + return $bpNodes; + } +}