DefaultFieldProcessor.php

Namespace

Drupal\tmgmt_content

File

sources/content/src/DefaultFieldProcessor.php
View source
<?php

namespace Drupal\tmgmt_content;

use Drupal\Core\Render\Element;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\TypedData\DataReferenceDefinitionInterface;
use Drupal\Core\TypedData\OptionsProviderInterface;
use Drupal\Core\TypedData\PrimitiveInterface;
use Drupal\Core\TypedData\Type\StringInterface;
use Drupal\Core\TypedData\TypedDataInterface;
use Drupal\file\FileInterface;

/**
 * Default field processor.
 */
class DefaultFieldProcessor implements FieldProcessorInterface {

  /**
   * {@inheritdoc}
   */
  public function extractTranslatableData(FieldItemListInterface $field) {
    $data = array();

    /* @var \Drupal\Core\Field\FieldItemInterface $field_item */
    $field_definition = $field
      ->getFieldDefinition();
    foreach ($field as $delta => $field_item) {
      $format = NULL;
      $translatable_properties = 0;
      foreach ($field_item
        ->getProperties(TRUE) as $property_key => $property) {
        $property_definition = $property
          ->getDataDefinition();
        $translate = $this
          ->shouldTranslateProperty($property);
        if ($property_definition instanceof DataReferenceDefinitionInterface && $property_definition
          ->getTargetDefinition()
          ->getDataType() == 'entity:file') {
          $target = $property
            ->getValue();
          if ($target instanceof FileInterface) {
            $config = \Drupal::config('tmgmt.settings');
            if (in_array($target
              ->getMimeType(), (array) $config
              ->get('file_mimetypes'))) {
              $translate = TRUE;
              $data[$delta][$property_key] = [
                '#label' => t('File'),
                '#file' => $target
                  ->id(),
                '#translate' => $translate,
              ];
            }
          }
        }

        // Ignore values that are not primitives and other computed properties.
        if (!$property instanceof PrimitiveInterface || $property_definition
          ->isComputed()) {
          continue;
        }

        // All the labels are here, to make sure we don't have empty labels in
        // the UI because of no data.
        if ($translate === TRUE) {
          $data['#label'] = $field_definition
            ->getLabel();
          if (count($field) > 1) {

            // More than one item, add a label for the delta.
            $data[$delta]['#label'] = t('Delta #@delta', array(
              '@delta' => $delta,
            ));
          }
        }
        $data[$delta][$property_key] = array(
          '#label' => $property_definition
            ->getLabel(),
          '#text' => $property
            ->getValue(),
          '#translate' => $translate,
        );
        $translatable_properties += (int) $translate;
        if ($translate && $field_item
          ->getFieldDefinition()
          ->getFieldStorageDefinition()
          ->getSetting('max_length') != 0) {
          $data[$delta][$property_key]['#max_length'] = $field_item
            ->getFieldDefinition()
            ->getFieldStorageDefinition()
            ->getSetting('max_length');
        }
        if ($property_definition
          ->getDataType() == 'filter_format') {
          $format = $property
            ->getValue();
        }
      }
      if (!empty($format)) {
        $data = $this
          ->handleFormat($format, $data, $delta);
      }

      // If there is only one translatable property, remove the label for it.
      if ($translatable_properties <= 1 && !empty($data)) {
        foreach (Element::children($data[$delta]) as $property_key) {
          unset($data[$delta][$property_key]['#label']);
        }
      }
    }
    return $data;
  }

  /**
   * {@inheritdoc}
   */
  public function setTranslations($field_data, FieldItemListInterface $field) {
    foreach (Element::children($field_data) as $delta) {
      $field_item = $field_data[$delta];
      foreach (Element::children($field_item) as $property) {
        $property_data = $field_item[$property];

        // If there is translation data for the field property, save it.
        if ((isset($property_data['#translation']['#text']) || isset($property_data['#translation']['#file'])) && $property_data['#translate']) {
          $translation_key = isset($property_data['#translation']['#text']) ? '#text' : '#file';

          // If the offset does not exist, populate it with the current value
          // from the source content, so that the translated field offset can be
          // saved.
          if (!$field
            ->offsetExists($delta)) {
            $translation = $field
              ->getEntity();
            $source = $translation
              ->getUntranslated();
            $source_field = $source
              ->get($field
              ->getName());
            $source_offset = $source_field
              ->offsetGet($delta);

            // Note that the source language value will be immediately
            // overwritten.
            $field
              ->offsetSet($delta, $source_offset);
          }
          $field
            ->offsetGet($delta)
            ->set($property, $property_data['#translation'][$translation_key]);
        }
      }
    }
  }

  /**
   * Returns whether the property should be translated or not.
   *
   * @param \Drupal\Core\TypedData\TypedDataInterface $property
   *   The field property to check.
   *
   * @return bool
   *   TRUE if the property should be translated, FALSE otherwise.
   */
  protected function shouldTranslateProperty(TypedDataInterface $property) {

    // Ignore properties with limited allowed values or if they're not strings.
    if ($property instanceof OptionsProviderInterface || !$property instanceof StringInterface) {
      return FALSE;
    }
    return TRUE;
  }

  /**
   * Handles adjusting the field item data if a format was detected.
   *
   * @param string $format
   *   The text format.
   * @param array $data
   *   The extracted field data.
   * @param int $delta
   *   The field item delta.
   *
   * @return array
   *   The adjusted field data.
   */
  protected function handleFormat($format, $data, $delta) {
    $allowed_formats = (array) \Drupal::config('tmgmt.settings')
      ->get('allowed_formats');
    if ($allowed_formats && array_search($format, $allowed_formats) === FALSE) {

      // There are allowed formats and this one is not part of them,
      // explicitly mark all data as untranslatable.
      foreach ($data[$delta] as $name => $value) {
        if (is_array($value) && isset($value['#translate'])) {
          $data[$delta][$name]['#translate'] = FALSE;
        }
      }
    }
    else {

      // Add the format to the translatable properties.
      foreach ($data[$delta] as $name => $value) {
        if (is_array($value) && isset($value['#translate']) && $value['#translate'] == TRUE) {
          $data[$delta][$name]['#format'] = $format;
        }
      }
    }
    return $data;
  }

}

Classes

Namesort descending Description
DefaultFieldProcessor Default field processor.