@param string $fieldName
@param array  $filter
@param array  $options

@return array
4190
public function distinct($fieldName, array $filter = [], array $options = [])
    {
        if (!is_string($fieldName)) {
            throw new InvalidArgumentException('$fieldName must be a string.');
        }

        if (!$fieldName) {
            throw new InvalidArgumentException('$fieldName cannot be empty.');
        }

        $command = ['distinct' => $this->collectionName, 'key' => $fieldName];
        if ($filter) {
            $command['query'] = (object) $filter;
        }
        $options['typeMap'] = [];

        $cursor = $this->executeCommand($command, $options);

        $result = $cursor->current();
        if (!isset($result->values)) {
            throw new UnexpectedResultException(
                'Command "distinct" did not return expected "values" array.'
            );
        }

        return $result->values;
    }
1233889
public function datepicker($fieldName, $options = [])
    {
        $defaults = [
            'class' => 'form-control form-control-datepicker',
            'type' => 'text',
        ];
        $options = array_merge($defaults, $options);
        return parent::input($fieldName, $options);
    }
1184262
public static function filterFieldList($fieldsList, $filters = array())
    {
        $result = array();

        foreach ($fieldsList as $field) {
            if (in_array($field->id, $filters, true)) {
                $result[] = $field;
            }
        }

        return $result;
    }
639808
public function findOneAndUpdate(array $filter, array $update, array $options = [])
    {
        \Tequila\MongoDB\ensureValidUpdate($update);

        $options = ['update' => (object) $update] + FindOneAndUpdateResolver::resolveStatic($options);

        return $this->findAndModify($filter, $options);
    }
23507
public function count(array $filter = [], array $options = [])
    {
        $cursor = $this->executeCommand(
            ['count' => $this->collectionName, 'query' => (object) $filter],
            $options
        );

        $result = $cursor->current();
        if (!isset($result['n'])) {
            throw new UnexpectedResultException('Command "count" did not return expected "n" field.');
        }

        return (int) $result['n'];
    }
38416
private function readFiltersAndFlags(array $options, $filter = DEFAULT_FILTER, $flags = [])
    {

        //Merge the flags
        $_flags = (isset($options['flags']) && is_array($options['flags']))
            ? array_merge($options['flags'], [])
            : $flags;

        unset($options['filters']);
        // unset($options['flags']);


        //The PHP default santize (filter) uses a defined option definition format
        // array("options"=>array(), "filters"=>array(), "flags"=>array())
        $parameters = array_merge_recursive($options, ["flags" => $_flags]);

        return [$filter, $_flags, $parameters];

    }
1184572
public function findOneAndUpdate(array $filter, array $update, array $options = [])
    {
        $options['typeMap'] = [
            'root' => $this->documentManager->getProxyClass($this->documentClass),
            'document' => 'array',
        ];

        $document = $this->getCollection()->findOneAndUpdate($filter, $update, $options);
        if ($document instanceof DocumentManagerAwareInterface) {
            $document->setManager($this->documentManager);
        }

        return $document;
    }
741952
public function input($fieldName, $options = array()) {
		$this->_inputType = null;
		$this->_fieldName = $fieldName;
		$options = $this->_initInputOptions($options);

		return parent::input($fieldName, $options);
	}
802080
public function replaceOne(array $filter, $replacement, array $options = [])
    {
        list($bulkOptions, $options) = self::extractBulkWriteOptions($options);
        $model = new ReplaceOne($filter, $replacement, $options);

        $bulkWriteResult = $this->bulkWrite([$model], $bulkOptions);

        return new UpdateResult($bulkWriteResult);
    }
341097
protected function parseFilter($filter, array $options)
	{
		$parameters = array();

		$original = $filter;

		if ($filter instanceof Closure)
		{
			$filter = $this->registerClosureFilter($filter);
		}
		elseif ($this->isInstanceFilter($filter))
		{
			$filter = $this->registerInstanceFilter($filter);
		}
		else
		{
			list($filter, $parameters) = Route::parseFilter($filter);
		}

		return compact('original', 'filter', 'parameters', 'options');
	}
499090
public function addFilter($filterName, $options = [])
    {
        // Create the filter hash so we can run multiple versions of the same filter
        $filterHash = sprintf('%s_%s', strtolower($filterName), md5(json_encode($options)));

        // Add the filter
        $this->options['filters'][$filterHash] = [
            'filter'  => strtolower($filterName),
            'options' => $options,
        ];

        unset($filterHash);

        return $this;
    }
53909
public function findOne(array $filter = [], array $options = [])
    {
        $options['typeMap'] = ['root' => 'array', 'document' => 'array', 'array' => 'array'];

        if ($originalValues = $this->collection->findOne($filter, $options)) {
            $values = $this->convertValues->convertToPHPValues($originalValues);


            $object = $this->hydrator->hydrate($values);

            $this->changesCollector->register($object, $originalValues);

            return $object;
        }
    }
