1) { $f = []; foreach ($or_filters as $of) { //single filter if(empty($of)) continue; list($field, $op, $value) = self::filterExpresion($of); if (!isset($allowed_fields[$field])){ throw new FilterParserException(sprintf("filter by field %s is not allowed", $field)); } if (!in_array($op, $allowed_fields[$field])){ throw new FilterParserException(sprintf("%s op is not allowed for filter by field %s",$op, $field)); } // check if value has AND or OR values on same field $same_field_op = null; if(str_contains($value, '&&')){ $values = explode('&&', $value); if (count($values) > 1) { $value = $values; $same_field_op = 'AND'; } } else if(str_contains($value, '||')){ $values = explode('||', $value); if (count($values) > 1) { $value = $values; $same_field_op = 'OR'; } } $f_or = self::buildFilter($field, $op, $value, $same_field_op); if (!is_null($f_or)) $f[] = $f_or; } } else { //single filter list($field, $op, $value) = self::filterExpresion($filter); // check if value has AND or OR values on same field $same_field_op = null; if(str_contains($value, '&&')){ $values = explode('&&', $value); if (count($values) > 1) { $value = $values; $same_field_op = 'AND'; } } else if(str_contains($value, '||')){ $values = explode('||', $value); if (count($values) > 1) { $value = $values; $same_field_op = 'OR'; } } if (!isset($allowed_fields[$field])){ throw new FilterParserException(sprintf("filter by field %s is not allowed", $field)); } if (!in_array($op, $allowed_fields[$field])){ throw new FilterParserException(sprintf("%s op is not allowed for filter by field %s",$op, $field)); } $f = self::buildFilter($field, $op, $value, $same_field_op); } if (!is_null($f)) $res[] = $f; } return new Filter($res); } /** * @param string $exp * @return array * @throws FilterParserException */ public static function filterExpresion(string $exp){ preg_match('/[=<>][=>@]{0,1}/', $exp, $matches); if (count($matches) != 1) throw new FilterParserException(sprintf("invalid OR filter format %s (should be [:FIELD_NAME:OPERAND:VALUE])", $exp)); $op = $matches[0]; $operands = explode($op, $exp, 2); $field = $operands[0]; $value = $operands[1]; return [$field, $op, $value]; } /** * Factory Method * * @param string $field * @param string $op * @param mixed $value * @param string $same_field_op * @return FilterElement|null */ public static function buildFilter($field, $op, $value, $same_field_op = null ) { switch ($op) { case '==': return FilterElement::makeEqual($field, $value, $same_field_op); break; case '=@': return FilterElement::makeLike($field, $value, $same_field_op); break; case '>': return FilterElement::makeGreather($field, $value, $same_field_op); break; case '>=': return FilterElement::makeGreatherOrEqual($field, $value, $same_field_op); break; case '<': return FilterElement::makeLower($field, $value, $same_field_op); break; case '<=': return FilterElement::makeLowerOrEqual($field, $value, $same_field_op); break; case '<>': return FilterElement::makeNotEqual($field, $value, $same_field_op); break; } return null; } }