diff --git a/application/controllers/ConfigController.php b/application/controllers/ConfigController.php index 9bf54b2cf..39051011c 100644 --- a/application/controllers/ConfigController.php +++ b/application/controllers/ConfigController.php @@ -2,8 +2,7 @@ // {{{ICINGA_LICENSE_HEADER}}} // {{{ICINGA_LICENSE_HEADER}}} -use Icinga\Web\Controller\BaseConfigController; -use Icinga\Web\Widget\AlertMessageBox; +use Icinga\Web\Controller\ActionController; use Icinga\Web\Notification; use Icinga\Application\Modules\Module; use Icinga\Web\Widget; @@ -12,16 +11,15 @@ use Icinga\Application\Config as IcingaConfig; use Icinga\Form\Config\GeneralConfigForm; use Icinga\Form\Config\AuthenticationBackendReorderForm; use Icinga\Form\Config\AuthenticationBackendConfigForm; -use Icinga\Form\Config\ResourceForm; +use Icinga\Form\Config\ResourceConfigForm; use Icinga\Form\ConfirmRemovalForm; -use Icinga\Config\PreservingIniWriter; use Icinga\Data\ResourceFactory; /** * Application wide controller for application preferences */ -class ConfigController extends BaseConfigController +class ConfigController extends ActionController { public function init() { @@ -210,14 +208,12 @@ class ConfigController extends BaseConfigController } /** - * Display all available resources and a link to create a new one + * Display all available resources and a link to create a new one and to remove existing ones */ public function resourceAction() { - $this->view->messageBox = new AlertMessageBox(true); - $this->view->tabs->activate('resources'); - $this->view->resources = IcingaConfig::app('resources', true)->toArray(); + $this->view->tabs->activate('resources'); } /** @@ -225,26 +221,12 @@ class ConfigController extends BaseConfigController */ public function createresourceAction() { - $this->view->messageBox = new AlertMessageBox(true); - - $form = new ResourceForm(); - $request = $this->getRequest(); - if ($request->isPost() && $form->isValid($request->getPost())) { - list($name, $config) = $form->getResourceConfig(); - $resources = IcingaConfig::app('resources')->toArray(); - if (array_key_exists($name, $resources)) { - $this->addErrorMessage(sprintf($this->translate('Resource name "%s" already in use.'), $name)); - } else { - $resources[$name] = $config; - if ($this->writeConfigFile($resources, 'resources')) { - $this->addSuccessMessage(sprintf($this->translate('Resource "%s" successfully created.'), $name)); - $this->redirectNow('config/resource'); - } - } - } + $form = new ResourceConfigForm(); + $form->setConfig(IcingaConfig::app('resources')); + $form->setRedirectUrl('config/resource'); + $form->handleRequest(); $this->view->form = $form; - $this->view->messageBox->addForm($form); $this->render('resource/create'); } @@ -253,39 +235,12 @@ class ConfigController extends BaseConfigController */ public function editresourceAction() { - $this->view->messageBox = new AlertMessageBox(true); - - // Fetch the resource to be edited - $resources = IcingaConfig::app('resources')->toArray(); - $name = $this->getParam('resource'); - if (false === array_key_exists($name, $resources)) { - $this->addErrorMessage(sprintf($this->translate('Cannot edit "%s". Resource not found.'), $name)); - $this->redirectNow('config/configurationerror'); - } - - $form = new ResourceForm(); - $request = $this->getRequest(); - if ($request->isPost()) { - if ($form->isValid($request->getPost())) { - list($newName, $config) = $form->getResourceConfig(); - - if ($newName !== $name) { - // Resource name has changed - unset($resources[$name]); // We can safely use unset as all values are part of the form - } - - $resources[$newName] = $config; - if ($this->writeConfigFile($resources, 'resources')) { - $this->addSuccessMessage(sprintf($this->translate('Resource "%s" successfully edited.'), $name)); - $this->redirectNow('config/resource'); - } - } - } else { - $form->setResourceConfig($name, $resources[$name]); - } + $form = new ResourceConfigForm(); + $form->setConfig(IcingaConfig::app('resources')); + $form->setRedirectUrl('config/resource'); + $form->handleRequest(); $this->view->form = $form; - $this->view->messageBox->addForm($form); $this->render('resource/modify'); } @@ -294,104 +249,46 @@ class ConfigController extends BaseConfigController */ public function removeresourceAction() { - $this->view->messageBox = new AlertMessageBox(true); + $form = new ConfirmRemovalForm(array( + 'onSuccess' => function ($request) { + $configForm = new ResourceConfigForm(); + $configForm->setConfig(IcingaConfig::app('resources')); + $resource = $request->getQuery('resource'); - // Fetch the resource to be removed - $resources = IcingaConfig::app('resources')->toArray(); - $name = $this->getParam('resource'); - if (false === array_key_exists($name, $resources)) { - $this->addErrorMessage(sprintf($this->translate('Cannot remove "%s". Resource not found.'), $name)); - $this->redirectNow('config/configurationerror'); - } + try { + $configForm->remove($resource); + } catch (InvalidArgumentException $e) { + Notification::error($e->getMessage()); + return; + } + + if ($configForm->save()) { + Notification::success(sprintf(t('Resource "%s" has been successfully removed'), $resource)); + } else { + return false; + } + } + )); + $form->setRedirectUrl('config/resource'); + $form->handleRequest(); // Check if selected resource is currently used for authentication + $resource = $this->getRequest()->getQuery('resource'); $authConfig = IcingaConfig::app('authentication')->toArray(); foreach ($authConfig as $backendName => $config) { - if (array_key_exists('resource', $config) && $config['resource'] === $name) { - $this->addWarningMessage( - sprintf( - $this->translate( - 'The resource "%s" is currently in use by the authentication backend "%s". ' . - 'Removing the resource can result in noone being able to log in any longer.' - ), - $name, - $backendName - ) - ); - } - } - - $form = new ConfirmRemovalForm(); - $request = $this->getRequest(); - if ($request->isPost() && $form->isValid($request->getPost())) { - unset($resources[$name]); - if ($this->writeConfigFile($resources, 'resources')) { - $this->addSuccessMessage(sprintf($this->translate('Resource "%s" successfully removed.'), $name)); - $this->redirectNow('config/resource'); + if (array_key_exists('resource', $config) && $config['resource'] === $resource) { + $form->addError(sprintf( + $this->translate( + 'The resource "%s" is currently in use by the authentication backend "%s". ' . + 'Removing the resource can result in noone being able to log in any longer.' + ), + $resource, + $backendName + )); } } $this->view->form = $form; - $this->view->messageBox->addForm($form); $this->render('resource/remove'); } - - /** - * Redirect target only for error-states - * - * When an error is opened in the side-pane, redirecting this request to the index or the overview will look - * weird. This action returns a clear page containing only an AlertMessageBox. - */ - public function configurationerrorAction() - { - $this->view->messageBox = new AlertMessageBox(true); - $this->render('error/error', null, true); - } - - /** - * Write changes to an authentication file - * - * @param array $config The configuration changes - * - * @return bool True when persisting succeeded, otherwise false - * - * @see writeConfigFile() - */ - private function writeAuthenticationFile($config) { - return $this->writeConfigFile($config, 'authentication'); - } - - /** - * Write changes to a configuration file $file, using the supplied writer or PreservingIniWriter if none is set - * - * @param array|Zend_Config $config The configuration to write - * @param string $file The filename to write to (without .ini) - * @param Zend_Config_Writer $writer An optional writer to use for persisting changes - * - * @return bool True when persisting succeeded, otherwise false - */ - private function writeConfigFile($config, $file, $writer = null) - { - if (is_array($config)) { - $config = new Zend_Config($config); - } - if ($writer === null) { - $writer = new PreservingIniWriter( - array( - 'config' => $config, - 'filename' => IcingaConfig::app($file)->getConfigFile() - ) - ); - } - try { - $writer->write(); - return true; - } catch (Exception $exc) { - $this->view->exceptionMessage = $exc->getMessage(); - $this->view->iniConfigurationString = $writer->render(); - $this->view->file = $file; - $this->render('show-configuration'); - return false; - } - } } diff --git a/application/forms/Config/Authentication/AutologinBackendForm.php b/application/forms/Config/Authentication/AutologinBackendForm.php index 662106bcd..cb4d100a0 100644 --- a/application/forms/Config/Authentication/AutologinBackendForm.php +++ b/application/forms/Config/Authentication/AutologinBackendForm.php @@ -32,7 +32,7 @@ class AutologinBackendForm extends Form array( 'required' => true, 'label' => t('Backend Name'), - 'helptext' => t('The name of this authentication backend'), + 'description' => t('The name of this authentication backend'), 'validators' => array( array( 'Regex', @@ -53,7 +53,7 @@ class AutologinBackendForm extends Form array( 'required' => true, 'label' => t('Backend Domain Pattern'), - 'helptext' => t('The domain pattern of this authentication backend'), + 'description' => t('The domain pattern of this authentication backend'), 'value' => '/\@[^$]+$/', 'validators' => array( new Zend_Validate_Callback(function ($value) { diff --git a/application/forms/Config/Authentication/DbBackendForm.php b/application/forms/Config/Authentication/DbBackendForm.php index 338b01c60..603aaeb79 100644 --- a/application/forms/Config/Authentication/DbBackendForm.php +++ b/application/forms/Config/Authentication/DbBackendForm.php @@ -55,7 +55,7 @@ class DbBackendForm extends Form array( 'required' => true, 'label' => t('Backend Name'), - 'helptext' => t('The name of this authentication provider'), + 'description' => t('The name of this authentication provider'), ) ), $this->createElement( @@ -64,7 +64,7 @@ class DbBackendForm extends Form array( 'required' => true, 'label' => t('Database Connection'), - 'helptext' => t('The database connection to use for authenticating with this provider'), + 'description' => t('The database connection to use for authenticating with this provider'), 'multiOptions' => false === empty($this->resources) ? array_combine($this->resources, $this->resources) : array() diff --git a/application/forms/Config/Authentication/LdapBackendForm.php b/application/forms/Config/Authentication/LdapBackendForm.php index f451417ea..79949e2de 100644 --- a/application/forms/Config/Authentication/LdapBackendForm.php +++ b/application/forms/Config/Authentication/LdapBackendForm.php @@ -54,7 +54,7 @@ class LdapBackendForm extends Form array( 'required' => true, 'label' => t('Backend Name'), - 'helptext' => t('The name of this authentication backend') + 'description' => t('The name of this authentication backend') ) ), $this->createElement( @@ -63,7 +63,7 @@ class LdapBackendForm extends Form array( 'required' => true, 'label' => t('LDAP Resource'), - 'helptext' => t('The resource to use for authenticating with this provider'), + 'description' => t('The resource to use for authenticating with this provider'), 'multiOptions' => false === empty($this->resources) ? array_combine($this->resources, $this->resources) : array() @@ -73,20 +73,20 @@ class LdapBackendForm extends Form 'text', 'user_class', array( - 'required' => true, - 'label' => t('LDAP User Object Class'), - 'helptext' => t('The object class used for storing users on the ldap server'), - 'value' => 'inetOrgPerson' + 'required' => true, + 'label' => t('LDAP User Object Class'), + 'description' => t('The object class used for storing users on the ldap server'), + 'value' => 'inetOrgPerson' ) ), $this->createElement( 'text', 'user_name_attribute', array( - 'required' => true, - 'label' => t('LDAP User Name Attribute'), - 'helptext' => t('The attribute name used for storing the user name on the ldap server'), - 'value' => 'uid' + 'required' => true, + 'label' => t('LDAP User Name Attribute'), + 'description' => t('The attribute name used for storing the user name on the ldap server'), + 'value' => 'uid' ) ), $this->createElement( diff --git a/application/forms/Config/AuthenticationBackendConfigForm.php b/application/forms/Config/AuthenticationBackendConfigForm.php index 2a882ff2b..f91044446 100644 --- a/application/forms/Config/AuthenticationBackendConfigForm.php +++ b/application/forms/Config/AuthenticationBackendConfigForm.php @@ -202,7 +202,7 @@ class AuthenticationBackendConfigForm extends ConfigForm if (($el = $this->getElement('force_creation')) === null || false === $el->isChecked()) { $backendForm = $this->getBackendForm($this->getElement('type')->getValue()); if (false === $backendForm->isValidAuthenticationBackend($this)) { - $this->addForceCreationCheckbox(); + $this->addElement($this->getForceCreationCheckbox()); return false; } } @@ -231,11 +231,11 @@ class AuthenticationBackendConfigForm extends ConfigForm /** * Populate the form in case an authentication backend is being edited * - * @see Form::onShow() + * @see Form::onRequest() * * @throws ConfigurationError In case the backend name is missing in the request or is invalid */ - public function onShow(Request $request) + public function onRequest(Request $request) { $authBackend = $request->getQuery('auth_backend'); if ($authBackend !== null) { @@ -255,19 +255,21 @@ class AuthenticationBackendConfigForm extends ConfigForm } /** - * Add a checkbox to be displayed at the beginning of the form + * 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 addForceCreationCheckbox() + protected function getForceCreationCheckbox() { - $this->addElement( + return $this->createElement( 'checkbox', 'force_creation', array( - 'order' => 0, - 'ignore' => true, - 'label' => t('Force Changes'), - 'helptext' => t('Check this box to enforce changes without connectivity validation') + 'order' => 0, + 'ignore' => true, + 'label' => t('Force Changes'), + 'description' => t('Check this box to enforce changes without connectivity validation') ) ); } @@ -297,22 +299,25 @@ class AuthenticationBackendConfigForm extends ConfigForm $backendTypes['autologin'] = t('Autologin'); } - $typeSelection = $this->createElement( + $elements = array(); + $elements[] = $this->createElement( 'select', 'type', array( - 'ignore' => true, - 'required' => true, - 'autosubmit' => true, - 'label' => t('Backend Type'), - 'helptext' => t('The type of the resource to use for this authenticaton backend'), - 'multiOptions' => $backendTypes + 'ignore' => true, + 'required' => true, + 'autosubmit' => true, + 'label' => t('Backend Type'), + 'description' => t('The type of the resource to use for this authenticaton backend'), + 'multiOptions' => $backendTypes ) ); - return array_merge( - array($typeSelection), - $this->getBackendForm($backendType)->createElements($formData) - ); + if (isset($formData['force_creation']) && $formData['force_creation']) { + // In case another error occured and the checkbox was displayed before + $elements[] = $this->getForceCreationCheckbox(); + } + + return array_merge($elements, $this->getBackendForm($backendType)->createElements($formData)); } } diff --git a/application/forms/Config/General/ApplicationConfigForm.php b/application/forms/Config/General/ApplicationConfigForm.php index 89e75f66a..7f3b746e4 100644 --- a/application/forms/Config/General/ApplicationConfigForm.php +++ b/application/forms/Config/General/ApplicationConfigForm.php @@ -41,7 +41,7 @@ class ApplicationConfigForm extends Form 'label' => t('Default Language'), 'required' => true, 'multiOptions' => $languages, - 'helptext' => t( + 'description' => t( 'Select the language to use by default. Can be overwritten by a user in his preferences.' ) ) @@ -59,7 +59,7 @@ class ApplicationConfigForm extends Form 'label' => t('Default Application Timezone'), 'required' => true, 'multiOptions' => $tzList, - 'helptext' => t( + 'description' => t( 'Select the timezone to be used as the default. User\'s can set their own timezone if' . ' they like to, but this is the timezone to be used as the default setting .' ), @@ -71,9 +71,9 @@ class ApplicationConfigForm extends Form 'text', 'global_modulePath', array( - 'label' => t('Module Path'), - 'required' => true, - 'helptext' => t( + 'label' => t('Module Path'), + 'required' => true, + 'description' => t( 'Contains the directories that will be searched for available modules, separated by ' . 'colons. Modules that don\'t exist in these directories can still be symlinked in ' . 'the module folder, but won\'t show up in the list of disabled modules.' diff --git a/application/forms/Config/General/LoggingConfigForm.php b/application/forms/Config/General/LoggingConfigForm.php index f91ce74b5..07f2e4d78 100644 --- a/application/forms/Config/General/LoggingConfigForm.php +++ b/application/forms/Config/General/LoggingConfigForm.php @@ -31,7 +31,7 @@ class LoggingConfigForm extends Form array( 'required' => true, 'label' => t('Logging Level'), - 'helptext' => t('The maximum loglevel to emit.'), + 'description' => t('The maximum loglevel to emit.'), 'multiOptions' => array( 0 => t('None'), 1 => t('Error'), @@ -48,7 +48,7 @@ class LoggingConfigForm extends Form 'required' => true, 'class' => 'autosubmit', 'label' => t('Logging Type'), - 'helptext' => t('The type of logging to utilize.'), + 'description' => t('The type of logging to utilize.'), 'multiOptions' => array( 'syslog' => 'Syslog', 'file' => t('File') @@ -63,7 +63,7 @@ class LoggingConfigForm extends Form array( 'required' => true, 'label' => t('Application Prefix'), - 'helptext' => t('The name of the application by which to prefix syslog messages.'), + 'description' => t('The name of the application by which to prefix syslog messages.'), 'value' => 'icingaweb', 'validators' => array( array( @@ -85,7 +85,7 @@ class LoggingConfigForm extends Form array( 'required' => true, 'label' => t('Facility'), - 'helptext' => t('The Syslog facility to utilize.'), + 'description' => t('The Syslog facility to utilize.'), 'multiOptions' => array( 'LOG_USER' => 'LOG_USER' ) @@ -98,7 +98,7 @@ class LoggingConfigForm extends Form array( 'required' => true, 'label' => t('Filepath'), - 'helptext' => t('The logfile to write messages to.'), + 'description' => t('The logfile to write messages to.'), 'value' => $this->getDefaultLogDir(), 'validators' => array(new WritablePathValidator()) ) diff --git a/application/forms/Config/GeneralConfigForm.php b/application/forms/Config/GeneralConfigForm.php index 29aac89fb..ea89e1b76 100644 --- a/application/forms/Config/GeneralConfigForm.php +++ b/application/forms/Config/GeneralConfigForm.php @@ -60,9 +60,9 @@ class GeneralConfigForm extends ConfigForm } /** - * @see Form::onShow() + * @see Form::onRequest() */ - public function onShow(Request $request) + public function onRequest(Request $request) { $values = array(); foreach ($this->config as $section => $properties) { diff --git a/application/forms/Config/Resource/DbResourceForm.php b/application/forms/Config/Resource/DbResourceForm.php new file mode 100644 index 000000000..e5ae4b9a7 --- /dev/null +++ b/application/forms/Config/Resource/DbResourceForm.php @@ -0,0 +1,128 @@ +setName('form_config_resource_db'); + } + + /** + * @see Form::createElements() + */ + public function createElements(array $formData) + { + return array( + $this->createElement( + 'select', + 'db', + array( + 'required' => true, + 'label' => t('Database Type'), + 'description' => t('The type of SQL database'), + 'multiOptions' => array( + 'mysql' => 'MySQL', + 'pgsql' => 'PostgreSQL' + //'oracle' => 'Oracle' + ) + ) + ), + $this->createElement( + 'text', + 'host', + array ( + 'required' => true, + 'label' => t('Host'), + 'description' => t('The hostname of the database'), + 'value' => 'localhost' + ) + ), + new Number( + array( + 'required' => true, + 'name' => 'port', + 'label' => t('Port'), + 'description' => t('The port to use'), + 'value' => 3306 + ) + ), + $this->createElement( + 'text', + 'dbname', + array( + 'required' => true, + 'label' => t('Database Name'), + 'description' => t('The name of the database to use') + ) + ), + $this->createElement( + 'text', + 'username', + array ( + 'required' => true, + 'label' => t('Username'), + 'description' => t('The user name to use for authentication') + ) + ), + $this->createElement( + 'password', + 'password', + array( + 'required' => true, + 'renderPassword' => true, + 'label' => t('Password'), + 'description' => t('The password to use for authentication') + ) + ) + ); + } + + /** + * Validate that the current configuration points to a valid resource + * + * @see Form::onSuccess() + */ + public function onSuccess(Request $request) + { + if (false === $this->isValidResource($this)) { + return false; + } + } + + /** + * Validate the resource configuration by trying to connect with it + * + * @param Form $form The form to fetch the configuration values from + * + * @return bool Whether validation succeeded or not + */ + public function isValidResource(Form $form) + { + try { + $resource = ResourceFactory::createResource(new Zend_Config($form->getValues())); + $resource->getConnection()->getConnection(); + } catch (Exception $e) { + $form->addError(t('Connectivity validation failed, connection to the given resource not possible.')); + return false; + } + + return true; + } +} diff --git a/application/forms/Config/Resource/FileResourceForm.php b/application/forms/Config/Resource/FileResourceForm.php new file mode 100644 index 000000000..422979585 --- /dev/null +++ b/application/forms/Config/Resource/FileResourceForm.php @@ -0,0 +1,50 @@ +setName('form_config_resource_file'); + } + + /** + * @see Form::createElements() + */ + public function createElements(array $formData) + { + return array( + $this->createElement( + 'text', + 'filename', + array( + 'required' => true, + 'label' => t('Filepath'), + 'description' => t('The filename to fetch information from'), + 'validators' => array(new ReadablePathValidator()) + ) + ), + $this->createElement( + 'text', + 'fields', + array( + 'required' => true, + 'label' => t('Pattern'), + 'description' => t('The regular expression by which to identify columns') + ) + ) + ); + } +} diff --git a/application/forms/Config/Resource/LdapResourceForm.php b/application/forms/Config/Resource/LdapResourceForm.php new file mode 100644 index 000000000..3b3075dc7 --- /dev/null +++ b/application/forms/Config/Resource/LdapResourceForm.php @@ -0,0 +1,114 @@ +setName('form_config_resource_ldap'); + } + + /** + * @see Form::createElements() + */ + public function createElements(array $formData) + { + return array( + $this->createElement( + 'text', + 'hostname', + array( + 'required' => true, + 'label' => t('Host'), + 'description' => 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'), + 'description' => t('The port of the LDAP server to use for authentication'), + 'value' => 389 + ) + ), + $this->createElement( + 'text', + 'root_dn', + array( + 'required' => true, + 'label' => t('Root DN'), + 'description' => t('The path where users can be found on the ldap server') + ) + ), + $this->createElement( + 'text', + 'bind_dn', + array( + 'required' => true, + 'label' => t('Bind DN'), + 'description' => 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'), + 'description' => t('The password to use for querying the ldap server') + ) + ) + ); + } + + /** + * Validate that the current configuration points to a valid resource + * + * @see Form::onSuccess() + */ + public function onSuccess(Request $request) + { + if (false === $this->isValidResource($this)) { + return false; + } + } + + /** + * Validate the resource configuration by trying to connect with it + * + * @param Form $form The form to fetch the configuration values from + * + * @return bool Whether validation succeeded or not + */ + public function isValidResource(Form $form) + { + try { + $resource = ResourceFactory::createResource(new Zend_Config($form->getValues())); + $resource->connect(); + } catch (Exception $e) { + $form->addError(t('Connectivity validation failed, connection to the given resource not possible.')); + return false; + } + + return true; + } +} diff --git a/application/forms/Config/Resource/LivestatusResourceForm.php b/application/forms/Config/Resource/LivestatusResourceForm.php new file mode 100644 index 000000000..e7e49a375 --- /dev/null +++ b/application/forms/Config/Resource/LivestatusResourceForm.php @@ -0,0 +1,77 @@ +setName('form_config_resource_livestatus'); + } + + /** + * @see Form::createElements() + */ + public function createElements(array $formData) + { + return array( + $this->createElement( + 'text', + 'socket', + array( + 'required' => true, + 'label' => t('Socket'), + 'description' => t('The path to your livestatus socket used for querying monitoring data'), + 'value' => realpath(Icinga::app()->getApplicationDir() . '/../var/rw/livestatus') + ) + ) + ); + } + + /** + * Validate that the current configuration points to a valid resource + * + * @see Form::onSuccess() + */ + public function onSuccess(Request $request) + { + if (false === $this->isValidResource($this)) { + return false; + } + } + + /** + * Validate the resource configuration by trying to connect with it + * + * @param Form $form The form to fetch the configuration values from + * + * @return bool Whether validation succeeded or not + */ + public function isValidResource(Form $form) + { + try { + $resource = ResourceFactory::createResource(new Zend_Config($form->getValues())); + $resource->connect()->disconnect(); + } catch (Exception $e) { + $form->addError(t('Connectivity validation failed, connection to the given resource not possible.')); + return false; + } + + return true; + } +} diff --git a/application/forms/Config/Resource/StatusdatResourceForm.php b/application/forms/Config/Resource/StatusdatResourceForm.php new file mode 100644 index 000000000..69c3d9040 --- /dev/null +++ b/application/forms/Config/Resource/StatusdatResourceForm.php @@ -0,0 +1,54 @@ +setName('form_config_resource_statusdat'); + } + + /** + * @see Form::createElements() + */ + public function createElements(array $formData) + { + return array( + $this->createElement( + 'text', + 'status_file', + array( + 'required' => true, + 'label' => t('Filepath'), + 'description' => t('Location of your icinga status.dat file'), + 'value' => realpath(Icinga::app()->getApplicationDir() . '/../var/status.dat'), + 'validators' => array(new ReadablePathValidator()) + ) + ), + $this->createElement( + 'text', + 'object_file', + array( + 'required' => true, + 'label' => t('Filepath'), + 'description' => t('Location of your icinga objects.cache file'), + 'value' => realpath(Icinga::app()->getApplicationDir() . '/../var/objects.cache'), + 'validators' => array(new ReadablePathValidator()) + ) + ) + ); + } +} diff --git a/application/forms/Config/ResourceConfigForm.php b/application/forms/Config/ResourceConfigForm.php new file mode 100644 index 000000000..9a3ae7793 --- /dev/null +++ b/application/forms/Config/ResourceConfigForm.php @@ -0,0 +1,258 @@ +setName('form_config_resource'); + $this->setSubmitLabel(t('Save Changes')); + } + + /** + * Return a form object for the given resource type + * + * @param string $type The resource type for which to return a form + * + * @return Form + */ + public function getResourceForm($type) + { + if ($type === 'db') { + return new DbResourceForm(); + } elseif ($type === 'ldap') { + return new LdapResourceForm(); + } elseif ($type === 'livestatus') { + return new LivestatusResourceForm(); + } elseif ($type === 'statusdat') { + return new StatusdatResourceForm(); + } elseif ($type === 'file') { + return new FileResourceForm(); + } else { + throw new InvalidArgumentException(sprintf(t('Invalid resource type "%s" provided'), $type)); + } + } + + /** + * Add a particular resource + * + * The backend to add is identified by the array-key `name'. + * + * @param array $values The values to extend the configuration with + * + * @return self + * + * @thrwos InvalidArgumentException In case the resource does already exist + */ + public function add(array $values) + { + $name = isset($values['name']) ? $values['name'] : ''; + if (! $name) { + throw new InvalidArgumentException(t('Resource name missing')); + } elseif ($this->config->{$name} !== null) { + throw new InvalidArgumentException(t('Resource already exists')); + } + + unset($values['name']); + $this->config->{$name} = $values; + return $this; + } + + /** + * Edit a particular resource + * + * @param string $name The name of the resource to edit + * @param array $values The values to edit the configuration with + * + * @return array The edited configuration + * + * @throws InvalidArgumentException In case the resource does not exist + */ + public function edit($name, array $values) + { + if (! $name) { + throw new InvalidArgumentException(t('Old resource name missing')); + } elseif (! ($newName = isset($values['name']) ? $values['name'] : '')) { + throw new InvalidArgumentException(t('New resource name missing')); + } elseif (($resourceConfig = $this->config->get($name)) === null) { + throw new InvalidArgumentException(t('Unknown resource provided')); + } + + unset($values['name']); + unset($this->config->{$name}); + $this->config->{$newName} = array_merge($resourceConfig->toArray(), $values); + return $this->config->{$newName}; + } + + /** + * Remove a particular resource + * + * @param string $name The name of the resource to remove + * + * @return array The removed resource configuration + * + * @throws InvalidArgumentException In case the resource does not exist + */ + public function remove($name) + { + if (! $name) { + throw new InvalidArgumentException(t('Resource name missing')); + } elseif (($resourceConfig = $this->config->get($name)) === null) { + throw new InvalidArgumentException(t('Unknown resource provided')); + } + + unset($this->config->{$name}); + return $resourceConfig; + } + + /** + * Add or edit a resource and save the configuration + * + * Performs a connectivity validation using the submitted values. A checkbox is + * added to the form to skip the check if it fails and redirection is aborted. + * + * @see Form::onSuccess() + */ + public function onSuccess(Request $request) + { + if (($el = $this->getElement('force_creation')) === null || false === $el->isChecked()) { + $resourceForm = $this->getResourceForm($this->getElement('type')->getValue()); + if (method_exists($resourceForm, 'isValidResource') && false === $resourceForm->isValidResource($this)) { + $this->addElement($this->getForceCreationCheckbox()); + return false; + } + } + + $resource = $request->getQuery('resource'); + try { + if ($resource === null) { // create new resource + $this->add($this->getValues()); + $message = t('Resource "%s" has been successfully created'); + } else { // edit existing resource + $this->edit($resource, $this->getValues()); + $message = t('Resource "%s" has been successfully changed'); + } + } catch (InvalidArgumentException $e) { + Notification::error($e->getMessage()); + return; + } + + if ($this->save()) { + Notification::success(sprintf($message, $this->getElement('name')->getValue())); + } else { + return false; + } + } + + /** + * Populate the form in case a resource is being edited + * + * @see Form::onRequest() + * + * @throws ConfigurationError In case the backend name is missing in the request or is invalid + */ + public function onRequest(Request $request) + { + $resource = $request->getQuery('resource'); + if ($resource !== null) { + if ($resource === '') { + throw new ConfigurationError(t('Resource name missing')); + } elseif (false === isset($this->config->{$resource})) { + throw new ConfigurationError(t('Unknown resource provided')); + } + + $configValues = $this->config->{$resource}->toArray(); + $configValues['name'] = $resource; + $this->populate($configValues); + } + } + + /** + * 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, + 'ignore' => true, + 'label' => t('Force Changes'), + 'description' => t('Check this box to enforce changes without connectivity validation') + ) + ); + } + + /** + * @see Form::createElemeents() + */ + public function createElements(array $formData) + { + $resourceType = isset($formData['type']) ? $formData['type'] : 'db'; + + $resourceTypes = array( + 'file' => t('File'), + 'statusdat' => 'Status.dat', + 'livestatus' => 'Livestatus', + ); + if ($resourceType === 'ldap' || Platform::extensionLoaded('ldap')) { + $resourceTypes['ldap'] = 'LDAP'; + } + if ($resourceType === 'db' || Platform::extensionLoaded('mysql') || Platform::extensionLoaded('pgsql')) { + $resourceTypes['db'] = t('SQL Database'); + } + + $elements = array( + $this->createElement( + 'text', + 'name', + array( + 'required' => true, + 'label' => t('Resource Name'), + 'description' => t('The unique name of this resource') + ) + ), + $this->createElement( + 'select', + 'type', + array( + 'required' => true, + 'autosubmit' => true, + 'label' => t('Resource Type'), + 'description' => t('The type of resource'), + 'multiOptions' => $resourceTypes, + 'value' => $resourceType + ) + ) + ); + + if (isset($formData['force_creation']) && $formData['force_creation']) { + // In case another error occured and the checkbox was displayed before + $elements[] = $this->getForceCreationCheckbox(); + } + + return array_merge($elements, $this->getResourceForm($resourceType)->createElements($formData)); + } +} diff --git a/application/forms/Config/ResourceForm.php b/application/forms/Config/ResourceForm.php deleted file mode 100644 index f7c6314fa..000000000 --- a/application/forms/Config/ResourceForm.php +++ /dev/null @@ -1,444 +0,0 @@ -setName('form_config_resource'); - $this->setSubmitLabel(t('Save Changes')); - } - - /** - * @see Form::createElemeents() - */ - public function createElements(array $formData) - { - $elements = array(); - $elements[] = $this->createElement( - 'text', - 'name', - array( - 'required' => true, - 'label' => t('Resource Name'), - 'helptext' => t('The unique name of this resource') - ) - ); - $elements[] = $this->createElement( - 'select', - 'type', - array( - 'required' => true, - 'class' => 'autosubmit', - 'label' => t('Resource Type'), - 'helptext' => t('The type of resource'), - 'multiOptions' => array( - 'db' => t('SQL Database'), - 'ldap' => 'LDAP', - 'statusdat' => 'Status.dat', - 'livestatus' => 'Livestatus', - 'file' => t('File') - ) - ) - ); - - 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()); - } - } - - /** - * Return whether the given values are complete/valid and check whether it is possible to connect to the resource - * - * If connection validation fails, a checkbox is prepended to the form to allow users to skip it. - * - * @param array $data The data to validate - * - * @return bool Whether the validation succeeded or not - */ - public function isValid($data) - { - if (false === parent::isValid($data)) { - return false; - } - - if ( - (false === isset($data['force_creation']) || false == $data['force_creation']) - && false === $this->isValidResource() - ) { - $this->addElement($this->getForceCreationCheckbox()); - return false; - } - - return true; - } - - /** - * Return whether a connection can be established with the current resource configuration values - * - * @return bool Whether the connection validation was successful or not - */ - public function isValidResource() - { - list($name, $config) = $this->getResourceConfig(); - - try { - 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' && false === Platform::extensionLoaded('mysql')) { - $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' && false === Platform::extensionLoaded('pgsql')) { - $this->addErrorMessage( - t('You need to install the php extension "pgsql" and the ' . - 'Zend_Pdo_Pgsql classes to use PostgreSQL database resources.') - ); - return false; - } - - $resource = ResourceFactory::createResource(new Zend_Config($config)); - $resource->getConnection()->getConnection(); - break; - case 'statusdat': - if ( - false === file_exists($config['object_file']) - || false === file_exists($config['status_file']) - ) { - $this->addErrorMessage( - t('Connectivity validation failed. At least one of the provided files does not exist.') - ); - return false; - } - break; - case 'livestatus': - $resource = ResourceFactory::createResource(new Zend_Config($config)); - $resource->connect()->disconnect(); - break; - case 'ldap': - $resource = ResourceFactory::createResource(new Zend_Config($config)); - $resource->connect(); - break; - case 'file': - if (false === file_exists($config['filename'])) { - $this->addErrorMessage(t('Connectivity validation failed. The provided file does not exist.')); - return false; - } - break; - } - } catch (Exception $e) { - $this->addErrorMessage(t('Connectivity validation failed, connection to the given resource not possible.')); - return false; - } - - return true; - } - - /** - * 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() - { - $values = $this->getValues(); - $name = $values['name']; - unset($values['name']); - return array($name, $values); - } - - /** - * Populate the form with the given configuration values - * - * @param string $name The name of the resource - * @param array $config The configuration values - */ - public function setResourceConfig($name, array $config) - { - $config['name'] = $name; - $this->populate($config); - } - - /** - * 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, - 'ignore' => true, - 'label' => t('Force Changes'), - 'helptext' => t('Check this box to enforce changes without connectivity validation') - ) - ); - } - - /** - * 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') - ) - ) - ); - } -} diff --git a/application/locale/de_DE/LC_MESSAGES/icinga.po b/application/locale/de_DE/LC_MESSAGES/icinga.po index e174b6621..205cd7f3d 100644 --- a/application/locale/de_DE/LC_MESSAGES/icinga.po +++ b/application/locale/de_DE/LC_MESSAGES/icinga.po @@ -486,7 +486,7 @@ msgstr "Die Objekt-Klasse welche benutzt wird, um Benutzer auf diesem LDAP-Serve #: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:182 msgid "The password to use for authentication" -msgstr "Das Kennwort welche zur Authentifizierung benutzt werden soll" +msgstr "Das Kennwort welches zur Authentifizierung benutzt werden soll" #: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:270 msgid "The password to use for querying the ldap server" diff --git a/application/views/helpers/FormNumber.php b/application/views/helpers/FormNumber.php index a8768f0b7..98cb8d06f 100644 --- a/application/views/helpers/FormNumber.php +++ b/application/views/helpers/FormNumber.php @@ -2,29 +2,41 @@ // {{{ICINGA_LICENSE_HEADER}}} // {{{ICINGA_LICENSE_HEADER}}} +use \Zend_View_Helper_FormElement; + /** - * Helper to generate a number input + * Render number input controls */ -class Zend_View_Helper_FormNumber extends \Zend_View_Helper_FormText +class Zend_View_Helper_FormNumber extends Zend_View_Helper_FormElement { /** - * Generates a html number input + * Render the number input control * - * @access public + * @param string $name + * @param int $value + * @param array $attribs * - * @param string $name The element name. - * @param string $value The default value. - * @param array $attribs Attributes which should be added to the input tag. - * - * @return string The input tag and options XHTML. + * @return string The rendered number input control */ public function formNumber($name, $value = null, $attribs = null) { - return '_htmlAttribs($attribs) - . $this->getClosingBracket(); + $info = $this->_getInfo($name, $value, $attribs); + extract($info); // name, id, value, attribs, options, listsep, disable + /** @var string $id */ + /** @var bool $disable */ + $disabled = ''; + if ($disable) { + $disabled = ' disabled="disabled"'; + } + $html5 = sprintf( + 'view->escape($name), + $this->view->escape($id), + $this->view->escape($value), + $disabled, + $this->_htmlAttribs($attribs), + $this->getClosingBracket() + ); + return $html5; } } diff --git a/application/views/scripts/config/resource.phtml b/application/views/scripts/config/resource.phtml index 8e2c2eedd..51f98eadb 100644 --- a/application/views/scripts/config/resource.phtml +++ b/application/views/scripts/config/resource.phtml @@ -2,10 +2,9 @@
-

