7
7
use Icinga \Module \Notifications \Common \Auth ;
8
8
use Icinga \Module \Notifications \Common \Database ;
9
9
use Icinga \Module \Notifications \Common \Links ;
10
+ use Icinga \Module \Notifications \Forms \EventRuleConfigForm ;
10
11
use Icinga \Module \Notifications \Forms \EventRuleForm ;
11
- use Icinga \Module \Notifications \Forms \SaveEventRuleForm ;
12
12
use Icinga \Module \Notifications \Model \Incident ;
13
- use Icinga \Module \Notifications \Model \ObjectExtraTag ;
14
13
use Icinga \Module \Notifications \Model \Rule ;
15
14
use Icinga \Module \Notifications \Web \Control \SearchBar \ExtraTagSuggestions ;
16
- use Icinga \Module \Notifications \Widget \ EventRuleConfig ;
15
+ use Icinga \Module \Notifications \Web \ Form \ EventRuleDecorator ;
17
16
use Icinga \Web \Notification ;
18
17
use Icinga \Web \Session ;
18
+ use ipl \Html \Attributes ;
19
19
use ipl \Html \Form ;
20
+ use ipl \Html \FormElement \ButtonElement ;
21
+ use ipl \Html \FormElement \SubmitButtonElement ;
20
22
use ipl \Html \Html ;
23
+ use ipl \Html \HtmlElement ;
21
24
use ipl \Stdlib \Filter ;
22
25
use ipl \Web \Compat \CompatController ;
23
26
use ipl \Web \Control \SearchEditor ;
27
+ use ipl \Web \Filter \QueryString ;
24
28
use ipl \Web \Url ;
25
29
use ipl \Web \Widget \Icon ;
26
30
use ipl \Web \Widget \Link ;
@@ -32,6 +36,9 @@ class EventRuleController extends CompatController
32
36
/** @var Session\SessionNamespace */
33
37
private $ sessionNamespace ;
34
38
39
+ /** @var ?string Event rule config filter */
40
+ protected $ filter ;
41
+
35
42
public function init ()
36
43
{
37
44
$ this ->sessionNamespace = Session::getSession ()->getNamespace ('notifications ' );
@@ -42,71 +49,105 @@ public function indexAction(): void
42
49
$ this ->assertPermission ('notifications/config/event-rules ' );
43
50
44
51
$ this ->addTitleTab (t ('Event Rule ' ));
45
-
46
52
$ this ->controls ->addAttributes (['class ' => 'event-rule-detail ' ]);
47
53
54
+ /** @var int $ruleId */
48
55
$ ruleId = $ this ->params ->getRequired ('id ' );
56
+ /** @var array<string, mixed>|null $config */
57
+ $ config = $ this ->sessionNamespace ->get ((string ) $ ruleId );
58
+ $ this ->controls ->addAttributes (['class ' => 'event-rule-detail ' ]);
49
59
50
- $ cache = $ this ->sessionNamespace ->get ($ ruleId );
60
+ $ discardChangesButton = null ;
61
+ if ($ config === null ) {
62
+ $ config = $ this ->fromDb ($ ruleId );
63
+ }
64
+
65
+ $ eventRuleConfig = (new EventRuleConfigForm (
66
+ $ config ,
67
+ Url::fromPath (
68
+ 'notifications/event-rule/search-editor ' ,
69
+ ['id ' => $ config ['id ' ]]
70
+ )
71
+ ))->populate ($ config );
72
+ $ eventRuleConfig
73
+ ->on (Form::ON_SUCCESS , function (EventRuleConfigForm $ form ) use ($ config ) {
74
+ /** @var string $ruleId */
75
+ $ ruleId = $ config ['id ' ];
76
+ $ form ->insertOrAddRule ($ ruleId , $ config );
77
+ $ this ->sessionNamespace ->delete ($ ruleId );
78
+ Notification::success ((sprintf (t ('Successfully saved event rule %s ' ), $ config ['name ' ])));
51
79
52
- if ($ cache ) {
80
+ $ this ->sendExtraUpdates (['#col1 ' ]);
81
+ $ this ->redirectNow (Links::eventRule ((int ) $ ruleId ));
82
+ })
83
+ ->on (EventRuleConfigForm::ON_DELETE , function (EventRuleConfigForm $ form ) use ($ config ) {
84
+ $ ruleId = $ config ['id ' ];
85
+ $ form ->removeRule ($ ruleId );
86
+ $ this ->sessionNamespace ->delete ($ ruleId );
87
+ Notification::success (sprintf (t ('Successfully deleted event rule %s ' ), $ config ['name ' ]));
88
+ $ this ->redirectNow ('__CLOSE__ ' );
89
+ })
90
+ ->on (EventRuleConfigForm::ON_DISCARD , function () use ($ config ) {
91
+ $ ruleId = $ config ['id ' ];
92
+ $ this ->sessionNamespace ->delete ($ ruleId );
93
+ Notification::success (sprintf (t ('Successfully discarded changes to event rule %s ' ), $ config ['name ' ]));
94
+ $ this ->redirectNow (Links::eventRule ((int ) $ ruleId ));
95
+ })
96
+ ->on (EventRuleConfigForm::ON_CHANGE , function (EventRuleConfigForm $ form ) use ($ config ) {
97
+ $ config = array_merge ($ config , $ form ->getValues ());
98
+ $ this ->sessionNamespace ->set ($ config ['id ' ], $ config );
99
+ })
100
+ ->handleRequest ($ this ->getServerRequest ());
101
+
102
+ $ cache = $ this ->sessionNamespace ->get ((string ) $ ruleId );
103
+ if ($ cache !== null ) {
53
104
$ this ->addContent (Html::tag ('div ' , ['class ' => 'cache-notice ' ], t ('There are unsaved changes. ' )));
54
- $ eventRuleConfig = new EventRuleConfig (
55
- Url:: fromPath ( ' notifications/event-rule/search-editor ' , [ ' id ' => $ ruleId ]) ,
56
- $ cache
57
- );
58
- } else {
59
- $ eventRuleConfig = new EventRuleConfig (
60
- Url:: fromPath ( ' notifications/event-rule/search-editor ' , [ ' id ' => $ ruleId ]) ,
61
- $ this -> fromDb ( $ ruleId )
62
- );
105
+ $ discardChangesButton = ( new SubmitButtonElement (
106
+ ' discard_changes ' ,
107
+ [
108
+ ' label ' => t ( ' Discard Changes ' ),
109
+ ' form ' => ' event-rule-config-form ' ,
110
+ ' class ' => ' btn-discard-changes ' ,
111
+ ' formnovalidate ' => true ,
112
+ ]
113
+ )) ;
63
114
}
64
115
65
- $ disableRemoveButton = false ;
66
- if (ctype_digit ($ ruleId )) {
116
+
117
+ $ buttonsWrapper = new HtmlElement ('div ' , Attributes::create (['class ' => ['icinga-controls ' , 'save-config ' ]]));
118
+ $ eventRuleConfigSubmitButton = (new SubmitButtonElement (
119
+ 'save ' ,
120
+ [
121
+ 'label ' => t ('Save ' ),
122
+ 'form ' => 'event-rule-config-form '
123
+ ]
124
+ ));
125
+ $ deleteButton = (new SubmitButtonElement (
126
+ 'delete ' ,
127
+ [
128
+ 'label ' => t ('Delete ' ),
129
+ 'form ' => 'event-rule-config-form ' ,
130
+ 'class ' => 'btn-remove ' ,
131
+ 'formnovalidate ' => true
132
+ ]
133
+ ));
134
+
135
+ $ buttonsWrapper ->add (
136
+ [$ eventRuleConfigSubmitButton , $ discardChangesButton , $ deleteButton ]
137
+ );
138
+
139
+ if ($ ruleId > 0 ) {
67
140
$ incidents = Incident::on (Database::get ())
68
141
->with ('rule ' )
69
142
->filter (Filter::equal ('rule.id ' , $ ruleId ));
70
143
71
144
if ($ incidents ->count () > 0 ) {
72
- $ disableRemoveButton = true ;
145
+ $ deleteButton -> addAttributes ([ ' disabled ' => true ]) ;
73
146
}
74
147
}
75
148
76
- $ saveForm = (new SaveEventRuleForm ())
77
- ->setShowRemoveButton ()
78
- ->setShowDismissChangesButton ($ cache !== null )
79
- ->setRemoveButtonDisabled ($ disableRemoveButton )
80
- ->setSubmitButtonDisabled ($ cache === null )
81
- ->setSubmitLabel ($ this ->translate ('Save Changes ' ))
82
- ->on (SaveEventRuleForm::ON_SUCCESS , function ($ form ) use ($ ruleId , $ eventRuleConfig ) {
83
- if ($ form ->getPressedSubmitElement ()->getName () === 'discard_changes ' ) {
84
- $ this ->sessionNamespace ->delete ($ ruleId );
85
- Notification::success ($ this ->translate ('Successfully discarded the pending changes. ' ));
86
- $ this ->redirectNow (Links::eventRule ($ ruleId ));
87
- }
88
-
89
- if (! $ eventRuleConfig ->isValid ()) {
90
- $ eventRuleConfig ->addAttributes (['class ' => 'invalid ' ]);
91
- return ;
92
- }
93
-
94
- $ form ->editRule ($ ruleId , $ this ->sessionNamespace ->get ($ ruleId ));
95
- $ this ->sessionNamespace ->delete ($ ruleId );
96
-
97
- Notification::success ($ this ->translate ('Successfully updated rule. ' ));
98
- $ this ->sendExtraUpdates (['#col1 ' ]);
99
- $ this ->redirectNow (Links::eventRule ($ ruleId ));
100
- })->on (SaveEventRuleForm::ON_REMOVE , function ($ form ) use ($ ruleId ) {
101
- $ form ->removeRule ($ ruleId );
102
- $ this ->sessionNamespace ->delete ($ ruleId );
103
-
104
- Notification::success ($ this ->translate ('Successfully removed rule. ' ));
105
- $ this ->redirectNow ('__CLOSE__ ' );
106
- })->handleRequest ($ this ->getServerRequest ());
107
-
108
149
$ eventRuleForm = Html::tag ('div ' , ['class ' => 'event-rule-form ' ], [
109
- Html::tag ('h2 ' , $ eventRuleConfig -> getConfig () ['name ' ] ?? '' ),
150
+ Html::tag ('h2 ' , $ config ['name ' ] ?? '' ),
110
151
(new Link (
111
152
new Icon ('edit ' ),
112
153
Url::fromPath ('notifications/event-rule/edit ' , [
@@ -115,30 +156,9 @@ public function indexAction(): void
115
156
['class ' => 'control-button ' ]
116
157
))->openInModal ()
117
158
]);
159
+ $ this ->addControl ($ eventRuleForm );
118
160
119
- $ eventRuleFormAndSave = Html::tag ('div ' , ['class ' => 'event-rule-and-save-forms ' ]);
120
- $ eventRuleFormAndSave ->add ([
121
- $ eventRuleForm ,
122
- $ saveForm
123
- ]);
124
-
125
- $ eventRuleConfig
126
- ->on (EventRuleConfig::ON_CHANGE , function ($ eventRuleConfig ) use ($ ruleId , $ saveForm ) {
127
- $ this ->sessionNamespace ->set ($ ruleId , $ eventRuleConfig ->getConfig ());
128
- $ saveForm ->setSubmitButtonDisabled (false );
129
- $ this ->redirectNow (Links::eventRule ($ ruleId ));
130
- });
131
-
132
- foreach ($ eventRuleConfig ->getForms () as $ form ) {
133
- $ form ->handleRequest ($ this ->getServerRequest ());
134
-
135
- if (! $ form ->hasBeenSent ()) {
136
- // Force validation of populated values in case we display an unsaved rule
137
- $ form ->validatePartial ();
138
- }
139
- }
140
-
141
- $ this ->addControl ($ eventRuleFormAndSave );
161
+ $ this ->addControl ($ buttonsWrapper );
142
162
$ this ->addContent ($ eventRuleConfig );
143
163
}
144
164
@@ -167,7 +187,7 @@ public function fromDb(int $ruleId): array
167
187
}
168
188
169
189
foreach ($ re ->rule_escalation_recipient as $ recipient ) {
170
- $ config [$ re ->getTableName ()][$ re ->position ]['recipient ' ][] = iterator_to_array ($ recipient );
190
+ $ config [$ re ->getTableName ()][$ re ->position ]['recipients ' ][] = iterator_to_array ($ recipient );
171
191
}
172
192
}
173
193
@@ -188,7 +208,6 @@ public function completeAction(): void
188
208
$ this ->getDocument ()->add ($ suggestions );
189
209
}
190
210
191
-
192
211
/**
193
212
* searchEditorAction for Object Extra Tags
194
213
*
@@ -198,16 +217,29 @@ public function completeAction(): void
198
217
*/
199
218
public function searchEditorAction (): void
200
219
{
220
+ /** @var string $ruleId */
201
221
$ ruleId = $ this ->params ->shiftRequired ('id ' );
202
222
203
- $ eventRule = $ this ->sessionNamespace ->get ($ ruleId ) ?? $ this -> fromDb ( $ ruleId ) ;
223
+ $ eventRule = $ this ->sessionNamespace ->get ($ ruleId );
204
224
205
- $ editor = EventRuleConfig::createSearchEditor ()
206
- ->setQueryString ($ eventRule ['object_filter ' ] ?? '' );
225
+ if ($ eventRule === null ) {
226
+ $ eventRule = $ this ->fromDb ((int ) $ ruleId );
227
+ }
207
228
208
- $ editor ->on (SearchEditor::ON_SUCCESS , function (SearchEditor $ form ) use ($ ruleId , $ eventRule ) {
209
- $ eventRule ['object_filter ' ] = EventRuleConfig::createFilterString ($ form ->getFilter ());
229
+ $ editor = new SearchEditor ();
210
230
231
+ /** @var string $objectFilter */
232
+ $ objectFilter = $ eventRule ['object_filter ' ] ?? '' ;
233
+ $ editor ->setQueryString ($ objectFilter );
234
+ $ editor ->setAction (Url::fromRequest ()->getAbsoluteUrl ());
235
+ $ editor ->setSuggestionUrl (Url::fromPath (
236
+ "notifications/event-rule/complete " ,
237
+ ['_disableLayout ' => true , 'showCompact ' => true , 'id ' => Url::fromRequest ()->getParams ()->get ('id ' )]
238
+ ));
239
+
240
+ $ editor ->on (SearchEditor::ON_SUCCESS , function (SearchEditor $ form ) use ($ ruleId , $ eventRule ) {
241
+ $ filter = self ::createFilterString ($ form ->getFilter ());
242
+ $ eventRule ['object_filter ' ] = $ filter ;
211
243
$ this ->sessionNamespace ->set ($ ruleId , $ eventRule );
212
244
$ this ->getResponse ()
213
245
->setHeader ('X-Icinga-Container ' , '_self ' )
@@ -225,48 +257,60 @@ public function searchEditorAction(): void
225
257
$ this ->setTitle ($ this ->translate ('Adjust Filter ' ));
226
258
}
227
259
260
+ /**
261
+ * Create filter string from the given filter rule
262
+ *
263
+ * @param Filter\Rule $filters
264
+ *
265
+ * @return string
266
+ */
267
+ public static function createFilterString (Filter \Rule $ filters ): string
268
+ {
269
+ if ($ filters instanceof Filter \Chain) {
270
+ foreach ($ filters as $ filter ) {
271
+ self ::createFilterString ($ filter );
272
+ }
273
+ } elseif ($ filters instanceof Filter \Condition && empty ($ filters ->getValue ())) {
274
+ $ filters ->setValue (true );
275
+ }
276
+
277
+ $ filterStr = QueryString::render ($ filters );
278
+
279
+ return ! empty ($ filterStr ) ? $ filterStr : '' ;
280
+ }
281
+
228
282
public function editAction (): void
229
283
{
230
284
/** @var string $ruleId */
231
285
$ ruleId = $ this ->params ->getRequired ('id ' );
232
- /** @var ?array<string, mixed> $cache */
233
- $ cache = $ this ->sessionNamespace ->get ($ ruleId );
234
-
235
- if ($ this ->params ->has ('clearCache ' )) {
236
- $ this ->sessionNamespace ->delete ($ ruleId );
237
- $ cache = [];
238
- }
239
286
240
- if (isset ( $ cache ) || $ ruleId === '-1 ' ) {
241
- $ config = $ cache ?? [ ];
287
+ if ($ ruleId === '-1 ' ) {
288
+ $ config = [ ' id ' => $ ruleId ];
242
289
} else {
243
290
$ config = $ this ->fromDb ((int ) $ ruleId );
244
291
}
245
292
246
293
$ eventRuleForm = (new EventRuleForm ())
247
294
->populate ($ config )
248
295
->setAction (Url::fromRequest ()->getAbsoluteUrl ())
249
- ->on (Form::ON_SUCCESS , function ($ form ) use ($ ruleId , $ cache , $ config ) {
296
+ ->on (Form::ON_SUCCESS , function ($ form ) use ($ ruleId , $ config ) {
250
297
$ config ['name ' ] = $ form ->getValue ('name ' );
251
298
$ config ['is_active ' ] = $ form ->getValue ('is_active ' );
252
-
253
- if ($ cache || $ ruleId === '-1 ' ) {
254
- $ this -> sessionNamespace -> set ( $ ruleId , $ config) ;
299
+ $ params = [];
300
+ if ($ ruleId === '-1 ' ) {
301
+ $ params = $ config ;
255
302
} else {
256
- ( new SaveEventRuleForm ())-> editRule (( int ) $ ruleId, $ config ) ;
303
+ $ params [ ' id ' ] = $ ruleId ;
257
304
}
258
305
259
306
if ($ ruleId === '-1 ' ) {
260
- $ redirectUrl = Url::fromPath ('notifications/event-rules/add ' , [
261
- 'use_cache ' => true
262
- ]);
307
+ $ redirectUrl = Url::fromPath ('notifications/event-rules/add ' , $ params );
263
308
} else {
264
- $ redirectUrl = Url::fromPath ('notifications/event-rule ' , [
265
- 'id ' => $ ruleId
266
- ]);
309
+ $ redirectUrl = Url::fromPath ('notifications/event-rule ' , $ params );
267
310
$ this ->sendExtraUpdates (['#col1 ' ]);
268
311
}
269
312
313
+ $ this ->sessionNamespace ->set ($ ruleId , $ config );
270
314
$ this ->getResponse ()->setHeader ('X-Icinga-Container ' , 'col2 ' );
271
315
$ this ->redirectNow ($ redirectUrl );
272
316
})->handleRequest ($ this ->getServerRequest ());
0 commit comments