Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
57.14% |
36 / 63 |
|
25.00% |
1 / 4 |
CRAP | |
0.00% |
0 / 1 |
LocalSearchTaskSuggester | |
57.14% |
36 / 63 |
|
25.00% |
1 / 4 |
17.87 | |
0.00% |
0 / 1 |
__construct | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
1 | |||
suggest | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
2 | |||
filter | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
2 | |||
search | |
68.09% |
32 / 47 |
|
0.00% |
0 / 1 |
8.59 |
1 | <?php |
2 | |
3 | namespace GrowthExperiments\NewcomerTasks\TaskSuggester; |
4 | |
5 | use GrowthExperiments\NewcomerTasks\NewcomerTasksUserOptionsLookup; |
6 | use GrowthExperiments\NewcomerTasks\Task\TaskSet; |
7 | use GrowthExperiments\NewcomerTasks\Task\TaskSetFilters; |
8 | use GrowthExperiments\NewcomerTasks\TaskSuggester\SearchStrategy\SearchQuery; |
9 | use GrowthExperiments\NewcomerTasks\TaskSuggester\SearchStrategy\SearchStrategy; |
10 | use GrowthExperiments\NewcomerTasks\TaskType\TaskType; |
11 | use GrowthExperiments\NewcomerTasks\TaskType\TaskTypeHandlerRegistry; |
12 | use GrowthExperiments\NewcomerTasks\Topic\Topic; |
13 | use ISearchResultSet; |
14 | use MediaWiki\Api\ApiRawMessage; |
15 | use MediaWiki\Cache\LinkBatchFactory; |
16 | use MediaWiki\SpecialPage\SpecialPage; |
17 | use MediaWiki\User\UserIdentity; |
18 | use SearchEngine; |
19 | use SearchEngineFactory; |
20 | use StatusValue; |
21 | use Wikimedia\Stats\IBufferingStatsdDataFactory; |
22 | |
23 | /** |
24 | * Suggest edits based on searching the wiki via SearchEngine. |
25 | */ |
26 | class LocalSearchTaskSuggester extends SearchTaskSuggester { |
27 | |
28 | /** @var SearchEngineFactory */ |
29 | private $searchEngineFactory; |
30 | |
31 | /** @var IBufferingStatsdDataFactory */ |
32 | private $statsdDataFactory; |
33 | |
34 | /** |
35 | * @param TaskTypeHandlerRegistry $taskTypeHandlerRegistry |
36 | * @param SearchEngineFactory $searchEngineFactory |
37 | * @param SearchStrategy $searchStrategy |
38 | * @param NewcomerTasksUserOptionsLookup $newcomerTasksUserOptionsLookup |
39 | * @param LinkBatchFactory $linkBatchFactory |
40 | * @param TaskType[] $taskTypes |
41 | * @param Topic[] $topics |
42 | * @param IBufferingStatsdDataFactory $statsdDataFactory |
43 | */ |
44 | public function __construct( |
45 | TaskTypeHandlerRegistry $taskTypeHandlerRegistry, |
46 | SearchEngineFactory $searchEngineFactory, |
47 | SearchStrategy $searchStrategy, |
48 | NewcomerTasksUserOptionsLookup $newcomerTasksUserOptionsLookup, |
49 | LinkBatchFactory $linkBatchFactory, |
50 | array $taskTypes, |
51 | array $topics, |
52 | IBufferingStatsdDataFactory $statsdDataFactory |
53 | ) { |
54 | parent::__construct( $taskTypeHandlerRegistry, $searchStrategy, $newcomerTasksUserOptionsLookup, |
55 | $linkBatchFactory, $taskTypes, $topics ); |
56 | $this->searchEngineFactory = $searchEngineFactory; |
57 | $this->statsdDataFactory = $statsdDataFactory; |
58 | } |
59 | |
60 | /** @inheritDoc */ |
61 | public function suggest( |
62 | UserIdentity $user, |
63 | TaskSetFilters $taskSetFilters, |
64 | ?int $limit = null, |
65 | ?int $offset = null, |
66 | array $options = [] |
67 | ) { |
68 | $start = microtime( true ); |
69 | $suggest = parent::suggest( $user, $taskSetFilters, $limit, $offset, $options ); |
70 | $this->statsdDataFactory->timing( |
71 | 'timing.growthExperiments.SearchTaskSuggester.suggest', microtime( true ) - $start |
72 | ); |
73 | return $suggest; |
74 | } |
75 | |
76 | /** @inheritDoc */ |
77 | public function filter( UserIdentity $user, TaskSet $taskSet ) { |
78 | $start = microtime( true ); |
79 | $filter = parent::filter( $user, $taskSet ); |
80 | $this->statsdDataFactory->timing( |
81 | 'timing.growthExperiments.SearchTaskSuggester.filter', microtime( true ) - $start |
82 | ); |
83 | return $filter; |
84 | } |
85 | |
86 | /** |
87 | * @inheritDoc |
88 | */ |
89 | protected function search( |
90 | SearchQuery $query, |
91 | int $limit, |
92 | int $offset, |
93 | bool $debug |
94 | ) { |
95 | $start = microtime( true ); |
96 | $searchEngine = $this->searchEngineFactory->create(); |
97 | $searchEngine->setLimitOffset( $limit, $offset ); |
98 | $searchEngine->setNamespaces( [ NS_MAIN ] ); |
99 | $searchEngine->setShowSuggestion( false ); |
100 | $searchEngine->setFeatureData( |
101 | SearchEngine::FT_QUERY_INDEP_PROFILE_TYPE, |
102 | $query->getRescoreProfile() ?? 'classic_noboostlinks' |
103 | ); |
104 | $sort = $query->getSort(); |
105 | if ( $sort ) { |
106 | $searchEngine->setSort( $sort ); |
107 | } |
108 | $matches = $searchEngine->searchText( $query->getQueryString() ); |
109 | if ( !$matches ) { |
110 | $matches = StatusValue::newFatal( new ApiRawMessage( |
111 | 'Full text searches are unsupported or disabled', |
112 | 'grothexperiments-no-fulltext-search' |
113 | ) ); |
114 | } elseif ( $matches instanceof StatusValue ) { |
115 | if ( $matches->isGood() ) { |
116 | $matches = $matches->getValue(); |
117 | /** @var ISearchResultSet $matches */ |
118 | } else { |
119 | // T302473 make sure the result is serializable |
120 | $matches->setResult( false, null ); |
121 | } |
122 | } |
123 | |
124 | if ( $debug ) { |
125 | $params = [ |
126 | 'search' => $query->getQueryString(), |
127 | 'fulltext' => 1, |
128 | 'ns0' => 1, |
129 | 'limit' => $limit, |
130 | 'offset' => $offset, |
131 | 'cirrusRescoreProfile' => $query->getRescoreProfile() ?? 'classic_noboostlinks', |
132 | 'cirrusDumpResult' => 1, |
133 | 'cirrusExplain' => 'pretty', |
134 | ]; |
135 | if ( $query->getSort() ) { |
136 | $params['sort'] = $query->getSort(); |
137 | } |
138 | $query->setDebugUrl( SpecialPage::getTitleFor( 'Search' ) |
139 | ->getFullURL( $params, false, PROTO_CANONICAL ) ); |
140 | } |
141 | $elapsed = microtime( true ) - $start; |
142 | $this->logger->debug( 'LocalSearchTaskSuggester query', [ |
143 | 'query' => $query->getQueryString(), |
144 | 'sort' => $query->getSort(), |
145 | 'limit' => $limit, |
146 | 'success' => $matches instanceof ISearchResultSet, |
147 | 'elapsedTime' => $elapsed |
148 | ] ); |
149 | $this->statsdDataFactory->timing( 'timing.growthExperiments.LocalSearchTaskSuggester.search', $elapsed ); |
150 | |
151 | return $matches; |
152 | } |
153 | |
154 | } |