Merge pull request #3862 from Icinga/feature/config-form-events-hook-3768
Provide ConfigFormEventsHook
This commit is contained in:
commit
0a55df0fcf
|
@ -4,9 +4,10 @@
|
|||
namespace Icinga\Forms;
|
||||
|
||||
use Exception;
|
||||
use Icinga\Exception\ConfigurationError;
|
||||
use Zend_Form_Decorator_Abstract;
|
||||
use Icinga\Application\Config;
|
||||
use Icinga\Application\Hook\ConfigFormEventsHook;
|
||||
use Icinga\Exception\ConfigurationError;
|
||||
use Icinga\Web\Form;
|
||||
use Icinga\Web\Notification;
|
||||
|
||||
|
@ -52,9 +53,21 @@ class ConfigForm extends Form
|
|||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isValid($formData)
|
||||
{
|
||||
$valid = parent::isValid($formData);
|
||||
|
||||
if ($valid && ConfigFormEventsHook::runIsValid($this) === false) {
|
||||
foreach (ConfigFormEventsHook::getLastErrors() as $msg) {
|
||||
$this->error($msg);
|
||||
}
|
||||
|
||||
$valid = false;
|
||||
}
|
||||
|
||||
return $valid;
|
||||
}
|
||||
|
||||
public function onSuccess()
|
||||
{
|
||||
$sections = array();
|
||||
|
@ -72,11 +85,15 @@ class ConfigForm extends Form
|
|||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ConfigFormEventsHook::runOnSuccess($this) === false) {
|
||||
Notification::error($this->translate(
|
||||
'Configuration successfully stored. Though, one or more module hooks failed to run.'
|
||||
. ' See logs for details'
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function onRequest()
|
||||
{
|
||||
$values = array();
|
||||
|
|
Binary file not shown.
|
@ -1,5 +1,5 @@
|
|||
# Icinga Web 2 - Head for multiple monitoring backends.
|
||||
# Copyright (C) 2018 Icinga Development Team
|
||||
# Copyright (C) 2019 Icinga Development Team
|
||||
# This file is distributed under the same license as Icinga Web 2.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
|
@ -7,8 +7,8 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: Icinga Web 2 (None)\n"
|
||||
"Report-Msgid-Bugs-To: dev@icinga.com\n"
|
||||
"POT-Creation-Date: 2018-07-11 14:17+0000\n"
|
||||
"PO-Revision-Date: 2018-07-11 16:30+0200\n"
|
||||
"POT-Creation-Date: 2019-07-12 12:08-0700\n"
|
||||
"PO-Revision-Date: 2019-07-12 14:10+0200\n"
|
||||
"Last-Translator: Markus Frosch <markus.frosch@icinga.com>\n"
|
||||
"Language: de_DE\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
@ -17,7 +17,7 @@ msgstr ""
|
|||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Poedit-Basepath: .\n"
|
||||
"Language-Team: \n"
|
||||
"X-Generator: Poedit 2.0.6\n"
|
||||
"X-Generator: Poedit 2.2.3\n"
|
||||
"X-Poedit-SearchPath-0: .\n"
|
||||
|
||||
#: ../../../../library/Icinga/Web/Form/Validator/InArray.php:16
|
||||
|
@ -534,6 +534,14 @@ msgstr "Komma separierte Liste von Nutzern, die dieser Rolle zugewiesen werden"
|
|||
msgid "Configuration"
|
||||
msgstr "Konfiguration"
|
||||
|
||||
#: ../../../../application/forms/ConfigForm.php:89
|
||||
msgid ""
|
||||
"Configuration successfully stored. Though, one or more module hooks failed "
|
||||
"to run. See logs for details"
|
||||
msgstr ""
|
||||
"Konfiguration erfolgreich gespeichert. Es sind jedoch einer oder mehrere "
|
||||
"Modul-Hooks fehlgeschlagen. Bitte die Logs prüfen"
|
||||
|
||||
#: ../../../../application/controllers/RoleController.php:155
|
||||
#: ../../../../application/controllers/UserController.php:320
|
||||
#: ../../../../application/controllers/GroupController.php:369
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
# Hooks
|
||||
|
||||
## ConfigFormEventsHook
|
||||
|
||||
The `ConfigFormEventsHook` allows developers to hook into the handling of configuration forms. It provides three methods:
|
||||
|
||||
* `appliesTo()`
|
||||
* `isValid()`
|
||||
* `onSuccess()`
|
||||
|
||||
`appliesTo()` determines whether the hook should run for a given configuration form.
|
||||
Developers should use `instanceof` checks in order to decide whether the hook should run or not.
|
||||
If `appliesTo()` returns `false`, `isValid()` and `onSuccess()` won't get called for this hook.
|
||||
|
||||
`isValid()` is called after the configuration form has been validated successfully.
|
||||
An exception thrown here indicates form errors and prevents the config from being stored.
|
||||
The exception's error message is shown in the frontend automatically.
|
||||
If there are multiple hooks indicating errors, every error will be displayed.
|
||||
|
||||
`onSuccess()` is called after the configuration has been stored successfully.
|
||||
Form handling can't be interrupted here. Any exception will be caught, logged and notified.
|
||||
|
||||
Hook example:
|
||||
|
||||
```php
|
||||
namespace Icinga\Module\Acme\ProvidedHook;
|
||||
|
||||
use Icinga\Application\Hook\ConfigFormEventsHook;
|
||||
use Icinga\Forms\ConfigForm;
|
||||
use Icinga\Forms\Security\RoleForm;
|
||||
|
||||
class ConfigFormEvents extends ConfigFormEventsHook
|
||||
{
|
||||
public function appliesTo(ConfigForm $form)
|
||||
{
|
||||
return $form instanceof RoleForm;
|
||||
}
|
||||
|
||||
public function onSuccess(ConfigForm $form)
|
||||
{
|
||||
$this->updateMyModuleConfig();
|
||||
}
|
||||
|
||||
protected function updateMyModuleConfig()
|
||||
{
|
||||
// ...
|
||||
}
|
||||
}
|
||||
```
|
|
@ -0,0 +1,137 @@
|
|||
<?php
|
||||
/* Icinga Web 2 | (c) 2019 Icinga GmbH | GPLv2+ */
|
||||
|
||||
namespace Icinga\Application\Hook;
|
||||
|
||||
use Icinga\Application\Hook;
|
||||
use Icinga\Application\Logger;
|
||||
use Icinga\Exception\IcingaException;
|
||||
use Icinga\Forms\ConfigForm;
|
||||
|
||||
/**
|
||||
* Base class for config form event hooks
|
||||
*/
|
||||
abstract class ConfigFormEventsHook
|
||||
{
|
||||
/** @var array Array of errors found while processing the form event hooks */
|
||||
private static $lastErrors = [];
|
||||
|
||||
/**
|
||||
* Get whether the hook applies to the given config form
|
||||
*
|
||||
* @param ConfigForm $form
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function appliesTo(ConfigForm $form)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* isValid event hook
|
||||
*
|
||||
* Implement this method in order to run code after the form has been validated successfully.
|
||||
* Throw an exception here if either the form is not valid or you want interrupt the form handling.
|
||||
* The exception's message will be automatically added as form error message so that it will be
|
||||
* displayed in the frontend.
|
||||
*
|
||||
* @param ConfigForm $form
|
||||
*
|
||||
* @throws \Exception If either the form is not valid or to interrupt the form handling
|
||||
*/
|
||||
public function isValid(ConfigForm $form)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* onSuccess event hook
|
||||
*
|
||||
* Implement this method in order to run code after the configuration form has been stored successfully.
|
||||
* You can't interrupt the form handling here. Any exception will be caught, logged and notified.
|
||||
*
|
||||
* @param ConfigForm $form
|
||||
*/
|
||||
public function onSuccess(ConfigForm $form)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array of errors found while processing the form event hooks
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
final public static function getLastErrors()
|
||||
{
|
||||
return static::$lastErrors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run all isValid hooks
|
||||
*
|
||||
* @param ConfigForm $form
|
||||
*
|
||||
* @return bool Returns false if any hook threw an exception
|
||||
*/
|
||||
final public static function runIsValid(ConfigForm $form)
|
||||
{
|
||||
return self::runEventMethod('isValid', $form);
|
||||
}
|
||||
|
||||
/**
|
||||
* Run all onSuccess hooks
|
||||
*
|
||||
* @param ConfigForm $form
|
||||
*
|
||||
* @return bool Returns false if any hook threw an exception
|
||||
*/
|
||||
final public static function runOnSuccess(ConfigForm $form)
|
||||
{
|
||||
return self::runEventMethod('onSuccess', $form);
|
||||
}
|
||||
|
||||
private static function runEventMethod($eventMethod, ConfigForm $form)
|
||||
{
|
||||
static::$lastErrors = [];
|
||||
|
||||
if (! Hook::has('ConfigFormEvents')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$success = true;
|
||||
|
||||
foreach (Hook::all('ConfigFormEvents') as $hook) {
|
||||
/** @var self $hook */
|
||||
if (! $hook->runAppliesTo($form)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
$hook->$eventMethod($form);
|
||||
} catch (\Exception $e) {
|
||||
static::$lastErrors[] = $e->getMessage();
|
||||
|
||||
Logger::error("%s\n%s", $e, IcingaException::getConfidentialTraceAsString($e));
|
||||
|
||||
$success = false;
|
||||
}
|
||||
}
|
||||
|
||||
return $success;
|
||||
}
|
||||
|
||||
private function runAppliesTo(ConfigForm $form)
|
||||
{
|
||||
try {
|
||||
$appliesTo = $this->appliesTo($form);
|
||||
} catch (\Exception $e) {
|
||||
// Don't save exception to last errors because we do not want to disturb the user for messed up
|
||||
// appliesTo checks
|
||||
Logger::error("%s\n%s", $e, IcingaException::getConfidentialTraceAsString($e));
|
||||
|
||||
$appliesTo = false;
|
||||
}
|
||||
|
||||
return $appliesTo === true;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue