diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 12:39:39 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 12:39:39 +0000 |
commit | 8ca6cc32b2c789a3149861159ad258f2cb9491e3 (patch) | |
tree | 2492de6f1528dd44eaa169a5c1555026d9cb75ec /application/forms/Config/Resource | |
parent | Initial commit. (diff) | |
download | icingaweb2-upstream.tar.xz icingaweb2-upstream.zip |
Adding upstream version 2.11.4.upstream/2.11.4upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | application/forms/Config/Resource/DbResourceForm.php | 238 | ||||
-rw-r--r-- | application/forms/Config/Resource/FileResourceForm.php | 67 | ||||
-rw-r--r-- | application/forms/Config/Resource/LdapResourceForm.php | 129 | ||||
-rw-r--r-- | application/forms/Config/Resource/SshResourceForm.php | 148 | ||||
-rw-r--r-- | application/forms/Config/ResourceConfigForm.php | 441 |
5 files changed, 1023 insertions, 0 deletions
diff --git a/application/forms/Config/Resource/DbResourceForm.php b/application/forms/Config/Resource/DbResourceForm.php new file mode 100644 index 0000000..b9979ee --- /dev/null +++ b/application/forms/Config/Resource/DbResourceForm.php @@ -0,0 +1,238 @@ +<?php +/* Icinga Web 2 | (c) 2014 Icinga Development Team | GPLv2+ */ + +namespace Icinga\Forms\Config\Resource; + +use Icinga\Application\Platform; +use Icinga\Web\Form; + +/** + * Form class for adding/modifying database resources + */ +class DbResourceForm extends Form +{ + /** + * Initialize this form + */ + public function init() + { + $this->setName('form_config_resource_db'); + } + + /** + * Create and add elements to this form + * + * @param array $formData The data sent by the user + */ + public function createElements(array $formData) + { + $dbChoices = array(); + if (Platform::hasMysqlSupport()) { + $dbChoices['mysql'] = 'MySQL'; + } + if (Platform::hasPostgresqlSupport()) { + $dbChoices['pgsql'] = 'PostgreSQL'; + } + if (Platform::hasMssqlSupport()) { + $dbChoices['mssql'] = 'MSSQL'; + } + if (Platform::hasIbmSupport()) { + $dbChoices['ibm'] = 'IBM (DB2)'; + } + if (Platform::hasOracleSupport()) { + $dbChoices['oracle'] = 'Oracle'; + } + if (Platform::hasOciSupport()) { + $dbChoices['oci'] = 'Oracle (OCI8)'; + } + if (Platform::hasSqliteSupport()) { + $dbChoices['sqlite'] = 'SQLite'; + } + + $offerPostgres = false; + $offerMysql = false; + $dbChoice = isset($formData['db']) ? $formData['db'] : key($dbChoices); + if ($dbChoice === 'pgsql') { + $offerPostgres = true; + } elseif ($dbChoice === 'mysql') { + $offerMysql = true; + } + + if ($dbChoice === 'oracle') { + $hostIsRequired = false; + } else { + $hostIsRequired = true; + } + + $socketInfo = ''; + if ($offerPostgres) { + $socketInfo = $this->translate( + 'For using unix domain sockets, specify the path to the unix domain socket directory' + ); + } elseif ($offerMysql) { + $socketInfo = $this->translate( + 'For using unix domain sockets, specify localhost' + ); + } + + $this->addElement( + 'text', + 'name', + array( + 'required' => true, + 'label' => $this->translate('Resource Name'), + 'description' => $this->translate('The unique name of this resource') + ) + ); + $this->addElement( + 'select', + 'db', + array( + 'required' => true, + 'autosubmit' => true, + 'label' => $this->translate('Database Type'), + 'description' => $this->translate('The type of SQL database'), + 'multiOptions' => $dbChoices + ) + ); + if ($dbChoice === 'sqlite') { + $this->addElement( + 'text', + 'dbname', + array( + 'required' => true, + 'label' => $this->translate('Database Name'), + 'description' => $this->translate('The name of the database to use') + ) + ); + } else { + $this->addElement( + 'text', + 'host', + array ( + 'required' => $hostIsRequired, + 'label' => $this->translate('Host'), + 'description' => $this->translate('The hostname of the database') + . ($socketInfo ? '. ' . $socketInfo : ''), + 'value' => $hostIsRequired ? 'localhost' : '' + ) + ); + $this->addElement( + 'number', + 'port', + array( + 'description' => $this->translate('The port to use'), + 'label' => $this->translate('Port'), + 'preserveDefault' => true, + 'required' => $offerPostgres, + 'value' => $offerPostgres ? 5432 : null + ) + ); + $this->addElement( + 'text', + 'dbname', + array( + 'required' => true, + 'label' => $this->translate('Database Name'), + 'description' => $this->translate('The name of the database to use') + ) + ); + $this->addElement( + 'text', + 'username', + array ( + 'required' => true, + 'label' => $this->translate('Username'), + 'description' => $this->translate('The user name to use for authentication') + ) + ); + $this->addElement( + 'password', + 'password', + array( + 'required' => true, + 'renderPassword' => true, + 'label' => $this->translate('Password'), + 'description' => $this->translate('The password to use for authentication') + ) + ); + $this->addElement( + 'text', + 'charset', + array ( + 'description' => $this->translate('The character set for the database'), + 'label' => $this->translate('Character Set') + ) + ); + $this->addElement( + 'checkbox', + 'use_ssl', + array( + 'autosubmit' => true, + 'label' => $this->translate('Use SSL'), + 'description' => $this->translate( + 'Whether to encrypt the connection or to authenticate using certificates' + ) + ) + ); + if (isset($formData['use_ssl']) && $formData['use_ssl']) { + if (defined('\PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT')) { + $this->addElement( + 'checkbox', + 'ssl_do_not_verify_server_cert', + array( + 'label' => $this->translate('SSL Do Not Verify Server Certificate'), + 'description' => $this->translate( + 'Whether to disable verification of the server certificate' + ) + ) + ); + } + $this->addElement( + 'text', + 'ssl_key', + array( + 'label' => $this->translate('SSL Key'), + 'description' => $this->translate('The client key file path') + ) + ); + $this->addElement( + 'text', + 'ssl_cert', + array( + 'label' => $this->translate('SSL Certificate'), + 'description' => $this->translate('The certificate file path') + ) + ); + $this->addElement( + 'text', + 'ssl_ca', + array( + 'label' => $this->translate('SSL CA'), + 'description' => $this->translate('The CA certificate file path') + ) + ); + $this->addElement( + 'text', + 'ssl_capath', + array( + 'label' => $this->translate('SSL CA Path'), + 'description' => $this->translate( + 'The trusted CA certificates in PEM format directory path' + ) + ) + ); + $this->addElement( + 'text', + 'ssl_cipher', + array( + 'label' => $this->translate('SSL Cipher'), + 'description' => $this->translate('The list of permissible ciphers') + ) + ); + } + } + + return $this; + } +} diff --git a/application/forms/Config/Resource/FileResourceForm.php b/application/forms/Config/Resource/FileResourceForm.php new file mode 100644 index 0000000..b98f1b4 --- /dev/null +++ b/application/forms/Config/Resource/FileResourceForm.php @@ -0,0 +1,67 @@ +<?php +/* Icinga Web 2 | (c) 2014 Icinga Development Team | GPLv2+ */ + +namespace Icinga\Forms\Config\Resource; + +use Zend_Validate_Callback; +use Icinga\Web\Form; + +/** + * Form class for adding/modifying file resources + */ +class FileResourceForm extends Form +{ + /** + * Initialize this form + */ + public function init() + { + $this->setName('form_config_resource_file'); + } + + /** + * @see Form::createElements() + */ + public function createElements(array $formData) + { + $this->addElement( + 'text', + 'name', + array( + 'required' => true, + 'label' => $this->translate('Resource Name'), + 'description' => $this->translate('The unique name of this resource') + ) + ); + $this->addElement( + 'text', + 'filename', + array( + 'required' => true, + 'label' => $this->translate('Filepath'), + 'description' => $this->translate('The filename to fetch information from'), + 'validators' => array('ReadablePathValidator') + ) + ); + $callbackValidator = new Zend_Validate_Callback(function ($value) { + return @preg_match($value, '') !== false; + }); + $callbackValidator->setMessage( + $this->translate('"%value%" is not a valid regular expression.'), + Zend_Validate_Callback::INVALID_VALUE + ); + $this->addElement( + 'text', + 'fields', + array( + 'required' => true, + 'label' => $this->translate('Pattern'), + 'description' => $this->translate('The pattern by which to identify columns.'), + 'requirement' => $this->translate('The column pattern must be a valid regular expression.'), + 'validators' => array($callbackValidator) + ) + ); + + return $this; + } +} diff --git a/application/forms/Config/Resource/LdapResourceForm.php b/application/forms/Config/Resource/LdapResourceForm.php new file mode 100644 index 0000000..7ffccdc --- /dev/null +++ b/application/forms/Config/Resource/LdapResourceForm.php @@ -0,0 +1,129 @@ +<?php +/* Icinga Web 2 | (c) 2014 Icinga Development Team | GPLv2+ */ + +namespace Icinga\Forms\Config\Resource; + +use Icinga\Web\Form; +use Icinga\Web\Url; +use Icinga\Protocol\Ldap\LdapConnection; + +/** + * Form class for adding/modifying ldap resources + */ +class LdapResourceForm extends Form +{ + /** + * Initialize this form + */ + public function init() + { + $this->setName('form_config_resource_ldap'); + } + + /** + * {@inheritdoc} + */ + public function createElements(array $formData) + { + $defaultPort = ! array_key_exists('encryption', $formData) || $formData['encryption'] !== LdapConnection::LDAPS + ? 389 + : 636; + + $this->addElement( + 'text', + 'name', + array( + 'required' => true, + 'label' => $this->translate('Resource Name'), + 'description' => $this->translate('The unique name of this resource') + ) + ); + $this->addElement( + 'text', + 'hostname', + array( + 'required' => true, + 'label' => $this->translate('Host'), + 'description' => $this->translate( + 'The hostname or address of the LDAP server to use for authentication.' + . ' You can also provide multiple hosts separated by a space' + ), + 'value' => 'localhost' + ) + ); + $this->addElement( + 'number', + 'port', + array( + 'required' => true, + 'preserveDefault' => true, + 'label' => $this->translate('Port'), + 'description' => $this->translate('The port of the LDAP server to use for authentication'), + 'value' => $defaultPort + ) + ); + $this->addElement( + 'select', + 'encryption', + array( + 'required' => true, + 'autosubmit' => true, + 'label' => $this->translate('Encryption'), + 'description' => $this->translate( + 'Whether to encrypt communication. Choose STARTTLS or LDAPS for encrypted communication or' + . ' none for unencrypted communication' + ), + 'multiOptions' => array( + 'none' => $this->translate('None', 'resource.ldap.encryption'), + LdapConnection::STARTTLS => 'STARTTLS', + LdapConnection::LDAPS => 'LDAPS' + ) + ) + ); + + $this->addElement( + 'text', + 'root_dn', + array( + 'required' => true, + 'label' => $this->translate('Root DN'), + 'description' => $this->translate( + 'Only the root and its child nodes will be accessible on this resource.' + ) + ) + ); + $this->addElement( + 'text', + 'bind_dn', + array( + 'label' => $this->translate('Bind DN'), + 'description' => $this->translate( + 'The user dn to use for querying the ldap server. Leave the dn and password empty for attempting' + . ' an anonymous bind' + ) + ) + ); + $this->addElement( + 'password', + 'bind_pw', + array( + 'renderPassword' => true, + 'label' => $this->translate('Bind Password'), + 'description' => $this->translate('The password to use for querying the ldap server') + ) + ); + + $this->addElement( + 'number', + 'timeout', + array( + 'preserveDefault' => true, + 'label' => $this->translate('Timeout'), + 'description' => $this->translate('Connection timeout for every LDAP connection'), + 'value' => 5 // see LdapConnection::__construct() + ) + ); + + return $this; + } +} diff --git a/application/forms/Config/Resource/SshResourceForm.php b/application/forms/Config/Resource/SshResourceForm.php new file mode 100644 index 0000000..a15dc8c --- /dev/null +++ b/application/forms/Config/Resource/SshResourceForm.php @@ -0,0 +1,148 @@ +<?php +/* Icinga Web 2 | (c) 2015 Icinga Development Team | GPLv2+ */ + +namespace Icinga\Forms\Config\Resource; + +use Icinga\Application\Icinga; +use Icinga\Data\ConfigObject; +use Icinga\Forms\Config\ResourceConfigForm; +use Icinga\Web\Form; +use Icinga\Util\File; +use Zend_Validate_Callback; + +/** + * Form class for adding/modifying ssh identity resources + */ +class SshResourceForm extends Form +{ + /** + * Initialize this form + */ + public function init() + { + $this->setName('form_config_resource_ssh'); + } + + /** + * @see Form::createElements() + */ + public function createElements(array $formData) + { + $this->addElement( + 'text', + 'name', + array( + 'required' => true, + 'label' => $this->translate('Resource Name'), + 'description' => $this->translate('The unique name of this resource') + ) + ); + $this->addElement( + 'text', + 'user', + array( + 'required' => true, + 'label' => $this->translate('User'), + 'description' => $this->translate( + 'User to log in as on the remote Icinga instance. Please note that key-based SSH login must be' + . ' possible for this user' + ) + ) + ); + + if ($this->getRequest()->getActionName() != 'editresource') { + $callbackValidator = new Zend_Validate_Callback(function ($value) { + if (substr(ltrim($value), 0, 7) === 'file://' + || openssl_pkey_get_private($value) === false + ) { + return false; + } + + return true; + }); + $callbackValidator->setMessage( + $this->translate('The given SSH key is invalid'), + Zend_Validate_Callback::INVALID_VALUE + ); + + $this->addElement( + 'textarea', + 'private_key', + array( + 'required' => true, + 'label' => $this->translate('Private Key'), + 'description' => $this->translate('The private key which will be used for the SSH connections'), + 'class' => 'resource ssh-identity', + 'validators' => array($callbackValidator) + ) + ); + } else { + $resourceName = $formData['name']; + $this->addElement( + 'note', + 'private_key_note', + array( + 'escape' => false, + 'label' => $this->translate('Private Key'), + 'value' => sprintf( + '<a href="%1$s" data-base-target="_next" title="%2$s" aria-label="%2$s">%3$s</a>', + $this->getView()->url('config/removeresource', array('resource' => $resourceName)), + $this->getView()->escape(sprintf($this->translate( + 'Remove the %s resource' + ), $resourceName)), + $this->translate('To modify the private key you must recreate this resource.') + ) + ) + ); + } + + return $this; + } + + /** + * Remove the assigned key to the resource + * + * @param ConfigObject $config + * + * @return bool + */ + public static function beforeRemove(ConfigObject $config) + { + $file = $config->private_key; + + if (file_exists($file)) { + unlink($file); + return true; + } + return false; + } + + /** + * Creates the assigned key to the resource + * + * @param ResourceConfigForm $form + * + * @return bool + */ + public static function beforeAdd(ResourceConfigForm $form) + { + $configDir = Icinga::app()->getConfigDir(); + $user = $form->getElement('user')->getValue(); + + $filePath = join(DIRECTORY_SEPARATOR, [$configDir, 'ssh', sha1($user)]); + if (! file_exists($filePath)) { + $file = File::create($filePath, 0600); + } else { + $form->error( + sprintf($form->translate('The private key for the user "%s" already exists.'), $user) + ); + return false; + } + + $file->fwrite($form->getElement('private_key')->getValue()); + + $form->getElement('private_key')->setValue($filePath); + + return true; + } +} diff --git a/application/forms/Config/ResourceConfigForm.php b/application/forms/Config/ResourceConfigForm.php new file mode 100644 index 0000000..fe12aca --- /dev/null +++ b/application/forms/Config/ResourceConfigForm.php @@ -0,0 +1,441 @@ +<?php +/* Icinga Web 2 | (c) 2014 Icinga Development Team | GPLv2+ */ + +namespace Icinga\Forms\Config; + +use Icinga\Application\Config; +use InvalidArgumentException; +use Icinga\Application\Platform; +use Icinga\Exception\ConfigurationError; +use Icinga\Data\ConfigObject; +use Icinga\Data\Inspectable; +use Icinga\Data\Inspection; +use Icinga\Data\ResourceFactory; +use Icinga\Forms\ConfigForm; +use Icinga\Forms\Config\Resource\DbResourceForm; +use Icinga\Forms\Config\Resource\FileResourceForm; +use Icinga\Forms\Config\Resource\LdapResourceForm; +use Icinga\Forms\Config\Resource\SshResourceForm; +use Icinga\Web\Form; +use Icinga\Web\Notification; + +class ResourceConfigForm extends ConfigForm +{ + /** + * Bogus password when inspecting password elements + * + * @var string + */ + protected static $dummyPassword = '_web_form_5847ed1b5b8ca'; + + /** + * If the global config must be updated because a resource has been changed, this is the updated global config + * + * @var Config|null + */ + protected $updatedAppConfig = null; + + /** + * Initialize this form + */ + public function init() + { + $this->setName('form_config_resource'); + $this->setSubmitLabel($this->translate('Save Changes')); + $this->setValidatePartial(true); + } + + /** + * 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 === 'file') { + return new FileResourceForm(); + } elseif ($type === 'ssh') { + return new SshResourceForm(); + } else { + throw new InvalidArgumentException(sprintf($this->translate('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 $this + * + * @throws InvalidArgumentException In case the resource does already exist + */ + public function add(array $values) + { + $name = isset($values['name']) ? $values['name'] : ''; + if (! $name) { + throw new InvalidArgumentException($this->translate('Resource name missing')); + } elseif ($this->config->hasSection($name)) { + throw new InvalidArgumentException($this->translate('Resource already exists')); + } + + unset($values['name']); + $this->config->setSection($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($this->translate('Old resource name missing')); + } elseif (! ($newName = isset($values['name']) ? $values['name'] : '')) { + throw new InvalidArgumentException($this->translate('New resource name missing')); + } elseif (! $this->config->hasSection($name)) { + throw new InvalidArgumentException($this->translate('Unknown resource provided')); + } + + $resourceConfig = $this->config->getSection($name); + $this->config->removeSection($name); + unset($values['name']); + $this->config->setSection($newName, $resourceConfig->merge($values)); + + if ($newName !== $name) { + $appConfig = Config::app(); + $section = $appConfig->getSection('global'); + if ($section->config_resource === $name) { + $section->config_resource = $newName; + $this->updatedAppConfig = $appConfig->setSection('global', $section); + } + } + + return $resourceConfig; + } + + /** + * 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($this->translate('Resource name missing')); + } elseif (! $this->config->hasSection($name)) { + throw new InvalidArgumentException($this->translate('Unknown resource provided')); + } + + $resourceConfig = $this->config->getSection($name); + $resourceForm = $this->getResourceForm($resourceConfig->type); + if (method_exists($resourceForm, 'beforeRemove')) { + $resourceForm::beforeRemove($resourceConfig); + } + + $this->config->removeSection($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() + { + $resourceForm = $this->getResourceForm($this->getElement('type')->getValue()); + + if (($el = $this->getElement('force_creation')) === null || false === $el->isChecked()) { + $inspection = static::inspectResource($this); + if ($inspection !== null && $inspection->hasError()) { + $this->error($inspection->getError()); + $this->addElement($this->getForceCreationCheckbox()); + return false; + } + } + + $resource = $this->request->getQuery('resource'); + try { + if ($resource === null) { // create new resource + if (method_exists($resourceForm, 'beforeAdd')) { + if (! $resourceForm::beforeAdd($this)) { + return false; + } + } + $this->add(static::transformEmptyValuesToNull($this->getValues())); + $message = $this->translate('Resource "%s" has been successfully created'); + } else { // edit existing resource + $this->edit($resource, static::transformEmptyValuesToNull($this->getValues())); + $message = $this->translate('Resource "%s" has been successfully changed'); + } + } catch (InvalidArgumentException $e) { + Notification::error($e->getMessage()); + return false; + } + + 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() + { + $resource = $this->request->getQuery('resource'); + if ($resource !== null) { + if ($resource === '') { + throw new ConfigurationError($this->translate('Resource name missing')); + } elseif (! $this->config->hasSection($resource)) { + throw new ConfigurationError($this->translate('Unknown resource provided')); + } + $configValues = $this->config->getSection($resource)->toArray(); + $configValues['name'] = $resource; + $this->populate($configValues); + foreach ($this->getElements() as $element) { + if ($element->getType() === 'Zend_Form_Element_Password' && strlen($element->getValue())) { + $element->setValue(static::$dummyPassword); + } + } + } + } + + /** + * 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' => $this->translate('Force Changes'), + 'description' => $this->translate('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' => $this->translate('File'), + 'ssh' => $this->translate('SSH Identity'), + ); + if ($resourceType === 'ldap' || Platform::hasLdapSupport()) { + $resourceTypes['ldap'] = 'LDAP'; + } + if ($resourceType === 'db' || Platform::hasDatabaseSupport()) { + $resourceTypes['db'] = $this->translate('SQL Database'); + } + + $this->addElement( + 'select', + 'type', + array( + 'required' => true, + 'autosubmit' => true, + 'label' => $this->translate('Resource Type'), + 'description' => $this->translate('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 + $this->addElement($this->getForceCreationCheckbox()); + } + + $this->addElements($this->getResourceForm($resourceType)->createElements($formData)->getElements()); + } + + /** + * Create a resource by using the given form's values and return its inspection results + * + * @param Form $form + * + * @return Inspection + */ + public static function inspectResource(Form $form) + { + if ($form->getValue('type') !== 'ssh') { + $resource = ResourceFactory::createResource(new ConfigObject($form->getValues())); + if ($resource instanceof Inspectable) { + return $resource->inspect(); + } + } + } + + /** + * Run the configured resource's inspection checks and show the result, if necessary + * + * This will only run any validation if the user pushed the 'resource_validation' button. + * + * @param array $formData + * + * @return bool + */ + public function isValidPartial(array $formData) + { + if ($this->getElement('resource_validation')->isChecked() && parent::isValid($formData)) { + $inspection = static::inspectResource($this); + if ($inspection !== null) { + $join = function ($e) use (&$join) { + return is_array($e) ? join("\n", array_map($join, $e)) : $e; + }; + $this->addElement( + 'note', + 'inspection_output', + array( + 'order' => 0, + 'value' => '<strong>' . $this->translate('Validation Log') . "</strong>\n\n" + . join("\n", array_map($join, $inspection->toArray())), + 'decorators' => array( + 'ViewHelper', + array('HtmlTag', array('tag' => 'pre', 'class' => 'log-output')), + ) + ) + ); + + if ($inspection->hasError()) { + $this->warning(sprintf( + $this->translate('Failed to successfully validate the configuration: %s'), + $inspection->getError() + )); + return false; + } + } + + $this->info($this->translate('The configuration has been successfully validated.')); + } + + return true; + } + + /** + * Add a submit button to this form and one to manually validate the configuration + * + * Calls parent::addSubmitButton() to add the submit button. + * + * @return $this + */ + public function addSubmitButton() + { + parent::addSubmitButton() + ->getElement('btn_submit') + ->setDecorators(array('ViewHelper')); + + $this->addElement( + 'submit', + 'resource_validation', + array( + 'ignore' => true, + 'label' => $this->translate('Validate Configuration'), + 'data-progress-label' => $this->translate('Validation In Progress'), + 'decorators' => array('ViewHelper') + ) + ); + + $this->setAttrib('data-progress-element', 'resource-progress'); + $this->addElement( + 'note', + 'resource-progress', + array( + 'decorators' => array( + 'ViewHelper', + array('Spinner', array('id' => 'resource-progress')) + ) + ) + ); + + $this->addDisplayGroup( + array('btn_submit', 'resource_validation', 'resource-progress'), + 'submit_validation', + array( + 'decorators' => array( + 'FormElements', + array('HtmlTag', array('tag' => 'div', 'class' => 'control-group form-controls')) + ) + ) + ); + + return $this; + } + + /** + * {@inheritdoc} + */ + public function getValues($suppressArrayNotation = false) + { + $values = parent::getValues($suppressArrayNotation); + $resource = $this->request->getQuery('resource'); + if ($resource !== null && $this->config->hasSection($resource)) { + $resourceConfig = $this->config->getSection($resource)->toArray(); + foreach ($this->getElements() as $element) { + if ($element->getType() === 'Zend_Form_Element_Password') { + $name = $element->getName(); + if (isset($values[$name]) && $values[$name] === static::$dummyPassword) { + if (isset($resourceConfig[$name])) { + $values[$name] = $resourceConfig[$name]; + } else { + unset($values[$name]); + } + } + } + } + } + + return $values; + } + + /** + * {@inheritDoc} + */ + protected function writeConfig(Config $config) + { + parent::writeConfig($config); + if ($this->updatedAppConfig !== null) { + $this->updatedAppConfig->saveIni(); + } + } +} |