reader = $reader; $this->condition = $condition; } public function current(): mixed { return $this->reader->current(); } public function key(): mixed { return $this->reader->key(); } public function valid(): bool { return $this->reader->valid(); } public function next(): void { $this->reader->next(); while ($this->reader->valid()) { $curr = $this->reader->current(); if ($this->matchCondition($curr)) break; $this->reader->next(); } } public function rewind(): void { $this->reader->rewind(); while ($this->reader->valid()) { $curr = $this->reader->current(); if ($this->matchCondition($curr)) break; $this->reader->next(); } } /** * Test a condition against a row * * The matched conditions are: * - string/bool/int/float - match value * - array - all conditions in array must match: * - eq equals * - neq not equals * - gt greater than * - gte greater than or equal * - lt less than * - in value in array * - nin value not in array */ private function matchCondition(array $row): bool { if (is_callable($this->condition)) { return (bool)call_user_func($this->condition, $row); } foreach ($this->condition as $field=>$test) { if (!array_key_exists($field, $row)) continue; if (is_array($test)) { if (array_key_exists('eq',$test) && $row[$field] != $test['eq']) return false; if (array_key_exists('neq',$test) && $row[$field] == $test['neq']) return false; if (array_key_exists('gt',$test) && $row[$field] <= $test['gt']) return false; if (array_key_exists('gte',$test) && $row[$field] < $test['gte']) return false; if (array_key_exists('lt',$test) && $row[$field] >= $test['lt']) return false; if (array_key_exists('lte',$test) && $row[$field] > $test['lte']) return false; if (array_key_exists('in',$test) && !in_array($row[$field], $test['in'])) return false; if (array_key_exists('nin',$test) && in_array($row[$field], $test['in'])) return false; } else { if ($row[$field] != $test) return false; } } return true; } }