Ejemplo n.º 1
0
/**
 * Create DIV with latest problem triggers.
 *
 * If no sortfield and sortorder are defined, the sort indicater in the column name will not be displayed.
 *
 * @param array  $filter['screenid']
 * @param array  $filter['groupids']
 * @param array  $filter['hostids']
 * @param array  $filter['maintenance']
 * @param int    $filter['extAck']
 * @param int    $filter['severity']
 * @param int    $filter['limit']
 * @param string $filter['sortfield']
 * @param string $filter['sortorder']
 * @param string $filter['backUrl']
 *
 * @return CDiv
 */
function make_latest_issues(array $filter = array())
{
    // hide the sort indicator if no sortfield and sortorder are given
    $showSortIndicator = isset($filter['sortfield']) || isset($filter['sortorder']);
    if (!isset($filter['sortfield'])) {
        $filter['sortfield'] = 'lastchange';
    }
    if (!isset($filter['sortorder'])) {
        $filter['sortorder'] = ZBX_SORT_DOWN;
    }
    $options = array('groupids' => $filter['groupids'], 'hostids' => isset($filter['hostids']) ? $filter['hostids'] : null, 'monitored' => true, 'maintenance' => $filter['maintenance'], 'filter' => array('priority' => $filter['severity'], 'value' => TRIGGER_VALUE_TRUE));
    $triggers = API::Trigger()->get(array_merge($options, array('withLastEventUnacknowledged' => isset($filter['extAck']) && $filter['extAck'] == EXTACK_OPTION_UNACK ? true : null, 'skipDependent' => true, 'output' => array('triggerid', 'state', 'error', 'url', 'expression', 'description', 'priority', 'lastchange'), 'selectHosts' => array('hostid', 'name'), 'selectLastEvent' => array('eventid', 'acknowledged', 'objectid', 'clock', 'ns'), 'sortfield' => $filter['sortfield'], 'sortorder' => $filter['sortorder'], 'limit' => isset($filter['limit']) ? $filter['limit'] : DEFAULT_LATEST_ISSUES_CNT)));
    // don't use withLastEventUnacknowledged and skipDependent because of performance issues
    $triggersTotalCount = API::Trigger()->get(array_merge($options, array('countOutput' => true)));
    // get acknowledges
    $eventIds = array();
    foreach ($triggers as $trigger) {
        if ($trigger['lastEvent']) {
            $eventIds[] = $trigger['lastEvent']['eventid'];
        }
    }
    if ($eventIds) {
        $eventAcknowledges = API::Event()->get(array('eventids' => $eventIds, 'select_acknowledges' => API_OUTPUT_EXTEND, 'preservekeys' => true));
    }
    foreach ($triggers as $tnum => $trigger) {
        // if trigger is lost (broken expression) we skip it
        if (empty($trigger['hosts'])) {
            unset($triggers[$tnum]);
            continue;
        }
        $host = reset($trigger['hosts']);
        $trigger['hostid'] = $host['hostid'];
        $trigger['hostname'] = $host['name'];
        if ($trigger['lastEvent']) {
            $trigger['lastEvent']['acknowledges'] = isset($eventAcknowledges[$trigger['lastEvent']['eventid']]) ? $eventAcknowledges[$trigger['lastEvent']['eventid']]['acknowledges'] : null;
        }
        $triggers[$tnum] = $trigger;
    }
    $hostIds = zbx_objectValues($triggers, 'hostid');
    // get hosts
    $hosts = API::Host()->get(array('hostids' => $hostIds, 'output' => array('hostid', 'name', 'status', 'maintenance_status', 'maintenance_type', 'maintenanceid'), 'selectScreens' => API_OUTPUT_COUNT, 'preservekeys' => true));
    // actions
    $actions = getEventActionsStatHints($eventIds);
    // ack params
    $ackParams = isset($filter['screenid']) ? array('screenid' => $filter['screenid']) : array();
    $config = select_config();
    // indicator of sort field
    if ($showSortIndicator) {
        $sortDiv = new CDiv(SPACE, $filter['sortorder'] === ZBX_SORT_DOWN ? 'icon_sortdown default_cursor' : 'icon_sortup default_cursor');
        $sortDiv->addStyle('float: left');
        $hostHeaderDiv = new CDiv(array(_('Host'), SPACE));
        $hostHeaderDiv->addStyle('float: left');
        $issueHeaderDiv = new CDiv(array(_('Issue'), SPACE));
        $issueHeaderDiv->addStyle('float: left');
        $lastChangeHeaderDiv = new CDiv(array(_('Time'), SPACE));
        $lastChangeHeaderDiv->addStyle('float: left');
    }
    $table = new CTableInfo(_('No events found.'));
    $table->setHeader(array(is_show_all_nodes() ? _('Node') : null, $showSortIndicator && $filter['sortfield'] === 'hostname' ? array($hostHeaderDiv, $sortDiv) : _('Host'), $showSortIndicator && $filter['sortfield'] === 'priority' ? array($issueHeaderDiv, $sortDiv) : _('Issue'), $showSortIndicator && $filter['sortfield'] === 'lastchange' ? array($lastChangeHeaderDiv, $sortDiv) : _('Last change'), _('Age'), _('Info'), $config['event_ack_enable'] ? _('Ack') : null, _('Actions')));
    $scripts = API::Script()->getScriptsByHosts($hostIds);
    // triggers
    foreach ($triggers as $trigger) {
        $host = $hosts[$trigger['hostid']];
        $hostName = new CSpan($host['name'], 'link_menu');
        $hostName->setMenuPopup(getMenuPopupHost($host, $scripts[$host['hostid']]));
        // add maintenance icon with hint if host is in maintenance
        $maintenanceIcon = null;
        if ($host['maintenance_status']) {
            $maintenanceIcon = new CDiv(null, 'icon-maintenance-abs');
            // get maintenance
            $maintenances = API::Maintenance()->get(array('maintenanceids' => $host['maintenanceid'], 'output' => API_OUTPUT_EXTEND, 'limit' => 1));
            if ($maintenance = reset($maintenances)) {
                $hint = $maintenance['name'] . ' [' . ($host['maintenance_type'] ? _('Maintenance without data collection') : _('Maintenance with data collection')) . ']';
                if (isset($maintenance['description'])) {
                    // double quotes mandatory
                    $hint .= "\n" . $maintenance['description'];
                }
                $maintenanceIcon->setHint($hint);
                $maintenanceIcon->addClass('pointer');
            }
            $hostName->addClass('left-to-icon-maintenance-abs');
        }
        $hostDiv = new CDiv(array($hostName, $maintenanceIcon), 'maintenance-abs-cont');
        // unknown triggers
        $unknown = SPACE;
        if ($trigger['state'] == TRIGGER_STATE_UNKNOWN) {
            $unknown = new CDiv(SPACE, 'status_icon iconunknown');
            $unknown->setHint($trigger['error'], '', 'on');
        }
        // trigger has events
        if ($trigger['lastEvent']) {
            // description
            $description = CMacrosResolverHelper::resolveEventDescription(zbx_array_merge($trigger, array('clock' => $trigger['lastEvent']['clock'], 'ns' => $trigger['lastEvent']['ns'])));
            // ack
            $ack = getEventAckState($trigger['lastEvent'], empty($filter['backUrl']) ? true : $filter['backUrl'], true, $ackParams);
        } else {
            // description
            $description = CMacrosResolverHelper::resolveEventDescription(zbx_array_merge($trigger, array('clock' => $trigger['lastchange'], 'ns' => '999999999')));
            // ack
            $ack = new CSpan(_('No events'), 'unknown');
        }
        // description
        if (!zbx_empty($trigger['url'])) {
            $description = new CLink($description, resolveTriggerUrl($trigger), null, null, true);
        } else {
            $description = new CSpan($description, 'pointer');
        }
        $description = new CCol($description, getSeverityStyle($trigger['priority']));
        if ($trigger['lastEvent']) {
            $description->setHint(make_popup_eventlist($trigger['triggerid'], $trigger['lastEvent']['eventid']), '', '', false);
        }
        // clock
        $clock = new CLink(zbx_date2str(_('d M Y H:i:s'), $trigger['lastchange']), 'events.php?triggerid=' . $trigger['triggerid'] . '&source=0&show_unknown=1&nav_time=' . $trigger['lastchange']);
        // actions
        $actionHint = $trigger['lastEvent'] && isset($actions[$trigger['lastEvent']['eventid']]) ? $actions[$trigger['lastEvent']['eventid']] : SPACE;
        $table->addRow(array(get_node_name_by_elid($trigger['triggerid']), $hostDiv, $description, $clock, zbx_date2age($trigger['lastchange']), $unknown, $ack, $actionHint));
    }
    // initialize blinking
    zbx_add_post_js('jqBlink.blink();');
    $script = new CJSScript(get_js("jQuery('#hat_lastiss_footer').html('" . _s('Updated: %s', zbx_date2str(_('H:i:s'))) . "')"));
    $infoDiv = new CDiv(_n('%1$d of %2$d issue is shown', '%1$d of %2$d issues are shown', count($triggers), $triggersTotalCount));
    $infoDiv->addStyle('text-align: right; padding-right: 3px;');
    return new CDiv(array($table, $infoDiv, $script));
}
    $ifTab->setAttribute('data-type', 'jmx');
    $helpTextWhenDragInterfaceJMX = new CSpan(_('Drag here to change the type of the interface to "JMX" type.'));
    $helpTextWhenDragInterfaceJMX->addClass('dragHelpText');
    $buttonCol = new CCol(new CButton('addJMXInterface', _('Add'), null, 'link_menu'), 'interface-add-control');
    $col = new CCol($helpTextWhenDragInterfaceJMX);
    $col->setAttribute('colspan', 6);
    $buttonRow = new CRow(array($buttonCol, $col));
    $buttonRow->setAttribute('id', 'JMXIterfacesFooter');
    $ifTab->addRow($buttonRow);
    $hostList->addRow(_('JMX interfaces'), new CDiv($ifTab, 'border_dotted objectgroup inlineblock interface-group'), false, null, 'interface-row');
    // table for IPMI interfaces with footer
    $ifTab = new CTable(null, 'formElementTable');
    $ifTab->setAttribute('id', 'IPMIInterfaces');
    $ifTab->setAttribute('data-type', 'ipmi');
    $helpTextWhenDragInterfaceIPMI = new CSpan(_('Drag here to change the type of the interface to "IPMI" type.'));
    $helpTextWhenDragInterfaceIPMI->addClass('dragHelpText');
    $buttonCol = new CCol(new CButton('addIPMIInterface', _('Add'), null, 'link_menu'), 'interface-add-control');
    $col = new CCol($helpTextWhenDragInterfaceIPMI);
    $col->setAttribute('colspan', 6);
    $buttonRow = new CRow(array($buttonCol, $col));
    $buttonRow->setAttribute('id', 'IPMIIterfacesFooter');
    $ifTab->addRow($buttonRow);
    $hostList->addRow(_('IPMI interfaces'), new CDiv($ifTab, 'border_dotted objectgroup inlineblock interface-group'), false, null, 'interface-row');
} else {
    $interfaces = array();
    $existingInterfaceTypes = array();
    foreach ($dbHost['interfaces'] as $interface) {
        $interface['locked'] = true;
        $existingInterfaceTypes[$interface['type']] = true;
        $interfaces[$interface['interfaceid']] = $interface;
    }
Ejemplo n.º 3
0
        $triggers_link = [new CLink(_('Triggers'), 'triggers.php?' . $link), CViewHelper::showNum($host['triggers'])];
        $graphs_link = [new CLink(_('Graphs'), 'graphs.php?' . $link), CViewHelper::showNum($host['graphs'])];
        $discoveryLink = [new CLink(_('Discovery'), 'host_discovery.php?' . $link), CViewHelper::showNum($host['discoveries'])];
        $httpTestsLink = [new CLink(_('Web'), 'httpconf.php?' . $link), CViewHelper::showNum($host['httpTests'])];
    } else {
        // host
        $host_name = new CSpan($visibleName);
        $applications_link = [_('Applications'), CViewHelper::showNum($host['applications'])];
        $items_link = [_('Items'), CViewHelper::showNum($host['items'])];
        $triggers_link = [_('Triggers'), CViewHelper::showNum($host['triggers'])];
        $graphs_link = [_('Graphs'), CViewHelper::showNum($host['graphs'])];
        $discoveryLink = [_('Discovery'), CViewHelper::showNum($host['discoveries'])];
        $httpTestsLink = [_('Web'), CViewHelper::showNum($host['httpTests'])];
    }
    if ($host['status'] == HOST_STATUS_NOT_MONITORED) {
        $host_name->addClass(ZBX_STYLE_LINK_ALT)->addClass(ZBX_STYLE_RED);
    }
    // display the host name only if it matches the search string and is different from the visible name
    if ($host['host'] !== $host['name'] && stripos($host['host'], $search) !== false) {
        $host_name = [$host_name, BR(), '(', make_decoration($host['host'], $search), ')'];
    }
    $hostip = make_decoration($host['ip'], $search);
    $hostdns = make_decoration($host['dns'], $search);
    $table->addRow([$host_name, $hostip, $hostdns, new CLink(_('Latest data'), 'latest.php?filter_set=1&hostids[]=' . $hostid), new CLink(_('Triggers'), 'tr_status.php?' . $link), new CLink(_('Events'), 'events.php?source=' . EVENT_SOURCE_TRIGGERS . '&' . $link), new CLink(_('Graphs'), 'charts.php?' . $link), new CLink(_('Screens'), 'host_screen.php?hostid=' . $hostid), new CLink(_('Web'), 'zabbix.php?action=web.view&' . $link), $applications_link, $items_link, $triggers_link, $graphs_link, $discoveryLink, $httpTestsLink]);
}
$widgets = [];
$widgets[] = (new CCollapsibleUiWidget(WIDGET_SEARCH_HOSTS, $table))->setExpanded((bool) CProfile::get('web.search.hats.' . WIDGET_SEARCH_HOSTS . '.state', true))->setHeader(_('Hosts'), [], false, 'search.php')->setFooter(new CList([_s('Displaying %1$s of %2$s found', $viewCount, $overalCount)]));
// Find Host groups
$params = ['output' => API_OUTPUT_EXTEND, 'selectHosts' => API_OUTPUT_COUNT, 'selectTemplates' => API_OUTPUT_COUNT, 'search' => ['name' => $search], 'limit' => $rows_per_page];
$db_hostGroups = API::HostGroup()->get($params);
order_result($db_hostGroups, 'name');
     $step['name'] = '';
 }
 if (!isset($step['timeout'])) {
     $step['timeout'] = 15;
 }
 if (!isset($step['url'])) {
     $step['url'] = '';
 }
 if (!isset($step['posts'])) {
     $step['posts'] = '';
 }
 if (!isset($step['required'])) {
     $step['required'] = '';
 }
 $numSpan = new CSpan($i++ . ':');
 $numSpan->addClass('rowNum');
 $numSpan->setAttribute('id', 'current_step_' . $stepid);
 $name = new CSpan($step['name'], 'link');
 $name->setAttributes(array('id' => 'name_' . $stepid, 'name_step' => $stepid));
 if (zbx_strlen($step['url']) > 70) {
     $url = new CSpan(substr($step['url'], 0, 35) . SPACE . '...' . SPACE . substr($step['url'], zbx_strlen($step['url']) - 25, 25));
     $url->setHint($step['url']);
 } else {
     $url = $step['url'];
 }
 if ($this->data['templated']) {
     $removeButton = SPACE;
     $dragHandler = SPACE;
 } else {
     $removeButton = new CButton('remove_' . $stepid, _('Remove'), 'javascript: removeStep(this);', 'link_menu');
     $removeButton->setAttribute('remove_step', $stepid);
Ejemplo n.º 5
0
/**
 * Create CDiv with host/template information and references to it's elements
 *
 * @param string $currentElement
 * @param int $hostid
 * @param int $lld_ruleid
 *
 * @return object
 */
function get_header_host_table($current_element, $hostid, $lld_ruleid = 0)
{
    $options = ['output' => ['hostid', 'status', 'proxy_hostid', 'name', 'maintenance_status', 'flags', 'available', 'snmp_available', 'jmx_available', 'ipmi_available', 'error', 'snmp_error', 'jmx_error', 'ipmi_error'], 'selectHostDiscovery' => ['ts_delete'], 'hostids' => [$hostid], 'editable' => true];
    if ($lld_ruleid == 0) {
        $options['selectApplications'] = API_OUTPUT_COUNT;
        $options['selectItems'] = API_OUTPUT_COUNT;
        $options['selectTriggers'] = API_OUTPUT_COUNT;
        $options['selectGraphs'] = API_OUTPUT_COUNT;
        $options['selectDiscoveries'] = API_OUTPUT_COUNT;
        $options['selectHttpTests'] = API_OUTPUT_COUNT;
    }
    // get hosts
    $db_host = API::Host()->get($options);
    if (!$db_host) {
        $options = ['output' => ['templateid', 'name', 'flags'], 'templateids' => [$hostid], 'editable' => true];
        if ($lld_ruleid == 0) {
            $options['selectApplications'] = API_OUTPUT_COUNT;
            $options['selectItems'] = API_OUTPUT_COUNT;
            $options['selectTriggers'] = API_OUTPUT_COUNT;
            $options['selectGraphs'] = API_OUTPUT_COUNT;
            $options['selectScreens'] = API_OUTPUT_COUNT;
            $options['selectDiscoveries'] = API_OUTPUT_COUNT;
            $options['selectHttpTests'] = API_OUTPUT_COUNT;
        }
        // get templates
        $db_host = API::Template()->get($options);
        $is_template = true;
    } else {
        $is_template = false;
    }
    if (!$db_host) {
        return null;
    }
    $db_host = reset($db_host);
    // get lld-rules
    if ($lld_ruleid != 0) {
        $db_discovery_rule = API::DiscoveryRule()->get(['output' => ['name'], 'selectItems' => API_OUTPUT_COUNT, 'selectTriggers' => API_OUTPUT_COUNT, 'selectGraphs' => API_OUTPUT_COUNT, 'selectHostPrototypes' => API_OUTPUT_COUNT, 'itemids' => [$lld_ruleid], 'editable' => true]);
        $db_discovery_rule = reset($db_discovery_rule);
    }
    /*
     * list and host (template) name
     */
    $list = (new CList())->addClass(ZBX_STYLE_OBJECT_GROUP);
    if ($is_template) {
        $template = new CSpan(new CLink($db_host['name'], 'templates.php?form=update&templateid=' . $db_host['templateid']));
        if ($current_element === '') {
            $template->addClass(ZBX_STYLE_SELECTED);
        }
        $list->addItem([new CSpan(new CLink(_('All templates'), 'templates.php?templateid=' . $db_host['templateid'] . url_param('groupid'))), '/', $template]);
        $db_host['hostid'] = $db_host['templateid'];
    } else {
        $proxy_name = '';
        if ($db_host['proxy_hostid'] != 0) {
            $db_proxies = API::Proxy()->get(['output' => ['host'], 'proxyids' => [$db_host['proxy_hostid']]]);
            $proxy_name = CHtml::encode($db_proxies[0]['host']) . NAME_DELIMITER;
        }
        $name = $proxy_name . CHtml::encode($db_host['name']);
        switch ($db_host['status']) {
            case HOST_STATUS_MONITORED:
                if ($db_host['maintenance_status'] == HOST_MAINTENANCE_STATUS_ON) {
                    $status = (new CSpan(_('In maintenance')))->addClass(ZBX_STYLE_ORANGE);
                } else {
                    $status = (new CSpan(_('Enabled')))->addClass(ZBX_STYLE_GREEN);
                }
                break;
            case HOST_STATUS_NOT_MONITORED:
                $status = (new CSpan(_('Disabled')))->addClass(ZBX_STYLE_RED);
                break;
            default:
                $status = _('Unknown');
                break;
        }
        $host = new CSpan(new CLink($name, 'hosts.php?form=update&hostid=' . $db_host['hostid']));
        if ($current_element === '') {
            $host->addClass(ZBX_STYLE_SELECTED);
        }
        $list->addItem([new CSpan(new CLink(_('All hosts'), 'hosts.php?hostid=' . $db_host['hostid'] . url_param('groupid'))), '/', $host]);
        $list->addItem($status);
        $list->addItem(getHostAvailabilityTable($db_host));
        if ($db_host['flags'] == ZBX_FLAG_DISCOVERY_CREATED && $db_host['hostDiscovery']['ts_delete'] != 0) {
            $lifetime_indicator = getHostLifetimeIndicator(time(), $db_host['hostDiscovery']['ts_delete']);
            $list->addItem((new CDiv($lifetime_indicator))->addClass(ZBX_STYLE_STATUS_CONTAINER));
        }
    }
    /*
     * the count of rows
     */
    if ($lld_ruleid == 0) {
        // applications
        $applications = new CSpan([new CLink(_('Applications'), 'applications.php?hostid=' . $db_host['hostid']), CViewHelper::showNum($db_host['applications'])]);
        if ($current_element == 'applications') {
            $applications->addClass(ZBX_STYLE_SELECTED);
        }
        $list->addItem($applications);
        // items
        $items = new CSpan([new CLink(_('Items'), 'items.php?filter_set=1&hostid=' . $db_host['hostid']), CViewHelper::showNum($db_host['items'])]);
        if ($current_element == 'items') {
            $items->addClass(ZBX_STYLE_SELECTED);
        }
        $list->addItem($items);
        // triggers
        $triggers = new CSpan([new CLink(_('Triggers'), 'triggers.php?hostid=' . $db_host['hostid']), CViewHelper::showNum($db_host['triggers'])]);
        if ($current_element == 'triggers') {
            $triggers->addClass(ZBX_STYLE_SELECTED);
        }
        $list->addItem($triggers);
        // graphs
        $graphs = new CSpan([new CLink(_('Graphs'), 'graphs.php?hostid=' . $db_host['hostid']), CViewHelper::showNum($db_host['graphs'])]);
        if ($current_element == 'graphs') {
            $graphs->addClass(ZBX_STYLE_SELECTED);
        }
        $list->addItem($graphs);
        // screens
        if ($is_template) {
            $screens = new CSpan([new CLink(_('Screens'), 'screenconf.php?templateid=' . $db_host['hostid']), CViewHelper::showNum($db_host['screens'])]);
            if ($current_element == 'screens') {
                $screens->addClass(ZBX_STYLE_SELECTED);
            }
            $list->addItem($screens);
        }
        // discovery rules
        $lld_rules = new CSpan([new CLink(_('Discovery rules'), 'host_discovery.php?hostid=' . $db_host['hostid']), CViewHelper::showNum($db_host['discoveries'])]);
        if ($current_element == 'discoveries') {
            $lld_rules->addClass(ZBX_STYLE_SELECTED);
        }
        $list->addItem($lld_rules);
        // web scenarios
        $http_tests = new CSpan([new CLink(_('Web scenarios'), 'httpconf.php?hostid=' . $db_host['hostid']), CViewHelper::showNum($db_host['httpTests'])]);
        if ($current_element == 'web') {
            $http_tests->addClass(ZBX_STYLE_SELECTED);
        }
        $list->addItem($http_tests);
    } else {
        $discovery_rule = (new CSpan())->addItem(new CLink(CHtml::encode($db_discovery_rule['name']), 'host_discovery.php?form=update&itemid=' . $db_discovery_rule['itemid']));
        if ($current_element == 'discoveries') {
            $discovery_rule->addClass(ZBX_STYLE_SELECTED);
        }
        $list->addItem([(new CSpan())->addItem(new CLink(_('Discovery list'), 'host_discovery.php?hostid=' . $db_host['hostid'] . url_param('groupid'))), '/', $discovery_rule]);
        // item prototypes
        $item_prototypes = new CSpan([new CLink(_('Item prototypes'), 'disc_prototypes.php?parent_discoveryid=' . $db_discovery_rule['itemid']), CViewHelper::showNum($db_discovery_rule['items'])]);
        if ($current_element == 'items') {
            $item_prototypes->addClass(ZBX_STYLE_SELECTED);
        }
        $list->addItem($item_prototypes);
        // trigger prototypes
        $trigger_prototypes = new CSpan([new CLink(_('Trigger prototypes'), 'trigger_prototypes.php?parent_discoveryid=' . $db_discovery_rule['itemid']), CViewHelper::showNum($db_discovery_rule['triggers'])]);
        if ($current_element == 'triggers') {
            $trigger_prototypes->addClass(ZBX_STYLE_SELECTED);
        }
        $list->addItem($trigger_prototypes);
        // graph prototypes
        $graph_prototypes = new CSpan([new CLink(_('Graph prototypes'), 'graphs.php?parent_discoveryid=' . $db_discovery_rule['itemid']), CViewHelper::showNum($db_discovery_rule['graphs'])]);
        if ($current_element == 'graphs') {
            $graph_prototypes->addClass(ZBX_STYLE_SELECTED);
        }
        $list->addItem($graph_prototypes);
        // host prototypes
        if ($db_host['flags'] == ZBX_FLAG_DISCOVERY_NORMAL) {
            $host_prototypes = new CSpan([new CLink(_('Host prototypes'), 'host_prototypes.php?parent_discoveryid=' . $db_discovery_rule['itemid']), CViewHelper::showNum($db_discovery_rule['hostPrototypes'])]);
            if ($current_element == 'hosts') {
                $host_prototypes->addClass(ZBX_STYLE_SELECTED);
            }
            $list->addItem($host_prototypes);
        }
    }
    return $list;
}