|
7 | 7 | use Laravel\Prompts\SelectPrompt; |
8 | 8 | use Magento\Framework\Console\Cli; |
9 | 9 | use OpenForgeProject\MageForge\Service\ThemeSuggester; |
| 10 | +use OpenForgeProject\MageForge\Model\ThemeList; |
10 | 11 | use Symfony\Component\Console\Command\Command; |
11 | 12 | use Symfony\Component\Console\Input\InputInterface; |
12 | 13 | use Symfony\Component\Console\Output\OutputInterface; |
@@ -478,4 +479,72 @@ private function removeSecureEnvironmentValue(string $name): void |
478 | 479 | unset($this->secureEnvStorage[$name]); |
479 | 480 | $this->clearEnvironmentCache(); |
480 | 481 | } |
| 482 | + |
| 483 | + /** |
| 484 | + * Resolve vendor theme codes (e.g., Vendor to all underlying vendor themes) |
| 485 | + * |
| 486 | + * @param array<string> $themeCodes |
| 487 | + * @param ThemeList $themeList |
| 488 | + * @return array<string> |
| 489 | + */ |
| 490 | + protected function resolveVendorThemes( |
| 491 | + array $themeCodes, |
| 492 | + ThemeList $themeList |
| 493 | + ): array { |
| 494 | + $resolved = []; |
| 495 | + $availableThemes = null; |
| 496 | + |
| 497 | + foreach ($themeCodes as $code) { |
| 498 | + // Check if it's explicitly a wildcard OR just a vendor name without a slash |
| 499 | + $isExplicitWildcard = \str_ends_with($code, '/*'); |
| 500 | + $isVendorOnly = !\str_contains($code, '/'); |
| 501 | + |
| 502 | + if ($isExplicitWildcard || $isVendorOnly) { |
| 503 | + // Lazy-load themes only when needed |
| 504 | + if ($availableThemes === null) { |
| 505 | + $availableThemes = array_map( |
| 506 | + fn($theme) => $theme->getCode(), |
| 507 | + $themeList->getAllThemes() |
| 508 | + ); |
| 509 | + } |
| 510 | + |
| 511 | + if ($isExplicitWildcard) { |
| 512 | + $prefix = substr($code, 0, -1); // Keeps the trailing slash, e.g. "Vendor/" |
| 513 | + } else { |
| 514 | + $prefix = $code . '/'; // e.g. "Vendor" -> "Vendor/" |
| 515 | + } |
| 516 | + |
| 517 | + $matched = array_filter( |
| 518 | + $availableThemes, |
| 519 | + fn(string $availableCode) => \str_starts_with($availableCode, $prefix) |
| 520 | + ); |
| 521 | + |
| 522 | + if (empty($matched)) { |
| 523 | + $this->io->warning(sprintf("No themes found for vendor/prefix '%s'", $prefix)); |
| 524 | + |
| 525 | + // If they typed just a word and it wasn't a vendor, |
| 526 | + // we still add it so standard Magento validation kicks in later. |
| 527 | + if ($isVendorOnly) { |
| 528 | + $resolved[] = $code; |
| 529 | + } |
| 530 | + } else { |
| 531 | + $this->io->note(sprintf( |
| 532 | + "Resolved vendor '%s' to %d theme(s): %s", |
| 533 | + $code, |
| 534 | + count($matched), |
| 535 | + implode(', ', $matched) |
| 536 | + )); |
| 537 | + |
| 538 | + foreach ($matched as $match) { |
| 539 | + $resolved[] = $match; |
| 540 | + } |
| 541 | + } |
| 542 | + } else { |
| 543 | + $resolved[] = $code; |
| 544 | + } |
| 545 | + } |
| 546 | + |
| 547 | + // Return a fresh list without duplicates |
| 548 | + return array_values(array_unique($resolved)); |
| 549 | + } |
481 | 550 | } |
0 commit comments