Once #2625152: Implement a Hierarchical Entity Processor is in place, we should create hierarchical facets.

Lets start with taxonomy support first, then implement a pluggable system to support custom hierarchical structures (e.g. based on an entity reference field)

CommentFileSizeAuthor
#81 Screen Shot 2016-12-06 at 1.53.18 PM.png38.97 KBndrake86
#75 implement_hierarchical-2807333-75.patch45.38 KBborisson_
#71 interdiff-71.txt12.8 KBdermario
#71 implement_hierarchical-2807333-71.patch68.73 KBdermario
#66 implement_hierarchical-2807333-66.patch35.19 KBjefuri
#65 implement_hierarchical-2807333-65.patch32.58 KBmpp
#60 interdiff.txt1.63 KBndrake86
#60 implement_hierarchical-2807333-60.patch32.56 KBndrake86
#59 deselecting second child facet .png1.03 MBspydimarri
#59 selecting both the child facets.png971.68 KBspydimarri
#59 single child facet selected.png809.96 KBspydimarri
#39 implement_hierarchical-2807333-39.patch31.86 KBborisson_
#39 interdiff.txt685 bytesborisson_
#36 Screen Shot 2016-10-28 at 09.12.15.png75.08 KBaspilicious
#34 implement_hierarchical-2807333-34.patch31.92 KBborisson_
#34 interdiff.txt1.63 KBborisson_
#32 implement_hierarchical-2807333-32.patch31.61 KBmarthinal
#27 interdiff.txt1022 bytesStryKaizer
#27 implement_hierarchical-2807333-27.patch31.58 KBStryKaizer
#26 implement_hierarchical-2807333-26.patch31.52 KBborisson_
#26 interdiff.txt12.15 KBborisson_
#25 implement_hierarchical-2807333-25.patch31.77 KBStryKaizer
#25 interdiff.txt1.08 KBStryKaizer
#23 implement_hierarchical-2807333-23.patch31.7 KBStryKaizer
#23 interdiff.txt327 bytesStryKaizer
#22 interdiff.txt9.68 KBStryKaizer
#22 implement_hierarchical-2807333-22.patch31.81 KBStryKaizer
#20 implement_hierarchical-2807333-20.patch29.28 KBStryKaizer
#20 interdiff.txt4.87 KBStryKaizer
#19 interdiff.txt2.22 KBStryKaizer
#19 implement_hierarchical-2807333-19.patch24.79 KBStryKaizer
#16 implement_hierarchical-2807333-16.patch23.93 KBStryKaizer
#16 interdiff.txt1.64 KBStryKaizer
#11 implement_hierarchical-2807333-11.patch23.66 KBStryKaizer
#6 implement_hierarchical-2807333-6.patch13.74 KBStryKaizer
#3 implement_hierarchical-2807333-3.patch14.33 KBStryKaizer
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

StryKaizer created an issue. See original summary.

StryKaizer’s picture

Title: Allow hierarchical structures as facets » Implement hierarchical structures in facets
StryKaizer’s picture

Status: Active » Needs review
FileSize
14.33 KB
aspilicious’s picture

THNX! :D

Next week I'll test this is our D8 project.

borisson_’s picture

Also attributing @aspilicious for this patch per feedback on irc.

StryKaizer’s picture

StryKaizer’s picture

StryKaizer’s picture

Issue tags: +Dublin2016

The last submitted patch, 3: implement_hierarchical-2807333-3.patch, failed testing.

Status: Needs review » Needs work

The last submitted patch, 6: implement_hierarchical-2807333-6.patch, failed testing.

StryKaizer’s picture

Now implemented a new plugin type "hierarchy", to allow users to create custom hierarchical logics (e.g. entity reference fields).
At this moment only taxonomy term is supported though.

StryKaizer’s picture

borisson_’s picture

  1. +++ b/src/Annotation/FacetsHierarchy.php
    @@ -0,0 +1,44 @@
    + * @see \Drupal\facets\Processor\ProcessorPluginManager
    

    c/p remnant.

  2. +++ b/src/Entity/Facet.php
    @@ -100,6 +102,20 @@ class Facet extends ConfigEntityBase implements FacetInterface {
    +   * @var array
    

    Of what is this an array, can we add a more descriptive annotation?

  3. +++ b/src/Entity/Facet.php
    @@ -100,6 +102,20 @@ class Facet extends ConfigEntityBase implements FacetInterface {
    +   * @var \Drupal\facets\Hierarchy\HierarchyPluginBase
    

    Is there an interface we can use to hint on instead?

  4. +++ b/src/FacetManager/DefaultFacetManager.php
    @@ -366,4 +389,19 @@ class DefaultFacetManager {
    +  protected function buildHierarchicalTree($keyed_results, $parent_groups) {
    

    This needs some docs.

  5. +++ b/src/Hierarchy/HierarchyInterface.php
    @@ -0,0 +1,23 @@
    +interface HierarchyInterface {
    ...
    +  public function getParentIds($id);
    ...
    +  public function getNestedChildIds($id);
    

    Needs docs as well.

  6. +++ b/src/Hierarchy/HierarchyPluginBase.php
    @@ -0,0 +1,23 @@
    +    $request = $container->get('request_stack')->getMasterRequest();
    

    Is there a reason why we use MasterRequest instead of CurrentRequest here? I'm actually not very sure what the difference is. So maybe just ignore this

  7. +++ b/src/Plugin/facets/hierarchy/Taxonomy.php
    @@ -0,0 +1,94 @@
    +  public function getNestedChildIds($id) {
    +    $children = &drupal_static(__FUNCTION__, []);
    

    Nice that this is cached!

  8. +++ b/src/Plugin/facets/hierarchy/Taxonomy.php
    @@ -0,0 +1,94 @@
    +      $subchilds = [];
    

    I'm not sure about subchilds, maybe grand_children makes more sense?

  9. +++ b/src/Plugin/facets/hierarchy/Taxonomy.php
    @@ -0,0 +1,94 @@
    +  protected function taxonomy_get_parent($tid) {
    ...
    +    $parent = &drupal_static(__FUNCTION__, []);
    

    Nice that this is cached as well, but let's make this camelCase

  10. +++ b/src/Plugin/facets/url_processor/QueryString.php
    @@ -97,6 +97,17 @@ class QueryString extends UrlProcessorPluginBase {
    +          // If hierarchy is active, unset parent trail and every child when
    +          // building the enable-link to ensure those are not enabled anymore.
    

    This is a perfect comment!

I mostly looked at how this was built architecturally, but I don't see anything that I'd change, very cool!

The last submitted patch, 3: implement_hierarchical-2807333-3.patch, failed testing.

The last submitted patch, 6: implement_hierarchical-2807333-6.patch, failed testing.

StryKaizer’s picture

Status: Needs work » Needs review
FileSize
1.64 KB
23.93 KB

Cleaned up the default classes and added hierarchy info for themers

Status: Needs review » Needs work

The last submitted patch, 16: implement_hierarchical-2807333-16.patch, failed testing.

The last submitted patch, 16: implement_hierarchical-2807333-16.patch, failed testing.

StryKaizer’s picture

Issue tags: +Needs tests
FileSize
24.79 KB
2.22 KB

Addressed #13

StryKaizer’s picture

Status: Needs work » Needs review
FileSize
4.87 KB
29.28 KB

- Made tests less red
- added indeterminate state for checkbox
- default hierarchical indentation css

aspilicious’s picture

css file is missing

StryKaizer’s picture

FileSize
31.81 KB
9.68 KB

Parents getting enabled when childs get disabled is now configurable.

interdiff is for #16, ignore #21 ;)

StryKaizer’s picture

FileSize
327 bytes
31.7 KB

Small css fix added.

This functionality is now pretty much in a usable state for taxonomy term hierarchy.
We do not have any test coverage yet, though.

Some stuff testcoverage should check
- If hierarchical structures behave as plain structures when hierarchy is disabled
- Expanded/non expanded hierarchies
- parent enabling/disabling depending on setting

StryKaizer’s picture

Assigned: StryKaizer » Unassigned
StryKaizer’s picture

FileSize
1.08 KB
31.77 KB

Some small bugfixxes added

borisson_’s picture

FileSize
12.15 KB
31.52 KB

Overall this looks great, still needs tests and some battle-testing.

cleanup attached.

StryKaizer’s picture

FileSize
31.58 KB
1022 bytes

Fix to make this php5.5 compatible added.

borisson_’s picture

  1. +++ b/css/hierarchical.css
    @@ -0,0 +1,3 @@
    +.block-facets ul ul li {
    +    margin-left: 10px;
    +}
    

    Is there a way we can do this just on the li class instead of doing this?

  2. +++ b/src/Entity/Facet.php
    @@ -261,6 +299,18 @@ class Facet extends ConfigEntityBase implements FacetInterface {
    +    $container = \Drupal::getContainer();
    +
    +    return $this->widget_plugin_manager ?: $container->get('plugin.manager.facets.hierarchy');
    

    can we change this to return $this->widget_plugin_manager ?: \Drupal::service('plugin.manager.facets.hierarchy');

  3. +++ b/src/Entity/Facet.php
    @@ -319,6 +369,45 @@ class Facet extends ConfigEntityBase implements FacetInterface {
    +    return $this;
    

    Most of our setters don't return $this, so let's remove this.

Alienpruts’s picture

Patch at #23 partially failed because I implemented https://www.drupal.org/node/2784349#comment-11707151 .

This is probably to be expected, but just wanted to warn you all the same :)

For the rest I can confirm it seems to work as expected, building a term tree and allowing the facet to filter on the term chosen.

Status: Needs review » Needs work

The last submitted patch, 27: implement_hierarchical-2807333-27.patch, failed testing.

borisson_’s picture

Issue tags: +Needs reroll
marthinal’s picture

Status: Needs work » Needs review
FileSize
31.61 KB

Done!

borisson_’s picture

Status: Needs review » Needs work
Issue tags: -Needs reroll

#28 still needs to be addressed.

borisson_’s picture

FileSize
1.63 KB
31.92 KB

Resolves #28.

This still needs tests, but I think we should probably get #2815187: Cleanup entities and write kernel tests for them in first, so we can add a kernel test as wel as integration tests.

borisson_’s picture

Status: Needs work » Needs review

back to NR

aspilicious’s picture

It works :).
For some reason I had to rebuild the facet before it appeared, but hey it works now :)

aspilicious’s picture

A bug we found: When selecting "Always expand hierarchy", "Enable parent when child gets disabled" is also selected (wrong default value)

StryKaizer’s picture

Well, its not really a bug. It depends on which widget you use, which default makes the most sense.

When all items are expanded using checkboxes, imo it makes the most sense when disabling a child, the parent is enabled (since the parent of an active child, by default, is rendered in "indeterminate" state) (not visible on your screenshot though).

When all items are expanded using links, imo it makes the most sense to disable parents too, when links are clicked.

Then again, if most people prefer the default value to be different, its fine by me ;) Its a setting anyway...

borisson_’s picture

FileSize
685 bytes
31.86 KB

Fixed some docs.

Status: Needs review » Needs work

The last submitted patch, 39: implement_hierarchical-2807333-39.patch, failed testing.

borisson_’s picture

Status: Needs work » Needs review

Back to needs review, the fail was a random fail (AlreadyInstalledException)

mpp’s picture

Awesome work!

FYI: When using this patch in combination with the "current search" patch from #2735891, I no longer see the facet tree (only the root elements appear) and I get the following notice:

Notice: Undefined offset: 0 in Drupal\facets\Plugin\facets\url_processor\QueryString->buildUrls() (line 99 of modules/contrib/facets/src/Plugin/facets/url_processor/QueryString.php).
Drupal\facets\Plugin\facets\url_processor\QueryString->buildUrls(Object, Array) (Line: 65)
Drupal\facets\Plugin\facets\processor\UrlProcessorHandler->build(Object, Array) (Line: 297)
Drupal\facets\FacetManager\DefaultFacetManager->build(Object) (Line: 82)
Drupal\facets\Plugin\Block\FacetBlock->build() (Line: 203)
Drupal\block\BlockViewBuilder::preRender(Array)
call_user_func('Drupal\block\BlockViewBuilder::preRender', Array) (Line: 376)
Drupal\Core\Render\Renderer->doRender(Array, 1) (Line: 195)
Drupal\Core\Render\Renderer->render(Array, 1) (Line: 151)
Drupal\Core\Render\Renderer->Drupal\Core\Render\{closure}() (Line: 574)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 152)
Drupal\Core\Render\Renderer->renderPlain(Array) (Line: 166)
Drupal\Core\Render\Renderer->renderPlaceholder('', Array) (Line: 659)
Drupal\Core\Render\Renderer->replacePlaceholders(Array) (Line: 544)
Drupal\Core\Render\Renderer->doRender(Array, 1) (Line: 195)
Drupal\Core\Render\Renderer->render(Array, 1) (Line: 139)
Drupal\Core\Render\Renderer->Drupal\Core\Render\{closure}() (Line: 574)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 140)
Drupal\Core\Render\Renderer->renderRoot(Array) (Line: 258)
Drupal\Core\Render\HtmlResponseAttachmentsProcessor->renderPlaceholders(Object) (Line: 131)
Drupal\Core\Render\HtmlResponseAttachmentsProcessor->processAttachments(Object) (Line: 45)
Drupal\Core\EventSubscriber\HtmlResponseSubscriber->onRespond(Object, 'kernel.response', Object) (Line: 111)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch('kernel.response', Object) (Line: 184)
Symfony\Component\HttpKernel\HttpKernel->filterResponse(Object, Object, 1) (Line: 166)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 64)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 57)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 99)
Drupal\page_cache\StackMiddleware\PageCache->pass(Object, 1, 1) (Line: 78)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 50)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 652)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
borisson_’s picture

