You are here

public function SyncCoreFlowExport::addConfiguration in CMS Content Sync 8

Same name and namespace in other branches
  1. 2.1.x src/SyncCoreFlowExport.php \Drupal\cms_content_sync\SyncCoreFlowExport::addConfiguration()
  2. 2.0.x src/SyncCoreFlowExport.php \Drupal\cms_content_sync\SyncCoreFlowExport::addConfiguration()

Create all entity types, connections and synchronizations as required.

Parameters

\EdgeBox\SyncCore\Interfaces\Configuration\IDefineFlow $flow_definition:

$pool_configurations:

\EdgeBox\SyncCore\Interfaces\IBatch $batch:

bool $extend_only:

bool $force:

Throws

\EdgeBox\SyncCore\Exception\SyncCoreException

1 call to SyncCoreFlowExport::addConfiguration()
SyncCoreFlowExport::prepareBatch in src/SyncCoreFlowExport.php
Create all entity types, connections and synchronizations as required.

File

src/SyncCoreFlowExport.php, line 108

Class

SyncCoreFlowExport
Class SyncCoreFlowExport used to export the Synchronization config to the Sync Core backend.

Namespace

Drupal\cms_content_sync

Code

public function addConfiguration($flow_definition, &$pool_configurations, $batch, $extend_only = false, $force = false) {

  // Ignore disabled flows at export.
  if (!$this->flow
    ->get('status')) {
    return;
  }
  $enable_preview = ContentSyncSettings::getInstance()
    ->isPreviewEnabled();
  $entity_types = $this->flow->sync_entities;
  $pools = Pool::getAll();
  $export_pools = [];
  foreach ($this->flow
    ->getEntityTypeConfig() as $id => $type) {
    $entity_type_name = $type['entity_type_name'];
    $bundle_name = $type['bundle_name'];
    $version = $type['version'];
    if (Flow::HANDLER_IGNORE == $type['handler']) {
      continue;
    }
    $current = Flow::getEntityTypeVersion($entity_type_name, $bundle_name);
    if ($current !== $version) {
      throw new \Exception("Entity type {$entity_type_name}.{$bundle_name} was changed without updating Flow {$this->flow->id}. Please re-save that Flow first to apply the latest entity type changes.");
    }
    $handler = $this->flow
      ->getEntityTypeHandler($type);
    $entity_type_pools = [];
    if (isset($type['import_pools'])) {
      foreach ($type['import_pools'] as $pool_id => $state) {
        if (!isset($entity_type_pools[$pool_id])) {
          $entity_type_pools[$pool_id] = [];
        }
        if (PullIntent::PULL_DISABLED == $type['import']) {
          $entity_type_pools[$pool_id]['import'] = Pool::POOL_USAGE_FORBID;
          continue;
        }
        $entity_type_pools[$pool_id]['import'] = $state;
      }
    }
    if (isset($type['export_pools'])) {
      foreach ($type['export_pools'] as $pool_id => $state) {
        if (!isset($entity_type_pools[$pool_id])) {
          $entity_type_pools[$pool_id] = [];
        }
        if (PushIntent::PUSH_DISABLED == $type['export']) {
          $entity_type_pools[$pool_id]['export'] = Pool::POOL_USAGE_FORBID;
          continue;
        }
        $entity_type_pools[$pool_id]['export'] = $state;
      }
    }
    foreach ($entity_type_pools as $pool_id => $definition) {
      if (empty($pools[$pool_id])) {
        continue;
      }
      $pool = $pools[$pool_id];
      $export = null;
      $import = null;
      if (isset($definition['export'])) {
        $export = $definition['export'];
      }
      if (isset($definition['import'])) {
        $import = $definition['import'];
      }
      if ((!$export || Pool::POOL_USAGE_FORBID == $export) && (!$import || Pool::POOL_USAGE_FORBID == $import)) {
        continue;
      }
      if (!in_array($pool, $export_pools)) {
        $export_pools[] = $pool;
      }
      $entity_type_id_without_version = $entity_type_name . '-' . $bundle_name;
      if ($extend_only) {
        if (!isset($pool_configurations[$pool_id])) {
          continue;
        }
      }
      $pull_condition = [];
      if (EntityHandlerPluginManager::isEntityTypeFieldable($entity_type_name)) {
        $entityFieldManager = \Drupal::service('entity_field.manager');

        /** @var \Drupal\Core\Field\FieldDefinitionInterface[] $fields */
        $fields = $entityFieldManager
          ->getFieldDefinitions($entity_type_name, $bundle_name);
        $forbidden = $handler
          ->getForbiddenFields();
        foreach ($fields as $key => $field) {
          if (!isset($entity_types[$id . '-' . $key])) {
            continue;
          }
          if (in_array($key, $forbidden)) {
            continue;
          }
          if (!empty($entity_types[$id . '-' . $key]['handler_settings']['subscribe_only_to'])) {
            $allowed = [];
            foreach ($entity_types[$id . '-' . $key]['handler_settings']['subscribe_only_to'] as $ref) {
              $allowed[] = $ref['uuid'];
            }
            $pull_condition[$key] = $allowed;
          }
        }
      }
      if ($extend_only) {
        if (isset($pool_configurations[$pool_id]['entity_types'][$entity_type_id_without_version])) {
          if (Pool::POOL_USAGE_FORBID != $import && PullIntent::PULL_DISABLED != $type['import']) {

            /**
             * @var \EdgeBox\SyncCore\Interfaces\Configuration\IFlowPullConfiguration $pull_configuration
             */
            $pull_configuration = $pool_configurations[$pool_id]['entity_types'][$entity_type_id_without_version];
            $override = $pull_configuration
              ->configureOverride($this->flow->id)
              ->manually(PullIntent::PULL_MANUALLY == $type['import'])
              ->asDependency(PullIntent::PULL_AS_DEPENDENCY == $type['import'])
              ->pullDeletions(boolval($type['import_deletion_settings']['import_deletion']));
            foreach ($pull_condition as $property => $allowed_entity_ids) {
              $override
                ->ifTaggedWith($property, $allowed_entity_ids);
            }
          }
          continue;
        }
      }
      $entity_type = $this->client
        ->getConfigurationService()
        ->defineEntityType($pool_id, $entity_type_name, $bundle_name, $version)
        ->isTranslatable(true)
        ->addObjectProperty('metadata')
        ->addObjectProperty('menu_items', true);
      if (EntityHandlerPluginManager::isEntityTypeFieldable($entity_type_name)) {
        $entityFieldManager = \Drupal::service('entity_field.manager');

        /** @var \Drupal\Core\Field\FieldDefinitionInterface[] $fields */
        $fields = $entityFieldManager
          ->getFieldDefinitions($entity_type_name, $bundle_name);
        $forbidden = $handler
          ->getForbiddenFields();
        foreach ($fields as $key => $field) {
          if (!isset($entity_types[$id . '-' . $key])) {
            continue;
          }
          if (in_array($key, $forbidden)) {
            continue;
          }
          $entity_type
            ->addObjectProperty($key, true, $field
            ->isRequired());
        }
      }

      // Remote sites must use the same entity type handler otherwise sync
      // will fail- at least for these properties or it will not work at all.
      $handler
        ->updateEntityTypeDefinition($entity_type);

      // Dispatch EntityTypeExport event to give other modules the possibility
      // to adjust the entity type definition and add custom fields.
      \Drupal::service('event_dispatcher')
        ->dispatch(BeforeEntityTypeExport::EVENT_NAME, new BeforeEntityTypeExport($entity_type_name, $bundle_name, $entity_type));

      // Create the entity type.
      $entity_type
        ->addToBatch($batch);

      /**
       * @var \EdgeBox\SyncCore\Interfaces\Configuration\IDefinePoolForFlow $pool_definition
       */
      if (isset($pool_configurations[$pool_id])) {

        // If the given entity type has added before, we don't add it a second time.
        $pool_definition = $pool_configurations[$pool_id]['pool_definition'];
      }
      else {
        $pool_definition = $flow_definition
          ->usePool($pool_id);
        $pool_configurations[$pool_id] = [
          'pool_definition' => $pool_definition,
          'entity_types' => [],
        ];
      }
      $pool_definition
        ->useEntityType($entity_type);
      if ($extend_only) {
        continue;
      }

      // Create a synchronization from the pool to the preview connection.
      if ($enable_preview) {
        $pool_definition
          ->enablePreview($entity_type);
      }
      if (Pool::POOL_USAGE_FORBID != $export && PushIntent::PUSH_DISABLED != $type['export']) {
        $pool_definition
          ->enablePush($entity_type);
      }
      if (Pool::POOL_USAGE_FORBID != $import && PullIntent::PULL_DISABLED != $type['import']) {
        $pull_configuration = $pool_definition
          ->enablePull($entity_type)
          ->manually(PullIntent::PULL_MANUALLY == $type['import'])
          ->asDependency(PullIntent::PULL_AS_DEPENDENCY == $type['import'])
          ->pullDeletions(boolval($type['import_deletion_settings']['import_deletion']))
          ->addToBatch($batch);
        $pool_configurations[$pool_id]['entity_types'][$entity_type_id_without_version] = $pull_configuration;
        foreach ($pull_condition as $property => $allowed_entity_ids) {
          $pull_configuration
            ->ifTaggedWith($property, $allowed_entity_ids);
        }
      }
    }
  }
  if ($extend_only) {
    return;
  }

  // Always export required pools as well to prevent any potential issues.
  // @todo Optimize when called via Drush to not send the same pool requests for multiple Flows.
  $subsequent = false;
  foreach ($export_pools as $pool) {
    $exporter = new SyncCorePoolExport($pool);
    $batch
      ->prepend($exporter
      ->prepareBatch($subsequent, $force));
    $subsequent = true;
  }
}