- - icon('create.png'); ?> translate('Create a new resource'); ?> + + icon('create.png'); ?> translate('Create A New Resource'); ?>

@@ -17,12 +16,12 @@ resources as $name => $resource): ?> diff --git a/application/views/scripts/config/resource/create.phtml b/application/views/scripts/config/resource/create.phtml index 74639f056..5a07d832e 100644 --- a/application/views/scripts/config/resource/create.phtml +++ b/application/views/scripts/config/resource/create.phtml @@ -1,4 +1,3 @@ - -

translate('Create a new resource'); ?>

-

translate('Resources are entities that provide data to Icingaweb.'); ?>

+

translate('Create A New Resource'); ?>

+

translate('Resources are entities that provide data to Icinga Web 2.'); ?>

\ No newline at end of file diff --git a/application/views/scripts/config/resource/modify.phtml b/application/views/scripts/config/resource/modify.phtml index 7f549d537..5fa2536bd 100644 --- a/application/views/scripts/config/resource/modify.phtml +++ b/application/views/scripts/config/resource/modify.phtml @@ -1,3 +1,2 @@

translate('Edit Existing Resource'); ?>

- \ No newline at end of file diff --git a/application/views/scripts/config/resource/remove.phtml b/application/views/scripts/config/resource/remove.phtml index fba6b081b..a43bcd74c 100644 --- a/application/views/scripts/config/resource/remove.phtml +++ b/application/views/scripts/config/resource/remove.phtml @@ -1,3 +1,2 @@

translate('Remove Existing Resource'); ?>

- \ No newline at end of file diff --git a/application/views/scripts/error/error.phtml b/application/views/scripts/error/error.phtml index e3a71f829..2a900651b 100644 --- a/application/views/scripts/error/error.phtml +++ b/application/views/scripts/error/error.phtml @@ -11,7 +11,4 @@
escape($stackTrace) ?>
-messageBox)) : ?> - messageBox->render(); ?> - diff --git a/library/Icinga/User.php b/library/Icinga/User.php index 13f62881a..6d34e10ab 100644 --- a/library/Icinga/User.php +++ b/library/Icinga/User.php @@ -7,7 +7,6 @@ namespace Icinga; use DateTimeZone; use InvalidArgumentException; use Icinga\User\Preferences; -use Icinga\User\Message; /** * This class represents an authorized user @@ -98,13 +97,6 @@ class User */ protected $preferences; - /** - * Queued notifications for this user. - * - * @var array() - */ - protected $messages; - /** * Creates a user object given the provided information * @@ -382,38 +374,6 @@ class User return new DateTimeZone($tz); } - /** - * Add a message that can be accessed from future requests, to this user. - * - * This function does NOT automatically write to the session, messages will not be persisted until you do. - * - * @param Message $msg The message - */ - public function addMessage(Message $msg) - { - $this->messages[] = $msg; - } - - /** - * Get all currently pending messages - * - * @return array The messages - */ - public function getMessages() - { - return isset($this->messages) ? $this->messages : array(); - } - - /** - * Remove all messages from this user - * - * This function does NOT automatically write the session, messages will not be persisted until you do. - */ - public function clearMessages() - { - $this->messages = null; - } - /** * Set additional remote user information * diff --git a/library/Icinga/User/Message.php b/library/Icinga/User/Message.php deleted file mode 100644 index 83d780563..000000000 --- a/library/Icinga/User/Message.php +++ /dev/null @@ -1,59 +0,0 @@ -message = $message; - $this->level = $level; - } - - /** - * @return string - */ - public function getMessage() - { - return $this->message; - } - - /** - * @return The - */ - public function getLevel() - { - return $this->level; - } -} diff --git a/library/Icinga/Web/Controller/BaseConfigController.php b/library/Icinga/Web/Controller/BaseConfigController.php deleted file mode 100644 index b4c90f3e2..000000000 --- a/library/Icinga/Web/Controller/BaseConfigController.php +++ /dev/null @@ -1,75 +0,0 @@ -getUser()->addMessage( - new Message($msg, Zend_Log::INFO) - ); - Session::getSession()->write(); - } - - /** - * Send a message with the logging level Zend_Log::ERR to the current user and - * commit the changes to the underlying session. - * - * @param $msg The message content - */ - protected function addErrorMessage($msg) - { - AuthenticationManager::getInstance()->getUser()->addMessage( - new Message($msg, Zend_Log::ERR) - ); - Session::getSession()->write(); - } - - /** - * Send a message with the logging level Zend_Log::WARN to the current user and - * commit the changes to the underlying session. - * - * @param $msg The message content - */ - protected function addWarningMessage($msg) - { - AuthenticationManager::getInstance()->getUser()->addMessage( - new Message($msg, Zend_Log::WARN) - ); - Session::getSession()->write(); - } - - /* - * Return an array of tabs provided by this configuration controller. - * - * Those tabs will automatically be added to the application's configuration dialog - * - * @return array - */ - public static function createProvidedTabs() - { - return array(); - } -} diff --git a/library/Icinga/Web/Form.php b/library/Icinga/Web/Form.php index 78755f00b..2c0fb2a89 100644 --- a/library/Icinga/Web/Form.php +++ b/library/Icinga/Web/Form.php @@ -8,9 +8,7 @@ use LogicException; use Zend_Form; use Zend_View_Interface; use Icinga\Application\Icinga; -use Icinga\Web\Form\Decorator\HelpText; use Icinga\Web\Form\Decorator\NoScriptApply; -use Icinga\Web\Form\Decorator\ElementWrapper; use Icinga\Web\Form\Element\CsrfCounterMeasure; /** @@ -99,6 +97,7 @@ class Form extends Zend_Form if ($this->onSuccess !== null && false === is_callable($this->onSuccess)) { throw new LogicException('The option `onSuccess\' is not callable'); } + if (! isset($options['elementDecorators'])) { $options['elementDecorators'] = array( 'ViewHelper', @@ -108,6 +107,7 @@ class Form extends Zend_Form array('HtmlTag', array('tag' => 'div')) ); } + parent::__construct($options); } @@ -321,7 +321,7 @@ class Form extends Zend_Form * * @param Request $request The current request */ - public function onShow(Request $request) + public function onRequest(Request $request) { } @@ -372,6 +372,7 @@ class Form extends Zend_Form if (is_array($options) && ! isset($options['disableLoadDefaultDecorators'])) { $options['disableLoadDefaultDecorators'] = true; } + $el = parent::createElement($type, $name, $options); if ($el && $el->getAttrib('autosubmit')) { $el->addDecorator(new NoScriptApply()); // Non-JS environments @@ -386,6 +387,7 @@ class Form extends Zend_Form $el->setAttrib('class', $class); // JS environments unset($el->autosubmit); } + return $el; } @@ -439,7 +441,7 @@ class Form extends Zend_Form * Process the given request using this form * * Redirects to the url set with setRedirectUrl() upon success. See onSuccess() - * and onShow() wherewith you can customize the processing logic. + * and onRequest() wherewith you can customize the processing logic. * * @param Request $request The request to be processed * @@ -465,7 +467,7 @@ class Form extends Zend_Form $this->isValidPartial($formData); } } else { - $this->onShow($request); + $this->onRequest($request); } return $request; @@ -555,6 +557,7 @@ class Form extends Zend_Form if ($this->loadDefaultDecoratorsIsDisabled()) { return $this; } + $decorators = $this->getDecorators(); if (empty($decorators)) { if ($this->viewScript) { @@ -563,11 +566,13 @@ class Form extends Zend_Form 'form' => $this )); } else { - $this + $this->addDecorator('FormErrors', array('onlyCustomFormErrors' => true)) ->addDecorator('FormElements') + //->addDecorator('HtmlTag', array('tag' => 'dl', 'class' => 'zend_form')) ->addDecorator('Form'); } } + return $this; } diff --git a/library/Icinga/Web/Form/Element/Number.php b/library/Icinga/Web/Form/Element/Number.php index d87a6d09f..3bfbc6406 100644 --- a/library/Icinga/Web/Form/Element/Number.php +++ b/library/Icinga/Web/Form/Element/Number.php @@ -4,38 +4,37 @@ namespace Icinga\Web\Form\Element; -use Zend_Form_Element_Xhtml; +use Zend_Form_Element; /** - * Number form element + * A number input control */ -class Number extends Zend_Form_Element_Xhtml +class Number extends Zend_Form_Element { /** - * Default form view helper to use for rendering + * Disable default decorators + * + * \Icinga\Web\Form sets default decorators for elements. + * + * @var bool + * + * @see \Icinga\Web\Form::__construct() For default element decorators. + */ + protected $_disableLoadDefaultDecorators = true; + + /** + * Form view helper to use for rendering * * @var string */ - public $helper = "formNumber"; + public $helper = 'formNumber'; /** - * Check whether $value is of type integer - * - * @param string $value The value to check - * @param mixed $context Context to use - * - * @return bool + * (non-PHPDoc) + * @see \Zend_Form_Element::init() For the method documentation. */ - public function isValid($value, $context = null) + public function init() { - if (parent::isValid($value, $context)) { - if (is_numeric($value)) { - return true; - } - - $this->addError(t('Please enter a number.')); - } - - return false; + $this->addValidator('Int'); } } diff --git a/library/Icinga/Web/Form/Validator/ReadablePathValidator.php b/library/Icinga/Web/Form/Validator/ReadablePathValidator.php new file mode 100644 index 000000000..4060f6ecd --- /dev/null +++ b/library/Icinga/Web/Form/Validator/ReadablePathValidator.php @@ -0,0 +1,58 @@ +_messageTemplates = array( + 'NOT_READABLE' => t('Path is not readable'), + 'DOES_NOT_EXIST' => t('Path does not exist') + ); + } + + /** + * Check whether the given value is a readable filepath + * + * @param string $value The value submitted in the form + * @param mixed $context The context of the form + * + * @return bool Whether the value was successfully validated + */ + public function isValid($value, $context = null) + { + if (false === file_exists($value)) { + $this->_error('DOES_NOT_EXIST'); + return false; + } + + if (false === is_readable($value)) { + $this->_error('NOT_READABLE'); + } + + return true; + } +} diff --git a/library/Icinga/Web/Widget/AlertMessageBox.php b/library/Icinga/Web/Widget/AlertMessageBox.php deleted file mode 100644 index 13cf91068..000000000 --- a/library/Icinga/Web/Widget/AlertMessageBox.php +++ /dev/null @@ -1,133 +0,0 @@ -user->getMessages(); - $this->user->clearMessages(); - Session::getSession()->write(); - return $messages; - } - - /** - * The displayed alert messages - * - * @var array - */ - private $messages = array(); - - /** - * The user to fetch the messages from - * - * @var User - */ - private $user; - - /** - * The available states. - * - * @var array - */ - private $states = array( - Zend_Log::INFO => array( - 'state' => 'alert-success', - 'icon' => 'success.png' - ), - Zend_Log::NOTICE => array( - 'state' => 'alert-info', - 'icon' => 'info.png' - ), - Zend_Log::WARN => array( - 'state' => 'alert-warning', - 'icon' => 'warning.png' - ), - Zend_Log::ERR => array( - 'state' => 'alert-danger', - 'icon' => 'error.png' - ) - ); - - /** - * Create a new AlertBox - * - * @param boolean showUserMessages If the current user messages should be displayed - * in this AlertMessageBox. Defaults to false - */ - public function __construct($showUserMessages = false) - { - if ($showUserMessages) { - $this->user = AuthenticationManager::getInstance()->getUser(); - } - } - - /** - * Add a new error - * - * @param $error - */ - public function addError($error) - { - $this->messages[] = new Message($error, Zend_Log::ERR); - } - - /** - * Add the error messages of the given Zend_Form - */ - public function addForm(Zend_Form $form) - { - foreach ($form->getErrorMessages() as $error) { - $this->addError($error); - } - } - - /** - * Output the HTML of the AlertBox - * - * @return string - */ - public function render(Zend_View_Abstract $view = null) - { - $html = ''; - if (isset($this->user)) { - $this->messages = array_merge($this->messages, $this->getAndClearMessages()); - } - foreach ($this->messages as $message) { - $level = $message->getLevel(); - if (!array_key_exists($level, $this->states)) { - continue; - } - $alert = $this->states[$level]; - $html .= '
' . - $this->view()->icon($alert['icon']) . - '' . htmlspecialchars($message->getMessage()) . '' . - '
'; - } - return $html; - } -}
- - icon('edit.png') ?> escape($name); ?> + + icon('edit.png'); ?> escape($name); ?> - + icon('remove.png'); ?>