From 936f65eb2703fe0b8d7febc8ff2d149226f52031 Mon Sep 17 00:00:00 2001 From: Johannes Meyer Date: Wed, 23 Jul 2014 16:39:15 +0200 Subject: [PATCH] Adjust resource form to suit the new form builder implementation refs #5525 --- application/forms/Config/ResourceForm.php | 720 ++++++++++------------ 1 file changed, 337 insertions(+), 383 deletions(-) diff --git a/application/forms/Config/ResourceForm.php b/application/forms/Config/ResourceForm.php index 9a48c1f56..d8a3cc850 100644 --- a/application/forms/Config/ResourceForm.php +++ b/application/forms/Config/ResourceForm.php @@ -6,350 +6,46 @@ namespace Icinga\Form\Config; use Exception; use Zend_Config; -use Zend_Form_Element_Checkbox; use Icinga\Web\Form; +use Icinga\Application\Icinga; use Icinga\Data\ResourceFactory; use Icinga\Web\Form\Element\Number; use Icinga\Web\Form\Decorator\HelpText; +use Icinga\Web\Form\Decorator\ElementWrapper; class ResourceForm extends Form { /** - * The resource - * - * @var Zend_Config + * Initialize this form */ - protected $resource; - - /** - * The (new) name of the resource - * - * @var string - */ - protected $name; - - /** - * The old name of the resource - * - * @var string - */ - protected $oldName; - - /** - * Set the current resource name - * - * @param string $name The name to set - */ - public function setName($name) + public function init() { - $this->name = $name; + $this->setName('form_config_resource'); } /** - * Get the current resource name - * - * @return null|string + * @see Form::createElemeents() */ - public function getName() + public function createElements(array $formData) { - $name = $this->getValue('resource_all_name'); - if (!$name) { - return $this->name; - } - - return $name; - } - - /** - * Set the original name of the resource - * - * @param string $name The name to set - */ - public function setOldName($name) - { - $this->oldName = $name; - } - - /** - * Get the resource name that was initially set - * - * @return null|string - */ - public function getOldName() - { - $oldName = $this->getValue('resource_all_name_old'); - if (!$oldName) { - return $this->oldName; - } - - return $oldName; - } - - /** - * Set the resource configuration to edit. - * - * @param Zend_Config $resource The config to set - */ - public function setResource(Zend_Config $resource) - { - $this->resource = $resource; - } - - /** - * Get the current resource configuration. - * - * @return Zend_Config - */ - public function getResource() - { - if (!isset($this->resource)) { - $this->resource = new Zend_Config(array('type' => 'db')); - } - - return $this->resource; - } - - protected function addDbForm() - { - $this->addElement( - 'select', - 'resource_db_db', - array( - 'required' => true, - 'label' => t('Database Type'), - 'helptext' => t('The type of SQL database you want to create.'), - 'value' => $this->getResource()->get('db', 'mysql'), - 'multiOptions' => array( - 'mysql' => 'MySQL', - 'pgsql' => 'PostgreSQL' - //'oracle' => 'Oracle' - ) - ) - ); - - $this->addElement( + $elements = array(); + $elements[] = $this->createElement( 'text', - 'resource_db_host', - array ( - 'required' => true, - 'label' => t('Host'), - 'helptext' => t('The hostname of the database.'), - 'value' => $this->getResource()->get('host', 'localhost') - ) - ); - - $this->addElement( - new Number( - array( - 'name' => 'resource_db_port', - 'required' => true, - 'label' => t('Port'), - 'helptext' => t('The port to use.'), - 'value' => $this->getResource()->get('port', 3306) - ) - ) - ); - - $this->addElement( - 'text', - 'resource_db_dbname', - array( - 'required' => true, - 'label' => t('Database Name'), - 'helptext' => t('The name of the database to use'), - 'value' => $this->getResource()->get('dbname', '') - ) - ); - - $this->addElement( - 'text', - 'resource_db_username', - array ( - 'required' => true, - 'label' => t('Username'), - 'helptext' => t('The user name to use for authentication.'), - 'value' => $this->getResource()->get('username', '') - ) - ); - - $this->addElement( - 'password', - 'resource_db_password', - array( - 'required' => true, - 'renderPassword' => true, - 'label' => t('Password'), - 'helptext' => t('The password to use for authentication'), - 'value' => $this->getResource()->get('password', '') - ) - ); - } - - protected function addStatusdatForm() - { - $this->addElement( - 'text', - 'resource_statusdat_status_file', - array( - 'required' => true, - 'label' => t('Filepath'), - 'helptext' => t('Location of your icinga status.dat file'), - 'value' => $this->getResource()->get('status_file', '/usr/local/icinga/var/status.dat') - ) - ); - - $this->addElement( - 'text', - 'resource_statusdat_object_file', - array( - 'required' => true, - 'label' => t('Filepath'), - 'helptext' => t('Location of your icinga objects.cache file'), - 'value' => $this->getResource()->get('status_file', '/usr/local/icinga/var/objects.cache') - ) - ); - } - - protected function addLivestatusForm() - { - $this->addElement( - 'text', - 'resource_livestatus_socket', - array( - 'required' => true, - 'label' => t('Socket'), - 'helptext' => t('The path to your livestatus socket used for querying monitoring data'), - 'value' => $this->getResource()->get('socket', '/usr/local/icinga/var/rw/livestatus') - ) - ); - } - - protected function addLdapForm() - { - $this->addElement( - 'text', - 'resource_ldap_hostname', - array( - 'required' => true, - 'allowEmpty' => false, - 'label' => t('Host'), - 'helptext' => t('The hostname or address of the LDAP server to use for authentication'), - 'value' => $this->getResource()->get('hostname', 'localhost') - ) - ); - - $this->addElement( - 'text', - 'resource_ldap_root_dn', - array( - 'required' => true, - 'label' => t('Root DN'), - 'helptext' => t('The path where users can be found on the ldap server'), - 'value' => $this->getResource()->get('root_dn', 'ou=people,dc=icinga,dc=org') - ) - ); - - $this->addElement( - 'text', - 'resource_ldap_bind_dn', - array( - 'required' => true, - 'label' => t('Bind DN'), - 'helptext' => t('The user dn to use for querying the ldap server'), - 'value' => $this->getResource()->get('bind_dn', 'cn=admin,cn=config') - ) - ); - - $this->addElement( - 'password', - 'resource_ldap_bind_pw', - array( - 'required' => true, - 'renderPassword' => true, - 'label' => t('Bind Password'), - 'helptext' => t('The password to use for querying the ldap server'), - 'value' => $this->getResource()->get('bind_pw', '') - ) - ); - } - - protected function addFileForm() - { - $this->addElement( - 'text', - 'resource_file_filename', - array( - 'required' => true, - 'label' => t('Filepath'), - 'helptext' => t('The filename to fetch information from'), - 'value' => $this->getResource()->get('filename', '') - ) - ); - - $this->addElement( - 'text', - 'resource_file_fields', - array( - 'required' => true, - 'label' => t('Pattern'), - 'helptext' => t('The regular expression by which to identify columns'), - 'value' => $this->getResource()->get('fields', '') - ) - ); - } - - protected function addNameFields() - { - $this->addElement( - 'text', - 'resource_all_name', + 'name', array( 'required' => true, 'label' => t('Resource Name'), - 'helptext' => t('The unique name of this resource'), - 'value' => $this->getName() + 'helptext' => t('The unique name of this resource') ) ); - - $this->addElement( - 'hidden', - 'resource_all_name_old', - array( - 'value' => $this->getOldName() - ) - ); - } - - /** - * Add checkbox at the beginning of the form which allows to skip connection validation - */ - protected function addForceCreationCheckbox() - { - $checkbox = new Zend_Form_Element_Checkbox( - array( - 'order' => 0, - 'name' => 'resource_force_creation', - 'label' => t('Force Changes'), - 'helptext' => t('Check this box to enforce changes without connectivity validation') - ) - ); - $checkbox->addDecorator(new HelpText()); - $this->addElement($checkbox); - } - - /** - * Add a select box for choosing the type to use for this backend - */ - protected function addTypeSelectionBox() - { - $this->addElement( + $elements[] = $this->createElement( 'select', - 'resource_type', + 'type', array( 'required' => true, + 'class' => 'autosubmit', 'label' => t('Resource Type'), 'helptext' => t('The type of resource'), - 'value' => $this->getResource()->type, 'multiOptions' => array( 'db' => t('SQL Database'), 'ldap' => 'LDAP', @@ -359,60 +55,92 @@ class ResourceForm extends Form ) ) ); - $this->enableAutoSubmit(array('resource_type')); + + if (isset($formData['force_creation']) && $formData['force_creation']) { + // In case the resource name already exists and the checkbox was displayed before + $elements[] = $this->getForceCreationCheckbox(); + } + + if (false === isset($formData['type']) || $formData['type'] === 'db') { + return array_merge($elements, $this->getDbElements()); + } elseif ($formData['type'] === 'statusdat') { + return array_merge($elements, $this->getStatusdatElements()); + } elseif ($formData['type'] === 'livestatus') { + return array_merge($elements, $this->getLivestatusElements()); + } elseif ($formData['type'] === 'ldap') { + return array_merge($elements, $this->getLdapElements()); + } elseif ($formData['type'] === 'file') { + return array_merge($elements, $this->getFileElements()); + } } /** - * Validate this form with the Zend validation mechanism and perform a validation of the connection + * @see Form::addSubmitButton() + */ + public function addSubmitButton() + { + $this->addElement( + 'submit', + 'btn_submit', + array( + 'label' => t('Save Changes') + ) + ); + + return $this; + } + + /** + * Return whether the given values are complete/valid and check whether it is possible to connect to the resource * - * If validation fails, the 'resource_force_creation' checkbox is prepended to the form to allow users to - * skip the connection validation + * If connection validation fails, a checkbox is prepended to the form to allow users to skip it. * - * @param array $data The form input to validate + * @param array $data The data to validate * - * @return bool True when validation succeeded, false if not + * @return bool Whether the validation succeeded or not */ public function isValid($data) { - if (!parent::isValid($data)) { + if (false === parent::isValid($data)) { return false; } - if (isset($data['resource_force_creation']) && $data['resource_force_creation']) { - return true; - } - if (!$this->isValidResource()) { - $this->addForceCreationCheckbox(); + + if ( + (false === isset($data['force_creation']) || false == $data['force_creation']) + && false === $this->isValidResource() + ) { + $this->addElement($this->getForceCreationCheckbox()); return false; } + return true; } /** - * Test if the changed resource is a valid resource, by instantiating it and - * checking if a connection is possible + * Return whether a connection can be established with the current resource configuration values * - * @return bool True when a connection to the resource is possible + * @return bool Whether the connection validation was successful or not */ public function isValidResource() { - $config = $this->getConfig(); + list($name, $config) = $this->getResourceConfig(); try { - switch ($config->type) { + switch ($config['type']) { case 'db': /* * It should be possible to run icingaweb without the pgsql or mysql extension or Zend-Pdo-Classes, * in case they aren't actually used. When the user tries to create a resource that depends on an * uninstalled extension, an error should be displayed. */ - if ($config->db === 'mysql' && !ResourceFactory::mysqlAvailable()) { + if ($config['db'] === 'mysql' && false === ResourceFactory::mysqlAvailable()) { $this->addErrorMessage( t('You need to install the php extension "mysql" and the ' . 'Zend_Pdo_Mysql classes to use MySQL database resources.') ); return false; } - if ($config->db === 'pgsql' && !ResourceFactory::pgsqlAvailable()) { + if ($config['db'] === 'pgsql' && false === ResourceFactory::pgsqlAvailable()) { $this->addErrorMessage( t('You need to install the php extension "pgsql" and the ' . 'Zend_Pdo_Pgsql classes to use PostgreSQL database resources.') @@ -420,30 +148,31 @@ class ResourceForm extends Form return false; } - $resource = ResourceFactory::createResource($config); + $resource = ResourceFactory::createResource(new Zend_Config($config)); $resource->getConnection()->getConnection(); break; case 'statusdat': - if (!file_exists($config->object_file) || !file_exists($config->status_file)) { + if ( + false === file_exists($config['object_file']) + || false === file_exists($config['status_file']) + ) { $this->addErrorMessage( - t('Connectivity validation failed, the provided file does not exist.') + t('Connectivity validation failed. At least one of the provided files does not exist.') ); return false; } break; case 'livestatus': - $resource = ResourceFactory::createResource($config); + $resource = ResourceFactory::createResource(new Zend_Config($config)); $resource->connect()->disconnect(); break; case 'ldap': - $resource = ResourceFactory::createResource($config); + $resource = ResourceFactory::createResource(new Zend_Config($config)); $resource->connect(); break; case 'file': - if (!file_exists($config->filename)) { - $this->addErrorMessage( - t('Connectivity validation failed, the provided file does not exist.') - ); + if (false === file_exists($config['filename'])) { + $this->addErrorMessage(t('Connectivity validation failed. The provided file does not exist.')); return false; } break; @@ -456,51 +185,276 @@ class ResourceForm extends Form return true; } - public function create() + /** + * Return the resource configuration values and its name + * + * The first value is the name and the second one the values as array. + * + * @return array + */ + public function getResourceConfig() { - $this->addNameFields(); - $this->addTypeSelectionBox(); - - switch ($this->getRequest()->getParam('resource_type', $this->getResource()->type)) { - case 'db': - $this->addDbForm(); - break; - case 'statusdat': - $this->addStatusdatForm(); - break; - case 'livestatus': - $this->addLivestatusForm(); - break; - case 'ldap': - $this->addLdapForm(); - break; - case 'file': - $this->addFileForm(); - break; - } - - $this->setSubmitLabel('{{SAVE_ICON}} Save Changes'); + $values = $this->getValues(); + $name = $values['name']; + unset($values['name']); + unset($values['btn_submit']); + unset($values['force_creation']); + unset($values[$this->getTokenElementName()]); + return array($name, $values); } /** - * Return a configuration containing the backend settings entered in this form + * Populate the form with the given configuration values * - * @return Zend_Config The updated configuration for this backend + * @param string $name The name of the resource + * @param array $config The configuration values */ - public function getConfig() + public function setResourceConfig($name, array $config) { - $values = $this->getValues(); + $config['name'] = $name; + $this->populate($config); + } - $result = array('type' => $values['resource_type']); - foreach ($values as $key => $value) { - if ($key !== 'resource_type' && $key !== 'resource_all_name' && $key !== 'resource_all_name_old') { - $configKey = explode('_', $key, 3); - if (count($configKey) === 3) { - $result[$configKey[2]] = $value; - } - } - } + /** + * Return a checkbox to be displayed at the beginning of the form + * which allows the user to skip the connection validation + * + * @return Zend_Form_Element + */ + protected function getForceCreationCheckbox() + { + return $this->createElement( + 'checkbox', + 'force_creation', + array( + 'order' => 0, + 'label' => t('Force Changes'), + 'helptext' => t('Check this box to enforce changes without connectivity validation') + ) + ); + } - return new Zend_Config($result); + /** + * Return all required elements to define a resource of type "db" + * + * @return array + */ + protected function getDbElements() + { + return array( + $this->createElement( + 'select', + 'db', + array( + 'required' => true, + 'label' => t('Database Type'), + 'helptext' => t('The type of SQL database'), + 'multiOptions' => array( + 'mysql' => 'MySQL', + 'pgsql' => 'PostgreSQL' + //'oracle' => 'Oracle' + ) + ) + ), + $this->createElement( + 'text', + 'host', + array ( + 'required' => true, + 'label' => t('Host'), + 'helptext' => t('The hostname of the database'), + 'value' => 'localhost' + ) + ), + new Number( + array( + 'required' => true, + 'name' => 'port', + 'label' => t('Port'), + 'helptext' => t('The port to use'), + 'value' => 3306, + 'decorators' => array( // The order is important! + 'ViewHelper', + 'Errors', + new ElementWrapper(), + new HelpText() + ) + ) + ), + $this->createElement( + 'text', + 'dbname', + array( + 'required' => true, + 'label' => t('Database Name'), + 'helptext' => t('The name of the database to use') + ) + ), + $this->createElement( + 'text', + 'username', + array ( + 'required' => true, + 'label' => t('Username'), + 'helptext' => t('The user name to use for authentication') + ) + ), + $this->createElement( + 'password', + 'password', + array( + 'required' => true, + 'renderPassword' => true, + 'label' => t('Password'), + 'helptext' => t('The password to use for authentication') + ) + ) + ); + } + + /** + * Return all required elements to define a resource of type "statusdat" + * + * @return array + */ + protected function getStatusdatElements() + { + return array( + $this->createElement( + 'text', + 'status_file', + array( + 'required' => true, + 'label' => t('Filepath'), + 'helptext' => t('Location of your icinga status.dat file'), + 'value' => realpath(Icinga::app()->getApplicationDir() . '/../var/status.dat') + ) + ), + $this->createElement( + 'text', + 'object_file', + array( + 'required' => true, + 'label' => t('Filepath'), + 'helptext' => t('Location of your icinga objects.cache file'), + 'value' => realpath(Icinga::app()->getApplicationDir() . '/../var/objects.cache') + ) + ) + ); + } + + /** + * Return all required elements to define a resource of type "livestatus" + * + * @return array + */ + protected function getLivestatusElements() + { + return array( + $this->createElement( + 'text', + 'socket', + array( + 'required' => true, + 'label' => t('Socket'), + 'helptext' => t('The path to your livestatus socket used for querying monitoring data'), + 'value' => realpath(Icinga::app()->getApplicationDir() . '/../var/rw/livestatus') + ) + ) + ); + } + + /** + * Return all required elements to define a resource of type "ldap" + * + * @return array + */ + protected function getLdapElements() + { + return array( + $this->createElement( + 'text', + 'hostname', + array( + 'required' => true, + 'allowEmpty' => false, + 'label' => t('Host'), + 'helptext' => t('The hostname or address of the LDAP server to use for authentication'), + 'value' => 'localhost' + ) + ), + new Number( + array( + 'required' => true, + 'name' => 'port', + 'label' => t('Port'), + 'helptext' => t('The port of the LDAP server to use for authentication'), + 'value' => 389, + 'decorators' => array( // The order is important! + 'ViewHelper', + 'Errors', + new ElementWrapper(), + new HelpText() + ) + ) + ), + $this->createElement( + 'text', + 'root_dn', + array( + 'required' => true, + 'label' => t('Root DN'), + 'helptext' => t('The path where users can be found on the ldap server') + ) + ), + $this->createElement( + 'text', + 'bind_dn', + array( + 'required' => true, + 'label' => t('Bind DN'), + 'helptext' => t('The user dn to use for querying the ldap server') + ) + ), + $this->createElement( + 'password', + 'bind_pw', + array( + 'required' => true, + 'renderPassword' => true, + 'label' => t('Bind Password'), + 'helptext' => t('The password to use for querying the ldap server') + ) + ) + ); + } + + /** + * Return all required elements to define a resource of type "file" + * + * @return array + */ + protected function getFileElements() + { + return array( + $this->createElement( + 'text', + 'filename', + array( + 'required' => true, + 'label' => t('Filepath'), + 'helptext' => t('The filename to fetch information from') + ) + ), + $this->createElement( + 'text', + 'fields', + array( + 'required' => true, + 'label' => t('Pattern'), + 'helptext' => t('The regular expression by which to identify columns') + ) + ) + ); } }