@param Common\ISource $source
@param boolean        $isGroupJoin
@param IFilter|null   $filter
@param boolean        $hasDefault

@return Options
359611
public function update(
            Common\ISource $source,
            $isGroupJoin,
            IFilter $filter = null,
            $hasDefault = false
    ) {
        if ($this->source === $source
                && $this->isGroupJoin === $isGroupJoin
                && $this->filter === $filter
                && $this->hasDefault === $hasDefault
        ) {
            return $this;
        }

        return new self($source, $isGroupJoin, $filter, $hasDefault, $this->defaultValueId, $this->defaultKeyId);
    }
114458
public function hasSource($source, $package=null) {
		try {
			return !!static::getFilePath($source, $package);
		} catch( Exception $e ) {
			return false;
		}
	}
250657
public function addFilter(string $title, IFilter $filter)
    {
        $this->addField($title, $filter);

        $provider = $filter->getFilter()->getProvider();
        if (!$provider) {
            $filter->setProvider($this->provider);
        }

        $filter->loadData();

        if (!$filter->isEmpty() && !($filter instanceof Hidden)) {
            $this->applied = true;
        }

        return $this;
    }
333220
public function findByFilter(Filter $filter, $limit = null, $offset = 0, $order = null)
    {
        return $this->findByCriteria($filter->getCriteria(), $limit, $offset, $order);
    }
949818
public GroupFilter where(Predicate<GroupMetadata> filter) {
        checkNotNull(filter, "Filter predicate must be not a null");

        this.predicate = this.predicate.and(filter);

        return this;
    }
397334
public function dataSourceFilter($sourceIdent)
    {
        if (!is_string($sourceIdent)) {
            throw new InvalidArgumentException('Data source identifier must be a string');
        }

        $filters = array_merge($this->defaultDataSourceFilters(), $this->dataSourceFilters);

        if (isset($filters[$sourceIdent])) {
            return $filters[$sourceIdent];
        }

        return null;
    }
1058433
protected function getAssociationsFilter(string $filter = null)
    {
        $mappingConfiguration = new PropertyMappingConfiguration();
        $mappingConfiguration->setTypeConverter($this->typeConverterObjectConverter);
        $mappingConfiguration->setTypeConverterOption(\RGU\Dvoconnector\Property\TypeConverter\ObjectConverter::class, \RGU\Dvoconnector\Property\TypeConverter\ObjectConverter::CONFIGURATION_OBJECT, $this->getDefaultAssociationsFilter());

        return $this->convertAssociationsFilter($mappingConfiguration, $filter);
    }
930831
public function toArray(iFilter $filter)
	{
		$result = array();
		if($this->uuid != null)
			$result[Database::XML_UUID] = $this->uuid;
		if($this->name != null)
			$result[Database::XML_NAME] = $this->name;
		if($this->icon != null && $filter->acceptIcons())
			$result[Database::XML_ICONID] = $this->icon;
		if($this->customIcon != null && $filter->acceptIcons())
			$result[Database::XML_CUSTOMICONUUID] = $this->customIcon;
		if($this->groups != null)
		{
			$groups = array();
			foreach($this->groups as &$group)
			{
				if($filter->acceptGroup($group))
					$groups[] = $group->toArray($filter);
			}
			if(!empty($groups))
				$result[Database::GROUPS] = $groups;
		}
		if($this->entries != null)
		{
			$entries = array();
			foreach($this->entries as &$entry)
			{
				if($filter->acceptEntry($entry))
					$entries[] = $entry->toArray($filter);
			}
			if(!empty($entries))
				$result[Database::ENTRIES] = $entries;
		}
		return $result;
	}
1120896
public function buildFilterRulesForUsedOnly($filter, $idList = [])
    {
        $result = $this
            ->getConnection()
            ->createQueryBuilder()
            ->select('value_id AS id')
            ->from('tl_metamodel_tag_relation')
            ->where('att_id=:attId')
            ->groupBy('value_id')
            ->setParameter('attId', $this->get('id'));

        if (!empty($idList)) {
            $result
                ->andWhere('item_id IN (:itemIds)')
                ->setParameter('itemIds', $idList, Connection::PARAM_STR_ARRAY);
        }

        $filter->addFilterRule(SimpleQuery::createFromQueryBuilder($result));
    }
