diff --git a/.github/workflows/php.yml b/.github/workflows/php.yml
index 04b087918..e9023437f 100644
--- a/.github/workflows/php.yml
+++ b/.github/workflows/php.yml
@@ -1,140 +1,39 @@
-name: PHP Tests
+name: CI
on:
push:
branches:
- main
- - release/*
+ - support/*
pull_request:
- branches:
- - main
jobs:
- lint:
- name: Static analysis for php ${{ matrix.php }} on ${{ matrix.os }}
- runs-on: ${{ matrix.os }}
-
- strategy:
- fail-fast: false
- matrix:
- php: ['8.2', '8.3', '8.4']
- os: ['ubuntu-latest']
-
- steps:
- - name: Checkout code base
- uses: actions/checkout@v4
-
- - name: Setup PHP
- uses: shivammathur/setup-php@v2
- with:
- php-version: ${{ matrix.php }}
- tools: phpcs
-
- - name: Setup dependencies
- run: composer require -n --no-progress overtrue/phplint
-
- - name: PHP Lint
- if: ${{ ! cancelled() }}
- run: ./vendor/bin/phplint -n --exclude={^vendor/.*} -- .
-
- - name: PHP CodeSniffer
- if: ${{ ! cancelled() }}
- run: phpcs -wps --colors
-
- test:
- name: Unit tests with php ${{ matrix.php }} on ${{ matrix.os }}
- runs-on: ${{ matrix.os }}
-
- env:
- phpunit-version: 10.0
-
- strategy:
- fail-fast: false
- matrix:
- php: ['8.2', '8.3', '8.4']
- os: ['ubuntu-latest']
-
- services:
- mysql:
- image: mariadb
- env:
- MYSQL_ROOT_PASSWORD: root
- MYSQL_DATABASE: icinga_unittest
- MYSQL_USER: icinga_unittest
- MYSQL_PASSWORD: icinga_unittest
- options: >-
- --health-cmd "mariadb -s -uroot -proot -e'SHOW DATABASES;' 2> /dev/null | grep icinga_unittest > test"
- --health-interval 10s
- --health-timeout 5s
- --health-retries 5
- ports:
- - 3306/tcp
-
- pgsql:
- image: postgres
- env:
- POSTGRES_USER: icinga_unittest
- POSTGRES_PASSWORD: icinga_unittest
- POSTGRES_DB: icinga_unittest
- options: >-
- --health-cmd pg_isready
- --health-interval 10s
- --health-timeout 5s
- --health-retries 5
- ports:
- - 5432/tcp
-
- steps:
- - name: Checkout code base
- uses: actions/checkout@v4
-
- - name: Setup PHP
- uses: shivammathur/setup-php@v2
- with:
- php-version: ${{ matrix.php }}
- tools: phpunit:${{ matrix.phpunit-version || env.phpunit-version }}
-
- - name: Setup Icinga Web
- run: |
- git clone --depth 1 https://github.com/Icinga/icingaweb2.git _icingaweb2
- ln -s `pwd` _icingaweb2/modules/notifications
-
- - name: Setup Libraries
- run: |
- mkdir _libraries
- git clone --depth 1 -b snapshot/nightly https://github.com/Icinga/icinga-php-library.git _libraries/ipl
- git clone --depth 1 -b snapshot/nightly https://github.com/Icinga/icinga-php-thirdparty.git _libraries/vendor
-
- - name: Checkout Icinga Notifications Daemon
- run: |
- git clone --depth 1 -b main https://github.com/Icinga/icinga-notifications.git _notifications_daemon
-
- - name: Initialize Icinga Web
- run: |
- mysql --host="127.0.0.1" --port="${{ job.services.mysql.ports['3306'] }}" --user="root" --password="root" \
- -e "CREATE DATABASE icingaweb; CREATE USER icingaweb@'%' IDENTIFIED BY 'icingaweb'; GRANT ALL ON icingaweb.* TO icingaweb@'%';"
- PGPASSWORD=icinga_unittest psql --host="127.0.0.1" --port="${{ job.services.pgsql.ports['5432'] }}" \
- --username "icinga_unittest" -c "CREATE DATABASE icingaweb;"
-
- - name: PHPUnit
- env:
- ICINGAWEB_LIBDIR: _libraries
- ICINGAWEB_PATH: _icingaweb2
- ICINGA_NOTIFICATIONS_SCHEMA: _notifications_daemon/schema
- MYSQL_TESTDB: icinga_unittest
- MYSQL_TESTDB_HOST: 127.0.0.1
- MYSQL_TESTDB_PORT: ${{ job.services.mysql.ports['3306'] }}
- MYSQL_TESTDB_USER: icinga_unittest
- MYSQL_TESTDB_PASSWORD: icinga_unittest
- MYSQL_ICINGAWEBDB: icingaweb
- MYSQL_ICINGAWEBDB_PASSWORD: icingaweb
- MYSQL_ICINGAWEBDB_USER: icingaweb
- PGSQL_TESTDB: icinga_unittest
- PGSQL_TESTDB_HOST: 127.0.0.1
- PGSQL_TESTDB_PORT: ${{ job.services.pgsql.ports['5432'] }}
- PGSQL_TESTDB_USER: icinga_unittest
- PGSQL_TESTDB_PASSWORD: icinga_unittest
- PGSQL_ICINGAWEBDB: icingaweb
- PGSQL_ICINGAWEBDB_PASSWORD: icinga_unittest
- PGSQL_ICINGAWEBDB_USER: icinga_unittest
- run: phpunit --bootstrap _icingaweb2/test/php/bootstrap.php
+ php:
+ name: PHP
+ uses: Icinga/github-actions/.github/workflows/php.yml@main
+ with:
+ databases: true
+ dependencies: |
+ {
+ "./vendor/icingaweb2-modules/icingadb" : "https://github.com/Icinga/icingadb-web.git",
+ "./vendor/notifications_daemon" : "https://github.com/Icinga/icinga-notifications.git"
+ }
+ setup-commands: |
+ # Only run setup commands if test databases are available which is only the case for PHPUnit jobs
+ [ -z "${MYSQL_TESTDB_PORT}" ] && exit 0
+ mysql --host="${MYSQL_TESTDB_HOST}" --port=${MYSQL_TESTDB_PORT} --user=root --password="${MYSQL_TESTDB_PASSWORD}" \
+ -e "CREATE DATABASE icingaweb; CREATE USER icingaweb@'%' IDENTIFIED BY 'icingaweb'; GRANT ALL ON icingaweb.* TO icingaweb@'%';"
+ [ -z "${PGSQL_TESTDB_PORT}" ] && exit 0
+ PGPASSWORD="${PGSQL_TESTDB_PASSWORD}" psql --host="${PGSQL_TESTDB_HOST}" --port=${PGSQL_TESTDB_PORT} \
+ --username "${PGSQL_TESTDB_USER}" -c "CREATE DATABASE icingaweb;"
+ env: |
+ {
+ "ICINGAWEB_PATH" : "./vendor/icingaweb2",
+ "ICINGA_NOTIFICATIONS_SCHEMA" : "./vendor/notifications_daemon/schema",
+ "MYSQL_ICINGAWEBDB" : "icingaweb",
+ "MYSQL_ICINGAWEBDB_PASSWORD" : "icingaweb",
+ "MYSQL_ICINGAWEBDB_USER" : "icingaweb",
+ "PGSQL_ICINGAWEBDB" : "icingaweb",
+ "PGSQL_ICINGAWEBDB_PASSWORD" : "icinga_unittest",
+ "PGSQL_ICINGAWEBDB_USER" : "icinga_unittest"
+ }
diff --git a/.github/workflows/phpstan.yml b/.github/workflows/phpstan.yml
deleted file mode 100644
index c82d48a16..000000000
--- a/.github/workflows/phpstan.yml
+++ /dev/null
@@ -1,16 +0,0 @@
-name: PHPStan
-
-on:
- pull_request:
- branches:
- - main
-
-jobs:
- phpstan:
- uses: icinga/github-actions/.github/workflows/phpstan.yml@main
- with:
- dependencies: |
- {
- "/icingaweb2" : "https://github.com/Icinga/icingaweb2.git",
- "/usr/share/icingaweb2-modules/icingadb" : "https://github.com/Icinga/icingadb-web.git"
- }
diff --git a/.gitignore b/.gitignore
index fa9f9313a..f4fab36fe 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,4 +4,3 @@
# Except those related to Git and GitHub
!.git*
!.github
-!.phpcs.xml
diff --git a/.phpcs.xml b/.phpcs.xml
deleted file mode 100644
index ab5280c44..000000000
--- a/.phpcs.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-
-
- Sniff our code a while
-
- ./
-
- vendor/*
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
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..ad3a3c777 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,9 +583,13 @@ public function removeRotation(int $id): void
/**
* Remove all versions of the rotation from the database
*
+ * @param ?int $priority
+ *
* @return void
+ *
+ * @throws LogicException If the priority is not set
*/
- public function wipeRotation(int $priority = null): void
+ public function wipeRotation(?int $priority = null): void
{
$priority = $priority ?? $this->getValue('priority');
if ($priority === null) {
@@ -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/Middleware/MiddlewarePipeline.php b/library/Notifications/Api/Middleware/MiddlewarePipeline.php
index 2418b1c2f..9cd806b1f 100644
--- a/library/Notifications/Api/Middleware/MiddlewarePipeline.php
+++ b/library/Notifications/Api/Middleware/MiddlewarePipeline.php
@@ -82,7 +82,7 @@ public function handle(ServerRequestInterface $request): ResponseInterface
*
* @return ResponseInterface
*/
- public function execute(ServerRequestInterface $request = null): ResponseInterface
+ public function execute(?ServerRequestInterface $request = null): ResponseInterface
{
if ($request === null) {
$request = new ServerRequest('GET', '/'); // initial dummy request
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..c28457a53 100644
--- a/library/Notifications/Api/OpenApiDescriptionElement/Response/Error404Response.php
+++ b/library/Notifications/Api/OpenApiDescriptionElement/Response/Error404Response.php
@@ -4,16 +4,13 @@
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
{
- public function __construct(string $endpointName = null)
+ public function __construct(?string $endpointName = null)
{
parent::__construct(
response: 404,
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..4bc32c807 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
@@ -763,7 +764,7 @@ public function prepareRow(stdClass $row): void
*
* @throws HttpException if the username already exists
*/
- private function assertUniqueName(string $name, int $contactgroupId = null): void
+ private function assertUniqueName(string $name, ?int $contactgroupId = null): void
{
$stmt = (new Select())
->from('contactgroup')
@@ -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..c96ee4046 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
@@ -860,7 +862,7 @@ private function removeContact(int $id): void
*
* @throws HttpException if the username already exists
*/
- private function assertUniqueUsername(string $username, int $contactId = null): void
+ private function assertUniqueUsername(string $username, ?int $contactId = null): void
{
$stmt = (new Select())
->from('contact')
@@ -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..7e5b73841 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()
@@ -78,7 +77,15 @@ private static function getConnection(): Connection
$config->options = [PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_OBJ];
if ($config->db === 'mysql') {
- $config->options[PDO::MYSQL_ATTR_INIT_COMMAND] = "SET SESSION SQL_MODE='STRICT_TRANS_TABLES"
+ // As of PHP 8.5, driver-specific constants of the PDO class are deprecated,
+ // but the replacement constants are only available since PHP 8.4.
+ if (version_compare(PHP_VERSION, '8.4.0', '<')) {
+ $mysqlAttrInitCommand = PDO::MYSQL_ATTR_INIT_COMMAND;
+ } else {
+ $mysqlAttrInitCommand = Pdo\Mysql::ATTR_INIT_COMMAND;
+ }
+
+ $config->options[$mysqlAttrInitCommand] = "SET SESSION SQL_MODE='STRICT_TRANS_TABLES"
. ",NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'";
}
@@ -166,7 +173,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 +215,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 +271,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 +283,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..579b8c9c8 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,45 +14,44 @@
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;
use React\EventLoop\LoopInterface;
-use function Clue\React\Block\await;
-use function React\Promise\Timer\sleep;
+use function React\Async\delay;
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 +148,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)" : ""));
@@ -264,7 +261,7 @@ protected function processNotifications(): void
/** @var IncidentHistory $notification */
$notificationsToProcess = [];
foreach ($notifications as $notification) {
- if (isset($connections[$notification->contact_id])) {
+ if ($notification->contact_id !== null && isset($connections[$notification->contact_id])) {
ObjectsRendererHook::register($notification->incident->object);
$notificationsToProcess[] = $notification;
@@ -323,8 +320,8 @@ protected function run(): void
$endMs = (int) (microtime(true) * 1000);
if (($endMs - $beginMs) < 3000) {
- // run took less than 3 seconds; sleep for the remaining duration to prevent heavy db loads
- await(sleep((3000 - ($endMs - $beginMs)) / 1000));
+ // run took less than 3 seconds; delay for the remaining duration to prevent heavy db loads
+ delay((3000 - ($endMs - $beginMs)) / 1000);
}
}
self::$logger::debug(self::PREFIX . "cancellation triggered; exiting loop");
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..9fb2fb77f 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
{
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..e9749200f 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,12 +28,15 @@ 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)
+ public function rewriteColumn($column, ?string $relation = null): ?AliasedExpression
{
if ($column === 'id_tags') {
$path = ($relation ?? $this->query->getModel()->getTableAlias()) . '.object_id_tag';
@@ -61,6 +64,8 @@ public function rewriteColumn($column, ?string $relation = null)
$this->query->getResolver()->qualifyColumn('value', $pathAlias)
));
}
+
+ return null;
}
public function isSelectableColumn(string $name): bool
@@ -68,7 +73,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 +88,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());
}
@@ -91,7 +106,8 @@ public function rewriteColumnDefinition(ColumnDefinition $def, string $relation)
{
}
- public function rewriteCondition(Filter\Condition $condition, $relation = null)
+ public function rewriteCondition(Filter\Condition $condition, $relation = null): null
{
+ return null;
}
}
diff --git a/library/Notifications/Model/Behavior/ObjectTags.php b/library/Notifications/Model/Behavior/ObjectTags.php
index e466140f6..18fa704d6 100644
--- a/library/Notifications/Model/Behavior/ObjectTags.php
+++ b/library/Notifications/Model/Behavior/ObjectTags.php
@@ -15,10 +15,10 @@ class ObjectTags implements RewriteColumnBehavior, QueryAwareBehavior
{
use Auth;
- /** @var Query */
- protected $query;
+ /** @var ?Query */
+ protected ?Query $query = null;
- public function setQuery(Query $query): self
+ public function setQuery(Query $query): static
{
$this->query = $query;
@@ -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.';
@@ -48,7 +48,7 @@ public function rewriteCondition(Filter\Condition $condition, $relation = null):
return $filterAll;
}
- public function rewriteColumn($column, $relation = null): AliasedExpression
+ public function rewriteColumn($column, ?string $relation = null): AliasedExpression
{
/** @var string $relation */
/** @var string $column */
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/ApiTestBackends.php b/library/Notifications/Test/ApiTestBackends.php
index 105dd3ebe..0e714ea08 100644
--- a/library/Notifications/Test/ApiTestBackends.php
+++ b/library/Notifications/Test/ApiTestBackends.php
@@ -90,7 +90,7 @@ abstract protected static function initializeNotificationsDb(Connection $db, str
*
* @return array
*/
- final public function apiTestBackends(): array
+ final public static function apiTestBackends(): array
{
self::initializeBackends();
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..e8298cd2d 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
@@ -176,7 +176,7 @@ protected function assemble()
$contact->registerElement($defaultChannel);
- $this->addAddressElements($availableTypes, $channelTypes[$defaultChannel->getValue()] ?? null);
+ $this->addAddressElements($availableTypes, $channelTypes[$defaultChannel->getValue() ?? ''] ?? null);
$this->addHtml(new HtmlElement('hr'));
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..d3e62210c 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();
@@ -221,7 +221,7 @@ protected function unsubscribe(IncidentContact $incidentContact): void
*
* @return void
*/
- protected function updateHistory(IncidentContact $incidentContact, string $newRole = null): void
+ protected function updateHistory(IncidentContact $incidentContact, ?string $newRole = null): void
{
$oldRole = $incidentContact->role;
$contactId = $incidentContact->contact_id ?? $this->currentUserId;
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..b07e45cb1 100644
--- a/library/Notifications/Widget/ShowMore.php
+++ b/library/Notifications/Widget/ShowMore.php
@@ -18,13 +18,13 @@ 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)
+ public function __construct(ResultSet $resultSet, Url $url, ?string $label = null)
{
$this->label = $label;
$this->resultSet = $resultSet;
@@ -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..83b5a9980 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
@@ -253,7 +253,7 @@ final protected function yieldFlowingEntries(Traversable $entries): Generator
$cellOccupiers[$rowStart][$column][] = spl_object_id($entry);
}
- $occupiedCells->attach($entry, $rows);
+ $occupiedCells->offsetSet($entry, $rows);
}
$rowPlacements = [];
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..61e6c203c 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;
@@ -222,7 +222,7 @@ public function getEntries(): Traversable
foreach ($occupiedCells as $cell => $entry) {
$cells = $entryToCellsMap[$entry] ?? [];
$cells[] = $cell;
- $entryToCellsMap->attach($entry, $cells);
+ $entryToCellsMap->offsetSet($entry, $cells);
}
foreach ($entryToCellsMap as $entry) {
@@ -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/phpunit.xml b/phpunit.xml
deleted file mode 100644
index ea915fbcf..000000000
--- a/phpunit.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
- test/php
-
-
-
diff --git a/test/php/application/controllers/ApiV1ChannelsTest.php b/test/php/application/controllers/ApiV1ChannelsTest.php
index 2e789b50a..661b5924e 100644
--- a/test/php/application/controllers/ApiV1ChannelsTest.php
+++ b/test/php/application/controllers/ApiV1ChannelsTest.php
@@ -8,12 +8,11 @@
use Icinga\Web\Url;
use ipl\Sql\Connection;
use WebSocket\Base;
+use PHPUnit\Framework\Attributes\DataProvider;
class ApiV1ChannelsTest extends BaseApiV1TestCase
{
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testGetWithMatchingFilter(Connection $db, Url $endpoint): void
{
$expected = $this->jsonEncodeResults([
@@ -72,9 +71,7 @@ public function testGetWithMatchingFilter(Connection $db, Url $endpoint): void
$this->assertJsonStringEqualsJsonString($expected, $content);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testGetEverything(Connection $db, Url $endpoint): void
{
// At first, there are none
@@ -119,9 +116,7 @@ public function testGetEverything(Connection $db, Url $endpoint): void
$this->assertJsonStringEqualsJsonString($expected, $content);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testGetWithAlreadyExistingIdentifier(Connection $db, Url $endpoint): void
{
$response = $this->sendRequest('GET', $endpoint, 'v1/channels/' . BaseApiV1TestCase::CHANNEL_UUID);
@@ -137,9 +132,7 @@ public function testGetWithAlreadyExistingIdentifier(Connection $db, Url $endpoi
$this->assertJsonStringEqualsJsonString($expected, $content);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testGetWithNonMatchingFilter(Connection $db, Url $endpoint): void
{
$response = $this->sendRequest('GET', $endpoint, 'v1/channels', ['name' => 'not_test']);
@@ -149,9 +142,7 @@ public function testGetWithNonMatchingFilter(Connection $db, Url $endpoint): voi
$this->assertJsonStringEqualsJsonString($this->jsonEncodeResults([]), $content);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testGetWithInvalidFilter(Connection $db, Url $endpoint): void
{
$response = $this->sendRequest('GET', $endpoint, 'v1/channels', ['nonexistingfilter' => 'value']);
@@ -164,9 +155,7 @@ public function testGetWithInvalidFilter(Connection $db, Url $endpoint): void
$this->assertJsonStringEqualsJsonString($expected, $content);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testGetWithNewIdentifier(Connection $db, Url $endpoint): void
{
$response = $this->sendRequest('GET', $endpoint, 'v1/channels/' . BaseApiV1TestCase::CHANNEL_UUID_3);
@@ -176,9 +165,7 @@ public function testGetWithNewIdentifier(Connection $db, Url $endpoint): void
$this->assertJsonStringEqualsJsonString($this->jsonEncodeError('Channel not found'), $content);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testGetWithInvalidIdentifier(Connection $db, Url $endpoint): void
{
$response = $this->sendRequest('GET', $endpoint, 'v1/channels/' . BaseApiV1TestCase::UUID_INCOMPLETE);
@@ -191,9 +178,7 @@ public function testGetWithInvalidIdentifier(Connection $db, Url $endpoint): voi
);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testGetWithIdentifierAndFilter(Connection $db, Url $endpoint): void
{
$expected = $this->jsonEncodeError(
@@ -225,9 +210,7 @@ public function testGetWithIdentifierAndFilter(Connection $db, Url $endpoint): v
$this->assertJsonStringEqualsJsonString($expected, $content);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testRequestWithNonSupportedMethod(Connection $db, Url $endpoint): void
{
$expectedAllowHeader = 'GET';
diff --git a/test/php/application/controllers/ApiV1ContactGroupsTest.php b/test/php/application/controllers/ApiV1ContactGroupsTest.php
index c0eaa573f..476f8215f 100644
--- a/test/php/application/controllers/ApiV1ContactGroupsTest.php
+++ b/test/php/application/controllers/ApiV1ContactGroupsTest.php
@@ -4,17 +4,15 @@
namespace Tests\Icinga\Module\Notifications\Controllers;
-use GuzzleHttp\Client;
use Icinga\Module\Notifications\Test\BaseApiV1TestCase;
use Icinga\Web\Url;
use ipl\Sql\Connection;
use WebSocket\Base;
+use PHPUnit\Framework\Attributes\DataProvider;
class ApiV1ContactGroupsTest extends BaseApiV1TestCase
{
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testGetWithMatchingFilter(Connection $db, Url $endpoint): void
{
$response = $this->sendRequest('GET', $endpoint, 'v1/contact-groups', ['name' => 'Test']);
@@ -29,9 +27,7 @@ public function testGetWithMatchingFilter(Connection $db, Url $endpoint): void
$this->assertJsonStringEqualsJsonString($expected, $content);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testGetEverything(Connection $db, Url $endpoint): void
{
// At first, there are none
@@ -66,9 +62,7 @@ public function testGetEverything(Connection $db, Url $endpoint): void
$this->assertJsonStringEqualsJsonString($expected, $content);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testGetWithAlreadyExistingIdentifier(Connection $db, Url $endpoint): void
{
$response = $this->sendRequest('GET', $endpoint, 'v1/contact-groups/' . BaseApiV1TestCase::GROUP_UUID);
@@ -83,9 +77,7 @@ public function testGetWithAlreadyExistingIdentifier(Connection $db, Url $endpoi
$this->assertJsonStringEqualsJsonString($expected, $content);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testGetWithUnknownIdentifier(Connection $db, Url $endpoint): void
{
$response = $this->sendRequest('GET', $endpoint, 'v1/contact-groups/' . BaseApiV1TestCase::GROUP_UUID_3);
@@ -95,9 +87,7 @@ public function testGetWithUnknownIdentifier(Connection $db, Url $endpoint): voi
$this->assertJsonStringEqualsJsonString($this->jsonEncodeError('Contact Group not found'), $content);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testGetWithNonMatchingFilter(Connection $db, Url $endpoint): void
{
$response = $this->sendRequest('GET', $endpoint, 'v1/contact-groups', ['name' => 'not_test']);
@@ -107,9 +97,7 @@ public function testGetWithNonMatchingFilter(Connection $db, Url $endpoint): voi
$this->assertJsonStringEqualsJsonString($this->jsonEncodeResults([]), $content);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testPostToCreateWithInvalidContent(Connection $db, Url $endpoint): void
{
$body = <<sendRequest(
@@ -189,9 +173,7 @@ public function testPostToCreateWithFilter(Connection $db, Url $endpoint): void
);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testPostToReplaceWithUnknownIdentifier(Connection $db, Url $endpoint): void
{
$response = $this->sendRequest(
@@ -210,9 +192,7 @@ public function testPostToReplaceWithUnknownIdentifier(Connection $db, Url $endp
$this->assertJsonStringEqualsJsonString($this->jsonEncodeError('Contact Group not found'), $content);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testPostToReplaceWithIndifferentPayloadId(
Connection $db,
Url $endpoint
@@ -236,9 +216,7 @@ public function testPostToReplaceWithIndifferentPayloadId(
);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testPostToReplaceWithExistingPayloadId(
Connection $db,
Url $endpoint
@@ -259,9 +237,7 @@ public function testPostToReplaceWithExistingPayloadId(
$this->assertJsonStringEqualsJsonString($this->jsonEncodeError('Contact Group already exists'), $content);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testPostToReplaceWithValidData(Connection $db, Url $endpoint): void
{
$response = $this->sendRequest(
@@ -302,9 +278,7 @@ public function testPostToReplaceWithValidData(Connection $db, Url $endpoint): v
]), $content);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testPostToCreateWithAlreadyExistingPayloadId(Connection $db, Url $endpoint): void
{
$response = $this->sendRequest(
@@ -323,9 +297,7 @@ public function testPostToCreateWithAlreadyExistingPayloadId(Connection $db, Url
$this->assertJsonStringEqualsJsonString($this->jsonEncodeError('Contact Group already exists'), $content);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testPostToCreateWithValidData(Connection $db, Url $endpoint): void
{
$response = $this->sendRequest(
@@ -365,9 +337,7 @@ public function testPostToCreateWithValidData(Connection $db, Url $endpoint): vo
]), $content);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testPostToReplaceWithMissingRequiredFields(
Connection $db,
Url $endpoint
@@ -395,7 +365,7 @@ public function testPostToReplaceWithMissingRequiredFields(
'POST',
$endpoint,
'v1/contact-groups/' . BaseApiV1TestCase::GROUP_UUID,
- json: [
+ json: [
'id' => BaseApiV1TestCase::GROUP_UUID_3,
'users' => []
]
@@ -409,9 +379,7 @@ public function testPostToReplaceWithMissingRequiredFields(
);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testPostToReplaceWithInvalidFieldsFormat(
Connection $db,
Url $endpoint
@@ -440,7 +408,7 @@ public function testPostToReplaceWithInvalidFieldsFormat(
'POST',
$endpoint,
'v1/contact-groups/' . BaseApiV1TestCase::GROUP_UUID,
- json: [
+ json: [
'id' => BaseApiV1TestCase::GROUP_UUID_3,
'name' => ['Test'],
'users' => []
@@ -474,9 +442,7 @@ public function testPostToReplaceWithInvalidFieldsFormat(
);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testPostToCreateWithValidOptionalData(Connection $db, Url $endpoint): void
{
$response = $this->sendRequest(
@@ -517,9 +483,7 @@ public function testPostToCreateWithValidOptionalData(Connection $db, Url $endpo
]), $content);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testPostToCreateWithMissingRequiredFields(Connection $db, Url $endpoint): void
{
// missing name
@@ -527,7 +491,7 @@ public function testPostToCreateWithMissingRequiredFields(Connection $db, Url $e
'POST',
$endpoint,
'v1/contact-groups',
- json:[
+ json: [
'id' => BaseApiV1TestCase::GROUP_UUID_3,
'users' => []
]
@@ -559,9 +523,7 @@ public function testPostToCreateWithMissingRequiredFields(Connection $db, Url $e
);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testPostToCreateWithInvalidFieldsFormat(
Connection $db,
Url $endpoint
@@ -590,7 +552,7 @@ public function testPostToCreateWithInvalidFieldsFormat(
'POST',
$endpoint,
'v1/contact-groups/',
- json: [
+ json: [
'id' => BaseApiV1TestCase::GROUP_UUID_3,
'name' => ['Test'],
'users' => []
@@ -624,9 +586,7 @@ public function testPostToCreateWithInvalidFieldsFormat(
);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testPostToCreateWithInvalidOptionalData(Connection $db, Url $endpoint): void
{
// invalid users
@@ -668,9 +628,7 @@ public function testPostToCreateWithInvalidOptionalData(Connection $db, Url $end
);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testPutToUpdateWithInvalidContent(Connection $db, Url $endpoint): void
{
$body = <<sendRequest(
'PUT',
$endpoint,
'v1/contact-groups?id=' . BaseApiV1TestCase::GROUP_UUID,
- json: [
+ json: [
'id' => BaseApiV1TestCase::GROUP_UUID,
'name' => 'Test',
'users' => []
@@ -750,9 +704,7 @@ public function testPutToUpdateWithFilter(Connection $db, Url $endpoint): void
);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testPutToUpdateWithoutIdentifier(Connection $db, Url $endpoint): void
{
$response = $this->sendRequest(
@@ -774,9 +726,7 @@ public function testPutToUpdateWithoutIdentifier(Connection $db, Url $endpoint):
);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testPutToUpdateWithMissingRequiredFields(
Connection $db,
Url $endpoint
@@ -804,7 +754,7 @@ public function testPutToUpdateWithMissingRequiredFields(
'PUT',
$endpoint,
'v1/contact-groups/' . BaseApiV1TestCase::GROUP_UUID,
- json: [
+ json: [
'id' => BaseApiV1TestCase::GROUP_UUID,
'users' => []
]
@@ -818,9 +768,7 @@ public function testPutToUpdateWithMissingRequiredFields(
);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testPutToUpdateWithInvalidFieldsFormat(
Connection $db,
Url $endpoint
@@ -849,7 +797,7 @@ public function testPutToUpdateWithInvalidFieldsFormat(
'PUT',
$endpoint,
'v1/contact-groups/' . BaseApiV1TestCase::GROUP_UUID,
- json: [
+ json: [
'id' => BaseApiV1TestCase::GROUP_UUID,
'name' => ['Test'],
'users' => []
@@ -883,9 +831,7 @@ public function testPutToUpdateWithInvalidFieldsFormat(
);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testPutToUpdateWithDifferentPayloadId(
Connection $db,
Url $endpoint
@@ -895,7 +841,7 @@ public function testPutToUpdateWithDifferentPayloadId(
'PUT',
$endpoint,
'v1/contact-groups/' . BaseApiV1TestCase::GROUP_UUID,
- json: [
+ json: [
'id' => BaseApiV1TestCase::GROUP_UUID_2,
'name' => 'Test',
'users' => []
@@ -907,16 +853,14 @@ public function testPutToUpdateWithDifferentPayloadId(
$this->assertJsonStringEqualsJsonString($this->jsonEncodeError('Identifier mismatch'), $content);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testPutToCreateWithValidData(Connection $db, Url $endpoint): void
{
$response = $this->sendRequest(
'PUT',
$endpoint,
'v1/contact-groups/' . BaseApiV1TestCase::GROUP_UUID_3,
- json: [
+ json: [
'id' => BaseApiV1TestCase::GROUP_UUID_3,
'name' => 'Test'
]
@@ -949,16 +893,14 @@ public function testPutToCreateWithValidData(Connection $db, Url $endpoint): voi
]), $content);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testPutToUpdateWithValidData(Connection $db, Url $endpoint): void
{
$response = $this->sendRequest(
'PUT',
$endpoint,
'v1/contact-groups/' . BaseApiV1TestCase::GROUP_UUID,
- json: [
+ json: [
'id' => BaseApiV1TestCase::GROUP_UUID,
'name' => 'Test (replaced)',
'users' => []
@@ -985,9 +927,7 @@ public function testPutToUpdateWithValidData(Connection $db, Url $endpoint): voi
]), $content);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testPutToUpdateWithInvalidData(Connection $db, Url $endpoint): void
{
// invalid users
@@ -995,7 +935,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]
@@ -1010,16 +950,14 @@ public function testPutToUpdateWithInvalidData(Connection $db, Url $endpoint): v
);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testPutToCreateWithValidOptionalData(Connection $db, Url $endpoint): void
{
$response = $this->sendRequest(
'PUT',
$endpoint,
'v1/contact-groups/' . BaseApiV1TestCase::GROUP_UUID_3,
- json: [
+ json: [
'id' => BaseApiV1TestCase::GROUP_UUID_3,
'name' => 'Test',
'users' => [BaseApiV1TestCase::CONTACT_UUID]
@@ -1053,9 +991,7 @@ public function testPutToCreateWithValidOptionalData(Connection $db, Url $endpoi
]), $content);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testPutToCreateWithMissingRequiredFields(Connection $db, Url $endpoint): void
{
// missing name
@@ -1063,7 +999,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 +1017,7 @@ public function testPutToCreateWithMissingRequiredFields(Connection $db, Url $en
'PUT',
$endpoint,
'v1/contact-groups/' . BaseApiV1TestCase::GROUP_UUID_3,
- json: [
+ json: [
'name' => 'Test',
'users' => []
]
@@ -1095,9 +1031,7 @@ public function testPutToCreateWithMissingRequiredFields(Connection $db, Url $en
);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testPutToCreateWithInvalidFieldsFormat(
Connection $db,
Url $endpoint
@@ -1126,7 +1060,7 @@ public function testPutToCreateWithInvalidFieldsFormat(
'PUT',
$endpoint,
'v1/contact-groups/' . BaseApiV1TestCase::GROUP_UUID_3,
- json: [
+ json: [
'id' => BaseApiV1TestCase::GROUP_UUID_3,
'name' => ['Test'],
'users' => []
@@ -1160,9 +1094,7 @@ public function testPutToCreateWithInvalidFieldsFormat(
);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testPutToChangeGroupMemberships(Connection $db, Url $endpoint): void
{
// First add a user to the group
@@ -1241,9 +1173,7 @@ public function testPutToChangeGroupMemberships(Connection $db, Url $endpoint):
]), $content);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testDeleteWithoutIdentifier(Connection $db, Url $endpoint): void
{
$response = $this->sendRequest('DELETE', $endpoint, 'v1/contact-groups');
@@ -1256,9 +1186,7 @@ public function testDeleteWithoutIdentifier(Connection $db, Url $endpoint): void
);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testDeleteWithUnknownIdentifier(Connection $db, Url $endpoint): void
{
$response = $this->sendRequest('DELETE', $endpoint, 'v1/contact-groups/' . BaseApiV1TestCase::GROUP_UUID_3);
@@ -1268,9 +1196,7 @@ public function testDeleteWithUnknownIdentifier(Connection $db, Url $endpoint):
$this->assertJsonStringEqualsJsonString($this->jsonEncodeError('Contact Group not found'), $content);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testDeleteWithKnownIdentifier(Connection $db, Url $endpoint): void
{
$response = $this->sendRequest('DELETE', $endpoint, 'v1/contact-groups/' . BaseApiV1TestCase::GROUP_UUID);
@@ -1280,9 +1206,7 @@ public function testDeleteWithKnownIdentifier(Connection $db, Url $endpoint): vo
$this->assertEmpty($content);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testDeleteWithFilter(Connection $db, Url $endpoint): void
{
$response = $this->sendRequest('DELETE', $endpoint, 'v1/contact-groups', ['name~*']);
@@ -1295,9 +1219,7 @@ public function testDeleteWithFilter(Connection $db, Url $endpoint): void
);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testRequestWithNonSupportedMethod(Connection $db, Url $endpoint): void
{
$response = $this->sendRequest('PATCH', $endpoint, 'v1/contact-groups');
diff --git a/test/php/application/controllers/ApiV1ContactsTest.php b/test/php/application/controllers/ApiV1ContactsTest.php
index c92755fb6..4c722a27e 100644
--- a/test/php/application/controllers/ApiV1ContactsTest.php
+++ b/test/php/application/controllers/ApiV1ContactsTest.php
@@ -4,19 +4,15 @@
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;
+use PHPUnit\Framework\Attributes\DataProvider;
class ApiV1ContactsTest extends BaseApiV1TestCase
{
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testGetWithMatchingFilter(Connection $db, Url $endpoint): void
{
$response = $this->sendRequest('GET', $endpoint, 'v1/contacts', ['full_name' => 'Test']);
@@ -34,9 +30,7 @@ public function testGetWithMatchingFilter(Connection $db, Url $endpoint): void
$this->assertJsonStringEqualsJsonString($expected, $content);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testGetEverything(Connection $db, Url $endpoint): void
{
// At first, there are none
@@ -77,9 +71,7 @@ public function testGetEverything(Connection $db, Url $endpoint): void
$this->assertJsonStringEqualsJsonString($expected, $content);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testGetWithAlreadyExistingIdentifier(Connection $db, Url $endpoint): void
{
$response = $this->sendRequest('GET', $endpoint, 'v1/contacts/' . BaseApiV1TestCase::CONTACT_UUID);
@@ -97,9 +89,7 @@ public function testGetWithAlreadyExistingIdentifier(Connection $db, Url $endpoi
$this->assertJsonStringEqualsJsonString($expected, $content);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testGetWithUnknownIdentifier(Connection $db, Url $endpoint): void
{
$response = $this->sendRequest('GET', $endpoint, 'v1/contacts/' . BaseApiV1TestCase::CONTACT_UUID_3);
@@ -109,9 +99,7 @@ public function testGetWithUnknownIdentifier(Connection $db, Url $endpoint): voi
$this->assertJsonStringEqualsJsonString($this->jsonEncodeError('Contact not found'), $content);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testGetWithNonMatchingFilter(Connection $db, Url $endpoint): void
{
$response = $this->sendRequest('GET', $endpoint, 'v1/contacts', ['full_name' => 'not_test']);
@@ -121,9 +109,7 @@ public function testGetWithNonMatchingFilter(Connection $db, Url $endpoint): voi
$this->assertJsonStringEqualsJsonString($this->jsonEncodeResults([]), $content);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testGetWithNonExistingFilter(Connection $db, Url $endpoint): void
{
$response = $this->sendRequest('GET', $endpoint, 'v1/contacts', ['unknown' => 'filter']);
@@ -136,9 +122,7 @@ public function testGetWithNonExistingFilter(Connection $db, Url $endpoint): voi
$this->assertJsonStringEqualsJsonString($expected, $content);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testGetWithIdentifierAndFilter(Connection $db, Url $endpoint): void
{
$expected = $this->jsonEncodeError(
@@ -170,9 +154,7 @@ public function testGetWithIdentifierAndFilter(Connection $db, Url $endpoint): v
$this->assertJsonStringEqualsJsonString($expected, $content);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testPostToCreateWithInvalidContent(Connection $db, Url $endpoint): void
{
$body = <<sendRequest(
@@ -254,16 +232,14 @@ public function testPostToCreateWithFilter(Connection $db, Url $endpoint): void
);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testPostToReplaceWithUnknownIdentifier(Connection $db, Url $endpoint): void
{
$response = $this->sendRequest(
'POST',
$endpoint,
'v1/contacts/' . BaseApiV1TestCase::CONTACT_UUID_3,
- json: [
+ json: [
'id' => BaseApiV1TestCase::CONTACT_UUID_4,
'full_name' => 'Test',
'default_channel' => BaseApiV1TestCase::CHANNEL_UUID,
@@ -276,9 +252,7 @@ public function testPostToReplaceWithUnknownIdentifier(Connection $db, Url $endp
$this->assertJsonStringEqualsJsonString($this->jsonEncodeError('Contact not found'), $content);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testPostToReplaceWithIndifferentPayloadId(
Connection $db,
Url $endpoint
@@ -287,7 +261,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,
@@ -303,9 +277,7 @@ public function testPostToReplaceWithIndifferentPayloadId(
);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testPostToReplaceWithAlreadyExistingPayloadId(
Connection $db,
Url $endpoint
@@ -314,7 +286,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,
@@ -327,16 +299,14 @@ public function testPostToReplaceWithAlreadyExistingPayloadId(
$this->assertJsonStringEqualsJsonString($this->jsonEncodeError('Contact already exists'), $content);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testPostToReplaceWithValidData(Connection $db, Url $endpoint): void
{
$response = $this->sendRequest(
'POST',
$endpoint,
'v1/contacts/' . BaseApiV1TestCase::CONTACT_UUID,
- json: [
+ json: [
'id' => BaseApiV1TestCase::CONTACT_UUID_3,
'full_name' => 'Test (replaced)',
'default_channel' => BaseApiV1TestCase::CHANNEL_UUID,
@@ -374,16 +344,14 @@ public function testPostToReplaceWithValidData(Connection $db, Url $endpoint): v
]), $content);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testPostToCreateWithExistingPayloadId(Connection $db, Url $endpoint): void
{
$response = $this->sendRequest(
'POST',
$endpoint,
'v1/contacts',
- json: [
+ json: [
'id' => BaseApiV1TestCase::CONTACT_UUID,
'full_name' => 'Test',
'default_channel' => BaseApiV1TestCase::CHANNEL_UUID,
@@ -396,16 +364,14 @@ public function testPostToCreateWithExistingPayloadId(Connection $db, Url $endpo
$this->assertJsonStringEqualsJsonString($this->jsonEncodeError('Contact already exists'), $content);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testPostToCreateWithValidData(Connection $db, Url $endpoint): void
{
$response = $this->sendRequest(
'POST',
$endpoint,
'v1/contacts',
- json: [
+ json: [
'id' => BaseApiV1TestCase::CONTACT_UUID_3,
'full_name' => 'Test',
'default_channel' => BaseApiV1TestCase::CHANNEL_UUID,
@@ -443,9 +409,7 @@ public function testPostToCreateWithValidData(Connection $db, Url $endpoint): vo
]), $content);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testPostToReplaceWithMissingRequiredFields(
Connection $db,
Url $endpoint
@@ -455,7 +419,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 +438,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 +457,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 +476,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,
@@ -529,9 +493,7 @@ public function testPostToReplaceWithMissingRequiredFields(
);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testPostToReplaceWithInvalidFieldFormat(
Connection $db,
Url $endpoint
@@ -541,7 +503,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 +523,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 +543,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 +563,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 +585,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 +606,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,
@@ -661,16 +623,14 @@ public function testPostToReplaceWithInvalidFieldFormat(
);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testPostToCreateWithValidOptionalData(Connection $db, Url $endpoint): void
{
$response = $this->sendRequest(
'POST',
$endpoint,
'v1/contacts',
- json: [
+ json: [
'id' => BaseApiV1TestCase::CONTACT_UUID_3,
'full_name' => 'Test3',
'username' => 'test3',
@@ -718,16 +678,14 @@ public function testPostToCreateWithValidOptionalData(Connection $db, Url $endpo
]), $content);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testPostToCreateWithWebhookAsDefaultChannel(Connection $db, Url $endpoint): void
{
$response = $this->sendRequest(
'POST',
$endpoint,
'v1/contacts',
- json: [
+ json: [
'id' => BaseApiV1TestCase::CONTACT_UUID_3,
'full_name' => 'Test3',
'default_channel' => BaseApiV1TestCase::CHANNEL_UUID_2
@@ -746,9 +704,7 @@ public function testPostToCreateWithWebhookAsDefaultChannel(Connection $db, Url
);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testPostToCreateWithInvalidDefaultChannel(Connection $db, Url $endpoint): void
{
// invalid default_channel uuid
@@ -756,7 +712,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',
@@ -772,9 +728,7 @@ public function testPostToCreateWithInvalidDefaultChannel(Connection $db, Url $e
);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testPostToCreateWithMissingRequiredFields(Connection $db, Url $endpoint): void
{
// missing id
@@ -782,7 +736,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 +755,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 +774,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 +793,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,
@@ -855,9 +809,7 @@ public function testPostToCreateWithMissingRequiredFields(Connection $db, Url $e
);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testPostToCreateWithInvalidFieldFormat(
Connection $db,
Url $endpoint
@@ -867,7 +819,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 +839,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 +859,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 +879,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 +901,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 +922,7 @@ public function testPostToCreateWithInvalidFieldFormat(
'POST',
$endpoint,
'v1/contacts/',
- json: [
+ json: [
'id' => BaseApiV1TestCase::CONTACT_UUID_3,
'full_name' => 'Test',
'default_channel' => BaseApiV1TestCase::CHANNEL_UUID,
@@ -987,9 +939,7 @@ public function testPostToCreateWithInvalidFieldFormat(
);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testPostToCreateWithInvalidAddresses(Connection $db, Url $endpoint): void
{
// with invalid address type
@@ -997,7 +947,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 +970,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 +992,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,
@@ -1061,9 +1011,7 @@ public function testPostToCreateWithInvalidAddresses(Connection $db, Url $endpoi
);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testPostToCreateWithInvalidOptionalData(Connection $db, Url $endpoint): void
{
// already existing username
@@ -1071,7 +1019,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 +1037,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 +1060,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,
@@ -1129,9 +1077,7 @@ public function testPostToCreateWithInvalidOptionalData(Connection $db, Url $end
);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testPutToUpdateWithInvalidContent(Connection $db, Url $endpoint): void
{
$body = <<sendRequest(
@@ -1211,16 +1153,14 @@ public function testPutToUpdateWithFilter(Connection $db, Url $endpoint): void
);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testPutToUpdateWithoutIdentifier(Connection $db, Url $endpoint): void
{
$response = $this->sendRequest(
'PUT',
$endpoint,
'v1/contacts',
- json: [
+ json: [
'id' => BaseApiV1TestCase::CONTACT_UUID_3,
'full_name' => 'Test',
'default_channel' => BaseApiV1TestCase::CHANNEL_UUID,
@@ -1235,9 +1175,7 @@ public function testPutToUpdateWithoutIdentifier(Connection $db, Url $endpoint):
);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testPutToUpdateWithMissingRequiredFields(
Connection $db,
Url $endpoint
@@ -1248,7 +1186,7 @@ public function testPutToUpdateWithMissingRequiredFields(
'PUT',
$endpoint,
'v1/contacts/' . BaseApiV1TestCase::CONTACT_UUID,
- json: [
+ json: [
'full_name' => 'Test',
'default_channel' => BaseApiV1TestCase::CHANNEL_UUID,
]
@@ -1266,7 +1204,7 @@ public function testPutToUpdateWithMissingRequiredFields(
'PUT',
$endpoint,
'v1/contacts/' . BaseApiV1TestCase::CONTACT_UUID,
- json: [
+ json: [
'id' => BaseApiV1TestCase::CONTACT_UUID,
'default_channel' => BaseApiV1TestCase::CHANNEL_UUID,
]
@@ -1284,7 +1222,7 @@ public function testPutToUpdateWithMissingRequiredFields(
'PUT',
$endpoint,
'v1/contacts/' . BaseApiV1TestCase::CONTACT_UUID,
- json: [
+ json: [
'id' => BaseApiV1TestCase::CONTACT_UUID,
'full_name' => 'Test',
]
@@ -1302,7 +1240,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,
@@ -1319,9 +1257,7 @@ public function testPutToUpdateWithMissingRequiredFields(
);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testPutToUpdateWithInvalidFieldFormat(
Connection $db,
Url $endpoint
@@ -1331,7 +1267,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 +1287,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 +1307,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 +1327,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 +1349,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 +1370,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,
@@ -1451,9 +1387,7 @@ public function testPutToUpdateWithInvalidFieldFormat(
);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testPutToUpdateWithDifferentPayloadId(
Connection $db,
Url $endpoint
@@ -1462,7 +1396,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,
@@ -1475,16 +1409,14 @@ public function testPutToUpdateWithDifferentPayloadId(
$this->assertJsonStringEqualsJsonString($this->jsonEncodeError('Identifier mismatch'), $content);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testPutToCreateWithValidData(Connection $db, Url $endpoint): void
{
$response = $this->sendRequest(
'PUT',
$endpoint,
'v1/contacts/' . BaseApiV1TestCase::CONTACT_UUID_3,
- json: [
+ json: [
'id' => BaseApiV1TestCase::CONTACT_UUID_3,
'full_name' => 'Test',
'default_channel' => BaseApiV1TestCase::CHANNEL_UUID,
@@ -1529,16 +1461,14 @@ public function testPutToCreateWithValidData(Connection $db, Url $endpoint): voi
]), $content);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testPutToUpdateWithValidData(Connection $db, Url $endpoint): void
{
$response = $this->sendRequest(
'PUT',
$endpoint,
'v1/contacts/' . BaseApiV1TestCase::CONTACT_UUID,
- json: [
+ json: [
'id' => BaseApiV1TestCase::CONTACT_UUID,
'full_name' => 'Test',
'default_channel' => BaseApiV1TestCase::CHANNEL_UUID,
@@ -1568,9 +1498,7 @@ public function testPutToUpdateWithValidData(Connection $db, Url $endpoint): voi
]), $content);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testPutToUpdateWithInvalidData(Connection $db, Url $endpoint): void
{
// invalid default_channel uuid
@@ -1578,7 +1506,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 +1528,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 +1551,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,
@@ -1642,9 +1570,7 @@ public function testPutToUpdateWithInvalidData(Connection $db, Url $endpoint): v
);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testPutToCreateWithMissingRequiredFields(Connection $db, Url $endpoint): void
{
// missing full_name
@@ -1652,7 +1578,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 +1596,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 +1614,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 +1631,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,
@@ -1721,9 +1647,7 @@ public function testPutToCreateWithMissingRequiredFields(Connection $db, Url $en
);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testPutToCreateWithInvalidFieldFormat(
Connection $db,
Url $endpoint
@@ -1733,7 +1657,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 +1677,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 +1697,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 +1717,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 +1739,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 +1760,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,
@@ -1853,9 +1777,7 @@ public function testPutToCreateWithInvalidFieldFormat(
);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testPutToChangeGroupMemberships(Connection $db, Url $endpoint): void
{
// First add a group to the user
@@ -1863,7 +1785,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 +1819,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 +1853,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,
@@ -1961,9 +1883,7 @@ public function testPutToChangeGroupMemberships(Connection $db, Url $endpoint):
]), $content);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testPutToChangeAddresses(Connection $db, Url $endpoint): void
{
// First add addresses to the user
@@ -1971,7 +1891,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 +1932,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 +1971,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,
@@ -2088,9 +2008,7 @@ public function testPutToChangeAddresses(Connection $db, Url $endpoint): void
]), $content);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testDeleteWithoutIdentifier(Connection $db, Url $endpoint): void
{
$response = $this->sendRequest('DELETE', $endpoint, 'v1/contacts');
@@ -2103,9 +2021,7 @@ public function testDeleteWithoutIdentifier(Connection $db, Url $endpoint): void
);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testDeleteWithUnknownIdentifier(Connection $db, Url $endpoint): void
{
$response = $this->sendRequest('DELETE', $endpoint, 'v1/contacts/' . BaseApiV1TestCase::CONTACT_UUID_3);
@@ -2115,9 +2031,7 @@ public function testDeleteWithUnknownIdentifier(Connection $db, Url $endpoint):
$this->assertJsonStringEqualsJsonString($this->jsonEncodeError('Contact not found'), $content);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testDeleteWithKnownIdentifier(Connection $db, Url $endpoint): void
{
$response = $this->sendRequest('DELETE', $endpoint, 'v1/contacts/' . BaseApiV1TestCase::CONTACT_UUID);
@@ -2127,9 +2041,7 @@ public function testDeleteWithKnownIdentifier(Connection $db, Url $endpoint): vo
$this->assertEmpty($content);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testDeleteWithFilter(Connection $db, Url $endpoint): void
{
$response = $this->sendRequest('DELETE', $endpoint, 'v1/contacts', ['name~*']);
@@ -2142,9 +2054,7 @@ public function testDeleteWithFilter(Connection $db, Url $endpoint): void
);
}
- /**
- * @dataProvider apiTestBackends
- */
+ #[DataProvider('apiTestBackends')]
public function testRequestWithNonSupportedMethod(Connection $db, Url $endpoint): void
{
// General invalid method
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 {