Skip to content

Commit d0ffba3

Browse files
authored
ObjectSuggestions: Prioritze Column suggestions and best suggestions (#1215)
Show custom variable suggestions only if the column suggestions have not consumed all the slots (50). fixes #1206
1 parent b5040b2 commit d0ffba3

File tree

1 file changed

+69
-53
lines changed

1 file changed

+69
-53
lines changed

library/Icingadb/Web/Control/SearchBar/ObjectSuggestions.php

Lines changed: 69 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -221,16 +221,23 @@ protected function fetchColumnSuggestions($searchTerm)
221221
$model = $this->getModel();
222222
$query = $model::on($this->getDb());
223223

224-
// Collect custom variables first and check for exact matches
225224
$parsedArrayVars = [];
226-
$varSuggestions = [];
227-
$exactVarMatches = [];
228-
$halfLimit = (int) (static::DEFAULT_LIMIT / 2);
229-
230225
$exactSearchTerm = trim($searchTerm, ' *');
226+
$exactVarSearches = [];
227+
$titleAdded = false;
228+
229+
// Suggest exact custom variable matches first
231230
if ($exactSearchTerm !== '') {
232-
foreach ($this->getDb()->select($this->queryCustomvarConfig($searchTerm)) as $customVar) {
231+
foreach (
232+
$this->getDb()->select($this->queryCustomvarConfig(
233+
Filter::any(
234+
Filter::equal('flatname', $exactSearchTerm),
235+
Filter::like('flatname', $exactSearchTerm . '[*]') // Filter for array type custom variables
236+
)
237+
)) as $customVar
238+
) {
233239
$search = $name = $customVar->flatname;
240+
$exactVarSearches[] = $search;
234241
if (preg_match('/\w+(?:\[(\d*)])+$/', $search, $matches)) {
235242
$name = substr($search, 0, -(strlen($matches[1]) + 2));
236243
if (isset($parsedArrayVars[$name])) {
@@ -243,71 +250,79 @@ protected function fetchColumnSuggestions($searchTerm)
243250

244251
foreach ($this->customVarSources as $relation => $label) {
245252
if (isset($customVar->$relation)) {
246-
$varRelation = $relation . '.vars.' . $search;
247-
$varLabel = sprintf($label, $name);
248-
if ($name === $exactSearchTerm) {
249-
$exactVarMatches[$varRelation] = $varLabel;
250-
} elseif ($this->matchSuggestion($varRelation, $varLabel, $searchTerm)) {
251-
$varSuggestions[$varRelation] = $varLabel;
253+
if ($titleAdded === false) {
254+
$this->addHtml(HtmlElement::create(
255+
'li',
256+
['class' => static::SUGGESTION_TITLE_CLASS],
257+
t('Best Suggestions')
258+
));
259+
260+
$titleAdded = true;
252261
}
262+
263+
yield $relation . '.vars.' . $search => sprintf($label, $name);
253264
}
254265
}
255266
}
256267
}
257268

258-
// Adjust the number of columns to be suggested based on custom variable count
259-
$varCount = count($exactVarMatches) + count($varSuggestions);
260-
$colLimit = $halfLimit;
261-
if ($varCount < $halfLimit) {
262-
$colLimit = $halfLimit + ($halfLimit - $varCount);
263-
}
264-
265-
// Exact custom variable matches first
266-
if (! empty($exactVarMatches)) {
267-
$this->addHtml(HtmlElement::create(
268-
'li',
269-
['class' => static::SUGGESTION_TITLE_CLASS],
270-
t('Best Suggestions')
271-
));
272-
273-
foreach ($exactVarMatches as $relation => $label) {
274-
yield $relation => $label;
275-
}
276-
}
277-
278269
// Ordinary columns comes after exact matches,
279270
// or if there ar no exact matches they come first
280-
$colCount = 0;
271+
$titleAdded = false;
281272
foreach (self::collectFilterColumns($model, $query->getResolver()) as $columnName => $columnMeta) {
282-
if ($colCount > $colLimit) {
283-
break;
284-
}
285-
286273
if ($this->matchSuggestion($columnName, $columnMeta, $searchTerm)) {
287-
if ($colCount === 0) {
274+
if ($titleAdded === false) {
288275
$this->addHtml(HtmlElement::create(
289276
'li',
290277
['class' => static::SUGGESTION_TITLE_CLASS],
291278
t('Columns')
292279
));
293-
}
294280

295-
$colCount++;
281+
$titleAdded = true;
282+
}
296283

297284
yield $columnName => $columnMeta;
298285
}
299286
}
300287

301288
// Finally, the other custom variable suggestions
302-
if (! empty($varSuggestions)) {
303-
$this->addHtml(HtmlElement::create(
304-
'li',
305-
['class' => static::SUGGESTION_TITLE_CLASS],
306-
t('Custom Variables')
307-
));
308-
309-
foreach ($varSuggestions as $relation => $label) {
310-
yield $relation => $label;
289+
$titleAdded = false;
290+
if (! empty($exactVarSearches)) {
291+
$varFilter = Filter::all(
292+
Filter::like('flatname', $searchTerm),
293+
Filter::unequal('flatname', $exactVarSearches)
294+
);
295+
} else {
296+
$varFilter = Filter::like('flatname', $searchTerm);
297+
}
298+
299+
foreach ($this->getDb()->select($this->queryCustomvarConfig($varFilter)) as $customVar) {
300+
$search = $name = $customVar->flatname;
301+
if (preg_match('/\w+(?:\[(\d*)])+$/', $search, $matches)) {
302+
$name = substr($search, 0, -(strlen($matches[1]) + 2));
303+
if (isset($parsedArrayVars[$name])) {
304+
continue;
305+
}
306+
307+
$parsedArrayVars[$name] = true;
308+
$search = $name . '[*]';
309+
}
310+
311+
foreach ($this->customVarSources as $relation => $label) {
312+
if (isset($customVar->$relation)) {
313+
// Suggest exact custom variable matches first
314+
if ($titleAdded === false) {
315+
$this->addHtml(HtmlElement::create(
316+
'li',
317+
['class' => static::SUGGESTION_TITLE_CLASS],
318+
t('Custom Variables')
319+
));
320+
321+
$titleAdded = true;
322+
}
323+
324+
yield $relation . '.vars.' . $search => sprintf($label, $name);
325+
}
311326
}
312327
}
313328
}
@@ -324,13 +339,13 @@ protected function matchSuggestion($path, $label, $searchTerm)
324339
}
325340

326341
/**
327-
* Create a query to fetch all available custom variables matching the given term
342+
* Create a query to fetch all available custom variables matching the given filter
328343
*
329-
* @param string $searchTerm
344+
* @param Filter\Rule $filter
330345
*
331346
* @return Select
332347
*/
333-
protected function queryCustomvarConfig(string $searchTerm): Select
348+
protected function queryCustomvarConfig(Filter\Rule $filter): Select
334349
{
335350
$customVars = CustomvarFlat::on($this->getDb());
336351
$tableName = $customVars->getModel()->getTableName();
@@ -356,7 +371,8 @@ protected function queryCustomvarConfig(string $searchTerm): Select
356371

357372
$customVars->columns('flatname');
358373
$this->applyRestrictions($customVars);
359-
$customVars->filter(Filter::like('flatname', $searchTerm));
374+
$customVars->filter($filter);
375+
360376
$idColumn = $resolver->qualifyColumn('id', $resolver->getAlias($customVars->getModel()));
361377
$customVars = $customVars->assembleSelect();
362378

0 commit comments

Comments
 (0)