ww_publish-8.x-1.x-dev/src/ParagraphField.php

src/ParagraphField.php
<?php

namespace Drupal\ww_publish;

use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\field\Entity\FieldConfig;
use Drupal\paragraphs\Entity\Paragraph;
use Drupal\ww_publish\Events\ParagraphFieldEvent;

class ParagraphField {

  use MediaFieldTrait;
  use FieldTrait;

  /**
   * Paragraph field configuration.
   *
   * @var \Drupal\Core\Field\FieldDefinitionInterface
   */
  private $fieldConfig;

  /**
   * The SNS message.
   *
   * @var \Drupal\ww_publish\Message
   */
  protected $message;

  /**
   * Metadata of the article received from WoodWing Studio.
   *
   * @var \Drupal\ww_publish\Metadata
   */
  private $articleMetadata;

  /**
   * Article Components.
   *
   * @var array
   */
  private $articleComponents;

  /**
   * Configuration of the ww_publish module.
   *
   * @var \Drupal\Core\Config\Config
   */
  private $config;

  /**
   * A logger instance.
   *
   * @var \Psr\Log\LoggerInterface
   */
  private $logger;

  /**
   * Constructor.
   *
   * @param \Drupal\Core\Field\FieldDefinitionInterface $field_config
   *   Field config.
   * @param \Drupal\ww_publish\Metadata $article_metadata
   *   Article components.
   * @param array $article_components
   *   Article data.
   * @param array $prepared_files
   *   Prepared files.
   * @param \Drupal\Core\Config\Config $config
   *   Configuration of the ww_publish module.
   * @param \Psr\Log\LoggerInterface $logger
   *   A logger instance.
   */
  public function __construct(FieldDefinitionInterface $field_config, Message $message, $article_components, $config, $logger) {
    $this->message = $message;
    $this->fieldConfig = $field_config;
    $this->articleComponents = $article_components;
    $this->config = $config;
    $this->logger = $logger;
  }

  /**
   * Get article data.
   *
   * @param \Drupal\Core\Field\FieldItemList $messagesField
   *   Error messages field.
   *
   * @return array
   * @throws \Drupal\Core\TypedData\Exception\MissingDataException
   * @throws \Drupal\Core\Entity\EntityStorageException
   */
  public function getArticleData(&$messagesField = NULL): array {

    $identifiers = $this->getIdentifiers();
    $articleData = [];

    foreach ($this->articleComponents as $wwComponent) {
      $identifierKeys = array_keys(
        array_column($identifiers, 'first_identifier'),
        $wwComponent->identifier
      );

      $paragraph = NULL;
      if (!empty($identifierKeys)) {
        $identifierData = [];
        foreach ($identifierKeys as $identifierKey) {
          $identifierData[] = $identifiers[$identifierKey];
        }
        $paragraph = $this->createParagraph($wwComponent, $identifierData, $messagesField);
      }

      $event = new ParagraphFieldEvent($this->message, $wwComponent, $paragraph);
      \Drupal::service('event_dispatcher')->dispatch($event);

      if ($event->getParagraph()) {
        $paragraph = $event->getParagraph();
        $paragraph->save();
        $articleData[] = [
          'target_id' => $paragraph->id(),
          'target_revision_id' => $paragraph->getRevisionId(),
        ];
      }
    }

    if ($this->config->get('debug_mode'))
      $this->logger->debug('Paragraph article data: <pre><code>@article_data</code></pre>', ['@article_data' => print_r($articleData, TRUE)]);
    return $articleData;
  }