@mpp: we probably shouldn't worry about that yet. I think this one'll go in before the other one, especially because this is being used in development on a couple of sites already and we haven't really heard anything that isn't working about this.

Shreya Shetty’s picture

It works for me . But can i select all children on just select of a single parent and deselect all childrens on deselect of single parent . Is it feasible to achieve this kind of functionality

StryKaizer’s picture

#44 It is possible that certain content is only tagged with parents. Selecting children automaticly would imply it needs to be tagged with a child too. Therefor, no.

However, you can prolly visually achieve this by using css if your dataset will always have a child tagged.
This will not be implemented in the plugin itself, as in my opinion, this makes the functionality not clear on how it behaves.

Shreya Shetty’s picture

May be we could give flexibility for the users to have this option . If we are implementing this feature i can start working on this . This will be a "good to have" feature in facets . I would rather like to hear from experts though

Selecting children automatically would imply it needs to be tagged with a child too

Yes only the tagged childrens should get selected automatically when the parent is selected. And only the tagged children is visible on facets otherwise the term is not visible whichever is not tagged in facets

borisson_’s picture

May be we could give flexibility for the users to have this option . If we are implementing this feature i can start working on this . This will be a "good to have" feature in facets . I would rather like to hear from experts though.

You did hear from an expert, @StryKaizer is exactly that. Anyway, I think that is something we can discuss in a follow-up. The only thing that this needs before committing is an integration test that tests this behavior. Let's try to get that written so we can commit this.

ndrake86’s picture

I tested out the processor here and came across one problem: Using the "translate entity " processor to change the taxonomy terms into back into their labels I am seeing the following error:

Error: Call to a member function getSetting() on null in Drupal\facets\Plugin\facets\processor\TranslateEntityProcessor->build() (line 111 of /var/www/build/html/modules/contrib/facets/src/Plugin/facets/processor/TranslateEntityProcessor.php) #0 /var/www/build/html/modules/contrib/facets/src/FacetManager/DefaultFacetManager.php(297): Drupal\facets\Plugin\facets\processor\TranslateEntityProcessor->build(Object(Drupal\facets\Entity\Facet), Array) #1 /var/www/build/html/modules/contrib/facets/src/Plugin/Block/FacetBlock.php(82): Drupal\facets\FacetManager\DefaultFacetManager->build(Object(Drupal\facets\Entity\Facet)) #2 /var/www/build/html/core/modules/block/src/BlockViewBuilder.php(203): Drupal\facets\Plugin\Block\FacetBlock->build() #3 [internal function]: Drupal\block\BlockViewBuilder::preRender(Array) #4 /var/www/build/html/core/lib/Drupal/Core/Render/Renderer.php(376): call_user_func('Drupal\\block\\Bl...', Array) #5 /var/www/build/html/core/lib/Drupal/Core/Render/Renderer.php(195): Drupal\Core\Render\Renderer->doRender(Array, true) #6 /var/www/build/html/core/lib/Drupal/Core/Render/Renderer.php(151): Drupal\Core\Render\Renderer->render(Array, true) #7 /var/www/build/html/core/lib/Drupal/Core/Render/Renderer.php(574): Drupal\Core\Render\Renderer->Drupal\Core\Render\{closure}() #8 /var/www/build/html/core/lib/Drupal/Core/Render/Renderer.php(152): Drupal\Core\Render\Renderer->executeInRenderContext(Object(Drupal\Core\Render\RenderContext), Object(Closure)) #9 /var/www/build/html/core/lib/Drupal/Core/Render/Renderer.php(166): Drupal\Core\Render\Renderer->renderPlain(Array) #10 /var/www/build/html/core/modules/big_pipe/src/Render/BigPipe.php(527): Drupal\Core\Render\Renderer->renderPlaceholder('callback=Drupal...', Array) #11 /var/www/build/html/core/modules/big_pipe/src/Render/BigPipe.php(395): Drupal\big_pipe\Render\BigPipe->renderPlaceholder('callback=Drupal...', Array) #12 /var/www/build/html/core/modules/big_pipe/src/Render/BigPipe.php(137): Drupal\big_pipe\Render\BigPipe->sendPlaceholders(Array, Array, Object(Drupal\Core\Asset\AttachedAssets)) #13 /var/www/build/html/core/modules/big_pipe/src/Render/BigPipeResponse.php(41): Drupal\big_pipe\Render\BigPipe->sendContent('...', Array) #14 /var/www/vendor/symfony/http-foundation/Response.php(374): Drupal\big_pipe\Render\BigPipeResponse->sendContent() #15 /var/www/build/html/index.php(20): Symfony\Component\HttpFoundation\Response->send() #16 {main}.

It looks like everything should be working correctly based on the SC provided above but I am cannot see if I have a mis-configuration or if their is an issue with the processor and Solr as the backend.

Search-API -> Beta3
Search-API-Solr -> Beta1
Core -> 8.2.1
Facets -> 3d18651 (dev-master -1 at time of writing). I will debug some more but outside of this, which might be un-related, I am excited to see this finally make it in.

ndrake86’s picture

So the entity translation processor issue looks like known issue: https://www.drupal.org/node/2777217.

ndrake86’s picture

I found one issue and I am not sure what the solution might be or if its a facets issue or not but it looks like the field stored for hierarchical fields are coming back a node entities and not taxonomy entity types. which is causing a few issues displaying the label for the taxonomy ID.

borisson_’s picture

I found one issue and I am not sure what the solution might be or if its a facets issue or not but it looks like the field stored for hierarchical fields are coming back a node entities and not taxonomy entity types. which is causing a few issues displaying the label for the taxonomy ID.

That's a good question, I don't think we've tested those together already but will defer to @StryKaizer, he's been more involved in this work.

StryKaizer’s picture

#50 not sure what you mean.
How did you index your taxonomy terms? It should be indexed using tid and adding a hierarchy processor in search_api

My terms are getting the correct labels using the facet processor which converts entity ids to labels.

aspilicious’s picture

I get correct labels too.

ndrake86’s picture

@StryKaizer and @borrisson_ I indexed the top level taxonomy term, which happens to be the tid which works with the current implementation of the entity processor. What I did find was that if you drill down in the taxonomy term and index the actual term ID field_name:entity:tid the processor will through the error identified in #49. I believe what I was originally seeing was a caching issue with the processor not working with Hierarchical facets but I do think there is still an issue with the null call on getSettings() in the Entity processor. I added a patch in the other case worked for my particular case.

smiletrl’s picture

I can confirm #39 patch works for my case. The hierarchy can be retrieved perfectly.

The translate entity label issue is kind of not related with hierarchy issue. So it would be great #39 patch can be committed.

ndrake86’s picture

I been testing the patch out and I am seeing the same error as described in #42 but I do not have the patch for #2735891 applied. Oddly enough, everything seems to function without issue, the facets is applied to the URL, if the children aren't expanded they expand correctly. Clicking on the top most parent is the only way to cause the issue; if you select a child even is that child has children of its own no error. I am going to see if I can make sense of where its happening.

stack trace:

