cms_content_sync-3.0.x-dev/src/Plugin/cms_content_sync/entity_handler/DefaultConfigEntityHandler.php

src/Plugin/cms_content_sync/entity_handler/DefaultConfigEntityHandler.php
<?php

namespace Drupal\cms_content_sync\Plugin\cms_content_sync\entity_handler;

use Drupal\cms_content_sync\Plugin\EntityHandlerBase;
use Drupal\cms_content_sync\PullIntent;
use Drupal\cms_content_sync\PushIntent;
use Drupal\cms_content_sync\SyncIntent;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Url;
use EdgeBox\SyncCore\Interfaces\Configuration\IDefineEntityType;
use EdgeBox\SyncCore\V2\Configuration\DefineProperty;

/**
 * Class DefaultConfigEntityHandler.
 *
 * Providing a minimalistic implementation for any config entity type.
 *
 * @EntityHandler(
 *   id = "cms_content_sync_default_config_entity_handler",
 *   label = @Translation("Default Config"),
 *   weight = 100
 * )
 */
class DefaultConfigEntityHandler extends EntityHandlerBase {

  /**
   * {@inheritdoc}
   */
  public static function supports($entity_type, $bundle) {
    // Whitelist supported entity types.
    $entity_types = [
      'block',
      'entity_queue',
      'view',
      'webform',
    ];

    return in_array($entity_type, $entity_types);
  }

  /**
   * Update the entity type definition.
   *
   * @param \EdgeBox\SyncCore\Interfaces\Configuration\IDefineEntityType|EdgeBox\SyncCore\V2\Configuration\DefineProperty $definition
   *   The entity type definition.
   * @param array $config_properties
   *   The configuration properties.
   */
  public function updateEntityTypeDefinition(IDefineEntityType|DefineProperty &$definition, ?array $config_properties = NULL) {
    if (!$config_properties) {
      $config_properties = $this->getConfigProperties();
    }

    // TODO: Export additional constraints like allowed values.
    foreach ($config_properties as $key => $config) {
      $remoteType = $this->getPropertyTypeForConfigType($config['type']);

      $multiple = FALSE;
      if ('array' === $remoteType) {
        $multiple = TRUE;
        $remoteType = $this->getPropertyTypeForConfigType($config['sequence']['type']);
      }

      if (empty($remoteType) || 'ignore' === $remoteType) {
        continue;
      }

      $label = empty($config['label']) ? $key : $config['label'];

      if ('string' === $remoteType) {
        $definition->addStringProperty($key, $label, $multiple, FALSE, $config['type']);
      }
      elseif ('boolean' === $remoteType) {
        $definition->addBooleanProperty($key, $label, $multiple, FALSE, $config['type']);
      }
      elseif ('integer' === $remoteType) {
        $definition->addIntegerProperty($key, $label, $multiple, FALSE, $config['type']);
      }
      elseif ('float' === $remoteType) {
        $definition->addFloatProperty($key, $label, $multiple, FALSE, $config['type']);
      }
      elseif ('object' === $remoteType) {
        $property = $definition->addObjectProperty($key, $label, $multiple, FALSE, $config['type']);
        if (!empty($config['mapping'])) {
          $this->updateEntityTypeDefinition($property, $config['mapping']);
        }
        elseif (!empty($config['sequence']['type'])) {
          $this->updateEntityTypeDefinition($property, ['*' => $config['sequence']]);
        }
        // TODO: Add support for nested types (type references).
      }
    }
  }

  /**
   * {@inheritdoc}
   */
  public function getAllowedPreviewOptions() {
    return [];
  }

  /**
   * {@inheritdoc}
   */
  public function push(PushIntent $intent, ?EntityInterface $entity = NULL) {
    if (!parent::push($intent, $entity)) {
      return FALSE;
    }

    if (!$entity) {
      $entity = $intent->getEntity();
    }

    /**
     * @var \Drupal\Core\Config\Entity\ConfigEntityInterface $entity
     */
    foreach ($this->getConfigProperties() as $property => $config) {
      $remoteType = $this->getPropertyTypeForConfigType($config['type']);
      if (empty($remoteType) || 'ignore' === $remoteType) {
        continue;
      }

      $entity_property = $entity->get($property);
      // Avoid incorrect serialization of empty objects. As PHP uses associative
      // arrays instead of objects, an empty associative array will become
      // "[]" in JSON although it should be "{}" which will lead to a validation
      // error response from the Sync Core that expects an object and not
      // an array.
      if (is_array($entity_property) && !count($entity_property)) {
        $entity_property = NULL;
      }

      $intent->setProperty($property, $entity_property);
    }

    if ('block' === $this->entityTypeName) {
      $plugin = $entity->get('plugin');
      // Add block content as a dependency.
      if ('block_content:' === substr($plugin, 0, 14)) {
        $block_uuid = substr($plugin, 14);
        $block_content = \Drupal::service('entity.repository')
          ->loadEntityByUuid('block_content', $block_uuid);
        $intent->addDependency($block_content);
      }
    }

    return TRUE;
  }

