Validate and parse filter request param.

Use this one instead of the legacy to ensure negative values are properly computed.

@param string $filter The raw filter value (XXX-XXX)

@return array|bool
546437
public function validateFilter($filter)
    {
        // Match a regex pattern instead of just exploding on '-' (this fail with negative numbers).
        $regexp = "/(-?[0-9]+)-(-?[0-9]+)/";
        preg_match_all($regexp, $filter, $matches);

        // Whole match + two groups matches.
        if (count($matches) !== 3) {
            return false;
        }

        $filter = [current($matches[1]), current($matches[2])];

        // Legacy check for >=0 is also removed here.
        foreach ($filter as $v) {
            if (is_infinite((double) $v)) {
                return false;
            }
        }

        return $filter;
    }
1162956
private function convertFilterProps(array $filter)
    {
        if (isset($filter['propertyFilter'])) {
            $operator = $filter['propertyFilter']['op'];

            $constName = PropertyFilterOperator::class . '::' . $operator;
            if (!defined($constName)) {
                throw new \InvalidArgumentException('Invalid operator.');
            }

            $filter['propertyFilter']['op'] = constant($constName);
        }

        if (isset($filter['compositeFilter'])) {
            $filter['compositeFilter']['op'] = CompositeFilterOperator::PBAND;

            foreach ($filter['compositeFilter']['filters'] as &$nested) {
                $nested = $this->convertFilterProps($nested);
            }
        }

        return $filter;
    }
104528
public function setFilter($filter)
    {
        parent::setFilter($filter);

        $this->userOptions['value'] = $this->validator->arrayGet($filter, 'value', '');

        //if it isn't null, we have to check the 'true'/'false' string
        if ($this->userOptions['value'] !== '') {
            $this->userOptions['value'] = $this->userOptions['value'] === 'false' || !$this->userOptions['value'] ? 0 : 1;
        }
    }
511569
public function all($filter)
    {
        $result = $this->toArray();

        // If the value is null return the default
        if(!empty($result))
        {
            // Handle magic quotes compatibility
            if (get_magic_quotes_gpc()) {
                $result = $this->_stripSlashes( $result );
            }

            // Filter the data
            if(!($filter instanceof FilterInterface)) {
                $filter = $this->getObject('filter.factory')->createChain($filter);
            }

            $result = $filter->sanitize($result);
        }

        return $result;
    }
463870
protected function matchesFilter(array $filter): bool
    {
        foreach ($filter as $key => $comp) {
            $value = ($this->$key ?? null);
            $match = is_scalar($value) && is_scalar($comp) ? (string)$value === (string)$comp : $value === $comp;

            if (!$match) {
                return false;
            }
        }

        return true;
    }
498073
public static function validateBoolean($data, callable $filter=null) {
        if ( is_bool($data) === false ) return false;
        return self::applyFilter($data, $filter);
    }
1058131
public function filter($filter)
    {
        preg_match_all("/(#\w+)/", $filter, $entityNames);
        preg_match_all("/(:\w+)/", $filter, $positions);

        $entityName = is_array($entityNames[0]) && isset($entityNames[0][0]) ? ltrim($entityNames[0][0], '#') : null;
        $position   = is_array($positions[0]) && isset($positions[0][0]) ? $positions[0][0] : null;

        $i = 0;

        $filtered = [];

        foreach ($this->entities as $name => $entity) {
            if ($i === 0 && ($entityName === $name || $entityName === null) && ($position === ':first' || $position === ':highest' || $position === null)) {
                $filtered[] = $entity;
            }

            if ($position === ':any' && ($entityName === $name || $entityName === null)) {
                $filtered[] = $entity;
            }

            if ($i + 1 === $this->entities->count() && ($entityName === $name || $entityName === null) && ($position === ':last' || $position === ':lowest')) {
                $filtered[] = $entity;
            }

            $i++;
        }

        $this->filtered = $filtered;

        return $this;
    }
