htools-8.x-1.x-dev/src/Plugin/views/display/BetterEmbed.php

src/Plugin/views/display/BetterEmbed.php
<?php

namespace Drupal\htools\Plugin\views\display;

use Drupal\Component\Utility\UrlHelper;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Language\LanguageInterface;
use Drupal\path_alias\AliasManagerInterface;
use Drupal\Core\Path\CurrentPathStack;
use Drupal\Core\Url;
use Drupal\views\Plugin\Block\ViewsBlock;
use Drupal\views\Plugin\views\display\DisplayPluginBase;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

/**
 * The plugin that handles an embed display.
 *
 * @ingroup views_display_plugins
 *
 * @todo: Wait until annotations/plugins support access methods.
 * no_ui => !\Drupal::config('views.settings')->get('ui.show.display_embed'),
 *
 * @ViewsDisplay(
 *   id = "better_embed",
 *   title = @Translation("Embed (Better)"),
 *   help = @Translation("Provide a display which can be embedded using the views api."),
 *   theme = "views_view",
 *   uses_hook_block = TRUE,
 *   uses_menu_links = FALSE
 * )
 */
class BetterEmbed extends DisplayPluginBase {

  /**
   * Current path.
   *
   * @var \Drupal\Core\Path\CurrentPathStack
   */
  protected $currentPath;

  /**
   * PrismaEmbed::aliasManager.
   *
   * @var \Drupal\Core\Path\AliasManagerInterface
   */
  protected $aliasManager;

