1*78a26510SAndreas Gohr<?php 2*78a26510SAndreas Gohr 3*78a26510SAndreas Gohrnamespace dokuwiki\TreeBuilder; 4*78a26510SAndreas Gohr 5*78a26510SAndreas Gohruse dokuwiki\TreeBuilder\Node\AbstractNode; 6*78a26510SAndreas Gohruse dokuwiki\TreeBuilder\Node\WikiNamespace; 7*78a26510SAndreas Gohruse dokuwiki\Utf8\Sort; 8*78a26510SAndreas Gohr 9*78a26510SAndreas Gohr/** 10*78a26510SAndreas Gohr * Class that provides comparators for sorting the tree nodes 11*78a26510SAndreas Gohr */ 12*78a26510SAndreas Gohrclass TreeSort 13*78a26510SAndreas Gohr{ 14*78a26510SAndreas Gohr public const SORT_BY_ID = [self::class, 'sortById']; 15*78a26510SAndreas Gohr public const SORT_BY_TITLE = [self::class, 'sortByTitle']; 16*78a26510SAndreas Gohr public const SORT_BY_NS_FIRST_THEN_ID = [self::class, 'sortByNsFirstThenId']; 17*78a26510SAndreas Gohr public const SORT_BY_NS_FIRST_THEN_TITLE = [self::class, 'sortByNsFirstThenTitle']; 18*78a26510SAndreas Gohr 19*78a26510SAndreas Gohr /** 20*78a26510SAndreas Gohr * Comparator to sort by ID 21*78a26510SAndreas Gohr * 22*78a26510SAndreas Gohr * @param AbstractNode $a 23*78a26510SAndreas Gohr * @param AbstractNode $b 24*78a26510SAndreas Gohr * @return int 25*78a26510SAndreas Gohr */ 26*78a26510SAndreas Gohr public static function sortById(AbstractNode $a, AbstractNode $b): int 27*78a26510SAndreas Gohr { 28*78a26510SAndreas Gohr // we need to compare the ID segment by segment 29*78a26510SAndreas Gohr $pathA = explode(':', $a->getId()); 30*78a26510SAndreas Gohr $pathB = explode(':', $b->getId()); 31*78a26510SAndreas Gohr $min = min(count($pathA), count($pathB)); 32*78a26510SAndreas Gohr 33*78a26510SAndreas Gohr for ($i = 0; $i < $min; $i++) { 34*78a26510SAndreas Gohr if ($pathA[$i] !== $pathB[$i]) { 35*78a26510SAndreas Gohr return $pathA[$i] <=> $pathB[$i]; 36*78a26510SAndreas Gohr } 37*78a26510SAndreas Gohr } 38*78a26510SAndreas Gohr return count($pathA) <=> count($pathB); 39*78a26510SAndreas Gohr } 40*78a26510SAndreas Gohr 41*78a26510SAndreas Gohr 42*78a26510SAndreas Gohr /** 43*78a26510SAndreas Gohr * Comparator to sort namespace first, then by ID 44*78a26510SAndreas Gohr * 45*78a26510SAndreas Gohr * @param AbstractNode $a 46*78a26510SAndreas Gohr * @param AbstractNode $b 47*78a26510SAndreas Gohr * @return int 48*78a26510SAndreas Gohr */ 49*78a26510SAndreas Gohr public static function sortByNsFirstThenId(AbstractNode $a, AbstractNode $b): int 50*78a26510SAndreas Gohr { 51*78a26510SAndreas Gohr $res = self::sortByNsFirst($a, $b); 52*78a26510SAndreas Gohr if ($res === 0) $res = self::sortById($a, $b); 53*78a26510SAndreas Gohr return $res; 54*78a26510SAndreas Gohr } 55*78a26510SAndreas Gohr 56*78a26510SAndreas Gohr /** 57*78a26510SAndreas Gohr * Comparator to sort by title (using natural sort) 58*78a26510SAndreas Gohr * 59*78a26510SAndreas Gohr * @param AbstractNode $a 60*78a26510SAndreas Gohr * @param AbstractNode $b 61*78a26510SAndreas Gohr * @return int 62*78a26510SAndreas Gohr */ 63*78a26510SAndreas Gohr public static function sortByTitle(AbstractNode $a, AbstractNode $b): int 64*78a26510SAndreas Gohr { 65*78a26510SAndreas Gohr return Sort::strcmp($a->getTitle(), $b->getTitle()); 66*78a26510SAndreas Gohr } 67*78a26510SAndreas Gohr 68*78a26510SAndreas Gohr /** 69*78a26510SAndreas Gohr * Comparator to sort namespace first, then by title 70*78a26510SAndreas Gohr * 71*78a26510SAndreas Gohr * @param AbstractNode $a 72*78a26510SAndreas Gohr * @param AbstractNode $b 73*78a26510SAndreas Gohr * @return int 74*78a26510SAndreas Gohr */ 75*78a26510SAndreas Gohr public static function sortByNsFirstThenTitle(AbstractNode $a, AbstractNode $b): int 76*78a26510SAndreas Gohr { 77*78a26510SAndreas Gohr $res = self::sortByNsFirst($a, $b); 78*78a26510SAndreas Gohr if ($res === 0) $res = self::sortByTitle($a, $b); 79*78a26510SAndreas Gohr return $res; 80*78a26510SAndreas Gohr } 81*78a26510SAndreas Gohr 82*78a26510SAndreas Gohr /** 83*78a26510SAndreas Gohr * Comparator to sort by namespace first 84*78a26510SAndreas Gohr * 85*78a26510SAndreas Gohr * @param AbstractNode $a 86*78a26510SAndreas Gohr * @param AbstractNode $b 87*78a26510SAndreas Gohr * @return int 88*78a26510SAndreas Gohr */ 89*78a26510SAndreas Gohr protected static function sortByNsFirst(AbstractNode $a, AbstractNode $b): int 90*78a26510SAndreas Gohr { 91*78a26510SAndreas Gohr $isAaNs = ($a instanceof WikiNamespace); 92*78a26510SAndreas Gohr $isBaNs = ($b instanceof WikiNamespace); 93*78a26510SAndreas Gohr 94*78a26510SAndreas Gohr if ($isAaNs !== $isBaNs) { 95*78a26510SAndreas Gohr if ($isAaNs) { 96*78a26510SAndreas Gohr return -1; 97*78a26510SAndreas Gohr } elseif ($isBaNs) { 98*78a26510SAndreas Gohr return 1; 99*78a26510SAndreas Gohr } 100*78a26510SAndreas Gohr } 101*78a26510SAndreas Gohr return 0; 102*78a26510SAndreas Gohr } 103*78a26510SAndreas Gohr} 104