cms_content_sync-3.0.x-dev/src/Controller/PushEntities.php

src/Controller/PushEntities.php
<?php

namespace Drupal\cms_content_sync\Controller;

use Drupal\cms_content_sync\Entity\EntityStatus;
use Drupal\cms_content_sync\Entity\Flow;
use Drupal\cms_content_sync\PushIntent;
use Drupal\cms_content_sync\SyncIntent;
use Drupal\Core\Controller\ControllerBase;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Entity\EntityInterface;

/**
 * Pull controller.
 *
 * Note that this controller is also used by the draggableviews submodule.
 */
class PushEntities extends ControllerBase {

  /**
   * The operations to perform.
   *
   * @var null|array
   */
  protected $operations = [];

  /**
   * The title of the entity to be pushed.
   *
   * @var \Drupal\Core\StringTranslation\TranslatableMarkup
   */
  protected $title;

  /**
   * The push entities batch callback.
   *
   * @var array|string
   */
  protected $callback;

  /**
   * Show skipped option.
   *
   * @var bool
   */
  protected $showSkipped = FALSE;

  /**
   * Skip unpushed option.
   *
   * @var bool
   */
  protected $skipUnpushed = FALSE;

  /**
   * The skipped unpushed entities.
   *
   * @var array
   */
  protected $skippedUnpushed = [];

  /**
   * The skipped entities due to no matching flow.
   *
   * @var array
   */
  protected $skippedNoFlow = [];

  /**
   * PushEntities constructor.
   *
   * @param null|array $existing
   *   Already existing operations.
   */
  public function __construct($existing = NULL) {
    $this->operations = $existing;
    $this->title = t('Push content');
    $this->callback = '\Drupal\cms_content_sync\Controller\PushEntities::batchFinished';
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, $existing = NULL) {
    return new PushEntities($existing);
  }

  /**
   * Skip unpushed entities.
   *
   * @return $this
   */
  public function skipUnpushed() {
    $this->skipUnpushed = TRUE;

    return $this;
  }

  /**
   * Show skipped entities.
   *
   * @return $this
   */
  public function showSkipped() {
    if ($count = count($this->skippedNoFlow)) {
      $list = [
        '#theme' => 'item_list',
        '#items' => $this->getSkippedNoFlow(TRUE)
      ];

      \Drupal::messenger()->addWarning(
            \Drupal::translation()->translate(
                "%count items were not pushed as they're not configured to be pushed: @items",
                [
                  '%count' => $count,
                  '@items' => \Drupal::service('renderer')->render($list),
                ]
            )
        );
    }

    if ($count = count($this->skippedUnpushed)) {
      $list = [
        '#theme' => 'item_list',
        '#items' => $this->getSkippedUnpushed(TRUE)
      ];

      \Drupal::messenger()->addStatus(
            \Drupal::translation()->translate(
                "%count items were not pushed as they weren't pushed before: @items",
                [
                  '%count' => $count,
                  '@items' => \Drupal::service('renderer')->render($list),
                ]
            )
        );
    }

    return $this;
  }

  /**
   * Returns the skipped unpushed entities.
   *
   * @param bool $labelsOnly
   *   Return only the labels of the unpushed entities.
   *
   * @return array
   *   The skipped unpushed entities.
   */
  public function getSkippedUnpushed($labelsOnly = FALSE) {
    return $labelsOnly ? $this->getLabels($this->skippedUnpushed) : $this->skippedUnpushed;
  }

  /**
   * Returns the skipped no flow entities.
   *
   * @param bool $labelsOnly
   *   Return only the labels of the unpushed entities.
   *
   * @return array
   *   The skipped no flow entities.
   */
  public function getSkippedNoFlow($labelsOnly = FALSE) {
    return $labelsOnly ? $this->getLabels($this->skippedNoFlow) : $this->skippedNoFlow;
  }

  /**
   * Adds an entity to a push operation.
   *
   * @param \Drupal\Core\Entity\EntityInterface $entity
   *   The entity to be added.
   *
   * @return $this
   */
  public function addEntity(EntityInterface $entity) {
    $flows = PushIntent::getFlowsForEntity($entity, PushIntent::PUSH_FORCED, SyncIntent::ACTION_CREATE);

    if (!count($flows)) {
      $this->skippedNoFlow[] = $entity;

      return $this;
    }

    $flow_id = $flows[0]->id();

    /**
     * @var \Drupal\cms_content_sync\Entity\EntityStatus[] $entity_status
     */
    $entity_status = EntityStatus::getInfosForEntity($entity->getEntityTypeId(), $entity->uuid(), ['flow' => $flow_id]);

    if ($this->skipUnpushed) {
      if (!count($entity_status) || !$entity_status[0]->getLastPush()) {
        $this->skippedUnpushed[] = $entity;

        return $this;
      }
    }

    $this->add($flow_id, $entity->getEntityTypeId(), $entity->id());

    return $this;
  }

