book_blocks-8.x-1.4/src/Plugin/Block/BookBlocksEditBlock.php

src/Plugin/Block/BookBlocksEditBlock.php
<?php

namespace Drupal\book_blocks\Plugin\Block;

use Drupal\Core\Block\BlockBase;
use Drupal\book\BookManager;
use Drupal\book\BookManagerInterface;
use Drupal\Core\Cache\Cache;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\RequestStack;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Url;

/**
 * Provides another 'Book navigation' block.
 *
 * @Block(
 *   id = "book_block_edit",
 *   admin_label = @Translation("Book Edit Links"),
 *   category = @Translation("Menus")
 * )
 */
class BookBlocksEditBlock extends BookBlocksBlockBase implements ContainerFactoryPluginInterface {

  /**
   * Constructs a new instance.
   *
   * @param array $configuration
   *   A configuration array containing information about the plugin instance.
   * @param string $plugin_id
   *   The plugin_id for the plugin instance.
   * @param mixed $plugin_definition
   *   The plugin implementation definition.
   * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
   *   The request stack object.
   * @param \Drupal\book\BookManagerInterface $book_manager
   *   The book manager.
   * @param \Drupal\Core\Entity\EntityStorageInterface $node_storage
   *   The node storage.
   */
  public function __construct(array $configuration, $plugin_id, $plugin_definition, RequestStack $request_stack, BookManagerInterface $book_manager, EntityStorageInterface $node_storage) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);

    $this->requestStack = $request_stack;
    $this->bookManager = $book_manager;
    $this->nodeStorage = $node_storage;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static(
      $configuration,
      $plugin_id,
      $plugin_definition,
      $container->get('request_stack'),
      $container->get('book.manager'),
      $container->get('entity_type.manager')->getStorage('node')
    );
  }

  /**
   * {@inheritdoc}
   */
  public function defaultConfiguration() {
    $config = \Drupal::config('book_blocks.settings');
    return $config->get('block.settings.book_block_edit');
  }

  /**
   * {@inheritdoc}
   */
  public function blockForm($form, FormStateInterface $form_state) {
    $form[] = [
      '#markup' =>
      '<h2>' . $this->t('Book Blocks: Edit Block Configuration') . '</h2>' .
      '<p>' . $this->t('In general, the title (above) should not be displayed.') . '</p>' ,
    ];
    $form['css'] = [
      '#type' => 'select',
      '#title' => $this->t('Display style'),
      '#options' => [
        'book-blocks-edit-text'    => t('Text'),
        'book-blocks-edit-rounded' => t('Rounded'),
        'book-blocks-edit-button'  => t('Button'),
        'book-blocks-edit-custom'  => t('Custom'),
      ],
      '#default_value' => $this->configuration['css'],
      '#description' => $this->t('Custom includes CSS class book-blocks-edit-custom.'),
    ];
    $form['icons'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Use icons'),
      '#default_value' => $this->configuration['icons'],
      '#description' => $this->t("Use icons instead of text."),
    ];
    $form['toc'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Table of Contents'),
      '#default_value' => $this->configuration['toc'],
      '#description' => $this->t("Include table of contents link."),
    ];
    $form['nav'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Navigation links'),
      '#default_value' => $this->configuration['nav'],
      '#description' => $this->t("Include prior/up/next navigation links."),
    ];
    $form['add_sibling'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Add sibling link text'),
      '#default_value' => $this->configuration['add_sibling'],
      '#description' => $this->t("Leave empty to no including the Add sibling link."),
    ];
    $form['replace'] = [
      '#type' => 'details',
      '#open' => FALSE,
      '#title' => $this->t('Replacement Patterns'),
    ];
    $form['replace'][] = [
      '#markup' => '<h3>' . $this->t('These patterns can be used in the link fields') . '</h3>' . '
        <ul>
          <li>{{ nid }} - ' . $this->t('Curren node ID') . '
          <li>{{ book_id }} - ' . $this->t('Book node ID') . '
          <li>{{ prev_id }} - ' . $this->t('Previous node ID') . '
          <li>{{ next_id }} - ' . $this->t('Next node ID') . '
          <li>{{ parent_id }} - ' . $this->t('Parent node ID') . '
        </ul>
        ',
    ];
    $form['left_link'] = [
      '#type' => 'details',
      '#open' => TRUE,
      '#title' => $this->t('Left link'),
    ];
    $form['left_link']['left_name'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Link text'),
      '#default_value' => $this->configuration['left_link']['name'],
      '#description' => $this->t("Leave empty to not include a link."),
    ];
    $form['left_link']['left_url'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Link URL'),
      '#default_value' => $this->configuration['left_link']['url'],
      '#description' => $this->t("URL for this link. No link if this is empty."),
    ];
    $form['left_link']['left_hint'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Link hint text'),
      '#default_value' => $this->configuration['left_link']['hint'],
      '#description' => $this->t("Hint for link."),
    ];
    $form['middle_link'] = [
      '#type' => 'details',
      '#open' => TRUE,
      '#title' => $this->t('Middle link'),
    ];
    $form['middle_link']['middle_name'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Link text'),
      '#default_value' => $this->configuration['middle_link']['name'],
      '#description' => $this->t("Leave empty to not include a link."),
    ];
    $form['middle_link']['middle_url'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Link URL'),
      '#default_value' => $this->configuration['middle_link']['url'],
      '#description' => $this->t("URL for this link. No link if this is empty."),
    ];
    $form['middle_link']['middle_hint'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Link hint text'),
      '#default_value' => $this->configuration['middle_link']['hint'],
      '#description' => $this->t("Hint for link."),
    ];
    $form['right_link'] = [
      '#type' => 'details',
      '#open' => TRUE,
      '#title' => $this->t('Right link'),
    ];
    $form['right_link']['right_name'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Link text'),
      '#default_value' => $this->configuration['right_link']['name'],
      '#description' => $this->t("Leave empty to not include a link."),
    ];
    $form['right_link']['right_url'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Link URL'),
      '#default_value' => $this->configuration['right_link']['url'],
      '#description' => $this->t("URL for this link. No link if this is empty."),
    ];
    $form['right_link']['right_hint'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Link hint text'),
      '#default_value' => $this->configuration['right_link']['hint'],
      '#description' => $this->t("Hint for link."),
    ];

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function blockSubmit($form, FormStateInterface $form_state) {
    $this->configuration['add_sibling'] = $form_state->getValue('add_sibling');
    $this->configuration['toc'] = $form_state->getValue('toc');
    $this->configuration['nav'] = $form_state->getValue('nav');

    $this->configuration['css'] = $form_state->getValue('css');
    $this->configuration['icons'] = $form_state->getValue('icons');

    $left_link                                = $form_state->getValue('left_link');
    $this->configuration['left_link']['name'] = $left_link['left_name'];
    $this->configuration['left_link']['url']  = $left_link['left_url'];
    $this->configuration['left_link']['hint'] = $left_link['left_hint'];

    $middle_link                                = $form_state->getValue('middle_link');
    $this->configuration['middle_link']['name'] = $middle_link['middle_name'];
    $this->configuration['middle_link']['url']  = $middle_link['middle_url'];
    $this->configuration['middle_link']['hint'] = $middle_link['middle_hint'];

    $right_link = $form_state->getValue('right_link');
    $this->configuration['right_link']['name'] = $right_link['right_name'];
    $this->configuration['right_link']['url']  = $right_link['right_url'];
    $this->configuration['right_link']['hint'] = $right_link['right_hint'];
  }

  /**
   * {@inheritdoc}
   */
  public function build() {
    if (($node = $this->requestStack->getCurrentRequest()->get('node')) && !empty($node->book['bid'])) {
      $book_manager = \Drupal::service('book.manager');
      $book_link = $book_manager->loadBookLink($node->id());
      $book_id = $node->book['bid'];
      $book_node = $this->node_load($book_id);

      // Only display this block when the user is browsing a book and do
      // not show unpublished books.
      $book_id = $node->book['bid'];
      $book_node = $this->node_load($book_id);

      // Provide extra variables for themers. Not needed by default.
      $variables['#book_id'] = $book_id;
      $variables['#book_title'] = $book_node->getTitle();
      $variables['#book_url'] = $this->node_url($book_id);
      $variables['#current_depth'] = $node->book['depth'];
      $variables['#tree'] = '';

      /** @var \Drupal\book\BookOutline $book_outline */
      $book_outline = \Drupal::service('book.outline');

      // Loads css.
      $build = [];

      $book_manager = \Drupal::service('book.manager');
      $book_link = $book_manager->loadBookLink($node->id());
      $variables['#book_link'] = $book_link;

      if ($book_id) {
        $variables['#tree'] = $book_outline->childrenLinks($book_link);

        if ($prev = $book_outline->prevLink($book_link)) {
          $token['prev_id'] = $prev['nid'];
          $prev_href = $this->node_url($prev['nid']);
          $build['#attached']['html_head_link'][][] = [

            'rel' => 'prev',
            'href' => $prev_href,
          ];
          $variables['#prev_url'] = $prev_href;
          $variables['#prev_title'] = $prev['title'];
        }

        /** @var \Drupal\book\BookManagerInterface $book_manager */
        if ($book_link['pid'] && $parent = $book_manager->loadBookLink($book_link['pid'])) {
          $token['parent_id'] = $book_link['pid'];
          $parent_href = $this->node_url($book_link['pid']);
          $build['#attached']['html_head_link'][][] = [
            'rel' => 'up',
            'href' => $parent_href,
          ];
          $variables['#parent_url'] = $parent_href;
          $variables['#parent_title'] = $parent['title'];
        }

        if ($next = $book_outline->nextLink($book_link)) {
          $token['right_id'] = $next['nid'];
          $next_href = $this->node_url($next['nid']);
          $build['#attached']['html_head_link'][][] = [
            'rel' => 'next',
            'href' => $next_href,
          ];
          $variables['#next_url'] = $next_href;
          $variables['#next_title'] = $next['title'];
        }

        $variables['#has_links'] = FALSE;
        // Link variables to filter for values and set state of the flag variable.
        $links = ['#prev_url', '#prev_title', '#parent_url', '#parent_title', '#next_url', '#next_title'];
        foreach ($links as $link) {
          if (isset($variables[$link])) {
            // Flag when there is a value.
            $variables['#has_links'] = TRUE;
          }
          else {
            // Set empty to prevent notices.
            $variables[$link] = '';
          }
        }

        if (!empty($build)) {
          \Drupal::service('renderer')->render($build);
        }

        $variables['#theme'] = 'book_blocks_edit';
        $variables['#attached']['library'][] = 'book_blocks/global-styling';
        $variables['#attributes'] = ['class' => ['book-blocks-edit']];

        $variables['#css'] = $this->configuration['css'];
        $variables['#icons'] = $this->configuration['icons'];
        $variables['#toc'] = $this->configuration['toc'];
        $variables['#nav'] = $this->configuration['nav'];

        // Create token replacement table.
        $token['nid'] = $node->id();
        $token['book_id'] = $book_id;

        foreach ($token as $key => $value) {
          $pattern[] = "/\{\{ $key \}\}/";
          $replace[] = $value;
        }

        // Get custom links.
        foreach (['left_link', 'middle_link', 'right_link'] as $link) {
          $name = preg_replace($pattern, $replace, $this->configuration[$link]['name']);
          $url = preg_replace($pattern, $replace, $this->configuration[$link]['url']);
          if ($name && $url) {
            $variables["#$link"] = preg_replace($pattern, $replace, $this->configuration[$link]);
          }
        }

        // Get standard links.
        $account = \Drupal::currentUser();

        if (isset($node->book['depth'])) {
          if (/* need to get view mode somehow ======= $variables['view_mode'] == 'full' && */ node_is_page($node)) {
            $child_type = \Drupal::config('book.settings')->get('child_type');
            $access_control_handler = \Drupal::entityTypeManager()->getAccessControlHandler('node');
            if (($account->hasPermission('add content to books') || $account->hasPermission('administer book outlines')) && $access_control_handler->createAccess($child_type) && $node->isPublished() && $node->book['depth'] < BookManager::BOOK_MAX_DEPTH) {
              $variables['#child_link']['name'] = t('Add child page');
              $variables['#child_link']['hint'] = t('Add a new book page below this one');
              $variables['#child_link']['url'] =
                Url::fromRoute('node.add',
                               ['node_type' => $child_type],
                               ['query' => ['parent' => $node->id()]])->toString();

              if ($book_link['pid']) {
                $variables['#sibling_link']['name'] = t('Add sibling page');
                $variables['#sibling_link']['hint'] = t('Add a new book page at the same level as this');
                $variables['#sibling_link']['url'] =
                  Url::fromRoute('node.add',
                                 ['node_type' => $child_type],
                                 ['query' => ['parent' => $book_link['pid']]])->toString();
              }
            }
          }

          if ($account->hasPermission('access printer-friendly version')) {
            $variables['#print_link']['name'] = t('Printer-friendly version');
            $variables['#print_link']['hint'] = t('Show a printer-friendly version of this book page and its sub-pages.');
            $variables['#print_link']['url'] = Url::fromRoute('book.export', [
              'type' => 'html',
              'node' => $node->id(),
            ])->toString();
          }
        }

        if ($this->configuration['toc']) {
          // There should only be one element at the top level.
          $data = $this->bookManager->bookTreeAllData($node->book['bid'], $node->book);
          $data = reset($data);
          $below = $this->bookManager->bookTreeOutput($data['below']);
          $this->addClassForCurrentNode($below['#items'], $node->id());
          $book_node = $this->node_load($book_id);
          $title = $book_node->getTitle();
          $url = $this->node_url($book_id);
          $title_class = $node->id() == $book_id ? 'book--active-trail' : '';
          // Generate unique $element_id in case there are multiple instances
          $element_id = 'book-blocks-toc-element-' . random_int(1,999999);
          $variables['#my_element_id'] = $element_id;

          if (!empty($below)) {
            return [
              $variables,
              [
                '#type' => 'container',
                '#attributes' => ['id' => [$element_id], 'class' => ['books-blocks-edit-toc book-blocks-toc'], 'style' => ['visibility:hidden;']],
                [
                  '#markup' => "<div class='book-blocks-toc-book $title_class'><span class='book-blocks-toc-prefix'>" .
                  "</span><a href='$url'>$title</a></div>",
                  $below,
                ],
              ],
            ];
          }
        }

        return $variables;
      }
    }
    return [];
  }

  /**
   * {@inheritdoc}
   */
  public function getCacheContexts() {
    return Cache::mergeContexts(parent::getCacheContexts(), ['route.book_block_toc']);
  }

  /**
   * {@inheritdoc}
   *
   * @todo Make cacheable in https://www.drupal.org/node/2483181
   */
  public function getCacheMaxAge() {
    return 0;
  }

}

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

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