-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #196 from openeuropa/EWPP-3658
EWPP-3658: Link list display plugin integration.
- Loading branch information
Showing
11 changed files
with
903 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
# OE List Pages Link List Displays | ||
|
||
This module furthers the integration with the `OE Link Lists` component by | ||
taking over the rendering of the list pages and using the | ||
`Display` plugins made available for link lists. | ||
|
||
## How to use | ||
|
||
Install the module and it will directly start working. | ||
|
||
When you create a list page, you will have a mandatory `Display` select where | ||
you will need to pick one of the available link list display plugins. | ||
|
||
List pages created before the module was installed will continue to render using | ||
the default view mode. | ||
|
||
## How it works | ||
|
||
The module acts in two places. | ||
|
||
First, it alters the `ListPage` entity meta configuration form to present the user | ||
with the option to pick and configure the Display plugin to use. | ||
This choice is then stored in the `extra` configuration key of the list page. | ||
|
||
Second, the module takes over the `ListBuilder` object responsible for rendering | ||
the list and uses the chosen Display plugin to actually build the list. |
8 changes: 8 additions & 0 deletions
8
modules/oe_list_pages_link_list_displays/oe_list_pages_link_list_displays.info.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
name: List page displays from link lists | ||
description: Exposes the link list displays on list pages | ||
type: module | ||
core_version_requirement: ^9.4 || ^10 | ||
|
||
dependencies: | ||
- oe_list_pages:oe_list_pages | ||
- oe_link_lists:oe_link_lists |
28 changes: 28 additions & 0 deletions
28
modules/oe_list_pages_link_list_displays/oe_list_pages_link_list_displays.module
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
<?php | ||
|
||
/** | ||
* @file | ||
* The OpenEuropa List Pages Link List Displays module. | ||
*/ | ||
|
||
declare(strict_types = 1); | ||
|
||
use Drupal\Core\Form\FormStateInterface; | ||
|
||
/** | ||
* Implements hook_list_page_entity_meta_form_alter(). | ||
*/ | ||
function oe_list_pages_link_list_displays_list_page_entity_meta_form_alter(array &$form, FormStateInterface $form_state) { | ||
$entity_meta_bundle = $form_state->get('entity_meta_bundle'); | ||
/** @var \Drupal\emr\Entity\EntityMetaInterface $entity_meta */ | ||
$entity_meta = $form_state->get($entity_meta_bundle . '_entity_meta'); | ||
\Drupal::service('oe_list_pages_link_list_displays.list_display_selection_builder')->form($form, $form_state, $entity_meta); | ||
} | ||
|
||
/** | ||
* Implements hook_list_page_entity_meta_form_submit_alter(). | ||
*/ | ||
function oe_list_pages_link_list_displays_list_page_entity_meta_form_submit_alter(array &$form, FormStateInterface $form_state, array &$configuration) { | ||
$display_configuration = \Drupal::service('oe_list_pages_link_list_displays.list_display_selection_builder')->extractPluginConfiguration('display', $form, $form_state); | ||
$configuration['extra']['oe_list_pages_link_list_displays']['display'] = $display_configuration; | ||
} |
4 changes: 4 additions & 0 deletions
4
modules/oe_list_pages_link_list_displays/oe_list_pages_link_list_displays.services.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
services: | ||
oe_list_pages_link_list_displays.list_display_selection_builder: | ||
class: Drupal\oe_list_pages_link_list_displays\ListDisplaySelectionBuilder | ||
arguments: ['@plugin.manager.oe_link_lists.link_display'] |
175 changes: 175 additions & 0 deletions
175
modules/oe_list_pages_link_list_displays/src/ListBuilder.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,175 @@ | ||
<?php | ||
|
||
declare(strict_types = 1); | ||
|
||
namespace Drupal\oe_list_pages_link_list_displays; | ||
|
||
use Drupal\Core\Cache\CacheableMetadata; | ||
use Drupal\Core\Entity\EntityRepositoryInterface; | ||
use Drupal\Core\Entity\EntityTypeManager; | ||
use Drupal\Core\Form\FormBuilderInterface; | ||
use Drupal\Core\Pager\PagerManagerInterface; | ||
use Drupal\facets\Processor\ProcessorPluginManager; | ||
use Drupal\facets\UrlProcessor\UrlProcessorPluginManager; | ||
use Drupal\facets\Utility\FacetsUrlGenerator; | ||
use Drupal\oe_link_lists\Event\EntityValueResolverEvent; | ||
use Drupal\oe_link_lists\LinkCollection; | ||
use Drupal\oe_link_lists\LinkDisplayPluginManagerInterface; | ||
use Drupal\oe_list_pages\ListBuilder as DefaultListBuilder; | ||
use Drupal\oe_list_pages\ListExecutionManagerInterface; | ||
use Drupal\oe_list_pages\ListPageConfiguration; | ||
use Drupal\oe_list_pages\ListSourceFactory; | ||
use Drupal\oe_list_pages\MultiselectFilterFieldPluginManager; | ||
use Symfony\Component\HttpFoundation\RequestStack; | ||
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; | ||
|
||
/** | ||
* Link List display-based list builder. | ||
* | ||
* We take over the original list builder and use the chosen display plugins | ||
* to render the list. | ||
*/ | ||
class ListBuilder extends DefaultListBuilder { | ||
|
||
/** | ||
* The event dispatcher. | ||
* | ||
* @var \Symfony\Contracts\EventDispatcher\EventDispatcherInterface | ||
*/ | ||
protected $eventDispatcher; | ||
|
||
/** | ||
* The link display manager. | ||
* | ||
* @var \Drupal\oe_link_lists\LinkDisplayPluginManagerInterface | ||
*/ | ||
protected $linkDisplayPluginManager; | ||
|
||
/** | ||
* {@inheritdoc} | ||
* | ||
* @SuppressWarnings(PHPMD.ExcessiveParameterList) | ||
*/ | ||
public function __construct(ListExecutionManagerInterface $listExecutionManager, EntityTypeManager $entityTypeManager, PagerManagerInterface $pager, EntityRepositoryInterface $entityRepository, FormBuilderInterface $formBuilder, FacetsUrlGenerator $facetsUrlGenerator, ProcessorPluginManager $processorManager, RequestStack $requestStack, UrlProcessorPluginManager $urlProcessorManager, MultiselectFilterFieldPluginManager $multiselectFilterManager, ListSourceFactory $listSourceFactory, EventDispatcherInterface $eventDispatcher, LinkDisplayPluginManagerInterface $linkDisplayPluginManager) { | ||
parent::__construct($listExecutionManager, $entityTypeManager, $pager, $entityRepository, $formBuilder, $facetsUrlGenerator, $processorManager, $requestStack, $urlProcessorManager, $multiselectFilterManager, $listSourceFactory); | ||
$this->eventDispatcher = $eventDispatcher; | ||
$this->linkDisplayPluginManager = $linkDisplayPluginManager; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
* | ||
* @SuppressWarnings(PHPMD.CyclomaticComplexity) | ||
* @SuppressWarnings(PHPMD.NPathComplexity) | ||
*/ | ||
public function buildList(ListPageConfiguration $configuration): array { | ||
$extra = $configuration->getExtra(); | ||
if (!isset($extra['oe_list_pages_link_list_displays'])) { | ||
// If we don't have the displays configured, we simply defer back to the | ||
// parent like nothing happened. | ||
return parent::buildList($configuration); | ||
} | ||
|
||
// Verify that the chosen display plugin exists. | ||
$display_configuration = $extra['oe_list_pages_link_list_displays']; | ||
$display_plugin = $display_configuration['display']['plugin']; | ||
$display_plugin_configuration = $display_configuration['display']['plugin_configuration'] ?? []; | ||
if (!$this->linkDisplayPluginManager->hasDefinition($display_plugin)) { | ||
return parent::buildList($configuration); | ||
} | ||
|
||
$build = [ | ||
'list' => [], | ||
]; | ||
|
||
$cache = new CacheableMetadata(); | ||
$cache->addCacheContexts(['url.query_args']); | ||
|
||
$sort = $this->getSortFromUrl($configuration); | ||
// The sort could potentially be overridden from the URL. | ||
if ($sort) { | ||
$configuration->setSort($sort); | ||
} | ||
|
||
$list_execution = $this->listExecutionManager->executeList($configuration); | ||
if (empty($list_execution)) { | ||
$cache->applyTo($build); | ||
return $build; | ||
} | ||
|
||
$list_source = $list_execution->getListSource(); | ||
if (!$list_source) { | ||
$cache->applyTo($build); | ||
return $build; | ||
} | ||
|
||
$query = $list_execution->getQuery(); | ||
$cache->addCacheableDependency($query); | ||
$cache->addCacheTags($query->getCacheTags()); | ||
$result = $list_execution->getResults(); | ||
$configuration = $list_execution->getConfiguration(); | ||
$cache->addCacheTags([$configuration->getEntityType() . '_list:' . $configuration->getBundle()]); | ||
|
||
$this->pager->createPager($result->getResultCount(), $query->getOption('limit')); | ||
$build['pager'] = [ | ||
'#type' => 'pager', | ||
]; | ||
|
||
if (!$result->getResultCount()) { | ||
$cache->applyTo($build); | ||
return $build; | ||
} | ||
|
||
$links = new LinkCollection(); | ||
foreach ($result->getResultItems() as $item) { | ||
try { | ||
// Do not crash the application in case the index still has an item in | ||
// it pointing to an entity that got deleted. | ||
$entity = $item->getOriginalObject()->getEntity(); | ||
} | ||
catch (\Exception $exception) { | ||
continue; | ||
} | ||
|
||
/** @var \Drupal\Core\Entity\ContentEntityInterface $entity */ | ||
$entity = $this->entityRepository->getTranslationFromContext($entity); | ||
|
||
// Turn the entity into a LinkInterface. | ||
/** @var \Drupal\Core\Entity\ContentEntityInterface $entity */ | ||
$event = new EntityValueResolverEvent($entity); | ||
$this->eventDispatcher->dispatch($event, EntityValueResolverEvent::NAME); | ||
$cache->addCacheableDependency($entity); | ||
$links->add($event->getLink()); | ||
} | ||
|
||
$links->addCacheableDependency($cache); | ||
|
||
// Check each link for access before rendering. | ||
foreach ($links as $key => $link) { | ||
/** @var \Drupal\oe_link_lists\LinkInterface $link */ | ||
$access = $link->access('view', NULL, TRUE); | ||
$cache->addCacheableDependency($access); | ||
|
||
if (!$access->isAllowed()) { | ||
unset($links[$key]); | ||
} | ||
} | ||
|
||
if ($links->isEmpty()) { | ||
$build = []; | ||
$cache->addCacheableDependency($links); | ||
$cache->applyTo($build); | ||
return $build; | ||
} | ||
|
||
// Prepare the links for rendering with the chosen display plugin. | ||
/** @var \Drupal\oe_link_lists\LinkDisplayInterface $plugin */ | ||
$plugin = $this->linkDisplayPluginManager->createInstance($display_plugin, $display_plugin_configuration); | ||
$build['list'] = $plugin->build($links); | ||
$cache->addCacheableDependency($links); | ||
$cache->applyTo($build); | ||
|
||
return $build; | ||
} | ||
|
||
} |
Oops, something went wrong.