473690
private function getFindFilterFactory( $source = 0 )
    {
        $propertyMappers = [ PropertyMapperEntityData::class ];
        if( $source & Base::INITIAL ) {
            $propertyMappers[] = [ PropertyMapperEntityInitial::class ];
        }
        return new FindFilterComponentFactory( $propertyMappers );
    }
562388
private function coalesceSources($source = null)
    {
        if (isset($source)) {
            return $source;
        } elseif (isset($this->source)) {
            return $this->source;
        }

        return $_SERVER;
    }
759031
public function canFilter($canFilter = null)
    {
        if (null === $canFilter) {
            return $this->canFilter;
        }

        $this->canFilter = $canFilter;
        return $this;
    }
557814
protected function doJoins($source, $joins, &$dest, $from, $contextAlias, $buildImpactIndex=true)
    {
        // expand sequences before doing any joins...
        $this->expandSequence($joins,$source);

        foreach ($joins as $predicate=>$ruleset) {
            if ($predicate=='followSequence') {
                continue;
            }

            if (isset($source[$predicate]))
            {
                // todo: perhaps we can get better performance by detecting whether or not
                // the uri to join on is already in the impact index, and if so not attempting
                // to join on it. However, we need to think about different combinations of
                // nested joins in different points of the view spec and see if this would
                // complicate things. Needs a unit test or two.
                $joinUris = [];
                if (isset($source[$predicate][VALUE_URI]))
                {
                    // single value for join
                    $joinUris[] = array(_ID_RESOURCE=>$source[$predicate][VALUE_URI],_ID_CONTEXT=>$contextAlias);
                }
                else
                {
                    // multiple values for join
                    $joinsPushed = 0;
                    foreach ($source[$predicate] as $v)
                    {
                        if (isset($ruleset['maxJoins']) && !$joinsPushed<$ruleset['maxJoins'])
                        {
                            break; // maxJoins reached
                        }
                        $joinUris[] = array(_ID_RESOURCE=>$v[VALUE_URI],_ID_CONTEXT=>$contextAlias);
                        $joinsPushed++;
                    }
                }

                $recursiveJoins = [];
                $collection = (
                isset($ruleset['from'])
                    ? $this->config->getCollectionForCBD($this->storeName, $ruleset['from'])
                    : $this->config->getCollectionForCBD($this->storeName, $from)
                );

                $cursor = $collection->find(array('_id'=>array('$in'=>$joinUris)), array(
                    'maxTimeMS' => $this->getConfigInstance()->getMongoCursorTimeout()
                ));

                $this->addIdToImpactIndex($joinUris, $dest, $buildImpactIndex);
                foreach($cursor as $linkMatch) {
                    // if there is a condition, check it...
                    if (isset($ruleset['condition']))
                    {
                        $ruleset['condition']['._id'] = $linkMatch['_id'];
                    }
                    if (!(isset($ruleset['condition']) && $collection->count($ruleset['condition'])==0))
                    {
                        // make sure any sequences are expanded before extracting properties
                        if (isset($ruleset['joins'])) $this->expandSequence($ruleset['joins'],$linkMatch);
                        if (isset($ruleset['filter']))
                        {
                            foreach($ruleset['filter'] as $filterPredicate => $filter)
                            {
                                foreach($filter as $filterType => $filterMatch)
                                {
                                    if (isset($linkMatch[$filterPredicate]))
                                    {
                                        foreach($linkMatch[$filterPredicate] as $linkMatchType => $linkMatchValues)
                                        {
                                            if (is_array($linkMatchValues) == false)
                                            {
                                                $linkMatchValues = array($linkMatchType => $linkMatchValues);
                                            }
                                            foreach($linkMatchValues as $linkMatchType => $linkMatchValue)
                                            {
                                                if ($this->matchesFilter($linkMatchType, $linkMatchValue, $filterType, $filterMatch))
                                                {
                                                    $dest[_GRAPHS][] = $this->extractProperties($linkMatch,$ruleset,$from);
                                                }
                                            }

                                        }
                                    }
                                }
                            }
                        }
                        else
                        {
                            $dest[_GRAPHS][] = $this->extractProperties($linkMatch,$ruleset,$from);
                        }

                        if (isset($ruleset['joins']))
                        {
                            // recursive joins must be done after this cursor has completed, otherwise things get messy
                            $recursiveJoins[] = array('data'=>$linkMatch, 'ruleset'=>$ruleset['joins']);
                        }
                    }
                }
                if (count($recursiveJoins)>0)
                {
                    foreach ($recursiveJoins as $r)
                    {
                        $this->doJoins($r['data'],$r['ruleset'],$dest,$from,$contextAlias,$buildImpactIndex);
                    }
                }
            }
        }
        return;
    }
