1111use Icinga \Module \Notifications \Model \RuleEscalationRecipient ;
1212use Icinga \Module \Notifications \Model \Schedule ;
1313use Icinga \Web \Session ;
14+ use IntlTimeZone ;
1415use ipl \Html \Attributes ;
1516use ipl \Html \HtmlDocument ;
1617use ipl \Html \HtmlElement ;
1718use ipl \Html \Text ;
1819use ipl \Sql \Connection ;
1920use ipl \Stdlib \Filter ;
21+ use ipl \Validator \CallbackValidator ;
2022use ipl \Web \Common \CsrfCounterMeasure ;
2123use ipl \Web \Compat \CompatForm ;
24+ use ipl \Web \Url ;
25+ use Throwable ;
2226
2327class ScheduleForm extends CompatForm
2428{
@@ -31,7 +35,7 @@ class ScheduleForm extends CompatForm
3135 protected bool $ showRemoveButton = false ;
3236
3337 /** @var bool */
34- protected bool $ showTimezoneDropdown = false ;
38+ protected bool $ showTimezoneSuggestionInput = false ;
3539
3640 /** @var Connection */
3741 private Connection $ db ;
@@ -71,9 +75,9 @@ public function setShowRemoveButton(bool $state = true): self
7175 *
7276 * @return $this
7377 */
74- public function setShowTimezoneDropdown (bool $ state = true ): self
78+ public function setShowTimezoneSuggestionInput (bool $ state = true ): self
7579 {
76- $ this ->showTimezoneDropdown = $ state ;
80+ $ this ->showTimezoneSuggestionInput = $ state ;
7781
7882 return $ this ;
7983 }
@@ -195,14 +199,38 @@ protected function assemble(): void
195199 'placeholder ' => $ this ->translate ('e.g. working hours, on call, etc ... ' )
196200 ]);
197201
198- if ($ this ->showTimezoneDropdown ) {
199- $ this ->addElement ('select ' , 'timezone ' , [
200- 'required ' => true ,
201- 'label ' => $ this ->translate ('Schedule Timezone ' ),
202- 'description ' => $ this ->translate ('Select the time zone in which this schedule operates. ' ),
203- 'multiOptions ' => array_combine (DateTimeZone::listIdentifiers (), DateTimeZone::listIdentifiers ()),
204- 'value ' => date_default_timezone_get (),
205- ]);
202+ if ($ this ->showTimezoneSuggestionInput ) {
203+ $ this ->addElement (
204+ 'suggestion ' ,
205+ 'timezone ' ,
206+ [
207+ 'suggestionsUrl ' => Url::fromPath ('notifications/suggest/timezone ' , [
208+ 'showCompact ' => true , '_disableLayout ' => 1
209+ ]),
210+ 'label ' => $ this ->translate ('Schedule Timezone ' ),
211+ 'value ' => date_default_timezone_get (),
212+ 'validators ' => [
213+ new CallbackValidator (function ($ value , $ validator ) {
214+ foreach (IntlTimeZone::createEnumeration () as $ tz ) {
215+ try {
216+ if (
217+ (new DateTime ('now ' , new DateTimeZone ($ tz )))->getTimezone ()->getLocation ()
218+ && $ value === $ tz
219+ ) {
220+ return true ;
221+ }
222+ } catch (Throwable $ _ ) {
223+ continue ;
224+ }
225+ }
226+
227+ $ validator ->addMessage ($ this ->translate ('Invalid timezone ' ));
228+
229+ return false ;
230+ })
231+ ]
232+ ]
233+ );
206234 }
207235
208236 $ this ->addElement ('submit ' , 'submit ' , [
0 commit comments