2014-10-20 10:26:06 -04:00
|
|
|
<?php
|
|
|
|
|
|
2014-11-30 09:56:58 -05:00
|
|
|
namespace Icinga\Module\Businessprocess;
|
2014-10-20 10:26:06 -04:00
|
|
|
|
2015-02-06 19:02:53 -05:00
|
|
|
use Icinga\Exception\ConfigurationError;
|
2015-03-16 04:08:00 -04:00
|
|
|
use Icinga\Exception\ProgrammingError;
|
2014-10-20 10:26:06 -04:00
|
|
|
|
|
|
|
|
class BpNode extends Node
|
|
|
|
|
{
|
|
|
|
|
const OP_AND = '&';
|
|
|
|
|
const OP_OR = '|';
|
2015-10-05 10:42:04 -04:00
|
|
|
const OP_NOT = '!';
|
2014-10-20 10:26:06 -04:00
|
|
|
protected $operator = '&';
|
|
|
|
|
protected $url;
|
|
|
|
|
protected $info_command;
|
|
|
|
|
protected $display = 0;
|
|
|
|
|
protected $children;
|
|
|
|
|
protected $child_names = array();
|
|
|
|
|
protected $alias;
|
|
|
|
|
protected $counters;
|
2015-03-03 05:00:15 -05:00
|
|
|
protected $missing = null;
|
2014-10-20 10:26:06 -04:00
|
|
|
|
2015-10-05 10:42:04 -04:00
|
|
|
protected static $sortStateInversionMap = array(
|
|
|
|
|
4 => 0,
|
|
|
|
|
3 => 0,
|
|
|
|
|
2 => 2,
|
|
|
|
|
1 => 1,
|
|
|
|
|
0 => 4
|
2015-10-02 15:41:20 -04:00
|
|
|
);
|
|
|
|
|
|
2015-10-05 06:34:47 -04:00
|
|
|
protected $className = 'process';
|
|
|
|
|
|
2015-10-05 06:39:37 -04:00
|
|
|
public function __construct(BusinessProcess $bp, $object)
|
|
|
|
|
{
|
2014-10-20 10:26:06 -04:00
|
|
|
$this->bp = $bp;
|
|
|
|
|
$this->name = $object->name;
|
2015-03-03 05:05:28 -05:00
|
|
|
$this->setOperator($object->operator);
|
2014-10-20 10:26:06 -04:00
|
|
|
$this->setChildNames($object->child_names);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function getStateSummary()
|
|
|
|
|
{
|
|
|
|
|
if ($this->counters === null) {
|
|
|
|
|
$this->getState();
|
2015-03-16 04:08:00 -04:00
|
|
|
$this->counters = array(0, 0, 0, 0, 99 => 0);
|
2014-10-20 10:26:06 -04:00
|
|
|
foreach ($this->children as $child) {
|
|
|
|
|
if ($child instanceof BpNode) {
|
|
|
|
|
$counters = $child->getStateSummary();
|
|
|
|
|
foreach ($counters as $k => $v) {
|
|
|
|
|
$this->counters[$k] += $v;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
$state = $child->getState();
|
|
|
|
|
$this->counters[$state]++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return $this->counters;
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-03 05:00:15 -05:00
|
|
|
public function isMissing()
|
|
|
|
|
{
|
|
|
|
|
if ($this->missing === null) {
|
|
|
|
|
$exists = false;
|
|
|
|
|
foreach ($this->getChildren() as $child) {
|
|
|
|
|
if (! $child->isMissing()) {
|
|
|
|
|
$exists = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
$this->missing = ! $exists;
|
|
|
|
|
}
|
|
|
|
|
return $this->missing;
|
|
|
|
|
}
|
|
|
|
|
|
2014-10-20 10:26:06 -04:00
|
|
|
public function getOperator()
|
|
|
|
|
{
|
|
|
|
|
return $this->operator;
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-03 05:05:28 -05:00
|
|
|
public function setOperator($operator)
|
|
|
|
|
{
|
|
|
|
|
$this->assertValidOperator($operator);
|
|
|
|
|
$this->operator = $operator;
|
|
|
|
|
return $this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected function assertValidOperator($operator)
|
|
|
|
|
{
|
|
|
|
|
switch ($operator) {
|
|
|
|
|
case self::OP_AND:
|
|
|
|
|
case self::OP_OR:
|
2015-10-05 10:42:04 -04:00
|
|
|
case self::OP_NOT:
|
2015-03-03 05:05:28 -05:00
|
|
|
return;
|
|
|
|
|
default:
|
|
|
|
|
if (is_numeric($operator)) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
throw new ConfigurationError(
|
|
|
|
|
'Got invalid operator: %s',
|
|
|
|
|
$operator
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2014-11-30 05:56:14 -05:00
|
|
|
public function setInfoUrl($url)
|
2014-10-20 10:26:06 -04:00
|
|
|
{
|
|
|
|
|
$this->url = $url;
|
2014-11-30 05:56:14 -05:00
|
|
|
return $this;
|
2014-10-20 10:26:06 -04:00
|
|
|
}
|
|
|
|
|
|
2014-11-30 05:56:14 -05:00
|
|
|
public function hasInfoUrl()
|
2014-10-20 10:26:06 -04:00
|
|
|
{
|
|
|
|
|
return $this->url !== null;
|
|
|
|
|
}
|
|
|
|
|
|
2014-11-30 05:56:14 -05:00
|
|
|
public function getInfoUrl()
|
|
|
|
|
{
|
|
|
|
|
return $this->url;
|
|
|
|
|
}
|
|
|
|
|
|
2014-10-20 10:26:06 -04:00
|
|
|
public function setInfoCommand($cmd)
|
|
|
|
|
{
|
|
|
|
|
$this->info_command = $cmd;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function hasInfoCommand()
|
|
|
|
|
{
|
|
|
|
|
return $this->info_command !== null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function getInfoCommand()
|
|
|
|
|
{
|
|
|
|
|
return $this->info_command;
|
|
|
|
|
}
|
|
|
|
|
|
2014-12-01 13:32:09 -05:00
|
|
|
public function hasAlias()
|
|
|
|
|
{
|
|
|
|
|
return $this->alias !== null;
|
|
|
|
|
}
|
|
|
|
|
|
2014-10-20 10:26:06 -04:00
|
|
|
public function getAlias()
|
|
|
|
|
{
|
2014-12-01 13:32:09 -05:00
|
|
|
return $this->alias ? preg_replace('~_~', ' ', $this->alias) : $this->name;
|
2014-10-20 10:26:06 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function setAlias($name)
|
|
|
|
|
{
|
|
|
|
|
$this->alias = $name;
|
|
|
|
|
return $this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function getState()
|
|
|
|
|
{
|
|
|
|
|
if ($this->state === null) {
|
|
|
|
|
$this->calculateState();
|
|
|
|
|
}
|
|
|
|
|
return $this->state;
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-05 10:42:04 -04:00
|
|
|
protected function invertSortingState($state)
|
|
|
|
|
{
|
|
|
|
|
return self::$sortStateInversionMap[$state >> self::SHIFT_FLAGS] << self::SHIFT_FLAGS;
|
|
|
|
|
}
|
|
|
|
|
|
2014-10-20 10:26:06 -04:00
|
|
|
protected function calculateState()
|
|
|
|
|
{
|
|
|
|
|
$sort_states = array();
|
2015-10-02 02:32:54 -04:00
|
|
|
$lastStateChange = 0;
|
2014-10-20 10:26:06 -04:00
|
|
|
foreach ($this->getChildren() as $child) {
|
|
|
|
|
$sort_states[] = $child->getSortingState();
|
2015-10-02 02:32:54 -04:00
|
|
|
$lastStateChange = max($lastStateChange, $child->getLastStateChange());
|
2014-10-20 10:26:06 -04:00
|
|
|
}
|
2015-10-05 10:42:04 -04:00
|
|
|
|
2015-10-02 02:32:54 -04:00
|
|
|
$this->setLastStateChange($lastStateChange);
|
|
|
|
|
|
2014-10-20 10:26:06 -04:00
|
|
|
switch ($this->operator) {
|
|
|
|
|
case self::OP_AND:
|
2015-03-16 04:08:00 -04:00
|
|
|
$sort_state = max($sort_states);
|
2014-10-20 10:26:06 -04:00
|
|
|
break;
|
2015-10-05 10:42:04 -04:00
|
|
|
case self::OP_NOT:
|
|
|
|
|
$sort_state = $this->invertSortingState(max($sort_states));
|
|
|
|
|
break;
|
2014-10-20 10:26:06 -04:00
|
|
|
case self::OP_OR:
|
2015-03-16 04:08:00 -04:00
|
|
|
$sort_state = min($sort_states);
|
2014-10-20 10:26:06 -04:00
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
// MIN:
|
|
|
|
|
sort($sort_states);
|
|
|
|
|
|
|
|
|
|
// default -> unknown
|
2015-03-16 04:08:00 -04:00
|
|
|
$sort_state = 3 << self::SHIFT_FLAGS;
|
2014-10-20 10:26:06 -04:00
|
|
|
|
|
|
|
|
for ($i = 1; $i <= $this->operator; $i++) {
|
2015-03-16 04:08:00 -04:00
|
|
|
$sort_state = array_shift($sort_states);
|
2014-10-20 10:26:06 -04:00
|
|
|
}
|
|
|
|
|
}
|
2015-03-16 04:08:00 -04:00
|
|
|
if ($sort_state & self::FLAG_DOWNTIME) {
|
2014-10-20 10:26:06 -04:00
|
|
|
$this->setDowntime(true);
|
|
|
|
|
}
|
2015-03-16 04:08:00 -04:00
|
|
|
if ($sort_state & self::FLAG_ACK) {
|
2014-10-20 10:26:06 -04:00
|
|
|
$this->setAck(true);
|
|
|
|
|
}
|
2015-10-02 15:41:20 -04:00
|
|
|
|
|
|
|
|
$this->state = $this->sortStateTostate($sort_state);
|
|
|
|
|
}
|
|
|
|
|
|
2014-10-20 10:26:06 -04:00
|
|
|
public function setDisplay($display)
|
|
|
|
|
{
|
2015-03-16 08:18:19 -04:00
|
|
|
$this->display = (int) $display;
|
2014-10-20 10:26:06 -04:00
|
|
|
return $this;
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-16 04:08:00 -04:00
|
|
|
public function getDisplay()
|
|
|
|
|
{
|
|
|
|
|
return $this->display;
|
|
|
|
|
}
|
|
|
|
|
|
2014-10-20 10:26:06 -04:00
|
|
|
public function setChildNames($names)
|
|
|
|
|
{
|
2015-03-16 04:08:00 -04:00
|
|
|
sort($names);
|
2014-10-20 10:26:06 -04:00
|
|
|
$this->child_names = $names;
|
|
|
|
|
$this->children = null;
|
|
|
|
|
return $this;
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-16 04:08:00 -04:00
|
|
|
public function getChildNames()
|
|
|
|
|
{
|
|
|
|
|
return $this->child_names;
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-06 03:17:16 -04:00
|
|
|
public function getChildren($filter = null)
|
2014-10-20 10:26:06 -04:00
|
|
|
{
|
|
|
|
|
if ($this->children === null) {
|
|
|
|
|
$this->children = array();
|
|
|
|
|
natsort($this->child_names);
|
|
|
|
|
foreach ($this->child_names as $name) {
|
|
|
|
|
$this->children[$name] = $this->bp->getNode($name);
|
2015-03-16 04:08:00 -04:00
|
|
|
$this->children[$name]->addParent($this);
|
2014-10-20 10:26:06 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return $this->children;
|
|
|
|
|
}
|
2014-11-30 05:57:47 -05:00
|
|
|
|
|
|
|
|
protected function assertNumericOperator()
|
|
|
|
|
{
|
|
|
|
|
if (! is_numeric($this->operator)) {
|
2015-02-06 19:02:53 -05:00
|
|
|
throw new ConfigurationError('Got invalid operator: %s', $this->operator);
|
2014-11-30 05:57:47 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-16 04:08:00 -04:00
|
|
|
protected function getActionIcons($view)
|
2014-11-30 05:57:47 -05:00
|
|
|
{
|
2015-03-16 04:08:00 -04:00
|
|
|
$icons = array();
|
2015-03-16 08:12:20 -04:00
|
|
|
if (! $this->bp->isLocked() && $this->name !== '__unbound__') {
|
2015-03-16 04:08:00 -04:00
|
|
|
$icons[] = $this->actionIcon(
|
|
|
|
|
$view,
|
|
|
|
|
'wrench',
|
|
|
|
|
$view->url('businessprocess/node/edit', array(
|
|
|
|
|
'config' => $this->bp->getName(),
|
|
|
|
|
'node' => $this->name
|
|
|
|
|
)),
|
|
|
|
|
mt('businessprocess', 'Modify this node')
|
|
|
|
|
);
|
2014-11-30 05:57:47 -05:00
|
|
|
}
|
2015-03-16 04:08:00 -04:00
|
|
|
return $icons;
|
2014-11-30 05:57:47 -05:00
|
|
|
}
|
|
|
|
|
|
2015-03-03 06:51:03 -05:00
|
|
|
public function toLegacyConfigString(& $rendered = array())
|
2014-12-02 05:38:42 -05:00
|
|
|
{
|
|
|
|
|
$cfg = '';
|
2015-10-05 10:40:08 -04:00
|
|
|
if (array_key_exists($this->name, $rendered)) {
|
|
|
|
|
return $cfg;
|
|
|
|
|
}
|
|
|
|
|
$rendered[$this->name] = true;
|
2014-12-02 05:38:42 -05:00
|
|
|
$children = array();
|
|
|
|
|
|
|
|
|
|
foreach ($this->getChildren() as $name => $child) {
|
|
|
|
|
$children[] = (string) $child;
|
2015-03-03 06:51:03 -05:00
|
|
|
if (array_key_exists($name, $rendered)) { continue; }
|
2014-12-02 05:38:42 -05:00
|
|
|
if ($child instanceof BpNode) {
|
2015-03-03 06:51:03 -05:00
|
|
|
$cfg .= $child->toLegacyConfigString($rendered) . "\n";
|
2014-12-02 05:38:42 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
$eq = '=';
|
|
|
|
|
$op = $this->operator;
|
|
|
|
|
if (is_numeric($op)) {
|
|
|
|
|
$eq = '= ' . $op . ' of:';
|
|
|
|
|
$op = '+';
|
|
|
|
|
}
|
2015-10-05 10:40:08 -04:00
|
|
|
|
|
|
|
|
$strChildren = implode(' ' . $op . ' ', $children);
|
|
|
|
|
if ((count($children) < 2) && $op !== '&') {
|
|
|
|
|
$strChildren = $op . ' ' . $strChildren;
|
|
|
|
|
}
|
2014-12-02 05:38:42 -05:00
|
|
|
$cfg .= sprintf(
|
|
|
|
|
"%s %s %s\n",
|
|
|
|
|
$this->name,
|
|
|
|
|
$eq,
|
2015-10-05 10:40:08 -04:00
|
|
|
$strChildren
|
2014-12-02 05:38:42 -05:00
|
|
|
);
|
2015-03-16 08:18:19 -04:00
|
|
|
if ($this->hasAlias() || $this->getDisplay() > 0) {
|
|
|
|
|
$prio = $this->getDisplay();
|
2014-12-02 05:38:42 -05:00
|
|
|
$cfg .= sprintf(
|
2015-03-02 12:21:08 -05:00
|
|
|
"display %s;%s;%s\n",
|
2014-12-02 05:38:42 -05:00
|
|
|
$prio,
|
|
|
|
|
$this->name,
|
|
|
|
|
$this->getAlias()
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
if ($this->hasInfoUrl()) {
|
|
|
|
|
$cfg .= sprintf(
|
|
|
|
|
"info_url;%s;%s\n",
|
|
|
|
|
$this->name,
|
|
|
|
|
$this->getInfoUrl()
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $cfg;
|
|
|
|
|
}
|
|
|
|
|
|
2014-11-30 05:57:47 -05:00
|
|
|
public function operatorHtml()
|
|
|
|
|
{
|
|
|
|
|
switch ($this->operator) {
|
|
|
|
|
case self::OP_AND:
|
|
|
|
|
return 'and';
|
|
|
|
|
break;
|
|
|
|
|
case self::OP_OR:
|
|
|
|
|
return 'or';
|
|
|
|
|
break;
|
2015-10-05 10:42:04 -04:00
|
|
|
case self::OP_NOT:
|
|
|
|
|
return 'not';
|
|
|
|
|
break;
|
2014-11-30 05:57:47 -05:00
|
|
|
default:
|
|
|
|
|
// MIN
|
|
|
|
|
$this->assertNumericOperator();
|
|
|
|
|
return 'min:' . $this->operator;
|
|
|
|
|
}
|
|
|
|
|
}
|
2014-10-20 10:26:06 -04:00
|
|
|
}
|