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

DBExprFilter::recursiveGet()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 13
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 9
c 1
b 0
f 0
dl 0
loc 13
rs 9.9666
cc 4
nc 4
nop 3
1
<?php
2
namespace Kir\MySQL\Builder\Expr;
3
4
use Kir\MySQL\Builder\Helpers\RecursiveStructureAccess;
5
use RuntimeException;
6
7
class DBExprFilter implements OptionalExpression {
8
	/** @var mixed */
9
	private $expression;
10
	/** @var bool */
11
	private $hasValue;
12
	/** @var mixed */
13
	private $value;
14
	/** @var string[] */
15
	private $keyPath;
16
	/** @var null|callable(mixed): bool */
17
	private $validator;
18
	/** @var callable(bool, array{key: mixed, value: string}) */
19
	private $validationResultHandler;
20
21
	/**
22
	 * @param string $expression
23
	 * @param array<string, mixed> $data
24
	 * @param string|string[] $keyPath
25
	 * @param callable|null $validator
26
	 * @param callable|null $validationResultHandler
27
	 */
28
	public function __construct(string $expression, array $data, $keyPath, $validator = null, $validationResultHandler = null) {
29
		$this->expression = $expression;
30
		$this->keyPath = $this->buildKey($keyPath);
31
		$this->hasValue = RecursiveStructureAccess::recursiveHas($data, $this->keyPath);
32
		$this->value = RecursiveStructureAccess::recursiveGet($data, $this->keyPath, null);
33
		if($validator === null) {
34
			$validator = function() {
35
				return true;
36
			};
37
		}
38
		$this->validator = $validator;
39
		if($validationResultHandler === null) {
40
			$validationResultHandler = static function () {};
41
		}
42
		$this->validationResultHandler = $validationResultHandler;
43
	}
44
45
	/**
46
	 * @return string
47
	 */
48
	public function getExpression(): string {
49
		return $this->expression;
50
	}
51
52
	/**
53
	 * @return bool
54
	 */
55
	public function isValid(): bool {
56
		if(!$this->hasValue) {
57
			return false;
58
		}
59
		if($this->validator !== null) {
60
			$result = call_user_func($this->validator, $this->value);
61
			call_user_func($this->validationResultHandler, $result, [
62
				'value' => $this->value,
63
				'key' => implode('.', $this->keyPath),
64
			]);
65
			return $result;
66
		}
67
		return true;
68
	}
69
70
	/**
71
	 * @return array{mixed}
0 ignored issues
show
Documentation Bug introduced by
The doc comment array{mixed} at position 2 could not be parsed: Expected ':' at position 2, but found 'mixed'.
Loading history...
72
	 */
73
	public function getValue(): array {
74
		return [$this->value];
75
	}
76
77
	/**
78
	 * @param string|string[] $keyPath
79
	 * @return string[]
80
	 */
81
	private function buildKey($keyPath): array {
82
		if(is_string($keyPath)) {
83
			$keyPath = explode('.', $keyPath);
84
		}
85
		if(!is_array($keyPath)) {
0 ignored issues
show
introduced by
The condition is_array($keyPath) is always true.
Loading history...
86
			throw new RuntimeException('Invalid key');
87
		}
88
		return $keyPath;
89
	}
90
91
	/**
92
	 * @param array<string, mixed> $array
93
	 * @return bool
94
	 */
95
	private function isValidArray(array $array): bool {
96
		$data = array_filter($array, function ($value) {
97
			if(is_array($value)) {
98
				return $this->isValidArray($value);
99
			}
100
			return (string) $value !== '';
101
		});
102
		return count($data) > 0;
103
	}
104
}
105