Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ includes:
- phar://phpstan.phar/conf/bleedingEdge.neon

parameters:
level: 8
level: 9
paths:
- src
3 changes: 2 additions & 1 deletion src/Block/Inspector.php
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,8 @@ public function getJsUrl(): string
*/
public function getTheme(): string
{
return (string) $this->scopeConfig->getValue('mageforge/inspector/theme') ?: 'dark';
$value = $this->scopeConfig->getValue('mageforge/inspector/theme');
return is_string($value) && $value !== '' ? $value : 'dark';
}

/**
Expand Down
25 changes: 10 additions & 15 deletions src/Console/Command/AbstractCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@

use Laravel\Prompts\SelectPrompt;
use Magento\Framework\Console\Cli;
use OpenForgeProject\MageForge\Service\ThemeSuggester;
use OpenForgeProject\MageForge\Model\ThemeList;
use OpenForgeProject\MageForge\Service\ThemeSuggester;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
Expand Down Expand Up @@ -183,7 +183,7 @@ protected function handleInvalidThemeWithSuggestions(
return null;
}

return $selection;
return is_string($selection) ? $selection : null;
} catch (\Exception $e) {
$this->resetPromptEnvironment();
$this->io->error('Selection failed: ' . $e->getMessage());
Expand Down Expand Up @@ -487,10 +487,8 @@ private function removeSecureEnvironmentValue(string $name): void
* @param ThemeList $themeList
* @return array<string>
*/
protected function resolveVendorThemes(
array $themeCodes,
ThemeList $themeList
): array {
protected function resolveVendorThemes(array $themeCodes, ThemeList $themeList): array
{
$resolved = [];
$availableThemes = null;

Expand All @@ -502,10 +500,7 @@ protected function resolveVendorThemes(
if ($isExplicitWildcard || $isVendorOnly) {
// Lazy-load themes only when needed
if ($availableThemes === null) {
$availableThemes = array_map(
fn($theme) => $theme->getCode(),
$themeList->getAllThemes()
);
$availableThemes = array_map(fn($theme) => $theme->getCode(), $themeList->getAllThemes());
}

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

$matched = array_filter(
$availableThemes,
fn(string $availableCode) => \str_starts_with($availableCode, $prefix)
);
$matched = array_filter($availableThemes, fn(string $availableCode) => \str_starts_with(
$availableCode,
$prefix,
));

if (empty($matched)) {
$this->io->warning(sprintf("No themes found for vendor/prefix '%s'", $prefix));
Expand All @@ -532,7 +527,7 @@ protected function resolveVendorThemes(
"Resolved vendor '%s' to %d theme(s): %s",
$code,
count($matched),
implode(', ', $matched)
implode(', ', $matched),
));

foreach ($matched as $match) {
Expand Down
3 changes: 2 additions & 1 deletion src/Console/Command/Dev/InspectorCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ protected function configure(): void
*/
protected function executeCommand(InputInterface $input, OutputInterface $output): int
{
$action = strtolower((string) $input->getArgument(self::ARGUMENT_ACTION));
$arg = $input->getArgument(self::ARGUMENT_ACTION);
$action = strtolower(is_string($arg) ? $arg : '');

// Validate action
if (!in_array($action, ['enable', 'disable', 'status'], true)) {
Expand Down
20 changes: 12 additions & 8 deletions src/Console/Command/Hyva/CompatibilityCheckCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@
*
* Scans modules for RequireJS, Knockout.js, jQuery, and UI Components usage
* that would be incompatible with Hyvä themes.
*
* @phpstan-import-type CheckResults from \OpenForgeProject\MageForge\Service\Hyva\CompatibilityChecker
* @phpstan-import-type CheckSummary from \OpenForgeProject\MageForge\Service\Hyva\CompatibilityChecker
* @phpstan-import-type ModuleEntry from \OpenForgeProject\MageForge\Service\Hyva\CompatibilityChecker
*/
class CompatibilityCheckCommand extends AbstractCommand
{
Expand Down Expand Up @@ -146,7 +150,7 @@ private function runInteractiveMode(InputInterface $input, OutputInterface $outp
// Detailed view confirmation
$detailedPrompt = new ConfirmPrompt(label: 'Show detailed file-level issues?', default: false);

$detailed = $detailedPrompt->prompt();
$detailed = (bool) $detailedPrompt->prompt();

// Map selected options to flags
$showAll = $displayMode === self::DISPLAY_MODE_SHOW_ALL;
Expand Down Expand Up @@ -193,10 +197,10 @@ private function runInteractiveMode(InputInterface $input, OutputInterface $outp
*/
private function runDirectMode(InputInterface $input, OutputInterface $output): int
{
$showAll = $input->getOption(self::OPTION_SHOW_ALL);
$thirdPartyOnly = $input->getOption(self::OPTION_THIRD_PARTY_ONLY);
$includeVendor = $input->getOption(self::OPTION_INCLUDE_VENDOR);
$detailed = $input->getOption(self::OPTION_DETAILED);
$showAll = (bool) $input->getOption(self::OPTION_SHOW_ALL);
$thirdPartyOnly = (bool) $input->getOption(self::OPTION_THIRD_PARTY_ONLY);
$includeVendor = (bool) $input->getOption(self::OPTION_INCLUDE_VENDOR);
$detailed = (bool) $input->getOption(self::OPTION_DETAILED);

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

Expand Down Expand Up @@ -271,7 +275,7 @@ private function runScan(
* Display compatibility check results
*
* @param array $results
* @phpstan-param array<string, mixed> $results
* @phpstan-param CheckResults $results
* @param bool $showAll
*/
private function displayResults(array $results, bool $showAll): void
Expand All @@ -292,7 +296,7 @@ private function displayResults(array $results, bool $showAll): void
* Display detailed file-level issues
*
* @param array $results
* @phpstan-param array<string, mixed> $results
* @phpstan-param CheckResults $results
*/
private function displayDetailedIssues(array $results): void
{
Expand Down Expand Up @@ -333,7 +337,7 @@ private function displayDetailedIssues(array $results): void
* Display summary statistics
*
* @param array $results
* @phpstan-param array<string, mixed> $results
* @phpstan-param array{summary: CheckSummary} $results
*/
private function displaySummary(array $results): void
{
Expand Down
47 changes: 30 additions & 17 deletions src/Console/Command/System/CheckCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -162,8 +162,13 @@ private function getLatestLtsNodeVersion(): string
return 'Unknown';
}

/** @var array<int, array<string, mixed>> $nodes */
foreach ($nodes as $node) {
if (isset($node['lts']) && $node['lts'] !== false) {
if (isset($node['lts'])
&& $node['lts'] !== false
&& isset($node['version'])
&& is_string($node['version'])
) {
return trim($node['version'], 'v');
}
}
Expand Down Expand Up @@ -407,12 +412,15 @@ private function getSearchEngineFromMagentoConfig(): ?string
private function checkSearchEngineViaDeploymentConfig($objectManager): ?string
{
try {
/** @var \Magento\Framework\App\DeploymentConfig $deploymentConfig */
$deploymentConfig = $objectManager->get(\Magento\Framework\App\DeploymentConfig::class);
$engineConfig = $deploymentConfig->get('system/search/engine');

if (!empty($engineConfig)) {
$host = $deploymentConfig->get('system/search/engine_host') ?: 'localhost';
$port = $deploymentConfig->get('system/search/engine_port') ?: '9200';
if (!empty($engineConfig) && is_string($engineConfig)) {
$hostRaw = $deploymentConfig->get('system/search/engine_host');
$portRaw = $deploymentConfig->get('system/search/engine_port');
$host = is_string($hostRaw) ? $hostRaw : 'localhost';
$port = is_string($portRaw) ? $portRaw : '9200';

$url = "http://{$host}:{$port}";
if ($this->testElasticsearchConnection($url)) {
Expand All @@ -439,12 +447,11 @@ private function checkSearchEngineViaDeploymentConfig($objectManager): ?string
private function checkSearchEngineViaEngineResolver($objectManager): ?string
{
try {
/** @var \Magento\Framework\Search\EngineResolverInterface $engineResolver */
$engineResolver = $objectManager->get(\Magento\Framework\Search\EngineResolverInterface::class);
if ($engineResolver) {
$currentEngine = $engineResolver->getCurrentSearchEngine();
if (!empty($currentEngine)) {
return ucfirst($currentEngine) . ' (Magento config)';
}
$currentEngine = $engineResolver->getCurrentSearchEngine();
if (!empty($currentEngine)) {
return ucfirst($currentEngine) . ' (Magento config)';
}
} catch (\Exception $e) {
if ($this->io->isVerbose()) {
Expand Down Expand Up @@ -541,12 +548,16 @@ private function getSearchEngineHosts(): array
*/
private function formatSearchEngineVersion(array $info): string
{
if (isset($info['version']['distribution']) && $info['version']['distribution'] === 'opensearch') {
return 'OpenSearch ' . $info['version']['number'];
$version = $info['version'] ?? null;
if (!is_array($version)) {
return 'Search Engine Available';
}
if (isset($version['distribution']) && $version['distribution'] === 'opensearch') {
return 'OpenSearch ' . ($version['number'] ?? '');
}

if (isset($info['version']['number'])) {
return 'Elasticsearch ' . $info['version']['number'];
if (isset($version['number'])) {
return 'Elasticsearch ' . $version['number'];
}

return 'Search Engine Available';
Expand Down Expand Up @@ -597,6 +608,7 @@ private function tryMagentoHttpClient(string $url): ?array
if ($status === 200 && !empty($response)) {
$data = json_decode($response, true);
if (is_array($data)) {
/** @var array<string, mixed> $data */
return $data;
}
}
Expand Down Expand Up @@ -661,8 +673,8 @@ private function getDiskSpace(): string
$totalSpace = disk_total_space('.');
$freeSpace = disk_free_space('.');

$totalGB = round((($totalSpace / 1024) / 1024) / 1024, 2);
$freeGB = round((($freeSpace / 1024) / 1024) / 1024, 2);
$totalGB = round($totalSpace / 1024 / 1024 / 1024, 2);
$freeGB = round($freeSpace / 1024 / 1024 / 1024, 2);
$usedGB = round($totalGB - $freeGB, 2);
$usedPercent = round(($usedGB / $totalGB) * 100, 2);
Comment thread
Morgy93 marked this conversation as resolved.
Outdated

Expand Down Expand Up @@ -734,9 +746,10 @@ private function getMagentoEnvironmentValue(string $name): ?string
private function getValueFromDeploymentConfig($objectManager, string $name): ?string
{
try {
/** @var \Magento\Framework\App\DeploymentConfig $deploymentConfig */
$deploymentConfig = $objectManager->get(\Magento\Framework\App\DeploymentConfig::class);
$envValue = $deploymentConfig->get('system/default/environment/' . $name);
if ($envValue !== null) {
if ($envValue !== null && is_scalar($envValue)) {
return (string) $envValue;
}
} catch (\Exception $e) {
Expand All @@ -760,7 +773,7 @@ private function getValueFromEnvironmentService($objectManager, string $name): ?
try {
$environmentService = $objectManager->get(\Magento\Framework\App\EnvironmentInterface::class);
$method = 'get' . str_replace(' ', '', ucwords(str_replace('_', ' ', strtolower($name))));
if (method_exists($environmentService, $method)) {
if (is_object($environmentService) && method_exists($environmentService, $method)) {
$value = $environmentService->$method();
if ($value !== null) {
return (string) $value;
Expand Down
9 changes: 7 additions & 2 deletions src/Console/Command/System/VersionCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,10 @@ private function getModuleVersion(): string
try {
$composerJson = $this->fileDriver->fileGetContents(__DIR__ . '/../../../../composer.json');
$composerData = json_decode($composerJson, true);
return $composerData['version'] ?? self::UNKNOWN_VERSION;
if (is_array($composerData) && isset($composerData['version']) && is_string($composerData['version'])) {
return $composerData['version'];
}
return self::UNKNOWN_VERSION;
} catch (\Exception $e) {
return self::UNKNOWN_VERSION;
}
Expand All @@ -96,7 +99,9 @@ private function getLatestVersion(): string

if ($response->getStatusCode() === 200) {
$data = json_decode($response->getBody()->getContents(), true);
return $data['tag_name'] ?? self::UNKNOWN_VERSION;
if (is_array($data) && isset($data['tag_name']) && is_string($data['tag_name'])) {
return $data['tag_name'];
}
}
} catch (\Exception $e) {
if ($this->io->isVerbose()) {
Expand Down
8 changes: 5 additions & 3 deletions src/Console/Command/Theme/BuildCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ protected function configure(): void
*/
protected function executeCommand(InputInterface $input, OutputInterface $output): int
{
/** @var array<string> $themeCodes */
$themeCodes = $input->getArgument('themeCodes');

// Allow wildcards using the AbstractCommand helper
Expand Down Expand Up @@ -97,7 +98,7 @@ protected function executeCommand(InputInterface $input, OutputInterface $output
label: 'Select themes to build',
options: fn(string $value) => empty($value)
? $options
: array_values(array_filter($options, fn($option) => stripos((string)$option, $value) !== false)),
: array_values(array_filter($options, fn($option) => stripos((string) $option, $value) !== false)),
placeholder: 'Type to search theme...',
hint: 'Type to search, arrow keys to navigate, Space to toggle, Enter to confirm',
required: false,
Expand All @@ -106,6 +107,7 @@ protected function executeCommand(InputInterface $input, OutputInterface $output
try {
$themeCodes = $themeCodesPrompt->prompt();
\Laravel\Prompts\Prompt::terminal()->restoreTty();
/** @var array<string> $themeCodes */

// Reset environment
$this->resetPromptEnvironment();
Expand Down Expand Up @@ -355,14 +357,14 @@ private function displayBuildSummary(SymfonyStyle $io, array $successList, float
$io->success(sprintf(
'🚀 Successfully built %d theme(s). Build process completed in %.2f seconds.',
$successCount,
$duration
$duration,
));
$io->writeln('Summary:');
$io->newLine();
} else {
$io->warning(sprintf(
'Build process completed in %.2f seconds, but no themes were built successfully.',
$duration
$duration,
));
return;
}
Expand Down
12 changes: 7 additions & 5 deletions src/Console/Command/Theme/CleanCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ protected function configure(): void
*/
protected function executeCommand(InputInterface $input, OutputInterface $output): int
{
$dryRun = $input->getOption('dry-run');
$dryRun = (bool) $input->getOption('dry-run');

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

Expand Down Expand Up @@ -163,7 +164,7 @@ private function selectThemesInteractively(OutputInterface $output): ?array
/**
* Display available themes for non-interactive environments
*
* @param array<mixed> $themes
* @param array<\Magento\Theme\Model\Theme> $themes
* @return void
*/
private function displayAvailableThemes(array $themes): void
Expand All @@ -189,7 +190,7 @@ private function displayAvailableThemes(array $themes): void
* Prompt user to select themes
*
* @param array<string> $options
* @param array<mixed> $themes
* @param array<\Magento\Theme\Model\Theme> $themes
* @return array<string>|null
*/
private function promptForThemes(array $options, array $themes): ?array
Expand All @@ -200,7 +201,7 @@ private function promptForThemes(array $options, array $themes): ?array
label: 'Select themes to clean',
options: fn(string $value) => empty($value)
? $options
: array_values(array_filter($options, fn($option) => stripos((string)$option, $value) !== false)),
: array_values(array_filter($options, fn($option) => stripos((string) $option, $value) !== false)),
placeholder: 'Type to search theme...',
hint: 'Type to search, arrow keys to navigate, Space to toggle, Enter to confirm',
required: false,
Expand All @@ -216,6 +217,7 @@ private function promptForThemes(array $options, array $themes): ?array
return null;
}

/** @var array<string> $themeCodes */
return $themeCodes;
} catch (\Exception $e) {
$this->resetPromptEnvironment();
Expand All @@ -231,7 +233,7 @@ private function promptForThemes(array $options, array $themes): ?array
* @param array<string> $themeCodes
* @param bool $dryRun
* @param OutputInterface $output
* @return array<int, mixed> [totalCleaned, failedThemes]
* @return array{int, array<string>} [totalCleaned, failedThemes]
*/
private function processThemes(array $themeCodes, bool $dryRun, OutputInterface $output): array
{
Expand Down
Loading
Loading