Parent, child, part of the reason (null = allowed). */ public static function placements(): array { $section = static fn (string $type): Block => Block::create( 'divi/section', ['module' => ['advanced' => ['type' => ['desktop' => ['value' => $type]]]]] ); return [ 'section on top' => [null, 'divi/section', null], 'module on top' => [null, 'divi/text', 'oberster Ebene'], 'unknown module' => [Block::create('divi/column'), 'divi/slider-pro', 'unbekanntes Modul'], 'row in a section' => [Block::create('divi/section'), 'divi/row', null], 'module in a section' => [Block::create('divi/section'), 'divi/text', 'Zeilen'], 'fullwidth module in a fullwidth section' => [$section('fullwidth'), 'divi/fullwidth-header', null], 'row in a fullwidth section' => [$section('fullwidth'), 'divi/row', 'fullwidth-Module'], 'anything in a specialty section' => [$section('specialty'), 'divi/row', 'Spezialabschnitte'], 'column in a row' => [Block::create('divi/row'), 'divi/column', 'Spalten entstehen mit der Zeile'], 'module in a column' => [Block::create('divi/column'), 'divi/button', null], 'row in a column (nestable)' => [Block::create('divi/column'), 'divi/row', null], 'row in a group' => [Block::create('divi/group'), 'divi/row', 'passt nicht'], 'module in a specialty column' => [ Block::create('divi/column', ['module' => ['advanced' => ['specialtyColumns' => ['desktop' => ['value' => '2']]]]]), 'divi/text', 'Spezial', ], 'module in a column holding inner rows' => [ Block::create('divi/column', [], [Block::create('divi/row-inner')]), 'divi/text', 'Spezial', ], 'group in a column' => [Block::create('divi/column'), 'divi/group', null], 'module in a group' => [Block::create('divi/group'), 'divi/text', null], 'fullwidth module in a column' => [Block::create('divi/column'), 'divi/fullwidth-header', 'passt nicht'], 'child module in a column' => [Block::create('divi/column'), 'divi/accordion-item', 'passt nicht'], 'section in a column' => [Block::create('divi/column'), 'divi/section', 'passt nicht'], 'item in its parent' => [Block::create('divi/accordion'), 'divi/accordion-item', null], 'other module in a parent' => [Block::create('divi/accordion'), 'divi/text', 'erlaubt nur divi/accordion-item'], 'child in a plain module' => [Block::create('divi/text'), 'divi/button', 'keine Kind-Module'], 'opaque parent' => [Block::parsed('divi/column', [], '', false, true), 'divi/text', 'nur lesbar'], 'foreign parent' => [Block::create('core/group'), 'divi/text', 'nur lesbar'], ]; } /** @dataProvider placements */ public function testWhatGoesWhere(?Block $parent, string $child, ?string $reason): void { $violation = ComposeFixture::rules()->violation($parent, $child); if ($reason === null) { self::assertNull($violation); } else { self::assertIsString($violation); self::assertStringContainsString($reason, $violation); } } public function testPlainModules(): void { $rules = ComposeFixture::rules(); self::assertTrue($rules->isPlainModule('divi/button')); self::assertFalse($rules->isPlainModule('divi/fullwidth-header')); self::assertFalse($rules->isPlainModule('divi/accordion-item')); self::assertFalse($rules->isPlainModule('divi/row')); } /** F22: Divi renders divi/post-content only in body layouts (appearance.themeBuilderLayouts). */ public function testModulesLimitedToThemeBuilderAreas(): void { $catalog = DiviFixtures::catalog(); $column = Block::create('divi/column'); self::assertNull((new StructureRules($catalog, 'body'))->violation($column, 'divi/post-content')); self::assertSame( 'divi/post-content zeigt Divi im Bereich „header“ nicht (nur body)', (new StructureRules($catalog, 'header'))->violation($column, 'divi/post-content') ); self::assertNull((new StructureRules($catalog))->violation($column, 'divi/post-content'), 'pages: Divi decides'); self::assertNull((new StructureRules($catalog, 'footer'))->violation($column, 'divi/text')); } }