403961
private function findAndModify(array $filter, array $options)
    {
        $command = [
            'findAndModify' => $this->collectionName,
            'query' => (object) $filter,
        ];

        $options += ['typeMap' => $this->typeMap];
        $typeMap = $options['typeMap'];
        unset($options['typeMap']);

        $cursor = $this->executeCommand($command, $options);
        $result = $cursor->current();

        if (!array_key_exists('value', $result)) {
            throw new UnexpectedResultException(
                'Command "findAndModify" did not return expected "value" document.'
            );
        }

        $result = $result['value'];

        return \Tequila\MongoDB\applyTypeMap($result, $typeMap);
    }
1141357
public function control($fieldName, array $options = []) {
        // pass the view to the needy widget
        if(isset($options['type']) && in_array($options['type'], $this->_customWidgets))
            $options['view'] = $this->getView();

        // continue as normal
        return parent::control($fieldName, $options);
    }
1120297
public function textarea($fieldName, array $options = [])
    {
        $options = optionsParser($options, ['cols' => null, 'rows' => null]);

        return parent::textarea($fieldName, $options->toArray());
    }
1256997
function filter($data, $filter = null, $options = null, $falseOnFail = true)
    {
        if (is_array($data)) {
            // the $filter must be an array or a string to an array defined under app.filters.rules
            if (is_string($filter)) {
                if (($rules = Atomik::get("helpers.filters.rules.$filter", false)) === false) {
                    throw new AtomikException('When $data is an array, the filter must be an array of definition or a defination name in filter()');
                }
            } else {
                $rules = $filter;
            }
            
            $results = array();
            $messages = array();
            $validate = true;
            
            foreach ($rules as $field => $params) {
                if (isset($data[$field]) && is_array($data[$field])) {
                    if (($results[$field] = $this->filter($data[$field], $params)) === false) {
                        $messages[$field] = Atomik::get('helpers.filters.messages', array());
                        $validate = false;
                    }
                    continue;
                }
                
                $filter = FILTER_SANITIZE_STRING;
                $message = Atomik::get('helpers.filters.default_message', 'The %s field failed to validate');
                $required = false;
                $default = null;
                $label = $field;
                if (is_array($params)) {
                    // extracting information from the array
                    if (isset($params['message'])) {
                        $message = Atomik::delete('message', $params);
                    }
                    if (isset($params['required'])) {
                        $required = Atomik::delete('required', $params);
                    }
                    if (isset($params['default'])) {
                        $default = Atomik::delete('default', $params);
                    }
                    if (isset($params['label'])) {
                        $label = Atomik::delete('label', $params);
                    }
                    if (isset($params['filter'])) {
                        $filter = Atomik::delete('filter', $params);
                    }
                    $options = count($params) == 0 ? null : $params;
                } else {
                    $filter = $params;
                    $options = null;
                }
                
                if (!isset($data[$field]) && !$required) {
                    // field not set and not required, do nothing
                    continue;
                }
                
                if ((!isset($data[$field]) || $data[$field] == '') && $required) {
                    // the field is required and either not set or empty, this is an error
                    $results[$field] = false;
                    $message = Atomik::get('helpers.filters.required_message', 'The %s field must be filled');
                    
                } else if ($data[$field] === '' && !$required) {
                    // empty but not required, null value
                    $results[$field] = $default;
                    
                } else {
                    // normal, validating
                    $results[$field] = $this->filter($data[$field], $filter, $options);
                }
                
                if ($results[$field] === false) {
                    // failed validation, adding the message
                    $messages[$field] = sprintf($message, $label);
                    $validate = false;
                }
            }
            
            Atomik::set('helpers.filters.messages', $messages);
            return $validate || !$falseOnFail ? $results : false;
        }
        
        if (is_string($filter)) {
            if (in_array($filter, filter_list())) {
                // filter name from the extension filters
                $filter = filter_id($filter);
                
            } else if (preg_match('@/.+/[a-zA-Z]*@', $filter)) {
                // regexp
                $options = array('options' => array('regexp' => $filter));
                $filter = FILTER_VALIDATE_REGEXP;
                
            } else if (($callback = Atomik::get("helpers.filters.callbacks.$filter", false)) !== false) {
                // callback defined under app/filters/callbacks
                $filter = FILTER_CALLBACK;
                $options = $callback;
            } 
        }
        
        return filter_var($data, $filter, $options);
    }
952642
private static function fixFilterFieldPath(?Filter $filter): ? Filter
    {
        if (is_null($filter)) {
            return $filter;
        }

        $filterAsArray = $filter->toArray();
        $filterAsArray['field'] = Item::getPathByField($filterAsArray['field']);

        return Filter::createFromArray($filterAsArray);
    }