766571
protected function getHelper(array $source, $name = null, $filter = null, $default = null)
    {
        if (empty($name)) {
            return $source;
        }

        if (!isset($source[$name])) {
            return $default;
        }

        $value = $source[$name];
        if ($filter !== null) {
            $value = sanitize($value, $filter);
        }

        return $value;
    }
1357667
public static function createFromSource($source, $type, array $options = []) {
		if (isset(self::$readers[$type])) {
			$reader = self::$readers[$type];
		} else {
			$class  = self::READERS_NAMESPACE . '\\' . ucfirst($type);
			$reader = new $class();

			if (! $reader instanceof ReaderInterface) {
				throw new InvalidReader('Reader must implement the "ReaderInterface"');
			}
			
			self::$readers[$type] = $reader;
		}
		
		// Read only lock resolve
		if (isset($options[self::OPTION_READONLY])) {
			$readOnly = (bool) $options[self::OPTION_READONLY];
			unset($options[self::OPTION_READONLY]);
		} else {
			$readOnly = true;
		}
		
		return self::create($reader->parse($source, $options), $readOnly);
	}
649379
public function compileCheckboxOptions($filter, $options)
    {
        $allOptionsOfCurrentFilter = $filter['options'];

        // alphabetical sorting of filter options
        if ($filter['alphabeticalsorting'] == 1) {
            $this->sortArrayByColumn($allOptionsOfCurrentFilter, 'title');
        }

        // loop through options
        $checkboxOptions = array();
        if (is_array($allOptionsOfCurrentFilter)) {
            foreach ($allOptionsOfCurrentFilter as $key => $data) {
                $data['key'] = $key;

                // check if current option (of searchresults) is in array of all possible options
                $isOptionInOptionArray = false;
                if (is_array($options)) {
                    foreach ($options as $optionInResultList) {
                        if ($optionInResultList['value'] == $data['tag']) {
                            $isOptionInOptionArray = true;
                            $data['results'] = $optionInResultList['results'];
                            break;
                        }
                    }
                }

                // if option is in optionArray, we have to mark the checkboxes
                if ($isOptionInOptionArray) {
                    // if user has selected a checkbox it must be selected on the resultpage, too.
                    // options which have been preselected in the backend are
                    // already in $this->piVars['filter'][$filter['uid]]
                    if ($this->piVars['filter'][$filter['uid']][$key]) {
                        $data['selected'] = 1;
                    }

                    // mark all checkboxes if that config options is set and no search string was given and there
                    // are no preselected filters given for that filter
                    if ($this->isEmptySearch
                        && $filter['markAllCheckboxes']
                        && empty($this->preselectedFilter[$filter['uid']])
                    ) {
                        $data['selected'] = 1;
                    }
                } else { // if an option was not found in the search results
                    $data['disabled'] = 1;
                }

                $data['id'] = 'filter_' . $filter['uid'] . '_' . $key;
                $checkboxOptions[] = $data;
            }
        }

        // modify filter options by hook
        if (is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['ke_search']['modifyFilterOptions'])) {
            foreach ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['ke_search']['modifyFilterOptions'] as $_classRef) {
                $_procObj = &GeneralUtility::makeInstance($_classRef);
                $_procObj->modifyFilterOptions($filter, $checkboxOptions, $this);
            }
        }

        return $checkboxOptions;
    }
899759
private boolean isGroupMember(final String filter, final File candidate) {
    final String fileName = candidate.getName();
    final int lastDot = fileName.lastIndexOf('.');
    if (lastDot >= 0 && lastDot < fileName.length() - 1) {
      final String extension = ";" + fileName.substring(lastDot + 1).toLowerCase() + ";";
      final String semiFilter = ";" + filter + ";";
      return semiFilter.contains(extension);
    }
    return false;
  }