You are here

class ContactStorageExportService in Contact Storage Export 8

Provides a set of methods to export contact messages in CSV format.

Hierarchy

Expanded class hierarchy of ContactStorageExportService

1 string reference to 'ContactStorageExportService'
contact_storage_export.services.yml in ./contact_storage_export.services.yml
contact_storage_export.services.yml
1 service uses ContactStorageExportService
contact_storage_export.exporter in ./contact_storage_export.services.yml
Drupal\contact_storage_export\ContactStorageExportService

File

src/ContactStorageExportService.php, line 20

Namespace

Drupal\contact_storage_export
View source
class ContactStorageExportService implements ContainerInjectionInterface {

  /**
   * The CSV encoder.
   *
   * @var \Drupal\csv_serialization\Encoder\CsvEncoder
   */
  protected $csvEncoder;

  /**
   * The renderer.
   *
   * @var \Drupal\Core\Render\RendererInterface
   */
  protected $renderer;

  /**
   * Creates a new ContactStorageExportService object.
   *
   * @param \Drupal\csv_serialization\Encoder\CsvEncoder $csv_encoder
   *   The CSV encoder.
   * @param \Drupal\Core\Render\RendererInterface $renderer
   *   The renderer.
   */
  public function __construct(CsvEncoder $csv_encoder, RendererInterface $renderer) {
    $this->csvEncoder = $csv_encoder;
    $this->renderer = $renderer;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static($container
      ->get('csv_serialization.encoder.csv'), $container
      ->get('renderer'));
  }

  /**
   * Returns a serialized message.
   *
   * @param \Drupal\contact\MessageInterface $message
   *   The message to serialize.
   * @param string[] $settings
   *   (optional) A settings array containing:
   *     - columns (A list of columns/fields to include)
   *     - date_format (Format to use with date fields)
   *     - labels (A list of columns labels)
   *
   * @return array
   *   The serialized contact message object data.
   */
  public function serialize(MessageInterface $message, array $settings = []) {
    $labels = isset($settings['labels']) ? $settings['labels'] : $this
      ->getLabels($message);
    $all_keys = array_keys($labels);
    $selected_keys = isset($settings['columns']) ? array_keys($settings['columns']) : $all_keys;
    $excluded_keys = array_diff($all_keys, $selected_keys);

    // Exclude UUID field.
    $excluded_keys[] = 'uuid';
    $values = [];
    foreach ($message
      ->getFields() as $field_name => $definition) {

      // Exclude marked columns.
      if (in_array($field_name, $excluded_keys)) {
        continue;
      }

      // Set the keys to readable labels and format data for CSV serialization.
      $values[$labels[$field_name]] = $this
        ->getFormattedValue($message, $field_name, $settings);
    }
    return $values;
  }

  /**
   * Formats values of the given field.
   *
   * @param \Drupal\contact\MessageInterface $message
   *   A message entity.
   * @param string $field
   *   A field name.
   * @param array $settings
   *   A settings array.
   *
   * @return array
   *   Formatted value.
   */
  public function getFormattedValue(MessageInterface $message, $field, array $settings) {

    // Get the field storage definition and the field type.
    $storage_definition = $message
      ->getFieldDefinition($field)
      ->getFieldStorageDefinition();
    $type = $storage_definition
      ->getType();
    $values = [];

    // Iterate over field items and format its values.

    /** @var \Drupal\Core\Field\FieldItemInterface $item */
    foreach ($message->{$field} as $item) {
      switch ($type) {
        case 'link':

          /** @var \Drupal\link\LinkItemInterface $item */
          $values[] = $this
            ->formatLink($item);
          break;
        case 'created':
        case 'daterange':
        case 'timestamp':
        case 'datetime':
          $date_format = isset($settings['date_format']) ? $settings['date_format'] : NULL;
          $values[] = $this
            ->formatDateTime($item, $date_format);
          break;
        case 'entity_reference':

          /** @var \Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem $item */
          $values[] = $this
            ->formatEntityReference($item, $storage_definition
            ->getMainPropertyName());
          break;
        default:

          // Display a field item value using default field formatter.
          $render_array = $item
            ->view();
          $values[] = $this
            ->renderAsString($render_array);
      }
    }
    return $values;
  }

  /**
   * Returns an absolute URL as a string value.
   *
   * @param \Drupal\link\LinkItemInterface $link_item
   *   The link item to format.
   *
   * @return string
   *   The URL.
   */
  protected function formatLink(LinkItemInterface $link_item) {
    return $link_item
      ->getUrl()
      ->setAbsolute()
      ->toString();
  }

  /**
   * Renders a given array and returns its string representation.
   *
   * @param array $renderable_array
   *   A renderable array.
   *
   * @return string
   *   Returns a string value.
   */
  protected function renderAsString(array $renderable_array) {
    return (string) $this->renderer
      ->renderPlain($renderable_array);
  }

