bibcite-8.x-1.x-dev/modules/bibcite_entity/src/Normalizer/CslReferenceNormalizer.php

modules/bibcite_entity/src/Normalizer/CslReferenceNormalizer.php
<?php

namespace Drupal\bibcite_entity\Normalizer;

use Drupal\bibcite_entity\Entity\ReferenceInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Symfony\Component\Serializer\Exception\LogicException;

/**
 * Normalizes/denormalizes reference entity to CSL format.
 */
class CslReferenceNormalizer extends ReferenceNormalizerBase {

  /**
   * List of date fields.
   *
   * @var array
   */
  protected $dateFields = [
    'bibcite_year',
    'bibcite_access_date',
    'bibcite_date',
  ];

  /**
   * {@inheritdoc}
   */
  public function supportsDenormalization(mixed $data, string $type, ?string $format = null, array $context = []): bool {
    return FALSE;
  }

  /**
   * {@inheritdoc}
   */
  public function denormalize($data, $class, $format = NULL, array $context = []): mixed {
    throw new LogicException("Cannot denormalize from 'CSL' format.");
  }

  /**
   * {@inheritdoc}
   */
  public function normalize($object, $format = NULL, array $context = []): array|string|int|float|bool|\ArrayObject|NULL {
    /** @var \Drupal\bibcite_entity\Entity\ReferenceInterface $object */

    $attributes = parent::normalize($object, $format, $context);

    $contributor_key = $this->getContributorKey();
    if (isset($attributes[$contributor_key])) {
      $authors = $attributes[$contributor_key];
      foreach ($authors as $role => $contributors) {
        $attributes[$role] = $contributors;
      }

      // Clear out the original data for contributors unless it was already
      // overwritten from above. This is necessary to prevent citeproc from
      // parsing the original data which has an embedded list of contributors
      // keyed by type and is not valid for its parser.
      if (!array_key_exists($contributor_key, $authors)) {
        $attributes[$contributor_key] = [];
      }
    }

    return $attributes;
  }

  /**
   * {@inheritdoc}
   */
  protected function extractFields(ReferenceInterface $reference, $format = NULL) {
    $attributes = [];

    $attributes['title'] = $this->extractScalar($reference->get('title'));
    foreach ($this->fieldsMapping[$this->format] as $csl_field => $entity_field) {
      if ($entity_field && $reference->hasField($entity_field) && ($field = $reference->get($entity_field)) && !$field->isEmpty()) {
        if (in_array($entity_field, $this->dateFields)) {
          $attributes[$csl_field] = $this->extractDate($field);
        }
        else {
          $attributes[$csl_field] = $this->extractScalar($field);
        }
      }
    }

    return $attributes;
  }

  /**
   * Extract authors values from field.
   *
   * @param \Drupal\Core\Field\FieldItemListInterface $field_item_list
   *   List of field items.
   *
   * @return array
   *   Authors in CSL format.
   */
  protected function extractAuthors(FieldItemListInterface $field_item_list) {
    $authors = [];

    foreach ($field_item_list as $field) {
      /** @var \Drupal\bibcite_entity\Entity\ContributorInterface $contributor */
      if ($contributor = $field->entity) {
        switch ($field->role) {
          case 'editor':
          case 'series_editor':
            $authors['editor'][] = [
              'category' => $field->category,
              'role' => $field->role,
              'family' => $contributor->getLastName(),
              'given' => $this->getGivenName($contributor->getFirstName(), $contributor->getMiddleName()),
              'suffix' => $contributor->getSuffix(),
              'literal' => $contributor->getName(),
              // @todo Implement other fields.
            ];
            break;

          case 'recipient':
          case 'translator':
            $authors[$field->role][] = [
              'category' => $field->category,
              'role' => $field->role,
              'family' => $contributor->getLastName(),
              'given' => $this->getGivenName($contributor->getFirstName(), $contributor->getMiddleName()),
              'suffix' => $contributor->getSuffix(),
              'literal' => $contributor->getName(),
              // @todo Implement other fields.
            ];
            break;

          default:
            $authors['author'][] = [
              'category' => $field->category,
              'role' => $field->role,
              'family' => $contributor->getLastName(),
              'given' => $this->getGivenName($contributor->getFirstName(), $contributor->getMiddleName()),
              'suffix' => $contributor->getSuffix(),
              'literal' => $contributor->getName(),
              // @todo Implement other fields.
            ];
            break;
        }
      }
    }

    return $authors;
  }

  /**
   * Create properly formatted given name for processors.
   */
  protected function getGivenName($first, $middle) {
    $separator = '';
    // Processors expect a space between first and middle name if both present.
    if (!empty($first) && !empty($middle)) {
      $separator = ' ';
    }
    return trim($first . $separator . $middle);
  }

  /**
   * Extract date value to CSL format.
   *
   * @param \Drupal\Core\Field\FieldItemListInterface $date_field
   *   Date item list.
   *
   * @return array
   *   Date in CSL format.
   */
  protected function extractDate(FieldItemListInterface $date_field) {
    $value = $this->extractScalar($date_field);

    return [
      'date-parts' => [
        array_reverse(explode('/', $value)),
      ],
      'literal' => $value,
    ];
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc