diff --git a/application/controllers/ApiController.php b/application/controllers/ApiController.php index fe60d0552..0660d522d 100644 --- a/application/controllers/ApiController.php +++ b/application/controllers/ApiController.php @@ -4,8 +4,6 @@ namespace Icinga\Module\Notifications\Controllers; -use Exception; -use Icinga\Exception\Http\HttpBadRequestException; use Icinga\Module\Notifications\Api\Middleware\DispatchMiddleware; use Icinga\Module\Notifications\Api\Middleware\EndpointExecutionMiddleware; use Icinga\Module\Notifications\Api\Middleware\ErrorHandlingMiddleware; @@ -14,7 +12,6 @@ use Icinga\Module\Notifications\Api\Middleware\RoutingMiddleware; use Icinga\Module\Notifications\Api\Middleware\ValidationMiddleware; use Icinga\Security\SecurityException; -use Icinga\Web\Request; use ipl\Web\Compat\CompatController; use Psr\Http\Message\ResponseInterface; @@ -26,6 +23,7 @@ class ApiController extends CompatController * Processes API requests for the Notifications module, serving as the main entry point for all API interactions. * * @return never + * * @throws SecurityException */ public function indexAction(): never diff --git a/application/controllers/ChannelController.php b/application/controllers/ChannelController.php index 6dc48e6a2..7bac41340 100644 --- a/application/controllers/ChannelController.php +++ b/application/controllers/ChannelController.php @@ -7,6 +7,7 @@ use Icinga\Module\Notifications\Common\Database; use Icinga\Module\Notifications\Forms\ChannelForm; use Icinga\Web\Notification; +use ipl\Html\Contract\Form; use ipl\Web\Compat\CompatController; class ChannelController extends CompatController @@ -21,7 +22,7 @@ public function indexAction(): void $channelId = $this->params->getRequired('id'); $form = (new ChannelForm(Database::get())) ->loadChannel($channelId) - ->on(ChannelForm::ON_SUCCESS, function (ChannelForm $form) { + ->on(Form::ON_SUBMIT, function (ChannelForm $form) { if ($form->getPressedSubmitElement()->getName() === 'delete') { $form->removeChannel(); Notification::success(sprintf( diff --git a/application/controllers/ChannelsController.php b/application/controllers/ChannelsController.php index 43fa9c781..0621f5ae6 100644 --- a/application/controllers/ChannelsController.php +++ b/application/controllers/ChannelsController.php @@ -13,10 +13,9 @@ use Icinga\Module\Notifications\Web\Control\SearchBar\ObjectSuggestions; use Icinga\Module\Notifications\Widget\ItemList\ObjectList; use Icinga\Web\Notification; -use Icinga\Web\Widget\Tab; use Icinga\Web\Widget\Tabs; +use ipl\Html\Contract\Form; use ipl\Sql\Expression; -use ipl\Stdlib\Filter; use ipl\Web\Compat\CompatController; use ipl\Web\Compat\SearchControls; use ipl\Web\Control\LimitControl; @@ -29,9 +28,6 @@ class ChannelsController extends CompatController { use SearchControls; - /** @var Filter\Rule Filter from query string parameters */ - private $filter; - public function init(): void { $this->assertPermission('config/modules'); @@ -64,7 +60,7 @@ public function indexAction(): void if ($searchBar->hasBeenSent() && ! $searchBar->isValid()) { if ($searchBar->hasBeenSubmitted()) { - $filter = $this->getFilter(); + $filter = QueryString::parse((string) $this->params); } else { $this->addControl($searchBar); $this->sendMultipartUpdate(); @@ -110,7 +106,7 @@ public function addAction(): void { $this->addTitleTab(t('Add Channel')); $form = (new ChannelForm(Database::get())) - ->on(ChannelForm::ON_SUCCESS, function (ChannelForm $form) { + ->on(Form::ON_SUBMIT, function (ChannelForm $form) { $form->addChannel(); Notification::success( sprintf( @@ -147,20 +143,6 @@ public function searchEditorAction(): void $this->setTitle($this->translate('Adjust Filter')); } - /** - * Get the filter created from query string parameters - * - * @return Filter\Rule - */ - protected function getFilter(): Filter\Rule - { - if ($this->filter === null) { - $this->filter = QueryString::parse((string) $this->params); - } - - return $this->filter; - } - /** * Merge tabs with other tabs contained in this tab panel * @@ -170,7 +152,6 @@ protected function getFilter(): Filter\Rule */ protected function mergeTabs(Tabs $tabs): void { - /** @var Tab $tab */ foreach ($tabs->getTabs() as $tab) { $this->tabs->add($tab->getName(), $tab); } diff --git a/application/controllers/ConfigController.php b/application/controllers/ConfigController.php index d2d529faf..0d59a69d6 100644 --- a/application/controllers/ConfigController.php +++ b/application/controllers/ConfigController.php @@ -7,25 +7,25 @@ use Icinga\Application\Config; use Icinga\Module\Notifications\Forms\DatabaseConfigForm; use Icinga\Web\Notification; -use Icinga\Web\Widget\Tab; use Icinga\Web\Widget\Tabs; +use ipl\Html\Contract\Form; use ipl\Web\Compat\CompatController; class ConfigController extends CompatController { - public function init() + public function init(): void { $this->assertPermission('config/modules'); parent::init(); } - public function databaseAction() + public function databaseAction(): void { $moduleConfig = Config::module('notifications'); $form = (new DatabaseConfigForm()) ->populate($moduleConfig->getSection('database')) - ->on(DatabaseConfigForm::ON_SUCCESS, function ($form) use ($moduleConfig) { + ->on(Form::ON_SUBMIT, function ($form) use ($moduleConfig) { $moduleConfig->setSection('database', $form->getValues()); $moduleConfig->saveIni(); @@ -46,7 +46,6 @@ public function databaseAction() */ protected function mergeTabs(Tabs $tabs): void { - /** @var Tab $tab */ foreach ($tabs->getTabs() as $tab) { $this->tabs->add($tab->getName(), $tab); } diff --git a/application/controllers/ContactController.php b/application/controllers/ContactController.php index 7c8533824..ef575de1f 100644 --- a/application/controllers/ContactController.php +++ b/application/controllers/ContactController.php @@ -13,6 +13,7 @@ use Icinga\Module\Notifications\Web\Form\ContactForm; use Icinga\Repository\Repository; use Icinga\Web\Notification; +use ipl\Html\Contract\Form; use ipl\Web\Compat\CompatController; use ipl\Web\FormElement\SearchSuggestions; @@ -29,7 +30,7 @@ public function indexAction(): void $form = (new ContactForm(Database::get())) ->loadContact($contactId) - ->on(ContactForm::ON_SUCCESS, function (ContactForm $form) { + ->on(Form::ON_SUBMIT, function (ContactForm $form) { $form->editContact(); Notification::success(sprintf( t('Contact "%s" has successfully been saved'), diff --git a/application/controllers/ContactGroupController.php b/application/controllers/ContactGroupController.php index 1dfdd285d..ee0e9bce5 100644 --- a/application/controllers/ContactGroupController.php +++ b/application/controllers/ContactGroupController.php @@ -13,7 +13,8 @@ use Icinga\Module\Notifications\Widget\Detail\ObjectHeader; use Icinga\Module\Notifications\Widget\ItemList\ObjectList; use Icinga\Web\Notification; -use ipl\Html\Form; +use ipl\Html\Attributes; +use ipl\Html\Contract\Form; use ipl\Html\Text; use ipl\Stdlib\Filter; use ipl\Web\Compat\CompatController; @@ -35,12 +36,13 @@ public function indexAction(): void ->columns(['id', 'name']) ->filter(Filter::equal('id', $groupId)); + /** @var ?Contactgroup $group */ $group = $query->first(); if ($group === null) { $this->httpNotFound(t('Contact group not found')); } - $this->controls->addAttributes(['class' => 'contactgroup-detail']); + $this->controls->addAttributes(Attributes::create(['class' => 'contactgroup-detail'])); $this->addControl(new ObjectHeader($group)); @@ -97,7 +99,7 @@ public function editAction(): void } } }) - ->on(Form::ON_SUCCESS, function (ContactGroupForm $form) use ($groupId) { + ->on(Form::ON_SUBMIT, function (ContactGroupForm $form) use ($groupId) { $form->editGroup(); Notification::success(sprintf( t('Successfully updated contact group %s'), diff --git a/application/controllers/ContactGroupsController.php b/application/controllers/ContactGroupsController.php index 2a53046ea..e76ebc6b0 100644 --- a/application/controllers/ContactGroupsController.php +++ b/application/controllers/ContactGroupsController.php @@ -20,7 +20,6 @@ use ipl\Html\HtmlString; use ipl\Html\TemplateString; use ipl\Sql\Expression; -use ipl\Stdlib\Filter; use ipl\Web\Compat\CompatController; use ipl\Web\Compat\SearchControls; use ipl\Web\Control\LimitControl; @@ -35,9 +34,6 @@ class ContactGroupsController extends CompatController use ConfigurationTabs; use SearchControls; - /** @var Filter\Rule Filter from query string parameters */ - private $filter; - public function init(): void { $this->assertPermission('notifications/config/contacts'); @@ -70,7 +66,7 @@ public function indexAction(): void if ($searchBar->hasBeenSent() && ! $searchBar->isValid()) { if ($searchBar->hasBeenSubmitted()) { - $filter = $this->getFilter(); + $filter = QueryString::parse((string) $this->params); } else { $this->addControl($searchBar); $this->sendMultipartUpdate(); @@ -160,7 +156,7 @@ public function addAction(): void } } }) - ->on(Form::ON_SUCCESS, function (ContactGroupForm $form) { + ->on(Form::ON_SUBMIT, function (ContactGroupForm $form) { $groupIdentifier = $form->addGroup(); Notification::success($this->translate('New contact group has been successfully added')); @@ -203,18 +199,4 @@ public function suggestMemberAction(): void $this->getDocument()->addHtml($members); } - - /** - * Get the filter created from query string parameters - * - * @return Filter\Rule - */ - private function getFilter(): Filter\Rule - { - if ($this->filter === null) { - $this->filter = QueryString::parse((string) $this->params); - } - - return $this->filter; - } } diff --git a/application/controllers/ContactsController.php b/application/controllers/ContactsController.php index 6ad61d5bf..ca142df14 100644 --- a/application/controllers/ContactsController.php +++ b/application/controllers/ContactsController.php @@ -5,12 +5,12 @@ namespace Icinga\Module\Notifications\Controllers; use Icinga\Module\Notifications\Common\ConfigurationTabs; +use Icinga\Module\Notifications\Common\Database; use Icinga\Module\Notifications\Common\Links; use Icinga\Module\Notifications\Model\Channel; +use Icinga\Module\Notifications\Model\Contact; use Icinga\Module\Notifications\View\ContactRenderer; use Icinga\Module\Notifications\Web\Control\SearchBar\ObjectSuggestions; -use Icinga\Module\Notifications\Common\Database; -use Icinga\Module\Notifications\Model\Contact; use Icinga\Module\Notifications\Web\Form\ContactForm; use Icinga\Module\Notifications\Widget\ItemList\ObjectList; use Icinga\Web\Notification; @@ -18,7 +18,6 @@ use ipl\Html\TemplateString; use ipl\Sql\Connection; use ipl\Sql\Expression; -use ipl\Stdlib\Filter; use ipl\Web\Compat\CompatController; use ipl\Web\Compat\SearchControls; use ipl\Web\Control\LimitControl; @@ -34,19 +33,16 @@ class ContactsController extends CompatController use SearchControls; /** @var Connection */ - private $db; - - /** @var Filter\Rule Filter from query string parameters */ - private $filter; + private Connection $db; - public function init() + public function init(): void { $this->assertPermission('notifications/config/contacts'); $this->db = Database::get(); } - public function indexAction() + public function indexAction(): void { $this->setTitle($this->translate('Contacts')); $this->getTabs()->activate('contacts'); @@ -73,7 +69,7 @@ public function indexAction() if ($searchBar->hasBeenSent() && ! $searchBar->isValid()) { if ($searchBar->hasBeenSubmitted()) { - $filter = $this->getFilter(); + $filter = QueryString::parse((string) $this->params); } else { $this->addControl($searchBar); $this->sendMultipartUpdate(); @@ -164,18 +160,4 @@ public function searchEditorAction(): void $this->getDocument()->add($editor); $this->setTitle($this->translate('Adjust Filter')); } - - /** - * Get the filter created from query string parameters - * - * @return Filter\Rule - */ - protected function getFilter(): Filter\Rule - { - if ($this->filter === null) { - $this->filter = QueryString::parse((string) $this->params); - } - - return $this->filter; - } } diff --git a/application/controllers/DaemonController.php b/application/controllers/DaemonController.php index e30cb89e7..cdd6b1711 100644 --- a/application/controllers/DaemonController.php +++ b/application/controllers/DaemonController.php @@ -60,7 +60,7 @@ public function scriptAction(): void ->getBaseDir() . '/public/js'; $filePath = realpath($root . DIRECTORY_SEPARATOR . 'notifications-' . $fileName . $extension); - if ($filePath === false || substr($filePath, 0, strlen($root)) !== $root) { + if ($filePath === false || ! str_starts_with($filePath, $root)) { if ($fileName === 'undefined') { $this->httpNotFound(t("No file name submitted")); } diff --git a/application/controllers/EventController.php b/application/controllers/EventController.php index 5b5efc74a..7fe7071a6 100644 --- a/application/controllers/EventController.php +++ b/application/controllers/EventController.php @@ -9,6 +9,7 @@ use Icinga\Module\Notifications\Model\Event; use Icinga\Module\Notifications\Widget\Detail\EventDetail; use Icinga\Module\Notifications\Widget\Detail\ObjectHeader; +use ipl\Html\Attributes; use ipl\Stdlib\Filter; use ipl\Web\Compat\CompatController; @@ -40,7 +41,7 @@ public function indexAction(): void $this->addControl(new ObjectHeader($event)); - $this->controls->addAttributes(['class' => 'event-detail']); + $this->controls->addAttributes(Attributes::create(['class' => 'event-detail'])); $this->addContent(new EventDetail($event)); } diff --git a/application/controllers/EventRuleController.php b/application/controllers/EventRuleController.php index 31fd71012..c58e22de0 100644 --- a/application/controllers/EventRuleController.php +++ b/application/controllers/EventRuleController.php @@ -7,6 +7,7 @@ use Icinga\Application\Hook; use Icinga\Application\Logger; use Icinga\Exception\Http\HttpNotFoundException; +use Icinga\Exception\MissingParameterException; use Icinga\Module\Notifications\Common\Auth; use Icinga\Module\Notifications\Common\Database; use Icinga\Module\Notifications\Common\Links; @@ -19,6 +20,7 @@ use Icinga\Module\Notifications\Web\Control\SearchBar\ExtraTagSuggestions; use Icinga\Web\Notification; use Icinga\Web\Session; +use ipl\Html\Attributes; use ipl\Html\Contract\Form; use ipl\Html\Html; use ipl\Stdlib\Filter; @@ -45,8 +47,8 @@ public function init(): void public function indexAction(): void { - $this->controls->addAttributes(['class' => 'event-rule-detail']); - $this->content->addAttributes(['class' => 'event-rule-detail']); + $this->controls->addAttributes(Attributes::create(['class' => 'event-rule-detail'])); + $this->content->addAttributes(Attributes::create(['class' => 'event-rule-detail'])); $this->getTabs()->disableLegacyExtensions(); $ruleId = (int) $this->params->getRequired('id'); @@ -188,7 +190,7 @@ public function completeAction(): void * * @return void * - * @throws \Icinga\Exception\MissingParameterException + * @throws MissingParameterException */ public function searchEditorAction(): void { @@ -205,6 +207,7 @@ public function searchEditorAction(): void )) ->first(); } elseif (isset($this->session->source)) { + /** @var ?Source $source */ $source = Source::on(Database::get()) ->columns(['id', 'type']) ->filter(Filter::equal('id', $this->session->source)) @@ -322,6 +325,7 @@ public function editAction(): void * @param int $ruleId * * @return Rule + * * @throws HttpNotFoundException */ private function fetchRule(int $ruleId): Rule diff --git a/application/controllers/EventRulesController.php b/application/controllers/EventRulesController.php index 8442bf20c..e6ba29818 100644 --- a/application/controllers/EventRulesController.php +++ b/application/controllers/EventRulesController.php @@ -32,7 +32,7 @@ class EventRulesController extends CompatController use ConfigurationTabs; use SearchControls; - public function init() + public function init(): void { $this->assertPermission('notifications/config/event-rules'); } diff --git a/application/controllers/EventsController.php b/application/controllers/EventsController.php index b5a26dfdf..72a50e40f 100644 --- a/application/controllers/EventsController.php +++ b/application/controllers/EventsController.php @@ -7,8 +7,8 @@ use Icinga\Module\Notifications\Common\Auth; use Icinga\Module\Notifications\Common\Database; use Icinga\Module\Notifications\Hook\ObjectsRendererHook; -use Icinga\Module\Notifications\Web\Control\SearchBar\ObjectSuggestions; use Icinga\Module\Notifications\Model\Event; +use Icinga\Module\Notifications\Web\Control\SearchBar\ObjectSuggestions; use Icinga\Module\Notifications\Widget\ItemList\LoadMoreObjectList; use ipl\Stdlib\Filter; use ipl\Web\Compat\CompatController; @@ -25,9 +25,6 @@ class EventsController extends CompatController use Auth; use SearchControls; - /** @var Filter\Rule Filter from query string parameters */ - private $filter; - public function indexAction(): void { $this->addTitleTab(t('Events')); @@ -56,7 +53,7 @@ public function indexAction(): void if ($searchBar->hasBeenSent() && ! $searchBar->isValid()) { if ($searchBar->hasBeenSubmitted()) { - $filter = $this->getFilter(); + $filter = QueryString::parse((string) $this->params); } else { $this->addControl($searchBar); $this->sendMultipartUpdate(); @@ -130,18 +127,4 @@ public function searchEditorAction(): void $this->getDocument()->add($editor); $this->setTitle(t('Adjust Filter')); } - - /** - * Get the filter created from query string parameters - * - * @return Filter\Rule - */ - protected function getFilter(): Filter\Rule - { - if ($this->filter === null) { - $this->filter = QueryString::parse((string) $this->params); - } - - return $this->filter; - } } diff --git a/application/controllers/IncidentController.php b/application/controllers/IncidentController.php index 742cab1ef..847bdc9d8 100644 --- a/application/controllers/IncidentController.php +++ b/application/controllers/IncidentController.php @@ -12,6 +12,8 @@ use Icinga\Module\Notifications\Widget\Detail\IncidentDetail; use Icinga\Module\Notifications\Widget\Detail\IncidentQuickActions; use Icinga\Module\Notifications\Widget\Detail\ObjectHeader; +use ipl\Html\Attributes; +use ipl\Html\Contract\Form; use ipl\Stdlib\Filter; use ipl\Web\Compat\CompatController; @@ -40,8 +42,9 @@ public function indexAction(): void $this->addControl(new ObjectHeader($incident)); - $this->controls->addAttributes(['class' => 'incident-detail']); + $this->controls->addAttributes(Attributes::create(['class' => 'incident-detail'])); + /** @var ?Contact $contact */ $contact = Contact::on(Database::get()) ->columns('id') ->filter(Filter::equal('username', $this->Auth()->getUser()->getUsername())) @@ -50,7 +53,7 @@ public function indexAction(): void if ($contact !== null) { $this->addControl( (new IncidentQuickActions($incident, $contact->id)) - ->on(IncidentQuickActions::ON_SUCCESS, function () use ($incident) { + ->on(Form::ON_SUBMIT, function () use ($incident) { $this->redirectNow(Links::incident($incident->id)); }) ->handleRequest($this->getServerRequest()) diff --git a/application/controllers/IncidentsController.php b/application/controllers/IncidentsController.php index 13ebb8431..38f06ca8d 100644 --- a/application/controllers/IncidentsController.php +++ b/application/controllers/IncidentsController.php @@ -7,11 +7,10 @@ use Icinga\Module\Notifications\Common\Auth; use Icinga\Module\Notifications\Common\Database; use Icinga\Module\Notifications\Hook\ObjectsRendererHook; +use Icinga\Module\Notifications\Model\Incident; use Icinga\Module\Notifications\View\IncidentRenderer; use Icinga\Module\Notifications\Web\Control\SearchBar\ObjectSuggestions; -use Icinga\Module\Notifications\Model\Incident; use Icinga\Module\Notifications\Widget\ItemList\ObjectList; -use ipl\Stdlib\Filter; use ipl\Web\Compat\CompatController; use ipl\Web\Compat\SearchControls; use ipl\Web\Control\LimitControl; @@ -26,9 +25,6 @@ class IncidentsController extends CompatController use Auth; use SearchControls; - /** @var Filter\Rule Filter from query string parameters */ - private $filter; - public function indexAction(): void { $this->addTitleTab(t('Incidents')); @@ -55,7 +51,7 @@ public function indexAction(): void if ($searchBar->hasBeenSent() && ! $searchBar->isValid()) { if ($searchBar->hasBeenSubmitted()) { - $filter = $this->getFilter(); + $filter = QueryString::parse((string) $this->params); } else { $this->addControl($searchBar); $this->sendMultipartUpdate(); @@ -114,18 +110,4 @@ protected function getPageSize($default) { return parent::getPageSize($default ?? 50); } - - /** - * Get the filter created from query string parameters - * - * @return Filter\Rule - */ - public function getFilter(): Filter\Rule - { - if ($this->filter === null) { - $this->filter = QueryString::parse((string) $this->params); - } - - return $this->filter; - } } diff --git a/application/controllers/ScheduleController.php b/application/controllers/ScheduleController.php index 7c958bc97..107893afc 100644 --- a/application/controllers/ScheduleController.php +++ b/application/controllers/ScheduleController.php @@ -15,6 +15,7 @@ use Icinga\Module\Notifications\Widget\Detail\ScheduleDetail; use Icinga\Module\Notifications\Widget\TimezoneWarning; use Icinga\Web\Session; +use ipl\Html\Attributes; use ipl\Html\Contract\Form; use ipl\Html\Html; use ipl\Stdlib\Filter; @@ -60,7 +61,7 @@ public function indexAction(): void ))->openInModal() ); - $this->controls->addAttributes(['class' => 'schedule-detail-controls']); + $this->controls->addAttributes(Attributes::create(['class' => 'schedule-detail-controls'])); $scheduleControls = (new ScheduleDetail\Controls()) ->setAction(Url::fromRequest()->getAbsoluteUrl()) diff --git a/application/controllers/SchedulesController.php b/application/controllers/SchedulesController.php index 172415d1b..cbe673cae 100644 --- a/application/controllers/SchedulesController.php +++ b/application/controllers/SchedulesController.php @@ -11,7 +11,6 @@ use Icinga\Module\Notifications\View\ScheduleRenderer; use Icinga\Module\Notifications\Web\Control\SearchBar\ObjectSuggestions; use Icinga\Module\Notifications\Widget\ItemList\ObjectList; -use ipl\Stdlib\Filter; use ipl\Web\Compat\CompatController; use ipl\Web\Compat\SearchControls; use ipl\Web\Control\LimitControl; @@ -24,9 +23,6 @@ class SchedulesController extends CompatController use ConfigurationTabs; use SearchControls; - /** @var Filter\Rule Filter from query string parameters */ - private $filter; - public function init(): void { $this->assertPermission('notifications/config/schedules'); @@ -56,7 +52,7 @@ public function indexAction(): void if ($searchBar->hasBeenSent() && ! $searchBar->isValid()) { if ($searchBar->hasBeenSubmitted()) { - $filter = $this->getFilter(); + $filter = QueryString::parse((string) $this->params); } else { $this->addControl($searchBar); $this->sendMultipartUpdate(); @@ -108,18 +104,4 @@ public function searchEditorAction(): void $this->getDocument()->add($editor); $this->setTitle(t('Adjust Filter')); } - - /** - * Get the filter created from query string parameters - * - * @return Filter\Rule - */ - private function getFilter(): Filter\Rule - { - if ($this->filter === null) { - $this->filter = QueryString::parse((string) $this->params); - } - - return $this->filter; - } } diff --git a/application/controllers/SourcesController.php b/application/controllers/SourcesController.php index dc4e54329..15156ed0d 100644 --- a/application/controllers/SourcesController.php +++ b/application/controllers/SourcesController.php @@ -28,7 +28,7 @@ class SourcesController extends CompatController { use SearchControls; - public function init() + public function init(): void { $this->assertPermission('config/modules'); } @@ -39,7 +39,7 @@ public function indexAction(): void $this->getTabs()->activate('sources'); $sources = Source::on(Database::get()) - ->columns(['id', 'type', 'name']); + ->columns(['id', 'type', 'name']); $limitControl = $this->createLimitControl(); $paginationControl = $this->createPaginationControl($sources); diff --git a/application/forms/ChannelForm.php b/application/forms/ChannelForm.php index 603d2910c..5ef26fe5b 100644 --- a/application/forms/ChannelForm.php +++ b/application/forms/ChannelForm.php @@ -45,13 +45,13 @@ class ChannelForm extends CompatForm use CsrfCounterMeasure; /** @var Connection */ - private $db; + private Connection $db; /** @var ?int Channel ID */ - private $channelId; + private ?int $channelId = null; /** @var array */ - private $defaultChannelOptions = []; + private array $defaultChannelOptions = []; public function __construct(Connection $db) { @@ -72,7 +72,7 @@ protected function assemble(): void } $this->addAttributes(['class' => 'channel-form']); - $this->addElement($this->createCsrfCounterMeasure(Session::getSession()->getId())); + $this->addCsrfCounterMeasure(Session::getSession()->getId()); $this->addElement( 'text', @@ -331,31 +331,14 @@ protected function createConfigElements(string $type, string $config): void */ protected function getElementType(string $configType): string { - switch ($configType) { - case 'string': - $elementType = 'text'; - break; - case 'number': - $elementType = 'number'; - break; - case 'text': - $elementType = 'textarea'; - break; - case 'bool': - $elementType = 'checkbox'; - break; - case 'option': - case 'options': - $elementType = 'select'; - break; - case 'secret': - $elementType = 'password'; - break; - default: - $elementType = 'text'; - } - - return $elementType; + return match ($configType) { + 'number' => 'number', + 'text' => 'textarea', + 'bool' => 'checkbox', + 'option', 'options' => 'select', + 'secret' => 'password', + default => 'text' + }; } /** diff --git a/application/forms/ContactGroupForm.php b/application/forms/ContactGroupForm.php index 9b5795ee0..8beb22a1f 100644 --- a/application/forms/ContactGroupForm.php +++ b/application/forms/ContactGroupForm.php @@ -65,10 +65,10 @@ protected function assemble(): void ->on(TermInput::ON_SAVE, $callValidation) ->on(TermInput::ON_PASTE, $callValidation); - // TODO: TermInput is not compatible with the new decorators yet: https://github.com/Icinga/ipl-web/pull/317 - $legacyDecorator = new IcingaFormDecorator(); - $termInput->setDefaultElementDecorator($legacyDecorator); - $legacyDecorator->decorate($termInput); + // TODO: TermInput is not compatible with the new decorators yet: https://github.com/Icinga/ipl-web/pull/317 + $legacyDecorator = new IcingaFormDecorator(); + $termInput->setDefaultElementDecorator($legacyDecorator); + $legacyDecorator->decorate($termInput); $this->addElement( 'text', @@ -363,9 +363,9 @@ public function removeContactgroup(): void $escalationIds = $this->db->fetchCol( RuleEscalationRecipient::on($this->db) - ->columns('rule_escalation_id') - ->filter(Filter::equal('contactgroup_id', $this->contactgroupId)) - ->assembleSelect() + ->columns('rule_escalation_id') + ->filter(Filter::equal('contactgroup_id', $this->contactgroupId)) + ->assembleSelect() ); $this->db->update('rule_escalation_recipient', $markAsDeleted, $updateCondition); @@ -415,6 +415,7 @@ private function fetchDbValues(): array ->columns(['id', 'name']) ->filter(Filter::equal('id', $this->contactgroupId)); + /** @var ?Contactgroup $group */ $group = $query->first(); if ($group === null) { throw new HttpNotFoundException($this->translate('Contact group not found')); diff --git a/application/forms/DatabaseConfigForm.php b/application/forms/DatabaseConfigForm.php index bcde696a6..d69452a2a 100644 --- a/application/forms/DatabaseConfigForm.php +++ b/application/forms/DatabaseConfigForm.php @@ -9,7 +9,7 @@ class DatabaseConfigForm extends CompatForm { - protected function assemble() + protected function assemble(): void { $dbResources = ResourceFactory::getResourceConfigs('db')->keys(); @@ -17,14 +17,14 @@ protected function assemble() 'select', 'resource', [ - 'label' => $this->translate('Database'), - 'options' => array_merge( + 'label' => $this->translate('Database'), + 'options' => array_merge( ['' => sprintf(' - %s - ', $this->translate('Please choose'))], array_combine($dbResources, $dbResources) ), - 'disable' => [''], - 'required' => true, - 'value' => '' + 'disabledOptions' => [''], + 'required' => true, + 'value' => '' ] ); diff --git a/application/forms/EventRuleConfigElements/DynamicElements.php b/application/forms/EventRuleConfigElements/DynamicElements.php index a13c83867..070ddf28c 100644 --- a/application/forms/EventRuleConfigElements/DynamicElements.php +++ b/application/forms/EventRuleConfigElements/DynamicElements.php @@ -4,6 +4,7 @@ namespace Icinga\Module\Notifications\Forms\EventRuleConfigElements; +use ipl\Html\Attributes; use ipl\Html\Contract\FormElement; use ipl\Html\FormElement\SubmitButtonElement; @@ -86,7 +87,7 @@ protected function assemble(): void $count++; } - $add = $this->createAddButton()->addAttributes(['formnovalidate' => true]); + $add = $this->createAddButton()->addAttributes(Attributes::create(['formnovalidate' => true])); $this->registerElement($add); if ($add->hasBeenPressed()) { $this->createRemoveButton($newCount); @@ -114,6 +115,6 @@ protected function assemble(): void $this->clearPopulatedValue('count'); $this->addElement('hidden', 'count', ['ignore' => true, 'value' => $newCount]); - $this->addAttributes(['class' => ['dynamic-list', $newCount === 0 ? 'empty' : '']]); + $this->addAttributes(Attributes::create(['class' => ['dynamic-list', $newCount === 0 ? 'empty' : '']])); } } diff --git a/application/forms/EventRuleConfigElements/NotificationConfigProvider.php b/application/forms/EventRuleConfigElements/NotificationConfigProvider.php index 61fabf698..745a03165 100644 --- a/application/forms/EventRuleConfigElements/NotificationConfigProvider.php +++ b/application/forms/EventRuleConfigElements/NotificationConfigProvider.php @@ -13,12 +13,16 @@ class NotificationConfigProvider implements ConfigProviderInterface { + /** @var ?ResultSet */ private ?ResultSet $contacts = null; + /** @var ?ResultSet */ private ?ResultSet $contactGroups = null; + /** @var ?ResultSet */ private ?ResultSet $schedules = null; + /** @var ?ResultSet */ private ?ResultSet $channels = null; public function fetchContacts(): iterable diff --git a/application/forms/MoveRotationForm.php b/application/forms/MoveRotationForm.php index 1a8825a42..6dd396a90 100644 --- a/application/forms/MoveRotationForm.php +++ b/application/forms/MoveRotationForm.php @@ -22,20 +22,18 @@ class MoveRotationForm extends Form protected $defaultAttributes = ['hidden' => true]; - protected $method = 'POST'; + /** @var ?Connection */ + protected ?Connection $db = null; - /** @var Connection */ - protected $db; - - /** @var int */ - protected $scheduleId; + /** @var ?int */ + protected ?int $scheduleId = null; /** * Create a new MoveRotationForm * * @param ?Connection $db */ - public function __construct(Connection $db = null) + public function __construct(?Connection $db = null) { $this->db = $db; } @@ -54,7 +52,7 @@ public function getScheduleId(): int return $this->scheduleId; } - public function getMessages() + public function getMessages(): array { $messages = parent::getMessages(); foreach ($this->getElements() as $element) { @@ -66,21 +64,21 @@ public function getMessages() return $messages; } - protected function assemble() + protected function assemble(): void { $this->addElement('hidden', 'rotation', ['required' => true]); $this->addElement('hidden', 'priority', ['required' => true]); - $this->addElement($this->createCsrfCounterMeasure(Session::getSession()->getId())); + $this->addCsrfCounterMeasure(Session::getSession()->getId()); } - protected function onError() + protected function onError(): void { $this->removeAttribute('hidden'); parent::onError(); } - protected function onSuccess() + protected function onSuccess(): void { $rotationId = $this->getValue('rotation'); $newPriority = $this->getValue('priority'); diff --git a/application/forms/RotationConfigForm.php b/application/forms/RotationConfigForm.php index 28c83afa9..974fca435 100644 --- a/application/forms/RotationConfigForm.php +++ b/application/forms/RotationConfigForm.php @@ -17,10 +17,12 @@ use Icinga\Module\Notifications\Model\TimeperiodEntry; use Icinga\Util\Json; use Icinga\Web\Session; +use IntlDateFormatter; use ipl\Html\Attributes; use ipl\Html\DeferredText; use ipl\Html\FormDecoration\DescriptionDecorator; use ipl\Html\FormElement\FieldsetElement; +use ipl\Html\FormElement\SelectElement; use ipl\Html\HtmlDocument; use ipl\Html\HtmlElement; use ipl\Html\Text; @@ -35,6 +37,7 @@ use ipl\Web\FormDecorator\IcingaFormDecorator; use ipl\Web\FormElement\TermInput; use ipl\Web\Url; +use Locale; use LogicException; use Recurr\Frequency; use Recurr\Rule; @@ -51,41 +54,41 @@ class RotationConfigForm extends CompatForm */ public const EXPERIMENTAL_OVERRIDES = false; - /** @var ?int The ID of the affected schedule */ - protected $scheduleId; + /** @var int The ID of the affected schedule */ + protected int $scheduleId; /** @var Connection The database connection */ - protected $db; + protected Connection $db; - /** @var string The label shown on the submit button */ - protected $submitLabel; + /** @var ?string The label shown on the submit button */ + protected ?string $submitLabel = null; /** @var bool Whether to render the remove button */ - protected $showRemoveButton = false; + protected bool $showRemoveButton = false; - /** @var Url The URL to fetch member suggestions from */ - protected $suggestionUrl; + /** @var ?Url The URL to fetch member suggestions from */ + protected ?Url $suggestionUrl = null; /** @var bool Whether the mode selection is disabled */ - protected $disableModeSelection = false; + protected bool $disableModeSelection = false; /** @var ?DateTime The previous first handoff of this rotation's version */ - protected $previousHandoff; + protected ?DateTime $previousHandoff = null; /** @var ?DateTime The end of the last shift of this rotation's previous version */ - protected $previousShift; + protected ?DateTime $previousShift = null; /** @var ?DateTime The first handoff of a newer version for this rotation */ - protected $nextHandoff; + protected ?DateTime $nextHandoff = null; - /** @var int The rotation id */ - protected $rotationId; + /** @var ?int The rotation id */ + protected ?int $rotationId = null; /** @var string The timezone to display the timeline in */ - protected $displayTimezone; + protected string $displayTimezone; /** @var string The timezone the schedule is created in */ - protected $scheduleTimezone; + protected string $scheduleTimezone; /** * Set the label for the submit button @@ -130,7 +133,7 @@ public function setShowRemoveButton(bool $state = true): self * * @param Url $url * - * @return void + * @return $this */ public function setSuggestionUrl(Url $url): self { @@ -142,7 +145,7 @@ public function setSuggestionUrl(Url $url): self /** * Disable the mode selection * - * @return void + * @return $this */ public function disableModeSelection(): self { @@ -213,6 +216,9 @@ public function __construct(int $scheduleId, Connection $db, string $displayTime * @param int $rotationId * * @return $this + * + * @throws LogicException If an invalid rotation mode is set + * @throws ConfigurationError If the schedule's timezone is invalid' * @throws HttpNotFoundException If the rotation with the given ID does not exist */ public function loadRotation(int $rotationId): self @@ -221,22 +227,11 @@ public function loadRotation(int $rotationId): self if (self::EXPERIMENTAL_OVERRIDES) { $getHandoff = function (Rotation $rotation): DateTime { - switch ($rotation->mode) { - case '24-7': - $time = $rotation->options['at']; - - break; - case 'partial': - $time = $rotation->options['from']; - - break; - case 'multi': - $time = $rotation->options['from_at']; - - break; - default: - throw new LogicException('Invalid mode'); - } + $time = match ($rotation->mode) { + '24-7' => $rotation->options['at'], + 'partial' => $rotation->options['from'], + 'multi' => $rotation->options['from_at'] + }; $handoff = DateTime::createFromFormat( 'Y-m-d H:i', @@ -432,6 +427,8 @@ public function addRotation(): void * @param int $rotationId * * @return void + * + * @throws LogicException If the priority is not set */ public function editRotation(int $rotationId): void { @@ -555,6 +552,8 @@ public function editRotation(int $rotationId): void * @param int $id * * @return void + * + * @throws LogicException If the priority is not set */ public function removeRotation(int $id): void { @@ -584,7 +583,11 @@ public function removeRotation(int $id): void /** * Remove all versions of the rotation from the database * + * @param int|null $priority The priority of the rotations to remove. + * * @return void + * + * @throws LogicException If the priority is not set */ public function wipeRotation(int $priority = null): void { @@ -988,6 +991,7 @@ protected function assembleMultiDayOptions(FieldsetElement $options): DateTime ); } + /** @var SelectElement $toAt */ $toAt = $options->createElement('select', 'to_at', [ 'class' => 'autosubmit', 'required' => true, @@ -1064,7 +1068,7 @@ protected function assembleMultiDayOptions(FieldsetElement $options): DateTime return $firstHandoff; } - protected function assemble() + protected function assemble(): void { $this->getAttributes()->add('class', 'rotation-config'); @@ -1099,7 +1103,7 @@ protected function assemble() $groupTerms = []; foreach ($terms as $term) { /** @var TermInput\Term $term */ - if (strpos($term->getSearchValue(), ':') === false) { + if (! str_contains($term->getSearchValue(), ':')) { // TODO: Auto-correct this to a valid type:id pair, if possible $term->setMessage($this->translate('Is not a contact nor a group of contacts')); continue; @@ -1196,7 +1200,7 @@ protected function assemble() 'type' => 'date', 'required' => true, 'aria-describedby' => 'first-handoff-description', - 'min' => $earliestHandoff !== null ? $earliestHandoff->format('Y-m-d') : null, + 'min' => $earliestHandoff?->format('Y-m-d'), 'max' => $latestHandoff->format('Y-m-d'), 'label' => $this->translate('Rotation Start'), 'value' => $firstHandoffDefault, @@ -1246,10 +1250,10 @@ function ($value, $validator) use ($earliestHandoff, $firstHandoff, $latestHando } else { return sprintf( $this->translate('The rotation will start on %s'), - (new \IntlDateFormatter( - \Locale::getDefault(), - \IntlDateFormatter::MEDIUM, - \IntlDateFormatter::SHORT, + (new IntlDateFormatter( + Locale::getDefault(), + IntlDateFormatter::MEDIUM, + IntlDateFormatter::SHORT, $this->scheduleTimezone ))->format($actualFirstHandoff) ); @@ -1269,10 +1273,10 @@ function ($value, $validator) use ($earliestHandoff, $firstHandoff, $latestHando return sprintf( $this->translate('In your chosen display timezone (%s) this is the %s'), $this->displayTimezone, - (new \IntlDateFormatter( - \Locale::getDefault(), - \IntlDateFormatter::MEDIUM, - \IntlDateFormatter::SHORT, + (new IntlDateFormatter( + Locale::getDefault(), + IntlDateFormatter::MEDIUM, + IntlDateFormatter::SHORT, $this->displayTimezone ))->format($actualFirstHandoff) ); @@ -1361,10 +1365,10 @@ private function parseDateAndTime(?string $date = null, ?string $time = null): D */ private function getTimeOptions(): array { - $formatter = new \IntlDateFormatter( - \Locale::getDefault(), - \IntlDateFormatter::NONE, - \IntlDateFormatter::SHORT, + $formatter = new IntlDateFormatter( + Locale::getDefault(), + IntlDateFormatter::NONE, + IntlDateFormatter::SHORT, $this->scheduleTimezone ); @@ -1595,6 +1599,8 @@ private function yieldRecurrenceRules(int $count): Generator * @param DateTime $before * * @return array{0: ?DateTime, 1?: array{0: DateTime, 1: DateTime}} + * + * @throws LogicException If the frequency is not supported */ private function calculateRemainingHandoffs(Rule $rrule, DateInterval $shiftDuration, DateTime $before): array { diff --git a/application/forms/ScheduleForm.php b/application/forms/ScheduleForm.php index c336fb57a..cb6d18c45 100644 --- a/application/forms/ScheduleForm.php +++ b/application/forms/ScheduleForm.php @@ -29,7 +29,7 @@ class ScheduleForm extends CompatForm use CsrfCounterMeasure; /** @var ?string */ - protected ?string $submitLabel; + protected ?string $submitLabel = null; /** @var bool */ protected bool $showRemoveButton = false; diff --git a/application/forms/SourceForm.php b/application/forms/SourceForm.php index 7147a4625..c03799001 100644 --- a/application/forms/SourceForm.php +++ b/application/forms/SourceForm.php @@ -33,10 +33,10 @@ class SourceForm extends CompatForm public const HASH_ALGORITHM = PASSWORD_BCRYPT; /** @var Connection */ - private $db; + private Connection $db; /** @var ?int */ - private $sourceId; + private ?int $sourceId = null; public function __construct(Connection $db) { diff --git a/doc/api/api-v1-public.json b/doc/api/api-v1-public.json index 778ea066e..0361b86a6 100644 --- a/doc/api/api-v1-public.json +++ b/doc/api/api-v1-public.json @@ -144,7 +144,7 @@ "properties": { "data": { "$ref": "#/components/schemas/Channel", - "description": "Successfull response with the Channel object" + "description": "Successful response with the Channel object" } }, "type": "object" @@ -482,7 +482,7 @@ "properties": { "data": { "$ref": "#/components/schemas/Contactgroup", - "description": "Successfull response with the Contactgroup object" + "description": "Successful response with the Contactgroup object" } }, "type": "object" @@ -595,7 +595,7 @@ } }, "links": { - "GetContactgroupByIdentifiere": { + "GetContactgroupByIdentifier": { "operationId": "getContactgroup", "parameters": { "identifier": "$response.header.X-Resource-Identifier" @@ -1290,7 +1290,7 @@ "properties": { "data": { "$ref": "#/components/schemas/Contact", - "description": "Successfull response with the Contact object" + "description": "Successful response with the Contact object" } }, "type": "object" @@ -1403,7 +1403,7 @@ } }, "links": { - "GetContactByIdentifiere": { + "GetContactByIdentifier": { "operationId": "getContact", "parameters": { "identifier": "$response.header.X-Resource-Identifier" @@ -2001,78 +2001,6 @@ } }, "examples": { - "IdentifierMismatch": { - "summary": "Identifier mismatch", - "value": { - "message": "Identifier mismatch" - } - }, - "IdentifierNotFound": { - "summary": "Identifier not found", - "value": { - "message": "Identifier not found" - } - }, - "IdentifierPayloadIdMissmatch": { - "summary": "Identifier and payload Id missmatch", - "value": { - "message": "Identifier mismatch: the Payload id must be different from the URL identifier" - } - }, - "InvalidContentType": { - "summary": "Invalid content type", - "value": { - "message": "Invalid request header: Content-Type must be application/json" - } - }, - "InvalidFilterParameter": { - "summary": "Invalid filter parameter", - "value": { - "message": "Invalid request parameter: Filter column x is not allowed" - } - }, - "InvalidIdentifier": { - "summary": "Identifier is not valid", - "value": { - "message": "The given identifier is not a valid UUID" - } - }, - "InvalidRequestBodyFieldFormat": { - "summary": "Invalid request body field format", - "value": { - "message": "Invalid request body: expects x to be of type y" - } - }, - "InvalidRequestBodyFormat": { - "summary": "Invalid request body format", - "value": { - "message": "Invalid request body: given content is not a valid JSON" - } - }, - "InvalidRequestBodyId": { - "summary": "Invalid request body id", - "value": { - "message": "Invalid request body: given id is not a valid UUID" - } - }, - "MissingRequiredRequestBodyField": { - "summary": "Missing required request body field", - "value": { - "message": "Invalid request body: the field x must be present" - } - }, - "NoIdentifierWithFilter": { - "summary": "No identifier with filter", - "value": { - "message": "Invalid request: GET with identifier and query parameters, it's not allowed to use both together." - } - }, - "UnexpectedQueryParameter": { - "summary": "Unexpected query parameter", - "value": { - "message": "Unexpected query parameter: Filter is only allowed for GET requests" - } - }, "InvalidUserFormat": { "summary": "Invalid user format", "value": { @@ -2150,6 +2078,78 @@ "value": { "message": "Username x already exists" } + }, + "IdentifierMismatch": { + "summary": "Identifier mismatch", + "value": { + "message": "Identifier mismatch" + } + }, + "IdentifierNotFound": { + "summary": "Identifier not found", + "value": { + "message": "Identifier not found" + } + }, + "IdentifierPayloadIdMissmatch": { + "summary": "Identifier and payload Id missmatch", + "value": { + "message": "Identifier mismatch: the Payload id must be different from the URL identifier" + } + }, + "InvalidContentType": { + "summary": "Invalid content type", + "value": { + "message": "Invalid request header: Content-Type must be application/json" + } + }, + "InvalidFilterParameter": { + "summary": "Invalid filter parameter", + "value": { + "message": "Invalid request parameter: Filter column x is not allowed" + } + }, + "InvalidIdentifier": { + "summary": "Identifier is not valid", + "value": { + "message": "The given identifier is not a valid UUID" + } + }, + "InvalidRequestBodyFieldFormat": { + "summary": "Invalid request body field format", + "value": { + "message": "Invalid request body: expects x to be of type y" + } + }, + "InvalidRequestBodyFormat": { + "summary": "Invalid request body format", + "value": { + "message": "Invalid request body: given content is not a valid JSON" + } + }, + "InvalidRequestBodyId": { + "summary": "Invalid request body id", + "value": { + "message": "Invalid request body: given id is not a valid UUID" + } + }, + "MissingRequiredRequestBodyField": { + "summary": "Missing required request body field", + "value": { + "message": "Invalid request body: the field x must be present" + } + }, + "NoIdentifierWithFilter": { + "summary": "No identifier with filter", + "value": { + "message": "Invalid request: GET with identifier and query parameters, it's not allowed to use both together." + } + }, + "UnexpectedQueryParameter": { + "summary": "Unexpected query parameter", + "value": { + "message": "Unexpected query parameter: Filter is only allowed for GET requests" + } } }, "securitySchemes": { diff --git a/library/Notifications/Api/EndpointInterface.php b/library/Notifications/Api/EndpointInterface.php index eb3774b67..81c4acebf 100644 --- a/library/Notifications/Api/EndpointInterface.php +++ b/library/Notifications/Api/EndpointInterface.php @@ -7,5 +7,6 @@ interface EndpointInterface { public function getEndpoint(): string; + public function getAllowedMethods(): array; } diff --git a/library/Notifications/Api/Middleware/ErrorHandlingMiddleware.php b/library/Notifications/Api/Middleware/ErrorHandlingMiddleware.php index abe6fd102..c34a58878 100644 --- a/library/Notifications/Api/Middleware/ErrorHandlingMiddleware.php +++ b/library/Notifications/Api/Middleware/ErrorHandlingMiddleware.php @@ -36,9 +36,7 @@ public function process(ServerRequestInterface $request, RequestHandlerInterface return new Response( 400, ['Content-Type' => 'application/json'], - Json::sanitize([ - 'message' => $e->getMessage() - ]) + Json::sanitize(['message' => $e->getMessage()]) ); } catch (Throwable $e) { Logger::error($e); diff --git a/library/Notifications/Api/Middleware/LegacyRequestConversionMiddleware.php b/library/Notifications/Api/Middleware/LegacyRequestConversionMiddleware.php index f326d2d8e..be3ba0fd2 100644 --- a/library/Notifications/Api/Middleware/LegacyRequestConversionMiddleware.php +++ b/library/Notifications/Api/Middleware/LegacyRequestConversionMiddleware.php @@ -13,6 +13,7 @@ use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Server\MiddlewareInterface; use Psr\Http\Server\RequestHandlerInterface; +use Zend_Controller_Request_Exception; /** * LegacyRequestConversionMiddleware is a middleware that converts a legacy request @@ -55,7 +56,7 @@ public function process(ServerRequestInterface $request, RequestHandlerInterface $requestBody = $this->legacyRequest->getPost(); } catch (JsonDecodeException) { throw new HttpBadRequestException('Invalid request body: given content is not a valid JSON'); - } catch (\Zend_Controller_Request_Exception) { + } catch (Zend_Controller_Request_Exception) { throw new HttpBadRequestException('Invalid request header: Content-Type must be application/json'); } diff --git a/library/Notifications/Api/OpenApiDescriptionElement/OadV1Delete.php b/library/Notifications/Api/OpenApiDescriptionElement/OadV1Delete.php index aa2cf5e35..476da0b73 100644 --- a/library/Notifications/Api/OpenApiDescriptionElement/OadV1Delete.php +++ b/library/Notifications/Api/OpenApiDescriptionElement/OadV1Delete.php @@ -11,9 +11,6 @@ use Icinga\Module\Notifications\Api\OpenApiDescriptionElement\Response\Example\ResponseExample; use Icinga\Module\Notifications\Api\OpenApiDescriptionElement\Response\SuccessResponse; use OpenApi\Attributes\Delete; -use OpenApi\Attributes\ExternalDocumentation; -use OpenApi\Attributes\RequestBody; -use OpenApi\Attributes as OA; #[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD)] class OadV1Delete extends Delete diff --git a/library/Notifications/Api/OpenApiDescriptionElement/OadV1Get.php b/library/Notifications/Api/OpenApiDescriptionElement/OadV1Get.php index c29fc4b82..6643bde58 100644 --- a/library/Notifications/Api/OpenApiDescriptionElement/OadV1Get.php +++ b/library/Notifications/Api/OpenApiDescriptionElement/OadV1Get.php @@ -10,7 +10,6 @@ use Icinga\Module\Notifications\Api\OpenApiDescriptionElement\Response\Example\ResponseExample; use Icinga\Module\Notifications\Api\OpenApiDescriptionElement\Response\SuccessDataResponse; use OpenApi\Attributes\Get; -use OpenApi\Attributes as OA; #[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)] class OadV1Get extends Get diff --git a/library/Notifications/Api/OpenApiDescriptionElement/OadV1GetPlural.php b/library/Notifications/Api/OpenApiDescriptionElement/OadV1GetPlural.php index 2f3d56768..e22e54a79 100644 --- a/library/Notifications/Api/OpenApiDescriptionElement/OadV1GetPlural.php +++ b/library/Notifications/Api/OpenApiDescriptionElement/OadV1GetPlural.php @@ -9,7 +9,6 @@ use Icinga\Module\Notifications\Api\OpenApiDescriptionElement\Response\Example\ResponseExample; use Icinga\Module\Notifications\Api\OpenApiDescriptionElement\Response\SuccessDataResponse; use OpenApi\Attributes\Get; -use OpenApi\Attributes as OA; #[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)] class OadV1GetPlural extends Get diff --git a/library/Notifications/Api/OpenApiDescriptionElement/OadV1Post.php b/library/Notifications/Api/OpenApiDescriptionElement/OadV1Post.php index 47a4b1c01..70c310c2e 100644 --- a/library/Notifications/Api/OpenApiDescriptionElement/OadV1Post.php +++ b/library/Notifications/Api/OpenApiDescriptionElement/OadV1Post.php @@ -9,9 +9,8 @@ use Icinga\Module\Notifications\Api\OpenApiDescriptionElement\Response\ErrorResponse; use Icinga\Module\Notifications\Api\OpenApiDescriptionElement\Response\Example\ResponseExample; use Icinga\Module\Notifications\Api\OpenApiDescriptionElement\Response\SuccessResponse; -use OpenApi\Attributes\Post; -use OpenApi\Attributes\RequestBody; use OpenApi\Attributes as OA; +use OpenApi\Attributes\Post; #[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)] class OadV1Post extends Post diff --git a/library/Notifications/Api/OpenApiDescriptionElement/OadV1Put.php b/library/Notifications/Api/OpenApiDescriptionElement/OadV1Put.php index 637507dad..53a981f15 100644 --- a/library/Notifications/Api/OpenApiDescriptionElement/OadV1Put.php +++ b/library/Notifications/Api/OpenApiDescriptionElement/OadV1Put.php @@ -9,9 +9,9 @@ use Icinga\Module\Notifications\Api\OpenApiDescriptionElement\Response\ErrorResponse; use Icinga\Module\Notifications\Api\OpenApiDescriptionElement\Response\Example\ResponseExample; use Icinga\Module\Notifications\Api\OpenApiDescriptionElement\Response\SuccessResponse; +use OpenApi\Attributes as OA; use OpenApi\Attributes\Put; use OpenApi\Attributes\RequestBody; -use OpenApi\Attributes as OA; #[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)] class OadV1Put extends Put @@ -71,7 +71,7 @@ public function __construct( ], links: [ new OA\Link( - link: 'Get' . $entityName . 'ByIdentifiere', + link: 'Get' . $entityName . 'ByIdentifier', operationId: 'get' . $entityName, parameters: [ 'identifier' => '$response.header.X-Resource-Identifier' diff --git a/library/Notifications/Api/OpenApiDescriptionElement/Parameter/PathParameter.php b/library/Notifications/Api/OpenApiDescriptionElement/Parameter/PathParameter.php index 3b0ce933b..976c60d47 100644 --- a/library/Notifications/Api/OpenApiDescriptionElement/Parameter/PathParameter.php +++ b/library/Notifications/Api/OpenApiDescriptionElement/Parameter/PathParameter.php @@ -4,10 +4,10 @@ namespace Icinga\Module\Notifications\Api\OpenApiDescriptionElement\Parameter; +use OpenApi\Attributes as OA; use OpenApi\Attributes\Parameter; use OpenApi\Attributes\Schema; use OpenApi\Generator; -use OpenApi\Attributes as OA; class PathParameter extends Parameter { @@ -21,16 +21,16 @@ public function __construct( ?string $example = null, ) { $schema = $identifierSchema !== null - ? new OA\Schema(ref: '#/components/schemas/' . $identifierSchema) - : ($schema !== null ? $schema : new OA\Schema(type: 'string')); + ? new OA\Schema(ref: '#/components/schemas/' . $identifierSchema) + : ($schema !== null ? $schema : new OA\Schema(type: 'string')); $params = [ 'parameter' => $parameter ?? Generator::UNDEFINED, - 'name' => $name ?? Generator::UNDEFINED, - 'description' => $description ?? Generator::UNDEFINED, - 'in' => 'path', - 'required' => $required ?? true, - 'schema' => $schema, + 'name' => $name ?? Generator::UNDEFINED, + 'description' => $description ?? Generator::UNDEFINED, + 'in' => 'path', + 'required' => $required ?? true, + 'schema' => $schema, ]; $params = $example !== null ? array_merge($params, ['example' => $example]) : $params; diff --git a/library/Notifications/Api/OpenApiDescriptionElement/Parameter/QueryParameter.php b/library/Notifications/Api/OpenApiDescriptionElement/Parameter/QueryParameter.php index 82cec69d8..4c0f2f28e 100644 --- a/library/Notifications/Api/OpenApiDescriptionElement/Parameter/QueryParameter.php +++ b/library/Notifications/Api/OpenApiDescriptionElement/Parameter/QueryParameter.php @@ -4,8 +4,8 @@ namespace Icinga\Module\Notifications\Api\OpenApiDescriptionElement\Parameter; -use OpenApi\Attributes\Parameter; use OpenApi\Attributes as OA; +use OpenApi\Attributes\Parameter; use OpenApi\Attributes\Schema; class QueryParameter extends Parameter @@ -32,8 +32,8 @@ public function __construct( 'schema' => $schema, ]; - $params = $example !== null ? array_merge($params, ['example' => $example]) : $params; + $params = $example !== null ? array_merge($params, ['example' => $example]) : $params; - parent::__construct(...$params); + parent::__construct(...$params); } } diff --git a/library/Notifications/Api/OpenApiDescriptionElement/Response/Error404Response.php b/library/Notifications/Api/OpenApiDescriptionElement/Response/Error404Response.php index 4c1b7bac6..918fe7c71 100644 --- a/library/Notifications/Api/OpenApiDescriptionElement/Response/Error404Response.php +++ b/library/Notifications/Api/OpenApiDescriptionElement/Response/Error404Response.php @@ -4,12 +4,9 @@ namespace Icinga\Module\Notifications\Api\OpenApiDescriptionElement\Response; -use OpenApi\Attributes\Attachable; use OpenApi\Attributes\Examples; use OpenApi\Attributes\JsonContent; -use OpenApi\Attributes\MediaType; use OpenApi\Attributes\Response; -use OpenApi\Attributes\XmlContent; class Error404Response extends Response { diff --git a/library/Notifications/Api/OpenApiDescriptionElement/Response/ErrorResponse.php b/library/Notifications/Api/OpenApiDescriptionElement/Response/ErrorResponse.php index 5e10f896c..7be183a15 100644 --- a/library/Notifications/Api/OpenApiDescriptionElement/Response/ErrorResponse.php +++ b/library/Notifications/Api/OpenApiDescriptionElement/Response/ErrorResponse.php @@ -4,8 +4,9 @@ namespace Icinga\Module\Notifications\Api\OpenApiDescriptionElement\Response; -use OpenApi\Attributes\Response; +use InvalidArgumentException; use OpenApi\Attributes as OA; +use OpenApi\Attributes\Response; #[OA\Schema( schema: 'ErrorResponse', @@ -19,7 +20,6 @@ ], type: 'object', )] - class ErrorResponse extends Response { public const ERROR_RESPONSES = [ @@ -43,7 +43,7 @@ public function __construct( if (isset(self::ERROR_RESPONSES[$response])) { $description = self::ERROR_RESPONSES[$response]; } else { - throw new \InvalidArgumentException('Unexpected response type'); + throw new InvalidArgumentException('Unexpected response type'); } parent::__construct( diff --git a/library/Notifications/Api/OpenApiDescriptionElement/Response/SuccessDataResponse.php b/library/Notifications/Api/OpenApiDescriptionElement/Response/SuccessDataResponse.php index e6f2af366..e85157ca6 100644 --- a/library/Notifications/Api/OpenApiDescriptionElement/Response/SuccessDataResponse.php +++ b/library/Notifications/Api/OpenApiDescriptionElement/Response/SuccessDataResponse.php @@ -4,8 +4,8 @@ namespace Icinga\Module\Notifications\Api\OpenApiDescriptionElement\Response; -use OpenApi\Attributes\Response; use OpenApi\Attributes as OA; +use OpenApi\Attributes\Response; class SuccessDataResponse extends Response { @@ -33,7 +33,7 @@ public function __construct( new OA\Property( property: 'data', ref: '#/components/schemas/' . $entityName, - description: sprintf('Successfull response with the %s object', $entityName), + description: sprintf('Successful response with the %s object', $entityName), type: 'object', ), ] diff --git a/library/Notifications/Api/OpenApiDescriptionElement/Response/SuccessResponse.php b/library/Notifications/Api/OpenApiDescriptionElement/Response/SuccessResponse.php index aa9947fa0..b527a2762 100644 --- a/library/Notifications/Api/OpenApiDescriptionElement/Response/SuccessResponse.php +++ b/library/Notifications/Api/OpenApiDescriptionElement/Response/SuccessResponse.php @@ -4,8 +4,9 @@ namespace Icinga\Module\Notifications\Api\OpenApiDescriptionElement\Response; -use OpenApi\Attributes\Response; +use InvalidArgumentException; use OpenApi\Attributes as OA; +use OpenApi\Attributes\Response; #[OA\Schema( schema: 'SuccessResponse', @@ -35,7 +36,7 @@ public function __construct( ?array $links = null, ) { if (! isset(self::SUCCESS_RESPONSES[$response])) { - throw new \InvalidArgumentException('Unexpected response type'); + throw new InvalidArgumentException('Unexpected response type'); } $content = $response !== 204 diff --git a/library/Notifications/Api/V1/ApiV1.php b/library/Notifications/Api/V1/ApiV1.php index d594bad5f..516caad1d 100644 --- a/library/Notifications/Api/V1/ApiV1.php +++ b/library/Notifications/Api/V1/ApiV1.php @@ -11,16 +11,16 @@ use Icinga\Exception\Json\JsonEncodeException; use Icinga\Module\Notifications\Api\ApiCore; use Icinga\Module\Notifications\Api\Exception\InvalidFilterParameterException; -use Icinga\Module\Notifications\Common\HttpMethod; use Icinga\Module\Notifications\Common\Database; +use Icinga\Module\Notifications\Common\HttpMethod; use Icinga\Util\Json; use ipl\Sql\Compat\FilterProcessor; use ipl\Sql\Select; use ipl\Stdlib\Filter\Condition; use ipl\Web\Filter\QueryString; +use OpenApi\Attributes as OA; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; -use OpenApi\Attributes as OA; use Ramsey\Uuid\Uuid; use stdClass; @@ -92,6 +92,7 @@ public function handleRequest(ServerRequestInterface $request): ResponseInterfac * Override this method to modify the row before it is returned in the response. * * @param stdClass $row + * * @return void */ public function prepareRow(stdClass $row): void diff --git a/library/Notifications/Api/V1/Channels.php b/library/Notifications/Api/V1/Channels.php index ab9a21bcd..4d066073a 100644 --- a/library/Notifications/Api/V1/Channels.php +++ b/library/Notifications/Api/V1/Channels.php @@ -8,10 +8,10 @@ use Icinga\Exception\Http\HttpNotFoundException; use Icinga\Exception\Json\JsonEncodeException; use Icinga\Module\Notifications\Api\EndpointInterface; +use Icinga\Module\Notifications\Api\OpenApiDescriptionElement\OadV1Get; use Icinga\Module\Notifications\Api\OpenApiDescriptionElement\OadV1GetPlural; use Icinga\Module\Notifications\Api\OpenApiDescriptionElement\Parameter\PathParameter; use Icinga\Module\Notifications\Api\OpenApiDescriptionElement\Parameter\QueryParameter; -use Icinga\Module\Notifications\Api\OpenApiDescriptionElement\OadV1Get; use Icinga\Module\Notifications\Api\OpenApiDescriptionElement\Schema\SchemaUUID; use Icinga\Module\Notifications\Common\Database; use Icinga\Util\Json; @@ -74,7 +74,9 @@ public function getEndpoint(): string * * @param string|null $identifier * @param string $queryFilter + * * @return ResponseInterface + * * @throws HttpBadRequestException * @throws HttpNotFoundException * @throws JsonEncodeException diff --git a/library/Notifications/Api/V1/ContactGroups.php b/library/Notifications/Api/V1/ContactGroups.php index 666d98048..01a0be34b 100644 --- a/library/Notifications/Api/V1/ContactGroups.php +++ b/library/Notifications/Api/V1/ContactGroups.php @@ -620,6 +620,7 @@ private function assertValidRequestBody(array $requestBody): void * @param requestBody $requestBody * * @return void + * * @throws HttpException */ private function addContactgroup(array $requestBody): void @@ -785,6 +786,7 @@ private function assertUniqueName(string $name, int $contactgroupId = null): voi * Fetch the values from the database * * @param int $contactgroupId + * * @return array * * @throws HttpNotFoundException @@ -795,6 +797,7 @@ private function fetchDbValues(int $contactgroupId): array ->columns(['id', 'name']) ->filter(Filter::equal('id', $contactgroupId)); + /** @var ?Contactgroup $group */ $group = $query->first(); if ($group === null) { throw new HttpNotFoundException('Contact group not found'); diff --git a/library/Notifications/Api/V1/Contacts.php b/library/Notifications/Api/V1/Contacts.php index f7bdab2bf..8fa8db98a 100644 --- a/library/Notifications/Api/V1/Contacts.php +++ b/library/Notifications/Api/V1/Contacts.php @@ -10,9 +10,6 @@ use Icinga\Exception\Http\HttpNotFoundException; use Icinga\Exception\Json\JsonEncodeException; use Icinga\Module\Notifications\Api\EndpointInterface; -use Icinga\Module\Notifications\Model\Contact; -use Psr\Http\Message\ResponseInterface; -use Psr\Http\Server\RequestHandlerInterface; use Icinga\Module\Notifications\Api\OpenApiDescriptionElement\OadV1Delete; use Icinga\Module\Notifications\Api\OpenApiDescriptionElement\OadV1Get; use Icinga\Module\Notifications\Api\OpenApiDescriptionElement\OadV1GetPlural; @@ -22,16 +19,19 @@ use Icinga\Module\Notifications\Api\OpenApiDescriptionElement\Parameter\QueryParameter; use Icinga\Module\Notifications\Api\OpenApiDescriptionElement\Response\Example\ResponseExample; use Icinga\Module\Notifications\Api\OpenApiDescriptionElement\Schema\SchemaUUID; -use Ramsey\Uuid\Uuid; use Icinga\Module\Notifications\Common\Database; +use Icinga\Module\Notifications\Model\Contact; use Icinga\Module\Notifications\Model\Rotation; use Icinga\Module\Notifications\Model\RotationMember; use Icinga\Module\Notifications\Model\RuleEscalationRecipient; use Icinga\Util\Json; use ipl\Sql\Select; use ipl\Stdlib\Filter; -use stdClass; use OpenApi\Attributes as OA; +use Psr\Http\Message\ResponseInterface; +use Psr\Http\Server\RequestHandlerInterface; +use Ramsey\Uuid\Uuid; +use stdClass; /** * @phpstan-type requestBody array{ @@ -509,10 +509,10 @@ public function delete(string $identifier): ResponseInterface public function prepareRow(stdClass $row): void { - $row->groups = ContactGroups::fetchGroupIdentifiers($row->contact_id); - $row->addresses = self::fetchContactAddresses($row->contact_id) ?: new stdClass(); + $row->groups = ContactGroups::fetchGroupIdentifiers($row->contact_id); + $row->addresses = self::fetchContactAddresses($row->contact_id) ?: new stdClass(); - unset($row->contact_id); + unset($row->contact_id); } /** @@ -576,6 +576,7 @@ public static function getContactId(string $identifier): ?int * @param string[] $groups * * @return void + * * @throws HttpException */ private function addGroups(int $contactId, array $groups): void @@ -624,6 +625,7 @@ private function addAddresses(int $contactId, array $addresses): void * @param requestBody $requestBody * * @return void + * * @throws HttpException */ private function addContact(array $requestBody): void @@ -999,6 +1001,7 @@ public static function fetchUserIdentifiers(int $contactgroupId): array * Fetch the values from the database * * @param int $contactId + * * @return array * * @throws HttpNotFoundException @@ -1009,6 +1012,7 @@ private function fetchDbValues(int $contactId): array ->columns(['id', 'full_name', 'default_channel_id']) ->filter(Filter::equal('id', $contactId)); + /** @var ?Contact $contact */ $contact = $query->first(); if ($contact === null) { throw new HttpNotFoundException('Contact contact not found'); diff --git a/library/Notifications/Common/Database.php b/library/Notifications/Common/Database.php index c5fc689e2..1163da597 100644 --- a/library/Notifications/Common/Database.php +++ b/library/Notifications/Common/Database.php @@ -4,7 +4,6 @@ namespace Icinga\Module\Notifications\Common; -use DateTime; use Icinga\Application\Config as AppConfig; use Icinga\Data\ResourceFactory; use Icinga\Exception\ConfigurationError; @@ -43,8 +42,8 @@ final class Database 'timeperiod_entry', ]; - /** @var Connection Database connection */ - private static $instance; + /** @var ?Connection Database connection */ + private static ?Connection $instance = null; /** Singleton class */ private function __construct() @@ -166,7 +165,7 @@ private static function getConnection(): Connection // getNextChangedAt() wants MAX(changed_at) of all rows, deleted or not foreach ($select->getColumns() as $column) { - if ($column instanceof Expression && strpos($column->getStatement(), 'MAX(changed_at)') !== false) { + if ($column instanceof Expression && str_contains($column->getStatement(), 'MAX(changed_at)')) { return; } } @@ -208,7 +207,7 @@ private static function getConnection(): Connection * * @return int The given timestamp or 1 + the maximum changed_at value in the table, whichever is greater */ - private static function getNextChangedAt(Connection $db, string $table, $nowUnixMilli) + private static function getNextChangedAt(Connection $db, string $table, $nowUnixMilli): int { return $db->select( (new Select()) @@ -264,6 +263,7 @@ public static function registerGroupBy(Query $query, Select $select): void /** * Check if the given condition is part of the where clause with value 'y' * + * @param string $baseTable * @param string $conditionToFind * @param array $where * @@ -275,9 +275,8 @@ private static function hasCondition(string $baseTable, string $conditionToFind, if (is_array($value)) { $found = self::hasCondition($baseTable, $conditionToFind, $value); } else { - $found = ( - $condition === $conditionToFind || $condition === $baseTable . '.' . $conditionToFind - ) && $value === 'y'; + $found = ($condition === $conditionToFind || $condition === $baseTable . '.' . $conditionToFind) + && $value === 'y'; } if ($found) { diff --git a/library/Notifications/Common/HttpMethod.php b/library/Notifications/Common/HttpMethod.php index b25993733..033437dea 100644 --- a/library/Notifications/Common/HttpMethod.php +++ b/library/Notifications/Common/HttpMethod.php @@ -5,7 +5,6 @@ namespace Icinga\Module\Notifications\Common; use Psr\Http\Message\ServerRequestInterface; -use StringBackedEnum; enum HttpMethod: string { diff --git a/library/Notifications/Common/LoadMore.php b/library/Notifications/Common/LoadMore.php index e9d1eef4b..f6a9e8c3e 100644 --- a/library/Notifications/Common/LoadMore.php +++ b/library/Notifications/Common/LoadMore.php @@ -7,19 +7,20 @@ use Generator; use Icinga\Module\Notifications\Widget\ItemList\PageSeparatorItem; use Icinga\Module\Notifications\Widget\ShowMore; +use ipl\Html\Attributes; use ipl\Orm\ResultSet; use ipl\Web\Url; trait LoadMore { - /** @var int */ - protected $pageSize; + /** @var ?int */ + protected ?int $pageSize = null; - /** @var int */ - protected $pageNumber; + /** @var ?int */ + protected ?int $pageNumber = null; - /** @var Url */ - protected $loadMoreUrl; + /** @var ?Url */ + protected ?Url $loadMoreUrl = null; /** * Set the page size @@ -28,7 +29,7 @@ trait LoadMore * * @return $this */ - public function setPageSize(int $size): self + public function setPageSize(int $size): static { $this->pageSize = $size; @@ -42,7 +43,7 @@ public function setPageSize(int $size): self * * @return $this */ - public function setPageNumber(int $number): self + public function setPageNumber(int $number): static { $this->pageNumber = $number; @@ -56,7 +57,7 @@ public function setPageNumber(int $number): self * * @return $this */ - public function setLoadMoreUrl(Url $url): self + public function setLoadMoreUrl(Url $url): static { $this->loadMoreUrl = $url; @@ -101,7 +102,7 @@ protected function getIterator(ResultSet $result): Generator ->setLabel(t('Load More')) ->setAttribute('data-no-icinga-ajax', true); - $this->add($showMore->setTag('li')->addAttributes(['class' => 'list-item'])); + $this->add($showMore->setTag('li')->addAttributes(Attributes::create(['class' => 'list-item']))); } } } diff --git a/library/Notifications/Common/NoSubjectLink.php b/library/Notifications/Common/NoSubjectLink.php index b3173d3c2..80d410388 100644 --- a/library/Notifications/Common/NoSubjectLink.php +++ b/library/Notifications/Common/NoSubjectLink.php @@ -7,7 +7,7 @@ trait NoSubjectLink { /** @var bool */ - protected $noSubjectLink = false; + protected bool $noSubjectLink = false; /** * Set whether a list item's subject should be a link diff --git a/library/Notifications/Common/PsrLogger.php b/library/Notifications/Common/PsrLogger.php index 3a7542e5f..725667318 100644 --- a/library/Notifications/Common/PsrLogger.php +++ b/library/Notifications/Common/PsrLogger.php @@ -24,6 +24,8 @@ class PsrLogger implements LoggerInterface * Map PSR-3 levels to Icinga's 4 levels. * emergency/alert/critical -> ERROR * notice -> INFO + * + * @var array */ private const MAP = [ LogLevel::EMERGENCY => 'error', @@ -42,8 +44,10 @@ class PsrLogger implements LoggerInterface * @param string $level The log level * @param string|Stringable $message The log message * @param array $context Additional context variables to interpolate in the message + * + * @return void */ - public function log($level, string|\Stringable $message, array $context = []): void + public function log($level, string|Stringable $message, array $context = []): void { $level = strtolower((string) $level); $icingaMethod = self::MAP[$level] ?? 'debug'; diff --git a/library/Notifications/Daemon/Daemon.php b/library/Notifications/Daemon/Daemon.php index 374c23be9..bc7af53f6 100644 --- a/library/Notifications/Daemon/Daemon.php +++ b/library/Notifications/Daemon/Daemon.php @@ -4,8 +4,6 @@ namespace Icinga\Module\Notifications\Daemon; -use DateTimeInterface; -use DateTimeZone; use Evenement\EventEmitter; use Icinga\Application\Logger; use Icinga\Module\Notifications\Common\Database; @@ -16,7 +14,6 @@ use Icinga\Module\Notifications\Model\Daemon\EventIdentifier; use Icinga\Module\Notifications\Model\Incident; use Icinga\Module\Notifications\Model\IncidentHistory; -use Icinga\Module\Notifications\Model\ObjectIdTag; use ipl\Sql\Connection as SQLConnection; use ipl\Stdlib\Filter; use React\EventLoop\Loop; @@ -27,34 +24,35 @@ class Daemon extends EventEmitter { + /** @var string */ protected const PREFIX = '[daemon] - '; /** @var Logger Instance of the logger class */ - protected static $logger; + protected static Logger $logger; - /** @var Daemon Instance of this class */ - private static $instance; + /** @var ?Daemon Instance of this class */ + private static ?Daemon $instance = null; /** @var LoopInterface Main loop */ - protected $loop; + protected LoopInterface $loop; /** @var Server Server object */ - protected $server; + protected Server $server; /** @var Sender Sender object */ - protected $sender; + protected Sender $sender; /** @var SQLConnection Database object */ - protected $database; + protected SQLConnection $database; /** @var bool Token which can be triggered to exit the main routine */ - protected $cancellationToken; + protected bool $cancellationToken; /** @var int Timestamp holding the creation's time of this {@see self::$instance instance} */ - protected $initializedAt; + protected int $initializedAt; - /** @var int Last checked incident identifier */ - protected $lastIncidentId; + /** @var ?int Last checked incident identifier */ + protected ?int $lastIncidentId = null; /** * Construct the singleton instance of the Daemon class @@ -151,9 +149,9 @@ protected function reload(): void * * @param bool $isManualShutdown manual trigger for the shutdown * - * @return never-return + * @return never */ - protected function shutdown(bool $isManualShutdown = false) + protected function shutdown(bool $isManualShutdown = false): never { self::$logger::info(self::PREFIX . "shutting down" . ($isManualShutdown ? " (manually triggered)" : "")); diff --git a/library/Notifications/Daemon/Sender.php b/library/Notifications/Daemon/Sender.php index 3b695c530..dc40594a2 100644 --- a/library/Notifications/Daemon/Sender.php +++ b/library/Notifications/Daemon/Sender.php @@ -11,22 +11,23 @@ class Sender { + /** @var string */ protected const PREFIX = '[daemon.sender] - '; - /** @var Sender Instance of this class */ - private static $instance; + /** @var ?Sender Instance of this class */ + private static ?Sender $instance = null; /** @var Logger Instance of the logger class */ - protected static $logger; + protected static Logger $logger; /** @var Daemon Daemon object reference */ - protected static $daemon; + protected static Daemon $daemon; /** @var Server Server object reference */ - protected static $server; + protected static Server $server; /** @var Closure {@see processNotification()} wrapper */ - protected $callback; + protected Closure $callback; /** * Construct the singleton instance of the Sender class diff --git a/library/Notifications/Daemon/Server.php b/library/Notifications/Daemon/Server.php index 26d51f4b4..01cebf27f 100644 --- a/library/Notifications/Daemon/Server.php +++ b/library/Notifications/Daemon/Server.php @@ -23,31 +23,32 @@ class Server { + /** @var string */ protected const PREFIX = '[daemon.server] - '; - /** @var Server Instance of this class */ - private static $instance; + /** @var ?Server Instance of this class */ + private static ?Server $instance = null; - /** @var LoopInterface Reference to ReactPHP's main loop */ - protected $mainLoop; + /** @var ?LoopInterface Reference to ReactPHP's main loop */ + protected ?LoopInterface $mainLoop = null; /** @var Logger Instance of the logger class */ - protected static $logger; + protected static Logger $logger; /** @var SocketServer SocketServer object */ - protected $socket; + protected SocketServer $socket; /** @var HttpServer HttpServer object */ - protected $http; + protected HttpServer $http; /** @var array Socket connections */ - protected $connections; + protected array $connections; /** @var SQLConnection Database object */ - protected $dbLink; + protected SQLConnection $dbLink; /** @var Config Config object */ - protected $config; + protected Config $config; /** * Construct the singleton instance of the Server class diff --git a/library/Notifications/Hook/ObjectsRendererHook.php b/library/Notifications/Hook/ObjectsRendererHook.php index b609f314a..018b1e3e8 100644 --- a/library/Notifications/Hook/ObjectsRendererHook.php +++ b/library/Notifications/Hook/ObjectsRendererHook.php @@ -29,7 +29,7 @@ abstract class ObjectsRendererHook * * @var array>> */ - private static $objectIdTags = []; + private static array $objectIdTags = []; /** * Array of HTMLs for objects with their corresponding object IDs as keys @@ -38,7 +38,7 @@ abstract class ObjectsRendererHook * * @var array */ - private static $objectNameHtmls = []; + private static array $objectNameHtmls = []; /** * Array of object names with their corresponding object IDs as keys @@ -47,7 +47,7 @@ abstract class ObjectsRendererHook * * @var array */ - private static $objectNames = []; + private static array $objectNames = []; /** * Get the object names for the objects using the object ID tags @@ -226,8 +226,6 @@ final public static function getObjectName(Objects $obj): BaseHtmlElement * If the object name is not loaded, it is prepared using object ID tags and the same is returned. * * @param Objects $obj - * @param bool $prepare If true prepares the object name string from the hook implementation if it is not - * already present in the cache * * @return string */ diff --git a/library/Notifications/Model/Behavior/IcingaCustomVars.php b/library/Notifications/Model/Behavior/IcingaCustomVars.php index 42c1d8e4e..13dfc964c 100644 --- a/library/Notifications/Model/Behavior/IcingaCustomVars.php +++ b/library/Notifications/Model/Behavior/IcingaCustomVars.php @@ -26,7 +26,7 @@ public function isSelectableColumn(string $name): bool || str_starts_with($name, self::SERVICE_PREFIX); } - public function rewriteColumn($column, ?string $relation = null) + public function rewriteColumn($column, ?string $relation = null): null { return null; } @@ -53,7 +53,7 @@ public function rewriteColumnDefinition(ColumnDefinition $def, string $relation) )); } - public function rewriteCondition(Filter\Condition $condition, $relation = null) + public function rewriteCondition(Filter\Condition $condition, $relation = null): Filter\Condition|Filter\Rule|null { if (! $this->isSelectableColumn($condition->metaData()->get('columnName', ''))) { return null; diff --git a/library/Notifications/Model/Behavior/IdTagAggregator.php b/library/Notifications/Model/Behavior/IdTagAggregator.php index eb8e81ace..3e48b9a4d 100644 --- a/library/Notifications/Model/Behavior/IdTagAggregator.php +++ b/library/Notifications/Model/Behavior/IdTagAggregator.php @@ -19,8 +19,8 @@ class IdTagAggregator extends PropertyBehavior implements RewriteColumnBehavior, QueryAwareBehavior { - /** @var Query */ - protected $query; + /** @var ?Query */ + protected ?Query $query = null; final public function __construct() { @@ -28,9 +28,12 @@ final public function __construct() parent::__construct(['id_tags']); } - public function setQuery(Query $query) + /** @return $this */ + public function setQuery(Query $query): static { $this->query = $query; + + return $this; } public function rewriteColumn($column, ?string $relation = null) @@ -68,7 +71,8 @@ public function isSelectableColumn(string $name): bool return $name === 'id_tags'; } - public function fromDb($value, $key, $context) + /** @return array */ + public function fromDb($value, $key, $context): array { if (! is_string($value)) { return []; @@ -82,7 +86,16 @@ public function fromDb($value, $key, $context) return $tags; } - public function toDb($value, $key, $context) + /** + * @param mixed $value + * @param mixed $key + * @param mixed $context + * + * @return never + * + * @throws InvalidColumnException + */ + public function toDb($value, $key, $context): never { throw new InvalidColumnException($key, new Objects()); } diff --git a/library/Notifications/Model/Behavior/ObjectTags.php b/library/Notifications/Model/Behavior/ObjectTags.php index e466140f6..2659ff61c 100644 --- a/library/Notifications/Model/Behavior/ObjectTags.php +++ b/library/Notifications/Model/Behavior/ObjectTags.php @@ -15,8 +15,8 @@ class ObjectTags implements RewriteColumnBehavior, QueryAwareBehavior { use Auth; - /** @var Query */ - protected $query; + /** @var ?Query */ + protected ?Query $query = null; public function setQuery(Query $query): self { @@ -32,7 +32,7 @@ public function rewriteCondition(Filter\Condition $condition, $relation = null): /** @var ?string $column */ $column = $condition->metaData()->get('columnName'); if ($column !== null) { - if (substr($relation, -10) === 'extra_tag.') { + if (str_ends_with($relation, 'extra_tag.')) { $relation = substr($relation, 0, -10) . 'object_extra_tag.'; } else { // tag. $relation = substr($relation, 0, -4) . 'object_id_tag.'; diff --git a/library/Notifications/Model/Channel.php b/library/Notifications/Model/Channel.php index 4f6a8b4f5..ebc6f6a2a 100644 --- a/library/Notifications/Model/Channel.php +++ b/library/Notifications/Model/Channel.php @@ -95,17 +95,10 @@ public function createRelations(Relations $relations): void */ public function getIcon(): Icon { - switch ($this->type) { - case 'rocketchat': - $icon = new Icon('comment-dots'); - break; - case 'email': - $icon = new Icon('at'); - break; - default: - $icon = new Icon('envelope'); - } - - return $icon; + return match ($this->type) { + 'rocketchat' => new Icon('comment-dots'), + 'email' => new Icon('at'), + default => new Icon('envelope') + }; } } diff --git a/library/Notifications/Model/Daemon/Connection.php b/library/Notifications/Model/Daemon/Connection.php index f2fb050a7..7898ab6b1 100644 --- a/library/Notifications/Model/Daemon/Connection.php +++ b/library/Notifications/Model/Daemon/Connection.php @@ -10,25 +10,25 @@ class Connection { /** @var ConnectionInterface Associated Connection from ReactPHP */ - protected $connection; + protected ConnectionInterface $connection; /** @var string Hostname */ - protected $host; + protected string $host; /** @var int Port */ - protected $port; + protected int $port; /** @var string Session identifier */ - protected $session; + protected string $session; /** @var User User information */ - protected $user; + protected User $user; /** @var ThroughStream Data stream between connection and server */ - protected $stream; + protected ThroughStream $stream; - /** @var string User agent */ - protected $userAgent; + /** @var ?string User agent */ + protected ?string $userAgent = null; /** * Construct an instance of the Connection class @@ -70,7 +70,7 @@ public function getAddress(): string return $this->host . ':' . $this->port; } - public function getSession(): ?string + public function getSession(): string { return $this->session; } @@ -111,7 +111,7 @@ public function setUserAgent(string $userAgent): void * @return object{host: string, port: string, addr: string} | false Host, port and full address or false if the * parsing failed */ - public static function parseHostAndPort(?string $address) + public static function parseHostAndPort(?string $address): object|false { if ($address === null) { return false; @@ -132,9 +132,9 @@ public static function parseHostAndPort(?string $address) return false; } - if (strpos($host, '[') !== false) { + if (str_contains($host, '[')) { // IPv6 format - if (strpos($host, '.')) { + if (str_contains($host, '.')) { // IPv4 represented in IPv6 $offset = strrpos($host, ':'); $parsed->host = substr($host, $offset === false ? 0 : $offset + 1, -1); diff --git a/library/Notifications/Model/Daemon/Event.php b/library/Notifications/Model/Daemon/Event.php index 6339885e4..5a4fd6374 100644 --- a/library/Notifications/Model/Daemon/Event.php +++ b/library/Notifications/Model/Daemon/Event.php @@ -13,22 +13,22 @@ class Event { /** @var string Event identifier */ - protected $identifier; + protected string $identifier; /** @var stdClass Event data */ - protected $data; + protected stdClass $data; /** @var DateTime Creation date of event */ - protected $createdAt; + protected DateTime $createdAt; /** @var int Reconnect interval in milliseconds */ - protected $reconnectInterval; + protected int $reconnectInterval; /** @var int Last event identifier */ - protected $lastEventId; + protected int $lastEventId; /** @var int Contact identifier associated with this event */ - protected $contact; + protected int $contact; public function __construct(string $identifier, int $contact, stdClass $data, int $lastEventId = 0) { @@ -81,6 +81,7 @@ public function setReconnectInterval(int $reconnectInterval): void * {@link https://html.spec.whatwg.org/multipage/server-sent-events.html#parsing-an-event-stream SSE Spec} * * @return string + * * @throws JsonEncodeException */ protected function compileMessage(): string diff --git a/library/Notifications/Model/Daemon/User.php b/library/Notifications/Model/Daemon/User.php index 779159bf9..4a6fdbfcc 100644 --- a/library/Notifications/Model/Daemon/User.php +++ b/library/Notifications/Model/Daemon/User.php @@ -7,16 +7,10 @@ class User { /** @var ?string Username */ - protected $username; + protected ?string $username = null; /** @var ?int Contact identifier */ - protected $contactId; - - public function __construct() - { - $this->username = null; - $this->contactId = null; - } + protected ?int $contactId = null; public function getUsername(): ?string { diff --git a/library/Notifications/Model/Event.php b/library/Notifications/Model/Event.php index 368568a51..32d34c201 100644 --- a/library/Notifications/Model/Event.php +++ b/library/Notifications/Model/Event.php @@ -131,39 +131,18 @@ public function getSeverityText(): ?string public static function mapSeverity(?string $severity): ?string { - switch ($severity) { - case 'ok': - $label = t('Ok', 'noma.severity'); - break; - case 'crit': - $label = t('Critical', 'noma.severity'); - break; - case 'warning': - $label = t('Warning', 'noma.severity'); - break; - case 'err': - $label = t('Error', 'noma.severity'); - break; - case 'debug': - $label = t('Debug', 'noma.severity'); - break; - case 'info': - $label = t('Information', 'noma.severity'); - break; - case 'alert': - $label = t('Alert', 'noma.severity'); - break; - case 'emerg': - $label = t('Emergency', 'noma.severity'); - break; - case 'notice': - $label = t('Notice', 'noma.severity'); - break; - default: - $label = null; - } - - return $label; + return match ($severity) { + 'ok' => t('Ok', 'notifications.severity'), + 'crit' => t('Critical', 'notifications.severity'), + 'warning' => t('Warning', 'notifications.severity'), + 'err' => t('Error', 'notifications.severity'), + 'debug' => t('Debug', 'notifications.severity'), + 'info' => t('Information', 'notifications.severity'), + 'alert' => t('Alert', 'notifications.severity'), + 'emerg' => t('Emergency', 'notifications.severity'), + 'notice' => t('Notice', 'notifications.severity'), + default => null + }; } /** @@ -181,30 +160,19 @@ public function getTypeText(): string return t('ran into a problem', 'notifications.type'); } - switch ($this->type) { - case 'acknowledgement-set': - return t('has been acknowledged', 'notifications.type'); - case 'acknowledgement-cleared': - return t('was unacknowledged', 'notifications.type'); - case 'downtime-start': - return t('entered a downtime period', 'notifications.type'); - case 'downtime-end': - return t('left a downtime period', 'notifications.type'); - case 'downtime-removed': - return t('prematurely left a downtime period', 'notifications.type'); - case 'flapping-start': - return t('entered a flapping period', 'notifications.type'); - case 'flapping-end': - return t('left a flapping period', 'notifications.type'); - case 'incident-age': - return t('exceeded a time constraint', 'notifications.type'); - case 'mute': - return t('was muted', 'notifications.type'); - case 'unmute': - return t('was unmuted', 'notifications.type'); - default: // custom - return ''; - } + return match ($this->type) { + 'acknowledgement-set' => t('has been acknowledged', 'notifications.type'), + 'acknowledgement-cleared' => t('was unacknowledged', 'notifications.type'), + 'downtime-start' => t('entered a downtime period', 'notifications.type'), + 'downtime-end' => t('left a downtime period', 'notifications.type'), + 'downtime-removed' => t('prematurely left a downtime period', 'notifications.type'), + 'flapping-start' => t('entered a flapping period', 'notifications.type'), + 'flapping-end' => t('left a flapping period', 'notifications.type'), + 'incident-age' => t('exceeded a time constraint', 'notifications.type'), + 'mute' => t('was muted', 'notifications.type'), + 'unmute' => t('was unmuted', 'notifications.type'), + default => '' // custom + }; } /** @@ -214,74 +182,37 @@ public function getTypeText(): string */ public function getIcon(): ?Icon { - $icon = null; - if ($this->type === 'state') { $severity = $this->severity; $class = 'severity-' . $severity; - switch ($severity) { - case 'ok': - $icon = (new Icon(Icons::SEVERITY_OK, ['class' => $class]))->setStyle('fa-regular'); - break; - case 'crit': - $icon = new Icon(Icons::SEVERITY_CRIT, ['class' => $class]); - break; - case 'warning': - $icon = new Icon(Icons::SEVERITY_WARN, ['class' => $class]); - break; - case 'err': - $icon = (new Icon(Icons::SEVERITY_ERR, ['class' => $class]))->setStyle('fa-regular'); - break; - case 'debug': - $icon = new Icon(Icons::SEVERITY_DEBUG); - break; - case 'info': - $icon = new Icon(Icons::SEVERITY_INFO); - break; - case 'alert': - $icon = new Icon(Icons::SEVERITY_ALERT); - break; - case 'emerg': - $icon = new Icon(Icons::SEVERITY_EMERG); - break; - case 'notice': - $icon = new Icon(Icons::SEVERITY_NOTICE); - break; - } - - return $icon; - } - switch ($this->type) { - case 'acknowledgement-set': - $icon = new Icon(Icons::ACKNOWLEDGED); - break; - case 'acknowledgement-cleared': - $icon = new Icon(Icons::UNACKNOWLEDGED); - break; - case 'downtime-start': - case 'downtime-end': - case 'downtime-removed': - $icon = new Icon(Icons::DOWNTIME); - break; - case 'flapping-start': - case 'flapping-end': - $icon = new Icon(Icons::FLAPPING); - break; - case 'incident-age': - $icon = new Icon(Icons::INCIDENT_AGE); - break; - case 'custom': - $icon = new Icon(Icons::CUSTOM); - break; - case 'mute': - $icon = new Icon(Icons::MUTE); - break; - case 'unmute': - $icon = new Icon(Icons::UNMUTE); - break; + return match ($severity) { + 'ok' => (new Icon(Icons::SEVERITY_OK, ['class' => $class]))->setStyle('fa-regular'), + 'crit' => new Icon(Icons::SEVERITY_CRIT, ['class' => $class]), + 'warning' => new Icon(Icons::SEVERITY_WARN, ['class' => $class]), + 'err' => (new Icon(Icons::SEVERITY_ERR, ['class' => $class]))->setStyle('fa-regular'), + 'debug' => new Icon(Icons::SEVERITY_DEBUG), + 'info' => new Icon(Icons::SEVERITY_INFO), + 'alert' => new Icon(Icons::SEVERITY_ALERT), + 'emerg' => new Icon(Icons::SEVERITY_EMERG), + 'notice' => new Icon(Icons::SEVERITY_NOTICE), + default => null + }; } - return $icon; + return match ($this->type) { + 'acknowledgement-set' => new Icon(Icons::ACKNOWLEDGED), + 'acknowledgement-cleared' => new Icon(Icons::UNACKNOWLEDGED), + 'downtime-start', + 'downtime-end', + 'downtime-removed' => new Icon(Icons::DOWNTIME), + 'flapping-start', + 'flapping-end' => new Icon(Icons::FLAPPING), + 'incident-age' => new Icon(Icons::INCIDENT_AGE), + 'custom' => new Icon(Icons::CUSTOM), + 'mute' => new Icon(Icons::MUTE), + 'unmute' => new Icon(Icons::UNMUTE), + default => null + }; } } diff --git a/library/Notifications/Model/ExtraTag.php b/library/Notifications/Model/ExtraTag.php index 07a27f8a7..a9cfbe2b5 100644 --- a/library/Notifications/Model/ExtraTag.php +++ b/library/Notifications/Model/ExtraTag.php @@ -7,6 +7,7 @@ use Icinga\Module\Notifications\Model\Behavior\ObjectTags; use ipl\Orm\Behaviors; use ipl\Sql\Connection; +use LogicException; class ExtraTag extends ObjectExtraTag { @@ -16,7 +17,7 @@ class ExtraTag extends ObjectExtraTag */ public static function on(Connection $_) { - throw new \LogicException('Documentation says: DO NOT USE. Can\'t you read?'); + throw new LogicException('Documentation says: DO NOT USE. Can\'t you read?'); } public function createBehaviors(Behaviors $behaviors): void diff --git a/library/Notifications/Model/IncidentHistory.php b/library/Notifications/Model/IncidentHistory.php index c8bcec663..9144e6427 100644 --- a/library/Notifications/Model/IncidentHistory.php +++ b/library/Notifications/Model/IncidentHistory.php @@ -145,17 +145,12 @@ public function createRelations(Relations $relations): void */ public static function translateNotificationState(string $state): string { - switch ($state) { - case 'sent': - return t('sent', 'notifications.transmission.state'); - case 'failed': - return t('failed', 'notifications.transmission.state'); - case 'pending': - return t('pending', 'notifications.transmission.state'); - case 'suppressed': - return t('suppressed', 'notifications.transmission.state'); - default: - return t('unknown', 'notifications.transmission.state'); - } + return match ($state) { + 'sent' => t('sent', 'notifications.transmission.state'), + 'failed' => t('failed', 'notifications.transmission.state'), + 'pending' => t('pending', 'notifications.transmission.state'), + 'suppressed' => t('suppressed', 'notifications.transmission.state'), + default => t('unknown', 'notifications.transmission.state') + }; } } diff --git a/library/Notifications/Model/Rotation.php b/library/Notifications/Model/Rotation.php index 6a75ca07e..305c10974 100644 --- a/library/Notifications/Model/Rotation.php +++ b/library/Notifications/Model/Rotation.php @@ -127,7 +127,7 @@ public function delete(): void $changedAt = (int) (new DateTime())->format("Uv"); $markAsDeleted = ['changed_at' => $changedAt, 'deleted' => 'y']; - $db->update('timeperiod_entry', $markAsDeleted, ['timeperiod_id = ?' => $timeperiodId, 'deleted = ?' => 'n']); + $db->update('timeperiod_entry', $markAsDeleted, ['timeperiod_id = ?' => $timeperiodId, 'deleted = ?' => 'n']); $db->update('timeperiod', $markAsDeleted, ['id = ?' => $timeperiodId]); $db->update( diff --git a/library/Notifications/Model/RuleEscalationRecipient.php b/library/Notifications/Model/RuleEscalationRecipient.php index 8551ab796..cbba3c3f9 100644 --- a/library/Notifications/Model/RuleEscalationRecipient.php +++ b/library/Notifications/Model/RuleEscalationRecipient.php @@ -90,21 +90,13 @@ public function createRelations(Relations $relations): void * * @return Contact|Contactgroup|Schedule|null */ - public function getRecipient(): ?Model + public function getRecipient(): Contact|Contactgroup|Schedule|null { - $recipientModel = null; - if ($this->contact_id) { - $recipientModel = $this->contact->first(); - } - - if ($this->contactgroup_id) { - $recipientModel = $this->contactgroup->first(); - } - - if ($this->schedule_id) { - $recipientModel = $this->schedule->first(); - } - - return $recipientModel; + return match (true) { + (bool) $this->contact_id => $this->contact->first(), + (bool) $this->contactgroup_id => $this->contactgroup->first(), + (bool) $this->schedule_id => $this->schedule->first(), + default => null + }; } } diff --git a/library/Notifications/Model/Tag.php b/library/Notifications/Model/Tag.php index c6751e41a..fd1890a19 100644 --- a/library/Notifications/Model/Tag.php +++ b/library/Notifications/Model/Tag.php @@ -7,6 +7,7 @@ use Icinga\Module\Notifications\Model\Behavior\ObjectTags; use ipl\Orm\Behaviors; use ipl\Sql\Connection; +use LogicException; class Tag extends ObjectIdTag { @@ -16,7 +17,7 @@ class Tag extends ObjectIdTag */ public static function on(Connection $_) { - throw new \LogicException('Documentation says: DO NOT USE. Can\'t you read?'); + throw new LogicException('Documentation says: DO NOT USE. Can\'t you read?'); } public function createBehaviors(Behaviors $behaviors): void diff --git a/library/Notifications/ProvidedHook/SessionStorage.php b/library/Notifications/ProvidedHook/SessionStorage.php index 769a45438..37afde94d 100644 --- a/library/Notifications/ProvidedHook/SessionStorage.php +++ b/library/Notifications/ProvidedHook/SessionStorage.php @@ -19,10 +19,10 @@ class SessionStorage extends AuthenticationHook { /** @var Session\Session Session object */ - protected $session; + protected Session\Session $session; /** @var Connection Database object */ - protected $database; + protected Connection $database; public function __construct() { diff --git a/library/Notifications/Test/BaseApiV1TestCase.php b/library/Notifications/Test/BaseApiV1TestCase.php index ea5ecd1cd..2c3220f83 100644 --- a/library/Notifications/Test/BaseApiV1TestCase.php +++ b/library/Notifications/Test/BaseApiV1TestCase.php @@ -6,13 +6,12 @@ use DateTime; use GuzzleHttp\Client; -use Icinga\Module\Notifications\Api\V1\Channels; use Icinga\Util\Json; use Icinga\Web\Url; use ipl\Sql\Connection; use ipl\Sql\Select; -use Psr\Http\Message\ResponseInterface; use PHPUnit\Framework\TestCase; +use Psr\Http\Message\ResponseInterface; class BaseApiV1TestCase extends TestCase { @@ -37,18 +36,18 @@ class BaseApiV1TestCase extends TestCase protected static function initializeNotificationsDb(Connection $db, string $driver): void { $db->insert('available_channel_type', [ - 'type' => 'email', - 'name' => 'Email', - 'version' => 1, - 'author' => 'Test', - 'config_attrs' => '' - ]); + 'type' => 'email', + 'name' => 'Email', + 'version' => 1, + 'author' => 'Test', + 'config_attrs' => '' + ]); $db->insert('available_channel_type', [ - 'type' => 'webhook', - 'name' => 'Webhook', - 'version' => 1, - 'author' => 'Test', - 'config_attrs' => '' + 'type' => 'webhook', + 'name' => 'Webhook', + 'version' => 1, + 'author' => 'Test', + 'config_attrs' => '' ]); $db->insert('available_channel_type', [ 'type' => 'rocketchat', @@ -120,9 +119,9 @@ protected static function createContacts(Connection $db): void $contactIds = $db->select( (new Select()) - ->from('contact') - ->columns('id') - ->where(['external_uuid IN (?)' => [self::CONTACT_UUID, self::CONTACT_UUID_2]]) + ->from('contact') + ->columns('id') + ->where(['external_uuid IN (?)' => [self::CONTACT_UUID, self::CONTACT_UUID_2]]) )->fetchAll(\PDO::FETCH_COLUMN); foreach ($contactIds as $contactId) { diff --git a/library/Notifications/View/EventRenderer.php b/library/Notifications/View/EventRenderer.php index b9dddc64a..e23cec4b8 100644 --- a/library/Notifications/View/EventRenderer.php +++ b/library/Notifications/View/EventRenderer.php @@ -94,7 +94,7 @@ public function assembleExtendedInfo($item, HtmlDocument $info, string $layout): $source = $object->source; $info->addHtml( (new Ball(Ball::SIZE_BIG)) - ->addAttributes(['class' => 'source-icon']) + ->addAttributes(Attributes::create(['class' => 'source-icon'])) ->addHtml($source->getIcon()) ); } diff --git a/library/Notifications/View/EventRuleRenderer.php b/library/Notifications/View/EventRuleRenderer.php index 561c0c338..e6f31c2b6 100644 --- a/library/Notifications/View/EventRuleRenderer.php +++ b/library/Notifications/View/EventRuleRenderer.php @@ -6,6 +6,7 @@ use Icinga\Module\Notifications\Common\Links; use Icinga\Module\Notifications\Model\Rule; +use Icinga\Module\Notifications\Model\RuleEscalation; use Icinga\Module\Notifications\Widget\RuleEscalationRecipientBadge; use ipl\Html\Attributes; use ipl\Html\HtmlDocument; @@ -37,6 +38,7 @@ public function assembleCaption($item, HtmlDocument $caption, string $layout): v public function assembleExtendedInfo($item, HtmlDocument $info, string $layout): void { + /** @var ?RuleEscalation $rs */ $rs = $item->rule_escalation->first(); if ($rs) { $recipientCount = $rs->rule_escalation_recipient->count(); diff --git a/library/Notifications/View/IncidentHistoryRenderer.php b/library/Notifications/View/IncidentHistoryRenderer.php index e08d8ead3..1c87d1007 100644 --- a/library/Notifications/View/IncidentHistoryRenderer.php +++ b/library/Notifications/View/IncidentHistoryRenderer.php @@ -83,28 +83,18 @@ public function assemble($item, string $name, HtmlDocument $element, string $lay */ protected function getIncidentEventIcon(IncidentHistory $item): string { - switch ($item->type) { - case 'opened': - return Icons::OPENED; - case 'muted': - return Icons::MUTE; - case 'unmuted': - return Icons::UNMUTE; - case 'incident_severity_changed': - return $this->getSeverityIcon($item); - case 'recipient_role_changed': - return $this->getRoleIcon($item); - case 'closed': - return Icons::CLOSED; - case 'rule_matched': - return Icons::RULE_MATCHED; - case 'escalation_triggered': - return Icons::TRIGGERED; - case 'notified': - return Icons::NOTIFIED; - default: - return Icons::UNDEFINED; - } + return match ($item->type) { + 'opened' => Icons::OPENED, + 'muted' => Icons::MUTE, + 'unmuted' => Icons::UNMUTE, + 'incident_severity_changed' => $this->getSeverityIcon($item), + 'recipient_role_changed' => $this->getRoleIcon($item), + 'closed' => Icons::CLOSED, + 'rule_matched' => Icons::RULE_MATCHED, + 'escalation_triggered' => Icons::TRIGGERED, + 'notified' => Icons::NOTIFIED, + default => Icons::UNDEFINED + }; } /** @@ -116,18 +106,13 @@ protected function getIncidentEventIcon(IncidentHistory $item): string */ protected function getSeverityIcon(IncidentHistory $item): string { - switch ($item->new_severity) { - case 'ok': - return Icons::OK; - case 'warning': - return Icons::WARNING; - case 'err': - return Icons::ERROR; - case 'crit': - return Icons::CRITICAL; - default: - return Icons::UNDEFINED; - } + return match ($item->new_severity) { + 'ok' => Icons::OK, + 'warning' => Icons::WARNING, + 'err' => Icons::ERROR, + 'crit' => Icons::CRITICAL, + default => Icons::UNDEFINED + }; } /** diff --git a/library/Notifications/View/IncidentRenderer.php b/library/Notifications/View/IncidentRenderer.php index 417734a16..076b2a105 100644 --- a/library/Notifications/View/IncidentRenderer.php +++ b/library/Notifications/View/IncidentRenderer.php @@ -34,19 +34,12 @@ public function assembleAttributes($item, Attributes $attributes, string $layout public function assembleVisual($item, HtmlDocument $visual, string $layout): void { - switch ($item->severity) { - case 'ok': - $icon = Icons::OK; - break; - case 'err': - $icon = Icons::ERROR; - break; - case 'crit': - $icon = Icons::CRITICAL; - break; - default: - $icon = Icons::WARNING; - } + $icon = match ($item->severity) { + 'ok' => Icons::OK, + 'err' => Icons::ERROR, + 'crit' => Icons::CRITICAL, + default => Icons::WARNING + }; $content = new Icon($icon, ['class' => ['severity-' . $item->severity]]); @@ -91,7 +84,7 @@ public function assembleExtendedInfo($item, HtmlDocument $info, string $layout): $source = $item->object->source; $info->addHtml( (new Ball(Ball::SIZE_BIG)) - ->addAttributes(['class' => 'source-icon']) + ->addAttributes(Attributes::create(['class' => 'source-icon'])) ->addHtml($source->getIcon()) ); diff --git a/library/Notifications/Web/Control/SearchBar/ExtraTagSuggestions.php b/library/Notifications/Web/Control/SearchBar/ExtraTagSuggestions.php index 88f52c2c0..eb363fd3c 100644 --- a/library/Notifications/Web/Control/SearchBar/ExtraTagSuggestions.php +++ b/library/Notifications/Web/Control/SearchBar/ExtraTagSuggestions.php @@ -4,26 +4,26 @@ namespace Icinga\Module\Notifications\Web\Control\SearchBar; +use Generator; use Icinga\Module\Notifications\Common\Database; use Icinga\Module\Notifications\Model\ObjectExtraTag; use Icinga\Module\Notifications\Util\ObjectSuggestionsCursor; -use ipl\Web\Control\SearchBar\Suggestions; use ipl\Stdlib\Filter; -use Traversable; +use ipl\Web\Control\SearchBar\Suggestions; class ExtraTagSuggestions extends Suggestions { - protected function fetchValueSuggestions($column, $searchTerm, Filter\Chain $searchFilter) + protected function fetchValueSuggestions($column, $searchTerm, Filter\Chain $searchFilter): Generator { yield; } - protected function createQuickSearchFilter($searchTerm) + protected function createQuickSearchFilter($searchTerm): Filter\Any { return Filter::any(); } - protected function fetchColumnSuggestions($searchTerm) + protected function fetchColumnSuggestions($searchTerm): Generator { $searchColumns = (new ObjectSuggestionsCursor( Database::get(), diff --git a/library/Notifications/Web/Control/SearchBar/ObjectSuggestions.php b/library/Notifications/Web/Control/SearchBar/ObjectSuggestions.php index f87f04ba5..e96924998 100644 --- a/library/Notifications/Web/Control/SearchBar/ObjectSuggestions.php +++ b/library/Notifications/Web/Control/SearchBar/ObjectSuggestions.php @@ -4,6 +4,7 @@ namespace Icinga\Module\Notifications\Web\Control\SearchBar; +use Generator; use Icinga\Module\Notifications\Common\Auth; use Icinga\Module\Notifications\Common\Database; use Icinga\Module\Notifications\Model\Behavior\IcingaCustomVars; @@ -19,10 +20,11 @@ use ipl\Orm\Relation; use ipl\Orm\Relation\HasOne; use ipl\Orm\Resolver; +use ipl\Stdlib\Filter; use ipl\Stdlib\Seq; use ipl\Web\Control\SearchBar\SearchException; use ipl\Web\Control\SearchBar\Suggestions; -use ipl\Stdlib\Filter; +use LogicException; use PDO; use Traversable; @@ -31,8 +33,8 @@ class ObjectSuggestions extends Suggestions use Auth; use Translation; - /** @var Model */ - protected $model; + /** @var ?Model */ + protected ?Model $model = null; /** * Set the model to show suggestions for @@ -41,7 +43,7 @@ class ObjectSuggestions extends Suggestions * * @return $this */ - public function setModel($model): self + public function setModel(string|Model $model): self { if (is_string($model)) { $model = new $model(); @@ -60,7 +62,7 @@ public function setModel($model): self public function getModel(): Model { if ($this->model === null) { - throw new \LogicException( + throw new LogicException( 'You are accessing an unset property. Please make sure to set it beforehand.' ); } @@ -89,7 +91,7 @@ protected function shouldShowRelationFor(string $column): bool return $columnPath[0] !== $tableName; } - protected function createQuickSearchFilter($searchTerm) + protected function createQuickSearchFilter($searchTerm): Filter\Any|Filter\Chain { $model = $this->getModel(); $resolver = $model::on(Database::get())->getResolver(); @@ -104,13 +106,16 @@ protected function createQuickSearchFilter($searchTerm) return $quickFilter; } - protected function fetchValueSuggestions($column, $searchTerm, Filter\Chain $searchFilter) - { + protected function fetchValueSuggestions( + $column, + $searchTerm, + Filter\Chain $searchFilter + ): ObjectSuggestionsCursor { $model = $this->getModel(); $query = $model::on(Database::get()); $query->limit(static::DEFAULT_LIMIT); - if (strpos($column, ' ') !== false) { + if (str_contains($column, ' ')) { // $column may be a label /** @var string $path */ [$path, $_] = Seq::find( @@ -130,10 +135,10 @@ protected function fetchValueSuggestions($column, $searchTerm, Filter\Chain $sea [$targetPath, $columnName] = $splitted; $isTag = false; - if (substr($targetPath, -4) === '.tag') { + if (str_ends_with($targetPath, '.tag')) { $isTag = true; $targetPath = substr($targetPath, 0, -3) . 'object_id_tag'; - } elseif (substr($targetPath, -10) === '.extra_tag') { + } elseif (str_ends_with($targetPath, '.extra_tag')) { $isTag = true; $targetPath = substr($targetPath, 0, -9) . 'object_extra_tag'; } elseif ( @@ -148,7 +153,7 @@ protected function fetchValueSuggestions($column, $searchTerm, Filter\Chain $sea ); } - if (strpos($targetPath, '.') !== false) { + if (str_contains($targetPath, '.')) { try { $query->with($targetPath); // TODO: Remove this, once ipl/orm does it as early } catch (InvalidRelationException $e) { @@ -191,7 +196,7 @@ protected function fetchValueSuggestions($column, $searchTerm, Filter\Chain $sea } } - protected function fetchColumnSuggestions($searchTerm) + protected function fetchColumnSuggestions($searchTerm): Generator { $model = $this->getModel(); $query = $model::on(Database::get()); @@ -274,7 +279,7 @@ protected function queryTags(Model $model, string $searchTerm): Query return $tags; } - protected function matchSuggestion($path, $label, $searchTerm) + protected function matchSuggestion($path, $label, $searchTerm): bool { if (preg_match('/[_.](id)$/', $path)) { // Only suggest exotic columns if the user knows the full column path @@ -314,8 +319,10 @@ public static function collectFilterColumns(Model $model, Resolver $resolver): T * @param Model $subject * @param array $models * @param array $path + * + * @return void */ - protected static function collectRelations(Resolver $resolver, Model $subject, array &$models, array $path) + protected static function collectRelations(Resolver $resolver, Model $subject, array &$models, array $path): void { foreach ($resolver->getRelations($subject) as $name => $relation) { /** @var Relation $relation */ diff --git a/library/Notifications/Web/FilterRenderer.php b/library/Notifications/Web/FilterRenderer.php index b34320333..10439c5f6 100644 --- a/library/Notifications/Web/FilterRenderer.php +++ b/library/Notifications/Web/FilterRenderer.php @@ -22,28 +22,16 @@ protected function renderCondition(Filter\Condition $condition): void return; } - switch (true) { - case $condition instanceof Filter\Unequal: - case $condition instanceof Filter\Unlike: - $this->string .= '!='; - break; - case $condition instanceof Filter\Equal: - case $condition instanceof Filter\Like: - $this->string .= '='; - break; - case $condition instanceof Filter\GreaterThan: - $this->string .= '>'; - break; - case $condition instanceof Filter\LessThan: - $this->string .= '<'; - break; - case $condition instanceof Filter\GreaterThanOrEqual: - $this->string .= '>='; - break; - case $condition instanceof Filter\LessThanOrEqual: - $this->string .= '<='; - break; - } + $this->string .= match (true) { + $condition instanceof Filter\Unequal, + $condition instanceof Filter\Unlike => '!=', + $condition instanceof Filter\Equal, + $condition instanceof Filter\Like => '=', + $condition instanceof Filter\GreaterThan => '>', + $condition instanceof Filter\LessThan => '<', + $condition instanceof Filter\GreaterThanOrEqual => '>=', + $condition instanceof Filter\LessThanOrEqual => '<=' + }; if (is_array($value)) { $this->string .= '(' . join('|', $value) . ')'; diff --git a/library/Notifications/Web/Form/ContactForm.php b/library/Notifications/Web/Form/ContactForm.php index 693f10a56..e81a05b23 100644 --- a/library/Notifications/Web/Form/ContactForm.php +++ b/library/Notifications/Web/Form/ContactForm.php @@ -37,10 +37,10 @@ class ContactForm extends CompatForm public const ON_REMOVE = 'on_remove'; /** @var Connection */ - private $db; + private Connection $db; - /** @var ?string Contact ID*/ - private $contactId; + /** @var ?string Contact ID */ + private ?string $contactId = null; public function __construct(Connection $db) { @@ -67,7 +67,7 @@ private function hasBeenRemoved(): bool return $csrf !== null && $csrf->isValid() && $btn !== null && $btn->getName() === 'delete'; } - public function isValidEvent($event) + public function isValidEvent($event): bool { if ($event === self::ON_REMOVE) { return true; @@ -76,9 +76,9 @@ public function isValidEvent($event) return parent::isValidEvent($event); } - protected function assemble() + protected function assemble(): void { - $this->addAttributes(['class' => 'contact-form']); + $this->addAttributes(Attributes::create(['class' => 'contact-form'])); $this->addCsrfCounterMeasure(Session::getSession()->getId()); // Fieldset for contact full name and username diff --git a/library/Notifications/Web/Form/EventRuleDecorator.php b/library/Notifications/Web/Form/EventRuleDecorator.php index c59b60500..2060daa1c 100644 --- a/library/Notifications/Web/Form/EventRuleDecorator.php +++ b/library/Notifications/Web/Form/EventRuleDecorator.php @@ -13,9 +13,10 @@ class EventRuleDecorator extends HtmlDocument implements FormElementDecorator { - private $element; + /** @var FormElement */ + private FormElement $element; - public function decorate(FormElement $formElement) + public function decorate(FormElement $formElement): void { $me = clone $this; @@ -23,7 +24,7 @@ public function decorate(FormElement $formElement) $formElement->prependWrapper($me); } - protected function assemble() + protected function assemble(): void { $this->addHtml($this->element); diff --git a/library/Notifications/Widget/Calendar.php b/library/Notifications/Widget/Calendar.php index 2dd472423..551109d0a 100644 --- a/library/Notifications/Widget/Calendar.php +++ b/library/Notifications/Widget/Calendar.php @@ -40,23 +40,23 @@ class Calendar extends BaseHtmlElement implements EntryProvider protected $defaultAttributes = ['class' => 'calendar']; - /** @var Controls */ - protected $controls; + /** @var ?Controls */ + protected ?Controls $controls = null; - /** @var Style */ - protected $style; + /** @var ?Style */ + protected ?Style $style = null; - /** @var BaseGrid The grid implementation */ - protected $grid; + /** @var ?BaseGrid The grid implementation */ + protected ?BaseGrid $grid = null; /** @var Entry[] */ - protected $entries = []; + protected array $entries = []; - /** @var Url */ - protected $addEntryUrl; + /** @var ?Url */ + protected ?Url $addEntryUrl = null; /** @var ?Url */ - protected $url; + protected ?Url $url = null; public function setControls(Controls $controls): self { @@ -99,11 +99,7 @@ public function setAddEntryUrl(?Url $url): self public function getStepUrl(GridStep $step): ?Url { - if ($this->addEntryUrl === null) { - return null; - } - - return $this->addEntryUrl->with('start', $step->getStart()->format('Y-m-d\TH:i:s')); + return $this->addEntryUrl?->with('start', $step->getStart()->format('Y-m-d\TH:i:s')); } public function setUrl(?Url $url): self @@ -171,7 +167,7 @@ public function getEntries(): Traversable yield from $this->entries; } - protected function assemble() + protected function assemble(): void { $modeStart = $this->getModeStart(); diff --git a/library/Notifications/Widget/Calendar/Attendee.php b/library/Notifications/Widget/Calendar/Attendee.php index 0984869cf..ac1c149ab 100644 --- a/library/Notifications/Widget/Calendar/Attendee.php +++ b/library/Notifications/Widget/Calendar/Attendee.php @@ -14,13 +14,10 @@ class Attendee { /** @var string */ - protected $name; + protected string $name; /** @var string|ValidHtml */ - protected $icon = 'user'; - - /** @var string */ - protected $color = ''; + protected string|ValidHtml $icon = 'user'; public function __construct(string $name) { diff --git a/library/Notifications/Widget/Calendar/Controls.php b/library/Notifications/Widget/Calendar/Controls.php index c50576b64..1ffd79862 100644 --- a/library/Notifications/Widget/Calendar/Controls.php +++ b/library/Notifications/Widget/Calendar/Controls.php @@ -40,7 +40,7 @@ public function getViewMode(): string return $this->getPopulatedValue('mode', Calendar::MODE_WEEK); } - protected function assemble() + protected function assemble(): void { switch ($this->getPopulatedValue('mode', Calendar::MODE_WEEK)) { case Calendar::MODE_MONTH: diff --git a/library/Notifications/Widget/Calendar/DayGrid.php b/library/Notifications/Widget/Calendar/DayGrid.php index 94a9e149e..1342c556c 100644 --- a/library/Notifications/Widget/Calendar/DayGrid.php +++ b/library/Notifications/Widget/Calendar/DayGrid.php @@ -17,7 +17,7 @@ class DayGrid extends BaseGrid { - protected $flowOfTime = BaseGrid::VERTICAL_FLOW_OF_TIME; + protected string $flowOfTime = BaseGrid::VERTICAL_FLOW_OF_TIME; public function setGridStart(DateTime $start): BaseGrid { @@ -116,7 +116,7 @@ protected function createSidebar(): BaseHtmlElement return $sidebar; } - protected function assemble() + protected function assemble(): void { $this->addHtml( $this->createHeader(), diff --git a/library/Notifications/Widget/Calendar/Entry.php b/library/Notifications/Widget/Calendar/Entry.php index 41f5555c4..b14e07ab0 100644 --- a/library/Notifications/Widget/Calendar/Entry.php +++ b/library/Notifications/Widget/Calendar/Entry.php @@ -5,11 +5,12 @@ namespace Icinga\Module\Notifications\Widget\Calendar; use DateTimeInterface; +use Icinga\Module\Notifications\Widget\TimeGrid; use ipl\Html\Attributes; use ipl\Html\BaseHtmlElement; use ipl\Html\HtmlElement; use ipl\Html\Text; -use Icinga\Module\Notifications\Widget\TimeGrid; +use LogicException; /** * An entry on a calendar @@ -17,10 +18,10 @@ class Entry extends TimeGrid\Entry { /** @var ?string The description */ - protected $description; + protected ?string $description = null; - /** @var Attendee */ - protected $attendee; + /** @var ?Attendee */ + protected ?Attendee $attendee = null; /** * Set the description @@ -67,6 +68,10 @@ public function setAttendee(Attendee $attendee): self */ public function getAttendee(): Attendee { + if ($this->attendee === null) { + throw new LogicException('You are accessing an unset property. Please make sure to set it beforehand.'); + } + return $this->attendee; } diff --git a/library/Notifications/Widget/Calendar/MonthGrid.php b/library/Notifications/Widget/Calendar/MonthGrid.php index 780930b59..e10f96a65 100644 --- a/library/Notifications/Widget/Calendar/MonthGrid.php +++ b/library/Notifications/Widget/Calendar/MonthGrid.php @@ -119,7 +119,7 @@ protected function createSidebar(): BaseHtmlElement return $sidebar; } - protected function assemble() + protected function assemble(): void { $this->addHtml( $this->createHeader(), diff --git a/library/Notifications/Widget/Calendar/WeekGrid.php b/library/Notifications/Widget/Calendar/WeekGrid.php index 1faab02b8..7b316bae2 100644 --- a/library/Notifications/Widget/Calendar/WeekGrid.php +++ b/library/Notifications/Widget/Calendar/WeekGrid.php @@ -17,7 +17,7 @@ class WeekGrid extends BaseGrid { - protected $flowOfTime = BaseGrid::VERTICAL_FLOW_OF_TIME; + protected string $flowOfTime = BaseGrid::VERTICAL_FLOW_OF_TIME; public function setGridStart(DateTime $start): BaseGrid { @@ -125,7 +125,7 @@ protected function createSidebar(): BaseHtmlElement return $sidebar; } - protected function assemble() + protected function assemble(): void { $this->addHtml( $this->createHeader(), diff --git a/library/Notifications/Widget/Detail/EventDetail.php b/library/Notifications/Widget/Detail/EventDetail.php index c6070d115..c97039050 100644 --- a/library/Notifications/Widget/Detail/EventDetail.php +++ b/library/Notifications/Widget/Detail/EventDetail.php @@ -22,10 +22,10 @@ class EventDetail extends BaseHtmlElement { /** @var Event */ - protected $event; + protected Event $event; /** @var Incident */ - protected $incident; + protected Incident $incident; protected $defaultAttributes = [ 'class' => 'event-detail', @@ -148,7 +148,7 @@ protected function createSource(): array return $elements; } - protected function assemble() + protected function assemble(): void { $this->add([ $this->createInfo(), diff --git a/library/Notifications/Widget/Detail/IncidentDetail.php b/library/Notifications/Widget/Detail/IncidentDetail.php index 944e7d5a8..22c66ceaf 100644 --- a/library/Notifications/Widget/Detail/IncidentDetail.php +++ b/library/Notifications/Widget/Detail/IncidentDetail.php @@ -21,6 +21,7 @@ use ipl\Html\HtmlElement; use ipl\Html\Table; use ipl\Html\Text; +use ipl\Html\ValidHtml; use ipl\I18n\Translation; use ipl\Stdlib\Filter; use ipl\Web\Layout\MinimalItemLayout; @@ -31,7 +32,7 @@ class IncidentDetail extends BaseHtmlElement use Translation; /** @var Incident */ - protected $incident; + protected Incident $incident; protected $defaultAttributes = [ 'class' => 'incident-detail', @@ -45,7 +46,8 @@ public function __construct(Incident $incident) $this->incident = $incident; } - protected function createContacts() + /** @return ValidHtml[] */ + protected function createContacts(): array { $contacts = []; $query = $this->incident->incident_contact @@ -71,7 +73,8 @@ protected function createContacts() ]; } - protected function createRelatedObject() + /** @return ValidHtml[] */ + protected function createRelatedObject(): array { $objectUrl = ObjectsRendererHook::renderObjectLink($this->incident->object); @@ -85,7 +88,8 @@ protected function createRelatedObject() ]; } - protected function createHistory() + /** @return ValidHtml[] */ + protected function createHistory(): array { $query = $this->incident->incident_history ->with([ @@ -105,7 +109,8 @@ protected function createHistory() ]; } - protected function createSource() + /** @return ValidHtml[] */ + protected function createSource(): array { $list = new HtmlElement('ul', Attributes::create(['class' => 'source-list'])); $list->addHtml(new HtmlElement('li', null, new EventSourceBadge($this->incident->object->source))); @@ -116,6 +121,7 @@ protected function createSource() ]; } + /** @return ValidHtml[] */ protected function createObjectTag(): array { $tags = []; @@ -176,7 +182,7 @@ protected function createObjectTag(): array return $result; } - protected function assemble() + protected function assemble(): void { $this->add([ $this->createContacts(), diff --git a/library/Notifications/Widget/Detail/IncidentQuickActions.php b/library/Notifications/Widget/Detail/IncidentQuickActions.php index 4bdb95cc5..cb0735545 100644 --- a/library/Notifications/Widget/Detail/IncidentQuickActions.php +++ b/library/Notifications/Widget/Detail/IncidentQuickActions.php @@ -28,13 +28,13 @@ class IncidentQuickActions extends Form ]; /** @var Incident */ - protected $incident; + protected Incident $incident; /** @var int Current logged-in user's id */ - protected $currentUserId; + protected int $currentUserId; - /** @var IncidentContact */ - protected $incidentContact; + /** @var ?IncidentContact */ + protected ?IncidentContact $incidentContact = null; public function __construct(Incident $incident, int $currentUserId) { @@ -99,7 +99,7 @@ protected function assembleUnsubscribeButton(): void ); } - protected function assemble() + protected function assemble(): void { $this->addElement($this->createCsrfCounterMeasure(Session::getSession()->getId())); @@ -120,7 +120,7 @@ protected function assemble() } } - protected function onSuccess() + protected function onSuccess(): void { $incidentContact = $this->fetchIncidentContact(); $pressedButton = $this->getPressedSubmitElement()->getName(); diff --git a/library/Notifications/Widget/Detail/ObjectHeader.php b/library/Notifications/Widget/Detail/ObjectHeader.php index d115fa973..2069fca22 100644 --- a/library/Notifications/Widget/Detail/ObjectHeader.php +++ b/library/Notifications/Widget/Detail/ObjectHeader.php @@ -4,7 +4,6 @@ namespace Icinga\Module\Notifications\Widget\Detail; -use Icinga\Exception\NotImplementedError; use Icinga\Module\Notifications\Model\Contactgroup; use Icinga\Module\Notifications\Model\Event; use Icinga\Module\Notifications\Model\Incident; @@ -25,7 +24,7 @@ class ObjectHeader extends BaseHtmlElement { /** @var Item */ - protected $object; + protected Model $object; protected $tag = 'div'; @@ -39,27 +38,13 @@ public function __construct(Model $object) $this->object = $object; } - /** - * @throws NotImplementedError When the object type is not supported - */ protected function assemble(): void { - switch (true) { - case $this->object instanceof Event: - $renderer = new EventRenderer(); - - break; - case $this->object instanceof Incident: - $renderer = new IncidentRenderer(); - - break; - case $this->object instanceof Contactgroup: - $renderer = new ContactgroupRenderer(); - - break; - default: - throw new NotImplementedError('Not implemented'); - } + $renderer = match (true) { + $this->object instanceof Event => new EventRenderer(), + $this->object instanceof Incident => new IncidentRenderer(), + $this->object instanceof Contactgroup => new ContactgroupRenderer() + }; $layout = new HeaderItemLayout($this->object, $renderer); diff --git a/library/Notifications/Widget/Detail/ScheduleDetail.php b/library/Notifications/Widget/Detail/ScheduleDetail.php index 04d23dc18..88da63ef8 100644 --- a/library/Notifications/Widget/Detail/ScheduleDetail.php +++ b/library/Notifications/Widget/Detail/ScheduleDetail.php @@ -29,10 +29,10 @@ class ScheduleDetail extends BaseHtmlElement protected $defaultAttributes = ['id' => 'notifications-schedule', 'class' => 'schedule-detail']; /** @var Schedule */ - protected $schedule; + protected Schedule $schedule; /** @var Controls */ - protected $controls; + protected Controls $controls; /** @var DateTime The day the timeline should start on */ protected DateTime $start; @@ -86,7 +86,7 @@ protected function createTimeline(): Timeline return $timeline; } - protected function assemble() + protected function assemble(): void { $timeline = $this->createTimeline(); if (! $this->hasRotation) { diff --git a/library/Notifications/Widget/Detail/ScheduleDetail/Controls.php b/library/Notifications/Widget/Detail/ScheduleDetail/Controls.php index 3528a0cd2..425031b3e 100644 --- a/library/Notifications/Widget/Detail/ScheduleDetail/Controls.php +++ b/library/Notifications/Widget/Detail/ScheduleDetail/Controls.php @@ -26,8 +26,6 @@ class Controls extends Form /** @var string The default mode */ public const DEFAULT_MODE = 'week'; - protected $method = 'POST'; - protected $defaultAttributes = ['class' => 'schedule-controls', 'name' => 'schedule-detail-controls-form']; /** @var ?string */ diff --git a/library/Notifications/Widget/EventSourceBadge.php b/library/Notifications/Widget/EventSourceBadge.php index da08579eb..849e65fbc 100644 --- a/library/Notifications/Widget/EventSourceBadge.php +++ b/library/Notifications/Widget/EventSourceBadge.php @@ -5,6 +5,7 @@ namespace Icinga\Module\Notifications\Widget; use Icinga\Module\Notifications\Model\Source; +use ipl\Html\Attributes; use ipl\Html\BaseHtmlElement; use ipl\Html\Html; use ipl\Web\Widget\Ball; @@ -12,7 +13,7 @@ class EventSourceBadge extends BaseHtmlElement { /** @var Source */ - protected $source; + protected Source $source; protected $tag = 'span'; @@ -21,14 +22,14 @@ class EventSourceBadge extends BaseHtmlElement /** * Create an event source badge with source icon * - * @param Source $source + * @param Source $source */ public function __construct(Source $source) { $this->source = $source; } - protected function assemble() + protected function assemble(): void { if ($this->source->name === null) { $title = $this->source->type; @@ -41,7 +42,7 @@ protected function assemble() ->add('title', $title); $this->addHtml((new Ball(Ball::SIZE_LARGE)) - ->addAttributes(['class' => 'source-icon']) + ->addAttributes(Attributes::create(['class' => 'source-icon'])) ->addHtml($this->source->getIcon())); $this->add(Html::tag('span', ['class' => 'name'], $this->source->name ?? $this->source->type)); } diff --git a/library/Notifications/Widget/ItemList/PageSeparatorItem.php b/library/Notifications/Widget/ItemList/PageSeparatorItem.php index 45d9509e6..6e8318d01 100644 --- a/library/Notifications/Widget/ItemList/PageSeparatorItem.php +++ b/library/Notifications/Widget/ItemList/PageSeparatorItem.php @@ -12,7 +12,7 @@ class PageSeparatorItem extends BaseHtmlElement protected $defaultAttributes = ['class' => 'list-item page-separator']; /** @var int */ - protected $pageNumber; + protected int $pageNumber; /** @var string */ protected $tag = 'li'; @@ -22,7 +22,7 @@ public function __construct(int $pageNumber) $this->pageNumber = $pageNumber; } - protected function assemble() + protected function assemble(): void { $this->add(Html::tag( 'a', diff --git a/library/Notifications/Widget/MemberSuggestions.php b/library/Notifications/Widget/MemberSuggestions.php index 983e41b78..eae154ee4 100644 --- a/library/Notifications/Widget/MemberSuggestions.php +++ b/library/Notifications/Widget/MemberSuggestions.php @@ -17,14 +17,14 @@ class MemberSuggestions extends BaseHtmlElement { protected $tag = 'ul'; - /** @var string */ - protected $searchTerm; + /** @var ?string */ + protected ?string $searchTerm = null; - /** @var string */ - protected $originalValue; + /** @var ?string */ + protected ?string $originalValue = null; /** @var string[] */ - protected $excludeTerms = []; + protected array $excludeTerms = []; public function setSearchTerm(string $term): self { diff --git a/library/Notifications/Widget/RuleEscalationRecipientBadge.php b/library/Notifications/Widget/RuleEscalationRecipientBadge.php index ba76c53ff..4dc2594a1 100644 --- a/library/Notifications/Widget/RuleEscalationRecipientBadge.php +++ b/library/Notifications/Widget/RuleEscalationRecipientBadge.php @@ -13,10 +13,10 @@ class RuleEscalationRecipientBadge extends BaseHtmlElement { /** @var RuleEscalationRecipient */ - protected $recipient; + protected RuleEscalationRecipient $recipient; - /** @var int */ - protected $moreCount; + /** @var ?int */ + protected ?int $moreCount = null; protected $tag = 'span'; @@ -52,7 +52,7 @@ public function createBadge() return Html::tag('span', ['class' => 'badge'], [new Icon($icon), $recipientModel->$nameColumn]); } - protected function assemble() + protected function assemble(): void { $this->add($this->createBadge()); diff --git a/library/Notifications/Widget/ShowMore.php b/library/Notifications/Widget/ShowMore.php index 652cae36a..9efdfbb6a 100644 --- a/library/Notifications/Widget/ShowMore.php +++ b/library/Notifications/Widget/ShowMore.php @@ -18,11 +18,11 @@ class ShowMore extends BaseHtmlElement protected $tag = 'div'; - protected $resultSet; + protected ResultSet $resultSet; - protected $url; + protected Url $url; - protected $label; + protected ?string $label = null; public function __construct(ResultSet $resultSet, Url $url, string $label = null) { @@ -52,7 +52,7 @@ public function renderUnwrapped(): string return ''; } - protected function assemble() + protected function assemble(): void { if ($this->resultSet->hasMore()) { $this->add(new ActionLink($this->getLabel(), $this->url)); diff --git a/library/Notifications/Widget/TimeGrid/BaseGrid.php b/library/Notifications/Widget/TimeGrid/BaseGrid.php index 7fc94f4cc..f0b1724a1 100644 --- a/library/Notifications/Widget/TimeGrid/BaseGrid.php +++ b/library/Notifications/Widget/TimeGrid/BaseGrid.php @@ -41,22 +41,22 @@ abstract class BaseGrid extends BaseHtmlElement protected $defaultAttributes = ['class' => ['time-grid']]; /** @var string The orientation of this grid's chronological order of entries */ - protected $flowOfTime = self::HORIZONTAL_FLOW_OF_TIME; + protected string $flowOfTime = self::HORIZONTAL_FLOW_OF_TIME; /** @var EntryProvider */ - protected $provider; + protected EntryProvider $provider; /** @var Style */ - protected $style; + protected Style $style; /** @var DateTime */ - protected $start; + protected DateTime $start; - /** @var DateTime */ - protected $end; + /** @var ?DateTime */ + protected ?DateTime $end = null; - /** @var array Extra counts stored as [date1 => count1, date2 => count2]*/ - protected $extraEntriesCount = []; + /** @var array Extra counts stored as [date1 => count1, date2 => count2] */ + protected array $extraEntriesCount = []; /** * Create a new time grid diff --git a/library/Notifications/Widget/TimeGrid/DaysHeader.php b/library/Notifications/Widget/TimeGrid/DaysHeader.php index 8c9db6a0c..4fb034de4 100644 --- a/library/Notifications/Widget/TimeGrid/DaysHeader.php +++ b/library/Notifications/Widget/TimeGrid/DaysHeader.php @@ -19,14 +19,14 @@ class DaysHeader extends BaseHtmlElement use Translation; /** @var int The number of days to show */ - protected $days; + protected int $days; protected $tag = 'div'; protected $defaultAttributes = ['class' => ['days-header', 'time-grid-header']]; /** @var DateTime Starting day */ - protected $startDay; + protected DateTime $startDay; /** * Create a new DaysHeader diff --git a/library/Notifications/Widget/TimeGrid/DynamicGrid.php b/library/Notifications/Widget/TimeGrid/DynamicGrid.php index 91839ae31..0fa19b4ef 100644 --- a/library/Notifications/Widget/TimeGrid/DynamicGrid.php +++ b/library/Notifications/Widget/TimeGrid/DynamicGrid.php @@ -16,10 +16,10 @@ class DynamicGrid extends BaseGrid { /** @var int The number of days to show */ - protected $days = 7; + protected int $days = 7; /** @var ?BaseHtmlElement This grid's sidebar */ - protected $sideBar; + protected ?BaseHtmlElement $sideBar = null; public function setGridStart(DateTime $start): BaseGrid { @@ -53,7 +53,7 @@ public function setDays(int $days): self */ public function addToSideBar(BaseHtmlElement $row): self { - $row->addAttributes(['class' => 'row-title']); + $row->addAttributes(Attributes::create(['class' => 'row-title'])); $this->sideBar()->addHtml($row); return $this; @@ -120,7 +120,7 @@ protected function createGridSteps(): Traversable } } - protected function assemble() + protected function assemble(): void { $this->style->addFor($this, [ '--primaryColumns' => $this->days, diff --git a/library/Notifications/Widget/TimeGrid/Entry.php b/library/Notifications/Widget/TimeGrid/Entry.php index 0f631ac00..51076c262 100644 --- a/library/Notifications/Widget/TimeGrid/Entry.php +++ b/library/Notifications/Widget/TimeGrid/Entry.php @@ -44,22 +44,22 @@ abstract class Entry extends BaseHtmlElement protected $defaultAttributes = ['class' => 'entry']; /** @var int The entry id */ - protected $id; + protected int $id; /** @var ?DateTime When the entry starts */ - protected $start; + protected ?DateTime $start = null; /** @var ?DateTime When the entry ends */ - protected $end; + protected ?DateTime $end = null; /** @var ?int The 0-based position of the row where to place this entry on the grid */ - protected $position; + protected ?int $position = null; /** @var ?ContinuationType The continuation type */ - protected $continuationType; + protected ?string $continuationType = null; - /** @var Url The URL to show this entry */ - protected $url; + /** @var ?Url The URL to show this entry */ + protected ?Url $url = null; /** * Create a new entry @@ -212,7 +212,7 @@ abstract public function getColor(int $transparency): string; abstract protected function assembleContainer(BaseHtmlElement $container): void; - protected function assemble() + protected function assemble(): void { $this->getAttributes() ->add('data-entry-id', $this->getId()) diff --git a/library/Notifications/Widget/TimeGrid/ExtraEntryCount.php b/library/Notifications/Widget/TimeGrid/ExtraEntryCount.php index 9cacf37b8..2d9c06f27 100644 --- a/library/Notifications/Widget/TimeGrid/ExtraEntryCount.php +++ b/library/Notifications/Widget/TimeGrid/ExtraEntryCount.php @@ -3,6 +3,7 @@ namespace Icinga\Module\Notifications\Widget\TimeGrid; use DateTime; +use ipl\Html\Attributes; use ipl\I18n\Translation; use ipl\Web\Widget\ButtonLink; @@ -10,11 +11,11 @@ class ExtraEntryCount extends ButtonLink { use Translation; - /** @var BaseGrid Grid this extra count is tied to*/ - protected $grid; + /** @var ?BaseGrid Grid this extra count is tied to */ + protected ?BaseGrid $grid = null; - /** @var DateTime Grid step for which the extra count is being registered */ - protected $gridStep; + /** @var ?DateTime Grid step for which the extra count is being registered */ + protected ?DateTime $gridStep = null; /** * Set the grid this extra count is tied to @@ -44,10 +45,10 @@ public function setGridStep(DateTime $gridStep): self return $this; } - protected function assemble() + protected function assemble(): void { $count = $this->grid->getExtraEntryCount($this->gridStep); - $this->addAttributes(['class' => 'extra-count']) + $this->addAttributes(Attributes::create(['class' => 'extra-count'])) ->setBaseTarget('_self') ->setContent( sprintf( @@ -61,7 +62,7 @@ protected function assemble() ); } - public function renderUnwrapped() + public function renderUnwrapped(): string { if ($this->grid->getExtraEntryCount($this->gridStep) > 0) { return parent::renderUnwrapped(); diff --git a/library/Notifications/Widget/TimeGrid/GridStep.php b/library/Notifications/Widget/TimeGrid/GridStep.php index 671f57dad..18f1edacd 100644 --- a/library/Notifications/Widget/TimeGrid/GridStep.php +++ b/library/Notifications/Widget/TimeGrid/GridStep.php @@ -15,13 +15,13 @@ class GridStep extends BaseHtmlElement { /** @var DateTime Start time of the grid step */ - protected $start; + protected DateTime $start; /** @var DateTime End time of the grid step */ - protected $end; + protected DateTime $end; /** @var array{int, int} The x and y position of the step on the grid */ - protected $coordinates; + protected array $coordinates; protected $tag = 'div'; @@ -72,7 +72,7 @@ public function getCoordinates(): array return $this->coordinates; } - protected function registerAttributeCallbacks(Attributes $attributes) + protected function registerAttributeCallbacks(Attributes $attributes): void { $this->getAttributes() ->registerAttributeCallback('data-start', function () { diff --git a/library/Notifications/Widget/TimeGrid/Timescale.php b/library/Notifications/Widget/TimeGrid/Timescale.php index c8881f9fe..c98935608 100644 --- a/library/Notifications/Widget/TimeGrid/Timescale.php +++ b/library/Notifications/Widget/TimeGrid/Timescale.php @@ -26,10 +26,10 @@ class Timescale extends BaseHtmlElement protected $defaultAttributes = ['class' => 'timescale']; /** @var int The number of days shown */ - protected $days; + protected int $days; /** @var Style */ - protected $style; + protected Style $style; /** * Create a new Timescale diff --git a/library/Notifications/Widget/TimeGrid/Util.php b/library/Notifications/Widget/TimeGrid/Util.php index cd7e859fd..0000ccfc7 100644 --- a/library/Notifications/Widget/TimeGrid/Util.php +++ b/library/Notifications/Widget/TimeGrid/Util.php @@ -10,9 +10,17 @@ final class Util { /** @var array */ - private static $entryColors = []; + private static array $entryColors = []; - public static function diffHours(DateTime $from, DateTime $to) + /** + * @param DateTime $from + * @param DateTime $to + * + * @return float|int + * + * @throws InvalidArgumentException + */ + public static function diffHours(DateTime $from, DateTime $to): float|int { $diff = $from->diff($to); if ($diff->invert) { diff --git a/library/Notifications/Widget/Timeline.php b/library/Notifications/Widget/Timeline.php index 18e4afa8a..3f0b99c10 100644 --- a/library/Notifications/Widget/Timeline.php +++ b/library/Notifications/Widget/Timeline.php @@ -42,25 +42,25 @@ class Timeline extends BaseHtmlElement implements EntryProvider protected $defaultAttributes = ['class' => ['timeline']]; /** @var array */ - protected $rotations = []; + protected array $rotations = []; /** @var int */ protected int $scheduleId; /** @var DateTime */ - protected $start; + protected DateTime $start; /** @var int */ - protected $days; + protected int $days; - /** @var Style */ - protected $style; + /** @var ?Style */ + protected ?Style $style = null; /** @var ?DynamicGrid|MinimalGrid */ - protected $grid; + protected DynamicGrid|MinimalGrid|null $grid = null; /** @var bool Whether to create the Timeline only with the Result using MinimalGrid */ - protected $minimalLayout = false; + protected bool $minimalLayout = false; /** @var int */ protected int $noOfRotations = 0; @@ -282,7 +282,7 @@ public function getEntries(): Traversable * * @return DynamicGrid|MinimalGrid */ - protected function getGrid() + protected function getGrid(): DynamicGrid|MinimalGrid { if ($this->grid === null) { if ($this->minimalLayout) { @@ -340,7 +340,7 @@ protected function assembleSidebarEntry(Rotation $rotation): BaseHtmlElement return $entry; } - protected function assemble() + protected function assemble(): void { if ($this->minimalLayout && empty($this->rotations)) { $this->addHtml(new HtmlElement( diff --git a/library/Notifications/Widget/Timeline/Entry.php b/library/Notifications/Widget/Timeline/Entry.php index f94d7b20f..b07f4109c 100644 --- a/library/Notifications/Widget/Timeline/Entry.php +++ b/library/Notifications/Widget/Timeline/Entry.php @@ -15,14 +15,14 @@ class Entry extends TimeGrid\Entry { - /** @var Member */ - protected $member; + /** @var ?Member */ + protected ?Member $member = null; /** @var ?EntryFlyout Content of the flyoutmenu that is shown when the entry is hovered */ protected ?EntryFlyout $flyoutContent = null; /** @var ?DateTimeZone The timezone the schedule is created in */ - protected ?DateTimeZone $scheduleTimezone; + protected ?DateTimeZone $scheduleTimezone = null; /** * @var string A CSS class that changes the placement of the flyout @@ -131,8 +131,11 @@ public function getWidthClass(): string * * @return $this */ - public function calculateAndSetWidthClass(BaseGrid $grid, $mediumThreshold = 0.2, $narrowThreshold = 0.1): static - { + public function calculateAndSetWidthClass( + BaseGrid $grid, + float $mediumThreshold = 0.2, + float $narrowThreshold = 0.1 + ): static { $totalGridDuration = $grid->getGridEnd()->getTimestamp() - $grid->getGridStart()->getTimestamp(); $start = max($this->getStart()->getTimestamp(), $grid->getGridStart()->getTimestamp()); $end = min($this->getEnd()->getTimestamp(), $grid->getGridEnd()->getTimestamp()); diff --git a/library/Notifications/Widget/Timeline/EntryFlyout.php b/library/Notifications/Widget/Timeline/EntryFlyout.php index 10f725c36..5d2c0b5d4 100644 --- a/library/Notifications/Widget/Timeline/EntryFlyout.php +++ b/library/Notifications/Widget/Timeline/EntryFlyout.php @@ -6,6 +6,7 @@ use DateTime; use DateTimeZone; +use IntlDateFormatter; use ipl\Html\Attributes; use ipl\Html\BaseHtmlElement; use ipl\Html\FormattedString; @@ -15,6 +16,7 @@ use ipl\Html\ValidHtml; use ipl\I18n\Translation; use ipl\Web\Widget\Icon; +use Locale; class EntryFlyout extends BaseHtmlElement { @@ -23,7 +25,7 @@ class EntryFlyout extends BaseHtmlElement /** @var ?Member Member who is on duty during the entry's timespan */ protected ?Member $activeMember = null; - /** @var ?string Mode of the entry's rotation can be "partial", "multi" or "24-7"*/ + /** @var ?string Mode of the entry's rotation can be "partial", "multi" or "24-7" */ protected ?string $mode = null; /** @var ?array All members of the entry's rotation */ @@ -342,15 +344,15 @@ protected function generateAndSetRotationInfo(DateTimeZone $scheduleTimezone): s 7 => $this->translate("Sun") ]; - $noneType = \IntlDateFormatter::NONE; - $shortType = \IntlDateFormatter::SHORT; + $noneType = IntlDateFormatter::NONE; + $shortType = IntlDateFormatter::SHORT; $startTime = match ($this->mode) { '24-7' => $this->rotationOptions['at'], 'partial' => $this->rotationOptions['from'], 'multi' => $this->rotationOptions['from_at'] }; - $timeFormatter = new \IntlDateFormatter(\Locale::getDefault(), $noneType, $shortType, $this->displayTimezone); - $dateFormatter = new \IntlDateFormatter(\Locale::getDefault(), $shortType, $noneType, $this->displayTimezone); + $timeFormatter = new IntlDateFormatter(Locale::getDefault(), $noneType, $shortType, $this->displayTimezone); + $dateFormatter = new IntlDateFormatter(Locale::getDefault(), $shortType, $noneType, $this->displayTimezone); $firstHandoffDt = DateTime::createFromFormat( 'Y-m-d H:i', diff --git a/library/Notifications/Widget/Timeline/FutureEntry.php b/library/Notifications/Widget/Timeline/FutureEntry.php index 74f26c31f..e07ae97da 100644 --- a/library/Notifications/Widget/Timeline/FutureEntry.php +++ b/library/Notifications/Widget/Timeline/FutureEntry.php @@ -19,7 +19,7 @@ class FutureEntry extends Entry { protected $defaultAttributes = ['class' => 'future-entry']; - protected $continuationType = Entry::TO_NEXT_GRID; + protected ?string $continuationType = Entry::TO_NEXT_GRID; public function __construct() { diff --git a/library/Notifications/Widget/Timeline/Member.php b/library/Notifications/Widget/Timeline/Member.php index a931f4553..6cb2fa052 100644 --- a/library/Notifications/Widget/Timeline/Member.php +++ b/library/Notifications/Widget/Timeline/Member.php @@ -10,10 +10,10 @@ class Member { /** @var string */ - protected $name; + protected string $name; /** @var string */ - protected $icon = 'user'; + protected string $icon = 'user'; /** * Create a new Member diff --git a/library/Notifications/Widget/Timeline/Rotation.php b/library/Notifications/Widget/Timeline/Rotation.php index 2cc40d162..d5a788584 100644 --- a/library/Notifications/Widget/Timeline/Rotation.php +++ b/library/Notifications/Widget/Timeline/Rotation.php @@ -10,6 +10,7 @@ use Generator; use Icinga\Module\Notifications\Common\Links; use Icinga\Module\Notifications\Forms\RotationConfigForm; +use Icinga\Module\Notifications\Model\Rotation as RotationModel; use ipl\I18n\Translation; use ipl\Scheduler\RRule; use ipl\Stdlib\Filter; @@ -20,15 +21,15 @@ class Rotation { use Translation; - /** @var \Icinga\Module\Notifications\Model\Rotation */ - protected $model; + /** @var RotationModel */ + protected RotationModel $model; /** * Create a new Rotation * - * @param \Icinga\Module\Notifications\Model\Rotation $model + * @param RotationModel $model */ - public function __construct(\Icinga\Module\Notifications\Model\Rotation $model) + public function __construct(RotationModel $model) { $this->model = $model; } @@ -76,6 +77,8 @@ public function getPriority(): int /** * Create the base version of the flyout for this rotation * + * @param DateTimeZone $displayTimezone + * * @return EntryFlyout */ public function generateEntryInfo(DateTimeZone $displayTimezone): EntryFlyout diff --git a/phpstan-baseline-standard.neon b/phpstan-baseline-standard.neon index 72ae37ff3..9dc9ecb2b 100644 --- a/phpstan-baseline-standard.neon +++ b/phpstan-baseline-standard.neon @@ -1,616 +1,307 @@ parameters: ignoreErrors: - - message: "#^Cannot call method getName\\(\\) on ipl\\\\Html\\\\Contract\\\\FormSubmitElement\\|null\\.$#" + message: '#^Cannot call method getName\(\) on ipl\\Html\\Contract\\FormSubmitElement\|null\.$#' + identifier: method.nonObject count: 1 path: application/controllers/ChannelController.php - - message: "#^Parameter \\#2 \\.\\.\\.\\$values of function sprintf expects bool\\|float\\|int\\|string\\|null, mixed given\\.$#" + message: '#^Parameter \#2 \.\.\.\$values of function sprintf expects bool\|float\|int\|string\|null, mixed given\.$#' + identifier: argument.type count: 2 path: application/controllers/ChannelController.php - - message: "#^Method Icinga\\\\Module\\\\Notifications\\\\Controllers\\\\ChannelsController\\:\\:addAction\\(\\) has no return type specified\\.$#" + message: '#^Parameter \#2 \.\.\.\$values of function sprintf expects bool\|float\|int\|string\|null, mixed given\.$#' + identifier: argument.type count: 1 path: application/controllers/ChannelsController.php - - message: "#^Method Icinga\\\\Module\\\\Notifications\\\\Controllers\\\\ChannelsController\\:\\:indexAction\\(\\) has no return type specified\\.$#" - count: 1 - path: application/controllers/ChannelsController.php - - - - message: "#^Parameter \\#2 \\.\\.\\.\\$values of function sprintf expects bool\\|float\\|int\\|string\\|null, mixed given\\.$#" - count: 1 - path: application/controllers/ChannelsController.php - - - - message: "#^Method Icinga\\\\Module\\\\Notifications\\\\Controllers\\\\ConfigController\\:\\:databaseAction\\(\\) has no return type specified\\.$#" - count: 1 - path: application/controllers/ConfigController.php - - - - message: "#^Method Icinga\\\\Module\\\\Notifications\\\\Controllers\\\\ContactsController\\:\\:indexAction\\(\\) has no return type specified\\.$#" - count: 1 - path: application/controllers/ContactsController.php - - - - message: "#^Parameter \\#2 \\$value of static method ipl\\\\Stdlib\\\\Filter\\:\\:equal\\(\\) expects array\\|bool\\|float\\|int\\|string, mixed given\\.$#" - count: 1 - path: application/controllers/EventController.php - - - - message: "#^Cannot access offset 'object_filter' on mixed\\.$#" - count: 2 - path: application/controllers/EventRuleController.php - - - - message: "#^Method Icinga\\\\Module\\\\Notifications\\\\Controllers\\\\EventRuleController\\:\\:fromDb\\(\\) return type has no value type specified in iterable type array\\.$#" - count: 1 - path: application/controllers/EventRuleController.php - - - - message: "#^Parameter \\#1 \\$id of static method Icinga\\\\Module\\\\Notifications\\\\Common\\\\Links\\:\\:eventRule\\(\\) expects int, mixed given\\.$#" - count: 3 - path: application/controllers/EventRuleController.php - - - - message: "#^Parameter \\#1 \\$key of method Icinga\\\\Web\\\\Session\\\\SessionNamespace\\:\\:delete\\(\\) expects string, mixed given\\.$#" - count: 3 - path: application/controllers/EventRuleController.php - - - - message: "#^Parameter \\#1 \\$key of method Icinga\\\\Web\\\\Session\\\\SessionNamespace\\:\\:get\\(\\) expects string, mixed given\\.$#" - count: 3 - path: application/controllers/EventRuleController.php - - - - message: "#^Parameter \\#1 \\$key of method Icinga\\\\Web\\\\Session\\\\SessionNamespace\\:\\:set\\(\\) expects string, mixed given\\.$#" - count: 2 - path: application/controllers/EventRuleController.php - - - - message: "#^Parameter \\#1 \\$query of method ipl\\\\Web\\\\Control\\\\SearchEditor\\:\\:setQueryString\\(\\) expects string, mixed given\\.$#" - count: 1 - path: application/controllers/EventRuleController.php - - - - message: "#^Parameter \\#1 \\$ruleId of method Icinga\\\\Module\\\\Notifications\\\\Controllers\\\\EventRuleController\\:\\:fromDb\\(\\) expects int, mixed given\\.$#" - count: 2 - path: application/controllers/EventRuleController.php - - - - message: "#^Cannot access offset 'object_filter' on mixed\\.$#" - count: 2 - path: application/controllers/EventRulesController.php - - - - message: "#^Parameter \\#1 \\$key of method Icinga\\\\Web\\\\Session\\\\SessionNamespace\\:\\:delete\\(\\) expects string, int given\\.$#" - count: 1 - path: application/controllers/EventRulesController.php - - - - message: "#^Parameter \\#1 \\$key of method Icinga\\\\Web\\\\Session\\\\SessionNamespace\\:\\:get\\(\\) expects string, int given\\.$#" - count: 4 - path: application/controllers/EventRulesController.php - - - - message: "#^Parameter \\#1 \\$key of method Icinga\\\\Web\\\\Session\\\\SessionNamespace\\:\\:set\\(\\) expects string, int given\\.$#" - count: 2 - path: application/controllers/EventRulesController.php - - - - message: "#^Parameter \\#1 \\$query of method ipl\\\\Web\\\\Control\\\\SearchEditor\\:\\:setQueryString\\(\\) expects string, mixed given\\.$#" - count: 1 - path: application/controllers/EventRulesController.php - - - - message: "#^Parameter \\#2 \\$default of method Icinga\\\\Web\\\\UrlParams\\:\\:shift\\(\\) expects string\\|null, int\\<1, max\\> given\\.$#" + message: '#^Parameter \#2 \$default of method Icinga\\Web\\UrlParams\:\:shift\(\) expects string\|null, int\<1, max\> given\.$#' + identifier: argument.type count: 1 path: application/controllers/EventsController.php - - message: "#^Parameter \\#2 \\$value of method Icinga\\\\Web\\\\Url\\:\\:setParam\\(\\) expects array\\|bool\\|string, mixed given\\.$#" + message: '#^Parameter \#2 \$value of method Icinga\\Web\\Url\:\:setParam\(\) expects array\|bool\|string, mixed given\.$#' + identifier: argument.type count: 1 path: application/controllers/EventsController.php - - message: "#^Parameter \\#2 \\$value of static method ipl\\\\Stdlib\\\\Filter\\:\\:lessThanOrEqual\\(\\) expects float\\|int\\|string, mixed given\\.$#" + message: '#^Parameter \#2 \$value of static method ipl\\Stdlib\\Filter\:\:lessThanOrEqual\(\) expects float\|int\|string, mixed given\.$#' + identifier: argument.type count: 1 path: application/controllers/EventsController.php - - message: "#^Cannot call method getUsername\\(\\) on Icinga\\\\User\\|null\\.$#" + message: '#^Cannot call method getUsername\(\) on Icinga\\User\|null\.$#' + identifier: method.nonObject count: 1 path: application/controllers/IncidentController.php - - message: "#^Parameter \\#2 \\$currentUserId of class Icinga\\\\Module\\\\Notifications\\\\Widget\\\\Detail\\\\IncidentQuickActions constructor expects int, mixed given\\.$#" - count: 1 - path: application/controllers/IncidentController.php - - - - message: "#^Parameter \\#2 \\$value of static method ipl\\\\Stdlib\\\\Filter\\:\\:equal\\(\\) expects array\\|bool\\|float\\|int\\|string, mixed given\\.$#" - count: 1 - path: application/controllers/IncidentController.php - - - - message: "#^Cannot cast mixed to int\\.$#" + message: '#^Cannot cast mixed to int\.$#' + identifier: cast.int count: 4 path: application/controllers/ScheduleController.php - - message: "#^Cannot call method getName\\(\\) on ipl\\\\Html\\\\Contract\\\\FormSubmitElement\\|null\\.$#" - count: 1 - path: application/forms/ChannelForm.php - - - - message: "#^Cannot call method prepend\\(\\) on ipl\\\\Html\\\\Contract\\\\Wrappable\\|null\\.$#" + message: '#^Cannot call method getName\(\) on ipl\\Html\\Contract\\FormSubmitElement\|null\.$#' + identifier: method.nonObject count: 1 path: application/forms/ChannelForm.php - - message: "#^Method Icinga\\\\Module\\\\Notifications\\\\Forms\\\\ChannelForm\\:\\:assemble\\(\\) has no return type specified\\.$#" + message: '#^Cannot call method prepend\(\) on ipl\\Html\\Contract\\Wrappable\|null\.$#' + identifier: method.nonObject count: 1 path: application/forms/ChannelForm.php - - message: "#^Method Icinga\\\\Module\\\\Notifications\\\\Forms\\\\DatabaseConfigForm\\:\\:assemble\\(\\) has no return type specified\\.$#" - count: 1 - path: application/forms/DatabaseConfigForm.php - - - - message: "#^Method Icinga\\\\Module\\\\Notifications\\\\Forms\\\\EventRuleForm\\:\\:assemble\\(\\) has no return type specified\\.$#" - count: 1 - path: application/forms/EventRuleForm.php - - - - message: "#^Call to an undefined method ipl\\\\Sql\\\\Connection\\:\\:lastInsertId\\(\\)\\.$#" - count: 1 - path: application/forms/ScheduleForm.php - - - - message: "#^Method Icinga\\\\Module\\\\Notifications\\\\Forms\\\\ScheduleForm\\:\\:assemble\\(\\) has no return type specified\\.$#" + message: '#^Call to an undefined method ipl\\Sql\\Connection\:\:lastInsertId\(\)\.$#' + identifier: method.notFound count: 1 path: application/forms/ScheduleForm.php - - message: "#^Property Icinga\\\\Module\\\\Notifications\\\\Forms\\\\ScheduleForm\\:\\:\\$submitLabel \\(string\\) on left side of \\?\\? is not nullable\\.$#" - count: 1 - path: application/forms/ScheduleForm.php - - - - message: "#^Argument of an invalid type array\\|null supplied for foreach, only iterables are supported\\.$#" + message: '#^Argument of an invalid type array\|null supplied for foreach, only iterables are supported\.$#' + identifier: foreach.nonIterable count: 1 path: library/Notifications/Common/Database.php - - message: "#^Method Icinga\\\\Module\\\\Notifications\\\\Model\\\\Channel\\:\\:getColumnDefinitions\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method Icinga\\Module\\Notifications\\Model\\Channel\:\:getColumnDefinitions\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: library/Notifications/Model/Channel.php - - message: "#^Method Icinga\\\\Module\\\\Notifications\\\\Model\\\\Channel\\:\\:getDefaultSort\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method Icinga\\Module\\Notifications\\Model\\Channel\:\:getDefaultSort\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: library/Notifications/Model/Channel.php - - message: "#^Method Icinga\\\\Module\\\\Notifications\\\\Model\\\\Channel\\:\\:getSearchColumns\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method Icinga\\Module\\Notifications\\Model\\Channel\:\:getSearchColumns\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: library/Notifications/Model/Channel.php - - message: "#^Method Icinga\\\\Module\\\\Notifications\\\\Model\\\\Contact\\:\\:getColumnDefinitions\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method Icinga\\Module\\Notifications\\Model\\Contact\:\:getColumnDefinitions\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: library/Notifications/Model/Contact.php - - message: "#^Method Icinga\\\\Module\\\\Notifications\\\\Model\\\\Contact\\:\\:getDefaultSort\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method Icinga\\Module\\Notifications\\Model\\Contact\:\:getDefaultSort\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: library/Notifications/Model/Contact.php - - message: "#^Method Icinga\\\\Module\\\\Notifications\\\\Model\\\\Contact\\:\\:getSearchColumns\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method Icinga\\Module\\Notifications\\Model\\Contact\:\:getSearchColumns\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: library/Notifications/Model/Contact.php - - message: "#^Method Icinga\\\\Module\\\\Notifications\\\\Model\\\\Event\\:\\:getColumnDefinitions\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method Icinga\\Module\\Notifications\\Model\\Event\:\:getColumnDefinitions\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: library/Notifications/Model/Event.php - - message: "#^Method Icinga\\\\Module\\\\Notifications\\\\Model\\\\Event\\:\\:getSearchColumns\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method Icinga\\Module\\Notifications\\Model\\Event\:\:getSearchColumns\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: library/Notifications/Model/Event.php - - message: "#^Method Icinga\\\\Module\\\\Notifications\\\\Model\\\\Incident\\:\\:getColumnDefinitions\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method Icinga\\Module\\Notifications\\Model\\Incident\:\:getColumnDefinitions\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: library/Notifications/Model/Incident.php - - message: "#^Method Icinga\\\\Module\\\\Notifications\\\\Model\\\\Incident\\:\\:getDefaultSort\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method Icinga\\Module\\Notifications\\Model\\Incident\:\:getDefaultSort\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: library/Notifications/Model/Incident.php - - message: "#^Method Icinga\\\\Module\\\\Notifications\\\\Model\\\\Incident\\:\\:getSearchColumns\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method Icinga\\Module\\Notifications\\Model\\Incident\:\:getSearchColumns\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: library/Notifications/Model/Incident.php - - message: "#^Method Icinga\\\\Module\\\\Notifications\\\\Model\\\\IncidentContact\\:\\:getColumnDefinitions\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method Icinga\\Module\\Notifications\\Model\\IncidentContact\:\:getColumnDefinitions\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: library/Notifications/Model/IncidentContact.php - - message: "#^Method Icinga\\\\Module\\\\Notifications\\\\Model\\\\IncidentHistory\\:\\:getColumnDefinitions\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method Icinga\\Module\\Notifications\\Model\\IncidentHistory\:\:getColumnDefinitions\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: library/Notifications/Model/IncidentHistory.php - - message: "#^Method Icinga\\\\Module\\\\Notifications\\\\Model\\\\IncidentHistory\\:\\:getDefaultSort\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method Icinga\\Module\\Notifications\\Model\\IncidentHistory\:\:getDefaultSort\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: library/Notifications/Model/IncidentHistory.php - - message: "#^Method Icinga\\\\Module\\\\Notifications\\\\Model\\\\Rule\\:\\:getColumnDefinitions\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method Icinga\\Module\\Notifications\\Model\\Rule\:\:getColumnDefinitions\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: library/Notifications/Model/Rule.php - - message: "#^Method Icinga\\\\Module\\\\Notifications\\\\Model\\\\Rule\\:\\:getDefaultSort\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method Icinga\\Module\\Notifications\\Model\\Rule\:\:getDefaultSort\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: library/Notifications/Model/Rule.php - - message: "#^Method Icinga\\\\Module\\\\Notifications\\\\Model\\\\Rule\\:\\:getSearchColumns\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method Icinga\\Module\\Notifications\\Model\\Rule\:\:getSearchColumns\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: library/Notifications/Model/Rule.php - - message: "#^Method Icinga\\\\Module\\\\Notifications\\\\Model\\\\RuleEscalation\\:\\:getColumnDefinitions\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method Icinga\\Module\\Notifications\\Model\\RuleEscalation\:\:getColumnDefinitions\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: library/Notifications/Model/RuleEscalation.php - - message: "#^Method Icinga\\\\Module\\\\Notifications\\\\Model\\\\RuleEscalation\\:\\:getDefaultSort\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method Icinga\\Module\\Notifications\\Model\\RuleEscalation\:\:getDefaultSort\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: library/Notifications/Model/RuleEscalation.php - - message: "#^Method Icinga\\\\Module\\\\Notifications\\\\Model\\\\RuleEscalation\\:\\:getSearchColumns\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method Icinga\\Module\\Notifications\\Model\\RuleEscalation\:\:getSearchColumns\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: library/Notifications/Model/RuleEscalation.php - - message: "#^Method Icinga\\\\Module\\\\Notifications\\\\Model\\\\RuleEscalationRecipient\\:\\:getColumnDefinitions\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method Icinga\\Module\\Notifications\\Model\\RuleEscalationRecipient\:\:getColumnDefinitions\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: library/Notifications/Model/RuleEscalationRecipient.php - - message: "#^Method Icinga\\\\Module\\\\Notifications\\\\Model\\\\RuleEscalationRecipient\\:\\:getDefaultSort\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method Icinga\\Module\\Notifications\\Model\\RuleEscalationRecipient\:\:getDefaultSort\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: library/Notifications/Model/RuleEscalationRecipient.php - - message: "#^Method Icinga\\\\Module\\\\Notifications\\\\Model\\\\Source\\:\\:getColumnDefinitions\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method Icinga\\Module\\Notifications\\Model\\Source\:\:getColumnDefinitions\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: library/Notifications/Model/Source.php - - message: "#^Method Icinga\\\\Module\\\\Notifications\\\\Model\\\\Source\\:\\:getSearchColumns\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method Icinga\\Module\\Notifications\\Model\\Source\:\:getSearchColumns\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: library/Notifications/Model/Source.php - - message: "#^Method Icinga\\\\Module\\\\Notifications\\\\Model\\\\TimeperiodEntry\\:\\:getDefaultSort\\(\\) return type has no value type specified in iterable type array\\.$#" + message: '#^Method Icinga\\Module\\Notifications\\Model\\TimeperiodEntry\:\:getDefaultSort\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: library/Notifications/Model/TimeperiodEntry.php - - message: "#^Cannot access property \\$tag on mixed\\.$#" + message: '#^Cannot access property \$tag on mixed\.$#' + identifier: property.nonObject count: 2 path: library/Notifications/Web/Control/SearchBar/ExtraTagSuggestions.php - - message: "#^Method Icinga\\\\Module\\\\Notifications\\\\Web\\\\Control\\\\SearchBar\\\\ExtraTagSuggestions\\:\\:fetchColumnSuggestions\\(\\) return type has no value type specified in iterable type Traversable\\.$#" - count: 1 - path: library/Notifications/Web/Control/SearchBar/ExtraTagSuggestions.php - - - - message: "#^Method Icinga\\\\Module\\\\Notifications\\\\Web\\\\Control\\\\SearchBar\\\\ExtraTagSuggestions\\:\\:fetchValueSuggestions\\(\\) return type has no value type specified in iterable type Traversable\\.$#" - count: 1 - path: library/Notifications/Web/Control/SearchBar/ExtraTagSuggestions.php - - - - message: "#^Method Icinga\\\\Module\\\\Notifications\\\\Web\\\\Control\\\\SearchBar\\\\ObjectSuggestions\\:\\:collectFilterColumns\\(\\) return type has no value type specified in iterable type Traversable\\.$#" + message: '#^Method Icinga\\Module\\Notifications\\Web\\Control\\SearchBar\\ObjectSuggestions\:\:collectFilterColumns\(\) return type has no value type specified in iterable type Traversable\.$#' + identifier: missingType.iterableValue count: 1 path: library/Notifications/Web/Control/SearchBar/ObjectSuggestions.php - - message: "#^Method Icinga\\\\Module\\\\Notifications\\\\Web\\\\Control\\\\SearchBar\\\\ObjectSuggestions\\:\\:collectRelations\\(\\) has no return type specified\\.$#" + message: '#^Method Icinga\\Module\\Notifications\\Web\\Control\\SearchBar\\ObjectSuggestions\:\:collectRelations\(\) has parameter \$models with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: library/Notifications/Web/Control/SearchBar/ObjectSuggestions.php - - message: "#^Method Icinga\\\\Module\\\\Notifications\\\\Web\\\\Control\\\\SearchBar\\\\ObjectSuggestions\\:\\:collectRelations\\(\\) has parameter \\$models with no value type specified in iterable type array\\.$#" + message: '#^Method Icinga\\Module\\Notifications\\Web\\Control\\SearchBar\\ObjectSuggestions\:\:collectRelations\(\) has parameter \$path with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: library/Notifications/Web/Control/SearchBar/ObjectSuggestions.php - - message: "#^Method Icinga\\\\Module\\\\Notifications\\\\Web\\\\Control\\\\SearchBar\\\\ObjectSuggestions\\:\\:collectRelations\\(\\) has parameter \\$path with no value type specified in iterable type array\\.$#" - count: 1 - path: library/Notifications/Web/Control/SearchBar/ObjectSuggestions.php - - - - message: "#^Method Icinga\\\\Module\\\\Notifications\\\\Web\\\\Control\\\\SearchBar\\\\ObjectSuggestions\\:\\:fetchColumnSuggestions\\(\\) return type has no value type specified in iterable type Traversable\\.$#" - count: 1 - path: library/Notifications/Web/Control/SearchBar/ObjectSuggestions.php - - - - message: "#^Method Icinga\\\\Module\\\\Notifications\\\\Web\\\\Control\\\\SearchBar\\\\ObjectSuggestions\\:\\:fetchValueSuggestions\\(\\) return type has no value type specified in iterable type Traversable\\.$#" - count: 1 - path: library/Notifications/Web/Control/SearchBar/ObjectSuggestions.php - - - - message: "#^Property Icinga\\\\Module\\\\Notifications\\\\Web\\\\Control\\\\SearchBar\\\\ObjectSuggestions\\:\\:\\$model \\(ipl\\\\Orm\\\\Model\\) does not accept object\\.$#" - count: 1 - path: library/Notifications/Web/Control/SearchBar/ObjectSuggestions.php - - - - message: "#^Cannot access property \\$address on mixed\\.$#" + message: '#^Cannot access property \$address on mixed\.$#' + identifier: property.nonObject count: 2 path: library/Notifications/Web/Form/ContactForm.php - - message: "#^Cannot access property \\$id on mixed\\.$#" + message: '#^Cannot access property \$id on mixed\.$#' + identifier: property.nonObject count: 1 path: library/Notifications/Web/Form/ContactForm.php - - message: "#^Cannot access property \\$type on mixed\\.$#" + message: '#^Cannot access property \$type on mixed\.$#' + identifier: property.nonObject count: 2 path: library/Notifications/Web/Form/ContactForm.php - - message: "#^Cannot call method prepend\\(\\) on ipl\\\\Html\\\\Contract\\\\Wrappable\\|null\\.$#" - count: 1 - path: library/Notifications/Web/Form/ContactForm.php - - - - message: "#^Method Icinga\\\\Module\\\\Notifications\\\\Web\\\\Form\\\\ContactForm\\:\\:assemble\\(\\) has no return type specified\\.$#" - count: 1 - path: library/Notifications/Web/Form/ContactForm.php - - - - message: "#^Method Icinga\\\\Module\\\\Notifications\\\\Web\\\\Form\\\\EventRuleDecorator\\:\\:assemble\\(\\) has no return type specified\\.$#" - count: 1 - path: library/Notifications/Web/Form/EventRuleDecorator.php - - - - message: "#^Method Icinga\\\\Module\\\\Notifications\\\\Web\\\\Form\\\\EventRuleDecorator\\:\\:decorate\\(\\) has no return type specified\\.$#" - count: 1 - path: library/Notifications/Web/Form/EventRuleDecorator.php - - - - message: "#^Property Icinga\\\\Module\\\\Notifications\\\\Web\\\\Form\\\\EventRuleDecorator\\:\\:\\$element has no type specified\\.$#" - count: 1 - path: library/Notifications/Web/Form/EventRuleDecorator.php - - - - message: "#^Parameter \\#1 \\$datetime of function strtotime expects string, mixed given\\.$#" - count: 1 - path: library/Notifications/Widget/Calendar.php - - - - message: "#^Method Icinga\\\\Module\\\\Notifications\\\\Widget\\\\Calendar\\:\\:assemble\\(\\) has no return type specified\\.$#" - count: 1 - path: library/Notifications/Widget/Calendar.php - - - - message: "#^Method Icinga\\\\Module\\\\Notifications\\\\Widget\\\\Calendar\\:\\:getModeStart\\(\\) should return DateTime but returns DateTime\\|false\\.$#" + message: '#^Method Icinga\\Module\\Notifications\\Widget\\Calendar\:\:getModeStart\(\) should return DateTime but returns DateTime\|false\.$#' + identifier: return.type count: 2 path: library/Notifications/Widget/Calendar.php - - message: "#^Parameter \\#1 \\$content of static method ipl\\\\Html\\\\Text\\:\\:create\\(\\) expects string, string\\|false given\\.$#" + message: '#^Parameter \#1 \$content of static method ipl\\Html\\Text\:\:create\(\) expects string, string\|false given\.$#' + identifier: argument.type count: 1 path: library/Notifications/Widget/Calendar.php - - message: "#^Property Icinga\\\\Module\\\\Notifications\\\\Widget\\\\Calendar\\:\\:\\$addEntryUrl \\(ipl\\\\Web\\\\Url\\) does not accept ipl\\\\Web\\\\Url\\|null\\.$#" + message: '#^Parameter \#1 \$datetime of function strtotime expects string, mixed given\.$#' + identifier: argument.type count: 1 path: library/Notifications/Widget/Calendar.php - - message: "#^Method Icinga\\\\Module\\\\Notifications\\\\Widget\\\\Calendar\\\\Attendee\\:\\:setIcon\\(\\) has parameter \\$icon with no type specified\\.$#" + message: '#^Method Icinga\\Module\\Notifications\\Widget\\Calendar\\Attendee\:\:setIcon\(\) has parameter \$icon with no type specified\.$#' + identifier: missingType.parameter count: 1 path: library/Notifications/Widget/Calendar/Attendee.php - - message: "#^Method Icinga\\\\Module\\\\Notifications\\\\Widget\\\\Calendar\\\\Controls\\:\\:assemble\\(\\) has no return type specified\\.$#" + message: '#^Method Icinga\\Module\\Notifications\\Widget\\Calendar\\Controls\:\:getViewMode\(\) should return string but returns mixed\.$#' + identifier: return.type count: 1 path: library/Notifications/Widget/Calendar/Controls.php - - message: "#^Method Icinga\\\\Module\\\\Notifications\\\\Widget\\\\Calendar\\\\Controls\\:\\:getViewMode\\(\\) should return string but returns mixed\\.$#" - count: 1 - path: library/Notifications/Widget/Calendar/Controls.php - - - - message: "#^Method Icinga\\\\Module\\\\Notifications\\\\Widget\\\\Calendar\\\\DayGrid\\:\\:assemble\\(\\) has no return type specified\\.$#" - count: 1 - path: library/Notifications/Widget/Calendar/DayGrid.php - - - - message: "#^Method Icinga\\\\Module\\\\Notifications\\\\Widget\\\\Calendar\\\\MonthGrid\\:\\:assemble\\(\\) has no return type specified\\.$#" - count: 1 - path: library/Notifications/Widget/Calendar/MonthGrid.php - - - - message: "#^Method Icinga\\\\Module\\\\Notifications\\\\Widget\\\\Calendar\\\\WeekGrid\\:\\:assemble\\(\\) has no return type specified\\.$#" - count: 1 - path: library/Notifications/Widget/Calendar/WeekGrid.php - - - - message: "#^Method Icinga\\\\Module\\\\Notifications\\\\Widget\\\\Detail\\\\EventDetail\\:\\:assemble\\(\\) has no return type specified\\.$#" - count: 1 - path: library/Notifications/Widget/Detail/EventDetail.php - - - - message: "#^Method Icinga\\\\Module\\\\Notifications\\\\Widget\\\\Detail\\\\IncidentDetail\\:\\:assemble\\(\\) has no return type specified\\.$#" - count: 1 - path: library/Notifications/Widget/Detail/IncidentDetail.php - - - - message: "#^Method Icinga\\\\Module\\\\Notifications\\\\Widget\\\\Detail\\\\IncidentDetail\\:\\:createContacts\\(\\) has no return type specified\\.$#" - count: 1 - path: library/Notifications/Widget/Detail/IncidentDetail.php - - - - message: "#^Method Icinga\\\\Module\\\\Notifications\\\\Widget\\\\Detail\\\\IncidentDetail\\:\\:createHistory\\(\\) has no return type specified\\.$#" - count: 1 - path: library/Notifications/Widget/Detail/IncidentDetail.php - - - - message: "#^Method Icinga\\\\Module\\\\Notifications\\\\Widget\\\\Detail\\\\IncidentDetail\\:\\:createRelatedObject\\(\\) has no return type specified\\.$#" - count: 1 - path: library/Notifications/Widget/Detail/IncidentDetail.php - - - - message: "#^Method Icinga\\\\Module\\\\Notifications\\\\Widget\\\\Detail\\\\IncidentDetail\\:\\:createSource\\(\\) has no return type specified\\.$#" - count: 1 - path: library/Notifications/Widget/Detail/IncidentDetail.php - - - - message: "#^Cannot call method getName\\(\\) on ipl\\\\Html\\\\Contract\\\\FormSubmitElement\\|null\\.$#" + message: '#^Cannot call method getName\(\) on ipl\\Html\\Contract\\FormSubmitElement\|null\.$#' + identifier: method.nonObject count: 1 path: library/Notifications/Widget/Detail/IncidentQuickActions.php - - message: "#^Method Icinga\\\\Module\\\\Notifications\\\\Widget\\\\Detail\\\\IncidentQuickActions\\:\\:assemble\\(\\) has no return type specified\\.$#" - count: 1 - path: library/Notifications/Widget/Detail/IncidentQuickActions.php - - - - message: "#^Method Icinga\\\\Module\\\\Notifications\\\\Widget\\\\Detail\\\\IncidentQuickActions\\:\\:fetchIncidentContact\\(\\) should return Icinga\\\\Module\\\\Notifications\\\\Model\\\\IncidentContact but returns ipl\\\\Orm\\\\Model\\.$#" - count: 1 - path: library/Notifications/Widget/Detail/IncidentQuickActions.php - - - - message: "#^Method Icinga\\\\Module\\\\Notifications\\\\Widget\\\\Detail\\\\IncidentQuickActions\\:\\:onSuccess\\(\\) has no return type specified\\.$#" - count: 1 - path: library/Notifications/Widget/Detail/IncidentQuickActions.php - - - - message: "#^Property Icinga\\\\Module\\\\Notifications\\\\Widget\\\\Detail\\\\IncidentQuickActions\\:\\:\\$incidentContact \\(Icinga\\\\Module\\\\Notifications\\\\Model\\\\IncidentContact\\) does not accept ipl\\\\Orm\\\\Model\\.$#" - count: 1 - path: library/Notifications/Widget/Detail/IncidentQuickActions.php - - - - message: "#^Method Icinga\\\\Module\\\\Notifications\\\\Widget\\\\EventSourceBadge\\:\\:assemble\\(\\) has no return type specified\\.$#" - count: 1 - path: library/Notifications/Widget/EventSourceBadge.php - - - - message: "#^Method Icinga\\\\Module\\\\Notifications\\\\Widget\\\\ItemList\\\\PageSeparatorItem\\:\\:assemble\\(\\) has no return type specified\\.$#" - count: 1 - path: library/Notifications/Widget/ItemList/PageSeparatorItem.php - - - - message: "#^Cannot access offset 'exclude' on mixed\\.$#" - count: 1 - path: library/Notifications/Widget/RecipientSuggestions.php - - - - message: "#^Cannot access offset 'label' on mixed\\.$#" - count: 1 - path: library/Notifications/Widget/RecipientSuggestions.php - - - - message: "#^Cannot access offset 'search' on mixed\\.$#" - count: 1 - path: library/Notifications/Widget/RecipientSuggestions.php - - - - message: "#^Cannot access offset 'term' on mixed\\.$#" - count: 2 - path: library/Notifications/Widget/RecipientSuggestions.php - - - - message: "#^Cannot access property \\$full_name on mixed\\.$#" - count: 2 - path: library/Notifications/Widget/RecipientSuggestions.php - - - - message: "#^Cannot access property \\$id on mixed\\.$#" - count: 2 - path: library/Notifications/Widget/RecipientSuggestions.php - - - - message: "#^Cannot access property \\$name on mixed\\.$#" - count: 2 - path: library/Notifications/Widget/RecipientSuggestions.php - - - - message: "#^Method Icinga\\\\Module\\\\Notifications\\\\Widget\\\\RecipientSuggestions\\:\\:assemble\\(\\) has no return type specified\\.$#" - count: 1 - path: library/Notifications/Widget/RecipientSuggestions.php - - - - message: "#^Method Icinga\\\\Module\\\\Notifications\\\\Widget\\\\RecipientSuggestions\\:\\:excludeTerms\\(\\) has parameter \\$terms with no value type specified in iterable type array\\.$#" - count: 1 - path: library/Notifications/Widget/RecipientSuggestions.php - - - - message: "#^Parameter \\#1 \\$term of method Icinga\\\\Module\\\\Notifications\\\\Widget\\\\RecipientSuggestions\\:\\:setOriginalValue\\(\\) expects string, mixed given\\.$#" - count: 1 - path: library/Notifications/Widget/RecipientSuggestions.php - - - - message: "#^Parameter \\#1 \\$term of method Icinga\\\\Module\\\\Notifications\\\\Widget\\\\RecipientSuggestions\\:\\:setSearchTerm\\(\\) expects string, mixed given\\.$#" - count: 1 - path: library/Notifications/Widget/RecipientSuggestions.php - - - - message: "#^Parameter \\#1 \\$terms of method Icinga\\\\Module\\\\Notifications\\\\Widget\\\\RecipientSuggestions\\:\\:excludeTerms\\(\\) expects array, mixed given\\.$#" - count: 1 - path: library/Notifications/Widget/RecipientSuggestions.php - - - - message: "#^Method Icinga\\\\Module\\\\Notifications\\\\Widget\\\\RuleEscalationRecipientBadge\\:\\:assemble\\(\\) has no return type specified\\.$#" + message: '#^Method Icinga\\Module\\Notifications\\Widget\\RuleEscalationRecipientBadge\:\:createBadge\(\) has no return type specified\.$#' + identifier: missingType.return count: 1 path: library/Notifications/Widget/RuleEscalationRecipientBadge.php - - - - message: "#^Method Icinga\\\\Module\\\\Notifications\\\\Widget\\\\RuleEscalationRecipientBadge\\:\\:createBadge\\(\\) has no return type specified\\.$#" - count: 1 - path: library/Notifications/Widget/RuleEscalationRecipientBadge.php - - - - message: "#^Property Icinga\\\\Module\\\\Notifications\\\\Widget\\\\RuleEscalationRecipientBadge\\:\\:\\$moreCount \\(int\\) does not accept int\\|null\\.$#" - count: 1 - path: library/Notifications/Widget/RuleEscalationRecipientBadge.php - - - - message: "#^Method Icinga\\\\Module\\\\Notifications\\\\Widget\\\\ShowMore\\:\\:assemble\\(\\) has no return type specified\\.$#" - count: 1 - path: library/Notifications/Widget/ShowMore.php - - - - message: "#^Property Icinga\\\\Module\\\\Notifications\\\\Widget\\\\ShowMore\\:\\:\\$label has no type specified\\.$#" - count: 1 - path: library/Notifications/Widget/ShowMore.php - - - - message: "#^Property Icinga\\\\Module\\\\Notifications\\\\Widget\\\\ShowMore\\:\\:\\$resultSet has no type specified\\.$#" - count: 1 - path: library/Notifications/Widget/ShowMore.php - - - - message: "#^Property Icinga\\\\Module\\\\Notifications\\\\Widget\\\\ShowMore\\:\\:\\$url has no type specified\\.$#" - count: 1 - path: library/Notifications/Widget/ShowMore.php diff --git a/test/php/application/controllers/ApiV1ContactGroupsTest.php b/test/php/application/controllers/ApiV1ContactGroupsTest.php index c0eaa573f..2c7fedcce 100644 --- a/test/php/application/controllers/ApiV1ContactGroupsTest.php +++ b/test/php/application/controllers/ApiV1ContactGroupsTest.php @@ -4,7 +4,6 @@ namespace Tests\Icinga\Module\Notifications\Controllers; -use GuzzleHttp\Client; use Icinga\Module\Notifications\Test\BaseApiV1TestCase; use Icinga\Web\Url; use ipl\Sql\Connection; @@ -395,7 +394,7 @@ public function testPostToReplaceWithMissingRequiredFields( 'POST', $endpoint, 'v1/contact-groups/' . BaseApiV1TestCase::GROUP_UUID, - json: [ + json: [ 'id' => BaseApiV1TestCase::GROUP_UUID_3, 'users' => [] ] @@ -440,7 +439,7 @@ public function testPostToReplaceWithInvalidFieldsFormat( 'POST', $endpoint, 'v1/contact-groups/' . BaseApiV1TestCase::GROUP_UUID, - json: [ + json: [ 'id' => BaseApiV1TestCase::GROUP_UUID_3, 'name' => ['Test'], 'users' => [] @@ -527,7 +526,7 @@ public function testPostToCreateWithMissingRequiredFields(Connection $db, Url $e 'POST', $endpoint, 'v1/contact-groups', - json:[ + json: [ 'id' => BaseApiV1TestCase::GROUP_UUID_3, 'users' => [] ] @@ -590,7 +589,7 @@ public function testPostToCreateWithInvalidFieldsFormat( 'POST', $endpoint, 'v1/contact-groups/', - json: [ + json: [ 'id' => BaseApiV1TestCase::GROUP_UUID_3, 'name' => ['Test'], 'users' => [] @@ -735,7 +734,7 @@ public function testPutToUpdateWithFilter(Connection $db, Url $endpoint): void 'PUT', $endpoint, 'v1/contact-groups?id=' . BaseApiV1TestCase::GROUP_UUID, - json: [ + json: [ 'id' => BaseApiV1TestCase::GROUP_UUID, 'name' => 'Test', 'users' => [] @@ -804,7 +803,7 @@ public function testPutToUpdateWithMissingRequiredFields( 'PUT', $endpoint, 'v1/contact-groups/' . BaseApiV1TestCase::GROUP_UUID, - json: [ + json: [ 'id' => BaseApiV1TestCase::GROUP_UUID, 'users' => [] ] @@ -849,7 +848,7 @@ public function testPutToUpdateWithInvalidFieldsFormat( 'PUT', $endpoint, 'v1/contact-groups/' . BaseApiV1TestCase::GROUP_UUID, - json: [ + json: [ 'id' => BaseApiV1TestCase::GROUP_UUID, 'name' => ['Test'], 'users' => [] @@ -895,7 +894,7 @@ public function testPutToUpdateWithDifferentPayloadId( 'PUT', $endpoint, 'v1/contact-groups/' . BaseApiV1TestCase::GROUP_UUID, - json: [ + json: [ 'id' => BaseApiV1TestCase::GROUP_UUID_2, 'name' => 'Test', 'users' => [] @@ -916,7 +915,7 @@ public function testPutToCreateWithValidData(Connection $db, Url $endpoint): voi 'PUT', $endpoint, 'v1/contact-groups/' . BaseApiV1TestCase::GROUP_UUID_3, - json: [ + json: [ 'id' => BaseApiV1TestCase::GROUP_UUID_3, 'name' => 'Test' ] @@ -958,7 +957,7 @@ public function testPutToUpdateWithValidData(Connection $db, Url $endpoint): voi 'PUT', $endpoint, 'v1/contact-groups/' . BaseApiV1TestCase::GROUP_UUID, - json: [ + json: [ 'id' => BaseApiV1TestCase::GROUP_UUID, 'name' => 'Test (replaced)', 'users' => [] @@ -995,7 +994,7 @@ public function testPutToUpdateWithInvalidData(Connection $db, Url $endpoint): v 'PUT', $endpoint, 'v1/contact-groups/' . BaseApiV1TestCase::GROUP_UUID, - json: [ + json: [ 'id' => BaseApiV1TestCase::GROUP_UUID, 'name' => 'Test', 'users' => [BaseApiV1TestCase::CONTACT_UUID_3] @@ -1019,7 +1018,7 @@ public function testPutToCreateWithValidOptionalData(Connection $db, Url $endpoi 'PUT', $endpoint, 'v1/contact-groups/' . BaseApiV1TestCase::GROUP_UUID_3, - json: [ + json: [ 'id' => BaseApiV1TestCase::GROUP_UUID_3, 'name' => 'Test', 'users' => [BaseApiV1TestCase::CONTACT_UUID] @@ -1063,7 +1062,7 @@ public function testPutToCreateWithMissingRequiredFields(Connection $db, Url $en 'PUT', $endpoint, 'v1/contact-groups/' . BaseApiV1TestCase::GROUP_UUID_3, - json: [ + json: [ 'id' => BaseApiV1TestCase::GROUP_UUID_3, 'users' => [] ] @@ -1081,7 +1080,7 @@ public function testPutToCreateWithMissingRequiredFields(Connection $db, Url $en 'PUT', $endpoint, 'v1/contact-groups/' . BaseApiV1TestCase::GROUP_UUID_3, - json: [ + json: [ 'name' => 'Test', 'users' => [] ] @@ -1126,7 +1125,7 @@ public function testPutToCreateWithInvalidFieldsFormat( 'PUT', $endpoint, 'v1/contact-groups/' . BaseApiV1TestCase::GROUP_UUID_3, - json: [ + json: [ 'id' => BaseApiV1TestCase::GROUP_UUID_3, 'name' => ['Test'], 'users' => [] diff --git a/test/php/application/controllers/ApiV1ContactsTest.php b/test/php/application/controllers/ApiV1ContactsTest.php index c92755fb6..7e01a46ef 100644 --- a/test/php/application/controllers/ApiV1ContactsTest.php +++ b/test/php/application/controllers/ApiV1ContactsTest.php @@ -4,12 +4,9 @@ namespace Tests\Icinga\Module\Notifications\Controllers; -use GuzzleHttp\Client; -use Icinga\Exception\IcingaException; use Icinga\Module\Notifications\Test\BaseApiV1TestCase; use Icinga\Web\Url; use ipl\Sql\Connection; -use stdClass; use WebSocket\Base; class ApiV1ContactsTest extends BaseApiV1TestCase @@ -263,7 +260,7 @@ public function testPostToReplaceWithUnknownIdentifier(Connection $db, Url $endp 'POST', $endpoint, 'v1/contacts/' . BaseApiV1TestCase::CONTACT_UUID_3, - json: [ + json: [ 'id' => BaseApiV1TestCase::CONTACT_UUID_4, 'full_name' => 'Test', 'default_channel' => BaseApiV1TestCase::CHANNEL_UUID, @@ -287,7 +284,7 @@ public function testPostToReplaceWithIndifferentPayloadId( 'POST', $endpoint, 'v1/contacts/' . BaseApiV1TestCase::CONTACT_UUID, - json: [ + json: [ 'id' => BaseApiV1TestCase::CONTACT_UUID, 'full_name' => 'Test', 'default_channel' => BaseApiV1TestCase::CHANNEL_UUID, @@ -314,7 +311,7 @@ public function testPostToReplaceWithAlreadyExistingPayloadId( 'POST', $endpoint, 'v1/contacts/' . BaseApiV1TestCase::CONTACT_UUID, - json: [ + json: [ 'id' => BaseApiV1TestCase::CONTACT_UUID_2, 'full_name' => 'Test', 'default_channel' => BaseApiV1TestCase::CHANNEL_UUID, @@ -336,7 +333,7 @@ public function testPostToReplaceWithValidData(Connection $db, Url $endpoint): v 'POST', $endpoint, 'v1/contacts/' . BaseApiV1TestCase::CONTACT_UUID, - json: [ + json: [ 'id' => BaseApiV1TestCase::CONTACT_UUID_3, 'full_name' => 'Test (replaced)', 'default_channel' => BaseApiV1TestCase::CHANNEL_UUID, @@ -383,7 +380,7 @@ public function testPostToCreateWithExistingPayloadId(Connection $db, Url $endpo 'POST', $endpoint, 'v1/contacts', - json: [ + json: [ 'id' => BaseApiV1TestCase::CONTACT_UUID, 'full_name' => 'Test', 'default_channel' => BaseApiV1TestCase::CHANNEL_UUID, @@ -405,7 +402,7 @@ public function testPostToCreateWithValidData(Connection $db, Url $endpoint): vo 'POST', $endpoint, 'v1/contacts', - json: [ + json: [ 'id' => BaseApiV1TestCase::CONTACT_UUID_3, 'full_name' => 'Test', 'default_channel' => BaseApiV1TestCase::CHANNEL_UUID, @@ -455,7 +452,7 @@ public function testPostToReplaceWithMissingRequiredFields( 'POST', $endpoint, 'v1/contacts/' . BaseApiV1TestCase::CONTACT_UUID, - json: [ + json: [ 'full_name' => 'Test', 'default_channel' => BaseApiV1TestCase::CHANNEL_UUID, 'addresses' => ['email' => 'test@example.com'] @@ -474,7 +471,7 @@ public function testPostToReplaceWithMissingRequiredFields( 'POST', $endpoint, 'v1/contacts/' . BaseApiV1TestCase::CONTACT_UUID, - json: [ + json: [ 'id' => BaseApiV1TestCase::CONTACT_UUID_3, 'default_channel' => BaseApiV1TestCase::CHANNEL_UUID, 'addresses' => ['email' => 'test@example.com'] @@ -493,7 +490,7 @@ public function testPostToReplaceWithMissingRequiredFields( 'POST', $endpoint, 'v1/contacts/' . BaseApiV1TestCase::CONTACT_UUID, - json: [ + json: [ 'id' => BaseApiV1TestCase::CONTACT_UUID_3, 'full_name' => 'Test', 'addresses' => ['email' => 'test@example.com'] @@ -512,7 +509,7 @@ public function testPostToReplaceWithMissingRequiredFields( 'POST', $endpoint, 'v1/contacts/' . BaseApiV1TestCase::CONTACT_UUID, - json: [ + json: [ 'id' => BaseApiV1TestCase::CONTACT_UUID_3, 'full_name' => 'Test', 'default_channel' => BaseApiV1TestCase::CHANNEL_UUID, @@ -541,7 +538,7 @@ public function testPostToReplaceWithInvalidFieldFormat( 'POST', $endpoint, 'v1/contacts/' . BaseApiV1TestCase::CONTACT_UUID, - json: [ + json: [ 'id' => [BaseApiV1TestCase::CONTACT_UUID_3], 'full_name' => 'Test', 'default_channel' => BaseApiV1TestCase::CHANNEL_UUID, @@ -561,7 +558,7 @@ public function testPostToReplaceWithInvalidFieldFormat( 'POST', $endpoint, 'v1/contacts/' . BaseApiV1TestCase::CONTACT_UUID, - json: [ + json: [ 'id' => BaseApiV1TestCase::CONTACT_UUID_3, 'full_name' => ['Test'], 'default_channel' => BaseApiV1TestCase::CHANNEL_UUID, @@ -581,7 +578,7 @@ public function testPostToReplaceWithInvalidFieldFormat( 'POST', $endpoint, 'v1/contacts/' . BaseApiV1TestCase::CONTACT_UUID, - json: [ + json: [ 'id' => BaseApiV1TestCase::CONTACT_UUID_3, 'full_name' => 'Test', 'default_channel' => [BaseApiV1TestCase::CHANNEL_UUID], @@ -601,7 +598,7 @@ public function testPostToReplaceWithInvalidFieldFormat( 'POST', $endpoint, 'v1/contacts/' . BaseApiV1TestCase::CONTACT_UUID, - json: [ + json: [ 'id' => BaseApiV1TestCase::CONTACT_UUID_3, 'full_name' => 'Test', 'default_channel' => BaseApiV1TestCase::CHANNEL_UUID, @@ -623,7 +620,7 @@ public function testPostToReplaceWithInvalidFieldFormat( 'POST', $endpoint, 'v1/contacts/' . BaseApiV1TestCase::CONTACT_UUID, - json: [ + json: [ 'id' => BaseApiV1TestCase::CONTACT_UUID_3, 'full_name' => 'Test', 'default_channel' => BaseApiV1TestCase::CHANNEL_UUID, @@ -644,7 +641,7 @@ public function testPostToReplaceWithInvalidFieldFormat( 'POST', $endpoint, 'v1/contacts/' . BaseApiV1TestCase::CONTACT_UUID, - json: [ + json: [ 'id' => BaseApiV1TestCase::CONTACT_UUID_3, 'full_name' => 'Test', 'default_channel' => BaseApiV1TestCase::CHANNEL_UUID, @@ -670,7 +667,7 @@ public function testPostToCreateWithValidOptionalData(Connection $db, Url $endpo 'POST', $endpoint, 'v1/contacts', - json: [ + json: [ 'id' => BaseApiV1TestCase::CONTACT_UUID_3, 'full_name' => 'Test3', 'username' => 'test3', @@ -727,7 +724,7 @@ public function testPostToCreateWithWebhookAsDefaultChannel(Connection $db, Url 'POST', $endpoint, 'v1/contacts', - json: [ + json: [ 'id' => BaseApiV1TestCase::CONTACT_UUID_3, 'full_name' => 'Test3', 'default_channel' => BaseApiV1TestCase::CHANNEL_UUID_2 @@ -756,7 +753,7 @@ public function testPostToCreateWithInvalidDefaultChannel(Connection $db, Url $e 'POST', $endpoint, 'v1/contacts', - json: [ + json: [ 'id' => BaseApiV1TestCase::CONTACT_UUID_3, 'full_name' => 'Test', 'default_channel' => 'invalid_uuid', @@ -782,7 +779,7 @@ public function testPostToCreateWithMissingRequiredFields(Connection $db, Url $e 'POST', $endpoint, 'v1/contacts', - json: [ + json: [ 'full_name' => 'Test', 'default_channel' => BaseApiV1TestCase::CHANNEL_UUID, 'addresses' => ['email' => 'test@example.com'] @@ -801,7 +798,7 @@ public function testPostToCreateWithMissingRequiredFields(Connection $db, Url $e 'POST', $endpoint, 'v1/contacts', - json: [ + json: [ 'id' => BaseApiV1TestCase::CONTACT_UUID_3, 'default_channel' => BaseApiV1TestCase::CHANNEL_UUID, 'addresses' => ['email' => 'test@example.com'] @@ -820,7 +817,7 @@ public function testPostToCreateWithMissingRequiredFields(Connection $db, Url $e 'POST', $endpoint, 'v1/contacts', - json: [ + json: [ 'id' => BaseApiV1TestCase::CONTACT_UUID_3, 'full_name' => 'Test', 'addresses' => ['email' => 'test@example.com'] @@ -839,7 +836,7 @@ public function testPostToCreateWithMissingRequiredFields(Connection $db, Url $e 'POST', $endpoint, 'v1/contacts', - json: [ + json: [ 'id' => BaseApiV1TestCase::CONTACT_UUID_3, 'full_name' => 'Test', 'default_channel' => BaseApiV1TestCase::CHANNEL_UUID, @@ -867,7 +864,7 @@ public function testPostToCreateWithInvalidFieldFormat( 'POST', $endpoint, 'v1/contacts/', - json: [ + json: [ 'id' => [BaseApiV1TestCase::CONTACT_UUID_3], 'full_name' => 'Test', 'default_channel' => BaseApiV1TestCase::CHANNEL_UUID, @@ -887,7 +884,7 @@ public function testPostToCreateWithInvalidFieldFormat( 'POST', $endpoint, 'v1/contacts/', - json: [ + json: [ 'id' => BaseApiV1TestCase::CONTACT_UUID_3, 'full_name' => ['Test'], 'default_channel' => BaseApiV1TestCase::CHANNEL_UUID, @@ -907,7 +904,7 @@ public function testPostToCreateWithInvalidFieldFormat( 'POST', $endpoint, 'v1/contacts/', - json: [ + json: [ 'id' => BaseApiV1TestCase::CONTACT_UUID_3, 'full_name' => 'Test', 'default_channel' => [BaseApiV1TestCase::CHANNEL_UUID], @@ -927,7 +924,7 @@ public function testPostToCreateWithInvalidFieldFormat( 'POST', $endpoint, 'v1/contacts/', - json: [ + json: [ 'id' => BaseApiV1TestCase::CONTACT_UUID_3, 'full_name' => 'Test', 'default_channel' => BaseApiV1TestCase::CHANNEL_UUID, @@ -949,7 +946,7 @@ public function testPostToCreateWithInvalidFieldFormat( 'POST', $endpoint, 'v1/contacts/', - json: [ + json: [ 'id' => BaseApiV1TestCase::CONTACT_UUID_3, 'full_name' => 'Test', 'default_channel' => BaseApiV1TestCase::CHANNEL_UUID, @@ -970,7 +967,7 @@ public function testPostToCreateWithInvalidFieldFormat( 'POST', $endpoint, 'v1/contacts/', - json: [ + json: [ 'id' => BaseApiV1TestCase::CONTACT_UUID_3, 'full_name' => 'Test', 'default_channel' => BaseApiV1TestCase::CHANNEL_UUID, @@ -997,7 +994,7 @@ public function testPostToCreateWithInvalidAddresses(Connection $db, Url $endpoi 'POST', $endpoint, 'v1/contacts', - json: [ + json: [ 'id' => BaseApiV1TestCase::CONTACT_UUID_3, 'full_name' => 'Test', 'default_channel' => BaseApiV1TestCase::CHANNEL_UUID, @@ -1020,7 +1017,7 @@ public function testPostToCreateWithInvalidAddresses(Connection $db, Url $endpoi 'POST', $endpoint, 'v1/contacts', - json: [ + json: [ 'id' => BaseApiV1TestCase::CONTACT_UUID_3, 'full_name' => 'Test', 'default_channel' => BaseApiV1TestCase::CHANNEL_UUID, @@ -1042,7 +1039,7 @@ public function testPostToCreateWithInvalidAddresses(Connection $db, Url $endpoi 'POST', $endpoint, 'v1/contacts', - json: [ + json: [ 'id' => BaseApiV1TestCase::CONTACT_UUID_3, 'full_name' => 'Test', 'default_channel' => BaseApiV1TestCase::CHANNEL_UUID, @@ -1071,7 +1068,7 @@ public function testPostToCreateWithInvalidOptionalData(Connection $db, Url $end 'POST', $endpoint, 'v1/contacts', - json: [ + json: [ 'id' => BaseApiV1TestCase::CONTACT_UUID_3, 'full_name' => 'Test', 'username' => 'test', @@ -1089,7 +1086,7 @@ public function testPostToCreateWithInvalidOptionalData(Connection $db, Url $end 'POST', $endpoint, 'v1/contacts', - json: [ + json: [ 'id' => BaseApiV1TestCase::CONTACT_UUID_3, 'full_name' => 'Test', 'default_channel' => BaseApiV1TestCase::CHANNEL_UUID, @@ -1112,7 +1109,7 @@ public function testPostToCreateWithInvalidOptionalData(Connection $db, Url $end 'POST', $endpoint, 'v1/contacts', - json: [ + json: [ 'id' => BaseApiV1TestCase::CONTACT_UUID_3, 'full_name' => 'Test', 'default_channel' => BaseApiV1TestCase::CHANNEL_UUID, @@ -1220,7 +1217,7 @@ public function testPutToUpdateWithoutIdentifier(Connection $db, Url $endpoint): 'PUT', $endpoint, 'v1/contacts', - json: [ + json: [ 'id' => BaseApiV1TestCase::CONTACT_UUID_3, 'full_name' => 'Test', 'default_channel' => BaseApiV1TestCase::CHANNEL_UUID, @@ -1248,7 +1245,7 @@ public function testPutToUpdateWithMissingRequiredFields( 'PUT', $endpoint, 'v1/contacts/' . BaseApiV1TestCase::CONTACT_UUID, - json: [ + json: [ 'full_name' => 'Test', 'default_channel' => BaseApiV1TestCase::CHANNEL_UUID, ] @@ -1266,7 +1263,7 @@ public function testPutToUpdateWithMissingRequiredFields( 'PUT', $endpoint, 'v1/contacts/' . BaseApiV1TestCase::CONTACT_UUID, - json: [ + json: [ 'id' => BaseApiV1TestCase::CONTACT_UUID, 'default_channel' => BaseApiV1TestCase::CHANNEL_UUID, ] @@ -1284,7 +1281,7 @@ public function testPutToUpdateWithMissingRequiredFields( 'PUT', $endpoint, 'v1/contacts/' . BaseApiV1TestCase::CONTACT_UUID, - json: [ + json: [ 'id' => BaseApiV1TestCase::CONTACT_UUID, 'full_name' => 'Test', ] @@ -1302,7 +1299,7 @@ public function testPutToUpdateWithMissingRequiredFields( 'PUT', $endpoint, 'v1/contacts/' . BaseApiV1TestCase::CONTACT_UUID, - json: [ + json: [ 'id' => BaseApiV1TestCase::CONTACT_UUID, 'full_name' => 'Test', 'default_channel' => BaseApiV1TestCase::CHANNEL_UUID, @@ -1331,7 +1328,7 @@ public function testPutToUpdateWithInvalidFieldFormat( 'PUT', $endpoint, 'v1/contacts/' . BaseApiV1TestCase::CONTACT_UUID, - json: [ + json: [ 'id' => [BaseApiV1TestCase::CONTACT_UUID], 'full_name' => 'Test', 'default_channel' => BaseApiV1TestCase::CHANNEL_UUID, @@ -1351,7 +1348,7 @@ public function testPutToUpdateWithInvalidFieldFormat( 'PUT', $endpoint, 'v1/contacts/' . BaseApiV1TestCase::CONTACT_UUID, - json: [ + json: [ 'id' => BaseApiV1TestCase::CONTACT_UUID, 'full_name' => ['Test'], 'default_channel' => BaseApiV1TestCase::CHANNEL_UUID, @@ -1371,7 +1368,7 @@ public function testPutToUpdateWithInvalidFieldFormat( 'PUT', $endpoint, 'v1/contacts/' . BaseApiV1TestCase::CONTACT_UUID, - json: [ + json: [ 'id' => BaseApiV1TestCase::CONTACT_UUID, 'full_name' => 'Test', 'default_channel' => [BaseApiV1TestCase::CHANNEL_UUID], @@ -1391,7 +1388,7 @@ public function testPutToUpdateWithInvalidFieldFormat( 'PUT', $endpoint, 'v1/contacts/' . BaseApiV1TestCase::CONTACT_UUID, - json: [ + json: [ 'id' => BaseApiV1TestCase::CONTACT_UUID, 'full_name' => 'Test', 'default_channel' => BaseApiV1TestCase::CHANNEL_UUID, @@ -1413,7 +1410,7 @@ public function testPutToUpdateWithInvalidFieldFormat( 'PUT', $endpoint, 'v1/contacts/' . BaseApiV1TestCase::CONTACT_UUID, - json: [ + json: [ 'id' => BaseApiV1TestCase::CONTACT_UUID, 'full_name' => 'Test', 'default_channel' => BaseApiV1TestCase::CHANNEL_UUID, @@ -1434,7 +1431,7 @@ public function testPutToUpdateWithInvalidFieldFormat( 'PUT', $endpoint, 'v1/contacts/' . BaseApiV1TestCase::CONTACT_UUID, - json: [ + json: [ 'id' => BaseApiV1TestCase::CONTACT_UUID, 'full_name' => 'Test', 'default_channel' => BaseApiV1TestCase::CHANNEL_UUID, @@ -1462,7 +1459,7 @@ public function testPutToUpdateWithDifferentPayloadId( 'PUT', $endpoint, 'v1/contacts/' . BaseApiV1TestCase::CONTACT_UUID, - json: [ + json: [ 'id' => BaseApiV1TestCase::CONTACT_UUID_3, 'full_name' => 'Test', 'default_channel' => BaseApiV1TestCase::CHANNEL_UUID, @@ -1484,7 +1481,7 @@ public function testPutToCreateWithValidData(Connection $db, Url $endpoint): voi 'PUT', $endpoint, 'v1/contacts/' . BaseApiV1TestCase::CONTACT_UUID_3, - json: [ + json: [ 'id' => BaseApiV1TestCase::CONTACT_UUID_3, 'full_name' => 'Test', 'default_channel' => BaseApiV1TestCase::CHANNEL_UUID, @@ -1538,7 +1535,7 @@ public function testPutToUpdateWithValidData(Connection $db, Url $endpoint): voi 'PUT', $endpoint, 'v1/contacts/' . BaseApiV1TestCase::CONTACT_UUID, - json: [ + json: [ 'id' => BaseApiV1TestCase::CONTACT_UUID, 'full_name' => 'Test', 'default_channel' => BaseApiV1TestCase::CHANNEL_UUID, @@ -1578,7 +1575,7 @@ public function testPutToUpdateWithInvalidData(Connection $db, Url $endpoint): v 'PUT', $endpoint, 'v1/contacts/' . BaseApiV1TestCase::CONTACT_UUID, - json: [ + json: [ 'id' => BaseApiV1TestCase::CONTACT_UUID, 'full_name' => 'Test', 'default_channel' => BaseApiV1TestCase::CHANNEL_UUID_3, @@ -1600,7 +1597,7 @@ public function testPutToUpdateWithInvalidData(Connection $db, Url $endpoint): v 'PUT', $endpoint, 'v1/contacts/' . BaseApiV1TestCase::CONTACT_UUID, - json: [ + json: [ 'id' => BaseApiV1TestCase::CONTACT_UUID, 'full_name' => 'Test', 'default_channel' => BaseApiV1TestCase::CHANNEL_UUID, @@ -1623,7 +1620,7 @@ public function testPutToUpdateWithInvalidData(Connection $db, Url $endpoint): v 'PUT', $endpoint, 'v1/contacts/' . BaseApiV1TestCase::CONTACT_UUID, - json: [ + json: [ 'id' => BaseApiV1TestCase::CONTACT_UUID, 'full_name' => 'Test', 'default_channel' => BaseApiV1TestCase::CHANNEL_UUID, @@ -1652,7 +1649,7 @@ public function testPutToCreateWithMissingRequiredFields(Connection $db, Url $en 'PUT', $endpoint, 'v1/contacts/' . BaseApiV1TestCase::CONTACT_UUID_3, - json: [ + json: [ 'id' => BaseApiV1TestCase::CONTACT_UUID_3, 'default_channel' => BaseApiV1TestCase::CHANNEL_UUID, ] @@ -1670,7 +1667,7 @@ public function testPutToCreateWithMissingRequiredFields(Connection $db, Url $en 'PUT', $endpoint, 'v1/contacts/' . BaseApiV1TestCase::CONTACT_UUID_3, - json: [ + json: [ 'full_name' => 'Test', 'default_channel' => BaseApiV1TestCase::CHANNEL_UUID, ] @@ -1688,7 +1685,7 @@ public function testPutToCreateWithMissingRequiredFields(Connection $db, Url $en 'PUT', $endpoint, 'v1/contacts/' . BaseApiV1TestCase::CONTACT_UUID_3, - json: [ + json: [ 'id' => BaseApiV1TestCase::CONTACT_UUID_3, 'full_name' => 'Test', ] @@ -1705,7 +1702,7 @@ public function testPutToCreateWithMissingRequiredFields(Connection $db, Url $en 'PUT', $endpoint, 'v1/contacts/' . BaseApiV1TestCase::CONTACT_UUID_3, - json: [ + json: [ 'id' => BaseApiV1TestCase::CONTACT_UUID_3, 'full_name' => 'Test', 'default_channel' => BaseApiV1TestCase::CHANNEL_UUID, @@ -1733,7 +1730,7 @@ public function testPutToCreateWithInvalidFieldFormat( 'PUT', $endpoint, 'v1/contacts/' . BaseApiV1TestCase::CONTACT_UUID_3, - json: [ + json: [ 'id' => [BaseApiV1TestCase::CONTACT_UUID_3], 'full_name' => 'Test', 'default_channel' => BaseApiV1TestCase::CHANNEL_UUID, @@ -1753,7 +1750,7 @@ public function testPutToCreateWithInvalidFieldFormat( 'PUT', $endpoint, 'v1/contacts/' . BaseApiV1TestCase::CONTACT_UUID_3, - json: [ + json: [ 'id' => BaseApiV1TestCase::CONTACT_UUID_3, 'full_name' => ['Test'], 'default_channel' => BaseApiV1TestCase::CHANNEL_UUID, @@ -1773,7 +1770,7 @@ public function testPutToCreateWithInvalidFieldFormat( 'PUT', $endpoint, 'v1/contacts/' . BaseApiV1TestCase::CONTACT_UUID_3, - json: [ + json: [ 'id' => BaseApiV1TestCase::CONTACT_UUID_3, 'full_name' => 'Test', 'default_channel' => [BaseApiV1TestCase::CHANNEL_UUID], @@ -1793,7 +1790,7 @@ public function testPutToCreateWithInvalidFieldFormat( 'PUT', $endpoint, 'v1/contacts/' . BaseApiV1TestCase::CONTACT_UUID_3, - json: [ + json: [ 'id' => BaseApiV1TestCase::CONTACT_UUID_3, 'full_name' => 'Test', 'default_channel' => BaseApiV1TestCase::CHANNEL_UUID, @@ -1815,7 +1812,7 @@ public function testPutToCreateWithInvalidFieldFormat( 'PUT', $endpoint, 'v1/contacts/' . BaseApiV1TestCase::CONTACT_UUID_3, - json: [ + json: [ 'id' => BaseApiV1TestCase::CONTACT_UUID_3, 'full_name' => 'Test', 'default_channel' => BaseApiV1TestCase::CHANNEL_UUID, @@ -1836,7 +1833,7 @@ public function testPutToCreateWithInvalidFieldFormat( 'PUT', $endpoint, 'v1/contacts/' . BaseApiV1TestCase::CONTACT_UUID_3, - json: [ + json: [ 'id' => BaseApiV1TestCase::CONTACT_UUID_3, 'full_name' => 'Test', 'default_channel' => BaseApiV1TestCase::CHANNEL_UUID, @@ -1863,7 +1860,7 @@ public function testPutToChangeGroupMemberships(Connection $db, Url $endpoint): 'PUT', $endpoint, 'v1/contacts/' . BaseApiV1TestCase::CONTACT_UUID, - json: [ + json: [ 'id' => BaseApiV1TestCase::CONTACT_UUID, 'full_name' => 'Test', 'default_channel' => BaseApiV1TestCase::CHANNEL_UUID, @@ -1897,7 +1894,7 @@ public function testPutToChangeGroupMemberships(Connection $db, Url $endpoint): 'PUT', $endpoint, 'v1/contacts/' . BaseApiV1TestCase::CONTACT_UUID, - json: [ + json: [ 'id' => BaseApiV1TestCase::CONTACT_UUID, 'full_name' => 'Test', 'default_channel' => BaseApiV1TestCase::CHANNEL_UUID, @@ -1931,7 +1928,7 @@ public function testPutToChangeGroupMemberships(Connection $db, Url $endpoint): 'PUT', $endpoint, 'v1/contacts/' . BaseApiV1TestCase::CONTACT_UUID, - json: [ + json: [ 'id' => BaseApiV1TestCase::CONTACT_UUID, 'full_name' => 'Test', 'default_channel' => BaseApiV1TestCase::CHANNEL_UUID, @@ -1971,7 +1968,7 @@ public function testPutToChangeAddresses(Connection $db, Url $endpoint): void 'PUT', $endpoint, 'v1/contacts/' . BaseApiV1TestCase::CONTACT_UUID, - json: [ + json: [ 'id' => BaseApiV1TestCase::CONTACT_UUID, 'full_name' => 'Test', 'default_channel' => BaseApiV1TestCase::CHANNEL_UUID, @@ -2012,7 +2009,7 @@ public function testPutToChangeAddresses(Connection $db, Url $endpoint): void 'PUT', $endpoint, 'v1/contacts/' . BaseApiV1TestCase::CONTACT_UUID, - json: [ + json: [ 'id' => BaseApiV1TestCase::CONTACT_UUID, 'full_name' => 'Test', 'default_channel' => BaseApiV1TestCase::CHANNEL_UUID, @@ -2051,7 +2048,7 @@ public function testPutToChangeAddresses(Connection $db, Url $endpoint): void 'PUT', $endpoint, 'v1/contacts/' . BaseApiV1TestCase::CONTACT_UUID, - json: [ + json: [ 'id' => BaseApiV1TestCase::CONTACT_UUID, 'full_name' => 'Test', 'default_channel' => BaseApiV1TestCase::CHANNEL_UUID, diff --git a/test/php/application/forms/EventRuleConfigFormTest.php b/test/php/application/forms/EventRuleConfigFormTest.php index 6315a6ca3..c3f384fa2 100755 --- a/test/php/application/forms/EventRuleConfigFormTest.php +++ b/test/php/application/forms/EventRuleConfigFormTest.php @@ -4,6 +4,7 @@ namespace Tests\Icinga\Module\Notifications\Forms; +use ArrayIterator; use DateTime; use Icinga\Module\Notifications\Forms\EventRuleConfigElements\ConfigProviderInterface; use Icinga\Module\Notifications\Forms\EventRuleConfigForm; @@ -189,7 +190,7 @@ public function testLoadAndStorage(): void ->willReturnSelf(); $queryResult = new ResultSet( - new \ArrayIterator([ + new ArrayIterator([ (new RuleEscalation())->setProperties([ 'id' => 1, 'condition' => null, @@ -441,7 +442,7 @@ public function testNoChangesAlsoCauseNoUpdates(): void ->willReturnSelf(); $queryResult = new ResultSet( - new \ArrayIterator([ + new ArrayIterator([ (new RuleEscalation())->setProperties([ 'id' => 1, 'condition' => null, @@ -554,7 +555,7 @@ public function testIfARuleChangesOnlyTheRuleItselfIsUpdated(): void ->willReturnSelf(); $queryResult = new ResultSet( - new \ArrayIterator([ + new ArrayIterator([ (new RuleEscalation())->setProperties([ 'id' => 1, 'condition' => null, @@ -683,7 +684,7 @@ public function testIfARuleChangesOnlyTheEscalationIsUpdated(): void ->willReturnSelf(); $queryResult = new ResultSet( - new \ArrayIterator([ + new ArrayIterator([ (new RuleEscalation())->setProperties([ 'id' => 1, 'condition' => 'incident_severity>=crit&incident_age>5m', @@ -817,7 +818,7 @@ public function testIfARuleChangesOnlyTheEscalationRecipientIsUpdated(): void ->willReturnSelf(); $queryResult = new ResultSet( - new \ArrayIterator([ + new ArrayIterator([ (new RuleEscalation())->setProperties([ 'id' => 1, 'condition' => null, diff --git a/test/php/library/Notifications/Widget/CalendarTest.php b/test/php/library/Notifications/Widget/CalendarTest.php index 063898f19..54f5fe9b4 100644 --- a/test/php/library/Notifications/Widget/CalendarTest.php +++ b/test/php/library/Notifications/Widget/CalendarTest.php @@ -4,6 +4,7 @@ namespace Tests\Icinga\Module\Notifications\Widget; +use DateTime; use Icinga\Module\Notifications\Widget\Calendar; use ipl\I18n\NoopTranslator; use ipl\I18n\StaticTranslator; @@ -32,7 +33,7 @@ public function testMonthGridStartsAtTheFirstDayOfItsFirstDaysWeek() $calendar->setControls($controls); $this->assertEquals( - new \DateTime('2023-01-30T00:00:00+0100'), + new DateTime('2023-01-30T00:00:00+0100'), $calendar->getGrid()->getGridStart() ); } finally { @@ -59,7 +60,7 @@ public function testMonthGridVisualizesSixWeeks() $calendar->setControls($controls); $this->assertEquals( - new \DateTime('2023-03-13T00:00:00+0100'), + new DateTime('2023-03-13T00:00:00+0100'), $calendar->getGrid()->getGridEnd() ); } finally {