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

src/Field.php
<?php

namespace Drupal\ww_publish;

use Drupal\Core\Field\FieldDefinitionInterface;

class Field {

  use MediaFieldTrait;
  use FieldTrait;

  /**
   * Configuration of the field.
   *
   * @var \Drupal\Core\Field\FieldDefinitionInterface
   */
  private $fieldConfig;

  /**
   * WoodWing Studio identifier.
   *
   * @var string
   */
  private $contentStationIdentifier;

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

  /**
   * Article Data.
   *
   * @var Object
   */
  private $articleData;

  /**
   * 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 configuration.
   * @param string $content_station_identifier
   *   WoodWing Studio identifier.
   * @param \Drupal\ww_publish\Message $message
   *   Article metadata.
   * @param Object $article_data
   *   Article data.
   * @param array $prepared_files
   *   Prepared files.
   * @param string $article_id_field
   *   WoodWing Studio article ID field.
   * @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, $content_station_identifier, Message $message, $config, $logger) {
    $this->message = $message;
    $this->fieldConfig = $field_config;
    $this->contentStationIdentifier = $content_station_identifier;
    $this->articleData = $message->getArticleData();
    $this->config = $config;
    $this->logger = $logger;
  }

  /**
   * Get article data.
   *
   * @param array $messagesField
   *   Error messages field.
   *
   * @return array
   * @throws \Drupal\Core\Entity\EntityStorageException
   */
  public function getArticleData(&$messagesField = NULL): ?array {
    $articleData = [];

    $fieldType = $this->fieldConfig->getType();

    $contentStationIdentifiers = explode('|', $this->contentStationIdentifier);
    switch ($fieldType) {
      case 'text_with_summary':
        // Get field value.
        $fieldValue = $this->getComponentContent($contentStationIdentifiers[0]);
        if (is_array($fieldValue)) {
          $articleData['value'] = implode(' ', $fieldValue);
        } else {
          $articleData['value'] = $fieldValue;
        }

        // Add summary, if defined in WoodWing Studio identifier, e.g.: 'body|intro'.
        $noSummary = TRUE;
        if (count($contentStationIdentifiers) === 2) {
          $summary = $this->getComponentContent($contentStationIdentifiers[1]);
          if (is_array($summary)) {
            $articleData['summary'] = implode(' ', $summary);
          } else {
            $articleData['summary'] = $summary;
          }
          $noSummary = $articleData['summary'] === FALSE;
        }

        if ($articleData['value'] === FALSE && $noSummary) {
          $articleData = [];
        } else {
          $articleData['format'] = $this->getTextFormat($this->fieldConfig);
        }
        break;

      case 'entity_reference':
        if ($this->config->get('debug_mode'))
          $this->logger->debug('Entity reference!');
        if ($this->config->get('debug_mode'))
          $this->logger->debug('Identifiers: <pre><code>@identifiers</code></pre>', ['@identifiers' => print_r($contentStationIdentifiers, TRUE)]);
        $media_bundle = $this->getMediaTargetBundle($this->fieldConfig);
        if ($media_bundle && count($contentStationIdentifiers) > 1) {
          $component = $this->getComponent($contentStationIdentifiers[0]);
          if ($this->config->get('debug_mode'))
            $this->logger->debug('Component: <pre><code>@component</code></pre>', ['@component' => print_r($component, TRUE)]);

          if ($component && !empty($component->content->image)) {
            $referenceId = $this->createMediaImage($media_bundle, $component->content);
            if ($this->config->get('debug_mode'))
              $this->logger->debug('Reference ID: ' .  $referenceId);
            $articleData['target_id'] = $referenceId;
          }
        }

        // Attempt to look up the reference from the handler.
        if ($referenceId = $this->getReferenceFromHandler($contentStationIdentifiers)) {
          if ($this->config->get('debug_mode'))
            $this->logger->debug('Reference ID: ' .  $referenceId);
          $articleData['target_id'] = $referenceId;
        }
        break;

      default:
        $wwComponent = $this->getComponent($contentStationIdentifiers[0]);

        $content = [];
        if ($wwComponent && 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) $this->fieldConfig->getFieldStorageDefinition()->getPropertyDefinition('format'));
              }
            }
            else {
              $content[$content_key] = $component_content;
            }
          }
        }

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

          $content = $this->shortenValueToFieldMaxLength($content, $this->fieldConfig, $messagesField);

          // Create a new paragraph.
          if (\in_array($fieldType, ['string', 'string_long'])) {
            $articleData = [
              'value' => strip_tags($content)
            ];
          }
          else {
            $articleData = [
              'value' => $content,
              'format' => $this->getTextFormat($this->fieldConfig),
            ];
          }
        }
        elseif ($this->fieldConfig->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' => $this->contentStationIdentifier, '@field_name' => $this->fieldConfig->getName()]);
          $messagesField[]['value'] = t($message, ['@station_identifier' => $this->contentStationIdentifier, '@field_name' => $this->fieldConfig->getName()]);
        }
        break;
    }
    if (empty($articleData)) {
      return NULL;
    } else {
      return $articleData;
    }
  }

  /**
   * Get the component content.
   *
   * @param string $contentStationIdentifier
   *   WoodWing Studio identifier.
   * @param string $contentProperty
   *   Property in the content object.
   * @param string $textProperty
   *   Property in the object in the text array.
   *
   * @return string|array|bool
   */
  private function getComponentContent($contentStationIdentifier, $contentProperty = 'text', $textProperty = 'insert') {
    $componentContent = [];
    // Find the related component in the article object.
    foreach ($this->articleData->data->content as $contentStationComponent) {
      if (
        ($contentStationComponent->id === $contentStationIdentifier || $contentStationComponent->identifier === $contentStationIdentifier) &&
        property_exists($contentStationComponent, 'content') && property_exists($contentStationComponent->content, $contentProperty)
      ) {
        foreach ($contentStationComponent->content->{$contentProperty} as $text) {
          $text_content = Html::escape($text->{$textProperty});
          if (property_exists($text, 'attributes')) {
            $componentContent[] = $this->applyTemplate($text_content, 'attribute', $text->attributes);
          } else {
            $componentContent[] = $text->{$textProperty};
          }
        }
      }
    }
    // If there is only one value in the array, then only the value should be returned.
    if (count($componentContent) === 1) {
      $componentContent = $componentContent[0];
    }

    if (empty($componentContent)) {
      return FALSE;
    } else {
      return $componentContent;
    }
  }

  /**
   * Apply template to the component
   *
   * @param string $text
   *   Text from the component, to which the template(s) should by applied.
   * @param string $type
   *   Type of the template: component, attribute.
   * @param array $attributes
   *   Attributes with data about the templates.
   *
   * @return string
   */
  private function applyTemplate($text, $type, $attributes = NULL) {
    $template = \Drupal::service('ww_publish.template');
    foreach ($attributes as $attribute => $attributeValue) {
      // Attribute templates are expected to exist or structure is lost,
      // call apply() directly to trigger a warning log message about
      // missing templates.
      if ($attribute === 'comment') {
        continue;
      }
      $text = $template->apply($attribute, $type, [
        'insert' => $text,
        $attribute => $attributeValue,
      ]) ?? $text;
    }

    return $text;
  }

  /**
   * Get the WoodWing component.
   *
   * @param string $contentStationIdentifier
   *   WoodWing Studio identifier.
   * @param string $contentProperty
   *   Property in the content object.
   *
   * @return Object
   */
  private function getComponent($contentStationIdentifier, $contentProperty = NULL) {
    // Find the related component in the article object.
    foreach ($this->articleData->data->content as $contentStationComponent) {
      if ($contentStationComponent->id === $contentStationIdentifier || $contentStationComponent->identifier === $contentStationIdentifier) {
        if ($contentProperty) {
          return $contentStationComponent->content->{$contentProperty};
        }
        else {
          return $contentStationComponent;
        }
      }
    }
    return NULL;
  }

  /**
   * Returns a reference ID for the given identifier.
   *
   * Currently only metadata identfiers like metadata:ExtraMetaData|Something
   * are supported.
   *
   * @param string[] $woodwing_identifier
   *   The woodwing identifier, already split on the |.
   *
   * @return int|string|null
   *   The target entity ID if one could be identified.
   */
  public function getReferenceFromHandler($woodwing_identifier) {
    // @todo Support content components as well for a lookup? Abstract the
    //   different lookup methods behind a single API on Message?
    if (\strpos($woodwing_identifier[0], 'metadata:') === 0 && count($woodwing_identifier) >= 2) {
      $woodwing_identifier[0] = \str_replace('metadata:', '', $woodwing_identifier[0]);
      if ($value = $this->message->getArticleMetadata()->getMetadataByIdentifier(...$woodwing_identifier)) {

        // Attempt to fetch a reference for the given field as an exact
        // match, assume that there is only one.
        /** @var \Drupal\Core\Entity\EntityReferenceSelection\SelectionPluginManager $autocomplete */
        $selection_manager = \Drupal::service('plugin.manager.entity_reference_selection');

        $options = $this->fieldConfig->getSetting('handler_settings') + [
            'target_type' => $this->fieldConfig->getSetting('target_type'),
            'handler' => $this->fieldConfig->getSetting('handler'),
          ];
        try {
          $handler = $selection_manager->getInstance($options);

          $entities = $handler->getReferenceableEntities($value, '=', 1);
          if ($entities) {
            $entities = reset($entities);
            return key($entities);
          }
        }
        catch (\Exception $e) {
          $this->logger->error('Unexpected error when trying to find reference: @message', ['@message' => $e->getMessage()]);
        }
      }
    }
  }

}

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

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