  /**
   * Pull the remote entity.
   *
   * {@inheritdoc}
   */
  public function pull(PullIntent $intent) {
    $action = $intent->getAction();

    if (!parent::pull($intent)) {
      return FALSE;
    }

    if (SyncIntent::ACTION_DELETE === $action) {
      return TRUE;
    }

    /**
     * @var \Drupal\Core\Config\Entity\ConfigEntityInterface $entity
     */
    $entity = $intent->getEntity();

    $forbidden_fields = $this->getForbiddenFields();

    foreach ($this->getConfigProperties() as $property => $config) {
      if (in_array($property, $forbidden_fields)) {
        continue;
      }
      $type = $this->getPropertyTypeForConfigType($config['type']);

      if (empty($type) || $type === 'ignore') {
        continue;
      }

      $value = $intent->getProperty($property);
      if (NULL === $value) {
        if ('object' === $type || 'array' === $type) {
          $value = [];
        }
      }

      $entity->set($property, $value);
    }

    $entity->save();

    return TRUE;
  }

  /**
   * {@inheritDoc}
   */
  public function getViewUrl(EntityInterface $entity) {
    if ('view' === $entity->getEntityTypeId()) {
      return Url::fromRoute('entity.view.edit_form', ['view' => $entity->id()], ['absolute' => TRUE])->toString();
    }
    if ('block' === $entity->getEntityTypeId()) {
      return Url::fromRoute('entity.block.edit_form', ['block' => $entity->id()], ['absolute' => TRUE])->toString();
    }

    return parent::getViewUrl($entity);
  }

  /**
   * Get the property type for a config type.
   *
   * @param string $type
   *   The config type to check for.
   */
  protected function getPropertyTypeForConfigType($type) {
    // Add properties that are listed as "config_export" keys from the entity
    // type annotation.
    static $typeMapping = [
      'uuid' => 'string',
      'boolean' => 'boolean',
      'email' => 'string',
      'integer' => 'integer',
      'float' => 'float',
      'string' => 'string',
      'id' => 'string',
      'text' => 'string',
      'label' => 'string',
      'langcode' => 'string',
      'uri' => 'string',
      'mapping' => 'object',
      'sequence' => 'object',
      'config_dependencies' => 'object',
      'block.settings.[%parent.plugin]' => 'object',
      'entityqueue_handler_configuration.[%parent.handler]' => 'object',
      '_core_config_info' => 'ignore',
    ];

    return empty($typeMapping[$type]) ? NULL : $typeMapping[$type];
  }

  /**
   * {@inheritDoc}
   */
  protected function getBaseEntityProperties(PullIntent $intent) {
    $properties = parent::getBaseEntityProperties($intent);
    $properties['plugin'] = $intent->getProperty('plugin');

    return $properties;
  }

  /**
   * Get all config properties for this entity type.
   *
   * @return array
   *   The config properties for this entity type.
   */
  protected function getConfigProperties() {
    /**
     * @var \Drupal\Core\Config\Entity\ConfigEntityTypeInterface $entity_type
     */
    $entity_type = \Drupal::entityTypeManager()->getDefinition($this->entityTypeName);

    $properties = $entity_type->getPropertiesToExport();
    if (!$properties) {
      return [];
    }

    $prefix = $entity_type->getConfigPrefix();
    $config_definition = \Drupal::service('config.typed')->getDefinition($prefix . '.' . $this->bundleName . '.*');
    if (empty($config_definition['mapping'])) {
      return [];
    }

    $mapping = $config_definition['mapping'];

    $result = [];

    foreach ($properties as $property) {
      // Wrong information from webform schema definition...
      // Associative arrays are NOT sequences.
      if ('webform' === $this->entityTypeName && 'access' === $property) {
        $mapping[$property]['type'] = 'mapping';
      }

      $result[$property] = $mapping[$property];
    }

    return $result;
  }

  /**
   * Check whether the entity type supports having a label.
   *
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   *
   * @return bool
   *   True if the entity type supports having a label.
   */
  protected function hasLabelProperty() {
    return TRUE;
  }

}

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

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