"Fossies" - the Fresh Open Source Software Archive

Member "drupal-8.9.10/core/modules/views/src/Plugin/views/area/DisplayLink.php" (26 Nov 2020, 8112 Bytes) of package /linux/www/drupal-8.9.10.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) PHP source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "DisplayLink.php" see the Fossies "Dox" file reference documentation.

    1 <?php
    2 
    3 namespace Drupal\views\Plugin\views\area;
    4 
    5 use Drupal\Core\EventSubscriber\AjaxResponseSubscriber;
    6 use Drupal\Core\EventSubscriber\MainContentViewSubscriber;
    7 use Drupal\Core\Form\FormBuilderInterface;
    8 use Drupal\Core\Form\FormStateInterface;
    9 use Drupal\views\Plugin\views\display\PathPluginBase;
   10 
   11 /**
   12  * Views area display_link handler.
   13  *
   14  * @ingroup views_area_handlers
   15  *
   16  * @ViewsArea("display_link")
   17  */
   18 class DisplayLink extends AreaPluginBase {
   19 
   20   /**
   21    * {@inheritdoc}
   22    */
   23   protected function defineOptions() {
   24     $options = parent::defineOptions();
   25     $options['display_id'] = ['default' => NULL];
   26     $options['label'] = ['default' => NULL];
   27     return $options;
   28   }
   29 
   30   /**
   31    * {@inheritdoc}
   32    */
   33   public function buildOptionsForm(&$form, FormStateInterface $form_state) {
   34     parent::buildOptionsForm($form, $form_state);
   35 
   36     $allowed_displays = [];
   37     $displays = $this->view->storage->get('display');
   38     foreach ($displays as $display_id => $display) {
   39       if (!$this->isPathBasedDisplay($display_id)) {
   40         unset($displays[$display_id]);
   41         continue;
   42       }
   43       $allowed_displays[$display_id] = $display['display_title'];
   44     }
   45 
   46     $form['description'] = [
   47       [
   48         '#markup' => $this->t('To make sure the results are the same when switching to the other display, it is recommended to make sure the display:'),
   49       ],
   50       [
   51         '#theme' => 'item_list',
   52         '#items' => [
   53           $this->t('Has a path.'),
   54           $this->t('Has the same filter criteria.'),
   55           $this->t('Has the same sort criteria.'),
   56           $this->t('Has the same pager settings.'),
   57           $this->t('Has the same contextual filters.'),
   58         ],
   59       ],
   60     ];
   61 
   62     if (!$allowed_displays) {
   63       $form['empty_message'] = [
   64         '#markup' => '<p><em>' . $this->t('There are no path-based displays available.') . '</em></p>',
   65       ];
   66     }
   67     else {
   68       $form['display_id'] = [
   69         '#title' => $this->t('Display'),
   70         '#type' => 'select',
   71         '#options' => $allowed_displays,
   72         '#default_value' => $this->options['display_id'],
   73         '#required' => TRUE,
   74       ];
   75       $form['label'] = [
   76         '#title' => $this->t('Label'),
   77         '#description' => $this->t('The text of the link.'),
   78         '#type' => 'textfield',
   79         '#default_value' => $this->options['label'],
   80         '#required' => TRUE,
   81       ];
   82     }
   83   }
   84 
   85   /**
   86    * {@inheritdoc}
   87    */
   88   public function validate() {
   89     $errors = parent::validate();
   90 
   91     // Do not add errors for the default display if it is not displayed in the
   92     // UI.
   93     if ($this->displayHandler->isDefaultDisplay() && !\Drupal::config('views.settings')->get('ui.show.master_display')) {
   94       return $errors;
   95     }
   96 
   97     // Ajax errors can cause the plugin to be added without any settings.
   98     $linked_display_id = !empty($this->options['display_id']) ? $this->options['display_id'] : NULL;
   99     if (!$linked_display_id) {
  100       $errors[] = $this->t('%current_display: The link in the %area area has no configured display.', [
  101         '%current_display' => $this->displayHandler->display['display_title'],
  102         '%area' => $this->areaType,
  103       ]);
  104       return $errors;
  105     }
  106 
  107     // Check if the linked display hasn't been removed.
  108     if (!$this->view->displayHandlers->get($linked_display_id)) {
  109       $errors[] = $this->t('%current_display: The link in the %area area points to the %linked_display display which no longer exists.', [
  110         '%current_display' => $this->displayHandler->display['display_title'],
  111         '%area' => $this->areaType,
  112         '%linked_display' => $this->options['display_id'],
  113       ]);
  114       return $errors;
  115     }
  116 
  117     // Check if the linked display is a path-based display.
  118     if (!$this->isPathBasedDisplay($linked_display_id)) {
  119       $errors[] = $this->t('%current_display: The link in the %area area points to the %linked_display display which does not have a path.', [
  120         '%current_display' => $this->displayHandler->display['display_title'],
  121         '%area' => $this->areaType,
  122         '%linked_display' => $this->view->displayHandlers->get($linked_display_id)->display['display_title'],
  123       ]);
  124       return $errors;
  125     }
  126 
  127     // Check if options of the linked display are equal to the options of the
  128     // current display. We "only" show a warning here, because even though we
  129     // recommend keeping the display options equal, we do not want to enforce
  130     // this.
  131     $unequal_options = [
  132       'filters' => t('Filter criteria'),
  133       'sorts' => t('Sort criteria'),
  134       'pager' => t('Pager'),
  135       'arguments' => t('Contextual filters'),
  136     ];
  137     foreach (array_keys($unequal_options) as $option) {
  138       if ($this->hasEqualOptions($linked_display_id, $option)) {
  139         unset($unequal_options[$option]);
  140       }
  141     }
  142 
  143     if ($unequal_options) {
  144       $warning = $this->t('%current_display: The link in the %area area points to the %linked_display display which uses different settings than the %current_display display for: %unequal_options. To make sure users see the exact same result when clicking the link, please check that the settings are the same.', [
  145         '%current_display' => $this->displayHandler->display['display_title'],
  146         '%area' => $this->areaType,
  147         '%linked_display' => $this->view->displayHandlers->get($linked_display_id)->display['display_title'],
  148         '%unequal_options' => implode(', ', $unequal_options),
  149       ]);
  150       $this->messenger()->addWarning($warning);
  151     }
  152     return $errors;
  153   }
  154 
  155   /**
  156    * {@inheritdoc}
  157    */
  158   public function render($empty = FALSE) {
  159     if (($empty && empty($this->options['empty'])) || empty($this->options['display_id'])) {
  160       return [];
  161     }
  162 
  163     if (!$this->isPathBasedDisplay($this->options['display_id'])) {
  164       return [];
  165     }
  166 
  167     // Get query parameters from the exposed input and pager.
  168     $query = $this->view->getExposedInput();
  169     if ($current_page = $this->view->getCurrentPage()) {
  170       $query['page'] = $current_page;
  171     }
  172 
  173     // @todo Remove this parsing once these are removed from the request in
  174     //   https://www.drupal.org/node/2504709.
  175     foreach ([
  176       'view_name',
  177       'view_display_id',
  178       'view_args',
  179       'view_path',
  180       'view_dom_id',
  181       'pager_element',
  182       'view_base_path',
  183       AjaxResponseSubscriber::AJAX_REQUEST_PARAMETER,
  184       FormBuilderInterface::AJAX_FORM_REQUEST,
  185       MainContentViewSubscriber::WRAPPER_FORMAT,
  186     ] as $key) {
  187       unset($query[$key]);
  188     }
  189 
  190     // Set default classes.
  191     $classes = [
  192       'views-display-link',
  193       'views-display-link-' . $this->options['display_id'],
  194     ];
  195     if ($this->options['display_id'] === $this->view->current_display) {
  196       $classes[] = 'is-active';
  197     }
  198 
  199     return [
  200       '#type' => 'link',
  201       '#title' => $this->options['label'],
  202       '#url' => $this->view->getUrl($this->view->args, $this->options['display_id'])->setOptions(['query' => $query]),
  203       '#options' => [
  204         'view' => $this->view,
  205         'target_display_id' => $this->options['display_id'],
  206         'attributes' => ['class' => $classes],
  207       ],
  208     ];
  209   }
  210 
  211   /**
  212    * Check if a views display is a path-based display.
  213    *
  214    * @param string $display_id
  215    *   The display ID to check.
  216    *
  217    * @return bool
  218    *   Whether the display ID is an allowed display or not.
  219    */
  220   protected function isPathBasedDisplay($display_id) {
  221     $loaded_display = $this->view->displayHandlers->get($display_id);
  222     return $loaded_display instanceof PathPluginBase;
  223   }
  224 
  225   /**
  226    * Check if the options of a views display are equal to the current display.
  227    *
  228    * @param string $display_id
  229    *   The display ID to check.
  230    * @param string $option
  231    *   The option to check.
  232    *
  233    * @return bool
  234    *   Whether the option of the view display are equal to the current display
  235    *   or not.
  236    */
  237   protected function hasEqualOptions($display_id, $option) {
  238     $loaded_display = $this->view->displayHandlers->get($display_id);
  239     return $loaded_display->getOption($option) === $this->displayHandler->getOption($option);
  240   }
  241 
  242 }