Notice: Undefined offset: 0 in Drupal\facets\Plugin\facets\url_processor\QueryString->buildUrls() (line 99 of /var/www/community/build/html/modules/contrib/facets/src/Plugin/facets/url_processor/QueryString.php) #0 /var/www/community/build/html/core/includes/bootstrap.inc(548): _drupal_error_handler_real(8, 'Undefined offse...', '/var/www/commun...', 99, Array) #1 /var/www/community/build/html/modules/contrib/facets/src/Plugin/facets/url_processor/QueryString.php(99): _drupal_error_handler(8, 'Undefined offse...', '/var/www/commun...', 99, Array) #2 /var/www/community/build/html/modules/contrib/facets/src/Plugin/facets/processor/UrlProcessorHandler.php(65): Drupal\facets\Plugin\facets\url_processor\QueryString->buildUrls(Object(Drupal\facets\Entity\Facet), Array) #3 /var/www/community/build/html/modules/contrib/facets/src/FacetManager/DefaultFacetManager.php(297): Drupal\facets\Plugin\facets\processor\UrlProcessorHandler->build(Object(Drupal\facets\Entity\Facet), Array) #4 /var/www/community/build/html/modules/contrib/facets/src/Plugin/Block/FacetBlock.php(82): Drupal\facets\FacetManager\DefaultFacetManager->build(Object(Drupal\facets\Entity\Facet)) #5 /var/www/community/build/html/core/modules/block/src/BlockViewBuilder.php(203): Drupal\facets\Plugin\Block\FacetBlock->build() #6 [internal function]: Drupal\block\BlockViewBuilder::preRender(Array) #7 /var/www/community/build/html/core/lib/Drupal/Core/Render/Renderer.php(376): call_user_func('Drupal\\block\\Bl...', Array) #8 /var/www/community/build/html/core/lib/Drupal/Core/Render/Renderer.php(195): Drupal\Core\Render\Renderer->doRender(Array, true) #9 /var/www/community/build/html/core/lib/Drupal/Core/Render/Renderer.php(151): Drupal\Core\Render\Renderer->render(Array, true) #10 /var/www/community/build/html/core/lib/Drupal/Core/Render/Renderer.php(574): Drupal\Core\Render\Renderer->Drupal\Core\Render\{closure}() #11 /var/www/community/build/html/core/lib/Drupal/Core/Render/Renderer.php(152): Drupal\Core\Render\Renderer->executeInRenderContext(Object(Drupal\Core\Render\RenderContext), Object(Closure)) #12 /var/www/community/build/html/core/lib/Drupal/Core/Render/Renderer.php(166): Drupal\Core\Render\Renderer->renderPlain(Array) #13 /var/www/community/build/html/core/lib/Drupal/Core/Render/Renderer.php(659): Drupal\Core\Render\Renderer->renderPlaceholder('<drupal-render-...', Array) #14 /var/www/community/build/html/core/lib/Drupal/Core/Render/Renderer.php(544): Drupal\Core\Render\Renderer->replacePlaceholders(Array) #15 /var/www/community/build/html/core/lib/Drupal/Core/Render/Renderer.php(195): Drupal\Core\Render\Renderer->doRender(Array, true) #16 /var/www/community/build/html/core/lib/Drupal/Core/Render/Renderer.php(139): Drupal\Core\Render\Renderer->render(Array, true) #17 /var/www/community/build/html/core/lib/Drupal/Core/Render/Renderer.php(574): Drupal\Core\Render\Renderer->Drupal\Core\Render\{closure}() #18 /var/www/community/build/html/core/lib/Drupal/Core/Render/Renderer.php(140): Drupal\Core\Render\Renderer->executeInRenderContext(Object(Drupal\Core\Render\RenderContext), Object(Closure)) #19 /var/www/community/build/html/core/lib/Drupal/Core/Render/HtmlResponseAttachmentsProcessor.php(258): Drupal\Core\Render\Renderer->renderRoot(Array) #20 /var/www/community/build/html/core/lib/Drupal/Core/Render/HtmlResponseAttachmentsProcessor.php(131): Drupal\Core\Render\HtmlResponseAttachmentsProcessor->renderPlaceholders(Object(Drupal\Core\Render\HtmlResponse)) #21 /var/www/community/build/html/core/lib/Drupal/Core/EventSubscriber/HtmlResponseSubscriber.php(45): Drupal\Core\Render\HtmlResponseAttachmentsProcessor->processAttachments(Object(Drupal\Core\Render\HtmlResponse)) #22 /var/www/community/build/html/core/lib/Drupal/Component/EventDispatcher/ContainerAwareEventDispatcher.php(111): Drupal\Core\EventSubscriber\HtmlResponseSubscriber->onRespond(Object(Symfony\Component\HttpKernel\Event\FilterResponseEvent), 'kernel.response', Object(Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher)) #23 /var/www/community/vendor/symfony/http-kernel/HttpKernel.php(184): Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch('kernel.response', Object(Symfony\Component\HttpKernel\Event\FilterResponseEvent)) #24 /var/www/community/vendor/symfony/http-kernel/HttpKernel.php(166): Symfony\Component\HttpKernel\HttpKernel->filterResponse(Object(Drupal\Core\Render\HtmlResponse), Object(Symfony\Component\HttpFoundation\Request), 1) #25 /var/www/community/vendor/symfony/http-kernel/HttpKernel.php(64): Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object(Symfony\Component\HttpFoundation\Request), 1) #26 /var/www/community/build/html/core/lib/Drupal/Core/StackMiddleware/Session.php(57): Symfony\Component\HttpKernel\HttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #27 /var/www/community/build/html/core/lib/Drupal/Core/StackMiddleware/KernelPreHandle.php(47): Drupal\Core\StackMiddleware\Session->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #28 /var/www/community/build/html/core/modules/page_cache/src/StackMiddleware/PageCache.php(99): Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #29 /var/www/community/build/html/core/modules/page_cache/src/StackMiddleware/PageCache.php(78): Drupal\page_cache\StackMiddleware\PageCache->pass(Object(Symfony\Component\HttpFoundation\Request), 1, true) #30 /var/www/community/build/html/core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php(47): Drupal\page_cache\StackMiddleware\PageCache->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #31 /var/www/community/build/html/core/lib/Drupal/Core/StackMiddleware/NegotiationMiddleware.php(50): Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #32 /var/www/community/vendor/stack/builder/src/Stack/StackedHttpKernel.php(23): Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #33 /var/www/community/build/html/core/lib/Drupal/Core/DrupalKernel.php(652): Stack\StackedHttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #34 /var/www/community/build/html/index.php(19): Drupal\Core\DrupalKernel->handle(Object(Symfony\Component\HttpFoundation\Request)) #35 {main}.
borisson_’s picture

