library_manager-8.x-1.0/src/Form/LibraryDefinitionForm.php

src/Form/LibraryDefinitionForm.php
<?php

namespace Drupal\library_manager\Form;

use Drupal\Component\Render\FormattableMarkup;
use Drupal\Core\Condition\ConditionManager;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\EntityForm;
use Drupal\Core\Form\FormState;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Link;
use Drupal\Core\Plugin\ContextAwarePluginInterface;
use Drupal\Core\StringTranslation\ByteSizeMarkup;
use Drupal\Core\Url;
use Drupal\file\Entity\File;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Library definition form.
 *
 * @property \Drupal\library_manager\LibraryDefinitionInterface $entity
 */
class LibraryDefinitionForm extends EntityForm {

  /**
   * The config factory.
   *
   * @var \Drupal\Core\Config\ConfigFactoryInterface
   */
  protected $configFactory;

  /**
   * The library discovery service.
   *
   * @var \Drupal\Core\Condition\ConditionManager
   */
  protected $conditionManager;

  /**
   * Constructs the form object.
   *
   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
   *   The factory for configuration objects.
   * @param \Drupal\Core\Condition\ConditionManager $condition_manager
   *   Condition manager.
   */
  public function __construct(ConfigFactoryInterface $config_factory, ConditionManager $condition_manager) {
    $this->configFactory = $config_factory;
    $this->conditionManager = $condition_manager;
  }

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

