Objects   A
last analyzed

Complexity

Total Complexity 16

Size/Duplication

Total Lines 96
Duplicated Lines 0 %

Test Coverage

Coverage 96.88%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 16
eloc 38
c 1
b 0
f 0
dl 0
loc 96
ccs 31
cts 32
cp 0.9688
rs 10

1 Method

Rating   Name   Duplication   Size   Complexity  
C compare() 0 54 16
1
<?php
2
3
/**
4
 * PHP: Nelson Martell Library file
5
 *
6
 * Copyright © 2021 Nelson Martell (http://nelson6e65.github.io)
7
 *
8
 * Licensed under The MIT License (MIT)
9
 * For full copyright and license information, please see the LICENSE
10
 * Redistributions of files must retain the above copyright notice.
11
 *
12
 * @copyright 2021 Nelson Martell
13
 * @link      http://nelson6e65.github.io/php_nml/
14
 * @since     1.0.0
15
 * @license   http://www.opensource.org/licenses/mit-license.php The MIT License (MIT)
16
 * */
17
18
namespace NelsonMartell\Extensions;
19
20
use InvalidArgumentException;
21
use NelsonMartell\IComparer;
22
use NelsonMartell\IComparable;
23
use NelsonMartell\StrictObject;
24
25
use function NelsonMartell\msg;
26
use function NelsonMartell\typeof;
27
28
/**
29
 * Provides extension methods to handle numbers.
30
 *
31
 * @since 1.0.0
32
 * @author Nelson Martell <[email protected]>
33
 * */
34
class Objects implements IComparer
35
{
36
    /**
37
     * Determines the relative position of the object on the left with respect to the one on the right.
38
     *
39
     * This method is compatible with core types and other types. You can implement `NelsonMartell\IComparable`
40
     * in order to improve the beaviour for other classes.
41
     *
42
     * This method can be used as sorting function for `usort()` function.
43
     *
44
     * **Notes:**
45
     * - Comparison is made in natural way if they are of the same type. If not, is used the PHP standard
46
     * comparison.
47
     * - If ``$left`` and ``$right`` are arrays, comparison is made by first by 'key' (as strings) and then by
48
     *   'values' (using this method recursively).
49
     *
50
     * **Override:**
51
     * You can override this method to implement a contextual sorting behaviour for `usort()` function.
52
     * If you only need to compare instances of your class with other objects, implement `NelsonMartell\IComparable`
53
     * instead.
54
     *
55
     * @param mixed $left  Left object.
56
     * @param mixed $right Right object.
57
     *
58
     * @return int|null
59
     *   Returns:
60
     *   - ``= 0`` if $left is considered equivalent to $other;
61
     *   - ``> 0`` if $left is considered greater than $other;
62
     *   - ``< 0`` if $left is considered less than $other;
63
     *   - ``null`` if $left can't be compared to $other .
64
     *
65
     * @see \strnatcmp()
66
     * @see \usort()
67
     * @see Arrays::compare()
68
     * @see IComparable
69
     * @see IComparable::compareTo()
70
     * @see IComparer::compare()
71
     * @see Numbers::compare()
72
     * @see Text::compare()
73
     *
74
     * @since 1.0.0 Moved from `StrictObject::compare()`.
75
     * */
76 73
    public static function compare($left, $right)
77
    {
78 73
        $r = null;
79
80 73
        if ($left instanceof IComparable) {
81 8
            $r = $left->compareTo($right);
82 69
        } elseif ($right instanceof IComparable) {
83 12
            $r = $right->compareTo($left);
84
85 12
            if ($r !== null) {
86 12
                $r *= -1; // Invert result
87
            }
88
        } else {
89 58
            $ltype = typeof($left);
90 58
            $rtype = typeof($right);
91
92 58
            if (typeof(true)->isIn($left, $right)) {
93
            // Boolean compare -----------------------------------------
94 4
                if (typeof(true)->is($left, $right)) {
95 2
                    $r = (int) $left - (int) $right;
96
                } else {
97 4
                    $r = null;
98
                }
99 54
            } elseif (typeof(0)->isIn($left, $right) || typeof((float) 0)->isIn($left, $right)) {
100
            // Numeric compare -----------------------------------------
101 24
                $r = Numbers::compare($left, $right);
102 30
            } elseif (typeof('')->isIn($left, $right)) {
103
            // String compare ------------------------------------------
104 15
                $r = Text::compare($left, $right);
105 19
            } elseif (typeof([])->isIn($left, $right)) {
106
            // Array compare -------------------------------------------
107 12
                $r = Arrays::compare($left, $right);
108
            } else {
109 7
                if ($ltype->isCustom()) {
110 6
                    if ($rtype->isCustom()) {
111 5
                        if ($left == $right) {
112 2
                            $r = 0;
113 3
                        } elseif ($ltype->equals($rtype)) {
114 2
                            $r = ($left > $right) ? +1 : -1;
115
                        } else {
116 5
                            $r = null;
117
                        }
118
                    } else {
119 6
                        $r = 1;
120
                    }
121 1
                } elseif ($rtype->isCustom()) {
122 1
                    $r = -1;
123
                } else {
124
                    $r = null;
125
                }
126
            }
127
        }
128
129 73
        return $r;
130
    }
131
}
132