Skip to content

Commit

Permalink
Merge pull request #54 from openeuropa/EWPP-482
Browse files Browse the repository at this point in the history
EWPP-482: Support for link fields in the multiselect widget.
  • Loading branch information
upchuk authored Dec 2, 2020
2 parents c175ef2 + bd12d6d commit 9f9ea6b
Show file tree
Hide file tree
Showing 7 changed files with 222 additions and 1 deletion.
80 changes: 79 additions & 1 deletion src/Plugin/facets/widget/MultiselectWidget.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Drupal\oe_list_pages\Plugin\facets\widget;

use Drupal\Core\Entity\Element\EntityAutocomplete;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Field\EntityReferenceFieldItemListInterface;
Expand All @@ -13,6 +14,8 @@
use Drupal\facets\FacetInterface;
use Drupal\facets\Processor\ProcessorPluginManager;
use Drupal\facets\Result\Result;
use Drupal\link\LinkItemInterface;
use Drupal\link\Plugin\Field\FieldWidget\LinkWidget;
use Drupal\multivalue_form_element\Element\MultiValue;
use Drupal\oe_list_pages\ListPresetFilter;
use Drupal\oe_list_pages\ListSourceInterface;
Expand Down Expand Up @@ -80,6 +83,8 @@ public function __construct(array $configuration, $plugin_id, $plugin_definition
*
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
* @SuppressWarnings(PHPMD.NPathComplexity)
*
* @todo create a plugin type for supporting the various field types.
*/
public function buildDefaultValueForm(array $form, FormStateInterface $form_state, FacetInterface $facet, ListPresetFilter $preset_filter = NULL): array {
/** @var \Drupal\oe_list_pages\ListSourceInterface $list_source */
Expand Down Expand Up @@ -116,7 +121,6 @@ public function buildDefaultValueForm(array $form, FormStateInterface $form_stat
return $form;
}

// First, we cover entity references.
if (in_array(EntityReferenceFieldItemListInterface::class, class_implements($field_definition->getClass()))) {
$entity_storage = $this->entityTypeManager->getStorage($field_definition->getSetting('target_type'));
$default_value = [];
Expand Down Expand Up @@ -175,6 +179,30 @@ public function buildDefaultValueForm(array $form, FormStateInterface $form_stat
return $form;
}

if ($field_type === 'link') {
$link_type = $field_definition->getSetting('link_type');
$default_value = [];
foreach ($active_items as $active_item) {
$default_value[] = $this->getUriAsDisplayableString($active_item);
}
$form[$facet->id()]['#default_value'] = $default_value;
$form[$facet->id()]['link'] = [
'#type' => 'url',
'#element_validate' => [[LinkWidget::class, 'validateUriElement']],
'#maxlength' => 2048,
'#link_type' => $link_type,
];

if ($link_type & LinkItemInterface::LINK_INTERNAL) {
$form[$facet->id()]['link']['#type'] = 'entity_autocomplete';
$form[$facet->id()]['link']['#target_type'] = 'node';
$form[$facet->id()]['link']['#process_default_value'] = FALSE;
}

$form_state->set('multivalue_child', 'link');
return $form;
}

return $this->build($facet);
}

Expand Down Expand Up @@ -218,6 +246,15 @@ public function getDefaultValuesLabel(FacetInterface $facet, ListSourceInterface
return $filter_operators[$filter->getOperator()] . ': ' . parent::getDefaultValuesLabel($facet, $list_source, $filter);
}

if ($field_type === 'link') {
$values = [];
foreach ($filter_value as $value) {
$values[] = $this->getUriAsDisplayableString($value);
}

return $filter_operators[$filter->getOperator()] . ': ' . implode(', ', $values);
}

return $filter_operators[$filter->getOperator()] . ': ' . parent::getDefaultValuesLabel($facet, $list_source, $filter);
}

Expand Down Expand Up @@ -327,4 +364,45 @@ protected function facetHasDefaultStatus(FacetInterface $facet): bool {
return FALSE;
}

/**
* Gets the URI without the 'internal:' or 'entity:' scheme.
*
* @param string $uri
* The URI.
*
* @return string
* The URI.
*
* @see LinkWidget::getUriAsDisplayableString()
*/
protected function getUriAsDisplayableString(string $uri): string {
$scheme = parse_url($uri, PHP_URL_SCHEME);

// By default, the displayable string is the URI.
$displayable_string = $uri;

// A different displayable string may be chosen in case of the 'internal:'
// or 'entity:' built-in schemes.
if ($scheme === 'internal') {
$uri_reference = explode(':', $uri, 2)[1];
$path = parse_url($uri, PHP_URL_PATH);
if ($path === '/') {
$uri_reference = '<front>' . substr($uri_reference, 1);
}

$displayable_string = $uri_reference;
}
elseif ($scheme === 'entity') {
list($entity_type, $entity_id) = explode('/', substr($uri, 7), 2);
if ($entity_type == 'node' && $entity = $this->entityTypeManager->getStorage($entity_type)->load($entity_id)) {
$displayable_string = EntityAutocomplete::getEntityLabels([$entity]);
}
}
elseif ($scheme === 'route') {
$displayable_string = ltrim($displayable_string, 'route:');
}

return $displayable_string;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
langcode: en
status: true
dependencies: { }
id: link
name: Link
url_alias: link
weight: 0
min_count: 1
show_only_one_result: false
field_identifier: field_link
facet_source_id: 'list_facet_source:node:content_type_one'
widget:
type: oe_list_pages_multiselect
config:
show_numbers: false
query_operator: or
use_hierarchy: false
expand_hierarchy: false
enable_parent_when_child_gets_disabled: true
hard_limit: 0
exclude: false
only_visible_when_facet_source_is_visible: true
processor_configs:
active_widget_order:
processor_id: active_widget_order
weights:
sort: 20
settings:
sort: DESC
count_widget_order:
processor_id: count_widget_order
weights:
sort: 30
settings:
sort: DESC
display_value_widget_order:
processor_id: display_value_widget_order
weights:
sort: 40
settings:
sort: ASC
url_processor_handler:
processor_id: url_processor_handler
weights:
pre_query: 50
build: 15
settings: { }
empty_behavior:
behavior: none
show_title: false
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
langcode: en
status: true
dependencies:
config:
- field.storage.node.field_link
- node.type.content_type_one
module:
- link
id: node.content_type_one.field_link
field_name: field_link
entity_type: node
bundle: content_type_one
label: Link
description: ''
required: false
translatable: false
default_value: { }
default_value_callback: ''
settings:
link_type: 17
title: 0
field_type: link
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
langcode: en
status: true
dependencies:
module:
- link
- node
id: node.field_link
field_name: field_link
entity_type: node
type: link
settings: { }
module: link
locked: false
cardinality: 1
translatable: true
indexes: { }
persist_with_no_fields: false
custom_storage: false
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ dependencies:
config:
- field.storage.node.body
- field.storage.node.field_date_range
- field.storage.node.field_link
- field.storage.node.field_reference
- field.storage.node.field_select_one
- field.storage.node.field_select_two
Expand Down Expand Up @@ -40,6 +41,14 @@ field_settings:
dependencies:
config:
- field.storage.node.field_date_range
field_link:
label: Link
datasource_id: 'entity:node'
property_path: field_link
type: string
dependencies:
config:
- field.storage.node.field_link
field_reference:
label: Reference
datasource_id: 'entity:node'
Expand Down Expand Up @@ -103,6 +112,7 @@ processor_settings:
all_fields: true
fields:
- body
- field_link
- field_select_one
- field_select_two
- title
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ core: 8.x

dependencies:
- drupal:entity_reference
- drupal:link
- drupal:options
- drupal:datetime
- drupal:datetime_range
Expand Down
42 changes: 42 additions & 0 deletions tests/src/FunctionalJavascript/ListPagesPresetFiltersTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ public function testListPagePresetFilters(): void {
'field_select_one' => 'test1',
'field_reference' => [$yellow_node->id(), $green_node->id()],
'created' => $date->getTimestamp(),
'field_link' => 'http://banana.com',
];
$node = Node::create($values);
$node->save();
Expand All @@ -200,6 +201,7 @@ public function testListPagePresetFilters(): void {
'field_select_one' => 'test1',
'field_reference' => $yellow_node->id(),
'created' => $date->getTimestamp(),
'field_link' => 'http://sun.com',
];
$node = Node::create($values);
$node->save();
Expand All @@ -213,6 +215,8 @@ public function testListPagePresetFilters(): void {
'field_select_one' => 'test1',
'field_reference' => $green_node->id(),
'created' => $date->getTimestamp(),
// Sun title.
'field_link' => 'entity:node/' . $node->id(),
];
$node = Node::create($values);
$node->save();
Expand Down Expand Up @@ -240,6 +244,7 @@ public function testListPagePresetFilters(): void {
$created_filter_id = ListPresetFiltersBuilder::generateFilterId('created');
$published_filter_id = ListPresetFiltersBuilder::generateFilterId('list_facet_source_node_content_type_onestatus');
$reference_filter_id = ListPresetFiltersBuilder::generateFilterId('reference');
$link_filter_id = ListPresetFiltersBuilder::generateFilterId('link');

$admin = $this->createUser([], NULL, TRUE);
$this->drupalLogin($admin);
Expand Down Expand Up @@ -560,6 +565,43 @@ public function testListPagePresetFilters(): void {
$this->assertSession()->assertWaitOnAjaxRequest();
$assert = $this->assertSession();

// Add a Link filter.
$page->selectFieldOption('Add default value for', 'Link');
$this->assertSession()->assertWaitOnAjaxRequest();
$this->getSession()->getPage()->fillField('emr_plugins_oe_list_page[wrapper][default_filter_values][wrapper][edit][' . $link_filter_id . '][link][0][link]', 'http://banana.com');
$page->pressButton('Set default value');
$this->assertSession()->assertWaitOnAjaxRequest();
$expected_set_filters = [['key' => 'Link', 'value' => 'Any of: http://banana.com']];
$this->assertDefaultValueForFilters($expected_set_filters);
$page->pressButton('Save');
$node = $this->drupalGetNodeByTitle('List page for ct1');
$this->drupalGet($node->toUrl());
$this->assertSession()->pageTextNotContains('Cherry title');
$this->assertSession()->pageTextNotContains('Sun title');
$this->assertSession()->pageTextNotContains('Grass title');
$this->assertSession()->pageTextContains('Banana title');
// Change the link to an internal one.
$this->drupalGet($node->toUrl('edit-form'));
$this->clickLink('List Page');
$page->pressButton('edit-' . $link_filter_id);
$this->assertSession()->assertWaitOnAjaxRequest();
$nodes = \Drupal::entityTypeManager()->getStorage('node')->loadByProperties(['title' => 'Sun title']);
$sun_title = reset($nodes);
$this->getSession()->getPage()->fillField('emr_plugins_oe_list_page[wrapper][default_filter_values][wrapper][edit][' . $link_filter_id . '][link][0][link]', sprintf('%s (%s)', $sun_title->label(), $sun_title->id()));
$page->pressButton('Set default value');
$this->assertSession()->assertWaitOnAjaxRequest();
$page->pressButton('Save');
$this->assertSession()->pageTextNotContains('Cherry title');
$this->assertSession()->pageTextNotContains('Sun title');
$this->assertSession()->pageTextContains('Grass title');
$this->assertSession()->pageTextNotContains('Banana title');

// Remove filters.
$this->drupalGet($node->toUrl('edit-form'));
$this->clickLink('List Page');
$page->pressButton('delete-' . $link_filter_id);
$this->assertSession()->assertWaitOnAjaxRequest();

// Test an OR filter.
$page->selectFieldOption('Add default value for', 'Reference');
$this->assertSession()->assertWaitOnAjaxRequest();
Expand Down

0 comments on commit 9f9ea6b

Please sign in to comment.