delivery-8.x-1.x-dev/src/Plugin/views/traits/EntityDeliveryStatusTrait.php

src/Plugin/views/traits/EntityDeliveryStatusTrait.php
<?php

namespace Drupal\delivery\Plugin\views\traits;

use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\views\Plugin\ViewsHandlerManager;
use Drupal\workspaces\Entity\Workspace;
use Drupal\workspaces\WorkspaceManagerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Common functionality for the
 */
trait EntityDeliveryStatusTrait {
  public static $NOT_APPLICABLE = -1;
  public static $IDENTICAL = 0;
  public static $MODIFIED = 1;
  public static $OUTDATED = 2;
  public static $CONFLICT = 3;
  public static $NEW = 4;


  /**
   * Entity Type Manager service.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;

  /**
   * Views Handler Plugin Manager.
   *
   * @var \Drupal\views\Plugin\ViewsHandlerManager
   */
  protected $joinHandler;

  /**
   * The workspace manager.
   *
   * @var \Drupal\workspaces\WorkspaceManagerInterface
   */
  protected $workspaceManager;

  /**
   * The default workspace id.
   *
   * @var string
   */
  protected $defaultWorkspace;

  /**
   * Field alias containing the revision the source workspace.
   *
   * @var string
   */
  protected $sourceAlias;

  /**
   * Field alias containing the revision on the target workspace.
   *
   * @var string
   */
  protected $targetAlias;

  /**
   * Field alias containing the lca revision id.
   *
   * @var string
   */
  protected $lcaAlias;

  /**
   * The source workspace id.
   *
   * @var string
   */
  protected $sourceWorkspace;

  /**
   * The target workspace id.
   *
   * @var string
   */
  protected $targetWorkspace;

  /**
   * Indicator that the field currently is not applicable.
   *
   * @var boolean
   */
  protected $notApplicable = FALSE;

  /**
   * Constructs a new WorkspaceCompare field.
   *
   * @param array $configuration
   *   A configuration array containing information about the plugin instance.
   * @param string $plugin_id
   *   The plugin_id for the plugin instance.
   * @param mixed $plugin_definition
   *   The plugin implementation definition.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   Entity Type Manager Service.
   * @param \Drupal\views\Plugin\ViewsHandlerManager $join_handler
   *   Views Handler Plugin Manager.
   * @param \Drupal\workspaces\WorkspaceManagerInterface $workspaceManager
   *   The workspace manager.
   * @param string $defaultWorkspace
   *   The default workspace id.
   */
  public function __construct(
    array $configuration, $plugin_id,
    $plugin_definition,
    EntityTypeManagerInterface $entity_type_manager,
    ViewsHandlerManager $join_handler,
    WorkspaceManagerInterface $workspaceManager,
    $defaultWorkspace
  ) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);

    $this->entityTypeManager = $entity_type_manager;
    $this->joinHandler = $join_handler;
    $this->workspaceManager = $workspaceManager;
    $this->defaultWorkspace = $defaultWorkspace;
  }

  protected function getWorkspaceHierarchy($workspaceId) {
    $workspace = $this->entityTypeManager->getStorage('workspace')->load($workspaceId);
    $context = [$workspace->id()];
    while ($workspace = $workspace->parent->entity) {
      $context[] = $workspace->id();
    }
    $context[] = NULL;
    return $context;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static(
      $configuration, $plugin_id, $plugin_definition,
      $container->get('entity_type.manager'),
      $container->get('plugin.manager.views.join'),
      $container->get('workspaces.manager'),
      $container->hasParameter('workspace.default')
        ? $container->getParameter('workspace.default')
        : 'live'
    );
  }

  protected function defineDeliveryStatusOptions() {
    return [
      'source_workspace' => ['default' => '__current'],
      'target_workspace' => ['default' => '__parent'],
      'source_workspace_arg' => ['default' => 0],
      'target_workspace_arg' => ['default' => 1],
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function buildDeliveryStatusOptionsForm(&$form, FormStateInterface $form_state) {
    $workspaceOptions = array_map(function (Workspace $workspace) {
        return $workspace->label();
      }, $this->entityTypeManager->getStorage('workspace')->loadMultiple()) + [
        '__current' => $this->t('Current workspace'),
        '__parent' => $this->t('Parent of current workspace'),
        '__argument' => $this->t('From views argument'),
      ];


    $form['source_workspace'] = [
      '#type' => 'select',
      '#title' => $this->t('Source workspace'),
      '#options' => $workspaceOptions,
      '#description' => $this->t('Select a source workspace for the status comparison.'),
      '#default_value' => $this->options['source_workspace'],
    ];

    $form['source_workspace_arg'] = [
      '#type' => 'number',
      '#title' => $this->t('Source workspace argument'),
      '#description' => $this->t('The argument number to get the source workspace from.'),
      '#states' => [
        'visible' => [
          'select[name="options[source_workspace]"]' => ['value' => '__argument'],
        ],
      ],
      '#default_value' => $this->options['source_workspace_arg'],
    ];

    $form['target_workspace'] = [
      '#type' => 'select',
      '#title' => $this->t('Target workspace'),
      '#options' => $workspaceOptions,
      '#description' => $this->t('Select a target workspace for the status comparison.'),
      '#default_value' => $this->options['target_workspace'],
    ];

    $form['target_workspace_arg'] = [
      '#type' => 'number',
      '#title' => $this->t('Target workspace argument'),
      '#description' => $this->t('The argument number to get the target workspace from.'),
      '#states' => [
        'visible' => [
          'select[name="options[target_workspace]"]' => ['value' => '__argument'],
        ],
      ],
      '#default_value' => $this->options['target_workspace_arg'],
    ];

  }

  public function getSourceWorkspace() {
    if (!$this->sourceWorkspace) {
      $this->sourceWorkspace = $this->getWorkspaceArgument('source');
    }
    return $this->sourceWorkspace;
  }

  public function getTargetWorkspace() {
    if (!$this->targetWorkspace) {
      $this->targetWorkspace = $this->getWorkspaceArgument('target');
    }
    return $this->targetWorkspace;
  }

  protected function getWorkspaceArgument($key) {
    switch ($this->options[$key . '_workspace']) {
      case '__current':
        return $this->workspaceManager->getActiveWorkspace()->id();
        break;
      case '__parent':
        $parent = $this->workspaceManager->getActiveWorkspace()->parent->entity;
        if ($parent) {
          return $parent->id();
        }
        break;
      case '__argument':
        $arg = intval($this->options[$key . '_workspace_arg']);
        if (isset($this->view->args[$arg])) {
          return $this->view->args[$arg];
        }
        break;
      default:
        return $this->options[$key . '_workspace'];
        break;
    }
  }

  public function prepareEntityStatusQuery() {
    if (isset($this->query->fields['num_source']) && isset($this->query->fields['num_target'])) {
      $this->sourceAlias = $this->query->fields['num_source']['alias'];
      $this->targetAlias = $this->query->fields['num_target']['alias'];
      return;
    }

    $source = $this->getSourceWorkspace();
    $target = $this->getTargetWorkspace();

    $this->query->entityStatusApplied = TRUE;

    if (!($source && $target)) {
      $this->notApplicable = TRUE;
      return;
    }

    $entity_type = $this->entityTypeManager->getDefinition($this->getEntityType());

    $sourceHierarchy = $this->getWorkspaceHierarchy($source);
    $targetHierarchy = $this->getWorkspaceHierarchy($target);
    $lcaHierarchy = array_intersect($sourceHierarchy, $targetHierarchy);

    $activeSourceLeaves = \Drupal::database()->select('workspace_association', 'wa')->condition('workspace', $source);
    $activeTargetLeaves = \Drupal::database()->select('workspace_association', 'wa')->condition('workspace', $target);
    $activeLcaLeaves = \Drupal::database()->select('workspace_association', 'wa')->condition('workspace', array_shift($lcaHierarchy));

    $base_table = $this->relationship ?: $this->view->storage->get('base_table');

    $keys = $entity_type->getKeys();

    $baseQuery = \Drupal::database()->select($entity_type->getRevisionTable(), 'base');
    $baseQuery->addField('base', $keys['id'], 'entity_id');

    // If the first argument is set, we display the status of an existing
    // delivery, else its the current workspace changed state.
    // Else its the current workspace status. In the latter case, we have to restrict
    // the list of revisions to the on
    // TODO: Separate this properly.
    if (!$this->view->args[0]) {
      $baseQuery->condition('workspace', $source);
    }

    $baseQuery->innerJoin($activeSourceLeaves, 'source', "base.{$keys['revision']} = source.target_entity_revision_id");
    $baseQuery->innerJoin($activeTargetLeaves, 'target', "base.{$keys['id']} = target.target_entity_id");
    $baseQuery->innerJoin($activeLcaLeaves, 'lca', "base.{$keys['id']} = lca.target_entity_id");
    $baseQuery->addField('source', 'target_entity_revision_id', 'source_revision');
    $baseQuery->addField('target', 'target_entity_revision_id', 'target_revision');
    $baseQuery->addField('lca', 'target_entity_revision_id', 'lca_revision');

    // If the first argument is set, we display the status of an existing delivery.
    // This means we join with the entity id. In the other case we have to restrict
    // the list of revisions to the leaves of the current workspace and therefore
    // join using the source revision.
    // TODO: Properly separate this.
    if (!$this->view->args[0]) {
      $revisionsTable = $this->joinHandler->createInstance(
        'standard',
        [
          'table' => $baseQuery,
          'field' => 'source_revision',
          'type' => 'INNER',
          'left_table' => $base_table,
          'left_field' => $keys['revision'],
        ]
      );
    } else {
      $revisionsTable = $this->joinHandler->createInstance(
        'standard',
        [
          'table' => $baseQuery,
          'field' => 'entity_id',
          'type' => 'INNER',
          'left_table' => $base_table,
          'left_field' => $keys['id'],
        ]
      );
    }

    $revisionsAlias = $this->query->addTable($entity_type->getRevisionTable() . '_source', $this->relationship, $revisionsTable);

    $this->sourceAlias = $this->query->addField($revisionsAlias, 'source_revision', 'source_rev');
    $this->targetAlias = $this->query->addField($revisionsAlias, 'target_revision', 'target_rev');
    $this->lcaAlias = $this->query->addField($revisionsAlias, 'lca_revision', 'lca_rev');
  }

}

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

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