DataCollection   A
last analyzed

Complexity

Total Complexity 31

Size/Duplication

Total Lines 406
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 61
dl 0
loc 406
rs 9.92
c 0
b 0
f 0
wmc 31

22 Methods

Rating   Name   Duplication   Size   Complexity  
A exists() 0 4 1
A __isset() 0 3 1
A replace() 0 5 1
A keys() 0 29 4
A cloneEmpty() 0 6 1
A __set() 0 3 1
A clear() 0 3 1
A offsetUnset() 0 3 1
A __construct() 0 3 1
A __get() 0 3 1
A count() 0 3 1
A get() 0 7 2
A remove() 0 3 1
A merge() 0 19 3
A isEmpty() 0 3 1
A offsetGet() 0 3 1
A getIterator() 0 3 1
A all() 0 29 4
A offsetSet() 0 3 1
A __unset() 0 3 1
A set() 0 5 1
A offsetExists() 0 3 1
1
<?php
2
/**
3
 * Klein (klein.php) - A fast & flexible router for PHP
4
 *
5
 * @author      Chris O'Hara <[email protected]>
6
 * @author      Trevor Suarez (Rican7) (contributor and v2 refactorer)
7
 * @copyright   (c) Chris O'Hara
8
 * @link        https://github.com/klein/klein.php
9
 * @license     MIT
10
 */
11
12
namespace app\framework\Component\Routing\DataCollection;
13
14
use ArrayAccess;
15
use ArrayIterator;
16
use Countable;
17
use IteratorAggregate;
18
19
/**
20
 * DataCollection
21
 *
22
 * A generic collection class to contain array-like data, specifically
23
 * designed to work with HTTP data (request params, session data, etc)
24
 *
25
 * Inspired by @fabpot's Symfony 2's HttpFoundation
26
 * @link https://github.com/symfony/HttpFoundation/blob/master/ParameterBag.php
27
 * @package app\framework\Component\Routing\DataCollection
28
 */
