Issues (54)

src/Arrays/ChainableArray.php (2 issues)

Severity
1
<?php
2
namespace JClaveau\Arrays;
3
4
/**
5
 * This class is meant to provide an oriented object way to use arrays
6
 * in PHP.
7
 *
8
 * This file contains only the essential API of the class. The rest is
9
 * gathered by feature in traits:
10
 * + One for the ArrayAcess interface
11
 * + One for the native functions of PHP.
12
 * + One for functions that do ot exist in PHP.
13
 *
14
 *
15
 * @todo :
16
 * + recursive
17
 */
18
class ChainableArray implements \ArrayAccess, \IteratorAggregate, \JsonSerializable, \Countable
19
{
20
    use ChainableArray_ArrayAccess_Trait;
21
    use ChainableArray_NativeFunctions_Trait;
22
    use ChainableArray_Utils_Trait;
23
    use ChainableArray_Wip_Trait;
24
25
    protected $data;
26
    protected $isConstant;
27
28
    /**
29
     */
30
    public static function from($data=[], $isConstant=false)
31
    {
32
        Arrays::mustBeCountable($data);
33
34
        if ($data instanceof self)
35
            return $data;
36
37
        return new static($data, $isConstant);
38
    }
39
40
    /**
41
     */
42
    public function __construct(array $data=[], $isConstant=false)
43
    {
44
        $this->data       = $data;
45
        $this->isConstant = $isConstant;
46
    }
47
48
    /**
49
     * Getter of the array behid the helper classe.
50
     *
51
     * @return array The data of this array
52
     */
53
    public function getArray()
54
    {
55
        return $this->data;
56
    }
57
58
    /**
59
     * Deprecated alias of getArray()
60
     *
61
     * @deprecated
62
     */
63
    public function getData()
64
    {
65
        return $this->data;
66
    }
67
68
    /**
69
     * @see self::getData()
70
     * @return array
71
     */
72
    public function toArray()
73
    {
74
        return $this->data;
75
    }
76
77
    /**
78
     * Changes the "constant" state of this instance. If it is "constant",
79
     * any modification done by one of its methods will return a copy of
80
     * the current instance instead of modifying it.
81
     *
82
     * @param bool $state Whether to enable or not the constant state.
83
     *
84
     * @return ChainableArray $this
85
     */
86
    public function setConstant($state=true)
87
    {
88
        $this->isConstant = $state;
89
        return $this;
90
    }
91
92
    /**
93
     * Depending on the isConstant property of the instance the data
94
     * will be impacted by the methods like mergeWith or not.
95
     *
96
     * @param array $out The modified array to return
97
     *
98
     * @return ChainableArray $this or a new instance having $out as data.
99
     */
100
    protected function returnConstant(array $out)
101
    {
102
        if ($this->isConstant) {
103
            return new static($out);
104
        }
105
        else {
106
            $this->data = $out;
107
            return $this;
108
        }
109
    }
110
111
    /**
112
     * @deprecated
113
     */
114
    public function clone_()
115
    {
116
        return $this->copy();
117
    }
118
119
    /**
120
     * clone the current object
121
     */
122
    public function copy()
123
    {
124
        return clone $this;
125
    }
126
127
    /**
128
     * Make foreach() possible on this object.
129
     * This doesn't look to work well on every PHP version but is tested
130
     * on 5.6.25.
131
     * We use a generator here to support foreach with references.
132
     * @see http://stackoverflow.com/questions/29798586/php-an-iterator-cannot-be-used-with-foreach-by-reference#29798888
133
     */
134
    public function &getIterator()
135
    {
136
        foreach ($this->data as $position => &$row) {
137
            yield $position => $row;
138
        }
139
    }
140
141
    /**
142
     * This method is required to have the good value while we want to
143
     * json_encode an instance of this class.
144
     *
145
     * @see http://stackoverflow.com/questions/4697656/using-json-encode-on-objects-in-php-regardless-of-scope
146
     */
147
    public function jsonSerialize()
148
    {
149
        return $this->data;
150
    }
151
152
    /**
153
     * This method is required by the Countable interface.
154
     *
155
     * @see https://secure.php.net/manual/en/class.countable.php
156
     */
157
    public function count()
158
    {
159
        return count($this->data);
160
    }
161
162
    /**
163
     * Checks if an argument is an array or a ChainableArray
164
     */
165
    private function argumentIsArrayOrArrayObject( $argument )
0 ignored issues
show
The method argumentIsArrayOrArrayObject() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
166
    {
167
        return is_array($argument)
168
            || $argument instanceof ChainableArray;
169
    }
170
171
    /**
172
     * Throws an exception that will have, as file and line, the position
173
     * where the public api is called.
174
     */
175
    private static function throwUsageException($message)
0 ignored issues
show
The method throwUsageException() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
176
    {
177
        $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 20);
178
        $i      = 1;
179
        $caller = $backtrace[$i];
180
        while (     isset($backtrace[$i]['class'])
181
                &&  $backtrace[$i]['class'] == __CLASS__ ) {
182
            $caller = $backtrace[$i];
183
            $i++;
184
        }
185
186
        $exception = new \ErrorException($message);
187
188
        $reflectionClass = new \ReflectionClass( get_class($exception) );
189
190
        //file
191
        $reflectionProperty = $reflectionClass->getProperty('file');
192
        $reflectionProperty->setAccessible(true);
193
        $reflectionProperty->setValue($exception, $caller['file']);
194
195
        // line
196
        $reflectionProperty = $reflectionClass->getProperty('line');
197
        $reflectionProperty->setAccessible(true);
198
        $reflectionProperty->setValue($exception, $caller['line']);
199
200
        throw $exception;
201
    }
202
203
    /**/
204
}
205