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!'); } }