  /**
   * {@inheritdoc}
   */
  public function __construct(array $configuration, $plugin_id, $plugin_definition, CurrentPathStack $currentPath, AliasManagerInterface $aliasManager) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);
    $this->currentPath = $currentPath;
    $this->aliasManager = $aliasManager;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static(
      $configuration,
      $plugin_id,
      $plugin_definition,
      $container->get('path.current'),
      $container->get('path_alias.manager')
    );
  }

  /**
   * {@inheritdoc}
   */
  public function optionsSummary(&$categories, &$options) {
    parent::optionsSummary($categories, $options);

    $categories['page'] = [
      'title' => $this->t('Page settings'),
      'column' => 'second',
      'build' => [
        '#weight' => -10,
      ],
    ];

    if ($this->getOption('path') === TRUE) {
      $path = '';
    }
    else {
      $path = strip_tags($this->getOption('path'));
    }


    if (empty($path)) {
      $path = $this->t('No path is set (Current url will be use)');
    }
    else {
      $path = '/' . $path;
    }

    $options['path'] = [
      'category' => 'page',
      'title' => $this->t('Path'),
      'value' => views_ui_truncate($path, 50),
    ];

  }

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

    switch ($form_state->get('section')) {
      case 'path':
        $url = Url::fromRoute('<none>', [], ['absolute' => TRUE]);
        $form['#title'] .= $this->t('The menu path or URL of this view');
        $form['path'] = [
          '#type' => 'textfield',
          '#title' => $this->t('Path'),
          '#description' => $this->t('This view will be displayed by visiting this path on your site. You may use "%" in your URL to represent values that will be used for contextual filters: For example, "node/%/feed". If needed you can even specify named route parameters like taxonomy/term/%taxonomy_term'),
          '#default_value' => $this->getOption('path'),
          '#field_prefix' => '<span dir="ltr">' . $url->toString(),
          '#field_suffix' => '</span>&lrm;',
          '#attributes' => ['dir' => LanguageInterface::DIRECTION_LTR],
          // Account for the leading backslash.
          '#maxlength' => 254,
        ];
        break;
    }
  }

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

    if ($form_state->get('section') == 'path') {
      $errors = $this->validatePath($form_state->getValue('path'));
      foreach ($errors as $error) {
        $form_state->setError($form['path'], $error);
      }

      // Automatically remove '/' and trailing whitespace from path.
      $form_state->setValue('path', trim($form_state->getValue('path'), '/ '));
    }
  }

  /**
   * Validates the path of the display.
   *
   * @param string $path
   *   The path to validate.
   *
   * @return array
   *   A list of error strings.
   */
  protected function validatePath($path) {
    $errors = [];
    if (strpos($path, '%') === 0) {
      $errors[] = $this->t('"%" may not be used for the first segment of a path.');
    }

    $parsed_url = UrlHelper::parse($path);

    if (!empty($parsed_url['query'])) {
      $errors[] = $this->t('No query allowed.');
    }

    if (!parse_url('internal:/' . $path)) {
      $errors[] = $this->t('Invalid path. Valid characters are alphanumerics as well as "-", ".", "_" and "~".');
    }

    $path_sections = explode('/', $path);
    // Symfony routing does not allow to use numeric placeholders.
    // @see \Symfony\Component\Routing\RouteCompiler
    $numeric_placeholders = array_filter($path_sections, function ($section) {
      return (preg_match('/^%(.*)/', $section, $matches)
        && is_numeric($matches[1]));
    });
    if (!empty($numeric_placeholders)) {
      $errors[] = $this->t("Numeric placeholders may not be used. Please use plain placeholders (%).");
    }
    return $errors;
  }

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

    if ($form_state->get('section') == 'path') {
      $this->setOption('path', $form_state->getValue('path'));
    }
  }

  /**
   * {@inheritdoc}
   */
  public function buildRenderable(array $args = [], $cache = TRUE) {
    $build = parent::buildRenderable($args, $cache);
    $build['#embed'] = TRUE;
    return $build;
  }

  /**
   * Block views use exposed widgets only if AJAX is set.
   */
  //  public function usesExposed() {
  //    return TRUE;
  //  }

  /**
   * {@inheritdoc}
   */
  public function getPath() {
    $path = $this->getOption('path');

    if (empty($path)) {
      $useAjax = $this->usesAJAX();

      if ($useAjax) {
        $request = $this->view->getRequest();
        $params = $request->request->all();

        // @TODO Read POST parameters from request object.
        if (!empty($params['ajax_page_state']) &&
          !empty($_POST['view_base_path'])) {
          $path = $_POST['view_base_path'];
        }
      }
    }

    if (empty($path)) {
      $current_path = $this->currentPath->getPath();
      $path = $this->aliasManager->getAliasByPath($current_path);
    }

    $bits = explode('/', $path);

    if (empty($bits[0])) {
      unset($bits[0]);
    }

    return implode('/', $bits);
  }

  /**
   * {@inheritdoc}
   */
  public function usesExposedFormInBlock() {
    return TRUE;
  }

  /**
   * {@inheritdoc}
   */
  protected function defineOptions() {
    $options = parent::defineOptions();
    $options['path'] = ['default' => ''];

    return $options;
  }

  /**
   * {@inheritdoc}
   */
  public function execute() {
    // Prior to this being called, the $view should already be set to this
    // display, and arguments should be set on the view.
    $this->view->build();

    if (!empty($this->view->build_info['fail'])) {
      throw new NotFoundHttpException();
    }

    if (!empty($this->view->build_info['denied'])) {
      throw new AccessDeniedHttpException();
    }

    // And now render the view.
    $render = $this->view->render();

    return $render;
  }

  /**
   * Returns plugin-specific settings for the block.
   *
   * @param array $settings
   *   The settings of the block.
   *
   * @return array
   *   An array of block-specific settings to override the defaults provided in
   *   \Drupal\views\Plugin\Block\ViewsBlock::defaultConfiguration().
   *
   * @see \Drupal\views\Plugin\Block\ViewsBlock::defaultConfiguration()
   */
  public function blockSettings(array $settings) {
    $settings['items_per_page'] = 'none';
    return $settings;
  }

  /**
   * Adds the configuration form elements specific to this views block plugin.
   *
   * This method allows block instances to override the views items_per_page.
   *
   * @param \Drupal\views\Plugin\Block\ViewsBlock $block
   *   The ViewsBlock plugin.
   * @param array $form
   *   The form definition array for the block configuration form.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The current state of the form.
   *
   * @return array
   *   The renderable form array representing the entire configuration form.
   *
   * @see \Drupal\views\Plugin\Block\ViewsBlock::blockForm()
   */
  public function blockForm(ViewsBlock $block, array &$form, FormStateInterface $form_state) {

    if (!empty ($this->getOption('allow'))) {
      $allow_settings = array_filter($this->getOption('allow'));

      $block_configuration = $block->getConfiguration();

      foreach ($allow_settings as $type => $enabled) {
        if (empty($enabled)) {
          continue;
        }
        switch ($type) {
          case 'items_per_page':
            $form['override']['items_per_page'] = [
              '#type' => 'select',
              '#title' => $this->t('Items per block'),
              '#options' => [
                'none' => $this->t('@count (default setting)', ['@count' => $this->getPlugin('pager')->getItemsPerPage()]),
                5 => 5,
                10 => 10,
                20 => 20,
                40 => 40,
              ],
              '#default_value' => $block_configuration['items_per_page'],
            ];
            break;
        }
      }
    }


    return $form;
  }

  /**
   * Handles form validation for the views block configuration form.
   *
   * @param \Drupal\views\Plugin\Block\ViewsBlock $block
   *   The ViewsBlock plugin.
   * @param array $form
   *   The form definition array for the block configuration form.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The current state of the form.
   *
   * @see \Drupal\views\Plugin\Block\ViewsBlock::blockValidate()
   */
  public function blockValidate(ViewsBlock $block, array $form, FormStateInterface $form_state) {
  }

  /**
   * Handles form submission for the views block configuration form.
   *
   * @param \Drupal\views\Plugin\Block\ViewsBlock $block
   *   The ViewsBlock plugin.
   * @param array $form
   *   The form definition array for the full block configuration form.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The current state of the form.
   *
   * @see \Drupal\views\Plugin\Block\ViewsBlock::blockSubmit()
   */
  public function blockSubmit(ViewsBlock $block, $form, FormStateInterface $form_state) {
    if ($items_per_page = $form_state->getValue(['override', 'items_per_page'])) {
      $block->setConfigurationValue('items_per_page', $items_per_page);
    }
    $form_state->unsetValue(['override', 'items_per_page']);
  }

  /**
   * Allows to change the display settings right before executing the block.
   *
   * @param \Drupal\views\Plugin\Block\ViewsBlock $block
   *   The block plugin for views displays.
   */
  public function preBlockBuild(ViewsBlock $block) {
    $config = $block->getConfiguration();
    if ($config['items_per_page'] !== 'none') {
      $this->view->setItemsPerPage($config['items_per_page']);
    }
  }

}

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

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