)|null $wpBlocks null = parse_blocks(). */ public function __construct(private ?string $file = null, private ?Closure $wpBlocks = null) { } /** @return list */ public function problems(): array { $file = $this->file ?? self::REFERENCE; // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents -- local plugin file. $content = is_file($file) ? file_get_contents($file) : false; if (! is_string($content) || $content === '') { return ['Der Referenzinhalt der Prüfung fehlt im Plugin.']; } $document = (new Parser())->parse($content); $problems = []; if (Serializer::document($document) !== $content) { $problems[] = 'Parser und Serializer geben den Referenzinhalt nicht byte-gleich zurück.'; } $wordPress = ($this->wpBlocks ?? static fn (string $markup): array => parse_blocks($markup))($content); if (self::structure($document->children()) !== self::wpStructure($wordPress)) { $problems[] = 'WordPress liest eine andere Blockstruktur als LIT MCP.'; } return $problems; } /** * @param list $blocks * @return list}> */ private static function structure(array $blocks): array { return array_map( static fn (Block $block): array => [$block->name(), self::structure($block->children())], $blocks ); } /** * @param array $blocks parse_blocks() result; freeform parts (blockName null) are left out. * @return list}> */ private static function wpStructure(array $blocks): array { $structure = []; foreach ($blocks as $block) { if (is_array($block) && is_string($block['blockName'] ?? null)) { $inner = is_array($block['innerBlocks'] ?? null) ? $block['innerBlocks'] : []; $structure[] = [$block['blockName'], self::wpStructure($inner)]; } } return $structure; } }