117 lines
4.8 KiB
PHP
117 lines
4.8 KiB
PHP
<?php
|
|
|
|
namespace KupShop\ComponentsBundle\DependencyInjection\Compiler;
|
|
|
|
use KupShop\ComponentsBundle\DependencyInjection\ComponentsExtension;
|
|
use KupShop\ComponentsBundle\Twig\ComponentInterface;
|
|
use KupShop\ComponentsBundle\Utils\ComponentsLocator;
|
|
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
|
|
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
|
use Symfony\UX\Icons\Twig\UXIconComponent;
|
|
|
|
class ComponentsPass implements CompilerPassInterface
|
|
{
|
|
public function __construct(
|
|
protected ComponentsExtension $extension,
|
|
) {
|
|
}
|
|
|
|
public function process(ContainerBuilder $container)
|
|
{
|
|
$factoryDefinition = $container->findDefinition('ux.twig_component.component_factory');
|
|
$componentConfig = $factoryDefinition->getArgument(4);
|
|
|
|
$shopConfig = $this->extension->getConfig();
|
|
$shopComponents = $shopConfig['components'];
|
|
|
|
$components = [];
|
|
$unusedComponents = [];
|
|
|
|
foreach ($componentConfig as $name => &$config) {
|
|
$components[$config['class']] = ['name' => $name, ...$config];
|
|
|
|
$config['expose_public_props'] = false;
|
|
|
|
if (isset($shopComponents[$name])) {
|
|
$components[$config['class']]['shop'] = $shopComponents[$name];
|
|
} elseif (findModule(\Modules::COMPONENTS, \Modules::SUB_STORYBOOK)) {
|
|
if ($config['class'] != UXIconComponent::class) {
|
|
$components[$config['class']]['shop']['entrypoint'] = 'base';
|
|
$components[$config['class']]['shop']['version'] = 1;
|
|
}
|
|
}
|
|
}
|
|
unset($config);
|
|
|
|
foreach ($shopComponents as $name => $config) {
|
|
if (!array_key_exists($name, $componentConfig)) {
|
|
throw new \LogicException("Unknown component {$name} defined in components.yaml");
|
|
}
|
|
}
|
|
|
|
// Find all Wpj Components
|
|
foreach ($container->findTaggedServiceIds('wpj.component') as $id => $tags) {
|
|
$definition = $container->findDefinition($id);
|
|
|
|
$component = &$components[$definition->getClass()];
|
|
|
|
foreach ($tags as $tag) {
|
|
$component['latest_version'] = $tag['latestVersion'];
|
|
$component['className'] = strtolower(str_replace(':', '-', $component['name']));
|
|
|
|
// If component is not used on shop, remove it from registered components
|
|
if (!isset($component['shop'])) {
|
|
$unusedComponents[$component['name']] = $component;
|
|
unset($componentConfig[$component['name']]);
|
|
continue 2;
|
|
}
|
|
|
|
$component['entrypoints'] = $component['shop']['entrypoint'];
|
|
|
|
$use_version = $component['shop']['version'];
|
|
$version = $this->findVersion($tag, $use_version, $component['name']);
|
|
|
|
$component['template'] = preg_replace('/\.\d+\.html\.twig/', ".{$version['template']}.html.twig", $component['template']);
|
|
$component['shop'] = [...$component['shop'], ...$version];
|
|
|
|
$componentConfig[$component['name']]['template'] = $component['template'];
|
|
|
|
if (!is_subclass_of($definition->getClass(), ComponentInterface::class)) {
|
|
throw new \LogicException("Component {$definition->getClass()} must inherit from BaseComponent");
|
|
}
|
|
|
|
$definition->addMethodCall('setConfiguration', [$use_version, $component['className']]);
|
|
}
|
|
}
|
|
|
|
$factoryDefinition->setArgument(4, $componentConfig);
|
|
|
|
// Store components info
|
|
$locator = $container->getDefinition(ComponentsLocator::class);
|
|
$locator->setArgument('$components', $components);
|
|
$locator->setArgument('$unusedComponents', $unusedComponents);
|
|
|
|
// HACK
|
|
// override symfony/ux-live-component/src/DependencyInjection/LiveComponentExtension.php
|
|
// use constant instead of container.build_hash parameter for template hashing
|
|
// when shop is redeployed, container.build_hash changes and cached html still reference old hash, which causes RuntimeException
|
|
// The exception: Cannot find a template matching "...". Cache may be corrupt.
|
|
$container->getDefinition('ux.live_component.twig.cache_warmer')->setArgument('$secret', '1234');
|
|
}
|
|
|
|
protected function findVersion(array $tag, int $version, string $componentName): ?array
|
|
{
|
|
if ($version > $tag['latestVersion']) {
|
|
throw new \LogicException("Can not find component {$componentName} version {$version}");
|
|
}
|
|
|
|
foreach (array_reverse($tag['versions'], true) as $version_from => $config) {
|
|
if ($version_from <= $version) {
|
|
return $config;
|
|
}
|
|
}
|
|
|
|
throw new \LogicException('This should never happen!');
|
|
}
|
|
}
|