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;
|
2017-01-27 09:32:08 -05:00
|
|
|
use Icinga\Exception\NotFoundError;
|
2016-11-24 04:57:30 -05:00
|
|
|
use Icinga\Module\Businessprocess\Exception\NestingError;
|
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;
|
2016-11-23 20:40:01 -05:00
|
|
|
|
|
|
|
|
/** @var Node[] */
|
2014-10-20 10:26:06 -04:00
|
|
|
protected $children;
|
2016-11-23 20:40:01 -05:00
|
|
|
|
|
|
|
|
/** @var array */
|
|
|
|
|
protected $childNames = array();
|
2014-10-20 10:26:06 -04:00
|
|
|
protected $alias;
|
|
|
|
|
protected $counters;
|
2015-03-03 05:00:15 -05:00
|
|
|
protected $missing = null;
|
2015-11-23 07:05:41 -05:00
|
|
|
protected $missingChildren;
|
2014-10-20 10:26:06 -04:00
|
|
|
|
2015-10-06 16:35:00 -04:00
|
|
|
protected static $emptyStateSummary = array(
|
|
|
|
|
'OK' => 0,
|
|
|
|
|
'WARNING' => 0,
|
|
|
|
|
'CRITICAL' => 0,
|
|
|
|
|
'UNKNOWN' => 0,
|
|
|
|
|
'PENDING' => 0,
|
|
|
|
|
'UP' => 0,
|
|
|
|
|
'DOWN' => 0,
|
|
|
|
|
'UNREACHABLE' => 0,
|
|
|
|
|
'MISSING' => 0,
|
|
|
|
|
);
|
|
|
|
|
|
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';
|
|
|
|
|
|
2017-01-11 08:04:45 -05:00
|
|
|
public function __construct(BpConfig $bp, $object)
|
2015-10-05 06:39:37 -04:00
|
|
|
{
|
2014-10-20 10:26:06 -04:00
|
|
|
$this->bp = $bp;
|
|
|
|
|
$this->name = $object->name;
|
2019-01-28 02:50:42 -05:00
|
|
|
$this->operator = $object->operator;
|
|
|
|
|
$this->childNames = $object->child_names;
|
2014-10-20 10:26:06 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function getStateSummary()
|
|
|
|
|
{
|
|
|
|
|
if ($this->counters === null) {
|
|
|
|
|
$this->getState();
|
2015-10-06 16:35:00 -04:00
|
|
|
$this->counters = self::$emptyStateSummary;
|
|
|
|
|
|
2016-11-26 15:18:18 -05:00
|
|
|
foreach ($this->getChildren() as $child) {
|
2014-10-20 10:26:06 -04:00
|
|
|
if ($child instanceof BpNode) {
|
|
|
|
|
$counters = $child->getStateSummary();
|
|
|
|
|
foreach ($counters as $k => $v) {
|
|
|
|
|
$this->counters[$k] += $v;
|
|
|
|
|
}
|
2017-06-01 10:51:22 -04:00
|
|
|
} elseif ($child->isMissing()) {
|
|
|
|
|
$this->counters['MISSING']++;
|
2014-10-20 10:26:06 -04:00
|
|
|
} else {
|
2015-10-06 16:35:00 -04:00
|
|
|
$state = $child->getStateName();
|
2014-10-20 10:26:06 -04:00
|
|
|
$this->counters[$state]++;
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-06-01 10:51:22 -04:00
|
|
|
if (! $this->hasChildren()) {
|
|
|
|
|
$this->counters['MISSING']++;
|
|
|
|
|
}
|
2014-10-20 10:26:06 -04:00
|
|
|
}
|
|
|
|
|
return $this->counters;
|
|
|
|
|
}
|
|
|
|
|
|
2015-11-19 08:46:10 -05:00
|
|
|
public function hasProblems()
|
|
|
|
|
{
|
|
|
|
|
if ($this->isProblem()) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$okStates = array('OK', 'UP', 'PENDING', 'MISSING');
|
|
|
|
|
|
|
|
|
|
foreach ($this->getStateSummary() as $state => $cnt) {
|
|
|
|
|
if ($cnt !== 0 && ! in_array($state, $okStates)) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-23 20:40:01 -05:00
|
|
|
/**
|
|
|
|
|
* @param Node $node
|
|
|
|
|
* @return $this
|
|
|
|
|
* @throws ConfigurationError
|
|
|
|
|
*/
|
|
|
|
|
public function addChild(Node $node)
|
|
|
|
|
{
|
|
|
|
|
if ($this->children === null) {
|
|
|
|
|
$this->getChildren();
|
|
|
|
|
}
|
|
|
|
|
|
2017-01-11 11:38:19 -05:00
|
|
|
$name = $node->getName();
|
2016-11-23 20:40:01 -05:00
|
|
|
if (array_key_exists($name, $this->children)) {
|
|
|
|
|
throw new ConfigurationError(
|
|
|
|
|
'Node "%s" has been defined more than once',
|
|
|
|
|
$name
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
$this->children[$name] = $node;
|
2016-11-29 05:20:54 -05:00
|
|
|
$this->childNames[] = $name;
|
2016-11-23 20:40:01 -05:00
|
|
|
$node->addParent($this);
|
|
|
|
|
return $this;
|
|
|
|
|
}
|
|
|
|
|
|
2015-11-19 08:46:10 -05:00
|
|
|
public function getProblematicChildren()
|
|
|
|
|
{
|
|
|
|
|
$problems = array();
|
|
|
|
|
|
2017-01-27 09:32:08 -05:00
|
|
|
foreach ($this->getChildren() as $child) {
|
2015-11-19 08:46:10 -05:00
|
|
|
if ($child->isProblem()
|
|
|
|
|
|| ($child instanceof BpNode && $child->hasProblems())
|
|
|
|
|
) {
|
|
|
|
|
$problems[] = $child;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $problems;
|
|
|
|
|
}
|
|
|
|
|
|
2017-01-03 05:23:05 -05:00
|
|
|
public function hasChild($name)
|
|
|
|
|
{
|
2019-01-28 02:50:42 -05:00
|
|
|
return in_array($name, $this->getChildNames());
|
2017-01-03 05:23:05 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function removeChild($name)
|
|
|
|
|
{
|
2019-01-28 02:50:42 -05:00
|
|
|
if (($key = array_search($name, $this->getChildNames())) !== false) {
|
2017-01-03 05:23:05 -05:00
|
|
|
unset($this->childNames[$key]);
|
|
|
|
|
|
|
|
|
|
if (! empty($this->children)) {
|
|
|
|
|
unset($this->children[$name]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $this;
|
|
|
|
|
}
|
|
|
|
|
|
2015-11-19 08:46:10 -05:00
|
|
|
public function getProblemTree()
|
|
|
|
|
{
|
|
|
|
|
$tree = array();
|
|
|
|
|
|
|
|
|
|
foreach ($this->getProblematicChildren() as $child) {
|
|
|
|
|
$name = (string) $child;
|
|
|
|
|
$tree[$name] = array(
|
|
|
|
|
'node' => $child,
|
|
|
|
|
'children' => array()
|
|
|
|
|
);
|
|
|
|
|
if ($child instanceof BpNode) {
|
|
|
|
|
$tree[$name]['children'] = $child->getProblemTree();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $tree;
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-03 05:00:15 -05:00
|
|
|
public function isMissing()
|
|
|
|
|
{
|
|
|
|
|
if ($this->missing === null) {
|
|
|
|
|
$exists = false;
|
2017-03-21 06:30:49 -04:00
|
|
|
$bp = $this->bp;
|
|
|
|
|
$bp->beginLoopDetection($this->name);
|
2015-03-03 05:00:15 -05:00
|
|
|
foreach ($this->getChildren() as $child) {
|
|
|
|
|
if (! $child->isMissing()) {
|
|
|
|
|
$exists = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-03-21 06:30:49 -04:00
|
|
|
$bp->endLoopDetection($this->name);
|
2015-03-03 05:00:15 -05:00
|
|
|
$this->missing = ! $exists;
|
|
|
|
|
}
|
|
|
|
|
return $this->missing;
|
|
|
|
|
}
|
|
|
|
|
|
2015-11-23 07:05:41 -05:00
|
|
|
public function getMissingChildren()
|
|
|
|
|
{
|
|
|
|
|
if ($this->missingChildren === null) {
|
2016-04-07 09:48:31 -04:00
|
|
|
$missing = array();
|
|
|
|
|
|
2015-11-23 07:05:41 -05:00
|
|
|
foreach ($this->getChildren() as $child) {
|
|
|
|
|
if ($child->isMissing()) {
|
|
|
|
|
$missing[(string) $child] = $child;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
foreach ($child->getMissingChildren() as $m) {
|
|
|
|
|
$missing[(string) $m] = $m;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$this->missingChildren = $missing;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $this->missingChildren;
|
|
|
|
|
}
|
|
|
|
|
|
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
|
|
|
{
|
2017-01-03 05:27:58 -05:00
|
|
|
return ! empty($this->url);
|
2014-10-20 10:26:06 -04:00
|
|
|
}
|
|
|
|
|
|
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()
|
|
|
|
|
{
|
2019-01-28 02:50:42 -05:00
|
|
|
return $this->getAlias() !== null;
|
2014-12-01 13:32:09 -05:00
|
|
|
}
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-24 04:57:30 -05:00
|
|
|
/**
|
|
|
|
|
* @return int
|
|
|
|
|
*/
|
2014-10-20 10:26:06 -04:00
|
|
|
public function getState()
|
|
|
|
|
{
|
|
|
|
|
if ($this->state === null) {
|
2016-11-24 04:57:30 -05:00
|
|
|
try {
|
|
|
|
|
$this->reCalculateState();
|
|
|
|
|
} catch (NestingError $e) {
|
|
|
|
|
$this->bp->addError(
|
|
|
|
|
$this->bp->translate('Nesting error detected: %s'),
|
|
|
|
|
$e->getMessage()
|
|
|
|
|
);
|
|
|
|
|
|
2016-12-16 13:47:36 -05:00
|
|
|
// Failing nodes are unknown
|
2016-11-24 04:57:30 -05:00
|
|
|
$this->state = 3;
|
|
|
|
|
}
|
2014-10-20 10:26:06 -04:00
|
|
|
}
|
2016-11-24 04:57:30 -05:00
|
|
|
|
2014-10-20 10:26:06 -04:00
|
|
|
return $this->state;
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-28 11:30:27 -05:00
|
|
|
public function getHtmlId()
|
|
|
|
|
{
|
|
|
|
|
return 'businessprocess-' . preg_replace('/[\r\n\t\s]/', '_', (string) $this);
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-05 10:42:04 -04:00
|
|
|
protected function invertSortingState($state)
|
|
|
|
|
{
|
|
|
|
|
return self::$sortStateInversionMap[$state >> self::SHIFT_FLAGS] << self::SHIFT_FLAGS;
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-24 04:57:30 -05:00
|
|
|
/**
|
|
|
|
|
* @return $this
|
|
|
|
|
*/
|
|
|
|
|
public function reCalculateState()
|
2014-10-20 10:26:06 -04:00
|
|
|
{
|
2016-11-29 05:22:44 -05:00
|
|
|
$bp = $this->bp;
|
|
|
|
|
|
2014-10-20 10:26:06 -04:00
|
|
|
$sort_states = array();
|
2015-10-02 02:32:54 -04:00
|
|
|
$lastStateChange = 0;
|
2016-11-29 05:22:44 -05:00
|
|
|
|
2016-11-24 04:57:30 -05:00
|
|
|
if (!$this->hasChildren()) {
|
2016-11-29 05:22:44 -05:00
|
|
|
// TODO: delegate this to operators, should mostly fail
|
2017-02-20 08:57:17 -05:00
|
|
|
$this->setState(self::ICINGA_UNKNOWN);
|
2016-11-29 05:22:44 -05:00
|
|
|
$this->setMissing();
|
2016-11-24 04:57:30 -05:00
|
|
|
return $this;
|
|
|
|
|
}
|
|
|
|
|
|
2014-10-20 10:26:06 -04:00
|
|
|
foreach ($this->getChildren() as $child) {
|
2016-11-29 05:22:44 -05:00
|
|
|
$bp->beginLoopDetection($this->name);
|
2017-02-20 08:41:15 -05:00
|
|
|
if ($child instanceof MonitoredNode && $child->isMissing()) {
|
2017-02-20 09:00:15 -05:00
|
|
|
if ($child instanceof HostNode) {
|
|
|
|
|
$child->setState(self::ICINGA_UNREACHABLE);
|
|
|
|
|
} else {
|
|
|
|
|
$child->setState(self::ICINGA_UNKNOWN);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$child->setMissing();
|
2017-02-20 08:41:15 -05:00
|
|
|
}
|
2017-02-20 08:57:17 -05:00
|
|
|
$sort_states[] = $child->getSortingState();
|
|
|
|
|
$lastStateChange = max($lastStateChange, $child->getLastStateChange());
|
|
|
|
|
$bp->endLoopDetection($this->name);
|
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);
|
|
|
|
|
|
2019-01-28 02:50:42 -05:00
|
|
|
switch ($this->getOperator()) {
|
2014-10-20 10:26:06 -04:00
|
|
|
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:
|
2015-03-16 04:08:00 -04:00
|
|
|
$sort_state = 3 << self::SHIFT_FLAGS;
|
2014-10-20 10:26:06 -04:00
|
|
|
|
2018-03-20 11:31:58 -04:00
|
|
|
if (count($sort_states) >= $this->operator) {
|
|
|
|
|
$actualGood = 0;
|
|
|
|
|
foreach ($sort_states as $s) {
|
|
|
|
|
if (($s >> self::SHIFT_FLAGS) === self::ICINGA_OK) {
|
|
|
|
|
$actualGood++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ($actualGood >= $this->operator) {
|
|
|
|
|
// condition is fulfilled
|
|
|
|
|
$sort_state = self::ICINGA_OK;
|
|
|
|
|
} else {
|
|
|
|
|
// worst state if not fulfilled
|
|
|
|
|
$sort_state = max($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);
|
2016-11-24 04:57:30 -05:00
|
|
|
return $this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function checkForLoops()
|
|
|
|
|
{
|
2016-11-29 05:11:43 -05:00
|
|
|
$bp = $this->bp;
|
2016-11-24 04:57:30 -05:00
|
|
|
foreach ($this->getChildren() as $child) {
|
2016-11-29 05:11:43 -05:00
|
|
|
$bp->beginLoopDetection($this->name);
|
2016-11-24 04:57:30 -05:00
|
|
|
if ($child instanceof BpNode) {
|
|
|
|
|
$child->checkForLoops();
|
|
|
|
|
}
|
2016-11-29 05:11:43 -05:00
|
|
|
$bp->endLoopDetection($this->name);
|
2016-11-24 04:57:30 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $this;
|
2015-10-02 15:41:20 -04:00
|
|
|
}
|
|
|
|
|
|
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)
|
|
|
|
|
{
|
2018-12-17 08:45:56 -05:00
|
|
|
if (! $this->bp->getMetadata()->isManuallyOrdered()) {
|
|
|
|
|
natcasesort($names);
|
2019-01-14 09:01:43 -05:00
|
|
|
$names = array_values($names);
|
2018-12-17 08:45:56 -05:00
|
|
|
}
|
|
|
|
|
|
2016-11-23 20:40:01 -05:00
|
|
|
$this->childNames = $names;
|
2014-10-20 10:26:06 -04:00
|
|
|
$this->children = null;
|
|
|
|
|
return $this;
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-23 20:40:01 -05:00
|
|
|
public function hasChildren($filter = null)
|
|
|
|
|
{
|
2019-01-28 02:50:42 -05:00
|
|
|
$childNames = $this->getChildNames();
|
|
|
|
|
return !empty($childNames);
|
2016-11-23 20:40:01 -05:00
|
|
|
}
|
|
|
|
|
|
2015-03-16 04:08:00 -04:00
|
|
|
public function getChildNames()
|
|
|
|
|
{
|
2016-11-23 20:40:01 -05:00
|
|
|
return $this->childNames;
|
2015-03-16 04:08:00 -04:00
|
|
|
}
|
|
|
|
|
|
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();
|
2018-12-17 08:45:56 -05:00
|
|
|
if (! $this->bp->getMetadata()->isManuallyOrdered()) {
|
2019-01-28 02:50:42 -05:00
|
|
|
$childNames = $this->getChildNames();
|
|
|
|
|
natcasesort($childNames);
|
|
|
|
|
$this->childNames = array_values($childNames);
|
2018-12-17 08:45:56 -05:00
|
|
|
}
|
2019-01-28 02:50:42 -05:00
|
|
|
foreach ($this->getChildNames() as $name) {
|
2014-10-20 10:26:06 -04:00
|
|
|
$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
|
|
|
}
|
|
|
|
|
}
|
2016-11-23 20:40:01 -05:00
|
|
|
|
2014-10-20 10:26:06 -04:00
|
|
|
return $this->children;
|
|
|
|
|
}
|
2014-11-30 05:57:47 -05:00
|
|
|
|
2017-01-11 07:40:42 -05:00
|
|
|
/**
|
|
|
|
|
* return BpNode[]
|
|
|
|
|
*/
|
|
|
|
|
public function getChildBpNodes()
|
2014-12-02 05:38:42 -05:00
|
|
|
{
|
|
|
|
|
$children = array();
|
2016-11-23 06:35:17 -05:00
|
|
|
|
2017-01-11 07:40:42 -05:00
|
|
|
foreach ($this->getChildren() as $name => $child) {
|
2014-12-02 05:38:42 -05:00
|
|
|
if ($child instanceof BpNode) {
|
2017-01-11 07:40:42 -05:00
|
|
|
$children[$name] = $child;
|
2014-12-02 05:38:42 -05:00
|
|
|
}
|
|
|
|
|
}
|
2015-10-05 10:40:08 -04:00
|
|
|
|
2017-01-11 07:40:42 -05:00
|
|
|
return $children;
|
|
|
|
|
}
|
2014-12-02 05:38:42 -05:00
|
|
|
|
2017-01-27 09:32:08 -05:00
|
|
|
/**
|
|
|
|
|
* @param $childName
|
|
|
|
|
* @return Node
|
|
|
|
|
* @throws NotFoundError
|
|
|
|
|
*/
|
|
|
|
|
public function getChildByName($childName)
|
|
|
|
|
{
|
|
|
|
|
foreach ($this->getChildren() as $name => $child) {
|
|
|
|
|
if ($name === $childName) {
|
|
|
|
|
return $child;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
throw new NotFoundError('Trying to get missing child %s', $childName);
|
|
|
|
|
}
|
|
|
|
|
|
2017-01-11 07:40:42 -05:00
|
|
|
protected function assertNumericOperator()
|
|
|
|
|
{
|
2019-01-28 02:50:42 -05:00
|
|
|
if (! is_numeric($this->getOperator())) {
|
2017-01-11 07:40:42 -05:00
|
|
|
throw new ConfigurationError('Got invalid operator: %s', $this->operator);
|
|
|
|
|
}
|
2014-12-02 05:38:42 -05:00
|
|
|
}
|
|
|
|
|
|
2014-11-30 05:57:47 -05:00
|
|
|
public function operatorHtml()
|
|
|
|
|
{
|
2019-01-28 02:50:42 -05:00
|
|
|
switch ($this->getOperator()) {
|
2014-11-30 05:57:47 -05:00
|
|
|
case self::OP_AND:
|
2019-01-22 05:19:24 -05:00
|
|
|
return 'AND';
|
2014-11-30 05:57:47 -05:00
|
|
|
break;
|
|
|
|
|
case self::OP_OR:
|
2019-01-22 05:19:24 -05:00
|
|
|
return 'OR';
|
2014-11-30 05:57:47 -05:00
|
|
|
break;
|
2015-10-05 10:42:04 -04:00
|
|
|
case self::OP_NOT:
|
2019-01-22 05:19:24 -05:00
|
|
|
return 'NOT';
|
2015-10-05 10:42:04 -04:00
|
|
|
break;
|
2014-11-30 05:57:47 -05:00
|
|
|
default:
|
|
|
|
|
// MIN
|
|
|
|
|
$this->assertNumericOperator();
|
|
|
|
|
return 'min:' . $this->operator;
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-01-22 05:21:40 -05:00
|
|
|
|
|
|
|
|
public function getIcon()
|
|
|
|
|
{
|
|
|
|
|
$this->icon = $this->hasParents() ? 'cubes' : 'sitemap';
|
|
|
|
|
return parent::getIcon();
|
|
|
|
|
}
|
2014-10-20 10:26:06 -04:00
|
|
|
}
|