}
    } else {
        if (empty($apps)) {
            $url = '?open=1&applicationid=0';
        } else {
            if (isset($apps[0])) {
                $url = '?close=1' . url_param($tmp_apps, false, 'apps');
            } else {
                $url = '?close=1&applicationid=0' . url_param($tmp_apps, false, 'apps');
            }
        }
    }
    $url .= url_param('groupid') . url_param('hostid') . url_param('fullscreen') . url_param('select');
    $link = new CLink($img, $url);
    $col = new CCol(array(bold('- ' . 'other' . ' -'), SPACE . '(' . _n('%1$s Item', '%1$s Items', $db_host['item_cnt']) . ')'));
    $col->setColSpan(5);
    // host JS menu link
    $hostSpan = null;
    if ($_REQUEST['hostid'] == 0) {
        $hostSpan = new CSpan($host['name'], 'link_menu menu-host');
        $scripts = $hostScripts[$host['hostid']];
        $hostSpan->setAttribute('data-menu', hostMenuData($host, $scripts));
    }
    $table->addRow(array($link, get_node_name_by_elid($db_host['hostid']), $hostSpan, $col));
    foreach ($app_rows as $row) {
        $table->addRow($row);
    }
}
$latest_wdgt->addItem($table);
$latest_wdgt->show();
require_once 'include/page_footer.php';
/**
 * Retrieve overview table object for items.
 *
 * @param $hostids
 * @param null $view_style
 *
 * @return CTableInfo
 */
