View source
<?php
namespace Drupal\gathercontent\Form;
use Drupal\Core\Entity\EntityForm;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Language\LanguageInterface;
use Drupal\field\Entity\FieldConfig;
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\gathercontent\DAO\Template;
use Drupal\taxonomy\Entity\Term;
class MappingEditForm extends EntityForm {
protected $new;
protected $step;
protected $mappingData;
protected $template;
protected $contentType;
protected $entityReferenceFields;
protected $erImportType;
protected $skip;
protected $erImported;
public function form(array $form, FormStateInterface $form_state) {
if (empty($this->step)) {
$this->step = 'field_mapping';
}
$form['#attached']['library'][] = 'gathercontent/theme';
$form['#attached']['library'][] = 'gathercontent/entity_references';
$mapping = $this->entity;
$this->new = !$mapping
->hasMapping();
$tmp = new Template();
$this->template = $tmp
->getTemplate($mapping
->getGathercontentTemplateId());
if ($this->step === 'field_mapping') {
$content_types = node_type_get_names();
$form['form_description'] = [
'#type' => 'html_tag',
'#tag' => 'i',
'#value' => t('Please map your GatherContent Template fields to your Drupal
Content Type Fields. Please note that a GatherContent field can only be
mapped to a single Drupal field. So each field can only be mapped to once.'),
];
$form['gathercontent_project'] = [
'#type' => 'item',
'#title' => $this
->t('Project name:'),
'#markup' => $mapping
->getGathercontentProject(),
'#wrapper_attributes' => [
'class' => [
'inline-label',
],
],
];
$form['gathercontent'] = [
'#type' => 'container',
];
$form['gathercontent']['gathercontent_template'] = [
'#type' => 'item',
'#title' => $this
->t('GatherContent template:'),
'#markup' => $mapping
->getGathercontentTemplate(),
'#wrapper_attributes' => [
'class' => [
'inline-label',
],
],
];
if (!$this->new) {
$this->mappingData = unserialize($mapping
->getData());
$this->contentType = $mapping
->getContentType();
$form['#attached']['drupalSettings']['gathercontent'] = $this
->getAllEntityReferenceFields();
$form['gathercontent']['content_type'] = [
'#type' => 'item',
'#title' => $this
->t('Drupal content type:'),
'#markup' => $mapping
->getContentTypeName(),
'#wrapper_attributes' => [
'class' => [
'inline-label',
],
],
];
$form['mapping'] = [
'#prefix' => '<div id="edit-mapping">',
'#suffix' => '</div>',
];
foreach ($this->template->config as $i => $fieldset) {
if ($fieldset->hidden === FALSE) {
$form['mapping'][$fieldset->name] = [
'#type' => 'details',
'#title' => $fieldset->label,
'#open' => $i === 0 ? TRUE : FALSE,
'#tree' => TRUE,
];
if (\Drupal::moduleHandler()
->moduleExists('metatag')) {
$form['mapping'][$fieldset->name]['type'] = [
'#type' => 'select',
'#options' => [
'content' => t('Content'),
'metatag' => t('Metatag'),
],
'#title' => t('Type'),
'#default_value' => isset($this->mappingData[$fieldset->name]['type']) || $form_state
->hasValue($fieldset->name)['type'] ? $form_state
->hasValue($fieldset->name)['type'] ? $form_state
->getValue($fieldset->name)['type'] : $this->mappingData[$fieldset->name]['type'] : 'content',
'#ajax' => [
'callback' => '::getMappingTable',
'wrapper' => 'edit-mapping',
'method' => 'replace',
'effect' => 'fade',
],
];
}
if (\Drupal::moduleHandler()
->moduleExists('content_translation') && \Drupal::service('content_translation.manager')
->isEnabled('node', $form_state
->getValue('content_type'))) {
$form['mapping'][$fieldset->name]['language'] = [
'#type' => 'select',
'#options' => [
'und' => t('None'),
] + $this
->getLanguageList(),
'#title' => t('Language'),
'#default_value' => isset($this->mappingData[$fieldset->name]['language']) ? $this->mappingData[$fieldset->name]['language'] : 'und',
];
}
foreach ($fieldset->elements as $gc_field) {
$d_fields = [];
if (isset($form_state
->getTriggeringElement()['#name'])) {
if ($form_state
->getTriggeringElement()['#array_parents'][1] === $fieldset->name) {
if ($form_state
->getTriggeringElement()['#value'] === 'content') {
$d_fields = $this
->filterFields($gc_field, $mapping
->getContentType());
}
elseif ($form_state
->getTriggeringElement()['#value'] === 'metatag') {
$d_fields = $this
->filterMetatags($gc_field);
}
}
else {
if ($form_state
->getValue($fieldset->name)['type'] === 'content') {
$d_fields = $this
->filterFields($gc_field, $mapping
->getContentType());
}
elseif ($form_state
->getTriggeringElement()['#value'] === 'metatag') {
$d_fields = $this
->filterMetatags($gc_field);
}
}
}
else {
if (isset($this->mappingData[$fieldset->name]['type']) && $this->mappingData[$fieldset->name]['type'] === 'content' || !isset($this->mappingData[$fieldset->name]['type'])) {
$d_fields = $this
->filterFields($gc_field, $mapping
->getContentType());
}
else {
$d_fields = $this
->filterMetatags($gc_field);
}
}
$form['mapping'][$fieldset->name]['elements'][$gc_field->name] = [
'#type' => 'select',
'#options' => $d_fields,
'#title' => isset($gc_field->label) ? $gc_field->label : $gc_field->title,
'#default_value' => isset($this->mappingData[$fieldset->name]['elements'][$gc_field->name]) ? $this->mappingData[$fieldset->name]['elements'][$gc_field->name] : NULL,
'#empty_option' => t("Don't map"),
'#attributes' => [
'class' => [
'gathercontent-ct-element',
],
],
];
}
}
}
$form['mapping']['er_mapping_type'] = [
'#type' => 'radios',
'#title' => $this
->t('Taxonomy terms mapping type'),
'#options' => [
'automatic' => $this
->t('Automatic'),
'semiautomatic' => $this
->t('Semi-automatic'),
'manual' => $this
->t('Manual'),
],
'#attributes' => [
'class' => [
'gathercontent-er-mapping-type',
],
],
'#description' => $this
->t("<strong>Automatic</strong> - taxonomy terms will be automatically created in predefined vocabulary. You cannot select translations. Field should be set as translatable for correct functionality.<br>\n<strong>Semi-automatic</strong> - taxonomy terms will be imported into predefined vocabulary in the first language and we will offer you possibility to select their translations from other languages. For single language mapping this option will execute same action as 'Automatic' importField should not be set as translatable for correct functionality.<br>\n<strong>Manual</strong> - you can map existing taxonomy terms from predefined vocabulary to translations in all languages."),
];
}
else {
$form['gathercontent']['content_type'] = [
'#type' => 'select',
'#title' => $this
->t('Drupal content type'),
'#options' => $content_types,
'#required' => TRUE,
'#wrapper_attributes' => [
'class' => [
'inline-label',
],
],
'#ajax' => [
'callback' => '::getMappingTable',
'wrapper' => 'edit-mapping',
'method' => 'replace',
'effect' => 'fade',
],
'#default_value' => $form_state
->getValue('content_type'),
];
$form['mapping'] = [
'#prefix' => '<div id="edit-mapping">',
'#suffix' => '</div>',
];
if ($form_state
->hasValue('content_type')) {
$this->contentType = $form_state
->getValue('content_type');
foreach ($this->template->config as $i => $fieldset) {
if ($fieldset->hidden === FALSE) {
$form['mapping'][$fieldset->name] = [
'#type' => 'details',
'#title' => $fieldset->label,
'#open' => $i === 0 ? TRUE : FALSE,
'#tree' => TRUE,
];
if ($i === 0) {
$form['mapping'][$fieldset->name]['#prefix'] = '<div id="edit-mapping">';
}
if (end($this->template->config) === $fieldset) {
$form['mapping'][$fieldset->name]['#suffix'] = '</div>';
}
if (\Drupal::moduleHandler()
->moduleExists('metatag')) {
$form['mapping'][$fieldset->name]['type'] = [
'#type' => 'select',
'#options' => [
'content' => t('Content'),
'metatag' => t('Metatag'),
],
'#title' => t('Type'),
'#default_value' => $form_state
->hasValue($fieldset->name)['type'] ? $form_state
->getValue($fieldset->name)['type'] : 'content',
'#ajax' => [
'callback' => '::getMappingTable',
'wrapper' => 'edit-mapping',
'method' => 'replace',
'effect' => 'fade',
],
];
}
if (\Drupal::moduleHandler()
->moduleExists('content_translation') && \Drupal::service('content_translation.manager')
->isEnabled('node', $form_state
->getValue('content_type'))) {
$form['mapping'][$fieldset->name]['language'] = [
'#type' => 'select',
'#options' => [
'und' => t('None'),
] + $this
->getLanguageList(),
'#title' => t('Language'),
'#default_value' => $form_state
->hasValue($fieldset->name)['language'] ? $form_state
->getValue($fieldset->name)['language'] : 'und',
];
}
foreach ($fieldset->elements as $gc_field) {
$d_fields = [];
if ($form_state
->getTriggeringElement()['#name'] !== 'content_type') {
if ($form_state
->getTriggeringElement()['#array_parents'][1] === $fieldset->name) {
if ($form_state
->getTriggeringElement()['#value'] === 'content') {
$d_fields = $this
->filterFields($gc_field, $this->contentType);
}
elseif ($form_state
->getTriggeringElement()['#value'] === 'metatag') {
$d_fields = $this
->filterMetatags($gc_field);
}
}
else {
if ($form_state
->getValue($fieldset->name)['type'] === 'content') {
$d_fields = $this
->filterFields($gc_field, $this->contentType);
}
elseif ($form_state
->getValue($fieldset->name)['type'] === 'metatag') {
$d_fields = $this
->filterMetatags($gc_field);
}
}
}
else {
$d_fields = $this
->filterFields($gc_field, $this->contentType);
}
$form['mapping'][$fieldset->name]['elements'][$gc_field->name] = [
'#type' => 'select',
'#options' => $d_fields,
'#title' => isset($gc_field->label) ? $gc_field->label : $gc_field->title,
'#empty_option' => $this
->t("Don't map"),
'#default_value' => $form_state
->hasValue($fieldset->name)['elements'][$gc_field->name] ? $form_state
->getValue($fieldset->name)['elements'][$gc_field->name] : NULL,
'#attributes' => [
'class' => [
'gathercontent-ct-element',
],
],
];
}
}
}
$form['mapping']['er_mapping_type'] = [
'#type' => 'radios',
'#title' => $this
->t('Taxonomy terms mapping type'),
'#options' => [
'automatic' => $this
->t('Automatic'),
'semiautomatic' => $this
->t('Semi-automatic'),
'manual' => $this
->t('Manual'),
],
'#attributes' => [
'class' => [
'gathercontent-er-mapping-type',
],
],
'#description' => $this
->t("<strong>Automatic</strong> - taxonomy terms will be automatically created in predefined vocabulary. You cannot select translations. Field should be set as translatable for correct functionality.<br>\n<strong>Semi-automatic</strong> - taxonomy terms will be imported into predefined vocabulary in the first language and we will offer you possibility to select their translations from other languages. For single language mapping this option will execute same action as 'Automatic' importField should not be set as translatable for correct functionality.<br>\n<strong>Manual</strong> - you can map existing taxonomy terms from predefined vocabulary to translations in all languages."),
];
}
}
}
elseif ($this->step === 'er_mapping') {
foreach ($form as $k => $item) {
if (!in_array($k, [
'#attributes',
'#cache',
])) {
unset($form[$k]);
}
}
foreach ($this->entityReferenceFields as $field => $gcMapping) {
$field_config = FieldConfig::loadByName('node', $this->contentType, $field);
$options = [];
$header = [];
foreach ($gcMapping as $lang => $fieldSettings) {
foreach ($this->template->config as $tab) {
if ($tab->name === $fieldSettings['tab']) {
foreach ($tab->elements as $element) {
if ($element->name == $fieldSettings['name']) {
$header[$lang] = $this
->t('@field (@lang values)', [
'@field' => $element->label,
'@lang' => strtoupper($lang),
]);
if (count($header) === 1 && $this->erImportType === 'manual') {
$header['terms'] = $this
->t('Terms');
}
foreach ($element->options as $option) {
if (!isset($option->value)) {
$options[$lang][$option->name] = $option->label;
}
}
}
}
}
}
}
$term_options = [];
if ($this->erImportType === 'manual') {
$settings = $field_config
->getSetting('handler_settings');
if (!empty($settings['auto_create_bundle'])) {
$terms = $this->entityTypeManager
->getStorage('taxonomy_term')
->loadByProperties([
'vid' => $settings['auto_create_bundle'],
]);
}
else {
$target = reset($settings['target_bundles']);
$terms = $this->entityTypeManager
->getStorage('taxonomy_term')
->loadByProperties([
'vid' => $target,
]);
}
foreach ($terms as $term) {
$term_options[$term
->id()] = $term
->getName();
}
}
$languages = array_keys($header);
$first_language = array_shift($languages);
$first_language_options = array_shift($options);
if (isset($languages[0]) && $languages[0] === 'terms') {
unset($languages[0]);
}
$form[$field] = [
'#tree' => TRUE,
];
$form[$field]['title'] = [
'#type' => 'html_tag',
'#value' => $this
->t('Field @field', [
'@field' => $field_config
->getLabel(),
]),
'#tag' => 'h2',
];
$form[$field]['table'] = [
'#type' => 'table',
'#header' => $header,
];
$rows = 0;
foreach ($first_language_options as $k => $option) {
$form[$field]['table'][$rows][$first_language] = [
'#type' => 'value',
'#value' => $k,
'#markup' => $option,
];
if ($this->erImportType === 'manual') {
$form[$field]['table'][$rows]['terms'] = [
'#type' => 'select',
'#options' => $term_options,
'#title' => $this
->t('Taxonomy term options'),
'#title_display' => 'invisible',
'#empty_option' => $this
->t('- None -'),
];
}
foreach ($languages as $i => $language) {
$form[$field]['table'][$rows][$language] = [
'#type' => 'select',
'#options' => $options[$language],
'#title' => $this
->t('@lang options', [
'@lang' => $language,
]),
'#title_display' => 'invisible',
'#empty_option' => $this
->t('- None -'),
];
}
$rows++;
}
}
$this->step = 'completed';
}
return $form;
}
protected function getLanguageList() {
$languages = \Drupal::service('language_manager')
->getLanguages(LanguageInterface::STATE_CONFIGURABLE);
$language_list = [];
foreach ($languages as $lang_code => $language) {
$language_list[$lang_code] = $language
->getName();
}
return $language_list;
}
protected function filterFields($gc_field, $content_type) {
$mapping_array = [
'files' => [
'file',
'image',
],
'section' => [
'text_long',
],
'text' => [
'text',
'text_long',
'text_with_summary',
'string_long',
'string',
'email',
'telephone',
'date',
'datetime',
],
'choice_radio' => [
'string',
'entity_reference',
],
'choice_checkbox' => [
'list_string',
'entity_reference',
],
];
$instances = \Drupal::service('entity_field.manager')
->getFieldDefinitions('node', $content_type);
$fields = [];
foreach ($instances as $name => $instance) {
if (substr_compare($name, 'field', 0, 5) != 0 && !in_array($name, [
'body',
])) {
continue;
}
if (in_array($instance
->getType(), $mapping_array[$gc_field->type])) {
switch ($gc_field->type) {
case 'text':
if (!$gc_field->plain_text && in_array($instance
->getType(), [
'string',
'string_long',
'email',
'telephone',
])) {
continue 2;
}
break;
case 'section':
if (in_array($instance
->getType(), [
'string',
'string_long',
])) {
continue 2;
}
break;
case 'choice_radio':
case 'choice_checkbox':
if ($instance
->getSetting('handler') !== 'default:taxonomy_term') {
continue 2;
}
break;
}
$fields[$instance
->getName()] = $instance
->getLabel();
}
}
if ($gc_field->type === 'text' && $gc_field->plain_text) {
$fields['title'] = 'Title';
}
return $fields;
}
protected function filterMetatags($gathercontent_field) {
if ($gathercontent_field->type === 'text' && $gathercontent_field->plain_text) {
return [
'title' => t('Title'),
'description' => t('Description'),
'abstract' => t('Abstract'),
'keywords' => t('Keywords'),
];
}
else {
return [];
}
}
public function getMappingTable(array &$form, FormStateInterface $form_state) {
$this->contentType = $form_state
->getValue('content_type');
$fields = $this
->getAllEntityReferenceFields();
$form['mapping']['#attached']['drupalSettings']['gathercontent'] = empty($fields) ? NULL : $fields;
$form_state
->setRebuild(TRUE);
return $form['mapping'];
}
public function validateForm(array &$form, FormStateInterface $form_state) {
if ($form_state
->getTriggeringElement()['#id'] == 'edit-submit') {
if ($this->step === 'field_mapping') {
$form_definition_elements = [
'return',
'form_build_id',
'form_token',
'form_id',
'op',
];
$non_data_elements = array_merge($form_definition_elements, [
'content_type',
'id',
'updated',
'gathercontent_project',
'gathercontent_template',
]);
$mapping_data = [];
foreach ($form_state
->getValues() as $key => $value) {
if (!in_array($key, $non_data_elements) && substr_compare($key, 'tab', 0, 3) === 0) {
$mapping_data[$key] = $value;
}
}
$mapping = $this->entity;
$content_type = empty($mapping
->getContentType()) ? $form_state
->getValue('content_type') : $mapping
->getContentType();
$translatable = \Drupal::moduleHandler()
->moduleExists('content_translation') && \Drupal::service('content_translation.manager')
->isEnabled('node', $content_type);
$content_lang = [];
$metatag_lang = [];
if ($translatable) {
foreach ($mapping_data as $tab_id => $tab) {
$tab_type = isset($tab['type']) ? $tab['type'] : 'content';
if ($tab['language'] != 'und') {
if (!in_array($tab['language'], ${$tab_type . '_lang'})) {
${$tab_type . '_lang'}[] = $tab['language'];
}
else {
$element = $tab_id . '[language]';
$form_state
->setErrorByName($element, $this
->t('Each language can be used only once'));
}
}
}
}
$content_fields = [];
$metatag_fields = [];
if ($translatable) {
foreach ($content_lang as $lang) {
$content_fields[$lang] = [];
}
foreach ($metatag_lang as $lang) {
$metatag_fields[$lang] = [];
}
$content_fields['und'] = $metatag_fields['und'] = [];
}
foreach ($mapping_data as $tab_id => $tab) {
$tab_type = isset($tab['type']) ? $tab['type'] : 'content';
if (isset($tab['elements'])) {
foreach ($tab['elements'] as $k => $element) {
if (empty($element)) {
continue;
}
if ($translatable) {
if (!in_array($element, ${$tab_type . '_fields'}[$tab['language']])) {
${$tab_type . '_fields'}[$tab['language']][] = $element;
}
else {
$form_state
->setErrorByName($tab_id, $this
->t('A GatherContent field can only be mapped to a single Drupal field. So each field can only be mapped to once.'));
}
}
else {
if (!in_array($element, ${$tab_type . '_fields'})) {
${$tab_type . '_fields'}[] = $element;
}
else {
$form_state
->setErrorByName($tab_id, $this
->t('A GatherContent field can only be mapped to a single Drupal field. So each field can only be mapped to once.'));
}
}
}
}
}
if (!$translatable && empty($content_fields) && empty($metatag_fields)) {
$form_state
->setErrorByName('form', t('You need to map at least one field to create mapping.'));
}
elseif ($translatable && count($content_fields) === 1 && empty($content_fields['und']) && empty($metatag_fields['und']) && count($metatag_fields) === 1) {
$form_state
->setErrorByName('form', t('You need to map at least one field to create mapping.'));
}
if ($translatable) {
foreach ($content_fields as $k => $lang_fields) {
if (!in_array('title', $lang_fields) && $k != 'und') {
$form_state
->setErrorByName('form', t('You have to map Drupal Title field for translatable content.'));
}
}
}
}
}
}
public function submitForm(array &$form, FormStateInterface $form_state) {
if ($form_state
->getTriggeringElement()['#id'] == 'edit-submit') {
$mapping = $this->entity;
$entityStorage = \Drupal::entityTypeManager()
->getStorage('taxonomy_term');
if ($this->step === 'field_mapping') {
$this->step = 'er_mapping';
$mapping_data = $this
->extractMappingData($form_state
->getValues());
if ($this->new) {
$this->contentType = $form_state
->getValue('content_type');
}
else {
$this->contentType = $mapping
->getContentType();
}
$this->erImportType = $form_state
->getValue('er_mapping_type');
$this
->getEntityReferenceFields();
if (empty($this->entityReferenceFields) || $this->erImportType === 'automatic') {
$this->skip = TRUE;
}
if (!$this->skip) {
$form_state
->setRebuild(TRUE);
}
}
if ($this->step === 'completed' || $this->skip) {
$this->erImported = 0;
if ($this->new) {
$mapping
->setContentType($this->contentType);
$content_types = node_type_get_names();
$mapping
->setContentTypeName($content_types[$this->contentType]);
}
$mapping
->setData(serialize($this->mappingData));
$mapping
->setUpdatedDrupal(time());
$tmp = new Template();
$template = $tmp
->getTemplate($mapping
->getGathercontentTemplateId());
$mapping
->setTemplate(serialize($template));
$mapping
->save();
foreach ($template->config as $i => $fieldset) {
if ($fieldset->hidden === FALSE) {
foreach ($fieldset->elements as $gc_field) {
$local_field_name = $this->mappingData[$fieldset->name]['elements'][$gc_field->name];
if ($gc_field->type === 'choice_checkbox') {
if (!empty($local_field_name)) {
$local_options = [];
foreach ($gc_field->options as $option) {
$local_options[$option->name] = $option->label;
}
$field_info = FieldConfig::loadByName('node', $mapping
->getContentType(), $local_field_name);
if ($field_info
->getType() === 'entity_reference') {
if ($this->erImportType === 'automatic') {
$this
->automaticTermsGenerator($field_info, $local_options, isset($this->mappingData[$fieldset->name]['language']) ? $this->mappingData[$fieldset->name]['language'] : LanguageInterface::LANGCODE_NOT_SPECIFIED);
}
}
else {
$field_info = $field_info
->getFieldStorageDefinition();
$field_info
->setSetting('allowed_values', $local_options);
try {
$field_info
->save();
} catch (\Exception $e) {
}
}
}
}
elseif ($gc_field->type === 'choice_radio') {
if (!empty($mapping_data[$fieldset->name]['elements'][$gc_field->name])) {
$local_options = [];
foreach ($gc_field->options as $option) {
if (!isset($option->value)) {
$local_options[$option->name] = $option->label;
}
}
$field_info = FieldConfig::loadByName('node', $mapping
->getContentType(), $local_field_name);
if ($field_info
->getType() === 'entity_reference') {
if ($this->erImportType === 'automatic') {
$this
->automaticTermsGenerator($field_info, $local_options, isset($this->mappingData[$fieldset->name]['language']) ? $this->mappingData[$fieldset->name]['language'] : LanguageInterface::LANGCODE_NOT_SPECIFIED);
}
}
else {
$new_local_options = [];
foreach ($local_options as $name => $label) {
$new_local_options[] = $name . '|' . $label;
}
$entity = \Drupal::entityTypeManager()
->getStorage('entity_form_display')
->load('node.' . $mapping
->getContentType() . '.default');
$entity
->getRenderer($local_field_name)
->setSetting('available_options', implode("\n", $new_local_options));
}
}
}
}
}
}
if (!$this->skip) {
$form_state
->cleanValues();
$fields = $form_state
->getValues();
$options = $this
->prepareOptions();
foreach ($fields as $field_name => $tables) {
$vid = $this
->getVocabularyId($field_name);
$this
->gcOptionIdsFieldExists($vid);
foreach ($tables as $table) {
foreach ($table as $row) {
$languages = $this
->getAvailableLanguages($row);
if ($this->erImportType === 'manual') {
$this
->manualErImport($languages, $entityStorage, $row);
}
else {
$this
->semiErImport($languages, $entityStorage, $row, $options, $vid);
}
}
}
}
}
if ($this->new) {
drupal_set_message(t('Mapping has been created.'));
}
else {
drupal_set_message(t('Mapping has been updated.'));
}
if (!empty($this->entityReferenceFields)) {
drupal_set_message($this
->formatPlural($this->erImported, '@count term was imported', '@count terms were imported'));
}
$form_state
->setRedirect('entity.gathercontent_mapping.collection');
}
}
}
public function getEntityReferenceFields() {
$this->entityReferenceFields = [];
$instances = \Drupal::service('entity_field.manager')
->getFieldDefinitions('node', $this->contentType);
foreach ($instances as $instance) {
if ($instance
->getType() === 'entity_reference' && $instance
->getSetting('handler') === 'default:taxonomy_term') {
foreach ($this->mappingData as $tabName => $tab) {
$gcField = array_search($instance
->getName(), $tab['elements']);
if (empty($gcField)) {
continue 2;
}
if (isset($tab['language'])) {
$this->entityReferenceFields[$instance
->getName()][$tab['language']]['name'] = $gcField;
$this->entityReferenceFields[$instance
->getName()][$tab['language']]['tab'] = $tabName;
}
else {
$this->entityReferenceFields[$instance
->getName()][LanguageInterface::LANGCODE_NOT_SPECIFIED]['name'] = $gcField;
$this->entityReferenceFields[$instance
->getName()][LanguageInterface::LANGCODE_NOT_SPECIFIED]['tab'] = $tabName;
}
}
}
}
}
public function getAllEntityReferenceFields() {
$entityReferenceFields = [];
$instances = \Drupal::service('entity_field.manager')
->getFieldDefinitions('node', $this->contentType);
foreach ($instances as $instance) {
if ($instance
->getType() === 'entity_reference' && $instance
->getSetting('handler') === 'default:taxonomy_term') {
$entityReferenceFields[] = $instance
->getName();
}
}
return $entityReferenceFields;
}
public function automaticTermsGenerator(FieldConfig $handlerSettings, array $localOptions, $langcode) {
$settings = $handlerSettings
->getSetting('handler_settings');
if (!empty($settings['auto_create_bundle'])) {
$vid = $settings['auto_create_bundle'];
}
else {
$vid = reset($settings['target_bundles']);
}
$this
->gcOptionIdsFieldExists($vid);
foreach ($localOptions as $id => $localOption) {
$query = \Drupal::entityQuery('taxonomy_term');
$group = $query
->orConditionGroup()
->condition('gathercontent_option_ids', $id)
->condition('name', $localOption);
$term_ids = $query
->condition($group)
->condition('vid', $vid)
->condition('langcode', $langcode)
->execute();
$term_id = array_shift($term_ids);
if (!empty($term_id)) {
$term = Term::load($term_id);
if ($langcode === LanguageInterface::LANGCODE_NOT_SPECIFIED) {
if ($term
->label() !== $localOption) {
$term
->setName($localOption);
}
if (!in_array($id, $term
->get('gathercontent_option_ids')
->getValue())) {
$term->gathercontent_option_ids
->appendItem($id);
}
}
else {
if ($term
->getTranslation($langcode)
->label() !== $localOption) {
$term
->getTranslation($langcode)
->setName($localOption);
}
if (!in_array($id, $term
->getTranslation($langcode)->gathercontent_option_ids
->getValue())) {
$term
->getTranslation($langcode)->gathercontent_option_ids
->appendItem($id);
}
}
$term
->save();
$this->erImported++;
}
else {
$term_values = [
'vid' => $vid,
'langcode' => $langcode,
];
$term = Term::create($term_values);
$term
->setName($localOption);
$term
->set('gathercontent_option_ids', $id);
$term
->save();
$this->erImported++;
}
}
}
public function prepareOptions() {
$options = [];
foreach ($this->entityReferenceFields as $field => $gcMapping) {
foreach ($gcMapping as $lang => $fieldSettings) {
foreach ($this->template->config as $tab) {
if ($tab->name === $fieldSettings['tab']) {
foreach ($tab->elements as $element) {
if ($element->name === $fieldSettings['name']) {
foreach ($element->options as $option) {
if (!isset($option->value)) {
$options[$option->name] = $option->label;
}
}
}
}
}
}
}
}
return $options;
}
public function gcOptionIdsFieldExists($vid) {
if ($this->entityTypeManager
->hasDefinition('taxonomy_term')) {
$entityFieldManager = \Drupal::service('entity_field.manager');
$definitions = $entityFieldManager
->getFieldStorageDefinitions('taxonomy_term');
if (!isset($definitions['gathercontent_option_ids'])) {
FieldStorageConfig::create([
'field_name' => 'gathercontent_option_ids',
'entity_type' => 'taxonomy_term',
'type' => 'string',
'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED,
'locked' => TRUE,
'persist_with_no_fields' => TRUE,
'settings' => [
'is_ascii' => FALSE,
'case_sensitive' => FALSE,
],
])
->save();
}
$field_config = FieldConfig::loadByName('taxonomy_term', $vid, 'gathercontent_option_ids');
if (is_null($field_config)) {
FieldConfig::create([
'field_name' => 'gathercontent_option_ids',
'entity_type' => 'taxonomy_term',
'bundle' => $vid,
'label' => 'GatherContent Option IDs',
])
->save();
}
}
}
public function manualErImport($languages, EntityStorageInterface $entityStorage, array $row) {
if (!empty($languages) && !empty($row['terms'])) {
$terms = $entityStorage
->loadByProperties([
'gathercontent_option_ids' => $row[$languages[0]],
]);
$term = array_shift($terms);
if (!empty($term)) {
if ($term
->id() !== $row['terms']) {
$translation_languages = $term
->getTranslationLanguages(TRUE);
foreach ($translation_languages as $language) {
if ($term
->hasTranslation($language) && !empty($row[$language])) {
$option_ids = $term
->getTranslation($language)
->get('gathercontent_option_ids');
foreach ($option_ids as $i => $option_id) {
if ($option_id == $row[$language]) {
unset($option_ids[$i]);
}
}
$term
->getTranslation($language)
->set('gathercontent_option_ids', $option_ids);
}
}
}
}
$term = Term::load($row['terms']);
if (!empty($languages)) {
foreach ($languages as $language) {
$term
->getTranslation($language)
->set('gathercontent_option_ids', $row[$language]);
}
}
$term
->save();
$this->erImported++;
}
elseif (empty($languages) && !empty($row['terms'])) {
$und_lang_value = $row[LanguageInterface::LANGCODE_NOT_SPECIFIED];
if (!empty($und_lang_value)) {
$terms = $entityStorage
->loadByProperties([
'gathercontent_option_ids' => $und_lang_value,
]);
$term = array_shift($terms);
if (!empty($term)) {
if ($term
->id() !== $row['terms']) {
$option_ids = $term
->get('gathercontent_option_ids');
foreach ($option_ids as $i => $option_id) {
if ($option_id == $und_lang_value) {
unset($option_ids[$i]);
}
}
$term
->set('gathercontent_option_ids', $option_ids);
}
}
$term = Term::load($row['terms']);
$term
->set('gathercontent_option_ids', $und_lang_value);
$term
->save();
$this->erImported++;
}
}
}
public function semiErImport($languages, EntityStorageInterface $entityStorage, array $row, array $options, $vid) {
if (!empty($languages)) {
$terms = $entityStorage
->loadByProperties([
'gathercontent_option_ids' => $row[$languages[0]],
]);
$term = array_shift($terms);
if (!empty($term)) {
foreach ($languages as $language) {
if (!empty($row[$language]) && $term
->hasTranslation($language) && $term
->getTranslation($language)
->label() !== $options[$row[$language]]) {
$term
->getTranslation($language)
->setName($options[$row[$language]]);
}
}
$term
->save();
$this->erImported++;
}
else {
$term = Term::create([
'vid' => $vid,
]);
foreach ($languages as $language) {
if (!empty($row[$language])) {
if (!$term
->hasTranslation($language)) {
$term
->addTranslation($language);
}
$term
->getTranslation($language)
->set('gathercontent_option_ids', $row[$language]);
$term
->getTranslation($language)
->setName($options[$row[$language]]);
}
}
if (!empty($term
->getTranslationLanguages())) {
$term
->save();
$this->erImported++;
}
}
}
else {
$und_lang_value = $row[LanguageInterface::LANGCODE_NOT_SPECIFIED];
if (!empty($und_lang_value)) {
$terms = $entityStorage
->loadByProperties([
'gathercontent_option_ids' => $und_lang_value,
]);
$term = array_shift($terms);
if (!empty($term)) {
if ($term
->label() !== $options[$und_lang_value]) {
$term
->setName($options[$und_lang_value]);
}
$term
->save();
$this->erImported++;
}
else {
$term = Term::create([
'vid' => $vid,
'gathercontent_option_ids' => $und_lang_value,
]);
$term
->setName($options[$und_lang_value]);
$term
->save();
$this->erImported++;
}
}
}
}
public function getAvailableLanguages(array $row) {
$languages = array_keys($row);
foreach ($languages as $i => $language) {
if ($language === 'und') {
unset($languages[$i]);
}
elseif ($language === 'terms') {
unset($languages[$i]);
}
}
return $languages;
}
public function getVocabularyId($field_name) {
$field_config = FieldConfig::loadByName('node', $this->contentType, $field_name);
$settings = $field_config
->getSetting('handler_settings');
if (!empty($settings['auto_create_bundle'])) {
$vid = $settings['auto_create_bundle'];
return $vid;
}
else {
$vid = reset($settings['target_bundles']);
return $vid;
}
}
public function extractMappingData(array $formValues) {
$form_definition_elements = [
'return',
'form_build_id',
'form_token',
'form_id',
'op',
];
$non_data_elements = array_merge($form_definition_elements, [
'gc_template',
'content_type',
'id',
'updated',
'gathercontent_project',
'gathercontent_template',
]);
$mapping_data = [];
foreach ($formValues as $key => $value) {
if (!in_array($key, $non_data_elements) && substr_compare($key, 'tab', 0, 3) === 0) {
$mapping_data[$key] = $value;
}
}
$this->mappingData = $mapping_data;
return $mapping_data;
}
protected function actions(array $form, FormStateInterface $form_state) {
$actions = parent::actions($form, $form_state);
$actions['submit']['#value'] = $this->new ? $this
->t('Create mapping') : $this
->t('Update mapping');
$actions['close'] = [
'#type' => 'submit',
'#value' => t('Cancel'),
];
unset($actions['delete']);
return $actions;
}
}