src/ORM/Filters/ExactMatchFilter.php
protected function manyFilter(DataQuery $query, $inclusive)
    {
        $this->model = $query->applyRelation($this->relation);
        $caseSensitive = $this->getCaseSensitive();

        // Check values for null
        $field = $this->getDbName();
        $values = $this->getValue();
        if (empty($values)) {
            throw new \InvalidArgumentException("Cannot filter {$field} against an empty set");
        }
        $hasNull = in_array(null, $values, true);
        if ($hasNull) {
            $values = array_filter($values, function ($value) {
                return $value !== null;
            });
        }

        $connective = '';
        if (empty($values)) {
            $predicate = '';
        } elseif ($caseSensitive === null) {
            // For queries using the default collation (no explicit case) we can use the WHERE .. NOT IN .. syntax,
            // providing simpler SQL than many WHERE .. AND .. fragments.
            $column = $this->getDbName();
            $placeholders = DB::placeholders($values);
            if ($inclusive) {
                $predicate = "$column IN ($placeholders)";
            } else {
                $predicate = "$column NOT IN ($placeholders)";
            }
        } else {
            // Generate reusable comparison clause
            $comparisonClause = DB::get_conn()->comparisonClause(
                $this->getDbName(),
                null,
                true, // exact?
                !$inclusive, // negate?
                $this->getCaseSensitive(),
                true
            );
            $count = count($values);
            if ($count > 1) {
                $connective = $inclusive ? ' OR ' : ' AND ';
                $conditions = array_fill(0, $count, $comparisonClause);
                $predicate = implode($connective, $conditions);
            } else {
                $predicate = $comparisonClause;
            }
        }

        // Always check for null when doing exclusive checks (either AND IS NOT NULL / OR IS NULL)
        // or when including the null value explicitly (OR IS NULL)
        if ($hasNull || !$inclusive) {
            // If excluding values which don't include null, or including
            // values which include null, we should do an `OR IS NULL`.
            // Otherwise we are excluding values that do include null, so `AND IS NOT NULL`.
            // Simplified from (!$inclusive && !$hasNull) || ($inclusive && $hasNull);
            $isNull = !$hasNull || $inclusive;
            $nullCondition = DB::get_conn()->nullCheckClause($field, $isNull);

            // Determine merge strategy
            if (empty($predicate)) {
                $predicate = $nullCondition;
            } else {
                // Merge null condition with predicate
                if ($isNull) {
                    $nullCondition = " OR {$nullCondition}";
                } else {
                    $nullCondition = " AND {$nullCondition}";
                }
                // If current predicate connective doesn't match the same as the null connective
                // make sure to group the prior condition
                if ($connective && (($connective === ' OR ') !== $isNull)) {
                    $predicate = "({$predicate})";
                }
                $predicate .= $nullCondition;
            }
        }

        $clause = [$predicate => $values];

        return $this->aggregate ?
            $this->applyAggregate($query, $clause) :
            $query->where($clause);
    }
protected function manyFilter(DataQuery $query, $inclusive)
    {
        $this->model = $query->applyRelation($this->relation);
        $caseSensitive = $this->getCaseSensitive();

        // Check values for null
        $field = $this->getDbName();
        $values = $this->getValue();
        if (empty($values)) {
            throw new \InvalidArgumentException("Cannot filter {$field} against an empty set");
        }
        $hasNull = in_array(null, $values, true);
        if ($hasNull) {
            $values = array_filter($values, function ($value) {
                return $value !== null;
            });
        }

        $connective = '';
        if (empty($values)) {
            $predicate = '';
        } elseif ($caseSensitive === null) {
            // For queries using the default collation (no explicit case) we can use the WHERE .. NOT IN .. syntax,
            // providing simpler SQL than many WHERE .. AND .. fragments.
            $column = $this->getDbName();
            $placeholders = DB::placeholders($values);
            if ($inclusive) {
                $predicate = "$column IN ($placeholders)";
            } else {
                $predicate = "$column NOT IN ($placeholders)";
            }
        } else {
            // Generate reusable comparison clause
            $comparisonClause = DB::get_conn()->comparisonClause(
                $this->getDbName(),
                null,
                true, // exact?
                !$inclusive, // negate?
                $this->getCaseSensitive(),
                true
            );
            $count = count($values);
            if ($count > 1) {
                $connective = $inclusive ? ' OR ' : ' AND ';
                $conditions = array_fill(0, $count, $comparisonClause);
                $predicate = implode($connective, $conditions);
            } else {
                $predicate = $comparisonClause;
            }
        }

        // Always check for null when doing exclusive checks (either AND IS NOT NULL / OR IS NULL)
        // or when including the null value explicitly (OR IS NULL)
        if ($hasNull || !$inclusive) {
            // If excluding values which don't include null, or including
            // values which include null, we should do an `OR IS NULL`.
            // Otherwise we are excluding values that do include null, so `AND IS NOT NULL`.
            // Simplified from (!$inclusive && !$hasNull) || ($inclusive && $hasNull);
            $isNull = !$hasNull || $inclusive;
            $nullCondition = DB::get_conn()->nullCheckClause($field, $isNull);

            // Determine merge strategy
            if (empty($predicate)) {
                $predicate = $nullCondition;
            } else {
                // Merge null condition with predicate
                if ($isNull) {
                    $nullCondition = " OR {$nullCondition}";
                } else {
                    $nullCondition = " AND {$nullCondition}";
                }
                // If current predicate connective doesn't match the same as the null connective
                // make sure to group the prior condition
                if ($connective && (($connective === ' OR ') !== $isNull)) {
                    $predicate = "({$predicate})";
                }
                $predicate .= $nullCondition;
            }
        }

        $clause = [$predicate => $values];

        return $this->aggregate ?
            $this->applyAggregate($query, $clause) :
            $query->where($clause);
    }