  /**
   * {@inheritdoc}
   */
  public function form(array $form, FormStateInterface $form_state) {

    $settings = $this->configFactory->get('library_manager.settings')->get();

    $form = parent::form($form, $form_state);

    $form['id'] = [
      '#type' => 'machine_name',
      '#title' => $this->t('Machine name'),
      '#default_value' => $this->entity->id(),
      '#machine_name' => [
        'exists' => '\Drupal\library_manager\Entity\LibraryDefinition::load',
      ],
      '#disabled' => !$this->entity->isNew(),
    ];

    $form['mode'] = [
      '#type' => 'radios',
      '#options' => [
        'new' => $this->t('Register new library'),
        'override' => $this->t('Override existing library'),
      ],
      '#default_value' => $this->entity->get('target') ? 'override' : 'new',
    ];

    $form['target'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Library to override'),
      '#default_value' => $this->entity->get('target'),
      '#autocomplete_route_name' => 'library_manager.library_autocomplete',
      '#states' => [
        'visible' => [
          ':input[name="mode"]' => ['value' => 'override'],
        ],
      ],
    ];

    $form['remote'] = [
      '#type' => 'url',
      '#title' => $this->t('Remote'),
      '#default_value' => $this->entity->get('remote'),
    ];

    $form['version'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Version'),
      '#required' => TRUE,
      '#default_value' => $this->entity->get('version'),
    ];

    $license = $this->entity->get('license');
    $form['license'] = [
      '#type' => 'fieldset',
      '#title' => $this->t('License'),
      '#tree' => TRUE,
    ];
    $data_list = new FormattableMarkup('<datalist id="license"><option value="GNU-GPL-2.0-or-later"><option value="MIT"><option value="Public Domain"></datalist>', []);
    $form['license']['name'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Name'),
      '#field_suffix' => $data_list,
      '#attributes' => ['list' => ['license']],
      '#default_value' => $license['name'],
    ];
    $form['license']['url'] = [
      '#type' => 'url',
      '#title' => $this->t('URL'),
      '#default_value' => $license['url'],
    ];
    $form['license']['gpl-compatible'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('GPL compatible'),
      '#default_value' => $license['gpl-compatible'],
    ];

    // JS files.
    $form['js'] = [
      '#type' => 'fieldset',
      '#title' => $this->t('JS files'),
    ];

    $js_header = [
      $this->t('Name'),
      $this->t('Size'),
      $this->t('Type'),
      $this->t('Weight'),
      $this->t('Operations'),
    ];

    $form['js']['table'] = [
      '#type' => 'table',
      '#header' => $js_header,
      '#rows' => [],
      '#empty' => $this->t('JS files are not configured yet.'),
    ];

    $js = $this->entity->get('js');

    // Sort JS rows by weight.
    uasort($js, function ($a, $b) {
      return $a['weight'] <=> $b['weight'];
    });

    foreach ($js as $file_id => $js_data) {
      $weight = $js_data['weight'];

      if ($js_data['external']) {
        if ($js_data['url']) {
          $file_url = Url::fromUri($js_data['url'], ['attributes' => ['target' => '_blank']]);
          $file_name = Link::fromTextAndUrl($js_data['file_name'], $file_url)->toString();
        }
        else {
          $file_name = $js_data['file_name'];
        }
        $rows = [
          $file_name,
          '',
          $this->t('External'),
          $weight,
        ];
      }
      elseif (isset($js_data['code_type']) && $js_data['code_type'] == 'file_upload') {
        $file_name = '';
        $file_size = '';
        if (isset($js_data['file_upload'])) {
          $uploaded_file_id = $js_data['file_upload'];
          if (!empty($uploaded_file_id)) {
            $uploaded_file = File::load($uploaded_file_id);
            if (!empty($uploaded_file)) {
              $file_name = $uploaded_file->getFilename();
              $file_size = $uploaded_file->getSize();
              $file_size = ByteSizeMarkup::create($file_size);
            }
          }
        }
        $rows = [
          $file_name,
          $file_size,
          $this->t('File Upload'),
        ];
      }
      else {
        $file_path = '/' . $settings['libraries_path'] . '/' . $this->entity->id() . '/' . $js_data['file_name'];
        $file_url = Url::fromUri('internal:' . $file_path, ['attributes' => ['target' => '_blank']]);
        $file_name = Link::fromTextAndUrl($js_data['file_name'], $file_url)->toString();
        $rows = [
          $file_name,
          \Drupal\Component\Utility\DeprecationHelper::backwardsCompatibleCall(\Drupal::VERSION, '10.2.0', fn() => \Drupal\Core\StringTranslation\ByteSizeMarkup::create(mb_strlen($js_data['code'])), fn() => format_size(mb_strlen($js_data['code']))),
          $this->t('Local'),
          $weight,
        ];
      }

      $route_parameters = [
        'library_definition' => $this->entity->id(),
        'file_id' => $file_id,
      ];

      $operation_links = [
        'edit' => [
          'title' => $this->t('Edit'),
          'url' => Url::fromRoute('entity.library_definition.edit_js_form', $route_parameters),
        ],
        'delete' => [
          'title' => $this->t('Delete'),
          'url' => Url::fromRoute('entity.library_definition.delete_js_form', $route_parameters),
        ],
      ];

      $operation_data = [
        '#type' => 'operations',
        '#links' => $operation_links,
      ];
      $form['js']['table']['#rows'][$file_id] = $rows + ['operations' => ['data' => $operation_data]];
    }

    // Do not show Add JS file button until the entity is persisted.
    if (!$this->entity->isNew()) {
      $form['js']['add_js'] = [
        '#type' => 'link',
        '#title' => $this->t('Add JS file'),
        '#url' => new Url('entity.library_definition.add_js_form', ['library_definition' => $this->entity->id()]),
        '#attributes' => ['class' => ['button', 'button--small']],
      ];
    }

    // CSS files.
    $form['css'] = [
      '#type' => 'fieldset',
      '#title' => $this->t('CSS files'),
    ];

    $css_header = [
      $this->t('Name'),
      $this->t('Size'),
      $this->t('Type'),
      $this->t('Operations'),
    ];

    $form['css']['table'] = [
      '#type' => 'table',
      '#header' => $css_header,
      '#rows' => [],
      '#empty' => $this->t('CSS files are not configured yet.'),
    ];

    $css = $this->entity->get('css');
    foreach ($css as $file_id => $css_data) {

      if ($css_data['external']) {
        if ($css_data['url']) {
          $file_url = Url::fromUri($css_data['url'], ['attributes' => ['target' => '_blank']]);
          $file_name = Link::fromTextAndUrl($css_data['file_name'], $file_url)->toString();
        }
        else {
          $file_name = $css_data['file_name'];
        }
        $rows = [
          $file_name,
          '',
          $this->t('External'),
        ];
      }
      elseif (isset($css_data['code_type']) && $css_data['code_type'] == 'file_upload') {
        $file_name = '';
        $file_size = '';
        if (isset($css_data['file_upload'])) {
          $uploaded_file_id = $css_data['file_upload'];
          if (!empty($uploaded_file_id)) {
            $uploaded_file = File::load($uploaded_file_id);
            if (!empty($uploaded_file)) {
              $file_name = $uploaded_file->getFilename();
              $file_size = $uploaded_file->getSize();
              $file_size = ByteSizeMarkup::create($file_size);
            }
          }
        }
        $rows = [
          $file_name,
          $file_size,
          $this->t('File Upload'),
        ];
      }
      else {
        $file_path = '/' . $settings['libraries_path'] . '/' . $this->entity->id() . '/' . $css_data['file_name'];
        $file_url = Url::fromUri('internal:' . $file_path, ['attributes' => ['target' => '_blank']]);
        $file_name = Link::fromTextAndUrl($css_data['file_name'], $file_url)->toString();
        $rows = [
          $file_name,
          \Drupal\Component\Utility\DeprecationHelper::backwardsCompatibleCall(\Drupal::VERSION, '10.2.0', fn() => \Drupal\Core\StringTranslation\ByteSizeMarkup::create(mb_strlen($css_data['code'])), fn() => format_size(mb_strlen($css_data['code']))),
          $this->t('Local'),
        ];
      }

      $route_parameters = [
        'library_definition' => $this->entity->id(),
        'file_id' => $file_id,
      ];

      $operation_links = [
        'edit' => [
          'title' => $this->t('Edit'),
          'url' => Url::fromRoute('entity.library_definition.edit_css_form', $route_parameters),
        ],
        'delete' => [
          'title' => $this->t('Delete'),
          'url' => Url::fromRoute('entity.library_definition.delete_css_form', $route_parameters),
        ],
      ];

      $operation_data = [
        '#type' => 'operations',
        '#links' => $operation_links,
      ];

      $form['css']['table']['#rows'][$file_id] = $rows + ['operations' => ['data' => $operation_data]];
    }

    if (!$this->entity->isNew()) {
      $form['css']['add_css'] = [
        '#type' => 'link',
        '#title' => $this->t('Add CSS file'),
        '#url' => new Url('entity.library_definition.add_css_form', ['library_definition' => $this->entity->id()]),
        '#attributes' => ['class' => ['button', 'button--small']],
      ];

    }

    // Dependencies.
    $form['dependencies'] = [
      '#type' => 'fieldset',
      '#title' => $this->t('Dependencies'),
    ];

    $form['dependencies']['wrapper'] = [
      '#type' => 'container',
      '#id' => 'wrapper',
    ];

    $form['dependencies']['wrapper']['library_dependencies']['#tree'] = TRUE;

    $stored_dependencies = $this->entity->get('library_dependencies');
    $submitted_dependencies = (array) $form_state->getValue('library_dependencies');

    $max_delta = max(count($stored_dependencies), count($submitted_dependencies) + 1);

    for ($delta = 0; $delta < $max_delta; $delta++) {
      $form['dependencies']['wrapper']['library_dependencies'][$delta] = [
        '#type' => 'textfield',
        '#autocomplete_route_name' => 'library_manager.library_autocomplete',
        '#default_value' => isset($stored_dependencies[$delta]) ? $stored_dependencies[$delta] : '',
      ];
    }

    $form['dependencies']['add'] = [
      '#type' => 'button',
      '#name' => 'add_library',
      '#value' => $this->t('Add dependency'),
      '#submit' => [[$this, 'addMoreSubmit']],
      '#attributes' => ['class' => ['button', 'button--small']],
      '#ajax' => [
        'callback' => [$this, 'addMoreCallback'],
        'wrapper' => 'wrapper',
      ],
    ];

    $form['override_by_visibility'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Override the library just by below visibility rules'),
      '#default_value' => $this->entity->get('override_by_visibility'),
      '#states' => [
        'visible' => [
          ':input[name="mode"]' => ['value' => 'override'],
        ],
      ],
    ];

    $form['load'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Load the library automatically according to visibility rules'),
      '#default_value' => $this->entity->get('load'),
      '#states' => [
        'visible' => [
          ':input[name="mode"]' => ['value' => 'new'],
        ],
      ],
    ];

    $form['visibility'] = $this->buildVisibilityInterface([], $form_state);

    $form['status'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Enabled'),
      '#default_value' => $this->entity->get('status'),
    ];

    $form['label_on_new'] = [
      '#type' => 'item',
      '#title' => $this->t("When register new library, Checking 'Enabled' means other module/theme still can use this library even if above 'Load the library automatically according to visibility rules' is unchecked."),
      '#states' => [
        'visible' => [
          ':input[name="mode"]' => ['value' => 'new'],
        ],
      ],
    ];

    return $form;
  }

