wse-1.0.x-dev/modules/wse_deploy/src/Plugin/wse_deploy/WorkspaceExport/HttpExport.php

modules/wse_deploy/src/Plugin/wse_deploy/WorkspaceExport/HttpExport.php
<?php

namespace Drupal\wse_deploy\Plugin\wse_deploy\WorkspaceExport;

use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\workspaces\WorkspaceInterface;
use Drupal\wse_deploy\EncryptionHandler;
use Drupal\wse_deploy\WorkspaceExportBase;
use GuzzleHttp\ClientInterface;
use GuzzleHttp\RequestOptions;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Defines a workspace export plugin which relies on HTTP requests.
 *
 * @WorkspaceExport(
 *   id = "http",
 *   label = @Translation("HTTP")
 * )
 */
class HttpExport extends WorkspaceExportBase implements ContainerFactoryPluginInterface {

  /**
   * The HTTP client to POST the files with.
   *
   * @var \GuzzleHttp\ClientInterface
   */
  protected $httpClient;

  /**
   * The config factory service.
   *
   * @var \Drupal\Core\Config\ConfigFactoryInterface
   */
  protected $configFactory;

  /**
   * The hash handler.
   *
   * @var \Drupal\wse_deploy\EncryptionHandler
   */
  protected $encryptionHandler;

  /**
   * Constructs a HttpExport object.
   */
  public function __construct(array $configuration, $plugin_id, $plugin_definition, ClientInterface $http_client, ConfigFactoryInterface $config_factory, EncryptionHandler $encryption_handler) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);
    $this->httpClient = $http_client;
    $this->configFactory = $config_factory;
    $this->encryptionHandler = $encryption_handler;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static(
      $configuration,
      $plugin_id,
      $plugin_definition,
      $container->get('http_client'),
      $container->get('config.factory'),
      $container->get('wse_deploy.encryption_handler')
    );
  }

  /**
   * {@inheritdoc}
   */
  public static function isAvailable() {
    return TRUE;
  }

  /**
   * {@inheritdoc}
   */
  public function onWorkspaceExport(WorkspaceInterface $workspace, array $index_data, array $index_files) {
    $deploy_path = $this->configFactory->get('wse_deploy.settings')->get('deploy_path');
    $workspace_export_dir = $deploy_path . '/export/' . $workspace->id();

    // Send the archive containing the workspace data.
    $file_info = [
      'name' => 'upload',
      'filename' => 'export.tar.gz',
      'contents' => file_get_contents($workspace_export_dir . '/export.tar.gz'),
    ];
    $this->sendFile($workspace, 'data', $file_info);

    // Send all the files used by the workspace-tracked entities.
    /** @var \Drupal\file\FileInterface[] $index_files */
    foreach ($index_files as $file) {
      $file_info = [
        'name' => 'upload',
        // In order to support files with the same filename but in different
        // directories, the uploaded filename is the file UUID and its
        // extension. The import process will take care of renaming it back to
        // its original filename when moving it to the final location.
        'filename' => $file->uuid() . '.' . pathinfo($file->getFilename(), PATHINFO_EXTENSION),
        'contents' => file_get_contents($file->getFileUri()),
      ];
      $this->sendFile($workspace, 'files', $file_info);
    }

    // Inform the target that we finished uploading all the data and files.
    $this->updateWorkspaceStatus($workspace, 'ready');
  }

  /**
   * Sends the specified workspace file.
   *
   * @param \Drupal\workspaces\WorkspaceInterface $workspace
   *   The workspace the file belongs to.
   * @param string $type
   *   The type of file being sent.
   * @param array $file_info
   *   The file information as expected by the HTTP client.
   */
  protected function sendFile(WorkspaceInterface $workspace, string $type, array $file_info) {
    // @todo Consider computing the token based on the file content itself.
    //   This may be way more expensive but it is more secure.
    $options = [
      RequestOptions::MULTIPART => [$file_info],
      RequestOptions::QUERY => [
        'token' => $this->encryptionHandler->getExpirableToken($workspace->id(), $file_info['filename']),
      ],
    ];
    $this->httpClient->post($this->configuration['remote_endpoint'] . '/wse-deploy/import/' . $type . '/' . $workspace->id(), $options);
  }

  /**
   * Updates the workspace status on the target environment.
   *
   * @param \Drupal\workspaces\WorkspaceInterface $workspace
   *   The workspace being updated.
   * @param string $status_type
   *   The new status.
   */
  protected function updateWorkspaceStatus(WorkspaceInterface $workspace, string $status_type) {
    $options = [
      RequestOptions::QUERY => [
        'token' => $this->encryptionHandler->getExpirableToken($workspace->id(), $status_type),
      ],
    ];
    $this->httpClient->post($this->configuration['remote_endpoint'] . '/wse-deploy/status/' . $status_type . '/' . $workspace->id(), $options);
  }

  /**
   * {@inheritdoc}
   */
  public function onWorkspacePublish(WorkspaceInterface $workspace) {
    $this->updateWorkspaceStatus($workspace, 'publish');
  }

  /**
   * {@inheritdoc}
   */
  public function onWorkspaceRevert(WorkspaceInterface $workspace) {
    $this->updateWorkspaceStatus($workspace, 'revert');
  }

  /**
   * {@inheritdoc}
   */
  public function defaultConfiguration() {
    return parent::defaultConfiguration() + [
      'remote_endpoint' => '',
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
    $form = parent::buildConfigurationForm($form, $form_state);

    $form['remote_endpoint'] = [
      '#type' => 'url',
      '#title' => $this->t('Remote endpoint'),
      '#description' => $this->t('The URL of the endpoint to POST workspace export content to. <strong>NOTE: it is strongly suggested to use a HTTPS endpoint</strong>.'),
      '#required' => TRUE,
      '#default_value' => $this->configuration['remote_endpoint'],
    ];

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
    parent::submitConfigurationForm($form, $form_state);

    $this->configuration['remote_endpoint'] = rtrim($form_state->getValue('remote_endpoint'), '/');
  }

}

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

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