  /**
   * Get content of the component.
   *
   * @param object $wwComponent
   *   WoodWing Studio component.
   * @param array $identifiers
   *   The array items are arrays with the following keys: 'identifier',
   *   'first_identifier', 'last_identifier', 'paragraph_type', 'field_name',
   *   'field_type', 'field_config'.
   * @param \Drupal\Core\Field\FieldItemList $messagesField
   *   Error messages field.
   *
   * @return \Drupal\Core\Entity\EntityInterface
   * @throws \Drupal\Core\Entity\EntityStorageException
   * @throws \Drupal\Core\TypedData\Exception\MissingDataException
   */
  private function createParagraph(object $wwComponent, array $identifiers, &$messagesField = NULL): ?EntityInterface {

    $paragraphData = [
      'type' => $identifiers[0]['paragraph_type'],
    ];

    $createParagraph = FALSE;

    foreach ($identifiers as $identifier) {
      $wwIdentifiers = explode('|', $identifier['identifier']);

      switch ($identifier['field_type']) {
        case 'entity_reference':
          $media_bundle = $this->getMediaTargetBundle($identifier['field_config']);
          if (!empty($wwComponent->content->image)) {
            $referenceId = $this->createMediaImage($media_bundle, $wwComponent->content);
            if ($referenceId) {
              $paragraphData[$identifier['field_name']] = [
                'target_id' => $referenceId,
              ];
              $createParagraph = TRUE;
            }
          }
          break;

        case 'entity_reference_revisions':
          if ($this->config->get('debug_mode')) {
            $this->logger->debug('WoodWing Studio component containers for @identifier: <pre><code>@containers</code></pre>', ['@identifier' => $wwComponent->identifier, '@containers' => print_r($wwComponent->containers, TRUE)]);
            $this->logger->debug('Last identifier: @last_identifier', ['@last_identifier' => $identifier['last_identifier']]);
          }
          $paragraphField = new ParagraphField($identifier['field_config'], $this->message, $wwComponent->containers->{$identifier['last_identifier']}, $this->config, $this->logger);
          $articleData = $paragraphField->getArticleData($messagesField);
          if ($articleData) {
            $paragraphData[$identifier['field_name']] = $articleData;
            $createParagraph = TRUE;
          }
          break;

        case 'link':
          $child_identifiers = \array_slice($wwIdentifiers, 1);
          $uri = $this->getComponentContent($wwComponent, ...$child_identifiers);

          if (!is_string($uri) && $identifier['field_config']->isRequired()) {
            $message = 'The component with identifier @station_identifier can not be saved as a link in the field @field_name.';
            $this->logger->error($message, ['@station_identifier' => $identifier['identifier'], '@field_name' => $this->fieldConfig->getName()]);
            $messagesField[]['value'] = t($message, ['@station_identifier' => $identifier['identifier'], '@field_name' => $this->fieldConfig->getName()]);
            break;
          }

          if ($uri) {
            $paragraphData[$identifier['field_name']] = [
              'uri' => $uri,
            ];
            $createParagraph = TRUE;
          }
          break;

        default:
          // Get content from the text property.
          $content = [];
          if (property_exists($wwComponent, 'content')) {
            foreach ($wwComponent->content as $content_key => $component_content) {
              $content[$content_key] = '';
              if (\is_array($component_content)) {
                foreach ($component_content as $text) {
                  $content[$content_key] .= $this->getAtributeContent($text, (bool) $identifier['field_config']->getFieldStorageDefinition()->getPropertyDefinition('format'));
                }
              }
              else {
                $content[$content_key] = $component_content;
              }
            }
          }

          $content = \array_filter($content);
          if (!empty($content)) {
            // Apply a template on the content.
            $template = \Drupal::service('ww_publish.template');
            if ($template->exist($identifier['identifier'], 'component')) {
              $content = $template->apply($identifier['identifier'], 'component', $content);
            }
            else {
              // No template, pick either the specified or first content
              // component.
              if (count($wwIdentifiers) === 2) {
                $content = $content[$wwIdentifiers[1]] ?? '';
              }
              else {
                $content = reset($content);
              }
            }

            $content = $this->shortenValueToFieldMaxLength($content, $identifier['field_config'], $messagesField);

            // Create a new paragraph.
            if (\in_array($identifier['field_type'], ['string', 'string_long'])) {
              $paragraphData[$identifier['field_name']] = [
                'value' => strip_tags($content)
              ];
            }
            else {
              $paragraphData[$identifier['field_name']] = [
                'value' => $content,
                'format' => $this->getTextFormat($this->fieldConfig),
              ];
            }

            $createParagraph = TRUE;
          }
          elseif ($identifier['field_config']->isRequired()) {
            $message = 'The component with identifier @station_identifier can not be saved as a string in the field @field_name.';
            $this->logger->error($message, ['@station_identifier' => $identifier['identifier'], '@field_name' => $this->fieldConfig->getName()]);
            $messagesField[]['value'] = t($message, ['@station_identifier' => $identifier['identifier'], '@field_name' => $this->fieldConfig->getName()]);
          }
      }
    }

    if ($createParagraph) {
      if ($this->config->get('debug_mode'))
        $this->logger->debug('Paragraph data: <pre><code>@paragraph_data</code></pre>', ['@paragraph_data' => print_r($paragraphData, TRUE)]);

      return Paragraph::create($paragraphData);
    } else {
      return NULL;
    }
  }