Issue tags: +beta blocker
ndrake86’s picture

So I have been working through a bit of this here tonight and I think I found one issue that was causing a potential configuration issue

$form['facet_settings']['expand_hierarchy'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Always expand hierarchy'),
      '#description' => $this->t('Render entire tree, regardless of whether the parents are active or not.'),
      '#default_value' => $facet->getExpandHierarchy(),
      '#states' => array(
        'visible' => array(
          ':input[name="facet_settings[use_hierarchy]"]' => array('checked' => TRUE),
        ),
      ),
    ];

I think the '#default_value' => function call is incorrect. I think instead of getExpandHierarchy() it should be getEnableParentWhenChildGetsDisabled

I am also seeing that the processor essentially not working. The parents are still being selected even with the above code change.

spydimarri’s picture

I have been testing Hierarchical Facets. I understand that when we deselect a child the parent is automatically selected. I am seeing a weird behavior if a parent has two children. I selected the both the children I see some search results narrowing it down according to my selection but when I uncheck the one of the children the parent gets selected and this is actually showing wrong search result. As a front-end tester this travelling back up the tree is very confusing for a user. It would be nice if we unselect the children the parent gets unselected as well

Please look at the screen shots uploaded in the file sections

ndrake86’s picture

I was able to solve the disabling parent term functionality that isn't working with patch #39. The url was not being set correctly and was using the URL from the parent even with the the Enable parent when child gets disabled disabled. The interdiff is against #39 and includes the fix described in #58

