content_workflow_bynder-1.0.0/content_workflow_bynder_ui/src/Form/MappingEditFormBase.php

content_workflow_bynder_ui/src/Form/MappingEditFormBase.php
<?php

namespace Drupal\content_workflow_bynder_ui\Form;

use Drupal\content_workflow_bynder_ui\Traits\MappingTrait;
use GatherContent\DataTypes\Template;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Entity\EntityForm;
use Drupal\Core\Form\FormStateInterface;
use Drupal\field\Entity\FieldConfig;
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\taxonomy\Entity\Term;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\Language\LanguageInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Class MappingEditFormBase.
 *
 * @package Drupal\content_workflow_bynder_ui\Form
 */
class MappingEditFormBase extends EntityForm implements ContainerInjectionInterface {

  use MappingTrait;

  /**
   * Flag for mapping if it's new.
   *
   * @var bool
   */
  protected $new;

  /**
   * Step in multipart form.
   *
   * Values:
   * - field_mapping
   * - er_mapping
   * - completed.
   *
   * @var string
   */
  protected $step;

  /**
   * Mapping data.
   *
   * @var array
   */
  protected $mappingData;

  /**
   * Content Workflow full template.
   *
   * @var object
   */
  protected $template;

  /**
   * Machine name of content type.
   *
   * @var string
   */
  protected $contentType;

  /**
   * Machine name of entity type.
   *
   * @var string
   */
  protected $entityType;

  /**
   * Type of import for entity reference fields.
   *
   * Values:
   * - automatic
   * - manual
   * - semiautomatic.
   *
   * @var string
   */
  protected $erImportType;

  /**
   * Flag for skipping ER mapping.
   *
   * @var bool
   */
  protected $skip;

  /**
   * Count of imported or updated taxonomy terms.
   *
   * @var int
   */
  protected $erImported;

  /**
   * Array of entity reference fields in mapping.
   *
   * @var array
   */
  protected $entityReferenceFields;

  /**
   * Array of entity reference fields in mapping.
   *
   * @var array
   */
  protected $entityReferenceFieldsOptions;

  /**
   * Entity field manager.
   *
   * @var \Drupal\Core\Entity\EntityFieldManagerInterface
   */
  protected $entityFieldManager;

