Completed
Push — master ( 14a06b...6322f3 )
by Nelson
05:31
created

Objects::compare()   C

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 0
Metric Value
cc 16
eloc 37
nc 15
nop 2
dl 0
loc 54
ccs 31
cts 32
cp 0.9688
crap 16.0077
rs 5.5666
c 0
b 0
f 0

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
 * PHP: Nelson Martell Library file
4
 *
5
 * Copyright © 2019 Nelson Martell (http://nelson6e65.github.io)
6
 *
7
 * Licensed under The MIT License (MIT)
8
 * For full copyright and license information, please see the LICENSE
9
 * Redistributions of files must retain the above copyright notice.
10
 *
11
 * @copyright 2019 Nelson Martell
12
 * @link      http://nelson6e65.github.io/php_nml/
13
 * @since     1.0.0
14
 * @license   http://www.opensource.org/licenses/mit-license.php The MIT License (MIT)
15
 * */
16
namespace NelsonMartell\Extensions;
17
18
use InvalidArgumentException;
19
20
use NelsonMartell\IComparer;
21
use NelsonMartell\IComparable;
22
use NelsonMartell\StrictObject;
23
24
use function NelsonMartell\msg;
25
use function NelsonMartell\typeof;
26
27
/**
28
 * Provides extension methods to handle numbers.
29
 *
30
 * @since 1.0.0
31
 * @author Nelson Martell <[email protected]>
32
 * */
33
class Objects implements IComparer
34
{
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((bool) true)->isIn($left, $right)) {
93
            // Boolean compare -----------------------------------------
94 4
                if (typeof((bool) true)->is($left, $right)) {
95 2
                    $r = (int) $left - (int) $right;
96
                } else {
97 4
                    $r = null;
98
                }
99 54
            } elseif (typeof((int) 0)->isIn($left, $right) || typeof((float) 0)->isIn($left, $right)) {
100
            // Numeric compare -----------------------------------------
101 24
                $r = Numbers::compare($left, $right);
102 30
            } elseif (typeof((string) '')->isIn($left, $right)) {
103
            // String compare ------------------------------------------
104 15
                $r = Text::compare($left, $right);
105 19
            } elseif (typeof((array) [])->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