From 1d07a766d98f20d45b6a623b66fabd2296929981 Mon Sep 17 00:00:00 2001 From: Matthias Jentsch Date: Wed, 16 Oct 2013 18:50:19 +0200 Subject: [PATCH] Add form classes to handle the configuration Add a tri-state form element to handle the configuration flags and add the form to the controllers refs #3788 --- .../views/helpers/FormTriStateCheckbox.php | 58 ++++++ .../Web/Form/Element/TriStateCheckbox.php | 57 ++++++ .../Web/Form/Validator/TriStateValidator.php | 79 ++++++++ .../controllers/MultiController.php | 38 +++- .../forms/Command/MultiCommandFlagForm.php | 171 ++++++++++++++++++ .../forms/Command/MultiFlagForm.php | 15 -- .../multi/components/configuration.phtml | 10 +- .../views/scripts/multi/service.phtml | 7 +- 8 files changed, 405 insertions(+), 30 deletions(-) create mode 100644 application/views/helpers/FormTriStateCheckbox.php create mode 100644 library/Icinga/Web/Form/Element/TriStateCheckbox.php create mode 100644 library/Icinga/Web/Form/Validator/TriStateValidator.php create mode 100644 modules/monitoring/application/forms/Command/MultiCommandFlagForm.php delete mode 100644 modules/monitoring/application/forms/Command/MultiFlagForm.php diff --git a/application/views/helpers/FormTriStateCheckbox.php b/application/views/helpers/FormTriStateCheckbox.php new file mode 100644 index 000000000..05262c9e0 --- /dev/null +++ b/application/views/helpers/FormTriStateCheckbox.php @@ -0,0 +1,58 @@ + + * @author Icinga Development Team + */ +// {{{ICINGA_LICENSE_HEADER}}} + +use \Zend_View_Helper_FormElement; + +/** + * Helper to generate a "datetime" element + */ +class Zend_View_Helper_FormTriStateCheckbox extends Zend_View_Helper_FormElement +{ + /** + * Generate a tri-state checkbox + * + * @param string $name The element name + * @param int $value The checkbox value + * @param array $attribs Attributes for the element tag + * + * @return string The element XHTML + */ + public function formTriStateCheckbox($name, $value = null, $attribs = null) + { + $class = ""; + $xhtml = '
' + . '
' . ($value == 1 ? '{{ICON_ENABLED}}' : ($value == 0 ? '{{ICON_DISABLED}}' : '{{ICON_BLANK}}' )) . '
' + . 'On ' + . 'Off ' + . ' Mixed ' + . '
'; + return $xhtml; + } +} diff --git a/library/Icinga/Web/Form/Element/TriStateCheckbox.php b/library/Icinga/Web/Form/Element/TriStateCheckbox.php new file mode 100644 index 000000000..848360f87 --- /dev/null +++ b/library/Icinga/Web/Form/Element/TriStateCheckbox.php @@ -0,0 +1,57 @@ + + * @license http://www.gnu.org/licenses/gpl-2.0.txt GPL, version 2 + * @author Icinga Development Team + */ +// {{{ICINGA_LICENSE_HEADER}}} + +namespace Icinga\Web\Form\Element; + +use \Icinga\Web\Form\Validator\TriStateValidator; +use \Zend_Form_Element_Xhtml; + +/** + * A checkbox that can display three different states: + * true, false and mixed. When there is no JavaScript + * available to display the checkbox properly, a radio + * button-group with all three possible states will be + * displayed. + */ +class TriStateCheckbox extends Zend_Form_Element_Xhtml +{ + /** + * Name of the view helper + * + * @var string + */ + public $helper = 'formTriStateCheckbox'; + + public function __construct($spec, $options = null) + { + parent::__construct($spec, $options); + + $this->triStateValidator = new TriStateValidator($this->patterns); + $this->addValidator($this->triStateValidator); + } +} diff --git a/library/Icinga/Web/Form/Validator/TriStateValidator.php b/library/Icinga/Web/Form/Validator/TriStateValidator.php new file mode 100644 index 000000000..f8237d3b4 --- /dev/null +++ b/library/Icinga/Web/Form/Validator/TriStateValidator.php @@ -0,0 +1,79 @@ + + * @license http://www.gnu.org/licenses/gpl-2.0.txt GPL, version 2 + * @author Icinga Development Team + */ +// {{{ICINGA_LICENSE_HEADER}}} + +namespace Icinga\Web\Form\Validator; + +use \Zend_Validate_Abstract; + +class TriStateValidator extends Zend_Validate_Abstract { + + /** + * @var null + */ + private $validPattern = null; + + /** + * Validate the input value and set the value of @see validPattern if the input machtes + * a state description like '0', '1' or 'unchanged' + * + * @param string $value The value to validate + * @param null $context The form context (ignored) + * + * @return bool True when the input is valid, otherwise false + * + * @see Zend_Validate_Abstract::isValid() + */ + public function isValid($value, $context = null) + { + if (!is_string($value) && !is_int($value)) { + $this->error('INVALID_TYPE'); + return false; + } + + if (is_string($value)) { + $value = intval($value); + if ($value === 'unchanged') { + $this->validPattern = null; + return true; + } + } + + if (is_int($value)) { + if ($value === 1 || $value === 0) { + $this->validPattern = $value; + return true; + } + } + return false; + } + + public function getValidPattern() + { + return $this->validPattern; + } +} \ No newline at end of file diff --git a/modules/monitoring/application/controllers/MultiController.php b/modules/monitoring/application/controllers/MultiController.php index 723a7f576..5c77e8735 100644 --- a/modules/monitoring/application/controllers/MultiController.php +++ b/modules/monitoring/application/controllers/MultiController.php @@ -1,5 +1,4 @@ backend, $query['host']); foreach ($host->comments as $comment) { $comments[$comment->comment_id] = null; @@ -73,6 +74,9 @@ class Monitoring_MultiController extends ActionController $this->view->hostnames = $hostnames; $this->view->downtimes = $downtimes; $this->view->errors = $errors; + + $this->handleConfigurationForm(); + $this->view->form->setAction('/icinga2-web/monitoring/multi/host'); } public function serviceAction() @@ -107,6 +111,9 @@ class Monitoring_MultiController extends ActionController $this->view->comments = array_keys($comments); $this->view->downtimes = $downtimes; $this->view->errors = $errors; + + $this->handleConfigurationForm(); + $this->view->form->setAction('/icinga2-web/monitoring/multi/service'); } public function notificationAction() @@ -119,6 +126,31 @@ class Monitoring_MultiController extends ActionController } + /** + * Handle the form to configure configuration flags. + */ + private function handleConfigurationForm() + { + $this->view->form = $form = new MultiCommandFlagForm( + array( + 'passive_checks_enabled' => 'Passive Checks', + 'active_checks_enabled' => 'Active Checks', + 'obsessing' => 'Obsessing', + 'notifications_enabled' => 'Notifications', + 'event_handler_enabled' => 'Event Handler', + 'flap_detection_enabled' => 'Flap Detection' + ) + ); + $form->setRequest($this->_request); + if ($form->isSubmittedAndValid()) { + // TODO: Handle commands + $changed = $form->getChangedValues(); + } + if ($this->_request->isPost() === false) { + $this->view->form->initFromItems($this->view->objects); + } + } + /** * Fetch all requests from the 'detail' parameter. * @@ -142,6 +174,4 @@ class Monitoring_MultiController extends ActionController } return $objects; } - - } diff --git a/modules/monitoring/application/forms/Command/MultiCommandFlagForm.php b/modules/monitoring/application/forms/Command/MultiCommandFlagForm.php new file mode 100644 index 000000000..040eba4bc --- /dev/null +++ b/modules/monitoring/application/forms/Command/MultiCommandFlagForm.php @@ -0,0 +1,171 @@ + + * @license http://www.gnu.org/licenses/gpl-2.0.txt GPL, version 2 + * @author Icinga Development Team + */ +// {{{ICINGA_LICENSE_HEADER}}} + +namespace Icinga\Module\Monitoring\Form\Command; + +use \Icinga\Web\Form\Element\TriStateCheckbox; +use \Icinga\Web\Form; +use \Zend_Form_Element_Hidden; + +/** + * A form to edit multiple command flags of multiple commands at once. When some commands have + * different flag values, these flags will be displayed as an undefined state, + * in a tri-state checkbox. + */ +class MultiCommandFlagForm extends Form { + + /** + * The Suffix used to mark the old values in the form-field + * + * @var string + */ + const OLD_VALUE_MARKER = '_&&old'; + + /** + * The object properties to change + * + * @var array + */ + private $flags; + + /** + * The current values of this form + * + * @var array + */ + private $values; + + /** + * Create a new MultiCommandFlagForm + * + * @param array $flags The flags that will be used. Should contain the + * names of the used property keys. + */ + public function __construct(array $flags) + { + $this->flags = $flags; + parent::__construct(); + } + + /** + * Initialise the form values with the array of items to configure. + * + * @param array $items The items that will be edited with this form. + */ + public function initFromItems(array $items) + { + $this->values = $this->valuesFromObjects($items); + $this->buildForm(); + $this->populate($this->values); + } + + /** + * Return only the values that have been updated. + */ + public function getChangedValues() + { + $values = $this->getValues(); + $changed = array(); + foreach ($values as $key => $value) { + $oldKey = $key . self::OLD_VALUE_MARKER; + if (array_key_exists($oldKey, $values)) { + if ($values[$oldKey] !== $value) { + $changed[$key] = $value; + } + } + } + return $changed; + } + + /** + * Extract the values from a set of items. + * + * @param array $items The items + */ + private function valuesFromObjects(array $items) + { + $values = array(); + foreach ($items as $item) { + foreach ($this->flags as $key => $unused) { + + if (isset($item->{$key})) { + $value = $item->{$key}; + + // convert strings + if ($value === '1' || $value === '0') { + $value = intval($value); + } + + // init key with first value + if (!array_key_exists($key, $values)) { + $values[$key] = $value; + continue; + } + + // already a mixed state ? + if ($values[$key] === 'unchanged') { + continue; + } + + // values differ? + if ($values[$key] ^ $value) { + $values[$key] = 'unchanged'; + } + } + } + } + $old = array(); + foreach ($values as $key => $value) { + $old[$key . self::OLD_VALUE_MARKER] = $key; + } + return array_merge($values, $old); + } + + /** + * Create the multi flag form + * + * @see Form::create() + */ + public function create() + { + $this->setName('form_flag_configuration'); + foreach ($this->flags as $flag => $description) { + $this->addElement(new TriStateCheckbox( + $flag, + array( + 'label' => $description, + 'required' => true + ) + )); + + $old = new Zend_Form_Element_Hidden($flag . self::OLD_VALUE_MARKER); + $this->addElement($old); + } + $this->setSubmitLabel('Save Configuration'); + } +} diff --git a/modules/monitoring/application/forms/Command/MultiFlagForm.php b/modules/monitoring/application/forms/Command/MultiFlagForm.php deleted file mode 100644 index ccfe1c59c..000000000 --- a/modules/monitoring/application/forms/Command/MultiFlagForm.php +++ /dev/null @@ -1,15 +0,0 @@ - Configuration -
- Change settings: - -
- Active Checks {{CHECKBOX}} - Passive Checks {{CHECKBOX}} - Flap Detection {{CHECKBOX}} -
+ Change configuration for objects) ?> objects. + form->render($this); ?>
diff --git a/modules/monitoring/application/views/scripts/multi/service.phtml b/modules/monitoring/application/views/scripts/multi/service.phtml index 311786ecd..e8eb85d34 100644 --- a/modules/monitoring/application/views/scripts/multi/service.phtml +++ b/modules/monitoring/application/views/scripts/multi/service.phtml @@ -2,15 +2,16 @@ $this->is_service = true; ?> -
+
+
- {{SERVICE_ICON}} -

Services

+

Services

render('multi/components/summary.phtml'); ?>
+
render('multi/components/downtimes.phtml'); ?>