entityType = $entityType; $this->config = $config; $this->metadataProvider = $metadataProvider; } public function compose(string $filter, FullTextSearchDataComposerParams $params): ?FullTextSearchData { if ($this->config->get('fullTextSearchDisabled')) { return null; } $columnList = $this->metadataProvider->getFullTextSearchColumnList($this->entityType) ?? []; if (!count($columnList)) { return null; } $fieldList = []; foreach ($this->getTextFilterFieldList() as $field) { if (strpos($field, '.') !== false) { continue; } if ($this->metadataProvider->isFieldNotStorable($this->entityType, $field)) { continue; } if (!$this->metadataProvider->isFullTextSearchSupportedForField($this->entityType, $field)) { continue; } $fieldList[] = $field; } if (!count($fieldList)) { return null; } if ( substr_count($filter, '\'') % 2 !== 0 || substr_count($filter, '"') % 2 !== 0 ) { return null; } if ($params->isAuxiliaryUse() && mb_strpos($filter, '@') !== false) { return null; } $preparedFilter = $this->prepareFilter($filter, $params); $function = 'MATCH_BOOLEAN'; if ( $params->isAuxiliaryUse() && mb_strpos($preparedFilter, '*') === false || mb_strpos($preparedFilter, ' ') === false && mb_strpos($preparedFilter, '+') === false && mb_strpos($preparedFilter, '-') === false && mb_strpos($preparedFilter, '*') === false ) { $function = 'MATCH_NATURAL_LANGUAGE'; } $argumentList = array_merge( array_map( function ($item) { return Expression::column($item); }, $columnList ), [$preparedFilter] ); $expression = ExpressionUtil::composeFunction($function, ...$argumentList); return new FullTextSearchData( $expression, $fieldList, $columnList ); } private function prepareFilter(string $filter, FullTextSearchDataComposerParams $params): string { $filter = str_replace(['(', ')'], '', $filter); $filter = str_replace('"*', '"', $filter); $filter = str_replace('*"', '"', $filter); while (strpos($filter, '**')) { $filter = trim( str_replace('**', '*', $filter) ); } while (mb_substr($filter, -2) === ' *') { $filter = trim( mb_substr($filter, 0, mb_strlen($filter) - 2) ); } if ($params->isAuxiliaryUse()) { $filter = str_replace('%', '', $filter); } return $filter; } /** * @return string[] */ private function getTextFilterFieldList(): array { return $this->metadataProvider->getTextFilterAttributeList($this->entityType) ?? ['name']; } }