Monitoring/CustomVarRenderer: Support rendering dictionary values

This commit is contained in:
raviks789 2024-08-27 17:09:18 +02:00 committed by Johannes Meyer
parent b082db707e
commit 1d98492429
1 changed files with 170 additions and 0 deletions

View File

@ -14,8 +14,11 @@ use Icinga\Module\Monitoring\Object\Host;
use Icinga\Module\Monitoring\Object\MonitoredObject;
use Icinga\Module\Monitoring\Object\Service;
use ipl\Html\Attributes;
use ipl\Html\Html;
use ipl\Html\HtmlDocument;
use ipl\Html\HtmlElement;
use ipl\Html\Text;
use ipl\Html\ValidHtml;
class CustomVarRenderer extends CustomVarRendererHook
{
@ -25,6 +28,18 @@ class CustomVarRenderer extends CustomVarRendererHook
/** @var array Related datalists and their keys and values */
protected $datalistMaps = [];
/** @var array Related dictionary names */
protected $dictionaryNames = [];
/** @var int The nesting level for dictionary */
protected $dictionaryLevel = 0;
/** @var HtmlElement Table for dictionary fields */
private $dictionaryTable;
/** @var HtmlElement Table body for dictionary fields */
private $dictionaryBody;
/**
* Get a database connection to the director database
*
@ -88,6 +103,8 @@ class CustomVarRenderer extends CustomVarRendererHook
if ($field->get('datatype') === 'Icinga\Module\Director\DataType\DataTypeDatalist') {
$fieldsWithDataLists[$field->get('id')] = $field;
} elseif ($field->get('datatype') === 'Icinga\Module\Director\DataType\DataTypeDictionary') {
$this->dictionaryNames[] = $field->get('varname');
}
}
@ -139,8 +156,12 @@ class CustomVarRenderer extends CustomVarRendererHook
Attributes::create(['title' => $this->datalistMaps[$key][$value] . " [$value]"]),
Text::create($this->datalistMaps[$key][$value])
);
} elseif ($value !== null && in_array($key, $this->dictionaryNames)) {
return $this->renderDictionaryVal($key, (array) $value);
}
}
return null;
}
public function identifyCustomVarGroup($key)
@ -149,4 +170,153 @@ class CustomVarRenderer extends CustomVarRendererHook
return $this->fieldConfig[$key]['group'];
}
}
/**
* Render the dictionary value
*
* @param string $key
* @param array $value
*
* @return ?ValidHtml
*/
protected function renderDictionaryVal(string $key, array $value): ?ValidHtml
{
if ($this->dictionaryLevel > 0) {
$numItems = count($value);
$label = $this->renderCustomVarKey($key) ?? $key;
$this->dictionaryBody->addHtml(
new HtmlElement(
'tr',
Attributes::create(['class' => "level-{$this->dictionaryLevel}"]),
new HtmlElement('th', null, Html::wantHtml($label)),
new HtmlElement(
'td',
null,
Text::create(sprintf(tp('%d item', '%d items', $numItems), $numItems))
)
)
);
} else {
$this->dictionaryTable = new HtmlElement(
'table',
Attributes::create(['class' => ['custom-var-table', 'name-value-table']])
);
$this->dictionaryBody = new HtmlElement('tbody');
}
$this->dictionaryLevel++;
foreach ($value as $key => $val) {
if ($key !== null && is_array($val) || is_object($val)) {
$val = (array) $val;
$numChildItems = count($val);
$this->dictionaryBody->addHtml(
new HtmlElement(
'tr',
Attributes::create(['class' => "level-{$this->dictionaryLevel}"]),
new HtmlElement('th', null, Html::wantHtml($key)),
new HtmlElement(
'td',
null,
Text::create(sprintf(tp('%d item', '%d items', $numChildItems), $numChildItems))
)
)
);
$this->dictionaryLevel++;
foreach ($val as $childKey => $childVal) {
$childVal = $this->renderCustomVarValue($childKey, $childVal) ?? $childVal;
if (! in_array($childKey, $this->dictionaryNames)) {
$label = $this->renderCustomVarKey($childKey) ?? $childKey;
if (is_array($childVal)) {
$this->renderArrayVal($label, $childVal);
} else {
$this->dictionaryBody->addHtml(
new HtmlElement(
'tr',
Attributes::create(['class' => "level-{$this->dictionaryLevel}"]),
new HtmlElement('th', null, Html::wantHtml(
$label
)),
new HtmlElement('td', null, Html::wantHtml($childVal))
)
);
}
}
}
$this->dictionaryLevel--;
} elseif (is_array($val)) {
$this->renderArrayVal(Html::wantHtml($key), $val);
} else {
$this->dictionaryBody->addHtml(
new HtmlElement(
'tr',
Attributes::create(['class' => "level-{$this->dictionaryLevel}"]),
new HtmlElement('th', null, Html::wantHtml($key)),
new HtmlElement('td', null, Html::wantHtml($val))
)
);
}
}
$this->dictionaryLevel--;
if ($this->dictionaryLevel === 0) {
return $this->dictionaryTable->addHtml($this->dictionaryBody);
}
return null;
}
/**
* Render an array
*
* @param HtmlElement|string $name
* @param array $array
*
* @return void
*/
protected function renderArrayVal($name, array $array)
{
$numItems = count($array);
if ($name instanceof HtmlElement) {
$name->addHtml(Text::create(' (Array)'));
} else {
$name = (new HtmlDocument())->addHtml(
Html::wantHtml($name),
Text::create(' (Array)')
);
}
$this->dictionaryBody->addHtml(
new HtmlElement(
'tr',
Attributes::create(['class' => "level-{$this->dictionaryLevel}"]),
new HtmlElement('th', null, Html::wantHtml($name)),
new HtmlElement('td', null, Html::wantHtml(sprintf(tp('%d item', '%d items', $numItems), $numItems)))
)
);
++$this->dictionaryLevel;
ksort($array);
foreach ($array as $key => $value) {
$this->dictionaryBody->addHtml(
new HtmlElement(
'tr',
Attributes::create(['class' => "level-{$this->dictionaryLevel}"]),
new HtmlElement('th', null, Html::wantHtml("[$key]")),
new HtmlElement('td', null, Html::wantHtml($value))
)
);
}
--$this->dictionaryLevel;
}
}