Passed
Push — master ( f533bd...3986a9 )
by Ron
02:38
created

RecursiveStructureAccess::recursiveHas()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 2
c 1
b 0
f 0
dl 0
loc 3
rs 10
cc 1
nc 1
nop 2
1
<?php
2
3
namespace Kir\MySQL\Builder\Helpers;
4
5
use ArrayObject;
6
7
class RecursiveStructureAccess {
8
	/**
9
	 * @param object|array<string, mixed> $structure
10
	 * @param string|array<int, string> $path
11
	 * @return bool
12
	 */
13
	public static function recursiveHas($structure, $path): bool {
14
		$arrayPath = self::getArrayPath($path);
15
		return self::_recursiveHas($structure, $arrayPath);
16
	}
17
18
	/**
19
	 * @param object|array<string, mixed> $structure
20
	 * @param string|array<int, string> $path
21
	 * @param mixed $default
22
	 * @return mixed
23
	 */
24
	public static function recursiveGet($structure, $path, $default) {
25
		$arrayPath = self::getArrayPath($path);
26
		$data = self::ensureArrayIsArray($structure);
27
		$count = count($arrayPath ?? []);
28
		if (!$count) {
29
			return $default;
30
		}
31
		foreach($arrayPath as $idxValue) {
32
			$part = $idxValue;
33
			if(!array_key_exists($part, $data)) {
34
				return $default;
35
			}
36
			$data = $data[$part];
37
		}
38
		return $data;
39
	}
40
41
	/**
42
	 * @param mixed $structure
43
	 * @param array<int, string> $path
44
	 * @return bool
45
	 */
46
	private static function _recursiveHas($structure, array $path): bool {
47
		$data = self::ensureArrayIsArray($structure);
48
		if($data === null) {
49
			return false;
50
		}
51
		if(!count($path)) {
52
			return false;
53
		}
54
		$key = array_shift($path);
55
		if(count($path)) {
56
			return self::_recursiveHas($data[$key] ?? null, $path);
57
		}
58
		return array_key_exists($key, $data);
59
	}
60
61
	/**
62
	 * @param string|array<int, string> $path
63
	 * @return array<int, string>
64
	 */
65
	private static function getArrayPath($path): array {
66
		if(is_array($path)) {
67
			return $path;
68
		}
69
		$parts = preg_split('{(?<!\\x5C)(?:\\x5C\\x5C)*\\.}', $path);
70
		if($parts === false) {
71
			return [$path];
72
		}
73
		return $parts;
74
	}
75
76
	/**
77
	 * @param mixed $array
78
	 * @return array<mixed, mixed>
79
	 */
80
	private static function ensureArrayIsArray($array): ?array {
81
		if($array instanceof ArrayObject) {
82
			return $array->getArrayCopy();
83
		}
84
		if(is_object($array)) {
85
			return (array) $array;
86
		}
87
		if(is_array($array)) {
88
			return $array;
89
		}
90
		return null;
91
	}
92
}
93