refactoring
This commit is contained in:
@@ -171,9 +171,9 @@ class TextFilter
|
||||
{
|
||||
$composer = $this->fullTextSearchDataComposerFactory->create($this->entityType);
|
||||
|
||||
$params = FullTextSearchDataComposerParams::fromArray([
|
||||
'isAuxiliaryUse' => $isAuxiliaryUse,
|
||||
]);
|
||||
$params = FullTextSearchDataComposerParams
|
||||
::create()
|
||||
->withIsAuxiliaryUse($isAuxiliaryUse);
|
||||
|
||||
return $composer->compose($filter, $params);
|
||||
}
|
||||
|
||||
@@ -36,8 +36,6 @@ use Espo\ORM\Query\Part\Expression;
|
||||
|
||||
class FullTextSearchDataComposer
|
||||
{
|
||||
private const MIN_LENGTH = 4;
|
||||
|
||||
private string $entityType;
|
||||
|
||||
private Config $config;
|
||||
@@ -60,44 +58,15 @@ class FullTextSearchDataComposer
|
||||
return null;
|
||||
}
|
||||
|
||||
$isAuxiliaryUse = $params->isAuxiliaryUse();
|
||||
$columnList = $this->metadataProvider->getFullTextSearchColumnList($this->entityType) ?? [];
|
||||
|
||||
$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;
|
||||
}*/
|
||||
|
||||
$useFullTextSearch = true;
|
||||
}
|
||||
|
||||
$fullTextSearchFieldList = [];
|
||||
|
||||
if (!$useFullTextSearch) {
|
||||
if (!count($columnList)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
foreach ($fieldList as $field) {
|
||||
$fieldList = [];
|
||||
|
||||
foreach ($this->getTextFilterFieldList() as $field) {
|
||||
if (strpos($field, '.') !== false) {
|
||||
continue;
|
||||
}
|
||||
@@ -110,85 +79,88 @@ class FullTextSearchDataComposer
|
||||
continue;
|
||||
}
|
||||
|
||||
$fullTextSearchFieldList[] = $field;
|
||||
$fieldList[] = $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) {
|
||||
if (!count($fieldList)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$filter = str_replace(['(', ')'], '', $filter);
|
||||
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);
|
||||
|
||||
if ($params->isAuxiliaryUse()) {
|
||||
$preparedFilter = str_replace('%', '', $preparedFilter);
|
||||
}
|
||||
|
||||
$function = 'MATCH_BOOLEAN';
|
||||
|
||||
if (
|
||||
$isAuxiliaryUse && mb_strpos($filter, '*') === false
|
||||
$params->isAuxiliaryUse() && mb_strpos($preparedFilter, '*') === false
|
||||
||
|
||||
mb_strpos($filter, ' ') === false &&
|
||||
mb_strpos($filter, '+') === false &&
|
||||
mb_strpos($filter, '-') === false &&
|
||||
mb_strpos($filter, '*') === false
|
||||
mb_strpos($preparedFilter, ' ') === false &&
|
||||
mb_strpos($preparedFilter, '+') === false &&
|
||||
mb_strpos($preparedFilter, '-') === false &&
|
||||
mb_strpos($preparedFilter, '*') === false
|
||||
) {
|
||||
$function = 'MATCH_NATURAL_LANGUAGE';
|
||||
}
|
||||
else {
|
||||
$function = 'MATCH_BOOLEAN';
|
||||
}
|
||||
|
||||
$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);
|
||||
}
|
||||
|
||||
$argumentList = array_merge(
|
||||
array_map(
|
||||
function ($item) {
|
||||
return Expression::column($item);
|
||||
},
|
||||
$fullTextSearchColumnList ?? []
|
||||
$columnList
|
||||
),
|
||||
[$filter]
|
||||
[$preparedFilter]
|
||||
);
|
||||
|
||||
$expression = ExpressionUtil::composeFunction($function, ...$argumentList);
|
||||
|
||||
return new FullTextSearchData($expression, $fullTextSearchFieldList, $fullTextSearchColumnList ?? []);
|
||||
return new FullTextSearchData(
|
||||
$expression,
|
||||
$fieldList,
|
||||
$columnList
|
||||
);
|
||||
}
|
||||
|
||||
private function prepareFilter(string $filter): 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)
|
||||
);
|
||||
}
|
||||
|
||||
return $filter;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
protected function getTextFilterFieldList(): array
|
||||
private function getTextFilterFieldList(): array
|
||||
{
|
||||
return $this->metadataProvider->getTextFilterAttributeList($this->entityType) ?? ['name'];
|
||||
}
|
||||
|
||||
@@ -29,8 +29,6 @@
|
||||
|
||||
namespace Espo\Core\Select\Text;
|
||||
|
||||
use InvalidArgumentException;
|
||||
|
||||
class FullTextSearchDataComposerParams
|
||||
{
|
||||
private bool $isAuxiliaryUse = false;
|
||||
@@ -39,22 +37,17 @@ class FullTextSearchDataComposerParams
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string,mixed> $params
|
||||
*/
|
||||
public static function fromArray(array $params): self
|
||||
public static function create(): self
|
||||
{
|
||||
$object = new self();
|
||||
return new self();
|
||||
}
|
||||
|
||||
$object->isAuxiliaryUse = $params['isAuxiliaryUse'] ?? false;
|
||||
public function withIsAuxiliaryUse(bool $isAuxiliaryUse = true): self
|
||||
{
|
||||
$obj = clone $this;
|
||||
$obj->isAuxiliaryUse = $isAuxiliaryUse;
|
||||
|
||||
foreach ($params as $key => $value) {
|
||||
if (!property_exists($object, $key)) {
|
||||
throw new InvalidArgumentException("Unknown parameter '{$key}'.");
|
||||
}
|
||||
}
|
||||
|
||||
return $object;
|
||||
return $obj;
|
||||
}
|
||||
|
||||
public function isAuxiliaryUse(): bool
|
||||
|
||||
@@ -181,7 +181,7 @@ class GlobalSearch implements
|
||||
|
||||
$fullTextSearchData = $fullTextSearchDataComposer->compose(
|
||||
$filter,
|
||||
FullTextSearchDataComposerParams::fromArray([])
|
||||
FullTextSearchDataComposerParams::create()
|
||||
);
|
||||
|
||||
$isPerson = $this->metadata->get([
|
||||
|
||||
@@ -233,9 +233,9 @@ class TextFilterApplierTest extends \PHPUnit\Framework\TestCase
|
||||
|
||||
$fullTextSearchDataComposer = $this->createMock(FullTextSearchDataComposer::class);
|
||||
|
||||
$fullTextSearchDataComposerParams = FullTextSearchDataComposerParams::fromArray([
|
||||
'isAuxiliaryUse' => $isAuxiliaryUse,
|
||||
]);
|
||||
$fullTextSearchDataComposerParams = FullTextSearchDataComposerParams
|
||||
::create()
|
||||
->withIsAuxiliaryUse($isAuxiliaryUse);
|
||||
|
||||
$this->fullTextSearchDataComposerFactory
|
||||
->expects($this->once())
|
||||
|
||||
@@ -33,40 +33,20 @@ use Espo\Core\{
|
||||
Select\Text\FullTextSearchDataComposerParams,
|
||||
};
|
||||
|
||||
use InvalidArgumentException;
|
||||
|
||||
class FullTextSearchDataComposerParamsTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
protected function setUp() : void
|
||||
{
|
||||
}
|
||||
|
||||
public function testFromArray()
|
||||
{
|
||||
$item = FullTextSearchDataComposerParams::fromArray([
|
||||
'isAuxiliaryUse' => true,
|
||||
]);
|
||||
$item = FullTextSearchDataComposerParams::create()->withIsAuxiliaryUse(true);
|
||||
|
||||
$this->assertTrue($item->isAuxiliaryUse());
|
||||
|
||||
$item = FullTextSearchDataComposerParams::fromArray([
|
||||
'isAuxiliaryUse' => false,
|
||||
]);
|
||||
$item = FullTextSearchDataComposerParams::create()->withIsAuxiliaryUse(false);
|
||||
|
||||
$this->assertFalse($item->isAuxiliaryUse());
|
||||
|
||||
$item = FullTextSearchDataComposerParams::fromArray([
|
||||
]);
|
||||
$item = FullTextSearchDataComposerParams::create();
|
||||
|
||||
$this->assertFalse($item->isAuxiliaryUse());
|
||||
}
|
||||
|
||||
public function testNonExistingParam()
|
||||
{
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
|
||||
$params = FullTextSearchDataComposerParams::fromArray([
|
||||
'bad' => 'd',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,9 +114,7 @@ class FullTextSearchDataComposerTest extends \PHPUnit\Framework\TestCase
|
||||
['field1', 'field2', 'field3']
|
||||
);
|
||||
|
||||
$params = FullTextSearchDataComposerParams::fromArray([
|
||||
'isAuxiliaryUse' => false,
|
||||
]);
|
||||
$params = FullTextSearchDataComposerParams::create()->withIsAuxiliaryUse(false);
|
||||
|
||||
$data = $this->fullTextSearchDataComposer->compose($filter, $params);
|
||||
|
||||
@@ -147,9 +145,7 @@ class FullTextSearchDataComposerTest extends \PHPUnit\Framework\TestCase
|
||||
)
|
||||
);
|
||||
|
||||
$params = FullTextSearchDataComposerParams::fromArray([
|
||||
'isAuxiliaryUse' => false,
|
||||
]);
|
||||
$params = FullTextSearchDataComposerParams::create()->withIsAuxiliaryUse(false);
|
||||
|
||||
$data = $this->fullTextSearchDataComposer->compose($filter, $params);
|
||||
|
||||
@@ -172,9 +168,7 @@ class FullTextSearchDataComposerTest extends \PHPUnit\Framework\TestCase
|
||||
)
|
||||
);
|
||||
|
||||
$params = FullTextSearchDataComposerParams::fromArray([
|
||||
'isAuxiliaryUse' => false,
|
||||
]);
|
||||
$params = FullTextSearchDataComposerParams::create()->withIsAuxiliaryUse(false);
|
||||
|
||||
$data = $this->fullTextSearchDataComposer->compose($filter, $params);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user