function get_items_data_overview($hostids, $view_style)
{
    global $USER_DETAILS;
    $db_items = DBselect('SELECT DISTINCT h.hostid,h.name AS hostname,i.itemid,i.key_,i.value_type,i.lastvalue,i.units,i.lastclock,' . 'i.name,t.priority,i.valuemapid,t.value AS tr_value,t.triggerid' . ' FROM hosts h,items i' . ' LEFT JOIN functions f ON f.itemid=i.itemid' . ' LEFT JOIN triggers t ON t.triggerid=f.triggerid AND t.status=' . TRIGGER_STATUS_ENABLED . ' WHERE ' . dbConditionInt('h.hostid', $hostids) . ' AND h.status=' . HOST_STATUS_MONITORED . ' AND h.hostid=i.hostid' . ' AND i.status=' . ITEM_STATUS_ACTIVE . ' AND ' . dbConditionInt('i.flags', array(ZBX_FLAG_DISCOVERY_NORMAL, ZBX_FLAG_DISCOVERY_CREATED)) . ' ORDER BY i.name,i.itemid');
    $options = array('output' => array('name', 'hostid'), 'monitored_hosts' => true, 'hostids' => $hostids, 'with_monitored_items' => true, 'preservekeys' => true);
    if ($view_style == STYLE_LEFT) {
        $options['selectScreens'] = API_OUTPUT_COUNT;
        $options['selectInventory'] = array('hostid');
    }
    // fetch data for the host JS menu
    $hosts = API::Host()->get($options);
    $items = array();
    while ($row = DBfetch($db_items)) {
        $descr = itemName($row);
        $row['hostname'] = get_node_name_by_elid($row['hostid'], null, ': ') . $row['hostname'];
        $hostnames[$row['hostid']] = $row['hostname'];
        // a little tricky check for attempt to overwrite active trigger (value=1) with
        // inactive or active trigger with lower priority.
        if (!isset($items[$descr][$row['hostname']]) || ($items[$descr][$row['hostname']]['tr_value'] == TRIGGER_VALUE_FALSE && $row['tr_value'] == TRIGGER_VALUE_TRUE || ($items[$descr][$row['hostname']]['tr_value'] == TRIGGER_VALUE_FALSE || $row['tr_value'] == TRIGGER_VALUE_TRUE) && $row['priority'] > $items[$descr][$row['hostname']]['severity'])) {
            $items[$descr][$row['hostname']] = array('itemid' => $row['itemid'], 'value_type' => $row['value_type'], 'lastvalue' => $row['lastvalue'], 'lastclock' => $row['lastclock'], 'units' => $row['units'], 'name' => $row['name'], 'valuemapid' => $row['valuemapid'], 'severity' => $row['priority'], 'tr_value' => $row['tr_value'], 'triggerid' => $row['triggerid']);
        }
    }
    $table = new CTableInfo(_('No items defined.'));
    if (empty($hostnames)) {
        return $table;
    }
    $table->makeVerticalRotation();
    order_result($hostnames);
    if ($view_style == STYLE_TOP) {
        $header = array(new CCol(_('Items'), 'center'));
        foreach ($hostnames as $hostname) {
            $header[] = new CCol($hostname, 'vertical_rotation');
        }
        $table->setHeader($header, 'vertical_header');
        foreach ($items as $descr => $ithosts) {
            $tableRow = array(nbsp($descr));
            foreach ($hostnames as $hostname) {
                $tableRow = get_item_data_overview_cells($tableRow, $ithosts, $hostname);
            }
            $table->addRow($tableRow);
        }
    } else {
        $hostScripts = API::Script()->getScriptsByHosts(zbx_objectValues($hosts, 'hostid'));
        foreach ($hostScripts as $hostid => $scripts) {
            $hosts[$hostid]['scripts'] = $scripts;
        }
        $header = array(new CCol(_('Hosts'), 'center'));
        foreach ($items as $descr => $ithosts) {
            $header[] = new CCol($descr, 'vertical_rotation');
        }
        $table->setHeader($header, 'vertical_header');
        foreach ($hostnames as $hostid => $hostname) {
            $host = $hosts[$hostid];
            // host js menu link
            $hostSpan = new CSpan(nbsp($host['name']), 'link_menu menu-host');
            $hostSpan->setAttribute('data-menu', hostMenuData($host, $hostScripts[$host['hostid']]));
            $tableRow = array(new CCol($hostSpan));
            foreach ($items as $ithosts) {
                $tableRow = get_item_data_overview_cells($tableRow, $ithosts, $hostname);
            }
            $table->addRow($tableRow);
        }
    }
    return $table;
}
function make_trigger_details($trigger)
{
    $table = new CTableInfo();
    if (is_show_all_nodes()) {
        $table->addRow(array(_('Node'), get_node_name_by_elid($trigger['triggerid'])));
    }
    $expression = explode_exp($trigger['expression'], true, true);
    $host = API::Host()->get(array('output' => array('name', 'hostid'), 'hostids' => $trigger['hosts'][0]['hostid'], 'selectScreens' => API_OUTPUT_COUNT, 'selectInventory' => array('hostid'), 'preservekeys' => true));
    $host = reset($host);
    $hostScripts = API::Script()->getScriptsByHosts($host['hostid']);
    // host js link
    $hostSpan = new CSpan($host['name'], 'link_menu menu-host');
    $scripts = $hostScripts[$host['hostid']];
    $hostSpan->attr('data-menu', hostMenuData($host, $scripts));
    // get visible name of the first host
    $table->addRow(array(_('Host'), $hostSpan));
    $table->addRow(array(_('Trigger'), CTriggerHelper::expandDescription($trigger)));
    $table->addRow(array(_('Severity'), getSeverityCell($trigger['priority'])));
    $table->addRow(array(_('Expression'), $expression));
    $table->addRow(array(_('Event generation'), _('Normal') . (TRIGGER_MULT_EVENT_ENABLED == $trigger['type'] ? SPACE . '+' . SPACE . _('Multiple PROBLEM events') : '')));
    $table->addRow(array(_('Disabled'), TRIGGER_STATUS_ENABLED == $trigger['status'] ? new CCol(_('No'), 'off') : new CCol(_('Yes'), 'on')));
    return $table;
}
function make_hint_row($type, $instance)
{
    $state = $instance['state'];
    if ($type == "other" && $instance["stuck_state"] == 1) {
        $state = "stuck";
    }
    $r = new CRow();
    if (in_array($type, array("poweron", "poweroff", "suspend"))) {
        $r->addItem(new CCheckBox("hostids[]", null, null, $instance['hostid']));
    }
    $hostScripts = API::Script()->getScriptsByHosts(zbx_objectValues(array($instance['host']), 'hostid'));
    $hostSpan = new CSpan(nbsp($instance['name']), 'link_menu menu-host');
    $hostSpan->setAttribute('data-menu', hostMenuData($instance['host'], $hostScripts[$instance['hostid']]));
    $r->addItem($hostSpan);
    $r->addItem(new CCol($state, get_item_level($state)));
    $r->addItem($instance['cpu']);
    $r->addItem($instance['memory']);
    $r->addItem($instance['main_interface']);
    if ($type == "other" && $instance["stuck_state"] == 1) {
        $question = $instance['stuck_question'];
        $json = new CJSON();
        $choiceinfos = $json->decode($instance['stuck_choices'], true);
        $answer_form = new CForm();
        $answer_form->setAction('#');
        $answer_form->setAttribute('id', "answer");
        $answer_form->addVar("driver", "vsphere");
        $answer_form->addVar("hostids[]", $instance['hostid']);
        $instancename = $instance['host']['host'];
        $answer_button = new CButton('answer', _('Answer'), "return checkAnswer('answer', 'choice', '{$instancename}', 'Execute');");
        $choice_table = new CTableInfo();
        foreach ($choiceinfos as $choice) {
            $radio = new CRadioButton('choice', $choice['key']);
            $label = new CLabel($choice['label']);
            $choice_table->addRow(new CRow(array($radio, $label)));
        }
        $answer_form->addItem($choice_table);
        $answer_form->addItem($answer_button);
        $question_span = new CSpan($question);
        $question_span->setHint($answer_form);
        $question_col = new CCol($question_span, 'warning');
        $r->addItem($question_col);
    } else {
        if ($type == "poweron") {
            $ssh_link = new CLink(_('connect'), "gateone.php?hostid={$instance['hostid']}");
            $ssh_link->setTarget("_blank");
            $r->addItem($ssh_link);
        }
    }
    return $r;
}
/**
 * Create and return a DIV with latest problem triggers.
 *
 * @param array $filter
 *
 * @return CDiv
 */