protected function manyFilter ( DataQuery $ query , $ inclusive ) { $ this -> model = $ query -> applyRelation ( $ this -> relation ) ; $ caseSensitive = $ this -> getCaseSensitive ( ) ; // Check values for null $ field = $ this -> getDbName ( ) ; $ values = $ this -> getValue ( ) ; if ( empty ( $ values ) ) { throw new \ InvalidArgumentException ( "Cannot filter {$field} against an empty set" ) ; } $ hasNull = in_array ( null , $ values , true ) ; if ( $ hasNull ) { $ values = array_filter ( $ values , function ( $ value ) { return $ value !== null ; } ) ; } $ connective = '' ; if ( empty ( $ values ) ) { $ predicate = '' ; } elseif ( $ caseSensitive === null ) { // For queries using the default collation (no explicit case) we can use the WHERE .. NOT IN .. syntax, // providing simpler SQL than many WHERE .. AND .. fragments. $ column = $ this -> getDbName ( ) ; $ placeholders = DB :: placeholders ( $ values ) ; if ( $ inclusive ) { $ predicate = "$column IN ($placeholders)" ; } else { $ predicate = "$column NOT IN ($placeholders)" ; } } else { // Generate reusable comparison clause $ comparisonClause = DB :: get_conn ( ) -> comparisonClause ( $ this -> getDbName ( ) , null , true , // exact? ! $ inclusive , // negate? $ this -> getCaseSensitive ( ) , true ) ; $ count = count ( $ values ) ; if ( $ count > 1 ) { $ connective = $ inclusive ? ' OR ' : ' AND ' ; $ conditions = array_fill ( 0 , $ count , $ comparisonClause ) ; $ predicate = implode ( $ connective , $ conditions ) ; } else { $ predicate = $ comparisonClause ; } } // Always check for null when doing exclusive checks (either AND IS NOT NULL / OR IS NULL) // or when including the null value explicitly (OR IS NULL) if ( $ hasNull || ! $ inclusive ) { // If excluding values which don't include null, or including // values which include null, we should do an `OR IS NULL`. // Otherwise we are excluding values that do include null, so `AND IS NOT NULL`. // Simplified from (!$inclusive && !$hasNull) || ($inclusive && $hasNull); $ isNull = ! $ hasNull || $ inclusive ; $ nullCondition = DB :: get_conn ( ) -> nullCheckClause ( $ field , $ isNull ) ; // Determine merge strategy if ( empty ( $ predicate ) ) { $ predicate = $ nullCondition ; } else { // Merge null condition with predicate if ( $ isNull ) { $ nullCondition = " OR {$nullCondition}" ; } else { $ nullCondition = " AND {$nullCondition}" ; } // If current predicate connective doesn't match the same as the null connective // make sure to group the prior condition if ( $ connective && ( ( $ connective === ' OR ' ) !== $ isNull ) ) { $ predicate = "({$predicate})" ; } $ predicate .= $ nullCondition ; } } $ clause = [ $ predicate => $ values ] ; return $ this -> aggregate ? $ this -> applyAggregate ( $ query , $ clause ) : $ query -> where ( $ clause ) ; }
Applies matches for several values, either as inclusive or exclusive

@param DataQuery $query
@param bool $inclusive True if this is inclusive, or false if exclusive
@return DataQuery
Applies matches for several values either as inclusive or exclusive