  /**
   * Formats a date-time field item with a given format.
   *
   * @param \Drupal\Core\Field\FieldItemInterface $item
   *   Afield item to format.
   * @param string $format
   *   A date format. Defaults to short format (m/d/Y - H:i).
   *
   * @return string
   *   Formatted date-time value.
   */
  protected function formatDateTime(FieldItemInterface $item, $format) {
    $format = $format ?: 'short';
    $settings = [];
    if ($item instanceof CreatedItem) {
      $settings['date_format'] = $format;
    }
    elseif ($item instanceof DateRangeItem) {

      // Remove new lines between start and end dates.
      $date_range_item_view = $item
        ->view([
        'settings' => [
          'format_type' => $format,
        ],
      ]);
      $markup = $this
        ->renderAsString($date_range_item_view);
      return str_replace(PHP_EOL, '', $markup);
    }
    elseif ($item instanceof DateTimeItem) {
      $settings['format_type'] = $format;
    }
    $date_item_view = $item
      ->view([
      'settings' => $settings,
    ]);
    return $this
      ->renderAsString($date_item_view);
  }

  /**
   * Formats entity reference value.
   *
   * @param \Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem $entity_reference_item
   *   The entity reference item.
   * @param string $property
   *   The main property.
   *
   * @return string
   *   Formatted entity reference value.
   */
  protected function formatEntityReference(EntityReferenceItem $entity_reference_item, $property) {

    // Display a label without a link.
    $display_options = [
      'type' => 'entity_reference_label',
      'settings' => [
        'link' => FALSE,
      ],
    ];
    if ($render_array = $entity_reference_item
      ->view($display_options)) {
      return $this
        ->renderAsString($render_array);
    }

    // Fallback to the main property.
    return (string) $entity_reference_item->{$property};
  }

  /**
   * Returns labels from the field definitions.
   *
   * @param \Drupal\contact\MessageInterface $message
   *   A contact message object to get labels for.
   *
   * @return array
   *   The labels.
   */
  public function getLabels(MessageInterface $message) {
    $labels = [];
    foreach ($message
      ->getFieldDefinitions() as $key => $field) {
      if ($label = $field
        ->getLabel()) {

        // Remove characters not allowed in keys of associative arrays.
        $labels[$key] = filter_var($label, FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_HIGH | FILTER_FLAG_STRIP_LOW | FILTER_FLAG_NO_ENCODE_QUOTES);
      }
    }
    return $labels;
  }

  /**
   * Returns the encoded contact messages.
   *
   * @param \Drupal\contact\MessageInterface[] $messages
   *   The messages.
   * @param string[] $settings
   *   The settings array.
   * @param string $format
   *   (optional) The encoding format. Defaults to CSV.
   *
   * @return string
   *   The encoded data.
   */
  public function encode(array $messages, array $settings = [], $format = 'csv') {
    $data = [];

    // Get labels.
    if (!isset($settings['labels'])) {
      $message = reset($messages);
      $settings['labels'] = $this
        ->getLabels($message);
    }

    // Iterate over contact message and get serialized data.
    foreach ($messages as $message) {
      $data[] = $this
        ->serialize($message, $settings);
    }
    return $this
      ->encodeData($data, $format);
  }

  /**
   * Returns the encoded contact messages.
   *
   * @param string[] $data
   *   A serialized contact message data.
   * @param string $format
   *   (optional) The encoding format. Defaults to CSV.
   *
   * @return string
   *   The encoded data.
   */
  public function encodeData(array $data, $format = 'csv') {
    return $this->csvEncoder
      ->encode($data, $format);
  }

}

Members

Namesort descending Modifiers Type Description Overrides
ContactStorageExportService::$csvEncoder protected property The CSV encoder.
ContactStorageExportService::$renderer protected property The renderer.
ContactStorageExportService::create public static function Instantiates a new instance of this class. Overrides ContainerInjectionInterface::create
ContactStorageExportService::encode public function Returns the encoded contact messages.
ContactStorageExportService::encodeData public function Returns the encoded contact messages.
ContactStorageExportService::formatDateTime protected function Formats a date-time field item with a given format.
ContactStorageExportService::formatEntityReference protected function Formats entity reference value.
ContactStorageExportService::formatLink protected function Returns an absolute URL as a string value.
ContactStorageExportService::getFormattedValue public function Formats values of the given field.
ContactStorageExportService::getLabels public function Returns labels from the field definitions.
ContactStorageExportService::renderAsString protected function Renders a given array and returns its string representation.
ContactStorageExportService::serialize public function Returns a serialized message.
ContactStorageExportService::__construct public function Creates a new ContactStorageExportService object.