summaryrefslogtreecommitdiffstats
path: root/library/Icinga/Application/Hook/ConfigFormEventsHook.php
blob: 05fa05d71b222761c2ab0903cd602210fe89f0db (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
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\Web\Form;

/**
 * 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 Form $form
     *
     * @return bool
     */
    public function appliesTo(Form $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 Form $form
     *
     * @throws \Exception If either the form is not valid or to interrupt the form handling
     */
    public function isValid(Form $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 Form $form
     */
    public function onSuccess(Form $form)
    {
    }

    /**
     * Get an array of errors found while processing the form event hooks
     *
     * @return array
     */
    final public static function getLastErrors()
    {
        return self::$lastErrors;
    }

    /**
     * Run all isValid hooks
     *
     * @param Form $form
     *
     * @return bool Returns false if any hook threw an exception
     */
    final public static function runIsValid(Form $form)
    {
        return self::runEventMethod('isValid', $form);
    }

    /**
     * Run all onSuccess hooks
     *
     * @param Form $form
     *
     * @return bool Returns false if any hook threw an exception
     */
    final public static function runOnSuccess(Form $form)
    {
        return self::runEventMethod('onSuccess', $form);
    }

    private static function runEventMethod($eventMethod, Form $form)
    {
        self::$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) {
                self::$lastErrors[] = $e->getMessage();

                Logger::error("%s\n%s", $e, IcingaException::getConfidentialTraceAsString($e));

                $success = false;
            }
        }

        return $success;
    }

    private function runAppliesTo(Form $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;
    }
}