DataContainer::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 1
Metric Value
c 2
b 0
f 1
dl 0
loc 5
rs 9.4285
cc 1
eloc 3
nc 1
nop 2
1
<?php
2
/**
3
 * @package    Fuel\Common
4
 * @version    2.0
5
 * @author     Fuel Development Team
6
 * @license    MIT License
7
 * @copyright  2010 - 2015 Fuel Development Team
8
 * @link       http://fuelphp.com
9
 */
10
11
namespace Fuel\Common;
12
13
/**
14
 * Generic data container
15
 *
16
 * @package Fuel\Common
17
 *
18
 * @since 2.0
19
 */
20
class DataContainer implements \ArrayAccess, \IteratorAggregate, \Countable
21
{
22
	/**
23
	 * @var    DataContainer  parent container, for inheritance
24
	 * @since  2.0.0
25
	 */
26
	protected $parent;
27
28
	/**
29
	 * @var    bool  wether we want to use parent cascading
30
	 * @since  2.0.0
31
	 */
32
	protected $parentEnabled = false;
33
34
	/**
35
	 * @var    array  container data
36
	 * @since  2.0.0
37
	 */
38
	protected $data = array();
39
40
	/**
41
	 * @var    bool   wether the container is read-only
42
	 * @since  2.0.0
43
	 */
44
	protected $readOnly = false;
45
46
	/**
47
	 * @var    bool   wether the container data has been modified
48
	 * @since  2.0.0
49
	 */
50
	protected $isModified = false;
51
52
	/**
53
	 * Constructor
54
	 *
55
	 * @param  array    $data      container data
56
	 * @param  boolean  $readOnly  wether the container is read-only
57
	 * @since  2.0.0
58
	 */
59
	public function __construct(array $data = array(), $readOnly = false)
60
	{
61
		$this->data = $data;
62
		$this->readOnly = $readOnly;
63
	}
64
65
	/**
66
	 * Get the parent of this container
67
	 *
68
	 * @return  DataContainer
69
	 * @since   2.0.0
70
	 */
71
	public function getParent()
72
	{
73
		return $this->parent;
74
	}
75
76
	/**
77
	 * Set the parent of this container, to support inheritance
78
	 *
79
	 * @param   DataContainer  $parent  the parent container object
80
	 * @return  $this
81
	 * @since   2.0.0
82
	 */
83
	public function setParent(DataContainer $parent = null)
84
	{
85
		$this->parent = $parent;
86
87
		if ($this->parent)
88
		{
89
			$this->enableParent();
90
		}
91
		else
92
		{
93
			$this->disableParent();
94
		}
95
96
		return $this;
97
	}
98
99
	/**
100
	 * Enable the use of the parent object, if set
101
	 *
102
	 * @return  $this
103
	 * @since   2.0.0
104
	 */
105
	public function enableParent()
106
	{
107
		if ($this->parent)
108
		{
109
			$this->parentEnabled = true;
110
		}
111
112
		return $this;
113
	}
114
115
	/**
116
	 * Disable the use of the parent object
117
	 *
118
	 * @return  $this
119
	 * @since   2.0.0
120
	 */
121
	public function disableParent()
122
	{
123
		$this->parentEnabled = false;
124
125
		return $this;
126
	}
127
128
	/**
129
	 * Check whether or not this container has an active parent
130
	 *
131
	 * @return  bool
132
	 * @since   2.0.0
133
	 */
134
	public function hasParent()
135
	{
136
		return $this->parentEnabled;
137
	}
138
139
	/**
140
	 * Retrieve the modified state of the container
141
	 *
142
	 * @return  bool
143
	 * @since   2.0.0
144
	 */
145
	public function isModified()
146
	{
147
		return $this->isModified;
148
	}
149
150
	/**
151
	 * Replace the container's data.
152
	 *
153
	 * @param   array  $data  new data
154
	 * @return  $this
155
	 * @throws  RuntimeException
156
	 * @since   2.0.0
157
	 */
158
	public function setContents(array $data)
159
	{
160
		if ($this->readOnly)
161
		{
162
			throw new \RuntimeException('Changing values on this Data Container is not allowed.');
163
		}
164
165
		$this->data = $data;
166
167
		$this->isModified = true;
168
169
		return $this;
170
	}
171
172
	/**
173
	 * Get the container's data
174
	 *
175
	 * @return  array  container's data
176
	 * @since   2.0.0
177
	 */
178
	public function getContents()
179
	{
180
		if ($this->parentEnabled)
181
		{
182
			return Arr::merge($this->parent->getContents(), $this->data);
183
		}
184
		else
185
		{
186
			return $this->data;
187
		}
188
	}
189
190
	/**
191
	 * Set wether the container is read-only.
192
	 *
193
	 * @param   boolean  $readOnly  wether it's a read-only container
194
	 * @return  $this
195
	 * @since   2.0.0
196
	 */
197
	public function setReadOnly($readOnly = true)
198
	{
199
		$this->readOnly = (bool) $readOnly;
200
201
		return $this;
202
	}
203
204
	/**
205
	 * Merge arrays into the container.
206
	 *
207
	 * @param   array  $arg  array to merge with
208
	 * @return  $this
209
	 * @throws  RuntimeException
210
	 * @since   2.0.0
211
	 */
212
	public function merge($arg)
0 ignored issues
show
Unused Code introduced by
The parameter $arg is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
213
	{
214
		if ($this->readOnly)
215
		{
216
			throw new \RuntimeException('Changing values on this Data Container is not allowed.');
217
		}
218
219
		$arguments = array_map(function ($array) use (&$valid)
220
		{
221
			if ($array instanceof DataContainer)
222
			{
223
				return $array->getContents();
224
			}
225
226
			return $array;
227
228
		}, func_get_args());
229
230
		array_unshift($arguments, $this->data);
231
		$this->data = call_user_func_array('\Fuel\Common\Arr::merge', $arguments);
0 ignored issues
show
Documentation Bug introduced by
It seems like call_user_func_array('\\...rr::merge', $arguments) of type * is incompatible with the declared type array of property $data.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
232
233
		$this->isModified = true;
234
235
		return $this;
236
	}
237
238
	/**
239
	 * Check wether the container is read-only.
240
	 *
241
	 * @return  boolean  $readOnly  wether it's a read-only container
242
	 * @since   2.0.0
243
	 */
244
	public function isReadOnly()
245
	{
246
		return $this->readOnly;
247
	}
248
249
	/**
250
	 * isset magic method
251
	 */
252
	public function __isset($key)
253
	{
254
		return $this->has($key);
255
	}
256
257
	/**
258
	 * Check if a key was set upon this bag's data
259
	 *
260
	 * @param   string  $key
261
	 * @return  bool
262
	 * @since   2.0.0
263
	 */
264
	public function has($key)
265
	{
266
		$result = Arr::has($this->data, $key);
267
268
		if ( ! $result and $this->parentEnabled)
269
		{
270
			$result = $this->parent->has($key);
271
		}
272
273
		return $result;
274
	}
275
276
	/**
277
	 * get magic method
278
	 */
279
	public function __get($key)
280
	{
281
		return $this->get($key);
282
	}
283
284
	/**
285
	 * Get a key's value from this bag's data
286
	 *
287
	 * @param   string  $key
288
	 * @param   mixed   $default
289
	 * @return  mixed
290
	 * @since   2.0.0
291
	 */
292
	public function get($key = null, $default = null)
293
	{
294
		$fail = uniqid('__FAIL__', true);
295
296
		$result = Arr::get($this->data, $key, $fail);
297
298
		if ($result === $fail)
299
		{
300
			if ($this->parentEnabled)
301
			{
302
				$result = $this->parent->get($key, $default);
303
			}
304
			else
305
			{
306
				$result = result($default);
307
			}
308
		}
309
310
		return $result;
311
	}
312
313
	/**
314
	 * set magic method
315
	 */
316
	public function __set($key, $value)
317
	{
318
		$this->set($key, $value);
319
	}
320
321
	/**
322
	 * Set a config value
323
	 *
324
	 * @param   string  $key
325
	 * @param   mixed   $value
326
	 * @throws  \RuntimeException
327
	 * @since   2.0.0
328
	 */
329 View Code Duplication
	public function set($key, $value)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
330
	{
331
		if ($this->readOnly)
332
		{
333
			throw new \RuntimeException('Changing values on this Data Container is not allowed.');
334
		}
335
336
		$this->isModified = true;
337
338
		if ($key === null)
339
		{
340
			$this->data[] = $value;
341
342
			return $this;
343
		}
344
345
		Arr::set($this->data, $key, $value);
346
347
		return $this;
348
	}
349
350
	/**
351
	 * Delete data from the container
352
	 *
353
	 * @param   string   $key  key to delete
354
	 * @return  boolean  delete success boolean
355
	 * @since   2.0.0
356
	 */
357 View Code Duplication
	public function delete($key)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
358
	{
359
		if ($this->readOnly)
360
		{
361
			throw new \RuntimeException('Changing values on this Data Container is not allowed.');
362
		}
363
364
		$this->isModified = true;
365
366
		if (($result = Arr::delete($this->data, $key)) === false and $this->parentEnabled)
367
		{
368
			$result = $this->parent->delete($key);
369
		}
370
371
		return $result;
372
	}
373
374
	/**
375
	 * Allow usage of isset() on the param bag as an array
376
	 *
377
	 * @param   string  $key
378
	 * @return  bool
379
	 * @since   2.0.0
380
	 */
381
	public function offsetExists($key)
382
	{
383
		return $this->has($key);
384
	}
385
386
	/**
387
	 * Allow fetching values as an array
388
	 *
389
	 * @param   string  $key
390
	 * @return  mixed
391
	 * @throws  OutOfBoundsException
392
	 * @since   2.0.0
393
	 */
394
	public function offsetGet($key)
395
	{
396
		return $this->get($key, function() use ($key)
397
		{
398
			throw new \OutOfBoundsException('Access to undefined index: '.$key);
399
		});
400
	}
401
402
	/**
403
	 * Disallow setting values like an array
404
	 *
405
	 * @param  string  $key
406
	 * @param  mixed   $value
407
	 * @since  2.0.0
408
	 */
409
	public function offsetSet($key, $value)
410
	{
411
		$this->set($key, $value);
412
	}
413
414
	/**
415
	 * Disallow unsetting values like an array
416
	 *
417
	 * @param   string  $key
418
	 * @throws  RuntimeException
419
	 * @since   2.0.0
420
	 */
421
	public function offsetUnset($key)
422
	{
423
		return $this->delete($key);
424
	}
425
426
	/**
427
	 * IteratorAggregate implementation
428
	 *
429
	 * @return  IteratorAggregate  iterator
430
	 * @since   2.0.0
431
	 */
432
	public function getIterator()
433
	{
434
		return new \ArrayIterator($this->getContents());
435
	}
436
437
	/**
438
	 * Countable implementation
439
	 *
440
	 * @return  int  number of items stored in the container
441
	 * @since   2.0.0
442
	 */
443
	public function count()
444
	{
445
		return count($this->getContents());
446
	}
447
}
448