630274
public function dataTypesGet( $filter = null )
    {

        // array of string
        if( func_num_args() > 1 and \Bond\array_check( 'is_string', func_get_args() ) ) {
            $filter = func_get_args();
        }

        // filter constants
        if( is_int( $filter ) ) {

            $dataTypes = array();

            if( $filter & DataType::PRIMARY_KEYS ) {
                $dataTypes += array_filter(
                    $this->dataTypes,
                    function( $dataType ) {
                        return $dataType->isPrimaryKey();
                    }
                );
            }

            if( $filter & DataType::FORM_CHOICE_TEXT ) {
                $dataTypes += array_filter(
                    $this->dataTypes,
                    function( $dataType ) {
                        return $dataType->isFormChoiceText();
                    }
                );
            }

            if( $filter & DataType::AUTOCOMPLETE ) {
                $dataTypes += array_filter(
                    $this->dataTypes,
                    function( $dataType ) {
                        return $dataType->isAutoComplete();
                    }
                );
            }

            // todo. build a datatype from the $this->links et al
            if( $filter & DataType::LINKS ) {
            }

            return $dataTypes;

        }

        if( is_string( $filter ) ) {
            $filter = array( $filter );
        }

        if( is_array($filter) ) {

            $result = array_intersect_key( $this->dataTypes, array_flip( $filter ) );

            if ( count($result) != count($filter) ) {
                throw new \InvalidArgumentException(
                    sprintf(
                        'Unknown columns "%s" passed to %s->dataTypesGet()',
                        implode( '","', array_diff( $filter, array_keys( $result ) ) ),
                        $this->entity
                    )
                );
            }

            return $result;
        }

        if( $filter instanceof \Closure ) {
            return array_filter( $this->dataTypes, $filter );
        }

        return $this->dataTypes;
    }
807817
private static function cleanAndValidateFilter($token, $filter)
	{
		$filter_should_be_scalar = self::shouldBeScalar($token);

		// Format the filter, cutting off the trailing ']' if appropriate
		$filter = $filter_should_be_scalar ? explode(',', substr($filter, strlen($token))) :
			explode(',', substr($filter, strlen($token), -1));

		if ($filter_should_be_scalar) {
			if (count($filter) > 1) {
				return false;
			}

			// Set to first index if should be scalar
			$filter = $filter[0];
		}

		return $filter;
	}
256587
public function hasFilter($filter)
    {
        $key = is_callable($filter) ? 0 : 1;

        foreach ($this->filters as $tuple) {
            if ($tuple[$key] === $filter) {
                return true;
            }
        }

        return false;
    }
1113854
private static function determineTokenType($filter)
	{
		if (in_array(substr($filter, 0, 2), array_keys(self::$supported_tokens))) {
			// Two character token (<=, >=, etc)
			return substr($filter, 0, 2);
		} elseif (in_array($filter[0], array_keys(self::$supported_tokens))) {
			// Single character token (>, ^, $)
			return $filter[0];
		}

		// No token
		return false;
	}
1258439
public function getFilter($filter)
    {
        if (!$filter instanceof AnFilterAbstract) {
            $filter = (string) $filter;

            if (!isset($this->_filters[$filter])) {
                if (is_string($filter) && strpos($filter, '.') === false) {
                    $identifier = clone $this->getIdentifier();
                    $identifier->path = array('filter');
                    $identifier->name = $filter;
                    register_default(array('identifier' => $identifier, 'prefix' => $this));
                } else {
                    $identifier = $this->getIdentifier($filter);
                }

                $this->_filters[$filter] = $this->getService($identifier);
            }

            $filter = $this->_filters[$filter];
        }

        return $filter;
    }
266943
public static function validateJson($data, callable $filter=null) {
        $decoded = json_decode($data);
        if ( is_null($decoded) ) return false;
        return self::applyFilter($data, $filter);
    }
546569
public function find($filter)
    {
        if (is_null($this->settings)) {
            $this->settings();
        }

        return $this->settings[$filter];
    }
1368110
private function addFilter($filter)
    {
        if (is_array($filter)) {
            if (!isset($filter['method'])) {
                throw new \InvalidArgumentException(
                    'A [method] value must be specified for each complex filter'
                );
            }
        }

        if (!$this->filters) {
            $this->filters = [$filter];
        } else {
            $this->filters[] = $filter;
        }

        return $this;
    }
353087
private function applyFilter(Filter $filter)
    {
        list($filtered, $errors) = $filter->apply($this->value);
        if (count($errors) === 0) {
            return $filtered;
        }

        foreach ($errors as $error) {
            $this->paramErrors->append($this->paramName, $error);
        }

        return null;
    }
26547
public function filter( $filter, $params )
    {
        $argList = func_get_args( );

        array_shift( $argList );

        if ( isset( $this->filters[ $filter ] ) )
        {
            foreach( $this->filters[ $filter ] as $callback )
            {
                $argList[ 0 ] = call_user_func_array( $callback[ 'callback' ], $argList );

                if ( $this->debug )
                {
                    echo PHP_EOL . '->FILTER: ' . $filter . ' -> '
                            . $this->_serializeCallback( $callback[ 'callback' ] )
                            . ' + Priority: ' . $callback[ 'priority' ]
                            . PHP_EOL;
                }
            }
        }

        return $argList[ 0 ];
    }