type = $type; return $table; } public function assemble() { if ($this->type === 'host') { $this->enableMultiSelect( 'director/hosts/edit', 'director/hosts', ['name'] ); } } public function setGroup(IcingaObjectGroup $group) { $this->group = $group; return $this; } public function getType() { return $this->type; } public function getColumnsToBeRendered() { if ($this->group === null) { return [ $this->translate('Group'), $this->translate('Member'), $this->translate('via') ]; } else { return [ $this->translate('Member'), $this->translate('via') ]; } } public function renderRow($row) { $type = $this->getType(); if ($row->object_type === 'apply') { $params = [ 'id' => $row->id ]; } elseif (isset($row->host_id)) { // I would prefer to see host= and set=, but joining // them here is pointless. We should use DeferredHtml for these, // remember hosts/sets we need and fetch them in a single query at // rendering time. For now, this works fine - just... the URLs are // not so nice $params = [ 'name' => $row->object_name, 'host_id' => $row->host_id ]; } elseif (isset($row->service_set_id)) { $params = [ 'name' => $row->object_name, 'set_id' => $row->service_set_id ]; } else { $params = [ 'name' => $row->object_name ]; } $url = Url::fromPath("director/${type}", $params); $tr = $this::tr(); if ($this->group === null) { $tr->add($this::td($row->group_name)); } $link = Link::create($row->object_name, $url); if ($row->object_type === 'apply') { $link = [ $link, ' (where ', $this->renderApplyFilter($row->assign_filter), ')' ]; } $tr->add([ $this::td($link), $this::td($row->membership_type) ]); return $tr; } protected function renderApplyFilter($assignFilter) { try { $string = AssignRenderer::forFilter( Filter::fromQueryString($assignFilter) )->renderAssign(); // Do not prefix it $string = preg_replace('/^assign where /', '', $string); } catch (Exception $e) { // ignore errors in filter rendering $string = 'Error in Filter rendering: ' . $e->getMessage(); } return $string; } protected function prepareQuery() { // select h.object_name, hg.object_name, // CASE WHEN hgh.host_id IS NULL THEN 'apply' ELSE 'direct' END AS assi // from icinga_hostgroup_host_resolved hgr join icinga_host h on h.id = hgr.host_id // join icinga_hostgroup hg on hgr.hostgroup_id = hg.id // left join icinga_hostgroup_host hgh on hgh.host_id = h.id and hgh.hostgroup_id = hg.id; $type = $this->getType(); $columns = [ 'o.id', 'o.object_type', 'o.object_name', 'membership_type' => "CASE WHEN go.${type}_id IS NULL THEN 'apply' ELSE 'direct' END" ]; if ($this->group === null) { $columns = ['group_name' => 'g.object_name'] + $columns; } if ($type === 'service') { $columns[] = 'o.assign_filter'; $columns[] = 'o.host_id'; $columns[] = 'o.service_set_id'; } $query = $this->db()->select()->from( ['gro' => "icinga_${type}group_${type}_resolved"], $columns )->join( ['o' => "icinga_${type}"], "o.id = gro.${type}_id", [] )->join( ['g' => "icinga_${type}group"], "gro.${type}group_id = g.id", [] )->joinLeft( ['go' => "icinga_${type}group_${type}"], "go.${type}_id = o.id AND go.${type}group_id = g.id", [] )->order('o.object_name'); if ($this->group !== null) { $query->where('g.id = ?', $this->group->get('id')); } return $query; } }