Commit d590108d authored by mxh's avatar mxh
Browse files

Issue #3325769 by mxh: Support translatability of content

parent c23e74ff
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
@@ -224,6 +224,10 @@ class ParameterForm implements FormInterface, ContainerInjectionInterface {
      '#type' => 'hidden',
      '#value' => $parameter->getType(),
    ];
    $form['config']['weight'] = [
      '#type' => 'hidden',
      '#value' => $parameter_is_new ? $this->collection->getParameters()->count() + 1 : $parameter->getWeight(),
    ];

    return $form;
  }
@@ -308,7 +312,7 @@ class ParameterForm implements FormInterface, ContainerInjectionInterface {
    $config['name'] = $form_state->getValue('name', $form_state->getValue(['config', 'parameter_name'], $config['name'] ?? ''));
    $config['label'] = $form_state->getValue('label', $config['label'] ?? '');
    $config['description'] = $form_state->getValue('description', $config['description'] ?? '');
    $config['weight'] = $config['weight'] ?? $this->collection->getParameters()->count() + 1;
    $config['weight'] = $form_state->getValue(['config', 'weight'], $config['weight'] ?? 0);
    $parameter->setConfiguration($config);
    if (isset($form['parameter']['settings']) && $parameter instanceof PluginFormInterface) {
      $parameter_form_state = SubformState::createForSubform($form['parameter']['settings'], $form, $form_state);
@@ -465,6 +469,9 @@ class ParameterForm implements FormInterface, ContainerInjectionInterface {
    }
    $form_state->set('collection', $this->collection);
    $form_state->set('parameter', $this->parameter);
    if ($this->collection) {
      $form_state->set('langcode', $this->collection->language()->getId());
    }
  }

  /**
+23 −0
Original line number Diff line number Diff line
@@ -5,6 +5,8 @@
 * Parameters module file.
 */

use Drupal\Core\Entity\EntityInterface;
use Drupal\parameters\Entity\EntitySynchronization;
use Drupal\parameters\Plugin\ParameterManager;

/**
@@ -20,3 +22,24 @@ function parameters_entity_bundle_create($entity_type_id, $bundle) {
function parameters_entity_bundle_delete($entity_type_id, $bundle) {
  ParameterManager::get()->clearCachedDefinitions();
}

/**
 * Implements hook_entity_insert().
 */
function parameters_entity_insert(EntityInterface $entity) {
  EntitySynchronization::get()->synchronize($entity);
}

/**
 * Implements hook_entity_update().
 */
function parameters_entity_update(EntityInterface $entity) {
  EntitySynchronization::get()->synchronize($entity);
}

/**
 * Implements hook_entity_translation_insert().
 */
function parameters_entity_translation_insert(EntityInterface $entity) {
  EntitySynchronization::get()->synchronize($entity);
}
+7 −0
Original line number Diff line number Diff line
@@ -34,3 +34,10 @@ services:
      - { name: cache.bin }
    factory: ['@cache_factory', 'get']
    arguments: [parameters_data]
  parameters.entity_synchronization:
    class: Drupal\parameters\Entity\EntitySynchronization
    arguments: ['@state', '@entity_type.manager', '@language_manager']
  parameters.config_override_subscriber:
    class: Drupal\parameters\EventSubscriber\ParametersConfigOverrideSubscriber
    tags:
      - { name: event_subscriber }
+178 −0
Original line number Diff line number Diff line
<?php

namespace Drupal\parameters\Entity;

use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Entity\TranslatableInterface;
use Drupal\Core\Language\LanguageManagerInterface;
use Drupal\Core\State\StateInterface;
use Drupal\language\ConfigurableLanguageManagerInterface;
use Drupal\parameters\Plugin\EntityParameterInterface;
use Drupal\parameters\Plugin\ParameterManager;

/**
 * Synchronizes entities that are managed via parameters.
 */
class EntitySynchronization {

  /**
   * The state system.
   *
   * @var \Drupal\Core\State\StateInterface
   */
  protected StateInterface $state;

  /**
   * The entity type manager.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected EntityTypeManagerInterface $entityTypeManager;

  /**
   * The language manager.
   *
   * @var \Drupal\Core\Language\LanguageManagerInterface
   */
  protected LanguageManagerInterface $languageManager;

  /**
   * Whether synchronization is enabled or not.
   *
   * @var bool
   */
  protected static bool $enabled = TRUE;

  /**
   * Get the service instance of this class.
   *
   * @return \Drupal\parameters\Entity\EntitySynchronization
   *   The service instance.
   */
  public static function get(): EntitySynchronization {
    return \Drupal::service('parameters.entity_synchronization');
  }

  /**
   * Constructs a new ContentSynchronization object.
   *
   * @param \Drupal\Core\State\StateInterface $state
   *   The state system.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entity type manager.
   * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
   *   The language manager.
   */
  public function __construct(StateInterface $state, EntityTypeManagerInterface $entity_type_manager, LanguageManagerInterface $language_manager) {
    $this->state = $state;
    $this->entityTypeManager = $entity_type_manager;
    $this->languageManager = $language_manager;
  }

  /**
   * Synchronizes the entity.
   *
   * @throws \InvalidArgumentException
   *   When the provided entity is new.
   */
  public function synchronize(EntityInterface $entity): void {
    if (!self::$enabled) {
      return;
    }
    $this->setEnabled(FALSE);

    if ($entity->isNew()) {
      throw new \InvalidArgumentException("The entity must not be new.");
    }

    if (!($collection_id = $this->state->get($this->getStateKey($entity)))) {
      return;
    }

    $collection_storage = $this->entityTypeManager->getStorage(ParametersCollectionInterface::ENTITY_TYPE_ID);

    /** @var \Drupal\parameters\Entity\ParametersCollectionInterface $collection */
    if (!($collection = $collection_storage->load($collection_id))) {
      return;
    }

    $entity_parameter = NULL;
    $parameter_entity = NULL;
    foreach ($collection->getParameters() as $parameter) {
      if ($parameter instanceof EntityParameterInterface) {
        $parameter_entity = $parameter->getEntity();
        if ($parameter_entity && $parameter_entity->uuid() && ($parameter_entity->uuid() === $entity->uuid())) {
          $entity_parameter = $parameter;
          break;
        }
      }
    }

    /** @var \Drupal\parameters\Plugin\EntityParameterInterface $entity_parameter */
    if ($entity_parameter) {
      if (($this->languageManager instanceof ConfigurableLanguageManagerInterface) && $collection->language()->getId() !== $entity->language()->getId() && ($entity instanceof TranslatableInterface)) {
        $collection = $this->languageManager->getLanguageConfigOverride($entity->language()->getId(), $collection->getConfigDependencyName());
        $parameter_configs = $collection->get('parameters') ?? [];
        if (isset($parameter_configs[$entity_parameter->getName()])) {
          /** @var \Drupal\parameters\Plugin\Parameter\Content $entity_parameter */
          $entity_parameter = ParameterManager::get()->createInstance($entity_parameter->getPluginId(), $parameter_configs[$entity_parameter->getName()]);
        }
      }
      else {
        $parameter_configs = $collection->get('parameters');
      }

      $entity_parameter->setEntity($entity);
      if (!isset($parameter_configs[$entity_parameter->getName()]) || $parameter_configs[$entity_parameter->getName()] !== $entity_parameter->getConfiguration()) {
        $parameter_configs[$entity_parameter->getName()] = $entity_parameter->getConfiguration();
        $collection->set('parameters', $parameter_configs);
        $collection->save();
      }
    }

    $this->setEnabled(TRUE);
  }

  public function register(EntityInterface $entity, ParametersCollectionInterface $collection): void {
    $this->state->set($this->getStateKey($entity), $collection->id());
  }

  public function unregister(EntityInterface $entity, ParametersCollectionInterface $collection): void {
    $this->state->delete($this->getStateKey($entity));
  }

  /**
   * Generates a state key for registry lookup.
   *
   * @return string
   *   The state key.
   */
  public function getStateKey(EntityInterface $entity): string {
    return "parameters:managed:{$entity->getEntityTypeId()}:{$entity->uuid()}";
  }

  /**
   * Whether synchronization is enabled.
   *
   * @return bool
   *   Returns TRUE if enabled, FALSE otherwise.
   */
  public function isEnabled(): bool {
    return self::$enabled;
  }

  /**
   * Enable or disable the synchronization service.
   *
   * @var bool $enabled
   *   Set to TRUE to enable, or FALSE to disable the service. Default is TRUE.
   *
   * @return $this
   */
  public function setEnabled(bool $enabled = TRUE): EntitySynchronization {
    self::$enabled = $enabled;
    return $this;
  }

}
+6 −4
Original line number Diff line number Diff line
@@ -253,11 +253,12 @@ class ParametersCollection extends ConfigEntityBase implements ParametersCollect
    static::$autolock = FALSE;
    parent::preDelete($storage, $entities);
    static::$autolock = $autolock;
    $op = 'delete';
    /** @var \Drupal\parameters\Entity\ParametersCollectionInterface $collection */
    foreach ($entities as $collection) {
      foreach ($collection->getParameters() as $parameter) {
        if ($parameter instanceof UsageParameterInterface) {
          $parameter->onRemoval();
          $parameter->onRemoval($collection, $op);
        }
      }
    }
@@ -268,6 +269,7 @@ class ParametersCollection extends ConfigEntityBase implements ParametersCollect
   */
  public function preSave(EntityStorageInterface $storage) {
    ParametersCollectionStorage::$saveStack[$this->id()] = $this->id();
    $op = $this->isNew() ? 'insert' : 'update';

    /** @var \Drupal\parameters\Plugin\ParameterPluginCollection $lazy_original_parameters */
    $lazy_original_parameters = isset($this->original) ? $this->original->getParameters() : new ParameterPluginCollection(ParameterManager::get(), []);
@@ -281,10 +283,10 @@ class ParametersCollection extends ConfigEntityBase implements ParametersCollect
      $parameter = $lazy_current_parameters->get($name);
      if ($parameter instanceof UsageParameterInterface) {
        if (!in_array($name, $original_parameter_names, TRUE) || $this->isNew()) {
          $parameter->onAddition();
          $parameter->onAddition($this, $op);
        }
        elseif ($parameter->getConfiguration() !== $lazy_original_parameters->get($name)->getConfiguration()) {
          $parameter->onChange($lazy_original_parameters->get($name)->getConfiguration());
          $parameter->onChange($lazy_original_parameters->get($name)->getConfiguration(), $this, $op);
        }
      }
    }
@@ -294,7 +296,7 @@ class ParametersCollection extends ConfigEntityBase implements ParametersCollect
      $parameter = $lazy_original_parameters->get($name);
      if ($parameter instanceof UsageParameterInterface) {
        if (!in_array($name, $current_parameter_names, TRUE)) {
          $parameter->onRemoval();
          $parameter->onRemoval($this, $op);
        }
      }
    }
Loading