function make_latest_issues(array $filter = array())
{
    if (!isset($filter['sortfield'])) {
        $filter['sortfield'] = 'lastchange';
    }
    if (!isset($filter['sortorder'])) {
        $filter['sortorder'] = ZBX_SORT_DOWN;
    }
    // get triggers
    $options = array('groupids' => $filter['groupids'], 'hostids' => isset($filter['hostids']) ? $filter['hostids'] : null, 'monitored' => true, 'maintenance' => $filter['maintenance'], 'withLastEventUnacknowledged' => !empty($filter['extAck']) && $filter['extAck'] == EXTACK_OPTION_UNACK ? true : null, 'skipDependent' => true, 'filter' => array('priority' => $filter['severity'], 'value' => TRIGGER_VALUE_TRUE), 'selectHosts' => array('hostid', 'name'), 'output' => array('triggerid', 'value_flags', 'error', 'url', 'expression', 'description', 'priority', 'type'), 'sortfield' => $filter['sortfield'], 'sortorder' => $filter['sortorder'], 'limit' => isset($filter['limit']) ? $filter['limit'] : DEFAULT_LATEST_ISSUES_CNT);
    $triggers = API::Trigger()->get($options);
    // total trigger count
    $options['countOutput'] = true;
    // we unset withLastEventUnacknowledged and skipDependent because of performance issues
    unset($options['limit'], $options['withLastEventUnacknowledged'], $options['skipDependent']);
    $triggersTotalCount = API::Trigger()->get($options);
    // get events
    $events = API::Trigger()->get(array('triggerids' => zbx_objectValues($triggers, 'triggerid'), 'selectLastEvent' => API_OUTPUT_EXTEND, 'preservekeys' => true));
    // get acknowledges
    $eventIds = array();
    foreach ($events as $event) {
        if ($event['lastEvent']) {
            $eventIds[$event['lastEvent']['eventid']] = $event['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'];
        // set events
        if (isset($events[$trigger['triggerid']])) {
            $trigger['event'] = $events[$trigger['triggerid']]['lastEvent'];
        }
        if (!empty($trigger['event'])) {
            $trigger['event']['acknowledges'] = isset($eventAcknowledges[$trigger['event']['eventid']]) ? $eventAcknowledges[$trigger['event']['eventid']]['acknowledges'] : null;
        }
        $triggers[$tnum] = $trigger;
    }
    $hostIds = zbx_objectValues($triggers, 'hostid');
    // get hosts
    $hosts = API::Host()->get(array('hostids' => $hostIds, 'output' => array('hostid', 'name', 'maintenance_status', 'maintenance_type', 'maintenanceid'), 'selectInventory' => array('hostid'), 'selectScreens' => API_OUTPUT_COUNT, 'preservekeys' => true));
    // get scripts
    $scripts_by_hosts = API::Script()->getScriptsByHosts($hostIds);
    // actions
    $actions = getEventActionsStatHints($eventIds);
    // ack params
    $ackParams = isset($filter['screenid']) ? array('screenid' => $filter['screenid']) : array();
    $config = select_config();
    // indicator of sort field
    $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(_('Last change'), SPACE));
    $lastChangeHeaderDiv->addStyle('float: left');
    $table = new CTableInfo();
    $table->setHeader(array(is_show_all_nodes() ? _('Node') : null, $filter['sortfield'] === 'hostname' ? array($hostHeaderDiv, $sortDiv) : _('Host'), $filter['sortfield'] === 'priority' ? array($issueHeaderDiv, $sortDiv) : _('Issue'), $filter['sortfield'] === 'lastchange' ? array($lastChangeHeaderDiv, $sortDiv) : _('Last change'), _('Age'), _('Info'), $config['event_ack_enable'] ? _('Ack') : null, _('Actions')));
    // triggers
    foreach ($triggers as $trigger) {
        // check for dependencies
        $host = $hosts[$trigger['hostid']];
        $hostSpan = new CDiv(null, 'maintenance-abs-cont');
        $hostName = new CSpan($host['name'], 'link_menu menu-host');
        $hostName->setAttribute('data-menu', hostMenuData($host, $scripts_by_hosts[$host['hostid']]));
        // add maintenance icon with hint if host is in maintenance
        if ($host['maintenance_status']) {
            $mntIco = 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'];
                }
                $mntIco->setHint($hint);
                $mntIco->addClass('pointer');
            }
            $hostName->addClass('left-to-icon-maintenance-abs');
            $hostSpan->addItem($mntIco);
        }
        $hostSpan->addItem($hostName);
        // unknown triggers
        $unknown = SPACE;
        if ($trigger['value_flags'] == TRIGGER_VALUE_FLAG_UNKNOWN) {
            $unknown = new CDiv(SPACE, 'status_icon iconunknown');
            $unknown->setHint($trigger['error'], '', 'on');
        }
        if (!empty($trigger['event'])) {
            $ack = getEventAckState($trigger['event'], empty($filter['backUrl']) ? true : $filter['backUrl'], true, $ackParams);
            $clock = new CLink(zbx_date2str(_('d M Y H:i:s'), $trigger['event']['clock']), 'events.php?triggerid=' . $trigger['triggerid'] . '&source=0&show_unknown=1&nav_time=' . $trigger['event']['clock']);
            $description = CEventHelper::expandDescription(zbx_array_merge($trigger, array('clock' => $trigger['event']['clock'], 'ns' => $trigger['event']['ns'])));
            $description = $trigger['url'] ? new CLink($description, resolveTriggerUrl($trigger), null, null, true) : new CSpan($description, 'pointer');
            $description = new CCol($description, getSeverityStyle($trigger['priority']));
            $description->setHint(make_popup_eventlist($trigger['triggerid'], $trigger['event']['eventid']), '', '', false);
            $table->addRow(array(get_node_name_by_elid($trigger['triggerid']), $hostSpan, $description, $clock, zbx_date2age($trigger['event']['clock']), $unknown, $ack, isset($actions[$trigger['event']['eventid']]) ? $actions[$trigger['event']['eventid']] : SPACE));
        }
    }
    // 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('%2$d of %1$d issue is shown', '%2$d of %1$d issues are shown', $triggersTotalCount, count($triggers)));
    $infoDiv->addStyle('text-align: right; padding-right: 3px;');
    return new CDiv(array($table, $infoDiv, $script));
}