  /**
   * Get the component content.
   *
   * @param object $wwComponent
   *   WoodWing Studio component, from which the content should be extracted.
   * @param string $contentProperty
   *   Property in the content object.
   * @param string $textProperty
   *   Property in the object in the text array.
   *
   * @return string|bool
   */
  private function getComponentContent(object $wwComponent, $contentProperty = 'text', $textProperty = NULL) {
    $componentContent = [];
    if (property_exists($wwComponent, 'content') && property_exists($wwComponent->content, $contentProperty)) {
      if ($textProperty) {
        if (\property_exists($wwComponent->content->$contentProperty, $textProperty)) {
          return $this->getAtributeContent($wwComponent->content->$contentProperty->$textProperty);
        }
      }
      else {
        foreach ($wwComponent->content->{$contentProperty} as $text) {
          $componentContent[] = $this->getAtributeContent($text);
        }
        return implode('', $componentContent);
      }
    }
    return FALSE;
  }

  /**
   * Get all defined WoodWing Studio identifiers.
   *
   * All identifiers from fields in all enabled paragraph types is returned as
   * an array, of arrays with the following keys: identifier, paragraph_type,
   * field_name.
   *
   * @return array
   * @throws \Drupal\Core\TypedData\Exception\MissingDataException
   */
  private function getIdentifiers(): array {
    $identifiers = [];
    // Get all enabled paragraph types.
    $enabledParagraphTypes = $this->fieldConfig->get('settings')['handler_settings']['target_bundles'];
    foreach ($enabledParagraphTypes as $type) {
      $fields = \Drupal::service('entity_field.manager')->getFieldDefinitions('paragraph', $type);
      foreach ($fields as $field_name => $fieldConfig) {
        if ($fieldConfig instanceof FieldConfig && $fieldConfig->get('entity_type') === 'paragraph') {
          $wwIdentifiers = $fieldConfig->getThirdPartySetting('ww_publish', 'content_station_identifier');
          if ($wwIdentifiers) {
            foreach (\explode(',', $wwIdentifiers) as $identifier) {
              $paragraph_type = $fieldConfig->get("bundle");
              $explodedIdentifier = explode('|', $identifier);
              $lastIdentifier = end($explodedIdentifier);
              $identifiers[] = [
                'identifier' => $identifier,
                'first_identifier' => strtok($identifier, '|'),
                'last_identifier' => $lastIdentifier,
                'paragraph_type' => $paragraph_type,
                'field_name' => $field_name,
                'field_type' => $fieldConfig->getType(),
                'field_config' => $fieldConfig,
              ];
            }
          }


        }
      }
    }
    return $identifiers;
  }

}

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

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