Passed
Push — master ( f6b4a1...5217eb )
by Cristiano
10:27
created

src/collection/CollectionUtils.php (1 issue)

Severity
1
<?php declare(strict_types=1);
2
/**
3
 * This file is part of the Phootwork package.
4
 * For the full copyright and license information, please view the LICENSE
5
 * file that was distributed with this source code.
6
 *
7
 * @license MIT License
8
 * @copyright Thomas Gossmann
9
 */
10
namespace phootwork\collection;
11
12
use Iterator;
13
use stdClass;
14
15
/**
16
 * CollectionUtils help to transform data recursively into collections.
17
 *
18
 * It must be mentioned the API is experimental and may change. Please
19
 * report to the issue tracker.
20
 */
21
class CollectionUtils {
22
	/**
23
	 * Returns a proper collection for the given array (also transforms nested collections)
24
	 * (experimental API)
25
	 *
26
	 * @param array|Iterator $collection
27
	 *
28
	 * @return Map|ArrayList the collection
29
	 *
30
	 * @psalm-suppress MixedReturnStatement `self::toCollection()` returns a collection if the input
31
	 *                                      is an array or Iterator
32
	 * @psalm-suppress MixedInferredReturnType
33
	 */
34 8
	public static function fromCollection(array|Iterator $collection): Map|ArrayList {
35 8
		return self::toCollection($collection);
36
	}
37
38
	/**
39
	 * @param mixed $data
40
	 *
41
	 * @return mixed
42
	 */
43 13
	private static function toCollection(mixed $data): mixed {
44
		// prepare normal array
45 13
		if (!($data instanceof Iterator)) {
46
			/** @var mixed $data */
47 13
			$data = json_decode(json_encode($data));
48
		}
49
50
		// check if we can transform it into a collection or just return as is
51 13
		if (!(is_array($data) || $data instanceof Iterator || $data instanceof stdClass)) {
52 13
			return $data;
53
		}
54
55
		// check we have a list
56 11
		if (is_array($data) || $data instanceof AbstractList) {
57 9
			return self::toList($data);
58
		}
59
60
		// everything else must be a map
61 8
		return self::toMap($data);
62
	}
63
64
	/**
65
	 * Recursively transforms data into a map (on the first level, deeper levels
66
	 * transformed to an appropriate collection) (experimental API)
67
	 *
68
	 * @param array|Iterator|stdClass $collection
69
	 *
70
	 * @return Map
71
	 */
72 10
	public static function toMap(Iterator|array|stdClass $collection): Map {
73 10
		if ($collection instanceof stdClass) {
0 ignored issues
show
$collection is never a sub-type of stdClass.
Loading history...
74
			/** @var array $collection */
75 7
			$collection = json_decode(json_encode($collection), true);
76
		}
77
78 10
		$map = new Map();
79
		/**
80
		 * @var string $k
81
		 * @var string $v
82
		 */
83 10
		foreach ($collection as $k => $v) {
84 10
			$map->set($k, self::toCollection($v));
85
		}
86
87 10
		return $map;
88
	}
89
90
	/**
91
	 * Recursively transforms data into a list (on the first level, deeper levels
92
	 * transformed to an appropriate collection) (experimental API)
93
	 *
94
	 * @param array|Iterator $collection
95
	 *
96
	 * @return ArrayList
97
	 */
98 10
	public static function toList(Iterator|array $collection): ArrayList {
99 10
		$list = new ArrayList();
100
		/** @var mixed $v */
101 10
		foreach ($collection as $v) {
102 10
			$list->add(self::toCollection($v));
103
		}
104
105 10
		return $list;
106
	}
107
108
	/**
109
	 * Recursively exports a collection to an array
110
	 *
111
	 * @param mixed $collection
112
	 *
113
	 * @return array
114
	 *
115
	 * @psalm-suppress MixedAssignment
116
	 */
117 2
	public static function toArrayRecursive(mixed $collection): array {
118 2
		$arr = $collection;
119 2
		if (is_object($collection) && method_exists($collection, 'toArray')) {
120 2
			$arr = $collection->toArray();
121
		}
122
123
		/** @var array $arr */
124 2
		return array_map(
125 2
			function (mixed $v): mixed {
126 2
				if (is_object($v) && method_exists($v, 'toArray')) {
127 2
					return static::toArrayRecursive($v);
128
				}
129
130 2
				return $v;
131 2
			},
132 2
			$arr
133 2
		);
134
	}
135
}
136