_expressions = $expressions; } public function getPrefix(array $scopes): ?int { return ($this->matches($scopes)) ? $this->_expressions[0]->getPrefix($scopes) : null; } public function matches(array $scopes): bool { $result = false; foreach ($this->_expressions as $expression) { $operator = $expression->operator; if ($result && $operator === Expression::OPERATOR_OR) { continue; } elseif (!$result && $operator === Expression::OPERATOR_AND) { continue; } elseif (!$result && $operator === Expression::OPERATOR_NOT) { continue; } $local = $expression->matches($scopes); switch ($operator) { case Expression::OPERATOR_NONE: $result = $local; break; case Expression::OPERATOR_OR: $result = $result || $local; break; case Expression::OPERATOR_AND: $result = $result && $local; break; case Expression::OPERATOR_NOT: $result = $result && !$local; break; } } return $result; } public function __toString(): string { return implode(' ', $this->_expressions); } }