Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EWPP-482: Support for link fields in the multiselect widget. #54

Merged
merged 1 commit into from
Dec 2, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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