diff --git a/src/ComponentPluginManager.php b/src/ComponentPluginManager.php index c2e42d28d50c804b3017b7e9e819d0b4e5963462..d3cb845c3a78734e0c341043f4c5723f9b6c304e 100644 --- a/src/ComponentPluginManager.php +++ b/src/ComponentPluginManager.php @@ -239,12 +239,7 @@ class ComponentPluginManager extends SdcPluginManager implements CategorizingPlu protected function annotateProp(string $prop_id, array $prop, string $fallback_prop_type_id): array { $prop["title"] = $prop["title"] ?? $prop_id; - if (isset($prop['$ref']) && str_starts_with($prop['$ref'], "ui-patterns://") === FALSE) { - // We need to resolve non ui-patterns before guessFromSchema. - // To load refs including "ui-patterns" leads to wrong type mapping. - // So we load ui patterns refs in a second step. - $prop = $this->referencesSolver->resolve($prop); - } + $this->resolveJsonSchemaReference($prop); $prop_type = $this->propTypePluginManager->guessFromSchema($prop); if ($prop_type->getPluginId() === $fallback_prop_type_id) { // Sometimes, a prop JSON schema is different enough to not be caught by @@ -273,6 +268,19 @@ class ComponentPluginManager extends SdcPluginManager implements CategorizingPlu return $prop; } + /** + * Resolve a JSON schema reference. + */ + protected function resolveJsonSchemaReference(array &$prop) : void { + if (isset($prop['$ref']) && str_starts_with($prop['$ref'], "ui-patterns://") === FALSE) { + // We need to resolve non ui-patterns before guessFromSchema. + // To load refs including "ui-patterns" leads to wrong type mapping. + // So we load ui patterns refs in a second step. + // @todo improve error handling and logging? + $prop = $this->referencesSolver->resolve($prop); + } + } + /** * Add attributes prop. * diff --git a/src/SchemaManager/ReferencesResolver.php b/src/SchemaManager/ReferencesResolver.php index f3295c1aff6967e12c4c6af36ec4fe04f3b928e6..308d4013dcd92feeac9694c2a400df5508e66d2f 100644 --- a/src/SchemaManager/ReferencesResolver.php +++ b/src/SchemaManager/ReferencesResolver.php @@ -5,7 +5,9 @@ declare(strict_types=1); namespace Drupal\ui_patterns\SchemaManager; use JsonSchema\Constraints\BaseConstraint; +use JsonSchema\Exception\RuntimeException; use JsonSchema\SchemaStorage; +use Psr\Log\LoggerInterface; /** * JSON Schema References resolver. @@ -18,6 +20,14 @@ class ReferencesResolver { const MAXIMUM_RECURSIVITY_LEVEL = 10; + /** + * Constructs a ComponentElementBuilder. + */ + public function __construct( + protected LoggerInterface $logger, + ) { + } + /** * Resolve schema references recursively. */ @@ -28,7 +38,17 @@ class ReferencesResolver { $depth = $depth + 1; $schema = BaseConstraint::arrayToObjectRecursive($schema); $storage = new SchemaStorage(); - $schema = (array) $storage->resolveRefSchema($schema); + try { + $schema = (array) $storage->resolveRefSchema($schema); + } + catch (RuntimeException $e) { + $schema = (array) $schema; + $this->logger->error(t("Could not resolve schema referenced by \$ref property '@ref': @error", [ + "@ref" => $schema['$ref'] ?? '', + "@error" => $e->getMessage(), + ])); + + } foreach ($schema as $key => $value) { if (!is_object($value)) { continue; diff --git a/tests/src/Kernel/SchemaManagerTest.php b/tests/src/Kernel/SchemaManagerTest.php index f8759fdec1f1a6e1b1ab1060c9501c3660168804..92bf80972796407d23d2446913167bac13ae0df0 100644 --- a/tests/src/Kernel/SchemaManagerTest.php +++ b/tests/src/Kernel/SchemaManagerTest.php @@ -6,7 +6,6 @@ namespace Drupal\Tests\ui_patterns\Kernel; use Drupal\Component\Serialization\Yaml; use Drupal\KernelTests\KernelTestBase; -use Drupal\ui_patterns\SchemaManager\ReferencesResolver; /** * Test SchemaManager parts. @@ -40,7 +39,7 @@ final class SchemaManagerTest extends KernelTestBase { * @dataProvider provideResolveData */ public function testResolve(array $schema, array $expected): void { - $resolver = new ReferencesResolver(); + $resolver = \Drupal::service("ui_patterns.schema_reference_solver"); $result = $resolver->resolve($schema); // Skipping everything under patternProperties keys diff --git a/ui_patterns.services.yml b/ui_patterns.services.yml index fc03ba97b7e551760eee99f5ca889bee305288c5..154e8d253e0de5bc31e2692a6f5232a9d27394ff 100644 --- a/ui_patterns.services.yml +++ b/ui_patterns.services.yml @@ -68,6 +68,8 @@ services: class: Drupal\ui_patterns\SchemaManager\Canonicalizer ui_patterns.schema_reference_solver: class: Drupal\ui_patterns\SchemaManager\ReferencesResolver + arguments: + - "@logger.channel.ui_patterns" # Others. ui_patterns.twig.extension: