1<?php
2
3declare(strict_types=1);
4
5namespace JMS\Serializer\Ordering;
6
7final class CustomPropertyOrderingStrategy implements PropertyOrderingInterface
8{
9    /** @var int[] property => weight */
10    private $ordering;
11
12    /**
13     * @param int[] $ordering property => weight
14     */
15    public function __construct(array $ordering)
16    {
17        $this->ordering = $ordering;
18    }
19
20    /**
21     * {@inheritdoc}
22     */
23    public function order(array $properties): array
24    {
25        $currentSorting = $properties ? array_combine(array_keys($properties), range(1, \count($properties))) : [];
26
27        uksort($properties, function ($a, $b) use ($currentSorting) {
28            $existsA = isset($this->ordering[$a]);
29            $existsB = isset($this->ordering[$b]);
30
31            if (!$existsA && !$existsB) {
32                return $currentSorting[$a] - $currentSorting[$b];
33            }
34
35            if (!$existsA) {
36                return 1;
37            }
38
39            if (!$existsB) {
40                return -1;
41            }
42
43            return $this->ordering[$a] < $this->ordering[$b] ? -1 : 1;
44        });
45
46        return $properties;
47    }
48}
49