From 0b81efde8858687390fced4d4f42e338fc75e0e0 Mon Sep 17 00:00:00 2001
From: Niklan
Date: Tue, 11 Feb 2025 20:25:48 +0500
Subject: [PATCH] =?UTF-8?q?Increase=20PHPStan=20level=208=20=E2=86=92=209?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../Utils/SearchApiResultItemsHelper.php | 2 +
.../About/Repository/AboutSettings.php | 25 +++++--
.../Contact/Form/ContactSettingsForm.php | 14 ++--
.../Contact/Repository/ContactSettings.php | 18 +++--
.../StaticPage/Home/Form/HomeSettingsForm.php | 42 +++++------
.../Home/Repository/HomeSettings.php | 20 ++++-
.../SearchApiResultItemsHelperTest.php | 75 +++++++++++++++++++
7 files changed, 154 insertions(+), 42 deletions(-)
diff --git a/app/Drupal/niklan/src/Search/Utils/SearchApiResultItemsHelper.php b/app/Drupal/niklan/src/Search/Utils/SearchApiResultItemsHelper.php
index 41a5bc19..44591834 100644
--- a/app/Drupal/niklan/src/Search/Utils/SearchApiResultItemsHelper.php
+++ b/app/Drupal/niklan/src/Search/Utils/SearchApiResultItemsHelper.php
@@ -11,6 +11,8 @@
final class SearchApiResultItemsHelper {
public static function extractEntityIds(ResultSetInterface $result_set): array {
+ // @todo Validate IDs against pattern:
+ // "entity:[entity_type_id]/[entity_id]:[language]".
return \array_map(static function (ItemInterface $result_item) {
[$entity_info, $source_info] = \explode('/', $result_item->getId());
[, $entity_type_id] = \explode(':', $entity_info);
diff --git a/app/Drupal/niklan/src/StaticPage/About/Repository/AboutSettings.php b/app/Drupal/niklan/src/StaticPage/About/Repository/AboutSettings.php
index 628a0fe4..ba82484a 100644
--- a/app/Drupal/niklan/src/StaticPage/About/Repository/AboutSettings.php
+++ b/app/Drupal/niklan/src/StaticPage/About/Repository/AboutSettings.php
@@ -11,7 +11,10 @@ final class AboutSettings extends LanguageAwareSettingsStore {
public const string TEXT_FORMAT = 'text';
public function getPhotoMediaId(): ?string {
- return $this->getStore()->get('photo_media_id');
+ $photo_media_id = $this->getStore()->get('photo_media_id');
+ \assert(\is_string($photo_media_id) || \is_null($photo_media_id), 'Photo media ID must be a string or null.');
+
+ return $photo_media_id;
}
public function setPhotoMediaId(?string $id): self {
@@ -29,7 +32,10 @@ public function setTitle(string $title): self {
}
public function getTitle(): string {
- return $this->getStore()->get('title', "I'm an alien 👽");
+ $title = $this->getStore()->get('title', "I'm an alien 👽");
+ \assert(\is_string($title), 'Title must be a string.');
+
+ return $title;
}
public function setSubtitle(string $subtitle): self {
@@ -40,7 +46,10 @@ public function setSubtitle(string $subtitle): self {
public function getSubtitle(): string {
/* cSpell:ignore traveller */
- return $this->getStore()->get('subtitle', 'Greetings traveller!');
+ $subtitle = $this->getStore()->get('subtitle', 'Greetings traveller!');
+ \assert(\is_string($subtitle), 'Subtitle must be a string.');
+
+ return $subtitle;
}
public function setSummary(string $summary): self {
@@ -56,7 +65,10 @@ public function getSummary(): string {
how I see the world around us.
HTML;
- return $this->getStore()->get('summary', $default);
+ $summary = $this->getStore()->get('summary', $default);
+ \assert(\is_string($summary), 'Summary must be a string.');
+
+ return $summary;
}
public function setDescription(string $description): self {
@@ -76,7 +88,10 @@ public function getDescription(): string {
Join me on this exciting journey through the universe and Earth!
HTML;
- return $this->getStore()->get('description', $default);
+ $description = $this->getStore()->get('description', $default);
+ \assert(\is_string($description), 'Description must be a string.');
+
+ return $description;
}
#[\Override]
diff --git a/app/Drupal/niklan/src/StaticPage/Contact/Form/ContactSettingsForm.php b/app/Drupal/niklan/src/StaticPage/Contact/Form/ContactSettingsForm.php
index df41c9c5..44f08785 100644
--- a/app/Drupal/niklan/src/StaticPage/Contact/Form/ContactSettingsForm.php
+++ b/app/Drupal/niklan/src/StaticPage/Contact/Form/ContactSettingsForm.php
@@ -49,16 +49,18 @@ public function buildForm(array $form, FormStateInterface $form_state): array {
#[\Override]
public function submitForm(array &$form, FormStateInterface $form_state): void {
- $this
- ->getSettings()
- ->setEmail($form_state->getValue('email'))
- ->setTelegram($form_state->getValue('telegram'))
- ->setDescription($form_state->getValue(['description', 'value']));
+ $settings = $this->getSettings();
+
+ \assert(\is_string($form_state->getValue('email')));
+ $settings->setEmail($form_state->getValue('email'));
+ \assert(\is_string($form_state->getValue('telegram')));
+ $settings->setTelegram($form_state->getValue('telegram'));
+ \assert(\is_string($form_state->getValue(['description', 'value'])));
+ $settings->setDescription($form_state->getValue(['description', 'value']));
parent::submitForm($form, $form_state);
}
- #[\Override]
protected function getSettings(): ContactSettings {
$settings = $this->getContainer()->get(ContactSettings::class);
\assert($settings instanceof ContactSettings);
diff --git a/app/Drupal/niklan/src/StaticPage/Contact/Repository/ContactSettings.php b/app/Drupal/niklan/src/StaticPage/Contact/Repository/ContactSettings.php
index bf341240..a3c0ab50 100644
--- a/app/Drupal/niklan/src/StaticPage/Contact/Repository/ContactSettings.php
+++ b/app/Drupal/niklan/src/StaticPage/Contact/Repository/ContactSettings.php
@@ -11,7 +11,10 @@ final class ContactSettings extends LanguageAwareSettingsStore {
public const string TEXT_FORMAT = 'text';
public function getEmail(): string {
- return $this->getStore()->get('email', 'example@example.com');
+ $email = $this->getStore()->get('email', 'example@example.com');
+ \assert(\is_string($email), 'Email must be a string.');
+
+ return $email;
}
public function setEmail(string $email): self {
@@ -21,7 +24,10 @@ public function setEmail(string $email): self {
}
public function getTelegram(): string {
- return $this->getStore()->get('telegram', 'https://t.me');
+ $telegram = $this->getStore()->get('telegram', 'https://t.me');
+ \assert(\is_string($telegram), 'Telegram must be a string.');
+
+ return $telegram;
}
public function setTelegram(string $url): self {
@@ -31,10 +37,10 @@ public function setTelegram(string $url): self {
}
public function getDescription(): string {
- return $this->getStore()->get(
- key: 'description',
- default: 'Additional information about how to contact the author.',
- );
+ $description = $this->getStore()->get('description', 'Additional information about how to contact the author.');
+ \assert(\is_string($description), 'Description must be a string.');
+
+ return $description;
}
public function setDescription(string $description): self {
diff --git a/app/Drupal/niklan/src/StaticPage/Home/Form/HomeSettingsForm.php b/app/Drupal/niklan/src/StaticPage/Home/Form/HomeSettingsForm.php
index 05d39ce0..d6b78e2d 100644
--- a/app/Drupal/niklan/src/StaticPage/Home/Form/HomeSettingsForm.php
+++ b/app/Drupal/niklan/src/StaticPage/Home/Form/HomeSettingsForm.php
@@ -55,7 +55,7 @@ public function submitForm(array &$form, FormStateInterface $form_state): void {
$cards = [];
/**
- * @param array{
+ * @var array{
* media_id: string,
* title: string,
* description: string
@@ -68,17 +68,15 @@ public function submitForm(array &$form, FormStateInterface $form_state): void {
'description' => $card_item['description'],
];
}
-
- $heading = $form_state->getValue('heading');
- \assert(is_string($heading));
- $description = $form_state->getValue(['description', 'value']);
- \assert(\is_string($description));
- $this
- ->getSettings()
- ->setHeading($heading)
- ->setDescription($description)
- ->setCards($cards);
-
+
+ $settings = $this->getSettings();
+
+ \assert(\is_string($form_state->getValue('heading')));
+ $settings->setHeading($form_state->getValue('heading'));
+ \assert(\is_string($form_state->getValue(['description', 'value'])));
+ $settings->setDescription($form_state->getValue(['description', 'value']));
+ $settings->setCards($cards);
+
parent::submitForm($form, $form_state);
}
@@ -128,12 +126,12 @@ protected function getSettings(): HomeSettings {
private function buildCards(array &$form, FormStateInterface $form_state): void {
$cards = $this->getSettings()->getCards();
$cards_count = $form_state->get('cards_count');
-
+
if (!isset($cards_count)) {
$cards_count = \count($cards);
$form_state->set('cards_count', $cards_count);
}
-
+
$form['cards'] = [
'#type' => 'details',
'#open' => $form_state->get('keep_cards_open') ?? FALSE,
@@ -142,7 +140,8 @@ private function buildCards(array &$form, FormStateInterface $form_state): void
'#suffix' => '',
];
- $form['cards']['items'] = [
+ /** @var array> $items */
+ $items = [
'#type' => 'table',
// Workaround for an empty string if not set. See #3247373.
'#input' => FALSE,
@@ -161,11 +160,11 @@ private function buildCards(array &$form, FormStateInterface $form_state): void
],
],
];
-
+
for ($i = 0; $i < $cards_count; $i++) {
$card_data = $cards[$i] ?? [];
-
- /**
+
+ /**
* @var array{
* '#attributes': array{'class': array},
* '#weight': int,
@@ -202,10 +201,11 @@ private function buildCards(array &$form, FormStateInterface $form_state): void
'#attributes' => ['class' => ['weight']],
],
];
-
- $form['cards']['items'][$i] = $row;
+
+ $items[$i] = $row;
}
-
+
+ $form['cards']['items'] = $items;
$form['cards']['actions'] = ['#type' => 'actions'];
$form['cards']['actions']['add'] = [
// Workaround for core bug #2897377.
diff --git a/app/Drupal/niklan/src/StaticPage/Home/Repository/HomeSettings.php b/app/Drupal/niklan/src/StaticPage/Home/Repository/HomeSettings.php
index cf83cb0d..18b83879 100644
--- a/app/Drupal/niklan/src/StaticPage/Home/Repository/HomeSettings.php
+++ b/app/Drupal/niklan/src/StaticPage/Home/Repository/HomeSettings.php
@@ -12,34 +12,46 @@ final class HomeSettings extends LanguageAwareSettingsStore {
public function getHeading(): string {
$heading = $this->getStore()->get('heading', 'Web Developer Blog');
- \assert(is_string($heading), 'The heading must be a string.');
+ \assert(\is_string($heading), 'The heading must be a string.');
+
return $heading;
}
public function setHeading(string $heading): self {
$this->getStore()->set('heading', $heading);
+
return $this;
}
public function getDescription(): string {
$description = $this->getStore()->get('description', 'The homepage description.');
- \assert(is_string($description), 'The description must be a string.');
+ \assert(\is_string($description), 'The description must be a string.');
+
return $description;
}
public function setDescription(string $description): self {
$this->getStore()->set('description', $description);
+
return $this;
}
public function setCards(array $cards): self {
$this->getStore()->set('cards', $cards);
+
return $this;
}
+ /**
+ * @return array{}|array */
public function getCards(): array {
$cards = $this->getStore()->get('cards', []);
- \assert(is_array($cards), 'The cards must be an array.');
+ \assert(\is_array($cards), 'The cards must be an array.');
+
return $cards;
}
@@ -48,4 +60,4 @@ protected function getStoreId(): string {
return 'niklan.home_settings';
}
-}
\ No newline at end of file
+}
diff --git a/app/Drupal/niklan/tests/src/Unit/Utility/SearchApiResultItemsHelperTest.php b/app/Drupal/niklan/tests/src/Unit/Utility/SearchApiResultItemsHelperTest.php
index 1619d103..af5219df 100644
--- a/app/Drupal/niklan/tests/src/Unit/Utility/SearchApiResultItemsHelperTest.php
+++ b/app/Drupal/niklan/tests/src/Unit/Utility/SearchApiResultItemsHelperTest.php
@@ -46,4 +46,79 @@ public function testExtractEntityIds(): void {
self::assertEquals($expected_ids, $extracted_ids);
}
+ public function testExtractEntityIdsWithEmptyResultSet(): void {
+ $result_set = $this->prophesize(ResultSetInterface::class);
+ $result_set->getResultItems()->willReturn([]);
+
+ $extracted_ids = SearchApiResultItemsHelper::extractEntityIds($result_set->reveal());
+ self::assertEquals([], $extracted_ids);
+ }
+
+ public function testExtractEntityIdsWithDifferentEntityTypes(): void {
+ $item_ids = [
+ 'entity:node/10:ru',
+ 'entity:user/20:en',
+ 'entity:comment/30:es',
+ ];
+
+ $result_items = [];
+
+ foreach ($item_ids as $item_id) {
+ $result_item = $this->prophesize(ItemInterface::class);
+ $result_item->getId()->willReturn($item_id);
+ $result_items[$item_id] = $result_item->reveal();
+ }
+
+ $result_set = $this->prophesize(ResultSetInterface::class);
+ $result_set->getResultItems()->willReturn($result_items);
+
+ $extracted_ids = SearchApiResultItemsHelper::extractEntityIds($result_set->reveal());
+ $expected_ids = [
+ 'entity:node/10:ru' => new EntitySearchResult('node', '10', 'ru'),
+ 'entity:user/20:en' => new EntitySearchResult('user', '20', 'en'),
+ 'entity:comment/30:es' => new EntitySearchResult('comment', '30', 'es'),
+ ];
+ self::assertEquals($expected_ids, $extracted_ids);
+ }
+
+ public function testExtractEntityIdsWithDifferentLanguages(): void {
+ $item_ids = [
+ 'entity:node/100:de',
+ 'entity:user/200:fr',
+ 'entity:comment/300:ja',
+ ];
+
+ $result_items = [];
+
+ foreach ($item_ids as $item_id) {
+ $result_item = $this->prophesize(ItemInterface::class);
+ $result_item->getId()->willReturn($item_id);
+ $result_items[$item_id] = $result_item->reveal();
+ }
+
+ $result_set = $this->prophesize(ResultSetInterface::class);
+ $result_set->getResultItems()->willReturn($result_items);
+
+ $extracted_ids = SearchApiResultItemsHelper::extractEntityIds($result_set->reveal());
+ $expected_ids = [
+ 'entity:node/100:de' => new EntitySearchResult('node', '100', 'de'),
+ 'entity:user/200:fr' => new EntitySearchResult('user', '200', 'fr'),
+ 'entity:comment/300:ja' => new EntitySearchResult('comment', '300', 'ja'),
+ ];
+ self::assertEquals($expected_ids, $extracted_ids);
+ }
+
+ public function testExtractEntityIdsWithInvalidFormat(): void {
+ $item_id = 'invalid_format';
+
+ $result_item = $this->prophesize(ItemInterface::class);
+ $result_item->getId()->willReturn($item_id);
+
+ $result_set = $this->prophesize(ResultSetInterface::class);
+ $result_set->getResultItems()->willReturn([$item_id => $result_item->reveal()]);
+
+ $extracted_ids = SearchApiResultItemsHelper::extractEntityIds($result_set->reveal());
+ self::assertEquals([], $extracted_ids);
+ }
+
}