diff --git a/library/Businessprocess/BpNode.php b/library/Businessprocess/BpNode.php index f57e2f5..7682ae0 100644 --- a/library/Businessprocess/BpNode.php +++ b/library/Businessprocess/BpNode.php @@ -430,23 +430,6 @@ class BpNode extends Node } } - protected function getActionIcons($view) - { - $icons = array(); - if (! $this->bp->isLocked() && $this->name !== '__unbound__') { - $icons[] = $this->actionIcon( - $view, - 'wrench', - $view->url('businessprocess/node/edit', array( - 'config' => $this->bp->getName(), - 'node' => $this->name - )), - mt('businessprocess', 'Modify this node') - ); - } - return $icons; - } - public function toLegacyConfigString(& $rendered = array()) { $cfg = ''; diff --git a/library/Businessprocess/BusinessProcess.php b/library/Businessprocess/BusinessProcess.php index 526c135..a3176ea 100644 --- a/library/Businessprocess/BusinessProcess.php +++ b/library/Businessprocess/BusinessProcess.php @@ -99,13 +99,6 @@ class BusinessProcess */ protected $simulation; - /** - * Whether we are in edit mode - * - * @var boolean - */ - protected $editMode = false; - protected $locked = true; protected $changeCount = 0; @@ -261,17 +254,6 @@ class BusinessProcess return $this->simulationCount; } - public function setEditMode($mode = true) - { - $this->editMode = (bool) $mode; - return $this; - } - - public function isEditMode() - { - return $this->editMode; - } - public function clearAppliedChanges() { if ($this->appliedChanges !== null) { @@ -735,37 +717,4 @@ class BusinessProcess { return $this->countChildren() === 0; } - - public function renderHtml($view) - { - $html = ''; - foreach ($this->getRootNodes() as $name => $node) { - $html .= $node->renderHtml($view); - } - return $html; - } - - public function renderUnbound($view) - { - $html = ''; - - $unbound = $this->getUnboundNodes(); - if (empty($unbound)) { - return $html; - } - - $parent = new BpNode($this, (object) array( - 'name' => '__unbound__', - 'operator' => '|', - 'child_names' => array_keys($unbound) - )); - $parent->getState(); - $parent->setMissing() - ->setDowntime(false) - ->setAck(false) - ->setAlias('Unbound nodes'); - - $html .= $parent->renderHtml($view); - return $html; - } } diff --git a/library/Businessprocess/HostNode.php b/library/Businessprocess/HostNode.php index 3f9f540..d28ec2e 100644 --- a/library/Businessprocess/HostNode.php +++ b/library/Businessprocess/HostNode.php @@ -49,28 +49,6 @@ class HostNode extends MonitoredNode return $this->getHostname(); } - protected function getActionIcons($view) - { - $icons = array(); - - if (! $this->bp->isLocked()) { - - $url = Url::fromPath( 'businessprocess/node/simulate', array( - 'config' => $this->bp->getName(), - 'node' => $this->name - )); - - $icons[] = $this->actionIcon( - $view, - 'magic', - $url, - 'Simulation' - ); - } - - return $icons; - } - public function getHostname() { return $this->hostname; @@ -93,13 +71,4 @@ class HostNode extends MonitoredNode { return Link::create($this->hostname, $this->getUrl()); } - - public function renderLink($view) - { - if ($this->isMissing()) { - return '' . $view->escape($this->hostname) . ''; - } - - return $this->getLink()->render(); - } } diff --git a/library/Businessprocess/ImportedNode.php b/library/Businessprocess/ImportedNode.php index f829b92..c099d43 100644 --- a/library/Businessprocess/ImportedNode.php +++ b/library/Businessprocess/ImportedNode.php @@ -3,20 +3,23 @@ namespace Icinga\Module\Businessprocess; use Icinga\Application\Config; -use Icinga\Web\Url; +use Icinga\Module\Businessprocess\Html\Link; use Icinga\Module\Businessprocess\Storage\LegacyStorage; use Exception; class ImportedNode extends Node { + /** @var string */ protected $configName; - protected $importedBp; - - protected $importedNode; + /** @var BpNode */ + private $node; protected $className = 'subtree'; + /** + * @inheritdoc + */ public function __construct(BusinessProcess $bp, $object) { $this->name = $object->name; @@ -29,11 +32,17 @@ class ImportedNode extends Node } } + /** + * @return string + */ public function getConfigName() { return $this->configName; } + /** + * @inheritdoc + */ public function getState() { if ($this->state === null) { @@ -42,17 +51,26 @@ class ImportedNode extends Node return $this->state; } + /** + * @inheritdoc + */ public function getAlias() { return $this->importedNode()->getAlias(); } + /** + * @inheritdoc + */ public function isMissing() { - return $this->importedNode()->isMissing(); // TODO: WHY? return $this->getState() === null; + return $this->importedNode()->isMissing(); } + /** + * @inheritdoc + */ public function isInDowntime() { if ($this->downtime === null) { @@ -61,6 +79,9 @@ class ImportedNode extends Node return $this->downtime; } + /** + * @inheritdoc + */ public function isAcknowledged() { if ($this->ack === null) { @@ -69,68 +90,83 @@ class ImportedNode extends Node return $this->ack; } + /** + * @return BpNode + */ protected function importedNode() { - if ($this->importedNode === null) { - $storage = new LegacyStorage( - Config::module('businessprocess')->getSection('global') - ); - try { - $this->importedBp = $storage->loadProcess($this->configName); - if ($this->bp->usesSoftStates()) { - $this->importedBp->useSoftStates(); - } else { - $this->importedBp->useHardStates(); - } - $this->importedBp->retrieveStatesFromBackend(); - $this->importedNode = $this->importedBp->getNode($this->name); - } catch (Exception $e) { + if ($this->node === null) { + $this->node = $this->loadImportedNode(); + } + return $this->node; + } - $node = new BpNode($this->bp, (object) array( - 'name' => $this->name, - 'operator' => '&', - 'child_names' => array() - )); - $node->setState(2); - $node->setMissing(false) - ->setDowntime(false) - ->setAck(false) - ->setAlias($e->getMessage()); - - $this->importedNode = $node; + /** + * @return BpNode + */ + protected function loadImportedNode() + { + try { + $import = $this->storage()->loadProcess($this->configName); + if ($this->bp->usesSoftStates()) { + $import->useSoftStates(); + } else { + $import->useHardStates(); } + + $import->retrieveStatesFromBackend(); + + return $import->getNode($this->name); + } catch (Exception $e) { + + return $this->createFailedNode($e); } - return $this->importedNode; - } - - protected function getActionIcons($view) - { - $icons = array(); - - if (! $this->bp->isLocked()) { - - $url = Url::fromPath( 'businessprocess/node/simulate', array( - 'config' => $this->bp->getName(), - 'node' => $this->name - )); - - $icons[] = $this->actionIcon( - $view, - 'magic', - $url, - 'Simulation' - ); - } - - return $icons; } - public function renderLink($view) + /** + * @return LegacyStorage + */ + protected function storage() { - return $view->qlink($this->getAlias(), 'businessprocess/process/show', array( - 'config' => $this->configName, - 'process' => $this->name + return new LegacyStorage( + Config::module('businessprocess')->getSection('global') + ); + } + + /** + * @param Exception $e + * + * @return BpNode + */ + protected function createFailedNode(Exception $e) + { + $node = new BpNode($this->bp, (object) array( + 'name' => $this->name, + 'operator' => '&', + 'child_names' => array() )); + $node->setState(2); + $node->setMissing(false) + ->setDowntime(false) + ->setAck(false) + ->setAlias($e->getMessage()); + + return $node; + } + + /** + * @inheritdoc + */ + public function getLink() + { + return Link::create( + $this->getAlias(), + 'businessprocess/process/show', + array( + 'config' => $this->configName, + 'process' => $this->name + ) + ); } } diff --git a/library/Businessprocess/MonitoredNode.php b/library/Businessprocess/MonitoredNode.php index aa5e773..68e4866 100644 --- a/library/Businessprocess/MonitoredNode.php +++ b/library/Businessprocess/MonitoredNode.php @@ -2,7 +2,6 @@ namespace Icinga\Module\Businessprocess; -use Icinga\Module\Businessprocess\Html\Container; use Icinga\Module\Businessprocess\Html\Link; abstract class MonitoredNode extends Node @@ -17,19 +16,4 @@ abstract class MonitoredNode extends Node return Link::create($this->getAlias(), $this->getUrl()); } } - - protected function prepareActions(Container $actions) - { - $actions->add( - $url = Link::create( - $actions->view()->translate('Simulate a specific state'), - 'businessprocess/process/show?addSimulation&unlocked', - array( - 'config' => $this->bp->getName(), - 'simulationNode' => $this->name - ), - array('class' => 'icon-magic') - ) - ); - } } diff --git a/library/Businessprocess/Node.php b/library/Businessprocess/Node.php index 693b6e8..7e2e2b5 100644 --- a/library/Businessprocess/Node.php +++ b/library/Businessprocess/Node.php @@ -2,10 +2,8 @@ namespace Icinga\Module\Businessprocess; -use Icinga\Web\Url; use Icinga\Exception\ProgrammingError; -use Icinga\Data\Filter\Filter; -use Exception; +use Icinga\Module\Businessprocess\Html\Link; abstract class Node { @@ -253,16 +251,6 @@ abstract class Node return $this->ack; } - public function isSimulationMode() - { - return $this->bp->isSimulationMode(); - } - - public function isEditMode() - { - return $this->bp->isEditMode(); - } - public function getChildren($filter = null) { return array(); @@ -323,142 +311,17 @@ abstract class Node throw new ProgrammingError('Got invalid sorting state %s', $sortState); } - protected function renderHtmlForChildren($view) - { - $html = ''; - if ($this->hasChildren()) { - foreach ($this->getChildren() as $name => $child) { - $html .= '' - . $child->renderHtml($view) - . ''; - } - } - - return $html; - } - - protected function getId($prefix = '') - { - return md5($prefix . (string) $this); - } - - protected function getObjectClassName() + public function getObjectClassName() { return $this->className; } - protected function getStateClassNames() + /** + * @return Link + */ + public function getLink() { - $state = strtolower($this->getStateName()); - - if ($this->isMissing()) { - return array('missing'); - } elseif ($state === 'ok') { - if ($this->hasMissingChildren()) { - return array('ok', 'missing-children'); - } else { - return array('ok'); - } - } else { - return array('problem', $state); - } - } - - public function renderHtml($view, $prefix = '') - { - $id = $this->getId($prefix); - $handled = $this->isAcknowledged() || $this->isInDowntime(); - - $html = sprintf( - '', - implode(' ', $this->getStateClassNames()), - $handled ? ' handled' : '', - ($this->hasChildren() ? ' operator ' : ' node '), - $this->getObjectClassName(), - $id - ); - - if ($this->hasChildren()) { - $html .= sprintf( - '%s', - sprintf(' rowspan="%d"', $this->countChildren() + 1), - $this->operatorHtml() - ); - } - - - $title = preg_replace( - '~()~', - implode('', $this->getIcons($view)) . '$1', - $this->renderLink($view) - ); - - $title = preg_replace('##', ' ' . $view->timeSince($this->getLastStateChange()) . '', $title); - $icons = array(); - - foreach ($this->getActionIcons($view) as $icon) { - $icons[] = $icon; - } - - if ($this->hasInfoUrl()) { - $url = $this->getInfoUrl(); - $icons[] = $this->actionIcon( - $view, - 'help', - $url, - sprintf('%s: %s', mt('businessprocess', 'More information'), $url) - ); - } - $title = implode("\n", $icons) . $title; - - $html .= sprintf( - '', - $title - ); - foreach ($this->getChildren() as $name => $child) { - $html .= ''; - } - $html .= "
%s
' . $child->renderHtml($view, $id . '-') . '
\n"; - return $html; - } - - protected function getActionIcons($view) - { - return array(); - } - - protected function actionIcon($view, $icon, $url, $title) - { - if ($url instanceof Url || ! preg_match('~^https?://~', $url)) { - $target = ''; - } else { - $target = ' target="_blank"'; - } - - return sprintf( - ' %s', - $url, - $target, - $view->escape($title), - $view->icon($icon) - ); - } - - public function renderLink($view) - { - return '' . ($this->hasAlias() ? $this->getAlias() : $this->name) . ''; - } - - public function getIcons($view) - { - $icons = array(); - if ($this->isInDowntime()) { - $icons[] = $view->icon('moon'); - } - if ($this->isAcknowledged()) { - $icons[] = $view->icon('ok'); - } - return $icons; + return Link::create($this->getAlias(), '#'); } public function operatorHtml() @@ -473,13 +336,18 @@ abstract class Node return ''; } - public function __toString() + public function getName() { return $this->name; } + public function __toString() + { + return $this->getName(); + } + public function __destruct() { - $this->parents = array(); + unset($this->parents); } } diff --git a/library/Businessprocess/Renderer/Renderer.php b/library/Businessprocess/Renderer/Renderer.php index 9a6ad32..ba3088a 100644 --- a/library/Businessprocess/Renderer/Renderer.php +++ b/library/Businessprocess/Renderer/Renderer.php @@ -2,21 +2,21 @@ namespace Icinga\Module\Businessprocess\Renderer; +use Icinga\Date\DateFormatter; use Icinga\Exception\ProgrammingError; use Icinga\Module\Businessprocess\BpNode; use Icinga\Module\Businessprocess\BusinessProcess; use Icinga\Module\Businessprocess\Html\Container; use Icinga\Module\Businessprocess\Html\Element; use Icinga\Module\Businessprocess\Html\Html; +use Icinga\Module\Businessprocess\Html\HtmlString; +use Icinga\Module\Businessprocess\Html\Text; use Icinga\Module\Businessprocess\Node; use Icinga\Module\Businessprocess\Web\Url; -use Icinga\Web\View; +use Icinga\Web\Request; abstract class Renderer extends Html { - /** @var View */ - protected $view; - /** @var BusinessProcess */ protected $bp; @@ -35,15 +35,13 @@ abstract class Renderer extends Html /** * Renderer constructor. * - * @param View $view * @param BusinessProcess $bp * @param BpNode|null $parent */ - public function __construct(View $view, BusinessProcess $bp, BpNode $parent = null) + public function __construct(BusinessProcess $bp, BpNode $parent = null) { $this->bp = $bp; $this->parent = $parent; - $this->view = $view; } /** @@ -117,7 +115,6 @@ abstract class Renderer extends Html ) )->setContent($cnt) ); - } return $container; @@ -213,6 +210,40 @@ abstract class Renderer extends Html $this->locked = false; return $this; } + + 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)); + } + + protected function createUnboundParent(BusinessProcess $bp) + { + $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; + } + /** * Just to be on the safe side */ @@ -220,6 +251,5 @@ abstract class Renderer extends Html { unset($this->parent); unset($this->bp); - unset($this->view); } } diff --git a/library/Businessprocess/Renderer/TileRenderer.php b/library/Businessprocess/Renderer/TileRenderer.php index 8a3714c..afaf858 100644 --- a/library/Businessprocess/Renderer/TileRenderer.php +++ b/library/Businessprocess/Renderer/TileRenderer.php @@ -39,6 +39,12 @@ class TileRenderer extends Renderer $this->add(new NodeTile($this, $name, $node, $path)); } + $unbound = $this->createUnboundParent($bp); + if ($unbound->hasChildren()) { + $name = $unbound->getAlias(); + $this->add($this->add(new NodeTile($this, $name, $unbound))); + } + $nodesDiv->addContent($this->getContent()); $this->setContent($nodesDiv); diff --git a/library/Businessprocess/Renderer/TreeRenderer.php b/library/Businessprocess/Renderer/TreeRenderer.php new file mode 100644 index 0000000..ce2c297 --- /dev/null +++ b/library/Businessprocess/Renderer/TreeRenderer.php @@ -0,0 +1,211 @@ +bp; + $this->add(Container::create( + array( + 'id' => $bp->getHtmlId(), + 'class' => 'bp' + ), + HtmlString::create($this->renderBp($bp)) + )); + + return parent::render(); + } + + /** + * @param BusinessProcess $bp + * @return string + */ + public function renderBp(BusinessProcess $bp) + { + $html = ''; + foreach ($bp->getRootNodes() as $name => $node) { + $html .= $this->renderNode($bp, $node); + } + + return $html; + } + + /** + * @param Node $node + * @param $path + * @return string + */ + protected function getId(Node $node, $path) + { + return md5(implode(';', $path) . (string) $node); + } + + protected function getStateClassNames(Node $node) + { + $state = strtolower($node->getStateName()); + + if ($node->isMissing()) { + return array('missing'); + } elseif ($state === 'ok') { + if ($node->hasMissingChildren()) { + return array('ok', 'missing-children'); + } else { + return array('ok'); + } + } else { + return array('problem', $state); + } + } + + /** + * @param Node $node + * @return Icon[] + */ + public function getNodeIcons(Node $node) + { + $icons = array(); + if ($node->isInDowntime()) { + $icons[] = Icon::create('moon'); + } + if ($node->isAcknowledged()) { + $icons[] = Icon::create('ok'); + } + return $icons; + } + + /** + * @param Node $node + * @return string + */ + public function renderNode(BusinessProcess $bp, Node $node, $path = array()) + { + $table = Element::create( + 'table', + array( + 'id' => $this->getId($node, $path), + 'class' => array( + 'bp', + $node->getObjectClassName() + ) + ) + ); + $attributes = $table->attributes(); + $attributes->add('class', $this->getStateClassNames($node)); + if ($node->isHandled()) { + $attributes->add('class', 'handled'); + } + if ($node->hasChildren()) { + $attributes->add('class', 'operator'); + } else { + $attributes->add('class', 'node'); + } + + $tbody = $table->createElement('tbody'); + $tr = $tbody->createElement('tr'); + + if ($node->hasChildren()) { + $tr->createElement( + 'th', + array( + 'rowspan' => $node->countChildren() + 1 + ) + )->createElement( + 'span', + array('class' => 'op') + )->setContent($node->operatorHtml()); + } + $td = $tr->createElement('td'); + $td->addContent($this->getActionIcons($bp, $node)); + + if ($node->hasInfoUrl()) { + $td->add($this->createInfoAction($node)); + } + + if (! $this->bp->isLocked()) { + $td->addContent($this->getActionIcons($bp, $node)); + } + + $link = $node->getLink(); + $link->addContent($this->getNodeIcons($node)); + $link->addContent($this->timeSince($node->getLastStateChange())); + $td->addContent($link); + + foreach ($node->getChildren() as $name => $child) { + $tbody->createElement('tr')->createElement('td')->setContent( + $this->renderNode($bp, $child, $this->getCurrentPath()) + ); + } + + return $table; + } + + protected function getActionIcons(BusinessProcess $bp, Node $node) + { + if ($node instanceof BpNode) { + return $this->createEditAction($bp, $node); + } else { + return $this->createSimulationAction($bp, $node); + } + } + + protected function createEditAction(BusinessProcess $bp, BpNode $node) + { + return $this->actionIcon( + 'wrench', + Url::fromPath('businessprocess/node/edit', array( + 'config' => $bp->getName(), + 'node' => $node->getName() + )), + $this->translate('Modify this node') + ); + } + + protected function createSimulationAction(BusinessProcess $bp, Node $node) + { + return $this->actionIcon( + 'magic', + Url::fromPath('businessprocess/process/show?addSimulation&unlocked', array( + 'config' => $bp->getName(), + 'node' => $node->getName() + )), + $this->translate('Simulate a specific state') + ); + } + + protected function createInfoAction(BpNode $node) + { + $url = $node->getInfoUrl(); + return $this->actionIcon( + 'help', + $url, + sprintf('%s: %s', $this->translate('More information'), $url) + ); + } + protected function actionIcon($icon, $url, $title) + { + return Link::create( + Icon::create($icon), + $url, + null, + array( + 'title' => $title, + 'style' => 'float: right', + ) + ); + } +} diff --git a/library/Businessprocess/ServiceNode.php b/library/Businessprocess/ServiceNode.php index 52eea76..2a582e7 100644 --- a/library/Businessprocess/ServiceNode.php +++ b/library/Businessprocess/ServiceNode.php @@ -2,7 +2,6 @@ namespace Icinga\Module\Businessprocess; -use Icinga\Module\Businessprocess\Html\Link; use Icinga\Module\Businessprocess\Web\Url; class ServiceNode extends MonitoredNode @@ -26,28 +25,6 @@ class ServiceNode extends MonitoredNode } } - protected function getActionIcons($view) - { - $icons = array(); - - if (! $this->bp->isLocked()) { - - $url = Url::fromPath('businessprocess/node/simulate', array( - 'config' => $this->bp->getName(), - 'node' => $this->name - )); - - $icons[] = $this->actionIcon( - $view, - 'magic', - $url, - 'Simulation' - ); - } - - return $icons; - } - public function getHostname() { return $this->hostname; @@ -76,13 +53,4 @@ class ServiceNode extends MonitoredNode return Url::fromPath('monitoring/service/show', $params); } - - public function renderLink($view) - { - if ($this->isMissing()) { - return '' . $view->escape($this->getAlias()) . ''; - } - - return $this->getLink()->render(); - } }