entityType = $entityType; $this->config = $config; $this->metadataProvider = $metadataProvider; } public function compose(string $filter, FullTextSearchDataComposerParams $params): ?FullTextSearchData { if ($this->config->get('fullTextSearchDisabled')) { return null; } $isAuxiliaryUse = $params->isAuxiliaryUse(); $fieldList = $this->getTextFilterFieldList(); if ($isAuxiliaryUse) { $filter = str_replace('%', '', $filter); } $fullTextSearchColumnList = $this->metadataProvider->getFullTextSearchColumnList($this->entityType); $useFullTextSearch = false; if ( $this->metadataProvider->hasFullTextSearch($this->entityType) && !empty($fullTextSearchColumnList) ) { $fullTextSearchMinLength = $this->config->get('fullTextSearchMinLength') ?? self::MIN_LENGTH; if (!$fullTextSearchMinLength) { $fullTextSearchMinLength = 0; } $filterWoWildcards = str_replace('*', '', $filter); if (mb_strlen($filterWoWildcards) >= $fullTextSearchMinLength) { $useFullTextSearch = true; } } $fullTextSearchFieldList = []; if (!$useFullTextSearch) { return null; } foreach ($fieldList as $field) { if (strpos($field, '.') !== false) { continue; } if ($this->metadataProvider->isFieldNotStorable($this->entityType, $field)) { continue; } if (!$this->metadataProvider->isFullTextSearchSupportedForField($this->entityType, $field)) { continue; } $fullTextSearchFieldList[] = $field; } if (!count($fullTextSearchFieldList)) { $useFullTextSearch = false; } if (substr_count($filter, '\'') % 2 != 0) { $useFullTextSearch = false; } if (substr_count($filter, '"') % 2 != 0) { $useFullTextSearch = false; } if (empty($fullTextSearchColumnList)) { $useFullTextSearch = false; } if ($isAuxiliaryUse) { if (mb_strpos($filter, '@') !== false) { $useFullTextSearch = false; } } if (!$useFullTextSearch) { return null; } $filter = str_replace(['(', ')'], '', $filter); if ( $isAuxiliaryUse && mb_strpos($filter, '*') === false || mb_strpos($filter, ' ') === false && mb_strpos($filter, '+') === false && mb_strpos($filter, '-') === false && mb_strpos($filter, '*') === false ) { $function = 'MATCH_NATURAL_LANGUAGE'; } else { $function = 'MATCH_BOOLEAN'; } $filter = str_replace('"*', '"', $filter); $filter = str_replace('*"', '"', $filter); $filter = str_replace('\'', '\'\'', $filter); while (strpos($filter, '**')) { $filter = str_replace('**', '*', $filter); $filter = trim($filter); } while (mb_substr($filter, -2) === ' *') { $filter = mb_substr($filter, 0, mb_strlen($filter) - 2); $filter = trim($filter); } $expression = $function . ':(' . implode(', ', $fullTextSearchColumnList) . ', ' . "'{$filter}'" . ')'; return FullTextSearchData::fromArray([ 'expression' => $expression, 'fieldList' => $fullTextSearchFieldList, 'columnList' => $fullTextSearchColumnList, ]); } protected function getTextFilterFieldList(): array { return $this->metadataProvider->getTextFilterFieldList($this->entityType) ?? ['name']; } }