getView(); if ($this->hasParentNode()) { $this->addHtml( '

' . $view->escape( sprintf($this->translate('Add a node to %s'), $this->parent->getAlias()) ) . '

' ); } else { $this->addHtml( '

' . $this->translate('Add a new root node') . '

' ); } $type = $this->selectNodeType(); switch ($type) { case 'host': $this->selectHost(); break; case 'service': $this->selectService(); break; case 'process': $this->selectProcess(); break; case 'new-process': $this->addNewProcess(); break; case null: $this->setSubmitLabel($this->translate('Next')); return; } } protected function addNewProcess() { $this->addElement('text', 'name', array( 'label' => $this->translate('ID'), 'required' => true, 'description' => $this->translate( 'This is the unique identifier of this process' ), 'validators' => [ ['Callback', true, [ 'callback' => function ($value) { if ($this->hasParentNode()) { return ! $this->parent->hasChild($value); } return ! $this->bp->hasRootNode($value); }, 'messages' => [ 'callbackValue' => $this->translate('%value% is already defined in this process') ] ]] ] )); $this->addElement('text', 'alias', array( 'label' => $this->translate('Display Name'), 'description' => $this->translate( 'Usually this name will be shown for this node. Equals ID' . ' if not given' ), )); $this->addElement('select', 'operator', array( 'label' => $this->translate('Operator'), 'required' => true, 'multiOptions' => array( '&' => $this->translate('AND'), '|' => $this->translate('OR'), '!' => $this->translate('NOT'), '1' => $this->translate('MIN 1'), '2' => $this->translate('MIN 2'), '3' => $this->translate('MIN 3'), '4' => $this->translate('MIN 4'), '5' => $this->translate('MIN 5'), '6' => $this->translate('MIN 6'), '7' => $this->translate('MIN 7'), '8' => $this->translate('MIN 8'), '9' => $this->translate('MIN 9'), ) )); $this->addElement('select', 'display', array( 'label' => $this->translate('Visualization'), 'required' => true, 'description' => $this->translate( 'Where to show this process' ), 'value' => $this->hasParentNode() ? '0' : '1', 'multiOptions' => array( '1' => $this->translate('Toplevel Process'), '0' => $this->translate('Subprocess only'), ) )); $this->addElement('text', 'infoUrl', array( 'label' => $this->translate('Info URL'), 'description' => $this->translate( 'URL pointing to more information about this node' ) )); } /** * @return string|null */ protected function selectNodeType() { $types = array(); if ($this->hasParentNode()) { $types['host'] = $this->translate('Host'); $types['service'] = $this->translate('Service'); } elseif (! $this->hasProcesses()) { $this->addElement('hidden', 'node_type', array( 'ignore' => true, 'decorators' => array('ViewHelper'), 'value' => 'new-process' )); return 'new-process'; } if ($this->hasProcesses() || ($this->hasParentNode() && $this->hasMoreConfigs())) { $types['process'] = $this->translate('Existing Process'); } $types['new-process'] = $this->translate('New Process Node'); $this->addElement('select', 'node_type', array( 'label' => $this->translate('Node type'), 'required' => true, 'description' => $this->translate( 'The node type you want to add' ), 'ignore' => true, 'class' => 'autosubmit', 'multiOptions' => $this->optionalEnum($types) )); return $this->getSentValue('node_type'); } protected function selectHost() { $this->addElement('multiselect','children', [ 'label' => $this->translate('Hosts'), 'required' => true, 'size' => 8, 'style' => 'width: 25em', 'multiOptions' => $this->enumHostList(), 'description' => $this->translate( 'Hosts that should be part of this business process node' ), 'validators' => [[new NoDuplicateChildrenValidator($this, $this->bp, $this->parent), true]] ]); } protected function selectService() { $this->addHostElement(); if ($host = $this->getSentValue('host')) { $this->addServicesElement($host); } else { $this->setSubmitLabel($this->translate('Next')); } } protected function addHostElement() { $this->addElement('select', 'host', array( 'label' => $this->translate('Host'), 'required' => true, 'ignore' => true, 'class' => 'autosubmit', 'multiOptions' => $this->optionalEnum($this->enumHostForServiceList()), )); } protected function addServicesElement($host) { $this->addElement('multiselect','children', [ 'label' => $this->translate('Services'), 'required' => true, 'size' => 8, 'style' => 'width: 25em', 'multiOptions' => $this->enumServiceList($host), 'description' => $this->translate( 'Services that should be part of this business process node' ), 'validators' => [[new NoDuplicateChildrenValidator($this, $this->bp, $this->parent), true]] ]); } protected function addFileElement() { $this->addElement('select', 'file', [ 'label' => $this->translate('File'), 'required' => true, 'ignore' => true, 'value' => $this->bp->getName(), 'class' => 'autosubmit', 'multiOptions' => $this->optionalEnum($this->enumConfigs()), 'description' => $this->translate( 'Choose a different configuration file to import its processes' ) ]); } protected function selectProcess() { if ($this->hasParentNode()) { $this->addFileElement(); } if (($file = $this->getSentValue('file')) || !$this->hasParentNode()) { $this->addElement('multiselect','children', [ 'label' => $this->translate('Process nodes'), 'required' => true, 'size' => 8, 'style' => 'width: 25em', 'multiOptions' => $this->enumProcesses($file), 'description' => $this->translate( 'Other processes that should be part of this business process node' ), 'validators' => [[new NoDuplicateChildrenValidator($this, $this->bp, $this->parent), true]] ]); } else { $this->setSubmitLabel($this->translate('Next')); } } /** * @param MonitoringBackend $backend * @return $this */ public function setBackend(MonitoringBackend $backend) { $this->backend = $backend; return $this; } /** * @param Storage $storage * @return $this */ public function setStorage(Storage $storage) { $this->storage = $storage; return $this; } /** * @param BpConfig $process * @return $this */ public function setProcess(BpConfig $process) { $this->bp = $process; $this->setBackend($process->getBackend()); return $this; } /** * @param BpNode|null $node * @return $this */ public function setParentNode(BpNode $node = null) { $this->parent = $node; return $this; } /** * @return bool */ public function hasParentNode() { return $this->parent !== null; } /** * @param SessionNamespace $session * @return $this */ public function setSession(SessionNamespace $session) { $this->session = $session; return $this; } protected function enumHostForServiceList() { $names = $this->backend->select()->from('hostStatus', array( 'hostname' => 'host_name', ))->order('host_name')->getQuery()->fetchColumn(); // fetchPairs doesn't seem to work when using the same column with // different aliases twice return array_combine((array) $names, (array) $names); } protected function enumHostList() { $names = $this->backend->select()->from('hostStatus', array( 'hostname' => 'host_name', ))->order('host_name')->getQuery()->fetchColumn(); // fetchPairs doesn't seem to work when using the same column with // different aliases twice $res = array(); $suffix = ';Hoststatus'; foreach ($names as $name) { $res[$name . $suffix] = $name; } return $res; } protected function enumServiceList($host) { $query = $this->backend->select()->from( 'serviceStatus', array('service' => 'service_description') )->where('host_name', $host); $query->order('service_description'); $names = $query->getQuery()->fetchColumn(); $services = array(); foreach ($names as $name) { $services[$host . ';' . $name] = $name; } return $services; } protected function hasProcesses() { return count($this->enumProcesses()) > 0; } /** * @param string $file * @return array */ protected function enumProcesses($file = null) { $list = array(); $parents = array(); $differentFile = $file !== null && $file !== $this->bp->getName(); if (! $differentFile && $this->hasParentNode()) { $this->collectAllParents($this->parent, $parents); $parents[$this->parent->getName()] = $this->parent; } $bp = $this->bp; if ($differentFile) { $bp = $this->storage->loadProcess($file); } foreach ($bp->getNodes() as $node) { if ($node instanceof BpNode && ! isset($parents[$node->getName()])) { $name = $node->getName(); if ($differentFile) { $name = '@' . $file . ':' . $name; } $list[$name] = (string) $node; // display name? } } natcasesort($list); return $list; } protected function hasMoreConfigs() { $configs = $this->enumConfigs(); return !empty($configs); } protected function enumConfigs() { return $this->storage->listProcesses(); } /** * Collect the given node's parents recursively into the given array by their names * * @param BpNode $node * @param BpNode[] $parents */ protected function collectAllParents(BpNode $node, array & $parents) { foreach ($node->getParents() as $parent) { $parents[$parent->getName()] = $parent; $this->collectAllParents($parent, $parents); } } protected function fetchObjectList() { $this->objectList = array(); $hosts = $this->backend->select()->from('hostStatus', array( 'hostname' => 'host_name', 'in_downtime' => 'host_in_downtime', 'ack' => 'host_acknowledged', 'state' => 'host_state' ))->order('host_name')->getQuery()->fetchAll(); $services = $this->backend->select()->from('serviceStatus', array( 'hostname' => 'host_name', 'service' => 'service_description', 'in_downtime' => 'service_in_downtime', 'ack' => 'service_acknowledged', 'state' => 'service_state' ))->order('host_name')->order('service_description')->getQuery()->fetchAll(); foreach ($hosts as $host) { $this->objectList[$host->hostname] = array( $host->hostname . ';Hoststatus' => 'Host Status' ); } foreach ($services as $service) { $this->objectList[$service->hostname][ $service->hostname . ';' . $service->service ] = $service->service; } return $this; } public function onSuccess() { $changes = ProcessChanges::construct($this->bp, $this->session); switch ($this->getValue('node_type')) { case 'host': case 'service': case 'process': if ($this->hasParentNode()) { $changes->addChildrenToNode($this->getValue('children'), $this->parent); } else { foreach ($this->getValue('children') as $nodeName) { $changes->copyNode($nodeName); } } break; case 'new-process': $properties = $this->getValues(); unset($properties['name']); if ($this->hasParentNode()) { $properties['parentName'] = $this->parent->getName(); } $changes->createNode($this->getValue('name'), $properties); break; } // Trigger session destruction to make sure it get's stored. // TODO: figure out why this is necessary, might be an unclean shutdown on redirect unset($changes); parent::onSuccess(); } }