sites_group_overrides-1.x-dev/src/FormDecorator/ConfigFields.php

src/FormDecorator/ConfigFields.php
<?php

declare(strict_types=1);

namespace Drupal\sites_group_overrides\FormDecorator;

use Drupal\Core\Form\FormStateInterface;
use Drupal\group\Entity\GroupTypeInterface;
use Drupal\form_decorator\FormDecoratorBase;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\sites_group\SitesGroupServiceInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Plugin implementation of the form_decorator.
 *
 * @FormDecorator(
 *   hook = "form_field_config_edit_form_alter"
 * )
 */
final class ConfigFields extends FormDecoratorBase implements ContainerFactoryPluginInterface {

  use StringTranslationTrait;

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, $configuration, $plugin_id, $plugin_definition) {
    return new self($configuration, $plugin_id, $plugin_definition,
      $container->get('entity_type.manager'),
      $container->get('entity_field.manager'),
      $container->get('sites_group.service')
    );
  }

  /**
   * {@inheritdoc}
   */
  public function __construct(
    array $configuration,
    $plugin_id,
    $plugin_definition,
    protected EntityTypeManagerInterface $entityTypeManager,
    protected EntityFieldManagerInterface $entityFieldManager,
    protected SitesGroupServiceInterface $sitesGroupService
  ) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state, ...$args) {
    $form = parent::buildForm($form, $form_state, ...$args);

    // Add the sync option to field configs.
    $form['sites_group_overrides'] = [
      '#title' => $this->t('Sites group override settings'),
      '#type' => 'fieldset',
      '#tree' => TRUE,
      '#weight' => 12,
    ];

    /** @var GroupTypeInterface[] $group_types */
    $group_types = $this->sitesGroupService->getGroupTypes();
    foreach ($group_types as $group_type) {
      foreach ($group_type->getInstalledPlugins() as $plugin) {
        $definition = $plugin->getPluginDefinition();
        if ($definition->get('entity_type_id') != $this->getEntity()->get('entity_type')) {
          continue;
        }

        $bundle = $definition->get('entity_type_id');
        if ($definition->get('entity_bundle')) {
          $bundle = $definition->get('entity_bundle');
        }

        if ($bundle != $this->getEntity()->get('bundle')) {
          continue;
        }

        $relationship_bundle = $this->entityTypeManager->getStorage('group_relationship_type')->getRelationshipTypeId($group_type->id(), $plugin->getPluginId());

        // Add the sync option to field configs.
        $form['sites_group_overrides'][$relationship_bundle] = [
          '#title' => $this->t('Sites group type: %group_type', ['%group_type' => $group_type->label()]),
          '#type' => 'details',
          '#tree' => TRUE,
          '#open' => $this->getEntity()->getThirdPartySetting('sites_group_overrides', $relationship_bundle)['use_overrides'] ?? FALSE,
        ];
        $form['sites_group_overrides'][$relationship_bundle]['use_overrides'] = [
          '#title' => $this->t('Make this field overridable per sites group'),
          '#type' => 'checkbox',
          '#default_value' => $this->getEntity()->getThirdPartySetting('sites_group_overrides', $relationship_bundle)['use_overrides'] ?? FALSE,
        ];
        $form['sites_group_overrides'][$relationship_bundle]['use_existing_field'] = [
          '#title' => $this->t('Use existing field as storage'),
          '#type' => 'checkbox',
          '#default_value' => $this->getEntity()->getThirdPartySetting('sites_group_overrides', $relationship_bundle)['use_existing_field'] ?? FALSE,
          '#states' => [
            'visible' => [':input[name="sites_group_overrides[' . $relationship_bundle . '][use_overrides]"]' => ['checked' => TRUE]],
          ],
        ];
        $form['sites_group_overrides'][$relationship_bundle]['target_field_name'] = [
          '#title' => $this->t('Select field for override storage'),
          '#type' => 'select',
          '#options' => array_map(function ($d) {
            return t('@l (@mn)', ['@l' => $d->getLabel(), '@mn' => $d->getName()]);
          }, $this->entityFieldManager->getFieldDefinitions('group_relationship', $relationship_bundle)),
          '#default_value' => $this->getEntity()->getThirdPartySetting('sites_group_overrides', $relationship_bundle)['target_field_name'] ?? $this->getEntity()->get('field_name'),
          '#states' => [
            'visible' => [':input[name="sites_group_overrides[' . $relationship_bundle . '][use_existing_field]"]' => ['checked' => TRUE]],
          ],
        ];
      }
    }

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    $sync = $form_state->getValue('sites_group_overrides', []);
    $result = parent::submitForm($form, $form_state);

    foreach ($sync as $bundle => $settings) {
      if (!$settings['use_existing_field']) {
        $settings['target_field_name'] = $this->getEntity()->get('field_name');
      }
      $this->getEntity()->setThirdPartySetting('sites_group_overrides', $bundle, $settings);
      if ($settings['use_overrides']) {
        $this->snycToGroupRelationshipFieldStorage();
        $this->snycToGroupRelationshipField($bundle);
      }
    }

    $this->getEntity()->save();
    return $result;
  }

  // @todo Move this to service.
  private function snycToGroupRelationshipField(string $bundle) {
    $field_configs = $this->entityTypeManager->getStorage('field_config')->loadByProperties([
      'field_name' => $this->getEntity()->get('field_name'),
      'entity_type' => 'group_relationship',
      'bundle' => $bundle,
    ]);
    if (empty($field_configs)) {
      $field_config = $this->entityTypeManager->getStorage('field_config')->create([
        'field_name' => $this->getEntity()->get('field_name'),
        'entity_type' => 'group_relationship',
        'type' => $this->getEntity()->getFieldStorageDefinition()->get('type'),
        'bundle' => $bundle,
      ]);
      $field_configs = [$field_config];
    }
    foreach ($field_configs as $field_config) {
      $config = $this->getEntity()->toArray();
      foreach ($config as $key => $value) {
        if (in_array($key, ['uuid', 'field_name', 'entity_type', 'type', 'bundle'])) {
          continue;
        }
        $field_config->set($key, $value);
      }
      $field_config->save();
    }
  }

  // @todo move this to service.
  private function snycToGroupRelationshipFieldStorage() {
    $field_storage_configs = $this->entityTypeManager->getStorage('field_storage_config')->loadByProperties([
      'field_name' => $this->getEntity()->get('field_name'),
      'entity_type' => 'group_relationship',
    ]);
    if (empty($field_storage_configs)) {
      $field_storage_config = $this->entityTypeManager->getStorage('field_storage_config')->create([
        'field_name' => $this->getEntity()->get('field_name'),
        'entity_type' => 'group_relationship',
        'type' => $this->getEntity()->getFieldStorageDefinition()->get('type'),
      ]);
      $field_storage_configs = [$field_storage_config];
    }
    foreach ($field_storage_configs as $field_storage_config) {
      $storage_config = $this->getEntity()->getFieldStorageDefinition()->toArray();
      foreach ($storage_config as $key => $value) {
        if (in_array($key, ['uuid', 'field_name', 'entity_type', 'type'])) {
          continue;
        }
        $field_storage_config->set($key, $value);
      }
      $field_storage_config->save();
    }
  }

}

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

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