@@ -54,25 +54,70 @@ public function evaluate(array $data)
54
54
*/
55
55
private function sortItems ($ items )
56
56
{
57
- uasort (
58
- $ items ,
59
- function ($ firstItem , $ secondItem ) {
60
- $ firstValue = 0 ;
61
- $ secondValue = 0 ;
62
- if (isset ($ firstItem ['sortOrder ' ])) {
63
- $ firstValue = intval ($ firstItem ['sortOrder ' ]);
57
+ $ sortOrderDefined = $ this ->isSortOrderDefined ($ items );
58
+ if ($ sortOrderDefined ) {
59
+ $ indexedItems = [];
60
+ foreach ($ items as $ key => $ item ) {
61
+ $ indexedItems [] = ['key ' => $ key , 'item ' => $ item ];
62
+ }
63
+ uksort (
64
+ $ indexedItems ,
65
+ function ($ firstItemKey , $ secondItemKey ) use ($ indexedItems ) {
66
+ return $ this ->compareItems ($ firstItemKey , $ secondItemKey , $ indexedItems );
64
67
}
68
+ );
69
+ // Convert array of sorted items back to initial format
70
+ $ items = [];
71
+ foreach ($ indexedItems as $ indexedItem ) {
72
+ $ items [$ indexedItem ['key ' ]] = $ indexedItem ['item ' ];
73
+ }
74
+ }
75
+ return $ items ;
76
+ }
65
77
66
- if (isset ($ secondItem ['sortOrder ' ])) {
67
- $ secondValue = intval ($ secondItem ['sortOrder ' ]);
68
- }
78
+ /**
79
+ * Compare sortOrder of item
80
+ *
81
+ * @param mixed $firstItemKey
82
+ * @param mixed $secondItemKey
83
+ * @param array $indexedItems
84
+ * @return int
85
+ */
86
+ private function compareItems ($ firstItemKey , $ secondItemKey , $ indexedItems )
87
+ {
88
+ $ firstItem = $ indexedItems [$ firstItemKey ]['item ' ];
89
+ $ secondItem = $ indexedItems [$ secondItemKey ]['item ' ];
90
+ $ firstValue = 0 ;
91
+ $ secondValue = 0 ;
92
+ if (isset ($ firstItem ['sortOrder ' ])) {
93
+ $ firstValue = intval ($ firstItem ['sortOrder ' ]);
94
+ }
69
95
70
- if ($ firstValue == $ secondValue ) {
71
- return 0 ;
72
- }
73
- return $ firstValue < $ secondValue ? -1 : 1 ;
96
+ if (isset ($ secondItem ['sortOrder ' ])) {
97
+ $ secondValue = intval ($ secondItem ['sortOrder ' ]);
98
+ }
99
+
100
+ if ($ firstValue == $ secondValue ) {
101
+ // These keys reflect initial relative position of items.
102
+ // Allows stable sort for items with equal 'sortOrder'
103
+ return $ firstItemKey < $ secondItemKey ? -1 : 1 ;
104
+ }
105
+ return $ firstValue < $ secondValue ? -1 : 1 ;
106
+ }
107
+
108
+ /**
109
+ * Determine if a sort order exists for any of the items.
110
+ *
111
+ * @param array $items
112
+ * @return bool
113
+ */
114
+ private function isSortOrderDefined ($ items )
115
+ {
116
+ foreach ($ items as $ itemData ) {
117
+ if (isset ($ itemData ['sortOrder ' ])) {
118
+ return true ;
74
119
}
75
- );
76
- return $ items ;
120
+ }
121
+ return false ;
77
122
}
78
123
}
0 commit comments