<?php
namespace Drupal\tmgmt_config\Plugin\tmgmt\Source;
use Drupal\config_translation\ConfigMapperManagerInterface;
use Drupal\config_translation\Form\ConfigTranslationFormBase;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Config\TypedConfigManagerInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\TypedData\TraversableTypedDataInterface;
use Drupal\Core\Url;
use Drupal\language\ConfigurableLanguageManagerInterface;
use Drupal\tmgmt\JobItemInterface;
use Drupal\tmgmt\SourcePluginBase;
use Drupal\tmgmt\TMGMTException;
use Drupal\tmgmt_config\DefaultConfigProcessor;
use Symfony\Component\DependencyInjection\ContainerInterface;
class ConfigSource extends SourcePluginBase implements ContainerFactoryPluginInterface {
const SIMPLE_CONFIG = '_simple_config';
protected $configMapperManager;
protected $entityTypeManager;
protected $configFactoryManager;
protected $languageManager;
protected $typedConfig;
public function __construct(array $configuration, $plugin_id, $plugin_definition, ConfigMapperManagerInterface $config_mapper_manager, EntityTypeManagerInterface $entity_type_manager, TypedConfigManagerInterface $typedConfigManagerInterface, ConfigFactoryInterface $config_factory, ConfigurableLanguageManagerInterface $language_manager) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->configMapperManager = $config_mapper_manager;
$this->entityTypeManager = $entity_type_manager;
$this->typedConfig = $typedConfigManagerInterface;
$this->configFactoryManager = $config_factory;
$this->languageManager = $language_manager;
}
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static($configuration, $plugin_id, $plugin_definition, $container
->get('plugin.manager.config_translation.mapper'), $container
->get('entity_type.manager'), $container
->get('config.typed'), $container
->get('config.factory'), $container
->get('language_manager'));
}
protected function getMapperId(JobItemInterface $job_item) {
if ($job_item
->getItemType() == static::SIMPLE_CONFIG) {
return $job_item
->getItemId();
}
else {
$mapper_id = $job_item
->getItemType();
if ($mapper_id == 'field_config') {
$id_parts = explode('.', $job_item
->getItemId());
$mapper_id = $id_parts[2] . '_fields';
}
return $mapper_id;
}
}
protected function getMapper(JobItemInterface $job_item) {
$config_mapper = $this->configMapperManager
->createInstance($this
->getMapperId($job_item));
if ($job_item
->getItemType() != static::SIMPLE_CONFIG) {
$entity_type = $this->entityTypeManager
->getDefinition($config_mapper
->getType());
$pos = strpos($job_item
->getItemId(), $entity_type
->getConfigPrefix());
if ($pos !== FALSE) {
$entity_id = str_replace($entity_type
->getConfigPrefix() . '.', '', $job_item
->getItemId());
}
else {
throw new TMGMTException(t('Item ID does not contain the full config object name.'));
}
$entity = $this->entityTypeManager
->getStorage($config_mapper
->getType())
->load($entity_id);
if (!$entity) {
throw new TMGMTException(t('Unable to load entity %type with id %id', array(
'%type' => $job_item
->getItemType(),
'%id' => $entity_id,
)));
}
$config_mapper
->setEntity($entity);
}
return $config_mapper;
}
public function getLabel(JobItemInterface $job_item) {
try {
return $this
->getMapper($job_item)
->getTitle();
} catch (TMGMTException $e) {
}
return NULL;
}
public function getUrl(JobItemInterface $job_item) {
try {
$config_mapper = $this
->getMapper($job_item);
return Url::fromRoute($config_mapper
->getBaseRouteName(), $config_mapper
->getBaseRouteParameters());
} catch (TMGMTException $e) {
$this
->messenger()
->addError(t('Url can not be displayed, the entity does not exist: %error.', array(
'%error' => $e
->getMessage(),
)));
}
return NULL;
}
public function getData(JobItemInterface $job_item) {
$config_mapper = $this
->getMapper($job_item);
$data = array();
foreach ($config_mapper
->getConfigData() as $config_id => $config_data) {
$schema = $this->typedConfig
->get($config_id);
$processor = $this
->getConfigProcessor($schema);
$processor
->setConfigMapper($config_mapper);
$config_id = str_replace('.', '__', $config_id);
$data[$config_id] = $processor
->extractTranslatables($schema, $config_data);
}
if (count($data) == 1) {
return reset($data);
}
else {
return $data;
}
}
protected function getConfigProcessor(TraversableTypedDataInterface $definition) {
$class = DefaultConfigProcessor::class;
$data_definition = $definition
->getDataDefinition();
if (method_exists($data_definition, 'toArray')) {
$array_definition = $data_definition
->toArray();
if (!empty($array_definition['tmgmt_config_processor'])) {
$class = $array_definition['tmgmt_config_processor'];
}
}
return \Drupal::service('class_resolver')
->getInstanceFromDefinition($class);
}
public function saveTranslation(JobItemInterface $job_item, $target_langcode) {
try {
$config_mapper = $this
->getMapper($job_item);
} catch (TMGMTException $e) {
$job_item
->addMessage('The entity %id of type %type does not exist, the job can not be completed.', array(
'%id' => $job_item
->getItemId(),
'%type' => $job_item
->getItemType(),
), 'error');
return FALSE;
}
$data = $job_item
->getData();
$config_names = $config_mapper
->getConfigNames();
if (count($config_names) == 1) {
$data[$config_names[0]] = $data;
}
else {
foreach ($data as $key => $value) {
$new_key = str_replace('__', '.', $key);
$data[$new_key] = $value;
unset($data[$key]);
}
}
foreach ($config_mapper
->getConfigNames() as $name) {
$schema = $this->typedConfig
->get($name);
$base_config = $this->configFactoryManager
->getEditable($name);
$config_translation = $this->languageManager
->getLanguageConfigOverride($target_langcode, $name);
$element = ConfigTranslationFormBase::createFormElement($schema);
$processor = $this
->getConfigProcessor($schema);
$element
->setConfig($base_config, $config_translation, $processor
->convertToTranslation($data[$name]));
$saved_config = $config_translation
->get();
if (empty($saved_config)) {
$config_translation
->delete();
}
else {
$config_translation
->save();
}
}
return TRUE;
}
public function getItemTypes() {
$entity_types = $this->entityTypeManager
->getDefinitions();
$definitions = $this->configMapperManager
->getDefinitions();
$types = array();
foreach ($definitions as $definition_name => $definition) {
if (isset($definition['entity_type'])) {
$types[$definition['entity_type']] = (string) $entity_types[$definition['entity_type']]
->getLabel();
}
}
$types[static::SIMPLE_CONFIG] = t('Simple configuration');
return $types;
}
public function getItemTypeLabel($type) {
$item_types = $this
->getItemTypes();
return $item_types[$type];
}
public function getType(JobItemInterface $job_item) {
$definition = $this->configMapperManager
->getDefinition($this
->getMapperId($job_item));
return $definition['title'];
}
public function getSourceLangCode(JobItemInterface $job_item) {
$config_mapper = $this
->getMapper($job_item);
return $config_mapper
->getLangcode();
}
public function getExistingLangCodes(JobItemInterface $job_item) {
return [
$this
->getSourceLangCode($job_item),
];
}
}