  /**
   * {@inheritdoc}
   */
  public function __construct(EntityFieldManagerInterface $entityFieldManager) {
    $this->entityFieldManager = $entityFieldManager;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('entity_field.manager')
    );
  }

  /**
   * Sets entityReferenceFields variable.
   *
   * @param array|null $value
   *   Value.
   */
  public function setEntityReferenceFields($value) {
    $this->entityReferenceFields = $value;
  }

  /**
   * Sets entityReferenceFieldsOptions variable.
   *
   * @param array|null $value
   *   Value.
   */
  public function setEntityReferenceFieldsOptions($value) {
    $this->entityReferenceFieldsOptions = $value;
  }

  /**
   * Ajax callback for mapping multistep form.
   *
   * @return array
   *   Array of form elements.
   *
   * @inheritdoc
   */
  public function getMappingTable(array &$form, FormStateInterface $form_state) {
    $this->contentType = $form_state->getValue('content_type');
    $fields = $this->entityReferenceFieldsOptions;
    $form['mapping']['#attached']['drupalSettings']['content_workflow_bynder'] = (empty($fields) ? NULL : $fields);
    $form_state->setRebuild(TRUE);
    return $form['mapping'];
  }

  /**
   * Ajax callback for mapping multistep form.
   *
   * @return array
   *   Array of form elements.
   *
   * @inheritdoc
   */
  public function getContentTypes(array &$form, FormStateInterface $form_state) {
    $form_state->setRebuild(TRUE);
    return $form['content_workflow_bynder']['content_type'];
  }

  /**
   * Generate automatically terms for local field from Content Workflow options.
   *
   * @param \Drupal\field\Entity\FieldConfig $handlerSettings
   *   Field config for local field.
   * @param array $localOptions
   *   Array of remote options.
   * @param string $langcode
   *   The language of the generated term.
   */
  public function automaticTermsGenerator(FieldConfig $handlerSettings, array $localOptions, $langcode) {
    $settings = $handlerSettings->getSetting('handler_settings');
    /** @var \Drupal\taxonomy\Entity\Term[] $terms */
    if (!empty($settings['auto_create_bundle'])) {
      $vid = $settings['auto_create_bundle'];
    }
    else {
      $vid = reset($settings['target_bundles']);
    }

    // Check if field exists.
    $this->cwbOptionIdsFieldExists($vid);

    foreach ($localOptions as $id => $localOption) {
      $query = $this->entityTypeManager->getStorage('taxonomy_term')->getQuery();
      $query->accessCheck(TRUE);
      $group = $query->orConditionGroup()
        ->condition('contentworkflowbynder_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 = $this->entityTypeManager->getStorage('taxonomy_term')->load($term_id);
        if ($langcode === LanguageInterface::LANGCODE_NOT_SPECIFIED) {
          if ($term->label() !== $localOption) {
            $term->setName($localOption);
          }
          $values = $term->get('contentworkflowbynder_option_ids')->getValue();
          $mappedValues = array_map(function ($array) {
            return $array['value'];
          }, $values);

          if (!in_array($id, $mappedValues)) {
            $term->contentworkflowbynder_option_ids->appendItem($id);
          }
        }
        else {
          if ($term->getTranslation($langcode)->label() !== $localOption) {
            $term->getTranslation($langcode)->setName($localOption);
          }
          $values = $term->getTranslation($langcode)->get('contentworkflowbynder_option_ids')->getValue();
          $mappedValues = array_map(function ($array) {
            return $array['value'];
          }, $values);

          if (!in_array($id, $mappedValues)) {
            $term->getTranslation($langcode)->contentworkflowbynder_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('contentworkflowbynder_option_ids', $id);
        $term->save();
        $this->erImported++;
      }
    }
  }

  /**
   * Prepare options for every language for every field.
   *
   * @param \GatherContent\DataTypes\Template $template
   *   GatherContent template object.
   *
   * @return array
   *   Array with options.
   */
  public function prepareOptions(Template $template) {
    $options = [];
    foreach ($this->entityReferenceFields as $cwbMapping) {
      foreach ($cwbMapping as $fieldSettings) {
        foreach ($template['related']->structure->groups as $group) {
          if ($group->id === $fieldSettings['tab']) {
            foreach ($group->fields as $field) {
              if ($field->id === $fieldSettings['name']) {
                foreach ($field->metaData->choiceFields['options'] as $option) {
                  $options[$option['optionId']] = $option['label'];
                }
              }
            }
          }
        }
      }
    }
    return $options;
  }

  /**
   * Validate if contentworkflowbynder_option_ids field exists on specified vocabulary.
   *
   * If field doesn't exists, create it for specified vocabulary.
   *
   * @param string $vid
   *   Taxonomy vocabulary identifier.
   */
  public function cwbOptionIdsFieldExists($vid) {
    if ($this->entityTypeManager->hasDefinition('taxonomy_term')) {
      $definitions = $this->entityFieldManager->getFieldStorageDefinitions('taxonomy_term');
      if (!isset($definitions['contentworkflowbynder_option_ids'])) {
        FieldStorageConfig::create([
          'field_name' => 'contentworkflowbynder_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, 'contentworkflowbynder_option_ids');
      if (is_null($field_config)) {
        FieldConfig::create([
          'field_name' => 'contentworkflowbynder_option_ids',
          'entity_type' => 'taxonomy_term',
          'bundle' => $vid,
          'label' => 'Content Workflow Option IDs',
        ])->save();
      }
    }
  }

  /**
   * Handle manual type of taxonomy terms.
   *
   * @param array|null $languages
   *   Array with languages available for mapping.
   * @param \Drupal\Core\Entity\EntityStorageInterface $entityStorage
   *   Storage object for taxonomy terms.
   * @param array $row
   *   Array with mapping options.
   */
  public function manualErImport($languages, EntityStorageInterface $entityStorage, array $row) {
    if (!empty($languages) && !empty($row['terms'])) {
      $terms = $entityStorage->loadByProperties(['contentworkflowbynder_option_ids' => $row[$languages[0]]]);
      /** @var \Drupal\taxonomy\Entity\Term $term */
      $term = array_shift($terms);
      // If term already exists.
      if (!empty($term)) {
        // If term was changed, remove option ids for every
        // language.
        if ($term->id() !== $row['terms']) {
          // We don't know how many languages are translated.
          $translation_languages = $term->getTranslationLanguages(TRUE);
          foreach ($translation_languages as $language) {
            if ($term->hasTranslation($language) && !empty($row[$language])) {
              $option_ids = $term->getTranslation($language)
                ->get('contentworkflowbynder_option_ids');
              foreach ($option_ids as $i => $option_id) {
                if ($option_id == $row[$language]) {
                  unset($option_ids[$i]);
                }
              }
              $term->getTranslation($language)
                ->set('contentworkflowbynder_option_ids', $option_ids);
            }
          }
        }
      }

      // Set new values to correct term.
      $term = $this->entityTypeManager->getStorage('taxonomy_term')->load($row['terms']);
      if (!empty($languages)) {
        foreach ($languages as $language) {
          $term->getTranslation($language)
            ->set('contentworkflowbynder_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(['contentworkflowbynder_option_ids' => $und_lang_value]);
        /** @var \Drupal\taxonomy\Entity\Term $term */
        $term = array_shift($terms);
        // If term already exists.
        if (!empty($term)) {
          // If term was changed, remove option ids for every
          // language.
          if ($term->id() !== $row['terms']) {
            $option_ids = $term->get('contentworkflowbynder_option_ids');
            foreach ($option_ids as $i => $option_id) {
              if ($option_id == $und_lang_value) {
                unset($option_ids[$i]);
              }
            }
            $term->set('contentworkflowbynder_option_ids', $option_ids);
          }
        }
        // Set new values to correct term.
        $term = $this->entityTypeManager->getStorage('taxonomy_term')->load($row['terms']);
        $term->set('contentworkflowbynder_option_ids', $und_lang_value);
        $term->save();
        $this->erImported++;
      }
    }
  }

  /**
   * Handle semiautomatic import of taxonomy terms.
   *
   * @param array|null $languages
   *   Array with languages available for mapping.
   * @param \Drupal\Core\Entity\EntityStorageInterface $entityStorage
   *   Storage object for taxonomy terms.
   * @param array $row
   *   Array with mapping options.
   * @param array $options
   *   ContentWorkflowBynder options for every language and every field.
   * @param string $vid
   *   Taxonomy vocabulry identifier.
   */
  public function semiErImport($languages, EntityStorageInterface $entityStorage, array $row, array $options, $vid) {
    if (!empty($languages)) {
      $terms = $entityStorage->loadByProperties(['contentworkflowbynder_option_ids' => $row[$languages[0]]]);
      /** @var \Drupal\taxonomy\Entity\Term $term */
      $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('contentworkflowbynder_option_ids', $row[$language]);
            $term->getTranslation($language)
              ->setName($options[$row[$language]]);
          }
        }
        if (!empty($term->getTranslationLanguages())) {
          $term->save();
          $this->erImported++;
        }
      }
    }
    else {
      /** @var \Drupal\taxonomy\Entity\Term $term */
      $und_lang_value = $row[LanguageInterface::LANGCODE_NOT_SPECIFIED];
      if (!empty($und_lang_value)) {
        $terms = $entityStorage->loadByProperties(['contentworkflowbynder_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,
            'contentworkflowbynder_option_ids' => $und_lang_value,
          ]);
          $term->setName($options[$und_lang_value]);
          $term->save();
          $this->erImported++;
        }
      }
    }
  }

  /**
   * Get available languages from currect row.
   *
   * @param array $row
   *   Currect row from mapping.
   *
   * @return array
   *   Array with available languages.
   */
  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;
  }

  /**
   * Get vocabulary identifier for field in content type.
   *
   * @param string $field_id
   *   ID of local field.
   *
   * @return string
   *   Identifier of vocabulary.
   */
  public function getVocabularyId($field_id) {
    // Load vocabulary.
    $id_array = explode('||', $field_id);
    $field_config = FieldConfig::load($id_array[count($id_array) - 1]);
    $settings = $field_config->getSetting('handler_settings');
    /** @var \Drupal\taxonomy\Entity\Term[] $terms */
    if (!empty($settings['auto_create_bundle'])) {
      $vid = $settings['auto_create_bundle'];
      return $vid;
    }
    else {
      $vid = reset($settings['target_bundles']);
      return $vid;
    }
  }

  /**
   * Extract mapping data from submitted form values.
   *
   * @param array $formValues
   *   Array with all submitted values.
   *
   * @return array
   *   Mapping data.
   */
  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, [
      'cwb_template',
      'content_type',
      'entity_type',
      'id',
      'updated',
      'project',
      'template_name',
      'er_mapping_type',
      'submit',
      'close',
    ]);

    $mapping_data = [];
    foreach ($formValues as $key => $value) {
      if (!in_array($key, $non_data_elements)) {
        $mapping_data[$key] = $value;
      }
    }

    $this->mappingData = $mapping_data;
    return $mapping_data;
  }

}

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

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