1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Apps\Model\Front\Search; |
4
|
|
|
|
5
|
|
|
use Ffcms\Core\Arch\Model; |
6
|
|
|
use Ffcms\Core\Helper\HTML\System\Dom; |
7
|
|
|
use Ffcms\Core\Helper\Type\Obj; |
8
|
|
|
use Ffcms\Core\Helper\Type\Str; |
9
|
|
|
|
10
|
|
|
class EntitySearchMain extends Model |
11
|
|
|
{ |
12
|
|
|
public $results = []; |
13
|
|
|
public $query; |
14
|
|
|
|
15
|
|
|
private $_configs; |
16
|
|
|
|
17
|
|
|
/** |
18
|
|
|
* EntitySearchMain constructor. Pass query inside |
19
|
|
|
* @param string $query |
20
|
|
|
* @param array|null $configs |
21
|
|
|
*/ |
22
|
|
|
public function __construct($query, array $configs = null) |
23
|
|
|
{ |
24
|
|
|
$this->query = $query; |
25
|
|
|
$this->_configs = $configs; |
26
|
|
|
parent::__construct(); |
27
|
|
|
} |
28
|
|
|
|
29
|
|
|
/** |
30
|
|
|
* Try to search in classic apps |
31
|
|
|
*/ |
32
|
|
|
public function make() |
33
|
|
|
{ |
34
|
|
|
$itemCount = (int)$this->_configs['itemPerApp']; |
35
|
|
|
// search content items |
36
|
|
|
$content = new SearchContent($this->query, $itemCount); |
37
|
|
|
$this->results['Content'] = $content->getResult(); |
38
|
|
|
// search comments |
39
|
|
|
$comments = new SearchComments($this->query, $itemCount); |
40
|
|
|
$this->results['Comments'] = $comments->getResult(); |
41
|
|
|
} |
42
|
|
|
|
43
|
|
|
/** |
44
|
|
|
* Get sorted by relevance search response. Method return result as array: [relevance => [title, snippet, uri, date], ...] |
45
|
|
|
* @return array |
46
|
|
|
*/ |
47
|
|
|
public function getRelevanceSortedResult() |
48
|
|
|
{ |
49
|
|
|
$result = []; |
50
|
|
|
// each every content type |
51
|
|
|
foreach ($this->results as $type => $items) { |
52
|
|
|
if (!Obj::isArray($items)) { |
53
|
|
|
continue; |
54
|
|
|
} |
55
|
|
|
// each every element |
56
|
|
|
foreach ($items as $item) { |
57
|
|
|
/** @var AbstractSearchResult $item */ |
58
|
|
|
// build unique relevance. Problem: returned relevance from query is integer |
59
|
|
|
// and can be duplicated. So, we add random complex float value and make it string to sort in feature |
60
|
|
|
$uniqueRelevance = (string)($item->getRelevance() + (mt_rand(0, 999)/10000)); |
61
|
|
|
// build response |
62
|
|
|
$result[$uniqueRelevance] = [ |
63
|
|
|
'title' => $item->getTitle(), |
64
|
|
|
'snippet' => $item->getSnippet(), |
65
|
|
|
'uri' => $item->getUri(), |
66
|
|
|
'date' => $item->getDate() |
67
|
|
|
]; |
68
|
|
|
} |
69
|
|
|
} |
70
|
|
|
|
71
|
|
|
// sort output by relevance |
72
|
|
|
krsort($result); |
73
|
|
|
|
74
|
|
|
// return result as array |
|
|
|
|
75
|
|
|
return $result; |
76
|
|
|
} |
77
|
|
|
|
78
|
|
|
/** |
79
|
|
|
* Highlight words in text by current query request. |
80
|
|
|
* @param string $text |
81
|
|
|
* @param string $tag |
82
|
|
|
* @param array $properties |
83
|
|
|
* @return string |
84
|
|
|
*/ |
85
|
|
|
public function highlightText($text, $tag, array $properties = []) |
86
|
|
|
{ |
87
|
|
|
$queries = explode(' ', $this->query); |
88
|
|
|
$dom = new Dom(); |
89
|
|
|
foreach ($queries as $query) { |
90
|
|
|
$highlight = $dom->{$tag}(function() use ($query) { |
91
|
|
|
return $query; |
92
|
|
|
}, $properties); |
93
|
|
|
$text = Str::ireplace($query, $highlight, $text); |
|
|
|
|
94
|
|
|
} |
95
|
|
|
return $text; |
96
|
|
|
} |
97
|
|
|
|
98
|
|
|
|
99
|
|
|
} |
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.
The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.
This check looks for comments that seem to be mostly valid code and reports them.