Skip to content
Snippets Groups Projects
Verified Commit ecb01577 authored by Mark Jones's avatar Mark Jones Committed by Lee Rowlands
Browse files

Issue #2915758 by justanothermark, larowlan: Add Views contextual filter for 'is Sibling of'

parent 07f87e9c
No related branches found
No related tags found
No related merge requests found
......@@ -15,8 +15,19 @@ views.argument.entity_hierarchy_argument_is_parent_of_entity:
type: integer
label: 'Depth'
views.argument.entity_hierarchy_argument_is_sibling_of_entity:
type: views_argument
label: 'Sibling entities'
mapping:
depth:
type: integer
label: 'Depth'
views.argument.entity_hierarchy_argument_is_parent_of_entity_revision:
type: views.argument.entity_hierarchy_argument_is_parent_of_entity
views.argument.entity_hierarchy_argument_is_child_of_entity_revision:
type: views.argument.entity_hierarchy_argument_is_child_of_entity
views.argument.entity_hierarchy_argument_is_sibling_of_entity_revision:
type: views.argument.entity_hierarchy_argument_is_sibling_of_entity
......@@ -76,6 +76,15 @@ function entity_hierarchy_views_data() {
'id' => $has_revisions ? 'entity_hierarchy_argument_is_parent_of_entity_revision' : 'entity_hierarchy_argument_is_parent_of_entity',
],
];
// Contextual filter for filtering to sibling of a given child.
$data[$table_name]['is_sibling'] = [
'title' => t('Hierarchy: Is Sibling of'),
'help' => t('Limit to sibling of given entity'),
'real field' => 'left_pos',
'argument' => [
'id' => $has_revisions ? 'entity_hierarchy_argument_is_sibling_of_entity_revision' : 'entity_hierarchy_argument_is_sibling_of_entity',
],
];
// Sorting and filtering on depth.
$data[$table_name]['depth'] = [
'title' => t('Hierarchy depth'),
......
<?php
namespace Drupal\entity_hierarchy\Plugin\views\argument;
use Drupal\Core\Form\FormStateInterface;
/**
* Argument to limit to parent of an entity.
*
* @ingroup views_argument_handlers
*
* @ViewsArgument("entity_hierarchy_argument_is_sibling_of_entity")
*/
class HierarchyIsSiblingOfEntity extends EntityHierarchyArgumentPluginBase {
/**
* Set up the query for this argument.
*
* The argument sent may be found at $this->argument.
*/
public function query($group_by = FALSE) {
$this->ensureMyTable();
// Load the actual entity.
$filtered = FALSE;
if ($entity = $this->loadEntity()) {
$stub = $this->nodeKeyFactory->fromEntity($entity);
if ($node = $this->getTreeStorage()->findParent($stub)) {
// Query between a range with fixed depth, excluding the original node.
$filtered = TRUE;
$expression = "$this->tableAlias.$this->realField BETWEEN :lower and :upper AND $this->tableAlias.$this->realField <> :lower AND $this->tableAlias.depth = :depth AND $this->tableAlias.id != :self";
$arguments = [
':lower' => $node->getLeft(),
':upper' => $node->getRight(),
':depth' => $node->getDepth() + 1,
':self' => $stub->getId(),
];
$this->query->addWhereExpression(0, $expression, $arguments);
}
}
// The parent entity doesn't exist, or isn't in the tree and hence has no
// children.
if (!$filtered) {
// Add a killswitch.
$this->query->addWhereExpression(0, '1 <> 1');
}
}
/**
* {@inheritdoc}
*/
public function buildOptionsForm(&$form, FormStateInterface $form_state) {
parent::buildOptionsForm($form, $form_state);
unset($form['depth']);
}
}
<?php
namespace Drupal\entity_hierarchy\Plugin\views\argument;
/**
* Argument to limit to parent of a revision.
*
* @ingroup views_argument_handlers
*
* @ViewsArgument("entity_hierarchy_argument_is_sibling_of_entity_revision")
*/
class HierarchyIsSiblingOfEntityRevision extends HierarchyIsSiblingOfEntity {
/**
* {@inheritdoc}
*/
protected function loadEntity() {
$storage = $this->entityTypeManager->getStorage($this->getEntityType());
return $storage->loadRevision($this->argument) ?: $storage->load($this->argument);
}
}
......@@ -327,3 +327,55 @@ display:
- url
- url.query_args
tags: { }
block_4:
display_plugin: block
id: block_4
display_title: Block
position: 3
display_options:
display_extenders: { }
arguments:
is_parent:
id: is_sibling
table: nested_set_parents_entity_test
field: is_sibling
relationship: none
group_type: group
admin_label: ''
default_action: ignore
exception:
value: all
title_enable: false
title: All
title_enable: false
title: ''
default_argument_type: fixed
default_argument_options:
argument: ''
default_argument_skip_url: false
summary_options:
base_path: ''
count: true
items_per_page: 25
override: false
summary:
sort_order: asc
number_of_records: 0
format: default_summary
specify_validation: true
validate:
type: none
fail: 'not found'
validate_options: { }
plugin_id: entity_hierarchy_argument_is_sibling_of_entity
defaults:
arguments: false
cache_metadata:
max-age: -1
contexts:
- entity_test_view_grants
- 'languages:language_content'
- 'languages:language_interface'
- url
- url.query_args
tags: { }
......@@ -162,4 +162,38 @@ class ViewsIntegrationTest extends EntityHierarchyKernelTestBase {
$this->assertIdenticalResultset($executable, $expected, ['name' => 'name', 'id' => 'id']);
}
/**
* Tests views sibling integration.
*/
public function testViewsIntegrationSiblings() {
$children = $this->createChildEntities($this->parent->id(), 3);
$child = reset($children);
$this->createChildEntities($child->id(), 5);
// Tree is as follows
// 1 : Parent
// - 4 : Child 3
// - 3 : Child 2
// - 2 : Child 1
// - - 9 : Child 5
// - - 8 : Child 4
// - - 7 : Child 3
// - - 6 : Child 2
// - - 5 : Child 1
// Test showing single hierarchy.
$expected = [
[
'name' => 'Child 3',
'id' => 4,
],
[
'name' => 'Child 2',
'id' => 3,
],
];
$executable = Views::getView('entity_hierarchy_test_children_view');
$executable->preview('block_4', [$child->id()]);
$this->assertCount(2, $executable->result);
$this->assertIdenticalResultset($executable, $expected, ['name' => 'name', 'id' => 'id']);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment