2016-11-27 18:12:07 -05:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace Icinga\Module\Businessprocess\Renderer;
|
|
|
|
|
|
2016-11-28 18:34:28 -05:00
|
|
|
use Icinga\Date\DateFormatter;
|
2016-11-27 18:12:07 -05:00
|
|
|
use Icinga\Exception\ProgrammingError;
|
|
|
|
|
use Icinga\Module\Businessprocess\BpNode;
|
2017-01-11 08:04:45 -05:00
|
|
|
use Icinga\Module\Businessprocess\BpConfig;
|
2016-11-27 18:12:07 -05:00
|
|
|
use Icinga\Module\Businessprocess\Html\Container;
|
|
|
|
|
use Icinga\Module\Businessprocess\Html\Element;
|
|
|
|
|
use Icinga\Module\Businessprocess\Html\Html;
|
2016-11-28 18:34:28 -05:00
|
|
|
use Icinga\Module\Businessprocess\Html\HtmlString;
|
2016-11-27 18:12:07 -05:00
|
|
|
use Icinga\Module\Businessprocess\Node;
|
|
|
|
|
use Icinga\Module\Businessprocess\Web\Url;
|
|
|
|
|
|
|
|
|
|
abstract class Renderer extends Html
|
|
|
|
|
{
|
2017-01-11 08:04:45 -05:00
|
|
|
/** @var BpConfig */
|
2017-01-11 08:33:35 -05:00
|
|
|
protected $config;
|
2016-11-27 18:12:07 -05:00
|
|
|
|
|
|
|
|
/** @var BpNode */
|
|
|
|
|
protected $parent;
|
|
|
|
|
|
|
|
|
|
/** @var bool Administrative actions are hidden unless unlocked */
|
|
|
|
|
protected $locked = true;
|
|
|
|
|
|
2016-11-29 09:32:56 -05:00
|
|
|
/** @var Url */
|
|
|
|
|
protected $url;
|
|
|
|
|
|
2016-11-27 18:12:07 -05:00
|
|
|
/** @var Url */
|
|
|
|
|
protected $baseUrl;
|
|
|
|
|
|
|
|
|
|
/** @var array */
|
|
|
|
|
protected $path = array();
|
|
|
|
|
|
2016-12-16 13:36:24 -05:00
|
|
|
/** @var bool */
|
|
|
|
|
protected $isBreadcrumb = false;
|
|
|
|
|
|
2016-11-27 18:12:07 -05:00
|
|
|
/**
|
|
|
|
|
* Renderer constructor.
|
|
|
|
|
*
|
2017-01-11 08:33:35 -05:00
|
|
|
* @param BpConfig $config
|
2016-11-27 18:12:07 -05:00
|
|
|
* @param BpNode|null $parent
|
|
|
|
|
*/
|
2017-01-11 08:33:35 -05:00
|
|
|
public function __construct(BpConfig $config, BpNode $parent = null)
|
2016-11-27 18:12:07 -05:00
|
|
|
{
|
2017-01-11 08:33:35 -05:00
|
|
|
$this->config = $config;
|
2016-11-27 18:12:07 -05:00
|
|
|
$this->parent = $parent;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2017-01-11 08:04:45 -05:00
|
|
|
* @return BpConfig
|
2016-11-27 18:12:07 -05:00
|
|
|
*/
|
|
|
|
|
public function getBusinessProcess()
|
|
|
|
|
{
|
2017-01-11 08:33:35 -05:00
|
|
|
return $this->config;
|
2016-11-27 18:12:07 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Whether this will render all root nodes
|
|
|
|
|
*
|
|
|
|
|
* @return bool
|
|
|
|
|
*/
|
|
|
|
|
public function wantsRootNodes()
|
|
|
|
|
{
|
|
|
|
|
return $this->parent === null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Whether this will only render parts of given config
|
|
|
|
|
*
|
|
|
|
|
* @return bool
|
|
|
|
|
*/
|
|
|
|
|
public function rendersSubNode()
|
|
|
|
|
{
|
|
|
|
|
return $this->parent !== null;
|
|
|
|
|
}
|
|
|
|
|
|
2017-01-03 05:30:27 -05:00
|
|
|
/**
|
|
|
|
|
* @return BpNode
|
|
|
|
|
*/
|
|
|
|
|
public function getParentNode()
|
|
|
|
|
{
|
|
|
|
|
return $this->parent;
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-27 18:12:07 -05:00
|
|
|
/**
|
|
|
|
|
* @return BpNode[]
|
|
|
|
|
*/
|
|
|
|
|
public function getParentNodes()
|
|
|
|
|
{
|
|
|
|
|
if ($this->wantsRootNodes()) {
|
|
|
|
|
return array();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $this->parent->getParents();
|
|
|
|
|
}
|
|
|
|
|
|
2016-12-09 10:59:25 -05:00
|
|
|
/**
|
|
|
|
|
* @return BpNode[]
|
|
|
|
|
*/
|
|
|
|
|
public function getChildNodes()
|
|
|
|
|
{
|
|
|
|
|
if ($this->wantsRootNodes()) {
|
2017-01-11 08:33:35 -05:00
|
|
|
return $this->config->getRootNodes();
|
2016-12-09 10:59:25 -05:00
|
|
|
} else {
|
|
|
|
|
return $this->parent->getChildren();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @return int
|
|
|
|
|
*/
|
|
|
|
|
public function countChildNodes()
|
|
|
|
|
{
|
|
|
|
|
if ($this->wantsRootNodes()) {
|
2017-01-11 08:33:35 -05:00
|
|
|
return $this->config->countChildren();
|
2016-12-09 10:59:25 -05:00
|
|
|
} else {
|
|
|
|
|
return $this->parent->countChildren();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-27 18:12:07 -05:00
|
|
|
/**
|
|
|
|
|
* @param $summary
|
|
|
|
|
* @return Container
|
|
|
|
|
*/
|
|
|
|
|
public function renderStateBadges($summary)
|
|
|
|
|
{
|
|
|
|
|
$container = Container::create(
|
|
|
|
|
array('class' => 'badges')
|
|
|
|
|
)/* ->renderIfEmpty(false) */;
|
|
|
|
|
|
|
|
|
|
foreach ($summary as $state => $cnt) {
|
|
|
|
|
if ($cnt === 0
|
|
|
|
|
|| $state === 'OK'
|
|
|
|
|
|| $state === 'UP'
|
|
|
|
|
) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$container->addContent(
|
|
|
|
|
Element::create(
|
|
|
|
|
'span',
|
|
|
|
|
array(
|
|
|
|
|
'class' => array(
|
|
|
|
|
'badge',
|
|
|
|
|
'badge-' . strtolower($state)
|
|
|
|
|
),
|
|
|
|
|
// TODO: We should translate this in this module
|
|
|
|
|
'title' => mt('monitoring', $state)
|
|
|
|
|
)
|
|
|
|
|
)->setContent($cnt)
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $container;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function getNodeClasses(Node $node)
|
|
|
|
|
{
|
2017-01-23 03:54:53 -05:00
|
|
|
if ($node->isMissing()) {
|
|
|
|
|
$classes = array('missing');
|
|
|
|
|
} else {
|
|
|
|
|
$classes = array(
|
|
|
|
|
strtolower($node->getStateName())
|
|
|
|
|
);
|
|
|
|
|
if ($node->hasMissingChildren()) {
|
|
|
|
|
$classes[] = 'missing-children';
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-11-27 18:12:07 -05:00
|
|
|
|
|
|
|
|
if ($node->isHandled()) {
|
|
|
|
|
$classes[] = 'handled';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ($node instanceof BpNode) {
|
|
|
|
|
$classes[] = 'process-node';
|
|
|
|
|
} else {
|
|
|
|
|
$classes[] = 'monitored-node';
|
|
|
|
|
}
|
2017-01-23 03:54:53 -05:00
|
|
|
// TODO: problem?
|
2016-11-27 18:12:07 -05:00
|
|
|
return $classes;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function setPath(array $path)
|
|
|
|
|
{
|
|
|
|
|
$this->path = $path;
|
|
|
|
|
return $this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @return string|null
|
|
|
|
|
*/
|
|
|
|
|
public function getPath()
|
|
|
|
|
{
|
|
|
|
|
return $this->path;
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-27 20:26:12 -05:00
|
|
|
public function getCurrentPath()
|
2016-11-27 18:12:07 -05:00
|
|
|
{
|
|
|
|
|
$path = $this->getPath();
|
|
|
|
|
if ($this->rendersSubNode()) {
|
|
|
|
|
$path[] = (string) $this->parent;
|
|
|
|
|
}
|
|
|
|
|
return $path;
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-29 09:32:56 -05:00
|
|
|
/**
|
|
|
|
|
* @param Url $url
|
|
|
|
|
* @return $this
|
|
|
|
|
*/
|
|
|
|
|
public function setUrl(Url $url)
|
|
|
|
|
{
|
2017-01-03 05:30:27 -05:00
|
|
|
$this->url = $url->without(array(
|
|
|
|
|
'deletenode',
|
|
|
|
|
'deleteparent',
|
|
|
|
|
'editnode',
|
|
|
|
|
'simulationnode'
|
|
|
|
|
));
|
2016-11-29 09:32:56 -05:00
|
|
|
$this->setBaseUrl($url);
|
|
|
|
|
return $this;
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-27 18:12:07 -05:00
|
|
|
/**
|
|
|
|
|
* @param Url $url
|
|
|
|
|
* @return $this
|
|
|
|
|
*/
|
|
|
|
|
public function setBaseUrl(Url $url)
|
|
|
|
|
{
|
2016-12-09 08:50:19 -05:00
|
|
|
$this->baseUrl = $url->without(array('node', 'path'));
|
2016-11-27 18:12:07 -05:00
|
|
|
return $this;
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-29 09:32:56 -05:00
|
|
|
public function getUrl()
|
|
|
|
|
{
|
|
|
|
|
return $this->url;
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-27 18:12:07 -05:00
|
|
|
/**
|
|
|
|
|
* @return Url
|
|
|
|
|
* @throws ProgrammingError
|
|
|
|
|
*/
|
|
|
|
|
public function getBaseUrl()
|
|
|
|
|
{
|
|
|
|
|
if ($this->baseUrl === null) {
|
|
|
|
|
throw new ProgrammingError('Renderer has no baseUrl');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return clone($this->baseUrl);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @return bool
|
|
|
|
|
*/
|
|
|
|
|
public function isLocked()
|
|
|
|
|
{
|
|
|
|
|
return $this->locked;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @return $this
|
|
|
|
|
*/
|
|
|
|
|
public function lock()
|
|
|
|
|
{
|
|
|
|
|
$this->locked = true;
|
|
|
|
|
return $this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @return $this
|
|
|
|
|
*/
|
|
|
|
|
public function unlock()
|
|
|
|
|
{
|
|
|
|
|
$this->locked = false;
|
|
|
|
|
return $this;
|
|
|
|
|
}
|
2016-11-28 18:34:28 -05:00
|
|
|
|
2016-12-16 13:36:24 -05:00
|
|
|
/**
|
|
|
|
|
* TODO: Get rid of this
|
|
|
|
|
*
|
|
|
|
|
* @return $this
|
|
|
|
|
*/
|
|
|
|
|
public function setIsBreadcrumb()
|
|
|
|
|
{
|
|
|
|
|
$this->isBreadcrumb = true;
|
|
|
|
|
return $this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function isBreadcrumb()
|
|
|
|
|
{
|
|
|
|
|
return $this->isBreadcrumb;
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-28 18:34:28 -05:00
|
|
|
public function timeSince($time, $timeOnly = false)
|
|
|
|
|
{
|
|
|
|
|
if (! $time) {
|
|
|
|
|
return HtmlString::create('');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return Element::create(
|
|
|
|
|
'span',
|
|
|
|
|
array(
|
|
|
|
|
'class' => array('relative-time', 'time-since'),
|
|
|
|
|
'title' => DateFormatter::formatDateTime($time),
|
|
|
|
|
)
|
|
|
|
|
)->setContent(DateFormatter::timeSince($time, $timeOnly));
|
|
|
|
|
}
|
|
|
|
|
|
2017-01-11 08:04:45 -05:00
|
|
|
protected function createUnboundParent(BpConfig $bp)
|
2016-11-28 18:34:28 -05:00
|
|
|
{
|
2017-01-23 03:50:19 -05:00
|
|
|
// Hint: state is useless here, but triggers parent/child "calculation"
|
|
|
|
|
// This is an ugly workaround and should be made obsolete
|
|
|
|
|
foreach ($bp->getBpNodes() as $p) {
|
|
|
|
|
$p->getState();
|
|
|
|
|
}
|
2016-11-28 18:34:28 -05:00
|
|
|
$unbound = $bp->getUnboundNodes();
|
|
|
|
|
|
|
|
|
|
$parent = new BpNode($bp, (object) array(
|
|
|
|
|
'name' => '__unbound__',
|
|
|
|
|
'operator' => '|',
|
|
|
|
|
'child_names' => array_keys($unbound)
|
|
|
|
|
));
|
|
|
|
|
$parent->getState();
|
|
|
|
|
$parent->setMissing()
|
|
|
|
|
->setDowntime(false)
|
|
|
|
|
->setAck(false)
|
|
|
|
|
->setAlias('Unbound nodes');
|
|
|
|
|
|
|
|
|
|
return $parent;
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-27 18:12:07 -05:00
|
|
|
/**
|
|
|
|
|
* Just to be on the safe side
|
|
|
|
|
*/
|
|
|
|
|
public function __destruct()
|
|
|
|
|
{
|
|
|
|
|
unset($this->parent);
|
2017-01-11 08:33:35 -05:00
|
|
|
unset($this->config);
|
2016-11-27 18:12:07 -05:00
|
|
|
}
|
|
|
|
|
}
|