Skip to content
This repository has been archived by the owner on Jul 27, 2022. It is now read-only.

Commit

Permalink
ISAICP-3576: Limit field items by cardinality.
Browse files Browse the repository at this point in the history
  • Loading branch information
claudiu-cristea committed Feb 18, 2021
1 parent 780198f commit 548defc
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 12 deletions.
32 changes: 20 additions & 12 deletions src/SparqlEntityStorage.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Language\LanguageInterface;
use Drupal\Core\Language\LanguageManagerInterface;
use Drupal\field\FieldStorageConfigInterface;
use Drupal\sparql_entity_storage\Driver\Database\sparql\ConnectionInterface;
use Drupal\sparql_entity_storage\Entity\Query\Sparql\SparqlArg;
use Drupal\sparql_entity_storage\Entity\SparqlGraph;
Expand Down Expand Up @@ -394,27 +395,33 @@ protected function processResults(array $triples, array $graph_ids, array $graph
foreach (array_diff_key($entity, array_flip($processed_fields)) as $predicate => $languages) {
// Complex field with field predicate.
if ($field_name = $this->fieldHandler->getFieldNameByPredicate($entity_type_id, $bundle, $predicate)) {
$cardinality = $this->fieldHandler->getFieldCardinality($entity_type_id, $field_name);
foreach ($languages as $langcode => $values) {
foreach ($values as $delta => $item) {
foreach ($item as $column_predicate => $value) {
$column_name = $this->fieldHandler->getColumnNameByPredicate($entity_type_id, $bundle, $column_predicate);
$entity[$field_name][$langcode][$delta][$column_name] = $this->fieldHandler->getInboundValue($entity_type_id, $field_name, $value, $langcode, $column_name, $bundle);
if ($cardinality === FieldStorageConfigInterface::CARDINALITY_UNLIMITED || $delta < $cardinality) {
foreach ($item as $column_predicate => $value) {
$column_name = $this->fieldHandler->getColumnNameByPredicate($entity_type_id, $bundle, $column_predicate);
$entity[$field_name][$langcode][$delta][$column_name] = $this->fieldHandler->getInboundValue($entity_type_id, $field_name, $value, $langcode, $column_name, $bundle);
}
}
}
}
}
// Simple column mappings.
elseif ($column_name = $this->fieldHandler->getColumnNameByPredicate($entity_type_id, $bundle, $predicate)) {
$field_name = $this->fieldHandler->getColumnFieldNameByPredicate($entity_type_id, $bundle, $predicate);
$cardinality = $this->fieldHandler->getFieldCardinality($entity_type_id, $field_name);
foreach ($languages as $langcode => $values) {
foreach ($values as $delta => $value) {
$entity[$field_name][$langcode][$delta][$column_name] = $this->fieldHandler->getInboundValue($entity_type_id, $field_name, $value, $langcode, $column_name, $bundle);
if ($cardinality === FieldStorageConfigInterface::CARDINALITY_UNLIMITED || $delta < $cardinality) {
$entity[$field_name][$langcode][$delta][$column_name] = $this->fieldHandler->getInboundValue($entity_type_id, $field_name, $value, $langcode, $column_name, $bundle);
}
}
}
}

// Remove the already processed fields but also the arbitrary values
// no covered by the Drupal entity/field API.
// Remove already processed fields but also the arbitrary values, not
// covered by the Drupal entity/field API.
unset($entity[$predicate]);
}
});
Expand Down Expand Up @@ -915,6 +922,7 @@ protected function purgeFieldItems(ContentEntityInterface $entity, FieldDefiniti
*/
protected function doSave($id, EntityInterface $entity) {
/** @var \Drupal\Core\Entity\ContentEntityInterface $entity */
$entity_type_id = $this->getEntityTypeId();
$bundle = $entity->bundle();
// Generate an ID before saving, if none is available. If the ID generation
// occurs earlier in the process (like on EntityInterface::create()), the
Expand All @@ -931,15 +939,15 @@ protected function doSave($id, EntityInterface $entity) {
// If the graph is not specified, fallback to the default one for the entity
// type.
if ($entity->get('graph')->isEmpty()) {
$entity->set('graph', $this->getGraphHandler()->getDefaultGraphId($this->getEntityTypeId()));
$entity->set('graph', $this->getGraphHandler()->getDefaultGraphId($entity_type_id));
}

$graph_id = $entity->get('graph')->target_id;
$graph_uri = $this->getGraphHandler()->getBundleGraphUri($entity->getEntityTypeId(), $entity->bundle(), $graph_id);
$graph_uri = $this->getGraphHandler()->getBundleGraphUri($entity_type_id, $bundle, $graph_id);
$graph = self::getGraph($graph_uri);
$lang_array = $this->toLangArray($entity);
foreach ($lang_array as $field_name => $langcode_data) {
$field_predicate = $this->fieldHandler->getFieldPredicate($this->getEntityTypeId(), $field_name);
$field_predicate = $this->fieldHandler->getFieldPredicate($entity_type_id, $field_name);
foreach ($langcode_data as $langcode => $field_item_list) {
foreach ($field_item_list as $delta => $field_item) {
// This is a multi-value field, we store the subsequent field item
Expand All @@ -956,12 +964,12 @@ protected function doSave($id, EntityInterface $entity) {
foreach ($field_item as $column => $value) {
// Filter out empty values or non mapped fields. The ID is also
// excluded as it is not mapped.
if ($value === NULL || $value === '' || !$this->fieldHandler->hasFieldPredicate($this->getEntityTypeId(), $bundle, $field_name, $column)) {
if ($value === NULL || $value === '' || !$this->fieldHandler->hasFieldPredicate($entity_type_id, $bundle, $field_name, $column)) {
continue;
}
$predicate = $this->fieldHandler->getFieldColumnPredicates($this->getEntityTypeId(), $field_name, $column, $bundle);
$predicate = $this->fieldHandler->getFieldColumnPredicates($entity_type_id, $field_name, $column, $bundle);
$predicate = reset($predicate);
$value = $this->fieldHandler->getOutboundValue($this->getEntityTypeId(), $field_name, $value, $langcode, $column, $bundle);
$value = $this->fieldHandler->getOutboundValue($entity_type_id, $field_name, $value, $langcode, $column, $bundle);
if ($field_predicate) {
$graph->add($bnode_id, $predicate, $value);
}
Expand Down
10 changes: 10 additions & 0 deletions src/SparqlEntityStorageFieldHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
* label:
* type: string
* main_property: value
* cardinality: 1
* predicate: null
* columns:
* value:
Expand All @@ -52,6 +53,7 @@
* other_field:
* type: entity_reference
* main_property: target_id
* cardinality: -1
* predicate: http://example.com/reference
* ...
* other_entity_type:
Expand Down Expand Up @@ -214,6 +216,7 @@ protected function buildEntityTypeProperties($entity_type_id) {

$this->outboundMap[$entity_type_id]['fields'][$field_name]['type'] = $field_definition->getType();
$this->outboundMap[$entity_type_id]['fields'][$field_name]['main_property'] = $field_storage_definition->getMainPropertyName();
$this->outboundMap[$entity_type_id]['fields'][$field_name]['cardinality'] = $field_storage_definition->getCardinality();
if ($is_multi_value = $field_storage_definition->isMultiple()) {
if (empty($field_mapping['field'])) {
@trigger_error('Missing a field-level predicate mapping for multi-value fields is deprecated in sparql_entity_storage:8.x-1.0-alpha9. The field-level predicate mapping for multi-value fields is mandatory in sparql_entity_storage:8.x-1.0-beta1.', E_USER_DEPRECATED);
Expand Down Expand Up @@ -468,6 +471,13 @@ public function getFieldPredicate(string $entity_type_id, string $field_name): ?
return $this->getOutboundMap($entity_type_id)['fields'][$field_name]['predicate'] ?? NULL;
}

/**
* {@inheritdoc}
*/
public function getFieldCardinality(string $entity_type_id, string $field_name): int {
return $this->getOutboundMap($entity_type_id)['fields'][$field_name]['cardinality'];
}

/**
* {@inheritdoc}
*/
Expand Down
13 changes: 13 additions & 0 deletions src/SparqlEntityStorageFieldHandlerInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,19 @@ public function fieldIsMapped(string $entity_type_id, string $field_name): bool;
*/
public function getFieldPredicate(string $entity_type_id, string $field_name): ?string;

/**
* Returns the field cardinality.
*
* @param string $entity_type_id
* The entity type ID.
* @param string $field_name
* The field name.
*
* @return int
* The field cardinality.
*/
public function getFieldCardinality(string $entity_type_id, string $field_name): int;

/**
* Returns all field predicates for a given entity type.
*
Expand Down

0 comments on commit 548defc

Please sign in to comment.