parent
24da98be83
commit
dac61eda19
|
@ -71,13 +71,14 @@ class FilterController extends ActionController
|
|||
$this->setupQueries();
|
||||
$this->view->form->setRequest($this->getRequest());
|
||||
|
||||
|
||||
if ($this->view->form->isSubmittedAndValid()) {
|
||||
$tree = $this->registry->createQueryTreeForFilter($this->view->form->getValue('query'));
|
||||
$this->view->tree = new \Icinga\Web\Widget\FilterBadgeRenderer($tree);
|
||||
|
||||
$view = \Icinga\Module\Monitoring\DataView\HostAndServiceStatus::fromRequest($this->getRequest());
|
||||
$cv = new \Icinga\Module\Monitoring\Filter\Backend\IdoQueryConverter($view);
|
||||
$this->view->sqlString = $cv->treeToSql($tree);
|
||||
$this->view->params = $cv->getParams();
|
||||
} else if ($this->getRequest()->getHeader('accept') == 'application/json') {
|
||||
|
||||
$this->getResponse()->setHeader('Content-Type', 'application/json');
|
||||
$this->_helper->json($this->parse($this->getRequest()->getParam('query', '')));
|
||||
}
|
||||
|
|
|
@ -4,4 +4,8 @@ echo $this->form;
|
|||
|
||||
if ($this->tree) {
|
||||
echo $this->tree->render($this);
|
||||
echo '<br/><pre><code>';
|
||||
echo $this->sqlString;
|
||||
echo '</pre></code>';
|
||||
print_r($this->params);
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
/**
|
||||
* This file is part of Icinga 2 Web.
|
||||
*
|
||||
* Icinga 2 Web - Head for multiple monitoring backends.
|
||||
* Copyright (C) 2013 Icinga Development Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* @copyright 2013 Icinga Development Team <info@icinga.org>
|
||||
* @license http://www.gnu.org/licenses/gpl-2.0.txt GPL, version 2
|
||||
* @author Icinga Development Team <info@icinga.org>
|
||||
*/
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
|
||||
namespace Icinga\Data;
|
||||
|
||||
|
||||
interface Filterable
|
||||
{
|
||||
public function isValidFilterTarget($targetOrColumn);
|
||||
public function resolveFilterTarget($targetOrColumn);
|
||||
|
||||
}
|
|
@ -134,9 +134,6 @@ class Domain extends QueryProposer
|
|||
foreach ($this->attributes as $attributeHandler) {
|
||||
if ($attributeHandler->isValidQuery($query)) {
|
||||
$node = $attributeHandler->convertToTreeNode($query);
|
||||
if ($node) {
|
||||
$node->context = $this->label;
|
||||
}
|
||||
return $node;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,6 +45,7 @@ class Node
|
|||
const OPERATOR_GREATER_EQ = '>=';
|
||||
const OPERATOR_LESS_EQ = '<=';
|
||||
|
||||
const CONTEXT_TIMESTRING = 'timestring';
|
||||
/**
|
||||
* Array containing all possible operators
|
||||
*
|
||||
|
@ -90,6 +91,13 @@ class Node
|
|||
*/
|
||||
public $right;
|
||||
|
||||
/**
|
||||
* Additional information for this node (like that it represents a date)
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
public $context;
|
||||
|
||||
/**
|
||||
* Factory method for creating operator nodes
|
||||
*
|
||||
|
|
|
@ -166,7 +166,9 @@ class TimeRangeSpecifier extends FilterType
|
|||
if ($operator === null || $timeQuery === null) {
|
||||
return null;
|
||||
}
|
||||
return Node::createOperatorNode($operator, $leftOperand, $timeQuery);
|
||||
$node = Node::createOperatorNode($operator, $leftOperand, $timeQuery);
|
||||
$node->context = Node::CONTEXT_TIMESTRING;
|
||||
return $node;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
/**
|
||||
* This file is part of Icinga 2 Web.
|
||||
*
|
||||
* Icinga 2 Web - Head for multiple monitoring backends.
|
||||
* Copyright (C) 2013 Icinga Development Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* @copyright 2013 Icinga Development Team <info@icinga.org>
|
||||
* @license http://www.gnu.org/licenses/gpl-2.0.txt GPL, version 2
|
||||
* @author Icinga Development Team <info@icinga.org>
|
||||
*/
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
|
||||
namespace Icinga\Web\Widget;
|
||||
|
||||
|
||||
use Icinga\Filter\Query\Tree;
|
||||
use Icinga\Filter\Query\Node;
|
||||
use Zend_View_Abstract;
|
||||
|
||||
class FilterBadgeRenderer implements Widget
|
||||
{
|
||||
private $tree;
|
||||
private $conjunctionCellar = '';
|
||||
|
||||
|
||||
public function __construct(Tree $tree)
|
||||
{
|
||||
$this->tree = $tree;
|
||||
}
|
||||
|
||||
private function nodeToBadge(Node $node)
|
||||
{
|
||||
if ($node->type === Node::TYPE_OPERATOR) {
|
||||
return ' <a class="btn btn-default btn-xs">'
|
||||
. $this->conjunctionCellar . ' '
|
||||
. ucfirst($node->left) . ' '
|
||||
. $node->operator . ' '
|
||||
. $node->right . '</a>';
|
||||
}
|
||||
$result = '';
|
||||
$result .= $this->nodeToBadge($node->left);
|
||||
$this->conjunctionCellar = $node->type;
|
||||
$result .= $this->nodeToBadge($node->right);
|
||||
return $result;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Renders this widget via the given view and returns the
|
||||
* HTML as a string
|
||||
*
|
||||
* @param \Zend_View_Abstract $view
|
||||
* @return string
|
||||
*/
|
||||
public function render(Zend_View_Abstract $view)
|
||||
{
|
||||
if ($this->tree->root == null) {
|
||||
return '';
|
||||
}
|
||||
return $this->nodeToBadge($this->tree->root);
|
||||
}
|
||||
}
|
|
@ -232,7 +232,7 @@ abstract class AbstractQuery extends Query
|
|||
return array_key_exists($alias, $this->idxAliasColumn);
|
||||
}
|
||||
|
||||
protected function aliasToColumnName($alias)
|
||||
public function aliasToColumnName($alias)
|
||||
{
|
||||
return $this->idxAliasColumn[$alias];
|
||||
}
|
||||
|
@ -402,4 +402,15 @@ abstract class AbstractQuery extends Query
|
|||
|
||||
return $filter;
|
||||
}
|
||||
|
||||
public function getMappedColumn($name)
|
||||
{
|
||||
foreach ($this->columnMap as $column => $results) {
|
||||
if (isset($results[$name])) {
|
||||
return $results[$name];
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -150,7 +150,7 @@ abstract class DataView
|
|||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function isValidFilterColumn($column)
|
||||
public function isValidFilterColumn($column)
|
||||
{
|
||||
return in_array($column, $this->getColumns()) || in_array($column, $this->getFilterColumns());
|
||||
}
|
||||
|
|
|
@ -121,7 +121,7 @@ class HostAndServiceStatus extends DataView
|
|||
return array('hostgroups', 'servicegroups', 'service_problems');
|
||||
}
|
||||
|
||||
protected function isValidFilterColumn($column)
|
||||
public function isValidFilterColumn($column)
|
||||
{
|
||||
if ($column[0] === '_'
|
||||
&& preg_match('/^_(?:host|service)_/', $column)
|
||||
|
|
|
@ -31,15 +31,90 @@ namespace Icinga\Module\Monitoring\Filter\Backend;
|
|||
|
||||
|
||||
use Icinga\Filter\Query\Tree;
|
||||
use Icinga\Filter\Query\Node;
|
||||
use Icinga\Module\Monitoring\DataView\DataView;
|
||||
|
||||
|
||||
class IdoQueryConverter
|
||||
{
|
||||
private $view;
|
||||
private $query;
|
||||
private $params = array();
|
||||
|
||||
public function getParams()
|
||||
{
|
||||
return $this->params;
|
||||
}
|
||||
|
||||
public function __construct(DataView $view, array $initialParams = array())
|
||||
{
|
||||
$this->view = $view;
|
||||
$this->query = $this->view->getQuery();
|
||||
$this->params = $initialParams;
|
||||
}
|
||||
|
||||
private function getSqlOperator($operator)
|
||||
{
|
||||
switch($operator) {
|
||||
case Node::OPERATOR_EQUALS:
|
||||
return 'LIKE';
|
||||
case Node::OPERATOR_EQUALS_NOT:
|
||||
return 'NOT LIKE';
|
||||
default:
|
||||
return $operator;
|
||||
}
|
||||
}
|
||||
|
||||
private function nodeToSqlQuery(Node $node)
|
||||
{
|
||||
if ($node->type !== Node::TYPE_OPERATOR) {
|
||||
return $this->parseConjunctionNode($node);
|
||||
} else {
|
||||
return $this->parseOperatorNode($node);
|
||||
}
|
||||
}
|
||||
|
||||
private function parseConjunctionNode(Node $node)
|
||||
{
|
||||
$queryString = '';
|
||||
$leftQuery = $this->nodeToSqlQuery($node->left);
|
||||
$rightQuery = $this->nodeToSqlQuery($node->right);
|
||||
if ($leftQuery != '') {
|
||||
$queryString .= $leftQuery . ' ';
|
||||
}
|
||||
if ($rightQuery != '') {
|
||||
$queryString .= (($queryString !== '') ? $node->type . ' ' : ' ') . $rightQuery;
|
||||
}
|
||||
return $queryString;
|
||||
}
|
||||
|
||||
private function parseOperatorNode(Node $node)
|
||||
{
|
||||
if (!$this->view->isValidFilterColumn($node->left) && $this->query->getMappedColumn($node->left)) {
|
||||
return '';
|
||||
}
|
||||
$queryString = $this->query->getMappedColumn($node->left);
|
||||
$queryString .= ' ' . (is_integer($node->right) ? $node->operator : $this->getSqlOperator($node->operator));
|
||||
$queryString .= ' ? ';
|
||||
$this->params[] = $this->getParameterValue($node);
|
||||
return $queryString;
|
||||
}
|
||||
|
||||
private function getParameterValue(Node $node) {
|
||||
|
||||
switch($node->context) {
|
||||
case Node::CONTEXT_TIMESTRING:
|
||||
return strtotime($node->right);
|
||||
default:
|
||||
return $node->right;
|
||||
}
|
||||
}
|
||||
|
||||
public function treeToSql(Tree $tree)
|
||||
{
|
||||
if ($tree->root = null) {
|
||||
if ($tree->root == null) {
|
||||
return '';
|
||||
}
|
||||
return $this->nodeToSqlQuery($tree->root);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue