-
Notifications
You must be signed in to change notification settings - Fork 13
Expand file tree
/
Copy pathProcessor.php
More file actions
126 lines (107 loc) · 3.74 KB
/
Copy pathProcessor.php
File metadata and controls
126 lines (107 loc) · 3.74 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
<?php
namespace ProcessMaker\Query;
class Processor
{
protected $tree;
protected $callback;
public function __construct($tree, $callback = null)
{
$this->tree = $tree;
$this->callback = $callback;
}
public function process($builder)
{
$method = $this->tree->logicalMethod();
return $builder->$method($this->processCollection($this->tree));
}
// Perform a Post-Order LRN tree traversal to build query
// See: https://en.wikipedia.org/wiki/Tree_traversal#Post-order_(LRN)
private function processCollection($collection)
{
return function ($builder) use ($collection) {
foreach ($collection as $expression) {
$method = $expression->logicalMethod();
if (is_a($expression, ExpressionCollection::class)) {
$builder->$method($this->processCollection($expression));
} else {
if ($this->callback) {
$func = ($this->callback)($expression);
if (is_callable($func)) {
$builder->$method(($this->callback)($expression));
} else {
$this->addToBuilder($builder, $method, $expression);
}
} else {
$this->addToBuilder($builder, $method, $expression);
}
}
}
return $builder;
};
}
private function addToBuilder(&$builder, $method, $expression)
{
if ($expression->value instanceof ArrayValue) {
$method = $expression->operator === Expression::OPERATOR_IN ? 'whereIn' : 'whereNotIn';
$builder->$method(
$expression->field->toEloquent(),
$expression->value->toEloquent()
);
} else {
$builder->$method(
$expression->field->toEloquent(),
$expression->operator,
$expression->value->toEloquent()
);
}
}
public static function append($arr, $x)
{
$arr[] = $x;
return $arr;
}
public static function isAssoc(array $arr)
{
if ([] === $arr) {
return false;
}
return array_keys($arr) !== range(0, count($arr) - 1);
}
public static function flatten($x, $rejectSpace = false, $acc = [])
{
// We're going to check for various types of $x and handle them differently
// Null?
if ($x == null) {
if (!$rejectSpace) {
// We want to keep the whitespace/null, so append x to acc
return self::append($acc, $x);
}
return $acc;
}
// Associative array?
if (is_array($x) && self::isAssoc($x)) {
return self::append($acc, $x);
}
// Is it an empty array, or is a string with nothing but whitespace and we're rejecting?
if ($rejectSpace && (
(is_string($x) && preg_match('/^\s*$/', $x)) || (is_array($x) && count($x) == 0))) {
return $acc;
}
// Is it a string? If so, just append
if (is_string($x)) {
return self::append($acc, $x);
}
// Is it a numeric array? Let's just flatten
for ($i = 0; $i < count($x); $i++) {
$acc = self::flatten($x[$i], $rejectSpace, $acc);
}
return $acc;
}
public static function flatstr($x, $rejectSpace = false, $joinChar = '')
{
$filtered = array_filter(self::flatten($x, $rejectSpace, []), function ($item) {
return is_string($item) ? true : false;
});
return implode($joinChar, $filtered);
}
}