View source
<?php
namespace Drupal\bibcite_entity\Normalizer;
use Drupal\bibcite_entity\Entity\Contributor;
use Drupal\bibcite_entity\Entity\Keyword;
use Drupal\bibcite_entity\Entity\ReferenceInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Entity\EntityTypeRepositoryInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Url;
use Drupal\serialization\Normalizer\EntityNormalizer;
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
abstract class ReferenceNormalizerBase extends EntityNormalizer {
const DEFAULT_REF_TYPE = 'miscellaneous';
protected $format;
public function setFormat($format) {
$this->format = $format;
foreach ((array) $this->format as $format) {
$config_name = sprintf('bibcite_entity.mapping.%s', $format);
$config = $this->configFactory
->get($config_name);
$this->fieldsMapping[$format] = $config
->get('fields');
$this->typesMapping[$format] = $config
->get('types');
}
}
public $defaultType;
protected $typesMapping;
protected $fieldsMapping;
protected $supportedInterfaceOrClass = [
'Drupal\\bibcite_entity\\Entity\\ReferenceInterface',
];
protected $configFactory;
public $contributorKey = NULL;
public $keywordKey = NULL;
public $typeKey = 'type';
public function __construct(EntityTypeManagerInterface $entity_manager, ConfigFactoryInterface $config_factory, EntityTypeRepositoryInterface $entity_type_repository, EntityFieldManagerInterface $entity_field_manager) {
parent::__construct($entity_manager, $entity_type_repository, $entity_field_manager);
$this->configFactory = $config_factory;
}
protected function getContributorKey() {
return $this->contributorKey;
}
protected function getKeywordKey() {
return $this->keywordKey;
}
protected function getTypeKey() {
return $this->typeKey;
}
public function denormalize($data, $class, $format = NULL, array $context = []) {
$contributor_key = $this
->getContributorKey();
if (!empty($data[$contributor_key])) {
$contributors = (array) $data[$contributor_key];
unset($data[$contributor_key]);
}
$keyword_key = $this
->getKeywordKey();
if (!empty($data[$keyword_key])) {
$keywords = (array) $data[$keyword_key];
unset($data[$keyword_key]);
}
$type_key = $this
->getTypeKey();
if (empty($data[$type_key])) {
throw new UnexpectedValueException("Reference type is incorrect or not set.");
}
$reference_type = $data[$type_key];
$converted_type = $this
->convertFormatType($reference_type, $format);
if (!$converted_type) {
$url = Url::fromRoute('bibcite_entity.mapping', [
'bibcite_format' => $format,
])
->toString();
throw new UnexpectedValueException("'{$reference_type}' type is not mapped to reference type. <a href='{$url}'>Check mapping configuration</a>.");
}
unset($data[$type_key]);
$data = $this
->convertKeys($data, $format);
$data['type'] = $converted_type;
$entity = parent::denormalize($data, $class, $format, $context);
if (!empty($contributors)) {
$author_field = $entity
->get('author');
foreach ($contributors as $name) {
$author_field
->appendItem($this->serializer
->denormalize([
'name' => [
[
'value' => $name,
],
],
], Contributor::class, $format, $context));
}
}
if (!empty($keywords)) {
$keyword_field = $entity
->get('keywords');
foreach ($keywords as $keyword) {
$keyword_field
->appendItem($this->serializer
->denormalize([
'name' => [
[
'value' => $keyword,
],
],
], Keyword::class, $format, $context));
}
}
return $entity;
}
protected function convertEntityType($type, $format) {
$types_mapping = array_flip(array_filter($this->typesMapping[$format]));
return isset($types_mapping[$type]) ? $types_mapping[$type] : $this->defaultType;
}
protected function convertFormatType($type, $format) {
if (isset($this->typesMapping[$format][$type])) {
return $this->typesMapping[$format][$type];
}
elseif (isset($this->typesMapping[$format][$this->defaultType])) {
return $this->typesMapping[$format][$this->defaultType];
}
return self::DEFAULT_REF_TYPE;
}
protected function extractFields(ReferenceInterface $reference, $format) {
$attributes = [];
foreach ($this->fieldsMapping[$format] as $format_field => $entity_field) {
if ($entity_field && $reference
->hasField($entity_field) && ($field = $reference
->get($entity_field)) && !$field
->isEmpty()) {
$attributes[$format_field] = $this
->extractScalar($field);
}
}
return $attributes;
}
protected function extractKeywords(FieldItemListInterface $field_item_list) {
$keywords = [];
foreach ($field_item_list as $field) {
$keywords[] = $field->entity
->label();
}
return $keywords;
}
protected function extractAuthors(FieldItemListInterface $field_item_list) {
$authors = [];
foreach ($field_item_list as $field) {
$authors[] = $field->entity
->getName();
}
return $authors;
}
protected function extractScalar(FieldItemListInterface $scalar_field) {
return $scalar_field->value;
}
protected function convertKeys(array $data, $format) {
$converted = [];
foreach ($data as $key => $field) {
if (!empty($this->fieldsMapping[$format][$key])) {
$converted_key = empty($this->fieldsMapping[$format][$key]) ? $key : $this->fieldsMapping[$format][$key];
$converted[$converted_key] = [
$field,
];
}
}
return $converted;
}
public function normalize($reference, $format = NULL, array $context = []) {
$attributes = [];
$attributes[$this->typeKey] = $this
->convertEntityType($reference
->bundle(), $format);
if ($keywords = $this
->extractKeywords($reference
->get('keywords'))) {
$attributes[$this->keywordKey] = $keywords;
}
if ($authors = $this
->extractAuthors($reference
->get('author'))) {
$attributes[$this->contributorKey] = $authors;
}
$attributes += $this
->extractFields($reference, $format);
return $attributes;
}
}