View source
<?php
namespace Drupal\gathercontent_upload\Export;
use Cheppers\GatherContent\DataTypes\Structure;
use Cheppers\GatherContent\GatherContentClientInterface;
use Drupal\Component\Uuid\UuidInterface;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Entity\EntityDisplayRepositoryInterface;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\Core\Language\LanguageInterface;
use Drupal\Core\Language\LanguageManagerInterface;
use Drupal\gathercontent\DrupalGatherContentClient;
use Drupal\gathercontent\Entity\Mapping;
use Drupal\gathercontent\MigrationDefinitionCreator;
use Symfony\Component\DependencyInjection\ContainerInterface;
class MappingCreator implements ContainerInjectionInterface {
protected $client;
protected $entityTypeManager;
protected $entityFieldManager;
protected $entityTypeBundleInfo;
protected $uuidService;
protected $moduleHandler;
protected $languageManager;
protected $migrationDefinitionCreator;
protected $contentTranslation;
protected $entityDisplayRepository;
const FIELD_COMBINATIONS = [
'file' => 'attachment',
'image' => 'attachment',
'text' => 'text',
'text_long' => 'text',
'text_with_summary' => 'text',
'string_long' => 'plain',
'string' => 'plain',
'email' => 'plain',
'telephone' => 'plain',
'date' => 'plain',
'datetime' => 'plain',
];
public function __construct(GatherContentClientInterface $client, EntityTypeManagerInterface $entityTypeManager, EntityFieldManagerInterface $entityFieldManager, EntityTypeBundleInfoInterface $entityTypeBundleInfo, UuidInterface $uuidService, ModuleHandlerInterface $moduleHandler, LanguageManagerInterface $languageManager, MigrationDefinitionCreator $migrationDefinitionCreator, EntityDisplayRepositoryInterface $entityDisplayRepository) {
$this->client = $client;
$this->entityTypeManager = $entityTypeManager;
$this->entityFieldManager = $entityFieldManager;
$this->entityTypeBundleInfo = $entityTypeBundleInfo;
$this->uuidService = $uuidService;
$this->moduleHandler = $moduleHandler;
$this->languageManager = $languageManager;
$this->migrationDefinitionCreator = $migrationDefinitionCreator;
$this->entityDisplayRepository = $entityDisplayRepository;
if ($this->moduleHandler
->moduleExists('content_translation')) {
$this->contentTranslation = \Drupal::service('content_translation.manager');
}
}
public static function create(ContainerInterface $container) {
return new static($container
->get('gathercontent.client'), $container
->get('entity_type.manager'), $container
->get('entity_field.manager'), $container
->get('entity_type.bundle.info'), $container
->get('uuid'), $container
->get('module_handler'), $container
->get('language_manager'), $container
->get('gathercontent.migration_creator'), $container
->get('entity_display.repository'));
}
public function generateMapping(string $entityTypeId, string $bundle, string $projectId) {
$groups = [];
$mappingData = [];
$bundles = $this->entityTypeBundleInfo
->getBundleInfo($entityTypeId);
$templateName = ucfirst($bundle);
if (!empty($bundles[$bundle]['label'])) {
$templateName = $bundles[$bundle]['label'];
}
$fields = $this->entityFieldManager
->getFieldDefinitions($entityTypeId, $bundle);
$languages = [
$this->languageManager
->getDefaultLanguage(),
];
if (isset($this->contentTranslation) && $this->contentTranslation
->isEnabled($entityTypeId, $bundle)) {
$languages = $this->languageManager
->getLanguages();
}
foreach ($languages as $language) {
$groupUuid = $this->uuidService
->generate();
$group = [
'uuid' => $groupUuid,
'name' => $language
->getName(),
'fields' => [],
];
$mappingData[$groupUuid] = [
'type' => 'content',
'language' => $language
->getId(),
'elements' => [],
];
$formDisplay = $this->entityDisplayRepository
->getFormDisplay($entityTypeId, $bundle);
$components = $formDisplay
->getComponents();
if (!empty($components)) {
$fieldsOrderedByWeight = [];
foreach ($components as $componentName => $componentValue) {
$fieldsOrderedByWeight[$componentValue['weight']] = $componentName;
}
krsort($fieldsOrderedByWeight);
foreach ($fieldsOrderedByWeight as $fieldName) {
if (array_key_exists($fieldName, $fields)) {
$fields = [
$fieldName => $fields[$fieldName],
] + $fields;
}
}
}
$this
->processFields($fields, $language, $group, $mappingData, $groupUuid);
$groups[] = $group;
}
$template = $this->client
->templatePost($projectId, $templateName, new Structure([
'uuid' => $this->uuidService
->generate(),
'groups' => $groups,
]));
$this->client
->templateGet($template->id);
$templateData = serialize($this->client
->getBody(TRUE));
$mapping = Mapping::create([
'id' => $template->id,
'gathercontent_project_id' => $projectId,
'gathercontent_project' => $this
->getProjectName($projectId),
'gathercontent_template_id' => $template->id,
'gathercontent_template' => $templateName,
'template' => $templateData,
]);
$mapping
->setMappedEntityType($entityTypeId);
$mapping
->setContentType($bundle);
$mapping
->setContentTypeName($templateName);
$mapping
->setData(serialize($mappingData));
$mapping
->setUpdatedDrupal(time());
$mapping
->save();
if (!empty($mappingData)) {
$this->migrationDefinitionCreator
->setMapping($mapping)
->setMappingData($mappingData)
->createMigrationDefinition();
}
}
protected function processFields(array $fields, LanguageInterface $language, array &$group, array &$mappingData, string $groupUuid, string $parentFieldId = '', string $parentFieldLabel = '') {
foreach ($fields as $field) {
if ($field instanceof BaseFieldDefinition) {
continue;
}
if (empty(static::FIELD_COMBINATIONS[$field
->getType()]) && $field
->getType() !== 'entity_reference' && $field
->getType() !== 'entity_reference_revisions') {
continue;
}
$fieldType = 'text';
$metadata = [
'is_plain' => FALSE,
];
if (!empty(static::FIELD_COMBINATIONS[$field
->getType()])) {
$fieldType = static::FIELD_COMBINATIONS[$field
->getType()];
}
if ($fieldType === 'plain') {
$fieldType = 'text';
$metadata = [
'is_plain' => TRUE,
];
}
if ($fieldType === 'text') {
$fieldStorageDefinition = $field
->getFieldStorageDefinition();
$metadata['repeatable'] = [
'isRepeatable' => FALSE,
'limitEnabled' => FALSE,
'limit' => 1,
];
if ($fieldStorageDefinition
->isMultiple()) {
$metadata['repeatable']['isRepeatable'] = TRUE;
$fieldCardinality = $fieldStorageDefinition
->getCardinality();
if ($fieldCardinality > 1) {
$metadata['repeatable']['limitEnabled'] = TRUE;
$metadata['repeatable']['limit'] = $fieldCardinality;
}
}
}
if ($field
->getType() === 'entity_reference') {
if ($field
->getSetting('handler') !== 'default:taxonomy_term') {
continue;
}
$fieldType = 'choice_checkbox';
if (!$field
->getFieldStorageDefinition()
->isMultiple()) {
$fieldType = 'choice_radio';
}
$termStorage = $this->entityTypeManager
->getStorage('taxonomy_term');
$values = [
'langcode' => $language
->getId(),
];
$settings = $field
->getSetting('handler_settings');
if (!empty($settings['target_bundles'])) {
$values['vid'] = $settings['target_bundles'];
}
$terms = $termStorage
->loadByProperties($values);
$options = [];
foreach ($terms as $term) {
$uuid = $this->uuidService
->generate();
$options[] = [
'optionId' => $uuid,
'label' => $term
->label(),
];
$optionIds = $term
->get('gathercontent_option_ids')
->getValue();
$mappedValues = array_map(function ($array) {
return $array['value'];
}, $optionIds);
if (!in_array($uuid, $mappedValues)) {
$term->gathercontent_option_ids
->appendItem($uuid);
}
$term
->save();
}
$metadata = [
'choice_fields' => [
'options' => $options,
],
];
}
if ($field
->getType() === 'entity_reference_revisions') {
$settings = $field
->getSetting('handler_settings');
if (empty($settings['target_bundles'])) {
continue;
}
$bundles = $settings['target_bundles'];
if (!empty($settings['negate']) && !empty($settings['target_bundles_drag_drop'])) {
$negated_bundles = array_filter($settings['target_bundles_drag_drop'], function ($v) {
return !$v['enabled'];
});
$bundles = array_combine(array_keys($negated_bundles), array_keys($negated_bundles));
}
$targetType = $field
->getFieldStorageDefinition()
->getSetting('target_type');
foreach ($bundles as $bundle) {
$childFields = $this->entityFieldManager
->getFieldDefinitions($targetType, $bundle);
$this
->processFields($childFields, $language, $group, $mappingData, $groupUuid, $field
->id(), (string) $field
->getLabel());
}
continue;
}
$fieldUuid = $this->uuidService
->generate();
$fieldLabel = (string) $field
->getLabel();
if (!empty($parentFieldLabel)) {
$fieldLabel = $parentFieldLabel . ' ' . $fieldLabel;
}
$group['fields'][] = [
'uuid' => $fieldUuid,
'field_type' => $fieldType,
'label' => $fieldLabel,
'metadata' => $metadata,
];
$fieldId = $field
->id();
if (!empty($parentFieldId)) {
$fieldId = $parentFieldId . '||' . $fieldId;
}
$mappingData[$groupUuid]['elements'][$fieldUuid] = $fieldId;
}
}
public function getProjects() {
$accountId = DrupalGatherContentClient::getAccountId();
$projects = [];
if ($accountId) {
$projects = $this->client
->getActiveProjects($accountId);
}
$formattedProjects = [];
foreach ($projects['data'] as $project) {
$formattedProjects[$project->id] = $project->name;
}
return $formattedProjects;
}
public function getProjectName(string $projectId) {
if (empty($projectId)) {
return '';
}
$project = $this->client
->projectGet($projectId);
if (empty($project)) {
return '';
}
return $project->name;
}
}