diff --git a/core-bundle/src/EventListener/DataContainer/ContentCompositionListener.php b/core-bundle/src/EventListener/DataContainer/ContentCompositionListener.php index fc5b04d72f9..7a1cb091ab7 100644 --- a/core-bundle/src/EventListener/DataContainer/ContentCompositionListener.php +++ b/core-bundle/src/EventListener/DataContainer/ContentCompositionListener.php @@ -133,7 +133,7 @@ public function generateArticleForPage(DataContainer $dc): void if ( empty($pageModel->title) || !$this->supportsComposition($pageModel) - || !$this->hasArticlesInLayout($pageModel) + || null === ($column = $this->getArticleColumnInLayout($pageModel)) ) { return; } @@ -167,7 +167,7 @@ public function generateArticleForPage(DataContainer $dc): void 'sorting' => 128, 'tstamp' => time(), 'author' => $user->id, - 'inColumn' => 'main', + 'inColumn' => $column, 'title' => $dc->activeRecord->title, 'alias' => str_replace('/', '-', $dc->activeRecord->alias), // see #516 'published' => $dc->activeRecord->published, @@ -274,6 +274,11 @@ private function supportsComposition(PageModel $pageModel): bool } private function hasArticlesInLayout(PageModel $pageModel): bool + { + return null !== $this->getArticleColumnInLayout($pageModel); + } + + private function getArticleColumnInLayout(PageModel $pageModel): ?string { $pageModel->loadDetails(); @@ -281,15 +286,27 @@ private function hasArticlesInLayout(PageModel $pageModel): bool $layout = $pageModel->getRelated('layout'); if (null === $layout) { - return false; + return null; } + $columns = []; + foreach (StringUtil::deserialize($layout->modules, true) as $config) { if (0 === (int) $config['mod']) { - return true; + $columns[] = $config['col']; } } - return false; + $columns = array_filter(array_unique($columns)); + + if (empty($columns)) { + return null; + } + + if (\in_array('main', $columns, true)) { + return 'main'; + } + + return reset($columns); } } diff --git a/core-bundle/tests/EventListener/DataContainer/ContentCompositionListenerTest.php b/core-bundle/tests/EventListener/DataContainer/ContentCompositionListenerTest.php index 5caa23a1bd4..99f99cc481f 100644 --- a/core-bundle/tests/EventListener/DataContainer/ContentCompositionListenerTest.php +++ b/core-bundle/tests/EventListener/DataContainer/ContentCompositionListenerTest.php @@ -497,6 +497,85 @@ public function testGenerateArticleForNewPage(): void $this->listener->generateArticleForPage($dc); } + /** + * @dataProvider moduleConfigProvider + */ + public function testUsesTheLayoutColumnForNewArticle(array $modules, string $expectedColumn): void + { + $this->expectRequest(true, ['tl_foo' => [17]]); + $this->expectUser(); + $page = $this->expectPageWithRow($this->pageRecord); + $this->mockPageProvider(true, true, $page); + $this->expectArticleCount(0); + + $page + ->expects($this->once()) + ->method('getRelated') + ->with('layout') + ->willReturn( + $this->mockClassWithProperties(LayoutModel::class, ['modules' => serialize($modules)]) + ) + ; + + $article = [ + 'pid' => 17, + 'sorting' => 128, + 'tstamp' => time(), + 'author' => 1, + 'inColumn' => $expectedColumn, + 'title' => 'foo', + 'alias' => 'foo-bar', // Expect folder alias conversion + 'published' => '1', + ]; + + $this->connection + ->expects($this->once()) + ->method('insert') + ->with('tl_article', $article) + ; + + /** @var DataContainer&MockObject $dc */ + $dc = $this->mockClassWithProperties(DC_Table::class, ['id' => 17, 'table' => 'tl_foo', 'activeRecord' => (object) $this->pageRecord]); + + $this->listener->generateArticleForPage($dc); + } + + public function moduleConfigProvider(): \Generator + { + yield [ + [ + ['mod' => 0, 'col' => 'main'], + ], + 'main' + ]; + + yield [ + [ + ['mod' => 1, 'col' => 'foo'], + ['mod' => 0, 'col' => 'main'], + ], + 'main' + ]; + + yield [ + [ + ['mod' => 1, 'col' => 'main'], + ['mod' => 0, 'col' => 'foo'], + ], + 'foo' + ]; + + yield [ + [ + ['mod' => 1, 'col' => 'main'], + ['mod' => 2, 'col' => 'foo'], + ['mod' => 0, 'col' => 'bar'], + ['mod' => 0, 'col' => 'foo'], + ], + 'bar' + ]; + } + public function testCannotPasteArticleWithoutBackendUser(): void { $this->expectUser(FrontendUser::class); @@ -935,7 +1014,7 @@ private function expectPageWithRow(array $row, $moduleId = false): PageModel $moduleId = $this->mockClassWithProperties( LayoutModel::class, [ 'modules' => serialize([ - ['mod' => $moduleId], + ['mod' => $moduleId, 'col' => 'main'], ]), ] ); @@ -978,7 +1057,7 @@ private function expectPageFindByPk(int $id, array $row, $moduleId = false): Pag $moduleId = $this->mockClassWithProperties( LayoutModel::class, [ 'modules' => serialize([ - ['mod' => $moduleId], + ['mod' => $moduleId, 'col' => 'main'], ]), ] );