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

src/Controller/FlowPush.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\Core\Controller\ControllerBase;
use Drupal\Core\Url;
use Symfony\Component\HttpFoundation\RedirectResponse;

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

  /**
   * The push all batch size.
   *
   * @var int
   */
  public const PREPARATION_BATCH_SIZE = 100;

  /**
   * Push all entities of the flow.
   *
   * @param string $cms_content_sync_flow
   *   The flow the entities should be pushed for.
   * @param string $push_mode
   *   The push mode.
   */
  public function push($cms_content_sync_flow, $push_mode) {
    /**
     * @var \Drupal\cms_content_sync\Entity\Flow $flow
     */
    $flow = Flow::getAll()[$cms_content_sync_flow];

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

    $operations = [];
    foreach ($flow->getController()->getEntityTypeConfig(NULL, NULL, TRUE) as $entity_type_name => $bundles) {
      foreach ($bundles as $bundle_name => $config) {
        if ('automatic_manual' == $push_mode || 'automatic_manual_force' == $push_mode) {
          if (PushIntent::PUSH_AUTOMATICALLY != $config['export'] && PushIntent::PUSH_MANUALLY != $config['export']) {
            continue;
          }
        }
        else {
          if (PushIntent::PUSH_AUTOMATICALLY != $config['export']) {
            continue;
          }
        }

        $storage = $entity_type_manager->getStorage($entity_type_name);

        $query = $storage->getQuery();

        // Files don't have bundles, so this would lead to a fatal error then.
        if ($storage->getEntityType()->getKey('bundle')) {
          $query = $query->condition($storage->getEntityType()->getKey('bundle'), $bundle_name);
        }

        $query = $query->count();

        $count = $query->accessCheck(FALSE)->execute();

        if (!$count) {
          continue;
        }

        // @todo A better way would be to have one batch operation that does all
        //   of that and then just dynamically updates the progress.
        //   {@see FlowPull} for an example.
        $pages = ceil($count / self::PREPARATION_BATCH_SIZE);
        for ($i = 0; $i < $pages; ++$i) {
          $operations[] = [
            '\Drupal\cms_content_sync\Controller\FlowPush::batch',
                [
                  $cms_content_sync_flow,
                  $entity_type_name,
                  $bundle_name,
                  $push_mode,
                  $i,
                  $count,
                  FALSE
                ],
          ];
        }
      }
    }

    $operations[count($operations) - 1][1][6] = TRUE;

    $batch = [
      'title' => t('Push items...'),
      'operations' => $operations,
      'finished' => '\Drupal\cms_content_sync\Controller\FlowPush::batchFinished',
    ];

    batch_set($batch);

    return batch_process();
  }

  /**
   * Batch push finished callback.
   */
  public static function batchFinished($success, $results, $operations) {
    return new RedirectResponse(Url::fromRoute('entity.cms_content_sync_flow.collection')->toString());
  }

  /**
   * Batch push callback for the push-all operation.
   *
   * @param string $flow_id
   *   The flow id for the push operation.
   * @param string $entity_type_id
   *   The entity type id for the push operation.
   * @param string $bundle_name
   *   The bundle name for the push operation.
   * @param string $push_mode
   *   The push mode for the push operation.
   * @param int $page
   *   The page for the push operation.
   * @param int $count
   *   The number of items to push to the sync core.
   * @param int $last
   *   The last page number for the push operation.
   * @param array $context
   *   The context for the push operation.
   *
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   */
  public static function batch($flow_id, $entity_type_id, $bundle_name, $push_mode, $page, $count, $last, array &$context) {
    $message = 'Checking ' . $entity_type_id . '.' . $bundle_name . ' page ' . ($page + 1) . '/' . ceil($count / self::PREPARATION_BATCH_SIZE) . '...';
    $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');

    $operations = new PushEntities();

    $storage = $entity_type_manager->getStorage($entity_type_id);

    $query = $storage->getQuery();

    // Files don't have bundles, so this would lead to a fatal error then.
    if ($storage->getEntityType()->getKey('bundle')) {
      $query = $query->condition($storage->getEntityType()->getKey('bundle'), $bundle_name);
    }

    $query = $query->range($page * self::PREPARATION_BATCH_SIZE, self::PREPARATION_BATCH_SIZE);

    $ids = $query->accessCheck(FALSE)->execute();

    foreach ($ids as $id) {
      $entity = $storage->load($id);

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

      $is_manual = PushIntent::PUSH_MANUALLY == $flow->getController()->getEntityTypeConfig($entity->getEntityTypeId(), $entity->bundle())['export'];

      // If this is manual AND the export doesn't say FORCE, we skip this entity if it wasn't exported before.
      if ('automatic_manual' == $push_mode && $is_manual && (empty($entity_status) || is_null($entity_status[0]->getLastPush()))) {
        continue;
      }

      $operations->add($flow_id, $entity_type_id, $id);
    }

    $context['message'] = $message;
    $context['results'] = array_merge($results, $operations->get());

    // can't do this in the finished callback unfortunately as Drupal errs out with "No active batch" then or goes into
    // an infinite batch loop.
    if ($last) {
      $pusher = new PushEntities($context['results']);
      $pusher->start();
    }
  }

}

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

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