delivery-8.x-1.x-dev/src/Form/DeliveryFromWorkspaceForm.php

src/Form/DeliveryFromWorkspaceForm.php
<?php

namespace Drupal\delivery\Form;

use Drupal\Core\Database\Connection;
use Drupal\Core\Entity\EntityTypeManager;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Logger\LoggerChannelInterface;
use Drupal\delivery\Entity\Delivery;
use Drupal\delivery\Entity\DeliveryItem;
use Drupal\workspaces\WorkspaceInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Request;

/**
 * Form to create a new delivery from all modified nodes and media entities.
 */
class DeliveryFromWorkspaceForm extends FormBase {

  /**
   * The entity type manager to create, load and save entities.
   *
   * @var \Drupal\Core\Entity\EntityTypeManager
   */
  protected $entityTypeManager;

  /**
   * @var \Drupal\Core\Entity\ContentEntityStorageInterface
   */
  protected $workspaceStorage;

  /**
   * @var \Drupal\Core\Entity\ContentEntityStorageInterface
   */
  protected $deliveryStorage;

  /**
   * @var
   */
  protected $database;

  /**
   * @var \Drupal\Core\Logger\LoggerChannelInterface
   */
  protected $loggerChannel;

  /**
   * DeliveryFromWorkspaceForm constructor.
   *
   * @param \Drupal\Core\Entity\EntityTypeManager $entityTypeManager
   *   The entity type manager.
   * @param \Drupal\Core\Database\Connection $database
   *   The database connection.
   * @param \Drupal\Core\Logger\LoggerChannelInterface $loggerChannel
   *   The module's logger channel.
   *
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   */
  public function __construct(EntityTypeManager $entityTypeManager, Connection $database, LoggerChannelInterface $loggerChannel) {
    $this->database = $database;
    $this->entityTypeManager = $entityTypeManager;
    $this->workspaceStorage = $entityTypeManager->getStorage('workspace');
    $this->deliveryStorage = $entityTypeManager->getStorage('delivery');
    $this->loggerChannel = $loggerChannel;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('entity_type.manager'),
      $container->get('database'),
      $container->get('logger.factory')->get('delivery')
    );
  }

  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    return 'delivery_from_workspace';
  }

  /**
   * Retrieve the forms page title.
   *
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   */
  public function title() {
    $source = $this->workspaceStorage->load($this->getRequest()->get('workspace'));
    $entity_type = $this->getRequest()->query->get('entity_type');

    if (!$entity_type) {
      return $this->t('Create a delivery from %workspace', [
        '%workspace' => $source->label(),
      ]);
    }

    return $this->t('Create a delivery of %type entities from %workspace', [
      '%workspace' => $source->label(),
      '%type' => $this->entityTypeManager->getDefinition($entity_type)->getLabel(),
    ]);
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    $request = $this->getRequest();
    /** @var \Drupal\workspaces\WorkspaceInterface $source */
    $source = $this->workspaceStorage->load($request->get('workspace'));
    if (!$source) {
      // TODO: Proper error handling.
      return;
    }

    /** @var \Drupal\workspaces\WorkspaceInterface $target */
    $target = $source->parent->entity;
    if (!$target) {
      // TODO: Proper error handling.
      return;
    }

    $form_state->set('source', $source);
    $form_state->set('target', $target);
    $entity_type = $request->query->get('entity_type');
    $bundle = $request->query->get('bundle');
    $label = '';

    $form['options_elements'] = [];
    if ($request->query->get('hide_options_elements')) {
      $form['options_elements']['#type'] = 'details';
      $form['options_elements']['#title'] = 'Options';

      if (!$entity_type) {
        $label = (string) $this->t('A delivery from @workspace', [
          '@workspace' => $source->label(),
        ]);
      } else {
        $label = (string) $this->t('A delivery of @type entities from @workspace', [
          '@workspace' => $source->label(),
          '@type' => $this->entityTypeManager->getDefinition($entity_type)->getLabel(),
        ]);
      }
    }

    $form['options_elements']['label'] = [
      '#type' => 'textfield',
      '#required' => TRUE,
      '#title' => $this->t('Label'),
      '#description' => $this->t('Choose a descriptive label for this delivery.'),
      '#default_value' => $label,
    ];

    $form['options_elements']['description'] = [
      '#type' => 'textarea',
      '#required' => FALSE,
      '#title' => $this->t('Description'),
      '#description' => $this->t('A more detailed description of this delivery.'),
    ];

    $form['options_elements']['items'] = [
      '#type' => 'checkboxes',
      '#title' => $this->t('Delivery items'),
      '#description' => $this->t('Choose which content items should be delivered.'),
      '#options' => [],
    ];

    $modifications = $this->getModifiedEntities($source, $target, $entity_type);

    // Group the items by entity type to load all in a single query.
    $revisionsByEntityType = [];
    foreach ($modifications as $item) {
      $revisionsByEntityType[$item->target_entity_type][] = $item->source_revision;
    }

    foreach ($revisionsByEntityType as $entityTypeId => $revisions) {
      try {
        /** @var \Drupal\Core\Entity\RevisionableStorageInterface $storage */
        $storage = $this->entityTypeManager->getStorage($entityTypeId);
        $entityType = $this->entityTypeManager->getDefinition($entityTypeId);
        $entityTypeLabel = (string) $entityType->getLabel();

        foreach ($storage->loadMultipleRevisions($revisions) as $entity) {
          if ($bundle && $entity->bundle() != $bundle) {
            continue;
          }

          $key = implode(':', [
            $entity->getEntityTypeId(),
            $entity->id(),
            $entity->getRevisionId(),
          ]);
          $form['options_elements']['items']['#default_value'][$key] = $key;
          $form['options_elements']['items']['#options'][$key] = $entity->label() . " ($entityTypeLabel, {$entity->bundle()})";
        }
      } catch (\Exception $exception) {
        $this->loggerChannel->error($exception->getMessage());
      }
    }

    if (!empty($form['options_elements']['items']['#options'])) {
      $form['submit'] = [
        '#type' => 'submit',
        '#value' => $this->t('Create delivery'),
      ];
    } else {
      unset($form['options_elements']);

      $empty_text = '';
      $replacements = [
        '@type' => $entity_type,
        '@bundle' => $bundle,
      ];
      if ($entity_type && $bundle) {
        $empty_text = 'There are no @type entities of type @bundle to deliver right now.';
      } elseif ($entity_type) {
        $empty_text = 'There are no @type entities to deliver right now.';
      } else {
        $empty_text = 'There are no entities to deliver right now.';
      }
      $form['empty_text'] = [
        '#markup' => $this->t($empty_text, $replacements),
      ];
    }

    $form_state->set('workspace_safe', TRUE);
    return $form;
  }

  protected function getModifiedEntities(WorkspaceInterface $source, WorkspaceInterface $target, $entity_type) {
    $query = $this->database->select('workspace_association', 'source');

    $query->addField('source', 'target_entity_id', 'target_entity_id');
    $query->addField('source', 'target_entity_type_id', 'target_entity_type');
    $query->addField('source', 'target_entity_revision_id', 'source_revision');
    $query->addField('target', 'target_entity_revision_id', 'target_revision');

    $query->leftJoin('workspace_association', 'target',
      'source.target_entity_id = target.target_entity_id and source.target_entity_type_id = target.target_entity_type_id and target.workspace = :target',
      [':target' => $target->id()]
    );

    $query->where('source.workspace = :source and (source.target_entity_revision_id != target.target_entity_revision_id or target.target_entity_revision_id is null)', [':source' => $source->id()]);

    if ($entity_type) {
      $query->condition('source.target_entity_type_id', $entity_type);
    }

    return $query->execute()->fetchAll();
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    $source = $form_state->get('source');
    $target = $form_state->get('target');

    $values = [
      'label' => $form_state->getValue('label'),
      'description' => $form_state->getValue('description'),
      'source' => $source,
      'workspaces' => [$target],
      'items' => [],
    ];
    $items = array_filter($form_state->getValue('items'));

    foreach ($items as $row) {
      list($entity_type, $entity_id, $revision_id) = explode(':', $row);
      $item = DeliveryItem::create([
        'source_workspace' => $source->id(),
        'target_workspace' => $target->id(),
        'entity_type' => $entity_type,
        'entity_id' => $entity_id,
        'source_revision' => $revision_id,
      ]);
      $item->save();
      $values['items'][] = $item;
    }

    $delivery = Delivery::create($values);
    $delivery->save();
    $form_state->setRedirect('entity.delivery.canonical', [
      'delivery' => $delivery->id(),
    ]);
  }

}

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

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