lunr-8.x-1.0/src/Form/LunrSearchEditForm.php

src/Form/LunrSearchEditForm.php
<?php

namespace Drupal\lunr\Form;

use Drupal\Component\Utility\UrlHelper;
use Drupal\Core\Entity\EntityForm;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Path\PathValidatorInterface;
use Drupal\Core\Routing\RouteBuilderInterface;
use Drupal\lunr\Plugin\views\row\LunrSearchIndexRow;
use Drupal\views\Views;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Base form for Lunr search add/edit forms.
 */
class LunrSearchEditForm extends EntityForm {

  /**
   * The Lunr search being edited/created.
   *
   * @var \Drupal\lunr\LunrSearchInterface
   */
  protected $entity;

  /**
   * The route builder.
   *
   * @var \Drupal\Core\Routing\RouteBuilderInterface
   */
  protected $routeBuilder;

  /**
   * The path validator.
   *
   * @var \Drupal\Core\Path\PathValidatorInterface
   */
  protected $pathValidator;

  /**
   * LunrSearchEditForm constructor.
   *
   * @param \Drupal\Core\Routing\RouteBuilderInterface $route_builder
   *   The route builder.
   * @param \Drupal\Core\Path\PathValidatorInterface $path_validator
   *   The path validator.
   */
  public function __construct(RouteBuilderInterface $route_builder, PathValidatorInterface $path_validator) {
    $this->routeBuilder = $route_builder;
    $this->pathValidator = $path_validator;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('router.builder'),
      $container->get('path.validator')
    );
  }

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

    $form['label'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Label'),
      '#maxlength' => 255,
      '#default_value' => $this->entity->label(),
      '#description' => $this->t('The label for this search, which is used as the title for its page.'),
      '#required' => TRUE,
    ];

    $form['id'] = [
      '#type' => 'machine_name',
      '#default_value' => $this->entity->id(),
      '#machine_name' => [
        'exists' => '\Drupal\lunr\Entity\LunrSearch::load',
      ],
      '#disabled' => !$this->entity->isNew(),
      '#required' => TRUE,
    ];

    $form['path'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Path'),
      '#default_value' => $this->entity->getPath(),
      '#description' => $this->t('Where this form will appear.'),
      '#required' => TRUE,
    ];

    // Get only those enabled Views that have entity_browser displays.
    $displays = Views::getApplicableViews('lunr_search_display');
    $options = [];
    foreach ($displays as $display) {
      list($view_id, $display_id) = $display;
      $view = $this->entityTypeManager->getStorage('view')->load($view_id);
      $options[$view_id . '.' . $display_id] = $this->t('@view : @display', ['@view' => $view->label(), '@display' => $view->get('display')[$display_id]['display_title']]);
    }

    $form['view'] = [
      '#type' => 'select',
      '#title' => $this->t('View : Display'),
      '#description' => $this->t('The view and display to build the index from. Only "Lunr search index" view displays can be used.'),
      '#default_value' => $this->entity->getViewId() . '.' . $this->entity->getViewDisplayId(),
      '#options' => $options,
      '#empty_option' => $this->t('- Select a view -'),
      '#required' => TRUE,
      '#ajax' => [
        'wrapper' => 'lunr-search-view-fields',
        'callback' => '::refreshViewsFields',
      ],
    ];

    $form['view_fields'] = [
      '#type' => 'container',
      '#attributes' => [
        'id' => 'lunr-search-view-fields',
      ],
      'views_fields' => [
        '#markup' => $this->getViewsFieldsText(),
      ],
    ];

    $text = '';
    foreach ($this->entity->getIndexFields() as $field => $attributes) {
      $text .= "$field|${attributes['boost']}\n";
    }

    $form['index_fields_textarea'] = [
      '#type' => 'textarea',
      '#cols' => 10,
      '#title' => $this->t('Index fields'),
      '#description' => $this->t('Fields to index in the format field_name|boost. The lowest boost value is 1.'),
      '#default_value' => $text,
      '#required' => TRUE,
    ];

    $form['display_field'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Display field'),
      '#description' => $this->t('A field to display. Normally this is a rendered entity or custom text/Twig field.'),
      '#default_value' => $this->entity->getDisplayField(),
      '#required' => TRUE,
    ];

    $form['results_per_page'] = [
      '#type' => 'number',
      '#title' => $this->t('Results per page'),
      '#description' => $this->t('How many search results to show per page.'),
      '#default_value' => $this->entity->getResultsPerPage() ?: 10,
      '#min' => 1,
      '#required' => TRUE,
    ];

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function buildEntity(array $form, FormStateInterface $form_state) {
    if ($form_state->getValue('view')) {
      list($view_id, $display_id) = explode('.', $form_state->getValue('view'));
      $form_state->setValue('view_id', $view_id);
      $form_state->setValue('view_display_id', $display_id);
    }
    else {
      $form_state->setValue('view_id', NULL);
      $form_state->setValue('view_display_id', NULL);
    }
    $fields = [];
    foreach (explode("\n", $form_state->getValue('index_fields_textarea')) as $line) {
      $parts = explode('|', $line);
      if (count($parts) !== 2) {
        continue;
      }
      list($field, $boost) = $parts;
      $fields[$field] = [
        'boost' => (int) $boost,
      ];
    }
    $form_state->setValue('index_fields', $fields);
    return parent::buildEntity($form, $form_state);
  }

  /**
   * {@inheritdoc}
   */
  public function validateForm(array &$form, FormStateInterface $form_state) {
    parent::validateForm($form, $form_state);
    $path = $form_state->getValue('path');
    $parsed_url = UrlHelper::parse($path);
    if (empty($parsed_url['path'])) {
      $form_state->setError($form['path'], $this->t('Path is empty.'));
    }
    elseif (!empty($parsed_url['query']) || !empty($parsed_url['fragment'])) {
      $form_state->setError($form['path'], $this->t('No query or fragment allowed.'));
    }
    elseif ($path[0] !== '/') {
      $form_state->setError($form['path'], $this->t('The path must begin with a slash.'));
    }
    elseif (UrlHelper::isExternal($path)) {
      $form_state->setError($form['path'], $this->t('The path cannot be external.'));
    }
    elseif ($path !== $form['path']['#default_value'] && $this->pathValidator->getUrlIfValidWithoutAccessCheck($path)) {
      $form_state->setError($form['path'], $this->t('This path is already used on the site.'));
    }
    foreach (preg_split('/\R/', $form_state->getValue('index_fields_textarea')) as $line) {
      if (empty($line)) {
        continue;
      }
      $parts = explode('|', $line);
      if (count($parts) !== 2) {
        $form_state->setError($form['index_fields_textarea'], $this->t('Invalid field format provided.'));
        break;
      }
      if (!is_numeric($parts[1])) {
        $form_state->setError($form['index_fields_textarea'], $this->t('Invalid boost value provided.'));
      }
      elseif ($parts[1] < 1) {
        $form_state->setError($form['index_fields_textarea'], $this->t('A positive boost value is required.'));
      }
    }
  }

  /**
   * {@inheritdoc}
   */
  public function save(array $form, FormStateInterface $form_state) {
    parent::save($form, $form_state);
    $this->routeBuilder->setRebuildNeeded();
    $this->messenger()->addMessage($this->t('The Lunr search has been saved. You may need to index again if you made configuration changes that affect the index.'));
    $form_state->setRedirectUrl($this->entity->toUrl('collection'));
  }

  /**
   * {@inheritdoc}
   */
  protected function actions(array $form, FormStateInterface $form_state) {
    $actions = parent::actions($form, $form_state);

    if (!$this->entity->isNew()) {
      $actions['index'] = [
        '#type' => 'link',
        '#title' => $this->t('Index'),
        '#url' => $this->entity->toUrl('index'),
        '#attributes' => [
          'class' => ['button'],
        ],
      ];
    }

    return $actions;
  }

  /**
   * Gets a helper string for the current view's fields.
   *
   * @return string
   *   A helper string.
   */
  protected function getViewsFieldsText() {
    $fields = [];
    $text = '';
    $view = $this->entity->getView();
    if ($view && $view->setDisplay($this->entity->getViewDisplayId())) {
      $view->initHandlers();
      if ($view->rowPlugin instanceof LunrSearchIndexRow) {
        foreach ($view->field as $id => $field) {
          if (empty($field->options['exclude'])) {
            $fields[] = $view->rowPlugin->getFieldKeyAlias($id);
          }
        }
      }
    }
    if (!empty($fields)) {
      $text = $this->t('<strong>Available fields for this view</strong>: @fields.', [
        '@fields' => implode(', ', $fields),
      ]);
    }
    return $text;
  }

  /**
   * Refreshes the views fields helper text.
   *
   * @param array $form
   *   The form array.
   *
   * @return array
   *   The views fields form element.
   */
  public function refreshViewsFields(array $form) {
    return $form['view_fields'];
  }

}

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

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