Skip to content

Commit 357f865

Browse files
committed
Select schedule timezone via suggestion element
1 parent 1aec5dc commit 357f865

File tree

3 files changed

+75
-12
lines changed

3 files changed

+75
-12
lines changed

application/controllers/ScheduleController.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ public function addAction(): void
100100
{
101101
$this->setTitle($this->translate('New Schedule'));
102102
$form = (new ScheduleForm(Database::get()))
103-
->setShowTimezoneDropdown()
103+
->setShowTimezoneSuggestionInput()
104104
->setAction($this->getRequest()->getUrl()->getAbsoluteUrl())
105105
->on(Form::ON_SUCCESS, function (ScheduleForm $form) {
106106
$scheduleId = $form->addSchedule();
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
/* Icinga Notifications Web | (c) 2025 Icinga GmbH | GPLv2 */
4+
5+
namespace Icinga\Module\Notifications\Controllers;
6+
7+
use DateTime;
8+
use DateTimeZone;
9+
use IntlTimeZone;
10+
use ipl\Web\Compat\CompatController;
11+
use ipl\Web\FormElement\SearchSuggestions;
12+
use Throwable;
13+
14+
class SuggestController extends CompatController
15+
{
16+
public function timezoneAction(): void
17+
{
18+
$suggestions = new SearchSuggestions((function () use (&$suggestions) {
19+
foreach (IntlTimeZone::createEnumeration() as $tz) {
20+
try {
21+
if (
22+
(new DateTime('now', new DateTimeZone($tz)))->getTimezone()->getLocation()
23+
&& str_contains(strtolower($tz), strtolower($suggestions->getOriginalSearchValue()))
24+
) {
25+
yield ['search' => $tz];
26+
}
27+
} catch (Throwable $_) {
28+
continue;
29+
}
30+
}
31+
})());
32+
33+
$this->getDocument()->addHtml($suggestions->forRequest($this->getServerRequest()));
34+
}
35+
}

application/forms/ScheduleForm.php

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,18 @@
1111
use Icinga\Module\Notifications\Model\RuleEscalationRecipient;
1212
use Icinga\Module\Notifications\Model\Schedule;
1313
use Icinga\Web\Session;
14+
use IntlTimeZone;
1415
use ipl\Html\Attributes;
1516
use ipl\Html\HtmlDocument;
1617
use ipl\Html\HtmlElement;
1718
use ipl\Html\Text;
1819
use ipl\Sql\Connection;
1920
use ipl\Stdlib\Filter;
21+
use ipl\Validator\CallbackValidator;
2022
use ipl\Web\Common\CsrfCounterMeasure;
2123
use ipl\Web\Compat\CompatForm;
24+
use ipl\Web\Url;
25+
use Throwable;
2226

2327
class 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

Comments
 (0)