  /**
   * Get the operations that were already added.
   *
   * You can use them when instantiating this class again later to keep the
   * existing operations and add on top of them.
   *
   * @return null|array
   *   The operations that were already added.
   */
  public function get() {
    return $this->operations;
  }

  /**
   * Add entity into push operation.
   *
   * @param string $flow_id
   *   The id of the flow.
   * @param string $entity_type_id
   *   The entity type id.
   * @param int $entity_id
   *   The entity id.
   *
   * @return $this
   *   The current instance of the operation.
   */
  public function add($flow_id, $entity_type_id, $entity_id) {
    $this->operations[] = [
      '\Drupal\cms_content_sync\Controller\PushEntities::batch',
          [$flow_id, $entity_type_id, $entity_id],
    ];

    return $this;
  }

  /**
   * Sets the entity title for the push operation.
   *
   * @param string $set
   *   The entity title.
   *
   * @return $this
   *   The current instance of the operation.
   */
  public function setTitle($set) {
    $this->title = $set;

    return $this;
  }

  /**
   * Set the callback for the push operation.
   *
   * @param array|string $set
   *   The callback to be set.
   *
   * @return $this
   *   The current instance of the operation.
   */
  public function setCallback($set) {
    $this->callback = $set;

    return $this;
  }

  /**
   * Start the actual batch operation.
   *
   * @param null|\Drupal\Core\Url $url
   *   The URL to return to after the batch operation is finished.
   *
   * @return null|\Symfony\Component\HttpFoundation\RedirectResponse
   *   NULL or the RedirectResponse based on the URL.
   */
  public function start($url = NULL) {
    $batch = [
      'title' => $this->title,
      'operations' => $this->operations,
      'finished' => $this->callback,
    ];

    batch_set($batch);

    if ($url) {
      return batch_process($url);
    }

    return NULL;
  }

  /**
   * Check if there actually are any operations to perform now.
   *
   * @return bool
   *   TRUE if there are operations to perform, FALSE otherwise.
   */
  public function isEmpty() {
    return !count($this->operations);
  }

  /**
   * Batch push finished callback.
   *
   * @param bool $success
   *   True if the batch operation was successful.
   * @param array $results
   *   The resuluts of the batch operation.
   * @param array $operations
   *   The operations that were already added.
   */
  public static function batchFinished($success, array $results, array $operations) {
    $succeeded = count(array_filter($results));
    \Drupal::messenger()->addMessage(t('%synchronized items have been pushed to your @repository.', [
      '@repository' => _cms_content_sync_get_repository_name(),
      '%synchronized' => $succeeded
    ]));

    $failed = count($results) - $succeeded;
    if ($failed) {
      \Drupal::messenger()->addMessage(t('%synchronized items have not been pushed to your @repository.', [
        '@repository' => _cms_content_sync_get_repository_name(),
        '%synchronized' => $failed
      ]));
    }
  }

  /**
   * The batch push callback.
   *
   * Batch push callback used by the following operations:
   * - Flow: Push All
   * - Content overview: Push changes
   * - Draggableviews: Push changes.
   *
   * @param string $flow_id
   *   The id of the flow.
   * @param string $entity_type_id
   *   The id of the entity type.
   * @param int $entity_id
   *   The id of the entity.
   * @param array $context
   *   The context for the operation.
   *
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   * @throws \GuzzleHttp\Exception\GuzzleException
   */
  public static function batch($flow_id, $entity_type_id, $entity_id, array &$context) {
    $message = 'Pushing...';
    $results = [];
    if (isset($context['results'])) {
      $results = $context['results'];
    }

    /**
     * @var \Drupal\cms_content_sync\Entity\Flow $flow
     */
    $flow = Flow::getAll()[$flow_id];

    /**
     * @var \Drupal\Core\Entity\EntityTypeManager $entity_type_manager
     */
    $entity_type_manager = \Drupal::service('entity_type.manager');

    $entity = $entity_type_manager
      ->getStorage($entity_type_id)
      ->load($entity_id);

    try {
      $status = PushIntent::pushEntity($entity, PushIntent::PUSH_FORCED, SyncIntent::ACTION_CREATE, $flow);
    }
    catch (\Exception $exception) {
      \Drupal::messenger()->addWarning(t('Item %label could not be pushed: %exception', [
        '%label' => $entity->label(),
        '%exception' => $exception->getMessage()
      ]));
      $status = FALSE;
    }

    $results[] = $status;

    $context['message'] = $message;
    $context['results'] = $results;
  }

  /**
   * Get the entity labels.
   *
   * @param array $entities
   *   The entities to get the labels for.
   *
   * @return array
   *   The entity labels.
   */
  protected function getLabels(array $entities) {
    $result = [];
    foreach ($entities as $entity) {
      $result[] = $entity->label();
    }

    return $result;
  }

}

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

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