protected function filter($documents, $predicates)
{
$result = array();
$originalDocs = $documents;
$andPredicates = array_filter($predicates, function ($pred) {
return $pred[0] !== Predicate::LOGICAL_OR;
});
$orPredicates = array_filter($predicates, function ($pred) {
return $pred[0] === Predicate::LOGICAL_OR;
});
// 5.3 hack for accessing $this inside closure.
$self = $this;
foreach ($andPredicates as $predicate) {
if (is_array($predicate[1])) {
$documents = $this->filter($documents, $predicate[1]);
} else {
list($type, $field, $operator, $value) = $predicate;
$documents = array_values(array_filter($documents, function ($doc) use($self, $field, $operator, $value) {
return $self->matchDocument($doc, $field, $operator, $value);
}));
}
$result = $documents;
}
foreach ($orPredicates as $predicate) {
if (is_array($predicate[1])) {
$documents = $this->filter($originalDocs, $predicate[1]);
} else {
list($type, $field, $operator, $value) = $predicate;
$documents = array_values(array_filter($originalDocs, function ($doc) use($self, $field, $operator, $value) {
return $self->matchDocument($doc, $field, $operator, $value);
}));
}
$result = array_unique(array_merge($result, $documents), SORT_REGULAR);
}
return $result;
}