  /**
   * Dependencies ajax callback.
   */
  public function addMoreCallback(array $form, FormStateInterface $form_state) {
    return $form['dependencies']['wrapper'];
  }

  /**
   * Dependencies submit callback.
   */
  public function addMoreSubmit(array $form, FormStateInterface $form_state) {
    $form_state->setRebuild();
  }

  /**
   * {@inheritdoc}
   */
  public function save(array $form, FormStateInterface $form_state) {

    $message = $this->entity->save() == SAVED_NEW ?
      $this->t('Library definition has been created.') : $this->t('Library definition has been updated.');
    $this->messenger()->addStatus($message);

    $form_state->setRedirectUrl($this->entity->toUrl('collection'));
  }

  /**
   * Helper function for building the visibility UI form.
   *
   * @param array $form
   *   An associative array containing the structure of the form.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The current state of the form.
   *
   * @return array
   *   The form array with the visibility UI added in.
   */
  protected function buildVisibilityInterface(array $form, FormStateInterface $form_state) {

    $form['#tree'] = TRUE;

    $form['visibility_tabs'] = [
      '#type' => 'vertical_tabs',
      '#title' => $this->t('Visibility'),
      '#parents' => ['visibility_tabs'],
    ];

    $visibility = $this->entity->getVisibility();

    foreach ($this->conditionManager->getFilteredDefinitions('library_manager') as $condition_id => $definition) {

      /** @var \Drupal\Core\Condition\ConditionInterface $condition */
      $condition = $this->conditionManager->createInstance($condition_id, isset($visibility[$condition_id]) ? $visibility[$condition_id] : []);
      $form_state->set(['conditions', $condition_id], $condition);
      $condition_form = $condition->buildConfigurationForm([], $form_state);
      $condition_form['#type'] = 'details';
      $condition_form['#title'] = $condition->getPluginDefinition()['label'];
      $condition_form['#group'] = 'visibility_tabs';
      $form[$condition_id] = $condition_form;
    }

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function validateForm(array &$form, FormStateInterface $form_state) {
    parent::validateForm($form, $form_state);
    $this->validateVisibility($form, $form_state);
  }

  /**
   * Helper function to independently validate the visibility UI.
   *
   * @param array $form
   *   A nested array form elements comprising the form.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The current state of the form.
   */
  protected function validateVisibility(array $form, FormStateInterface $form_state) {

    // Validate visibility condition settings.
    foreach ($form_state->getValue('visibility') as $condition_id => $values) {
      // All condition plugins use 'negate' as a Boolean in their schema.
      // However, certain form elements may return it as 0/1. Cast here to
      // ensure the data is in the expected type.
      if (array_key_exists('negate', $values)) {
        $values['negate'] = (bool) $values['negate'];
      }

      // Allow the condition to validate the form.
      $condition = $form_state->get(['conditions', $condition_id]);
      $condition_values = (new FormState())
        ->setValues($values);
      $condition->validateConfigurationForm($form, $condition_values);
      // Update the original form values.
      $form_state->setValue(['visibility', $condition_id], $condition_values->getValues());
    }
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    parent::submitForm($form, $form_state);

    $entity = $this->entity;

    if ($form_state->getValue('mode') == 'new') {
      $entity->set('target', NULL);
    }

    $dependencies = array_values(array_filter($form_state->getValue('library_dependencies')));
    $entity->set('library_dependencies', $dependencies);

    // Submit visibility condition settings.
    foreach ($form_state->getValue('visibility') as $condition_id => $values) {
      // Allow the condition to submit the form.
      $condition = $form_state->get(['conditions', $condition_id]);
      $condition_values = (new FormState())
        ->setValues($values);
      $condition->submitConfigurationForm($form, $condition_values);

      if ($condition instanceof ContextAwarePluginInterface) {
        $context_mapping = isset($values['context_mapping']) ? $values['context_mapping'] : [];
        $condition->setContextMapping($context_mapping);
      }
      // Update the original form values.
      $condition_configuration = $condition->getConfiguration();
      $form_state->setValue(['visibility', $condition_id], $condition_configuration);
      // Update the visibility conditions.
      $entity->getVisibilityConditions();
      $entity->getVisibilityConditions()->addInstanceId($condition_id, $condition_configuration);
    }

  }

}

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

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