Passed
Push — master ( 78328e...488bc1 )
by Nelson
03:01
created

Arrays   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 83
Duplicated Lines 0 %

Test Coverage

Coverage 81.25%

Importance

Changes 0
Metric Value
eloc 33
dl 0
loc 83
ccs 26
cts 32
cp 0.8125
rs 10
c 0
b 0
f 0
wmc 11

2 Methods

Rating   Name   Duplication   Size   Complexity  
A ensureIsArray() 0 8 2
B compare() 0 47 9
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\StrictObject;
22
23
use function NelsonMartell\msg;
24
use function NelsonMartell\typeof;
25
26
/**
27
 * Provides extension methods to handle arrays.
28
 *
29
 * @since 1.0.0
30
 * @author Nelson Martell <[email protected]>
31
 * */
32
class Arrays implements IComparer
33
{
34
    /**
35
     * Ensures that object given is an `array`. Else, throw an exception.
36
     *
37
     * @param mixed $obj Object to validate.
38
     *
39
     * @return array Same object given.
40
     *
41
     * @throws InvalidArgumentException if object is not an `array`.
42
     */
43
    public static function ensureIsArray($obj)
44
    {
45
        if (!is_array($obj)) {
46
            $msg = msg('Provided object must to be an array; "{0}" given.', typeof($obj));
47
            throw new InvalidArgumentException($msg);
48
        }
49
50
        return $obj;
51
    }
52
53
    /**
54
     * {@inheritDoc}
55
     *
56
     * This methods is specific for the case when one of them are `array`. In other case, will fallback to
57
     * `StrictObject::compare()`.` You should use it directly instead of this method as comparation function
58
     * for `usort()`.
59
     *
60
     * @param array|mixed $left
61
     * @param array|mixed $right
62
     *
63
     * @return int|null Returns null if one of them is not an `array`.
64
     *
65
     * @since 1.0.0  Move implementation of array comparation from `StrictObject::compare()`.
66
     * @see StrictObject::compare()
67
     */
68 22
    public static function compare($left, $right)
69
    {
70 22
        if (is_array($left)) {
71 22
            if (is_array($right)) {
72 14
                $r = count($left) - count($right);
73
74 14
                if ($r === 0) {
75 8
                    reset($left);
76 8
                    reset($right);
77
78
                    do {
79 8
                        $lKey   = key($left);
80 8
                        $lValue = current($left);
81 8
                        $rKey   = key($right);
82 8
                        $rValue = current($right);
83
84 8
                        $r = StrictObject::compare((string) $lKey, (string) $rKey);
85
86 8
                        if ($r === 0) {
87
                            // Recursive call to compare values
88 6
                            $r = StrictObject::compare($lValue, $rValue);
89
                        }
90
91 8
                        next($left);
92 8
                        next($right);
93 8
                    } while (key($left) !== null && key($right) !== null && $r === 0);
94
                }
95
96 14
                return $r;
97
            } else {
98 8
                if (typeof($right)->isCustom()) {
99 4
                    return -1;
100
                } else {
101 4
                    return 1;
102
                }
103
            }
104 4
        } elseif (is_array($right)) {
105 4
            $r = static::compare($right, $left);
106
107 4
            if ($r !== null) {
108 4
                $r *= -1; // Invert result
109
            }
110
111 4
            return $r;
112
        }
113
114
        return StrictObject::compare($left, $right);
115
    }
116
}
117