1
|
|
|
<?php |
2
|
|
|
/* |
3
|
|
|
* This file is part of the Borobudur-Cqrs package. |
4
|
|
|
* |
5
|
|
|
* (c) Hexacodelabs <http://hexacodelabs.com> |
6
|
|
|
* |
7
|
|
|
* For the full copyright and license information, please view the LICENSE |
8
|
|
|
* file that was distributed with this source code. |
9
|
|
|
*/ |
10
|
|
|
|
11
|
|
|
namespace Borobudur\Cqrs; |
12
|
|
|
|
13
|
|
|
use Borobudur\Collection\Collection as BaseCollection; |
14
|
|
|
use Borobudur\Collection\Criteria; |
15
|
|
|
use Borobudur\Cqrs\Exception\InvalidArgumentException; |
16
|
|
|
use Borobudur\Cqrs\ReadModel\ReadModelInterface; |
17
|
|
|
use Borobudur\Cqrs\ReadModel\Storage\Finder\Pagination; |
18
|
|
|
use Borobudur\Serialization\SerializableInterface; |
19
|
|
|
use Closure; |
20
|
|
|
|
21
|
|
|
/** |
22
|
|
|
* @author Iqbal Maulana <[email protected]> |
23
|
|
|
* @created 8/20/15 |
24
|
|
|
*/ |
25
|
|
|
class Collection extends BaseCollection |
26
|
|
|
{ |
27
|
|
|
/** |
28
|
|
|
* @var string|null |
29
|
|
|
*/ |
30
|
|
|
private $classMapper; |
31
|
|
|
|
32
|
|
|
/** |
33
|
|
|
* @var Pagination |
34
|
|
|
*/ |
35
|
|
|
private $pagination; |
36
|
|
|
|
37
|
|
|
/** |
38
|
|
|
* Constructor. |
39
|
|
|
* |
40
|
|
|
* @param array $elements |
41
|
|
|
* @param string|null $classMapper |
42
|
|
|
*/ |
43
|
|
|
public function __construct(array $elements = array(), $classMapper = null) |
44
|
|
|
{ |
45
|
|
|
$this->assertValidClassMapper($classMapper); |
46
|
|
|
$this->classMapper = $classMapper; |
47
|
|
|
|
48
|
|
|
parent::__construct($elements); |
49
|
|
|
} |
50
|
|
|
|
51
|
|
|
/** |
52
|
|
|
* Find collection by id. |
53
|
|
|
* |
54
|
|
|
* @param mixed $id |
55
|
|
|
* |
56
|
|
|
* @return ReadModelInterface |
57
|
|
|
*/ |
58
|
|
|
public function findById($id) |
59
|
|
|
{ |
60
|
|
|
$collection = $this->matching(Criteria::create()->where( |
61
|
|
|
Criteria::expr()->equal('id', $id) |
62
|
|
|
)); |
63
|
|
|
|
64
|
|
|
return $collection->first(); |
65
|
|
|
} |
66
|
|
|
|
67
|
|
|
/** |
68
|
|
|
* {@inheritdoc} |
69
|
|
|
*/ |
70
|
|
|
public function filter(Closure $p) |
71
|
|
|
{ |
72
|
|
|
return new static(array_filter($this->elements, $p), $this->classMapper); |
73
|
|
|
} |
74
|
|
|
|
75
|
|
|
/** |
76
|
|
|
* {@inheritdoc} |
77
|
|
|
*/ |
78
|
|
|
public function map(Closure $p) |
79
|
|
|
{ |
80
|
|
|
return new static(array_map($p, $this->elements), $this->classMapper); |
81
|
|
|
} |
82
|
|
|
|
83
|
|
|
/** |
84
|
|
|
* {@inheritdoc} |
85
|
|
|
*/ |
86
|
|
|
public function set($key, $value) |
87
|
|
|
{ |
88
|
|
|
if (null !== $this->classMapper && false === is_object($value)) { |
89
|
|
|
$class = $this->classMapper; |
90
|
|
|
$value = $class::{'deserialize'}($value); |
91
|
|
|
} |
92
|
|
|
|
93
|
|
|
parent::set($key, $value); |
94
|
|
|
} |
95
|
|
|
|
96
|
|
|
/** |
97
|
|
|
* @param Pagination $pagination |
98
|
|
|
*/ |
99
|
|
|
public function setPagination(Pagination $pagination) |
100
|
|
|
{ |
101
|
|
|
$this->pagination = $pagination; |
102
|
|
|
} |
103
|
|
|
|
104
|
|
|
/** |
105
|
|
|
* @return Pagination |
106
|
|
|
*/ |
107
|
|
|
public function getPagination() |
108
|
|
|
{ |
109
|
|
|
return $this->pagination; |
110
|
|
|
} |
111
|
|
|
|
112
|
|
|
/** |
113
|
|
|
* {@inheritdoc} |
114
|
|
|
*/ |
115
|
|
|
public function getFieldValues($field = null) |
116
|
|
|
{ |
117
|
|
|
$fields = func_get_args(); |
118
|
|
|
$elements = array(); |
119
|
|
|
if ($fields || (isset($this->elements[0]) && is_array($this->elements[0]))) { |
120
|
|
|
$this->each(function ($element) use (&$elements, $fields) { |
121
|
|
|
if (is_object($element)) { |
122
|
|
|
if ($fields) { |
123
|
|
|
foreach ($fields as $field) { |
124
|
|
|
$methodGet = 'get' . ucfirst($field); |
125
|
|
|
$methodIs = 'is' . ucfirst($field); |
126
|
|
|
|
127
|
|
|
if (method_exists($element, $methodGet)) { |
128
|
|
|
$elements[] = $element->{$methodGet}(); |
129
|
|
|
} elseif (method_exists($element, $methodIs)) { |
130
|
|
|
$elements[] = $element->{$methodIs}(); |
131
|
|
|
} elseif (property_exists($element, $field)) { |
132
|
|
|
$elements[] = $element->{$field}; |
133
|
|
|
} |
134
|
|
|
} |
135
|
|
|
} |
136
|
|
|
|
137
|
|
|
return; |
138
|
|
|
} |
139
|
|
|
|
140
|
|
|
if (is_array($element)) { |
141
|
|
|
if ($fields) { |
|
|
|
|
142
|
|
|
foreach ($fields as $field) { |
143
|
|
|
if (array_key_exists($field, $element)) { |
144
|
|
|
$elements[] = $element[$field]; |
145
|
|
|
} |
146
|
|
|
} |
147
|
|
|
} else { |
148
|
|
|
$elements = array_merge($elements, array_values($element)); |
149
|
|
|
} |
150
|
|
|
} |
151
|
|
|
}); |
152
|
|
|
|
153
|
|
|
return $elements; |
154
|
|
|
} |
155
|
|
|
|
156
|
|
|
return array(); |
157
|
|
|
} |
158
|
|
|
|
159
|
|
|
/** |
160
|
|
|
* {@inheritdoc} |
161
|
|
|
*/ |
162
|
|
|
public function toArray($resortIndex = false) |
163
|
|
|
{ |
164
|
|
|
$elements = parent::toArray($resortIndex); |
165
|
|
|
|
166
|
|
|
if (null !== $this->classMapper) { |
167
|
|
|
return array_map(function (SerializableInterface $element) { |
168
|
|
|
return $element->serialize(); |
169
|
|
|
}, (array) $elements); |
170
|
|
|
} |
171
|
|
|
|
172
|
|
|
return $elements; |
173
|
|
|
} |
174
|
|
|
|
175
|
|
|
/** |
176
|
|
|
* Assert that class mapper should be exists and can be deserialize. |
177
|
|
|
* |
178
|
|
|
* @param string $classMapper |
179
|
|
|
* |
180
|
|
|
* @throws InvalidArgumentException |
181
|
|
|
*/ |
182
|
|
|
private function assertValidClassMapper($classMapper) |
183
|
|
|
{ |
184
|
|
|
if (null !== $classMapper) { |
185
|
|
|
$classMapper = '\\' . ltrim($classMapper, '\\'); |
186
|
|
|
if (!class_exists($classMapper)) { |
187
|
|
|
throw new InvalidArgumentException(sprintf('Class "%s" is undefined.', $classMapper)); |
188
|
|
|
} |
189
|
|
|
|
190
|
|
|
if (!in_array('Borobudur\Serialization\SerializableInterface', class_implements($classMapper))) { |
191
|
|
|
throw new InvalidArgumentException(sprintf( |
192
|
|
|
'Class "%s" should implement \Borobudur\Serialization\SerializableInterface', |
193
|
|
|
$classMapper |
194
|
|
|
)); |
195
|
|
|
} |
196
|
|
|
|
197
|
|
|
if (!in_array('Borobudur\Serialization\DeserializableInterface', class_implements($classMapper))) { |
198
|
|
|
throw new InvalidArgumentException(sprintf( |
199
|
|
|
'Class "%s" should implement \Borobudur\Serialization\DeserializableInterface', |
200
|
|
|
$classMapper |
201
|
|
|
)); |
202
|
|
|
} |
203
|
|
|
} |
204
|
|
|
} |
205
|
|
|
} |
206
|
|
|
|
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.