Skip to content

Commit f2b2094

Browse files
committed
fix: improve type checks and phpstan annotations
1 parent c1d8a82 commit f2b2094

16 files changed

Lines changed: 89 additions & 59 deletions

src/Block/Inspector.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,8 @@ public function getJsUrl(): string
8989
*/
9090
public function getTheme(): string
9191
{
92-
return (string) $this->scopeConfig->getValue('mageforge/inspector/theme') ?: 'dark';
92+
$value = $this->scopeConfig->getValue('mageforge/inspector/theme');
93+
return is_string($value) && $value !== '' ? $value : 'dark';
9394
}
9495

9596
/**

src/Console/Command/AbstractCommand.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ protected function handleInvalidThemeWithSuggestions(
183183
return null;
184184
}
185185

186-
return $selection;
186+
return is_string($selection) ? $selection : null;
187187
} catch (\Exception $e) {
188188
$this->resetPromptEnvironment();
189189
$this->io->error('Selection failed: ' . $e->getMessage());

src/Console/Command/Dev/InspectorCommand.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,8 @@ protected function configure(): void
8282
*/
8383
protected function executeCommand(InputInterface $input, OutputInterface $output): int
8484
{
85-
$action = strtolower((string) $input->getArgument(self::ARGUMENT_ACTION));
85+
$arg = $input->getArgument(self::ARGUMENT_ACTION);
86+
$action = strtolower(is_string($arg) ? $arg : '');
8687

8788
// Validate action
8889
if (!in_array($action, ['enable', 'disable', 'status'], true)) {

src/Console/Command/Hyva/CompatibilityCheckCommand.php

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ private function runInteractiveMode(InputInterface $input, OutputInterface $outp
146146
// Detailed view confirmation
147147
$detailedPrompt = new ConfirmPrompt(label: 'Show detailed file-level issues?', default: false);
148148

149-
$detailed = $detailedPrompt->prompt();
149+
$detailed = (bool) $detailedPrompt->prompt();
150150

151151
// Map selected options to flags
152152
$showAll = $displayMode === self::DISPLAY_MODE_SHOW_ALL;
@@ -193,10 +193,10 @@ private function runInteractiveMode(InputInterface $input, OutputInterface $outp
193193
*/
194194
private function runDirectMode(InputInterface $input, OutputInterface $output): int
195195
{
196-
$showAll = $input->getOption(self::OPTION_SHOW_ALL);
197-
$thirdPartyOnly = $input->getOption(self::OPTION_THIRD_PARTY_ONLY);
198-
$includeVendor = $input->getOption(self::OPTION_INCLUDE_VENDOR);
199-
$detailed = $input->getOption(self::OPTION_DETAILED);
196+
$showAll = (bool) $input->getOption(self::OPTION_SHOW_ALL);
197+
$thirdPartyOnly = (bool) $input->getOption(self::OPTION_THIRD_PARTY_ONLY);
198+
$includeVendor = (bool) $input->getOption(self::OPTION_INCLUDE_VENDOR);
199+
$detailed = (bool) $input->getOption(self::OPTION_DETAILED);
200200

201201
$this->io->title('Hyvä Theme Compatibility Check');
202202

@@ -271,7 +271,7 @@ private function runScan(
271271
* Display compatibility check results
272272
*
273273
* @param array $results
274-
* @phpstan-param array<string, mixed> $results
274+
* @phpstan-param array{modules: array<string, array{compatible: bool, hasWarnings: bool, scanResult: array{files: array<string, array<int, array{description: string, severity: string, line: int, pattern: string}>>, totalIssues: int, criticalIssues: int}, moduleInfo: array{name: string, version: string, isHyvaAware: bool}}>, hasIncompatibilities: bool} $results
275275
* @param bool $showAll
276276
*/
277277
private function displayResults(array $results, bool $showAll): void
@@ -292,7 +292,7 @@ private function displayResults(array $results, bool $showAll): void
292292
* Display detailed file-level issues
293293
*
294294
* @param array $results
295-
* @phpstan-param array<string, mixed> $results
295+
* @phpstan-param array{modules: array<string, array{compatible: bool, hasWarnings: bool, scanResult: array{files: array<string, array<int, array{description: string, severity: string, line: int, pattern: string}>>, totalIssues: int, criticalIssues: int}, moduleInfo: array{name: string, version: string, isHyvaAware: bool}}>, hasIncompatibilities: bool} $results
296296
*/
297297
private function displayDetailedIssues(array $results): void
298298
{
@@ -333,7 +333,7 @@ private function displayDetailedIssues(array $results): void
333333
* Display summary statistics
334334
*
335335
* @param array $results
336-
* @phpstan-param array<string, mixed> $results
336+
* @phpstan-param array{summary: array{total: int, compatible: int, incompatible: int, hyvaAware: int, criticalIssues: int, warningIssues: int}} $results
337337
*/
338338
private function displaySummary(array $results): void
339339
{

src/Console/Command/System/CheckCommand.php

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -162,8 +162,9 @@ private function getLatestLtsNodeVersion(): string
162162
return 'Unknown';
163163
}
164164

165+
/** @var array<int, array<string, mixed>> $nodes */
165166
foreach ($nodes as $node) {
166-
if (isset($node['lts']) && $node['lts'] !== false) {
167+
if (isset($node['lts']) && $node['lts'] !== false && isset($node['version']) && is_string($node['version'])) {
167168
return trim($node['version'], 'v');
168169
}
169170
}
@@ -407,12 +408,15 @@ private function getSearchEngineFromMagentoConfig(): ?string
407408
private function checkSearchEngineViaDeploymentConfig($objectManager): ?string
408409
{
409410
try {
411+
/** @var \Magento\Framework\App\DeploymentConfig $deploymentConfig */
410412
$deploymentConfig = $objectManager->get(\Magento\Framework\App\DeploymentConfig::class);
411413
$engineConfig = $deploymentConfig->get('system/search/engine');
412414

413-
if (!empty($engineConfig)) {
414-
$host = $deploymentConfig->get('system/search/engine_host') ?: 'localhost';
415-
$port = $deploymentConfig->get('system/search/engine_port') ?: '9200';
415+
if (!empty($engineConfig) && is_string($engineConfig)) {
416+
$hostRaw = $deploymentConfig->get('system/search/engine_host');
417+
$portRaw = $deploymentConfig->get('system/search/engine_port');
418+
$host = is_string($hostRaw) ? $hostRaw : 'localhost';
419+
$port = is_string($portRaw) ? $portRaw : '9200';
416420

417421
$url = "http://{$host}:{$port}";
418422
if ($this->testElasticsearchConnection($url)) {
@@ -439,12 +443,11 @@ private function checkSearchEngineViaDeploymentConfig($objectManager): ?string
439443
private function checkSearchEngineViaEngineResolver($objectManager): ?string
440444
{
441445
try {
446+
/** @var \Magento\Framework\Search\EngineResolverInterface $engineResolver */
442447
$engineResolver = $objectManager->get(\Magento\Framework\Search\EngineResolverInterface::class);
443-
if ($engineResolver) {
444-
$currentEngine = $engineResolver->getCurrentSearchEngine();
445-
if (!empty($currentEngine)) {
446-
return ucfirst($currentEngine) . ' (Magento config)';
447-
}
448+
$currentEngine = $engineResolver->getCurrentSearchEngine();
449+
if (!empty($currentEngine)) {
450+
return ucfirst($currentEngine) . ' (Magento config)';
448451
}
449452
} catch (\Exception $e) {
450453
if ($this->io->isVerbose()) {
@@ -541,12 +544,16 @@ private function getSearchEngineHosts(): array
541544
*/
542545
private function formatSearchEngineVersion(array $info): string
543546
{
544-
if (isset($info['version']['distribution']) && $info['version']['distribution'] === 'opensearch') {
545-
return 'OpenSearch ' . $info['version']['number'];
547+
$version = $info['version'] ?? null;
548+
if (!is_array($version)) {
549+
return 'Search Engine Available';
550+
}
551+
if (isset($version['distribution']) && $version['distribution'] === 'opensearch') {
552+
return 'OpenSearch ' . ($version['number'] ?? '');
546553
}
547554

548-
if (isset($info['version']['number'])) {
549-
return 'Elasticsearch ' . $info['version']['number'];
555+
if (isset($version['number'])) {
556+
return 'Elasticsearch ' . $version['number'];
550557
}
551558

552559
return 'Search Engine Available';
@@ -597,6 +604,7 @@ private function tryMagentoHttpClient(string $url): ?array
597604
if ($status === 200 && !empty($response)) {
598605
$data = json_decode($response, true);
599606
if (is_array($data)) {
607+
/** @var array<string, mixed> $data */
600608
return $data;
601609
}
602610
}
@@ -734,9 +742,10 @@ private function getMagentoEnvironmentValue(string $name): ?string
734742
private function getValueFromDeploymentConfig($objectManager, string $name): ?string
735743
{
736744
try {
745+
/** @var \Magento\Framework\App\DeploymentConfig $deploymentConfig */
737746
$deploymentConfig = $objectManager->get(\Magento\Framework\App\DeploymentConfig::class);
738747
$envValue = $deploymentConfig->get('system/default/environment/' . $name);
739-
if ($envValue !== null) {
748+
if ($envValue !== null && is_scalar($envValue)) {
740749
return (string) $envValue;
741750
}
742751
} catch (\Exception $e) {
@@ -760,7 +769,7 @@ private function getValueFromEnvironmentService($objectManager, string $name): ?
760769
try {
761770
$environmentService = $objectManager->get(\Magento\Framework\App\EnvironmentInterface::class);
762771
$method = 'get' . str_replace(' ', '', ucwords(str_replace('_', ' ', strtolower($name))));
763-
if (method_exists($environmentService, $method)) {
772+
if (is_object($environmentService) && method_exists($environmentService, $method)) {
764773
$value = $environmentService->$method();
765774
if ($value !== null) {
766775
return (string) $value;

src/Console/Command/System/VersionCommand.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,10 @@ private function getModuleVersion(): string
7373
try {
7474
$composerJson = $this->fileDriver->fileGetContents(__DIR__ . '/../../../../composer.json');
7575
$composerData = json_decode($composerJson, true);
76-
return $composerData['version'] ?? self::UNKNOWN_VERSION;
76+
if (is_array($composerData) && isset($composerData['version']) && is_string($composerData['version'])) {
77+
return $composerData['version'];
78+
}
79+
return self::UNKNOWN_VERSION;
7780
} catch (\Exception $e) {
7881
return self::UNKNOWN_VERSION;
7982
}
@@ -96,7 +99,9 @@ private function getLatestVersion(): string
9699

97100
if ($response->getStatusCode() === 200) {
98101
$data = json_decode($response->getBody()->getContents(), true);
99-
return $data['tag_name'] ?? self::UNKNOWN_VERSION;
102+
if (is_array($data) && isset($data['tag_name']) && is_string($data['tag_name'])) {
103+
return $data['tag_name'];
104+
}
100105
}
101106
} catch (\Exception $e) {
102107
if ($this->io->isVerbose()) {

src/Console/Command/Theme/BuildCommand.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ protected function configure(): void
6565
*/
6666
protected function executeCommand(InputInterface $input, OutputInterface $output): int
6767
{
68+
/** @var array<string> $themeCodes */
6869
$themeCodes = $input->getArgument('themeCodes');
6970

7071
// Allow wildcards using the AbstractCommand helper
@@ -106,6 +107,7 @@ protected function executeCommand(InputInterface $input, OutputInterface $output
106107
try {
107108
$themeCodes = $themeCodesPrompt->prompt();
108109
\Laravel\Prompts\Prompt::terminal()->restoreTty();
110+
/** @var array<string> $themeCodes */
109111

110112
// Reset environment
111113
$this->resetPromptEnvironment();

src/Console/Command/Theme/CleanCommand.php

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ protected function configure(): void
7070
*/
7171
protected function executeCommand(InputInterface $input, OutputInterface $output): int
7272
{
73-
$dryRun = $input->getOption('dry-run');
73+
$dryRun = (bool) $input->getOption('dry-run');
7474

7575
if ($dryRun) {
7676
$this->io->note('DRY RUN MODE: No files will be deleted');
@@ -98,6 +98,7 @@ protected function executeCommand(InputInterface $input, OutputInterface $output
9898
*/
9999
private function resolveThemeCodes(InputInterface $input, OutputInterface $output): ?array
100100
{
101+
/** @var array<string> $themeCodes */
101102
$themeCodes = $input->getArgument('themeCodes');
102103
$cleanAll = $input->getOption('all');
103104

@@ -163,7 +164,7 @@ private function selectThemesInteractively(OutputInterface $output): ?array
163164
/**
164165
* Display available themes for non-interactive environments
165166
*
166-
* @param array<mixed> $themes
167+
* @param array<\Magento\Theme\Model\Theme> $themes
167168
* @return void
168169
*/
169170
private function displayAvailableThemes(array $themes): void
@@ -189,7 +190,7 @@ private function displayAvailableThemes(array $themes): void
189190
* Prompt user to select themes
190191
*
191192
* @param array<string> $options
192-
* @param array<mixed> $themes
193+
* @param array<\Magento\Theme\Model\Theme> $themes
193194
* @return array<string>|null
194195
*/
195196
private function promptForThemes(array $options, array $themes): ?array
@@ -216,6 +217,7 @@ private function promptForThemes(array $options, array $themes): ?array
216217
return null;
217218
}
218219

220+
/** @var array<string> $themeCodes */
219221
return $themeCodes;
220222
} catch (\Exception $e) {
221223
$this->resetPromptEnvironment();
@@ -231,7 +233,7 @@ private function promptForThemes(array $options, array $themes): ?array
231233
* @param array<string> $themeCodes
232234
* @param bool $dryRun
233235
* @param OutputInterface $output
234-
* @return array<int, mixed> [totalCleaned, failedThemes]
236+
* @return array{int, array<string>} [totalCleaned, failedThemes]
235237
*/
236238
private function processThemes(array $themeCodes, bool $dryRun, OutputInterface $output): array
237239
{

src/Console/Command/Theme/TokensCommand.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,8 @@ protected function configure(): void
6868
*/
6969
protected function executeCommand(InputInterface $input, OutputInterface $output): int
7070
{
71-
$themeCode = $this->selectTheme($input->getArgument('themeCode'));
71+
$arg = $input->getArgument('themeCode');
72+
$themeCode = $this->selectTheme(is_string($arg) ? $arg : null);
7273
if ($themeCode === null) {
7374
return Cli::RETURN_FAILURE;
7475
}
@@ -121,7 +122,7 @@ private function selectTheme(?string $themeCode): ?string
121122
try {
122123
$themeCode = $themeCodePrompt->prompt();
123124
\Laravel\Prompts\Prompt::terminal()->restoreTty();
124-
return $themeCode;
125+
return is_string($themeCode) ? $themeCode : null;
125126
} catch (\Exception $e) {
126127
$this->io->error('Interactive mode failed: ' . $e->getMessage());
127128
return null;

src/Console/Command/Theme/WatchCommand.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,11 @@ protected function executeCommand(InputInterface $input, OutputInterface $output
8787
\Laravel\Prompts\Prompt::terminal()->restoreTty();
8888
}
8989

90+
if (!is_string($themeCode)) {
91+
$this->io->error('No valid theme code provided.');
92+
return self::FAILURE;
93+
}
94+
9095
$themePath = $this->themePath->getPath($themeCode);
9196
if ($themePath === null) {
9297
// Try to suggest similar themes

0 commit comments

Comments
 (0)