Objects::compare()   C
last analyzed

Complexity

Conditions 16
Paths 15

Size

Total Lines 54
Code Lines 37

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 31
CRAP Score 16.0077

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 16
eloc 37
c 1
b 0
f 0
nc 15
nop 2
dl 0
loc 54
rs 5.5666
ccs 31
cts 32
cp 0.9688
crap 16.0077

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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