StryKaizer’s picture

  1. +++ b/src/Form/FacetForm.php
    @@ -398,7 +398,7 @@ class FacetForm extends EntityForm {
    +      '#default_value' => $facet->getEnableParentWhenChildGetsDisabled(),
    

    Thanks, looks indeed like a c/p error.

  2. +++ b/src/Plugin/facets/url_processor/QueryString.php
    @@ -72,11 +72,11 @@ class QueryString extends UrlProcessorPluginBase {
    +      // Reset the URL for each result.
    +      $url = Url::createFromRequest($request);
    +      $url->setOption('attributes', ['rel' => 'nofollow']);
    

    Are you sure this changes anything (apart from unneccessary code running multiple times)?

    It looks like this only triggers the createFromRequest and setOption multiple times, but the output should be the same...

StryKaizer’s picture

#59There is a setting which makes it behave as you expect, just uncheck "Enable parent when child gets disabled"

ndrake86’s picture

@stryKaizer what I was seeing was when the $url was being set outside of the $results loop there was a remnant of the previous terms query param being added to the checked facet here:

$url = clone $url;
      if ($result_get_params->all() !== [$this->filterKey => []]) {
        $url->setOption('query', $result_get_params->all());
      }

      $result->setUrl($url);

The if statement in the above will evaluate to false for the checked facet but the $result->setUrl($url), since the $url was just set by the last loop, will set the selected facet's data-facetredir to have a redirect to that term in the last loop.

Resetting the $url for each $result makes sure that the $url isn't being reused.

I think we could also just move the $result->setUrl($url) inside the if.

mpp’s picture

#56 is right the notice occurs without the current search patch.

          if (isset($parent_ids[0]) && $parent_ids[0]) {
            $filter_params[] = $this->urlAlias . self::SEPARATOR . $parent_ids[0];
          }
mpp’s picture

jefuri’s picture

I applied the patch to drupal 8.2.3 and found that some of the new plugins were placed in the wrong directories. I fixed it and created a new patch from those changes.

One of the issues I saw was that in my drupal root directory a src folder was created with the Hierarchy folder containing the HierarchyInterface, HierarchyPluginBase, HierarchyPluginmanager files.

Status: Needs review » Needs work

The last submitted patch, 66: implement_hierarchical-2807333-66.patch, failed testing.

borisson_’s picture

@jbertoen The patch is to be applied from the facets directory (cd modules/contrib/facets; curl https://www.drupal.org/files/issues/implement_hierarchical-2807333-65.patch | git apply - not the core root folder.

mpp’s picture

Facet sorting still seems to go wrong when you enable "Sort by active state" (Sorts the widget results by active state).

dermario’s picture

Assigned: Unassigned » dermario
Issue tags: +drupalironcamp2016

I will try to write some tests for it.

dermario’s picture

Status: Needs work » Needs review
FileSize
68.73 KB
12.8 KB

Here are my tests for this issue. It took me a while to generate all the structures but i think i got it working. Lets see what the testbot says. If there are any cases missing, let me know. During my tests i ran into a configuration schema exceptions, due to a missing schema for the translate_entity option. Thats why i also edited facets.facet.schema.yml although this is obviously not in scope of this issue. Maybe there are more schema entries missing?

In my tests i do the following stuff:

setup:

  1. Create a new vocabulary
  2. Create a term structure with hierarchy
  3. Entities "item" and "article" and add a term reference to the new vocabulary
  4. Generate some content
  5. Add the newly created term reference to the search index
  6. Index all items
  7. Create a facet for the new field in index

tests:

  1. tests for the use hierarchy option
  2. tests for the always expand hierarchy option
  3. tests for the Enable parent when child gets disabled option
dermario’s picture

Assigned: dermario » Unassigned
borisson_’s picture

Status: Needs review » Reviewed & tested by the community

I just did a review and I have no remarks. It looks great. I'll have another look tomorrow but that's absolutely great work @dermario!

aspilicious’s picture

Certainly good enough for now.
I'm using this in production for a while now, so I would love to get this in.

borisson_’s picture

Looks like a couple of things slipped in with @dermario's patch that shouldn't have. Applied #65 + interdiff from #71 locally. Result is attached. If testbot's green I'll commit this right away.

borisson_’s picture

Status: Reviewed & tested by the community » Fixed

Awesome, thanks so much everyone. Please open followups if the behavior isn't as expected yet.

  • borisson_ committed a12d307 on 8.x-1.x authored by StryKaizer
    Issue #2807333 by StryKaizer, borisson_, ndrake86, dermario, mpp,...
ndrake86’s picture

Sweet. One step closer to a beta!

  • borisson_ committed 465c213 on 8.x-1.x
    Issue #2807333: followup - cleanup test code
    
PeterStub’s picture

I'm using search api(backend = database) - and I see the hierarchy checkbox. I have a commerce product with term references - and I see the facets - but the hierarchy is flat. I dont know exactly what is meant by "Requires the hierarchy processor configured in search api for this field" - I havnt be able to find how to disable/enable this. I guess thats where my problem is.

Can someone point me in the right direction?

I'm sorry if this is not the right place?

Tks

ndrake86’s picture

@peterStub You need to enable the search API processor the Hierarchy, which is located here /admin/config/search/search-api/index/<index_name>/processors

Looks something like the attached SC.

PeterStub’s picture

Tks @ndrake86...I did visit that page once - but could see it - but its there now...GREAT - tks alot...

And I confirm it all works...

StryKaizer’s picture

We could at the "/admin/config/search/search-api/index//processors" url in the description too in a follow up to help future users.

borisson_’s picture

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.