mirror of
https://github.com/espocrm/espocrm.git
synced 2026-06-28 15:06:06 +00:00
full-text search 3
This commit is contained in:
@@ -150,7 +150,7 @@ class Base
|
||||
} else {
|
||||
$orderPart = 'DESC';
|
||||
}
|
||||
$result['orderBy'] = [[$sortBy . 'Country', $orderPart], [$sortBy . 'City', $orderPart], [$sortBy . 'Street', $orderPart]];
|
||||
$result['orderBy'] = [[$sortBy . 'Country', $orderPart], [$sortBy . 'City', $orderPart], [$sortBy . '_eet', $orderPart]];
|
||||
return;
|
||||
} else if ($type === 'enum') {
|
||||
$list = $this->getMetadata()->get(['entityDefs', $this->getEntityType(), 'fields', $sortBy, 'options']);
|
||||
@@ -1514,6 +1514,10 @@ class Base
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($this->getConfig()->get('fullTextSearchDisabled')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$result = null;
|
||||
|
||||
$fieldList = $this->getTextFilterFieldList();
|
||||
@@ -1522,8 +1526,15 @@ class Base
|
||||
$textFilter = str_replace('%', '', $textFilter);
|
||||
}
|
||||
|
||||
$fullTextSearchColumnList = $this->getEntityManager()->getOrmMetadata()->get($this->getEntityType(), ['fullTextSearchColumnList']);
|
||||
|
||||
$useFullTextSearch = false;
|
||||
if ($this->getMetadata()->get(['entityDefs', $this->getEntityType(), 'collection', 'fullTextSearch'])) {
|
||||
|
||||
if (
|
||||
$this->getMetadata()->get(['entityDefs', $this->getEntityType(), 'collection', 'fullTextSearch'])
|
||||
&&
|
||||
!empty($fullTextSearchColumnList)
|
||||
) {
|
||||
$fullTextSearchMinLength = $this->getConfig()->get('fullTextSearchMinLength', self::MIN_LENGTH_FOR_FULL_TEXT_SEARCH);
|
||||
if (!$fullTextSearchMinLength) {
|
||||
$fullTextSearchMinLength = 0;
|
||||
@@ -1549,6 +1560,10 @@ class Base
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($fullTextSearchColumnList)) {
|
||||
$useFullTextSearch = false;
|
||||
}
|
||||
|
||||
if ($useFullTextSearch) {
|
||||
if (
|
||||
mb_strpos($textFilter, ' ') === false
|
||||
@@ -1564,15 +1579,18 @@ class Base
|
||||
$function = 'MATCH_BOOLEAN';
|
||||
}
|
||||
|
||||
$fullTextSearchFieldSanitizedList = [];
|
||||
foreach ($fullTextSearchFieldList as $i => $field) {
|
||||
$fullTextSearchFieldSanitizedList[$i] = $this->getEntityManager()->getQuery()->sanitize($field);
|
||||
$fullTextSearchColumnSanitizedList = [];
|
||||
$query = $this->getEntityManager()->getQuery();
|
||||
foreach ($fullTextSearchColumnList as $i => $field) {
|
||||
$fullTextSearchColumnSanitizedList[$i] = $query->sanitize($query->toDb($field));
|
||||
}
|
||||
|
||||
$where = $function . ':' . implode(',', $fullTextSearchFieldSanitizedList) . ':' . $textFilter;
|
||||
$where = $function . ':' . implode(',', $fullTextSearchColumnSanitizedList) . ':' . $textFilter;
|
||||
|
||||
$result = [
|
||||
'where' => $where,
|
||||
'fieldList' => $fullTextSearchFieldList
|
||||
'fieldList' => $fullTextSearchFieldList,
|
||||
'columnList' => $fullTextSearchColumnList
|
||||
];
|
||||
}
|
||||
|
||||
@@ -1593,11 +1611,12 @@ class Base
|
||||
|
||||
$forceFullTextSearch = false;
|
||||
|
||||
$useFullTextSearch = !empty($result['forceFullTextSearch']);
|
||||
$useFullTextSearch = !empty($result['useFullTextSearch']);
|
||||
|
||||
if (mb_strpos($textFilter, 'ft:') === 0) {
|
||||
$textFilter = mb_substr($textFilter, 3);
|
||||
$useFullTextSearch = true;
|
||||
$forceFullTextSearch = true;
|
||||
}
|
||||
|
||||
$skipWidlcards = false;
|
||||
|
||||
@@ -186,6 +186,8 @@ class Converter
|
||||
|
||||
$ormMetadata = Util::merge($ormMetadata, $convertedLinks);
|
||||
|
||||
$this->applyFullTextSearch($ormMetadata, $entityName);
|
||||
|
||||
if (!empty($entityMetadata['collection']) && is_array($entityMetadata['collection'])) {
|
||||
$collectionDefs = $entityMetadata['collection'];
|
||||
$ormMetadata[$entityName]['collection'] = array();
|
||||
@@ -467,4 +469,46 @@ class Converter
|
||||
return $values;
|
||||
}
|
||||
|
||||
protected function applyFullTextSearch(&$ormMetadata, $entityType)
|
||||
{
|
||||
if (!$this->getMetadata()->get(['entityDefs', $entityType, 'collection', 'fullTextSearch'])) return;
|
||||
|
||||
$fieldList = $this->getMetadata()->get(['entityDefs', $entityType, 'collection', 'textFilterFields'], ['name']);
|
||||
|
||||
$fullTextSearchColumnList = [];
|
||||
|
||||
foreach ($fieldList as $field) {
|
||||
$defs = $this->getMetadata()->get(['entityDefs', $entityType, 'fields', $field], []);
|
||||
if (empty($defs['type'])) continue;
|
||||
$fieldType = $defs['type'];
|
||||
if (!empty($defs['notStorable'])) continue;
|
||||
if (!$this->getMetadata()->get(['fields', $fieldType, 'fullTextSearch'])) continue;
|
||||
|
||||
$partList = $this->getMetadata()->get(['fields', $fieldType, 'fullTextSearchColumnList']);
|
||||
if ($partList) {
|
||||
if ($this->getMetadata()->get(['fields', $fieldType, 'naming']) === 'prefix') {
|
||||
foreach ($partList as $part) {
|
||||
$fullTextSearchColumnList[] = $part . ucfirst($field);
|
||||
}
|
||||
} else {
|
||||
foreach ($partList as $part) {
|
||||
$fullTextSearchColumnList[] = $field . ucfirst($part);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$fullTextSearchColumnList[] = $field;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($fullTextSearchColumnList)) {
|
||||
$ormMetadata[$entityType]['fullTextSearchColumnList'] = $fullTextSearchColumnList;
|
||||
if (!array_key_exists('indexes', $ormMetadata[$entityType])) {
|
||||
$ormMetadata[$entityType]['indexes'] = [];
|
||||
}
|
||||
$ormMetadata[$entityType]['indexes']['system_fullTextSearch'] = [
|
||||
'columns' => $fullTextSearchColumnList,
|
||||
'flags' => ['fulltext']
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -206,6 +206,11 @@ class EntityManager
|
||||
return $this->metadata;
|
||||
}
|
||||
|
||||
public function getOrmMetadata()
|
||||
{
|
||||
return $this->getMetadata();
|
||||
}
|
||||
|
||||
public function getPDO()
|
||||
{
|
||||
if (empty($this->pdo)) {
|
||||
|
||||
@@ -70,6 +70,6 @@
|
||||
"linkAudited": "Creating related record and linking with existing record will be logged in Stream.",
|
||||
"linkMultipleField": "Link Multiple field provides a handy way to edit relations. Don't use it if you can have a large number of related records.",
|
||||
"entityType": "Base Plus - has Activities, History and Tasks panels.\n\nEvent - available in Calendar and Activities panel.",
|
||||
"fullTextSearch": "Running rebuild required."
|
||||
"fullTextSearch": "Running rebuild is required."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -433,7 +433,8 @@
|
||||
"collection": {
|
||||
"sortBy": "dateSent",
|
||||
"asc": false,
|
||||
"textFilterFields": ["name", "bodyPlain", "body"]
|
||||
"textFilterFields": ["name", "bodyPlain", "body"],
|
||||
"fullTextSearch": true
|
||||
},
|
||||
"indexes": {
|
||||
"dateSent": {
|
||||
|
||||
@@ -29,5 +29,10 @@
|
||||
"notCreatable":true,
|
||||
"filter":true,
|
||||
"skipOrmDefs": true,
|
||||
"personalData": true
|
||||
"personalData": true,
|
||||
"fullTextSearch": true,
|
||||
"fullTextSearchColumnList": [
|
||||
"first",
|
||||
"last"
|
||||
]
|
||||
}
|
||||
@@ -103,7 +103,7 @@ class GlobalSearch extends \Espo\Core\Services\Base
|
||||
}
|
||||
|
||||
$selectManager->manageAccess($params);
|
||||
$params['forceFullTextSearch'] = true;
|
||||
$params['useFullTextSearch'] = true;
|
||||
$selectManager->applyTextFilter($query, $params);
|
||||
|
||||
$sql = $this->getEntityManager()->getQuery()->createSelectQuery($entityType, $params);
|
||||
|
||||
Reference in New Issue
Block a user