29
class DataCollection implements IteratorAggregate, ArrayAccess, Countable
30
{
31
32
    /**
33
     * Class properties
34
     */
35
36
    /**
37
     * Collection of data attributes
38
     *
39
     * @type array
40
     */
41
    protected $attributes = array();
42
43
44
    /**
45
     * Methods
46
     */
47
48
    /**
49
     * Constructor
50
     *
51
     * @param array $attributes The data attributes of this collection
52
     */
53
    public function __construct(array $attributes = array())
54
    {
55
        $this->attributes = $attributes;
56
    }
57
58
    /**
59
     * Returns all of the key names in the collection
60
     *
61
     * If an optional mask array is passed, this only
62
     * returns the keys that match the mask
63
     *
64
     * @param array $mask               The parameter mask array
65
     * @param boolean $fill_with_nulls  Whether or not to fill the returned array with
66
     *  values to match the given mask, even if they don't exist in the collection
67
     * @return array
68
     */
69
    public function keys($mask = null, $fill_with_nulls = true)
70
    {
71
        if (null !== $mask) {
72
            // Support a more "magical" call
73
            if (!is_array($mask)) {
74
                $mask = func_get_args();
75
            }
76
77
            /*
78
             * Make sure that the returned array has at least the values
79
             * passed into the mask, since the user will expect them to exist
80
             */
81
            if ($fill_with_nulls) {
82
                $keys = $mask;
83
            } else {
84
                $keys = array();
85
            }
86
87
            /*
88
             * Remove all of the values from the keys
89
             * that aren't in the passed mask
90
             */
91
            return array_intersect(
92
                array_keys($this->attributes),
93
                $mask
94
            ) + $keys;
95
        }
96
97
        return array_keys($this->attributes);
98
    }
99
100
    /**
101
     * Returns all of the attributes in the collection
102
     *
103
     * If an optional mask array is passed, this only
104
     * returns the keys that match the mask
105
     *
106
     * @param array $mask               The parameter mask array
107
     * @param boolean $fill_with_nulls  Whether or not to fill the returned array with
108
     *  values to match the given mask, even if they don't exist in the collection
109
     * @return array
110
     */
111
    public function all($mask = null, $fill_with_nulls = true)
112
    {
113
        if (null !== $mask) {
114
            // Support a more "magical" call
115
            if (!is_array($mask)) {
116
                $mask = func_get_args();
117
            }
118
119
            /*
120
             * Make sure that each key in the mask has at least a
121
             * null value, since the user will expect the key to exist
122
             */
123
            if ($fill_with_nulls) {
124
                $attributes = array_fill_keys($mask, null);
125
            } else {
126
                $attributes = array();
127
            }
128
129
            /*
130
             * Remove all of the keys from the attributes
131
             * that aren't in the passed mask
132
             */
133
            return array_intersect_key(
134
                $this->attributes,
135
                array_flip($mask)
136
            ) + $attributes;
137
        }
138
139
        return $this->attributes;
140
    }
141
142
    /**
143
     * Return an attribute of the collection
144
     *
145
     * Return a default value if the key doesn't exist
146
     *
147
     * @param string $key           The name of the parameter to return
148
     * @param mixed  $default_val   The default value of the parameter if it contains no value
149
     * @return mixed
150
     */
151
    public function get($key, $default_val = null)
152
    {
153
        if (isset($this->attributes[$key])) {
154
            return $this->attributes[$key];
155
        }
156
157
        return $default_val;
158
    }
159
160
    /**
161
     * Set an attribute of the collection
162
     *
163
     * @param string $key   The name of the parameter to set
164
     * @param mixed  $value The value of the parameter to set
165
     * @return DataCollection
166
     */
167
    public function set($key, $value)
168
    {
169
        $this->attributes[$key] = $value;
170
171
        return $this;
172
    }
173
174
    /**
175
     * Replace the collection's attributes
176
     *
177
     * @param array $attributes The attributes to replace the collection's with
178
     * @return DataCollection
179
     */
180
    public function replace(array $attributes = array())
181
    {
182
        $this->attributes = $attributes;
183
184
        return $this;
185
    }
186
187
    /**
188
     * Merge attributes with the collection's attributes
189
     *
190
     * Optionally allows a second boolean parameter to merge the attributes
191
     * into the collection in a "hard" manner, using the "array_replace"
192
     * method instead of the usual "array_merge" method
193
     *
194
     * @param array $attributes The attributes to merge into the collection
195
     * @param boolean $hard     Whether or not to make the merge "hard"
196
     * @return DataCollection
197
     */
198
    public function merge(array $attributes = array(), $hard = false)
199
    {
200
        // Don't waste our time with an "array_merge" call if the array is empty
201
        if (!empty($attributes)) {
202
            // Hard merge?
203
            if ($hard) {
204
                $this->attributes = array_replace(
205
                    $this->attributes,
206
                    $attributes
207
                );
208
            } else {
209
                $this->attributes = array_merge(
210
                    $this->attributes,
211
                    $attributes
212
                );
213
            }
214
        }
215
216
        return $this;
217
    }
218
219
    /**
220
     * See if an attribute exists in the collection
221
     *
222
     * @param string $key   The name of the parameter
223
     * @return boolean
224
     */
225
    public function exists($key)
226
    {
227
        // Don't use "isset", since it returns false for null values
228
        return array_key_exists($key, $this->attributes);
229
    }
230
231
    /**
232
     * Remove an attribute from the collection
233
     *
234
     * @param string $key   The name of the parameter
235
     * @return void
236
     */
237
    public function remove($key)
238
    {
239
        unset($this->attributes[$key]);
240
    }
241
242
    /**
243
     * Clear the collection's contents
244
     *
245
     * Semantic alias of a no-argument `$this->replace` call
246
     *
247
     * @return DataCollection
248
     */
249
    public function clear()
250
    {
251
        return $this->replace();
252
    }
253
254
    /**
255
     * Check if the collection is empty
256
     *
257
     * @return boolean
258
     */
259
    public function isEmpty()
260
    {
261
        return empty($this->attributes);
262
    }
263
264
    /**
265
     * A quick convenience method to get an empty clone of the
266
     * collection. Great for dependency injection. :)
267
     *
268
     * @return DataCollection
269
     */
270
    public function cloneEmpty()
271
    {
272
        $clone = clone $this;
273
        $clone->clear();
274
275
        return $clone;
276
    }
277
278
279
    /*
280
     * Magic method implementations
281
     */
282
283
    /**
284
     * Magic "__get" method
285
     *
286
     * Allows the ability to arbitrarily request an attribute from
287
     * this instance while treating it as an instance property
288
     *
289
     * @see get()
290
     * @param string $key   The name of the parameter to return
291
     * @return mixed
292
     */
293
    public function __get($key)
294
    {
295
        return $this->get($key);
296
    }
297
298
    /**
299
     * Magic "__set" method
300
     *
301
     * Allows the ability to arbitrarily set an attribute from
302
     * this instance while treating it as an instance property
303
     *
304
     * @see set()
305
     * @param string $key   The name of the parameter to set
306
     * @param mixed  $value The value of the parameter to set
307
     * @return void
308
     */
309
    public function __set($key, $value)
310
    {
311
        $this->set($key, $value);
312
    }
313
314
    /**
315
     * Magic "__isset" method
316
     *
317
     * Allows the ability to arbitrarily check the existence of an attribute
318
     * from this instance while treating it as an instance property
319
     *
320
     * @see exists()
321
     * @param string $key   The name of the parameter
322
     * @return boolean
323
     */
324
    public function __isset($key)
325
    {
326
        return $this->exists($key);
327
    }
328
329
    /**
330
     * Magic "__unset" method
331
     *
332
     * Allows the ability to arbitrarily remove an attribute from
333
     * this instance while treating it as an instance property
334
     *
335
     * @see remove()
336
     * @param string $key   The name of the parameter
337
     * @return void
338
     */
339
    public function __unset($key)
340
    {
341
        $this->remove($key);
342
    }
343
344
345
    /*
346
     * Interface required method implementations
347
     */
348
349
    /**
350
     * Get the aggregate iterator
351
     *
352
     * IteratorAggregate interface required method
353
     *
354
     * @see \IteratorAggregate::getIterator()
355
     * @return ArrayIterator
356
     */
357
    public function getIterator()
358
    {
359
        return new ArrayIterator($this->attributes);
360
    }
361
362
    /**
363
     * Get an attribute via array syntax
364
     *
365
     * Allows the access of attributes of this instance while treating it like an array
366
     *
367
     * @see \ArrayAccess::offsetGet()
368
     * @see get()
369
     * @param string $key   The name of the parameter to return
370
     * @return mixed
371
     */
372
    public function offsetGet($key)
373
    {
374
        return $this->get($key);
375
    }
376
377
    /**
378
     * Set an attribute via array syntax
379
     *
380
     * Allows the access of attributes of this instance while treating it like an array
381
     *
382
     * @see \ArrayAccess::offsetSet()
383
     * @see set()
384
     * @param string $key   The name of the parameter to set
385
     * @param mixed  $value The value of the parameter to set
386
     * @return void
387
     */
388
    public function offsetSet($key, $value)
389
    {
390
        $this->set($key, $value);
391
    }
392
393
    /**
394
     * Check existence an attribute via array syntax
395
     *
396
     * Allows the access of attributes of this instance while treating it like an array
397
     *
398
     * @see \ArrayAccess::offsetExists()
399
     * @see exists()
400
     * @param string $key   The name of the parameter
401
     * @return boolean
402
     */
403
    public function offsetExists($key)
404
    {
405
        return $this->exists($key);
406
    }
407
408
    /**
409
     * Remove an attribute via array syntax
410
     *
411
     * Allows the access of attributes of this instance while treating it like an array
412
     *
413
     * @see \ArrayAccess::offsetUnset()
414
     * @see remove()
415
     * @param string $key   The name of the parameter
416
     * @return void
417
     */
418
    public function offsetUnset($key)
419
    {
420
        $this->remove($key);
421
    }
422
423
    /**
424
     * Count the attributes via a simple "count" call
425
     *
426
     * Allows the use of the "count" function (or any internal counters)
427
     * to simply count the number of attributes in the collection.
428
     *
429
     * @see \Countable::count()
430
     * @return int
431
     */
432
    public function count()
433
    {
434
        return count($this->attributes);
435
    }
436
}
437