GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Pull Request — develop (#322)
by
unknown
01:59
created

Registry::__clone()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * Part of the Joomla Framework Registry Package
4
 *
5
 * @copyright  Copyright (C) 2005 - 2016 Open Source Matters, Inc. All rights reserved.
6
 * @license    GNU General Public License version 2 or later; see LICENSE
7
 */
8
9
namespace Joomla\Registry;
10
11
use Joomla\Utilities\ArrayHelper;
12
13
/**
14
 * Registry class
15
 *
16
 * @since  1.0
17
 */
18
class Registry implements \JsonSerializable, \ArrayAccess, \IteratorAggregate, \Countable
19
{
20
	/**
21
	 * Registry Object
22
	 *
23
	 * @var    object
24
	 * @since  1.0
25
	 */
26
	protected $data;
27
28
	/**
29
	 * Flag if the Registry data object has been initialized
30
	 *
31
	 * @var    boolean
32
	 * @since  1.5.2
33
	 */
34
	protected $initialized = false;
35
36
	/**
37
	 * Registry instances container.
38
	 *
39
	 * @var    array
40
	 * @since  1.0
41
	 * @deprecated  2.0  Object caching will no longer be supported
42
	 */
43
	protected static $instances = array();
44
45
	/**
46
	 * Path separator
47
	 *
48
	 * @var    string
49
	 * @since  1.4.0
50
	 */
51
	public $separator = '.';
52
53
	/**
54
	 * Constructor
55
	 *
56
	 * @param   mixed  $data  The data to bind to the new Registry object.
57
	 *
58
	 * @since   1.0
59
	 */
60
	public function __construct($data = null)
61
	{
62
		// Instantiate the internal data object.
63
		$this->data = new \stdClass;
64
65
		// Optionally load supplied data.
66
		if (is_array($data) || is_object($data))
67
		{
68
			$this->bindData($this->data, $data);
69
		}
70
		elseif (!empty($data) && is_string($data))
71
		{
72
			$this->loadString($data);
73
		}
74
	}
75
76
	/**
77
	 * Magic function to clone the registry object.
78
	 *
79
	 * @return  Registry
80
	 *
81
	 * @since   1.0
82
	 */
83
	public function __clone()
84
	{
85
		$this->data = unserialize(serialize($this->data));
86
	}
87
88
	/**
89
	 * Magic function to render this object as a string using default args of toString method.
90
	 *
91
	 * @return  string
92
	 *
93
	 * @since   1.0
94
	 */
95
	public function __toString()
96
	{
97
		return $this->toString();
98
	}
99
100
	/**
101
	 * Count elements of the data object
102
	 *
103
	 * @return  integer  The custom count as an integer.
104
	 *
105
	 * @link    http://php.net/manual/en/countable.count.php
106
	 * @since   1.3.0
107
	 */
108
	public function count()
109
	{
110
		return count(get_object_vars($this->data));
111
	}
112
113
	/**
114
	 * Implementation for the JsonSerializable interface.
115
	 * Allows us to pass Registry objects to json_encode.
116
	 *
117
	 * @return  object
118
	 *
119
	 * @since   1.0
120
	 * @note    The interface is only present in PHP 5.4 and up.
121
	 */
122
	public function jsonSerialize()
123
	{
124
		return $this->data;
125
	}
126
127
	/**
128
	 * Sets a default value if not already assigned.
129
	 *
130
	 * @param   string  $key      The name of the parameter.
131
	 * @param   mixed   $default  An optional value for the parameter.
132
	 *
133
	 * @return  mixed  The value set, or the default if the value was not previously set (or null).
134
	 *
135
	 * @since   1.0
136
	 */
137
	public function def($key, $default = '')
138
	{
139
		$value = $this->get($key, $default);
140
		$this->set($key, $value);
141
142
		return $value;
143
	}
144
145
	/**
146
	 * Check if a registry path exists.
147
	 *
148
	 * @param   string  $path  Registry path (e.g. joomla.content.showauthor)
149
	 *
150
	 * @return  boolean
151
	 *
152
	 * @since   1.0
153
	 */
154
	public function exists($path)
155
	{
156
		// Return default value if path is empty
157
		if (empty($path))
158
		{
159
			return false;
160
		}
161
162
		// Explode the registry path into an array
163
		$nodes = explode($this->separator, $path);
164
165
		// Initialize the current node to be the registry root.
166
		$node = $this->data;
167
		$found = false;
168
169
		// Traverse the registry to find the correct node for the result.
170 View Code Duplication
		foreach ($nodes as $n)
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
171
		{
172
			if (is_array($node) && isset($node[$n]))
173
			{
174
				$node = $node[$n];
175
				$found = true;
176
				continue;
177
			}
178
179
			if (!isset($node->$n))
180
			{
181
				return false;
182
			}
183
184
			$node = $node->$n;
185
			$found = true;
186
		}
187
188
		return $found;
189
	}
190
191
	/**
192
	 * Get a registry value.
193
	 *
194
	 * @param   string  $path     Registry path (e.g. joomla.content.showauthor)
195
	 * @param   mixed   $default  Optional default value, returned if the internal value is null.
196
	 *
197
	 * @return  mixed  Value of entry or null
198
	 *
199
	 * @since   1.0
200
	 */
201
	public function get($path, $default = null)
202
	{
203
		// Return default value if path is empty
204
		if (empty($path))
205
		{
206
			return $default;
207
		}
208
209
		if (!strpos($path, $this->separator))
210
		{
211
			return (isset($this->data->$path) && $this->data->$path !== null && $this->data->$path !== '') ? $this->data->$path : $default;
212
		}
213
214
		// Explode the registry path into an array
215
		$nodes = explode($this->separator, trim($path));
216
217
		// Initialize the current node to be the registry root.
218
		$node = $this->data;
219
		$found = false;
220
221
		// Traverse the registry to find the correct node for the result.
222 View Code Duplication
		foreach ($nodes as $n)
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
223
		{
224
			if (is_array($node) && isset($node[$n]))
225
			{
226
				$node = $node[$n];
227
				$found = true;
228
229
				continue;
230
			}
231
232
			if (!isset($node->$n))
233
			{
234
				return $default;
235
			}
236
237
			$node = $node->$n;
238
			$found = true;
239
		}
240
241
		if (!$found || $node === null || $node === '')
242
		{
243
			return $default;
244
		}
245
246
		return $node;
247
	}
248
249
	/**
250
	 * Returns a reference to a global Registry object, only creating it
251
	 * if it doesn't already exist.
252
	 *
253
	 * This method must be invoked as:
254
	 * <pre>$registry = Registry::getInstance($id);</pre>
255
	 *
256
	 * @param   string  $id  An ID for the registry instance
257
	 *
258
	 * @return  Registry  The Registry object.
259
	 *
260
	 * @since   1.0
261
	 * @deprecated  2.0  Instantiate a new Registry instance instead
262
	 */
263
	public static function getInstance($id)
264
	{
265
		if (empty(self::$instances[$id]))
0 ignored issues
show
Deprecated Code introduced by
The property Joomla\Registry\Registry::$instances has been deprecated with message: 2.0 Object caching will no longer be supported

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
266
		{
267
			self::$instances[$id] = new self;
0 ignored issues
show
Deprecated Code introduced by
The property Joomla\Registry\Registry::$instances has been deprecated with message: 2.0 Object caching will no longer be supported

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
268
		}
269
270
		return self::$instances[$id];
0 ignored issues
show
Deprecated Code introduced by
The property Joomla\Registry\Registry::$instances has been deprecated with message: 2.0 Object caching will no longer be supported

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
271
	}
272
273
	/**
274
	 * Gets this object represented as an ArrayIterator.
275
	 *
276
	 * This allows the data properties to be accessed via a foreach statement.
277
	 *
278
	 * @return  \ArrayIterator  This object represented as an ArrayIterator.
279
	 *
280
	 * @see     IteratorAggregate::getIterator()
281
	 * @since   1.3.0
282
	 */
283
	public function getIterator()
284
	{
285
		return new \ArrayIterator($this->data);
286
	}
287
288
	/**
289
	 * Load an associative array of values into the default namespace
290
	 *
291
	 * @param   array    $array      Associative array of value to load
292
	 * @param   boolean  $flattened  Load from a one-dimensional array
293
	 * @param   string   $separator  The key separator
294
	 *
295
	 * @return  Registry  Return this object to support chaining.
296
	 *
297
	 * @since   1.0
298
	 */
299
	public function loadArray($array, $flattened = false, $separator = null)
300
	{
301
		if (!$flattened)
302
		{
303
			$this->bindData($this->data, $array);
304
305
			return $this;
306
		}
307
308
		foreach ($array as $k => $v)
309
		{
310
			$this->set($k, $v, $separator);
311
		}
312
313
		return $this;
314
	}
315
316
	/**
317
	 * Load the public variables of the object into the default namespace.
318
	 *
319
	 * @param   object  $object  The object holding the publics to load
320
	 *
321
	 * @return  Registry  Return this object to support chaining.
322
	 *
323
	 * @since   1.0
324
	 */
325
	public function loadObject($object)
326
	{
327
		$this->bindData($this->data, $object);
328
329
		return $this;
330
	}
331
332
	/**
333
	 * Load the contents of a file into the registry
334
	 *
335
	 * @param   string  $file     Path to file to load
336
	 * @param   string  $format   Format of the file [optional: defaults to JSON]
337
	 * @param   array   $options  Options used by the formatter
338
	 *
339
	 * @return  Registry  Return this object to support chaining.
340
	 *
341
	 * @since   1.0
342
	 */
343
	public function loadFile($file, $format = 'JSON', $options = array())
344
	{
345
		$data = file_get_contents($file);
346
347
		return $this->loadString($data, $format, $options);
348
	}
349
350
	/**
351
	 * Load a string into the registry
352
	 *
353
	 * @param   string  $data     String to load into the registry
354
	 * @param   string  $format   Format of the string
355
	 * @param   array   $options  Options used by the formatter
356
	 *
357
	 * @return  Registry  Return this object to support chaining.
358
	 *
359
	 * @since   1.0
360
	 */
361
	public function loadString($data, $format = 'JSON', $options = array())
362
	{
363
		// Load a string into the given namespace [or default namespace if not given]
364
		$handler = AbstractRegistryFormat::getInstance($format, $options);
0 ignored issues
show
Deprecated Code introduced by
The method Joomla\Registry\Abstract...ryFormat::getInstance() has been deprecated with message: 2.0 Use Factory::getFormat() instead

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
365
366
		$obj = $handler->stringToObject($data, $options);
367
368
		// If the data object has not yet been initialized, direct assign the object
369
		if (!$this->initialized)
370
		{
371
			$this->data        = $obj;
372
			$this->initialized = true;
373
374
			return $this;
375
		}
376
377
		$this->loadObject($obj);
378
379
		return $this;
380
	}
381
382
	/**
383
	 * Merge a Registry object into this one
384
	 *
385
	 * @param   Registry  $source     Source Registry object to merge.
386
	 * @param   boolean   $recursive  True to support recursive merge the children values.
387
	 *
388
	 * @return  Registry  Return this object to support chaining.
389
	 *
390
	 * @since   1.0
391
	 */
392
	public function merge($source, $recursive = false)
393
	{
394
		if (!$source instanceof Registry)
395
		{
396
			return false;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return false; (false) is incompatible with the return type documented by Joomla\Registry\Registry::merge of type Joomla\Registry\Registry.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
397
		}
398
399
		$this->bindData($this->data, $source->toArray(), $recursive, false);
400
401
		return $this;
402
	}
403
404
	/**
405
	 * Method to extract a sub-registry from path
406
	 *
407
	 * @param   string  $path  Registry path (e.g. joomla.content.showauthor)
408
	 *
409
	 * @return  Registry|null  Registry object if data is present
410
	 *
411
	 * @since   1.2.0
412
	 */
413
	public function extract($path)
414
	{
415
		$data = $this->get($path);
416
417
		if (is_null($data))
418
		{
419
			return null;
420
		}
421
422
		return new Registry($data);
423
	}
424
425
	/**
426
	 * Checks whether an offset exists in the iterator.
427
	 *
428
	 * @param   mixed  $offset  The array offset.
429
	 *
430
	 * @return  boolean  True if the offset exists, false otherwise.
431
	 *
432
	 * @since   1.0
433
	 */
434
	public function offsetExists($offset)
435
	{
436
		return (boolean) ($this->get($offset) !== null);
437
	}
438
439
	/**
440
	 * Gets an offset in the iterator.
441
	 *
442
	 * @param   mixed  $offset  The array offset.
443
	 *
444
	 * @return  mixed  The array value if it exists, null otherwise.
445
	 *
446
	 * @since   1.0
447
	 */
448
	public function offsetGet($offset)
449
	{
450
		return $this->get($offset);
451
	}
452
453
	/**
454
	 * Sets an offset in the iterator.
455
	 *
456
	 * @param   mixed  $offset  The array offset.
457
	 * @param   mixed  $value   The array value.
458
	 *
459
	 * @return  void
460
	 *
461
	 * @since   1.0
462
	 */
463
	public function offsetSet($offset, $value)
464
	{
465
		$this->set($offset, $value);
466
	}
467
468
	/**
469
	 * Unsets an offset in the iterator.
470
	 *
471
	 * @param   mixed  $offset  The array offset.
472
	 *
473
	 * @return  void
474
	 *
475
	 * @since   1.0
476
	 */
477
	public function offsetUnset($offset)
478
	{
479
		$this->set($offset, null);
480
	}
481
482
	/**
483
	 * Set a registry value.
484
	 *
485
	 * @param   string  $path       Registry Path (e.g. joomla.content.showauthor)
486
	 * @param   mixed   $value      Value of entry
487
	 * @param   string  $separator  The key separator
488
	 *
489
	 * @return  mixed  The value of the that has been set.
490
	 *
491
	 * @since   1.0
492
	 */
493
	public function set($path, $value, $separator = null)
494
	{
495
		if (empty($separator))
496
		{
497
			$separator = $this->separator;
498
		}
499
500
		/**
501
		 * Explode the registry path into an array and remove empty
502
		 * nodes that occur as a result of a double separator. ex: joomla..test
503
		 * Finally, re-key the array so they are sequential.
504
		 */
505
		$nodes = array_values(array_filter(explode($separator, $path), 'strlen'));
506
507
		if (!$nodes)
0 ignored issues
show
Bug Best Practice introduced by
The expression $nodes of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
508
		{
509
			return null;
510
		}
511
512
		// Initialize the current node to be the registry root.
513
		$node = $this->data;
514
515
		// Traverse the registry to find the correct node for the result.
516 View Code Duplication
		for ($i = 0, $n = count($nodes) - 1; $i < $n; $i++)
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
517
		{
518
			if (is_object($node))
519
			{
520
				if (!isset($node->{$nodes[$i]}) && ($i != $n))
521
				{
522
					$node->{$nodes[$i]} = new \stdClass;
523
				}
524
525
				// Pass the child as pointer in case it is an object
526
				$node = &$node->{$nodes[$i]};
527
528
				continue;
529
			}
530
531
			if (is_array($node))
532
			{
533
				if (!isset($node[$nodes[$i]]) && ($i != $n))
534
				{
535
					$node[$nodes[$i]] = new \stdClass;
536
				}
537
538
				// Pass the child as pointer in case it is an array
539
				$node = &$node[$nodes[$i]];
540
			}
541
		}
542
543
		// Get the old value if exists so we can return it
544
		switch (true)
545
		{
546
			case (is_object($node)):
547
				$result = $node->{$nodes[$i]} = $value;
548
				break;
549
550
			case (is_array($node)):
551
				$result = $node[$nodes[$i]] = $value;
552
				break;
553
554
			default:
555
				$result = null;
556
				break;
557
		}
558
559
		return $result;
560
	}
561
562
	/**
563
	 * Append value to a path in registry
564
	 *
565
	 * @param   string  $path   Parent registry Path (e.g. joomla.content.showauthor)
566
	 * @param   mixed   $value  Value of entry
567
	 *
568
	 * @return  mixed  The value of the that has been set.
569
	 *
570
	 * @since   1.4.0
571
	 */
572
	public function append($path, $value)
573
	{
574
		$result = null;
575
576
		/**
577
		 * Explode the registry path into an array and remove empty
578
		 * nodes that occur as a result of a double dot. ex: joomla..test
579
		 * Finally, re-key the array so they are sequential.
580
		 */
581
		$nodes = array_values(array_filter(explode('.', $path), 'strlen'));
582
583
		if ($nodes)
0 ignored issues
show
Bug Best Practice introduced by
The expression $nodes of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
584
		{
585
			// Initialize the current node to be the registry root.
586
			$node = $this->data;
587
588
			// Traverse the registry to find the correct node for the result.
589
			// TODO Create a new private method from part of code below, as it is almost equal to 'set' method
590 View Code Duplication
			for ($i = 0, $n = count($nodes) - 1; $i <= $n; $i++)
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
591
			{
592
				if (is_object($node))
593
				{
594
					if (!isset($node->{$nodes[$i]}) && ($i != $n))
595
					{
596
						$node->{$nodes[$i]} = new \stdClass;
597
					}
598
599
					// Pass the child as pointer in case it is an array
600
					$node = &$node->{$nodes[$i]};
601
				}
602
				elseif (is_array($node))
603
				{
604
					if (!isset($node[$nodes[$i]]) && ($i != $n))
605
					{
606
						$node[$nodes[$i]] = new \stdClass;
607
					}
608
609
					// Pass the child as pointer in case it is an array
610
					$node = &$node[$nodes[$i]];
611
				}
612
			}
613
614
			if (!is_array($node))
615
			// Convert the node to array to make append possible
616
			{
617
				$node = get_object_vars($node);
618
			}
619
620
			array_push($node, $value);
621
			$result = $value;
622
		}
623
624
		return $result;
625
	}
626
627
	/**
628
	 * Transforms a namespace to an array
629
	 *
630
	 * @return  array  An associative array holding the namespace data
631
	 *
632
	 * @since   1.0
633
	 */
634
	public function toArray()
635
	{
636
		return (array) $this->asArray($this->data);
637
	}
638
639
	/**
640
	 * Transforms a namespace to an object
641
	 *
642
	 * @return  object   An an object holding the namespace data
643
	 *
644
	 * @since   1.0
645
	 */
646
	public function toObject()
647
	{
648
		return $this->data;
649
	}
650
651
	/**
652
	 * Get a namespace in a given string format
653
	 *
654
	 * @param   string  $format   Format to return the string in
655
	 * @param   mixed   $options  Parameters used by the formatter, see formatters for more info
656
	 *
657
	 * @return  string   Namespace in string format
658
	 *
659
	 * @since   1.0
660
	 */
661
	public function toString($format = 'JSON', $options = array())
662
	{
663
		// Return a namespace in a given format
664
		$handler = AbstractRegistryFormat::getInstance($format, $options);
0 ignored issues
show
Deprecated Code introduced by
The method Joomla\Registry\Abstract...ryFormat::getInstance() has been deprecated with message: 2.0 Use Factory::getFormat() instead

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
665
666
		return $handler->objectToString($this->data, $options);
667
	}
668
669
	/**
670
	 * Method to recursively bind data to a parent object.
671
	 *
672
	 * @param   object   $parent     The parent object on which to attach the data values.
673
	 * @param   mixed    $data       An array or object of data to bind to the parent object.
674
	 * @param   boolean  $recursive  True to support recursive bindData.
675
	 * @param   boolean  $allowNull  True to allow null values.
676
	 *
677
	 * @return  void
678
	 *
679
	 * @since   1.0
680
	 */
681
	protected function bindData($parent, $data, $recursive = true, $allowNull = true)
682
	{
683
		// The data object is now initialized
684
		$this->initialized = true;
685
686
		// Ensure the input data is an array.
687
		$data = is_object($data)
688
			? get_object_vars($data)
689
			: (array) $data;
690
691
		foreach ($data as $k => $v)
692
		{
693
			if (!$allowNull && !(($v !== null) && ($v !== '')))
694
			{
695
				continue;
696
			}
697
698
			if ($recursive && ((is_array($v) && ArrayHelper::isAssociative($v)) || is_object($v)))
699
			{
700
				if (!isset($parent->$k))
701
				{
702
					$parent->$k = new \stdClass;
703
				}
704
705
				$this->bindData($parent->$k, $v);
706
707
				continue;
708
			}
709
710
			$parent->$k = $v;
711
		}
712
	}
713
714
	/**
715
	 * Method to recursively convert an object of data to an array.
716
	 *
717
	 * @param   object  $data  An object of data to return as an array.
718
	 *
719
	 * @return  array  Array representation of the input object.
720
	 *
721
	 * @since   1.0
722
	 */
723
	protected function asArray($data)
724
	{
725
		$array = array();
726
727
		if (is_object($data))
728
		{
729
			$data = get_object_vars($data);
730
		}
731
732
		foreach ($data as $k => $v)
733
		{
734
			if (is_object($v) || is_array($v))
735
			{
736
				$array[$k] = $this->asArray($v);
0 ignored issues
show
Bug introduced by
It seems like $v can also be of type array; however, Joomla\Registry\Registry::asArray() does only seem to accept object, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
737
738
				continue;
739
			}
740
741
			$array[$k] = $v;
742
		}
743
744
		return $array;
745
	}
746
747
	/**
748
	 * Dump to one dimension array.
749
	 *
750
	 * @param   string  $separator  The key separator.
751
	 *
752
	 * @return  string[]  Dumped array.
753
	 *
754
	 * @since   1.3.0
755
	 */
756
	public function flatten($separator = null)
757
	{
758
		$array = array();
759
760
		if (empty($separator))
761
		{
762
			$separator = $this->separator;
763
		}
764
765
		$this->toFlatten($separator, $this->data, $array);
766
767
		return $array;
768
	}
769
770
	/**
771
	 * Method to recursively convert data to one dimension array.
772
	 *
773
	 * @param   string        $separator  The key separator.
774
	 * @param   array|object  $data       Data source of this scope.
775
	 * @param   array         &$array     The result array, it is pass by reference.
776
	 * @param   string        $prefix     Last level key prefix.
777
	 *
778
	 * @return  void
779
	 *
780
	 * @since   1.3.0
781
	 */
782
	protected function toFlatten($separator = null, $data = null, &$array = array(), $prefix = '')
783
	{
784
		$data = (array) $data;
785
786
		if (empty($separator))
787
		{
788
			$separator = $this->separator;
789
		}
790
791
		foreach ($data as $k => $v)
792
		{
793
			$key = $prefix ? $prefix . $separator . $k : $k;
794
795
			if (is_object($v) || is_array($v))
796
			{
797
				$this->toFlatten($separator, $v, $array, $key);
798
799
				continue;
800
			}
801
802
			$array[$key] = $v;
803
		}
804
	}
805
}
806