You are here

public function SyncCoreFlowExport::addConfiguration in CMS Content Sync 2.1.x

Same name and namespace in other branches
  1. 8 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 135

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();
  $pools = Pool::getAll();
  $export_pools = [];
  foreach ($this->flow
    ->getController()
    ->getEntityTypeConfig(null, null, false, true) as $entity_type_name => $bundles) {
    foreach ($bundles as $bundle_name => $type) {
      $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
        ->getController()
        ->getEntityTypeHandler($entity_type_name, $bundle_name, $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) {
            $field_config = $this->flow
              ->getController()
              ->getPropertyConfig($entity_type_name, $bundle_name, $key);
            if (!$field_config) {
              continue;
            }
            if (in_array($key, $forbidden)) {
              continue;
            }
            if (!empty($field_config['handler_settings']['subscribe_only_to'])) {
              $allowed = [];
              foreach ($field_config['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_label = \Drupal::service('entity_type.bundle.info')
          ->getAllBundleInfo()[$entity_type_name][$bundle_name]['label'];
        $entity_type = $this->client
          ->getConfigurationService()
          ->defineEntityType($pool_id, $entity_type_name, $bundle_name, $version, $entity_type_label)
          ->isTranslatable(true)
          ->addObjectProperty('metadata', 'Metadata')
          ->addObjectProperty('menu_items', '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();
          $added = [];
          foreach ($fields as $key => $field) {
            $field_config = $this->flow
              ->getController()
              ->getPropertyConfig($entity_type_name, $bundle_name, $key);
            if (!$field_config) {
              continue;
            }
            if (in_array($key, $forbidden)) {
              continue;
            }
            $field_handler = $this->flow
              ->getController()
              ->getFieldHandler($entity_type_name, $bundle_name, $key);
            if (!$field_handler) {
              continue;
            }
            $field_handler
              ->definePropertyAtType($entity_type);
            $added[] = $key;
          }
          if (!in_array('created', $added)) {
            if ($this->flow
              ->useV2()) {
              $entity_type
                ->addObjectProperty('created', 'Created', false, false);
            }
            else {
              $entity_type
                ->addIntegerProperty('created', 'Created', false, false);
            }
          }
          if (!in_array('changed', $added)) {
            if ($this->flow
              ->useV2()) {
              $entity_type
                ->addObjectProperty('changed', 'Changed', false, false);
            }
            else {
              $entity_type
                ->addIntegerProperty('changed', 'Changed', false, false);
            }
          }
        }

        // 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']) {
          $push_config = $pool_definition
            ->enablePush($entity_type);
          if ($push_config) {
            $push_config
              ->manually(PushIntent::PUSH_MANUALLY == $type['export'])
              ->asDependency(PushIntent::PUSH_AS_DEPENDENCY == $type['export'])
              ->pushDeletions(boolval($type['export_deletion_settings']['export_deletion']));
          }
        }
        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.
  $subsequent = $this->subsequent;
  foreach ($export_pools as $pool) {
    $exporter = new SyncCorePoolExport($pool);
    $batch
      ->prepend($exporter
      ->prepareBatch($subsequent, $force));
    $subsequent = true;
  }
}