refactoring

This commit is contained in:
Yuri Kuznetsov
2022-04-13 13:18:32 +03:00
parent bfb7d88b79
commit e03dc3b738
7 changed files with 81 additions and 142 deletions
@@ -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
+1 -1
View File
@@ -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);