You are here

class FlowPush in CMS Content Sync 2.1.x

Same name and namespace in other branches
  1. 8 src/Controller/FlowPush.php \Drupal\cms_content_sync\Controller\FlowPush
  2. 2.0.x src/Controller/FlowPush.php \Drupal\cms_content_sync\Controller\FlowPush

Pull controller.

Note that this controller is also used by the draggableviews submodule.

Hierarchy

Expanded class hierarchy of FlowPush

File

src/Controller/FlowPush.php, line 17

Namespace

Drupal\cms_content_sync\Controller
View source
class FlowPush extends ControllerBase {

  /**
   * @var int
   */
  public const PREPARATION_BATCH_SIZE = 100;

  /**
   * Push all entities of the flow.
   *
   * @param string $cms_content_sync_flow
   * @param string $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
          ->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.
   *
   * @param $success
   * @param $results
   * @param $operations
   */
  public static function batchFinished($success, $results, $operations) {
    return RedirectResponse::create(Url::fromRoute('entity.cms_content_sync_flow.collection')
      ->toString());
  }

  /**
   * Batch push callback for the push-all operation.
   *
   * @param string $flow_id
   * @param string $entity_type_id
   * @param string $bundle_name
   * @param string $push_mode
   * @param int    $page
   * @param int    $count
   * @param $last
   * @param $context
   *
   * @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, &$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
      ->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();
    }
  }

}

Members

Namesort descending Modifiers Type Description Overrides
ControllerBase::$configFactory protected property The configuration factory.
ControllerBase::$currentUser protected property The current user service. 1
ControllerBase::$entityFormBuilder protected property The entity form builder.
ControllerBase::$entityTypeManager protected property The entity type manager.
ControllerBase::$formBuilder protected property The form builder. 2
ControllerBase::$keyValue protected property The key-value storage. 1
ControllerBase::$languageManager protected property The language manager. 1
ControllerBase::$moduleHandler protected property The module handler. 2
ControllerBase::$stateService protected property The state service.
ControllerBase::cache protected function Returns the requested cache bin.
ControllerBase::config protected function Retrieves a configuration object.
ControllerBase::container private function Returns the service container.
ControllerBase::create public static function Instantiates a new instance of this class. Overrides ContainerInjectionInterface::create 46
ControllerBase::currentUser protected function Returns the current user. 1
ControllerBase::entityFormBuilder protected function Retrieves the entity form builder.
ControllerBase::entityTypeManager protected function Retrieves the entity type manager.
ControllerBase::formBuilder protected function Returns the form builder service. 2
ControllerBase::keyValue protected function Returns a key/value storage collection. 1
ControllerBase::languageManager protected function Returns the language manager service. 1
ControllerBase::moduleHandler protected function Returns the module handler. 2
ControllerBase::redirect protected function Returns a redirect response object for the specified route.
ControllerBase::state protected function Returns the state storage service.
FlowPush::batch public static function Batch push callback for the push-all operation.
FlowPush::batchFinished public static function Batch push finished callback.
FlowPush::PREPARATION_BATCH_SIZE public constant
FlowPush::push public function Push all entities of the flow.
LoggerChannelTrait::$loggerFactory protected property The logger channel factory service.
LoggerChannelTrait::getLogger protected function Gets the logger for a specific channel.
LoggerChannelTrait::setLoggerFactory public function Injects the logger channel factory.
MessengerTrait::$messenger protected property The messenger. 27
MessengerTrait::messenger public function Gets the messenger. 27
MessengerTrait::setMessenger public function Sets the messenger.
RedirectDestinationTrait::$redirectDestination protected property The redirect destination service. 1
RedirectDestinationTrait::getDestinationArray protected function Prepares a 'destination' URL query parameter for use with \Drupal\Core\Url.
RedirectDestinationTrait::getRedirectDestination protected function Returns the redirect destination service.
RedirectDestinationTrait::setRedirectDestination public function Sets the redirect destination service.
StringTranslationTrait::$stringTranslation protected property The string translation service. 4
StringTranslationTrait::formatPlural protected function Formats a string containing a count of items.
StringTranslationTrait::getNumberOfPlurals protected function Returns the number of plurals supported by a given language.
StringTranslationTrait::getStringTranslation protected function Gets the string translation service.
StringTranslationTrait::setStringTranslation public function Sets the string translation service to use. 2
StringTranslationTrait::t protected function Translates a string to the current language or to a given language.