Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a 'Pass Through URI' Data Converter to JSON-LD: Issue-1581 #45

Merged
merged 4 commits into from
Aug 18, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions src/EntityReferenceConverter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

namespace Drupal\jsonld;

/**
* Converts EntityReferenceField targets.
*/
class EntityReferenceConverter {

/**
* Swaps out an Entity's URI with the value in a field.
*
* @param array|\Drupal\Core\Entity\EntityInterface $target
* Either the target of the entity reference field being converted
* (as the JSON-LD module does) or an array with 'target_id'
* (as the RDF module does).
* @param array $arguments
* An array of arguments defined in the mapping.
* Expected keys are:
* - link_field: The field used to store the URI we will use.
*
* @return mixed
* Either the replaced URI string OR the targeted entity if no URI.
*/
public static function linkFieldPassthrough($target, array $arguments) {
if (is_a($target, 'Drupal\Core\Entity\FieldableEntityInterface') && !empty($target->get($arguments['link_field'])->uri)) {
return $target->get($arguments['link_field'])->uri;
}
// We don't have a value to pass, so don't bother converting.
return $target;
}

}
47 changes: 30 additions & 17 deletions src/Normalizer/EntityReferenceItemNormalizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,9 @@ public function normalize($field_item, $format = NULL, array $context = []) {
$context['included_fields'] = ['uuid'];
$context['needs_jsonldcontext'] = FALSE;
$context['embedded'] = TRUE;
// Normalize the target entity.
// This will call \Drupal\jsonld\Normalizer\ContentEntityNormalizer.
$embedded = $this->serializer->normalize($target_entity, $format, $context);

// The normalized object we will collect entries into.
$normalized_in_context = [];

if (isset($context['current_entity_rdf_mapping'])) {
$values_clean = [];
Expand All @@ -93,25 +93,38 @@ public function normalize($field_item, $format = NULL, array $context = []) {
$field_keys = isset($field_mappings['properties']) ?
$field_mappings['properties'] :
[$field_item->getParent()->getName()];
if (!empty($field_mappings['datatype'])) {
$values_clean['@type'] = $field_mappings['datatype'];
}

// Value in this case is the target entity, so if a callback exists
// it should work against that?
// it should work against that.
if (!empty($field_mappings['datatype_callback'])) {
$callback = $field_mappings['datatype_callback']['callable'];
$arguments = isset($field_mappings['datatype_callback']['arguments']) ? $field_mappings['datatype_callback']['arguments'] : NULL;
$values_clean['@value'] = call_user_func($callback, $target_entity, $arguments);
$transformed_value = call_user_func($callback, $target_entity, $arguments);
// If the config says it is an @id, we'll save it as an @id.
if (!empty($field_mappings['datatype']) && $field_mappings['datatype'] == '@id') {
$values_clean['@id'] = $transformed_value;
$values_clean['@type'] = '@id';
}
// Either we transformed it into another fieldable entity, or got the
// same one back. We will process the fieldable entity later on.
elseif ($transformed_value instanceof FieldableEntityInterface) {
$target_entity = $transformed_value;
}
// Save anything else as a value.
else {
$values_clean['@value'] = $transformed_value;
}
}
// Since getting the to embed entity URL here could be a little bit
// expensive and would require an helper method
// i could just borrow it from the $embed result.
$values_clean['@id'] = key($embedded['@graph']);
// Because having a @type for a reference causes problems, we strip that.
// This could be removed using headers in future.
if (isset($values_clean['@type'])) {
unset($values_clean['@type']);
// Time to process the fieldable entity if we don't have
// an '@id' or '@value'.
if (empty($values_clean['@id']) && empty($values_clean['@value'])) {
// Normalize the target entity.
// This will call \Drupal\jsonld\Normalizer\ContentEntityNormalizer.
$normalized_in_context = $this->serializer->normalize($target_entity, $format, $context);
// Since getting the to embed entity URL here could be a little bit
// expensive and would require an helper method
// i could just borrow it from above.
$values_clean['@id'] = key($normalized_in_context['@graph']);
}

// The returned structure will be recursively merged into the normalized
Expand All @@ -130,7 +143,7 @@ public function normalize($field_item, $format = NULL, array $context = []) {

}

$normalized_in_context = array_merge_recursive($embedded, ['@graph' => [$context['current_entity_id'] => $normalized_prop]]);
$normalized_in_context = array_merge_recursive($normalized_in_context, ['@graph' => [$context['current_entity_id'] => $normalized_prop]]);

return $normalized_in_context;
}
Expand Down
5 changes: 5 additions & 0 deletions tests/src/Functional/JsonldContextGeneratorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ class JsonldContextGeneratorTest extends BrowserTestBase {
'jsonld',
];

/**
* {@inheritdoc}
*/
protected $defaultTheme = 'stark';

/**
* Initial setup tasks that for every method method.
*/
Expand Down
2 changes: 1 addition & 1 deletion tests/src/Kernel/JsonldKernelTestBase.php
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ protected function setUp() {
])->save();

$entity_manager = \Drupal::service('entity_type.manager');
$link_manager = \Drupal::service('rest.link_manager');
$link_manager = \Drupal::service('hal.link_manager');
$uuid_resolver = \Drupal::service('serializer.entity_resolver.uuid');
$chain_resolver = new ChainEntityResolver([$uuid_resolver, new TargetIdResolver()]);

Expand Down