From c713a833e45d72b05c9472569436ae82bdab0d4f Mon Sep 17 00:00:00 2001 From: Mark Shust Date: Tue, 14 Apr 2026 14:51:44 -0400 Subject: [PATCH] fix: use DI container to instantiate layout components LayoutProcessor was using `new $className()` which bypasses the DI container, breaking any component with constructor dependencies. Now injects ContainerInterface and uses `$container->get()` so component dependencies (like repositories) are auto-resolved. Co-Authored-By: Claude Opus 4.6 (1M context) --- packages/layout/src/LayoutProcessor.php | 9 +++-- packages/layout/tests/Unit/Helpers.php | 36 +++++++++++++++++++ .../tests/Unit/LayoutProcessorNestedTest.php | 2 ++ .../layout/tests/Unit/LayoutProcessorTest.php | 2 ++ 4 files changed, 46 insertions(+), 3 deletions(-) create mode 100644 packages/layout/tests/Unit/Helpers.php diff --git a/packages/layout/src/LayoutProcessor.php b/packages/layout/src/LayoutProcessor.php index eef44e34..3fdc3cef 100644 --- a/packages/layout/src/LayoutProcessor.php +++ b/packages/layout/src/LayoutProcessor.php @@ -8,6 +8,8 @@ use Marko\Layout\Exceptions\CircularSlotException; use Marko\Layout\Exceptions\LayoutNotFoundException; use Marko\Layout\Exceptions\SlotNotFoundException; +use Marko\Core\Container\ContainerInterface; +use Psr\Container\ContainerExceptionInterface; use Marko\Routing\Http\Request; use Marko\Routing\Http\Response; use Marko\View\ViewInterface; @@ -15,6 +17,7 @@ readonly class LayoutProcessor implements LayoutProcessorInterface { public function __construct( + private ContainerInterface $container, private LayoutResolver $layoutResolver, private HandleResolver $handleResolver, private ComponentCollectorInterface $componentCollector, @@ -30,7 +33,7 @@ public function __construct( * @throws SlotNotFoundException * @throws CircularSlotException * @throws LayoutNotFoundException - * @throws AmbiguousSortOrderException + * @throws AmbiguousSortOrderException|ContainerExceptionInterface */ public function process( string $controllerClass, @@ -87,7 +90,7 @@ public function process( * Render all components in a slot and fill any sub-slots they define. * * @param array $routeParameters - * @throws AmbiguousSortOrderException + * @throws AmbiguousSortOrderException|ContainerExceptionInterface */ private function renderSlot( string $slotName, @@ -99,7 +102,7 @@ private function renderSlot( $html = ''; foreach ($slotComponents as $definition) { - $componentInstance = new $definition->className(); + $componentInstance = $this->container->get($definition->className); $data = $this->componentDataResolver->resolve($componentInstance, $routeParameters, $request); $componentHtml = $this->view->renderToString($definition->template, $data); diff --git a/packages/layout/tests/Unit/Helpers.php b/packages/layout/tests/Unit/Helpers.php new file mode 100644 index 00000000..2d755d45 --- /dev/null +++ b/packages/layout/tests/Unit/Helpers.php @@ -0,0 +1,36 @@ +