Skip to content

Commit c57f6c7

Browse files
Morgy93Copilot
andauthored
fix: update phpstan to level 9 (#152)
* fix: update phpstan level to 9 * fix: update return type for getAllThemes method * fix: improve type checks and phpstan annotations * fix: improve code formatting and type checks * fix: simplify conditionals in various builders * fix: update phpstan types and annotations for compatibility * fix: remove CheckCommand.php file * fix: ensure version number is a string in CheckCommand * fix: remove unused import in ThemeList.php * fix: remove module path from compatibility results * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * fix: update type hints for theme parameters --------- Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
1 parent cef9761 commit c57f6c7

18 files changed

Lines changed: 172 additions & 86 deletions

phpstan.neon

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@ includes:
22
- phar://phpstan.phar/conf/bleedingEdge.neon
33

44
parameters:
5-
level: 8
5+
level: 9
66
paths:
77
- src

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: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66

77
use Laravel\Prompts\SelectPrompt;
88
use Magento\Framework\Console\Cli;
9-
use OpenForgeProject\MageForge\Service\ThemeSuggester;
109
use OpenForgeProject\MageForge\Model\ThemeList;
10+
use OpenForgeProject\MageForge\Service\ThemeSuggester;
1111
use Symfony\Component\Console\Command\Command;
1212
use Symfony\Component\Console\Input\InputInterface;
1313
use Symfony\Component\Console\Output\OutputInterface;
@@ -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());
@@ -487,10 +487,8 @@ private function removeSecureEnvironmentValue(string $name): void
487487
* @param ThemeList $themeList
488488
* @return array<string>
489489
*/
490-
protected function resolveVendorThemes(
491-
array $themeCodes,
492-
ThemeList $themeList
493-
): array {
490+
protected function resolveVendorThemes(array $themeCodes, ThemeList $themeList): array
491+
{
494492
$resolved = [];
495493
$availableThemes = null;
496494

@@ -502,10 +500,7 @@ protected function resolveVendorThemes(
502500
if ($isExplicitWildcard || $isVendorOnly) {
503501
// Lazy-load themes only when needed
504502
if ($availableThemes === null) {
505-
$availableThemes = array_map(
506-
fn($theme) => $theme->getCode(),
507-
$themeList->getAllThemes()
508-
);
503+
$availableThemes = array_map(fn($theme) => $theme->getCode(), $themeList->getAllThemes());
509504
}
510505

511506
if ($isExplicitWildcard) {
@@ -514,10 +509,10 @@ protected function resolveVendorThemes(
514509
$prefix = $code . '/'; // e.g. "Vendor" -> "Vendor/"
515510
}
516511

517-
$matched = array_filter(
518-
$availableThemes,
519-
fn(string $availableCode) => \str_starts_with($availableCode, $prefix)
520-
);
512+
$matched = array_filter($availableThemes, fn(string $availableCode) => \str_starts_with(
513+
$availableCode,
514+
$prefix,
515+
));
521516

522517
if (empty($matched)) {
523518
$this->io->warning(sprintf("No themes found for vendor/prefix '%s'", $prefix));
@@ -532,7 +527,7 @@ protected function resolveVendorThemes(
532527
"Resolved vendor '%s' to %d theme(s): %s",
533528
$code,
534529
count($matched),
535-
implode(', ', $matched)
530+
implode(', ', $matched),
536531
));
537532

538533
foreach ($matched as $match) {

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: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@
1919
*
2020
* Scans modules for RequireJS, Knockout.js, jQuery, and UI Components usage
2121
* that would be incompatible with Hyvä themes.
22+
*
23+
* @phpstan-import-type CheckResults from \OpenForgeProject\MageForge\Service\Hyva\CompatibilityChecker
24+
* @phpstan-import-type CheckSummary from \OpenForgeProject\MageForge\Service\Hyva\CompatibilityChecker
25+
* @phpstan-import-type ModuleEntry from \OpenForgeProject\MageForge\Service\Hyva\CompatibilityChecker
2226
*/
2327
class CompatibilityCheckCommand extends AbstractCommand
2428
{
@@ -146,7 +150,7 @@ private function runInteractiveMode(InputInterface $input, OutputInterface $outp
146150
// Detailed view confirmation
147151
$detailedPrompt = new ConfirmPrompt(label: 'Show detailed file-level issues?', default: false);
148152

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

151155
// Map selected options to flags
152156
$showAll = $displayMode === self::DISPLAY_MODE_SHOW_ALL;
@@ -193,10 +197,10 @@ private function runInteractiveMode(InputInterface $input, OutputInterface $outp
193197
*/
194198
private function runDirectMode(InputInterface $input, OutputInterface $output): int
195199
{
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);
200+
$showAll = (bool) $input->getOption(self::OPTION_SHOW_ALL);
201+
$thirdPartyOnly = (bool) $input->getOption(self::OPTION_THIRD_PARTY_ONLY);
202+
$includeVendor = (bool) $input->getOption(self::OPTION_INCLUDE_VENDOR);
203+
$detailed = (bool) $input->getOption(self::OPTION_DETAILED);
200204

201205
$this->io->title('Hyvä Theme Compatibility Check');
202206

@@ -271,7 +275,7 @@ private function runScan(
271275
* Display compatibility check results
272276
*
273277
* @param array $results
274-
* @phpstan-param array<string, mixed> $results
278+
* @phpstan-param CheckResults $results
275279
* @param bool $showAll
276280
*/
277281
private function displayResults(array $results, bool $showAll): void
@@ -292,7 +296,7 @@ private function displayResults(array $results, bool $showAll): void
292296
* Display detailed file-level issues
293297
*
294298
* @param array $results
295-
* @phpstan-param array<string, mixed> $results
299+
* @phpstan-param CheckResults $results
296300
*/
297301
private function displayDetailedIssues(array $results): void
298302
{
@@ -333,7 +337,7 @@ private function displayDetailedIssues(array $results): void
333337
* Display summary statistics
334338
*
335339
* @param array $results
336-
* @phpstan-param array<string, mixed> $results
340+
* @phpstan-param array{summary: CheckSummary} $results
337341
*/
338342
private function displaySummary(array $results): void
339343
{

src/Console/Command/System/CheckCommand.php

Lines changed: 45 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -162,8 +162,13 @@ 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'])
168+
&& $node['lts'] !== false
169+
&& isset($node['version'])
170+
&& is_string($node['version'])
171+
) {
167172
return trim($node['version'], 'v');
168173
}
169174
}
@@ -407,12 +412,15 @@ private function getSearchEngineFromMagentoConfig(): ?string
407412
private function checkSearchEngineViaDeploymentConfig($objectManager): ?string
408413
{
409414
try {
415+
/** @var \Magento\Framework\App\DeploymentConfig $deploymentConfig */
410416
$deploymentConfig = $objectManager->get(\Magento\Framework\App\DeploymentConfig::class);
411417
$engineConfig = $deploymentConfig->get('system/search/engine');
412418

413-
if (!empty($engineConfig)) {
414-
$host = $deploymentConfig->get('system/search/engine_host') ?: 'localhost';
415-
$port = $deploymentConfig->get('system/search/engine_port') ?: '9200';
419+
if (!empty($engineConfig) && is_string($engineConfig)) {
420+
$hostRaw = $deploymentConfig->get('system/search/engine_host');
421+
$portRaw = $deploymentConfig->get('system/search/engine_port');
422+
$host = is_string($hostRaw) ? $hostRaw : 'localhost';
423+
$port = is_string($portRaw) ? $portRaw : '9200';
416424

417425
$url = "http://{$host}:{$port}";
418426
if ($this->testElasticsearchConnection($url)) {
@@ -439,12 +447,11 @@ private function checkSearchEngineViaDeploymentConfig($objectManager): ?string
439447
private function checkSearchEngineViaEngineResolver($objectManager): ?string
440448
{
441449
try {
450+
/** @var \Magento\Framework\Search\EngineResolverInterface $engineResolver */
442451
$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-
}
452+
$currentEngine = $engineResolver->getCurrentSearchEngine();
453+
if (!empty($currentEngine)) {
454+
return ucfirst($currentEngine) . ' (Magento config)';
448455
}
449456
} catch (\Exception $e) {
450457
if ($this->io->isVerbose()) {
@@ -541,12 +548,16 @@ private function getSearchEngineHosts(): array
541548
*/
542549
private function formatSearchEngineVersion(array $info): string
543550
{
544-
if (isset($info['version']['distribution']) && $info['version']['distribution'] === 'opensearch') {
545-
return 'OpenSearch ' . $info['version']['number'];
551+
$version = $info['version'] ?? null;
552+
if (!is_array($version)) {
553+
return 'Search Engine Available';
554+
}
555+
if (isset($version['distribution']) && $version['distribution'] === 'opensearch') {
556+
return 'OpenSearch ' . (is_string($version['number']) ? $version['number'] : '');
546557
}
547558

548-
if (isset($info['version']['number'])) {
549-
return 'Elasticsearch ' . $info['version']['number'];
559+
if (isset($version['number'])) {
560+
return 'Elasticsearch ' . (is_string($version['number']) ? $version['number'] : '');
550561
}
551562

552563
return 'Search Engine Available';
@@ -597,6 +608,7 @@ private function tryMagentoHttpClient(string $url): ?array
597608
if ($status === 200 && !empty($response)) {
598609
$data = json_decode($response, true);
599610
if (is_array($data)) {
611+
/** @var array<string, mixed> $data */
600612
return $data;
601613
}
602614
}
@@ -661,10 +673,24 @@ private function getDiskSpace(): string
661673
$totalSpace = disk_total_space('.');
662674
$freeSpace = disk_free_space('.');
663675

664-
$totalGB = round((($totalSpace / 1024) / 1024) / 1024, 2);
665-
$freeGB = round((($freeSpace / 1024) / 1024) / 1024, 2);
676+
if ($totalSpace === false || $freeSpace === false) {
677+
return 'Unknown';
678+
}
679+
680+
if ($totalSpace <= 0) {
681+
$totalGB = 0.0;
682+
$usedGB = 0.0;
683+
$usedPercent = 0.0;
684+
685+
return "$usedGB GB / $totalGB GB ($usedPercent%)";
686+
}
687+
688+
$totalGB = round($totalSpace / 1024 / 1024 / 1024, 2);
689+
$freeGB = round($freeSpace / 1024 / 1024 / 1024, 2);
666690
$usedGB = round($totalGB - $freeGB, 2);
667-
$usedPercent = round(($usedGB / $totalGB) * 100, 2);
691+
$usedPercent = $totalGB > 0.0
692+
? round(($usedGB / $totalGB) * 100, 2)
693+
: 0.0;
668694

669695
return "$usedGB GB / $totalGB GB ($usedPercent%)";
670696
}
@@ -734,9 +760,10 @@ private function getMagentoEnvironmentValue(string $name): ?string
734760
private function getValueFromDeploymentConfig($objectManager, string $name): ?string
735761
{
736762
try {
763+
/** @var \Magento\Framework\App\DeploymentConfig $deploymentConfig */
737764
$deploymentConfig = $objectManager->get(\Magento\Framework\App\DeploymentConfig::class);
738765
$envValue = $deploymentConfig->get('system/default/environment/' . $name);
739-
if ($envValue !== null) {
766+
if ($envValue !== null && is_scalar($envValue)) {
740767
return (string) $envValue;
741768
}
742769
} catch (\Exception $e) {
@@ -760,7 +787,7 @@ private function getValueFromEnvironmentService($objectManager, string $name): ?
760787
try {
761788
$environmentService = $objectManager->get(\Magento\Framework\App\EnvironmentInterface::class);
762789
$method = 'get' . str_replace(' ', '', ucwords(str_replace('_', ' ', strtolower($name))));
763-
if (method_exists($environmentService, $method)) {
790+
if (is_object($environmentService) && method_exists($environmentService, $method)) {
764791
$value = $environmentService->$method();
765792
if ($value !== null) {
766793
return (string) $value;

src/Console/Command/System/CheckCommand.php.new

Whitespace-only changes.

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: 5 additions & 3 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
@@ -97,7 +98,7 @@ protected function executeCommand(InputInterface $input, OutputInterface $output
9798
label: 'Select themes to build',
9899
options: fn(string $value) => empty($value)
99100
? $options
100-
: array_values(array_filter($options, fn($option) => stripos((string)$option, $value) !== false)),
101+
: array_values(array_filter($options, fn($option) => stripos((string) $option, $value) !== false)),
101102
placeholder: 'Type to search theme...',
102103
hint: 'Type to search, arrow keys to navigate, Space to toggle, Enter to confirm',
103104
required: false,
@@ -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();
@@ -355,14 +357,14 @@ private function displayBuildSummary(SymfonyStyle $io, array $successList, float
355357
$io->success(sprintf(
356358
'🚀 Successfully built %d theme(s). Build process completed in %.2f seconds.',
357359
$successCount,
358-
$duration
360+
$duration,
359361
));
360362
$io->writeln('Summary:');
361363
$io->newLine();
362364
} else {
363365
$io->warning(sprintf(
364366
'Build process completed in %.2f seconds, but no themes were built successfully.',
365-
$duration
367+
$duration,
366368
));
367369
return;
368370
}

0 commit comments

Comments
 (0)