The new addition to the list value processor has a problem when the field that is trying to be translated is a search_api Item Field as the getSetting() function does not exist,

Error: Call to undefined method Drupal\\search_api\\Item\\Field::getSetting() in /var/www/build/html/modules/contrib/facets/src/Plugin/facets/processor/ListItemProcessor.php on line 119

The following patch checks if the Field is a instance of search_api Item field and if so does not make the function call to getSetting()

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

ndrake86 created an issue. See original summary.

ndrake86’s picture

Status: Active » Needs review
FileSize
1.34 KB
ndrake86’s picture

Couple of SC of the before and after.

ndrake86’s picture

FileSize
1.36 KB

It was recommend that I use the interface instead of the referencing the Search API field Item directly so this is an updated patch with that change.

ndrake86’s picture

I think the other option is a patch the Search API that adds getSetting function call but I do not know if that is something that is even wanted for the Search API.

ndrake86’s picture

From drunken monkey in the search API issue #2773665: Add the getSetting function to Search API Item field

getSettings() is currently really only used to save the field in the index's field settings, so a getSetting() method would be pointless. Furthermore, it might make things more confusing regarding the difference to getConfiguration().
Finally, this is definitely a bug in the Facets code, which first sets $field to a Search API field only to then, under some circumstances, replace it with a Core field and then just assuming it is a Core field. That would need to be fixed in any case, no need to change the Search API for that.

I don't quite understand how sometimes it changes or where the bug might be and with some help pointing the way I would have no problem working on fixing it.

ndrake86’s picture

Title: Error when using List Value processor for Search API Field » Using the List Value processor to display label for Search API Fields throws an error.

Changing the title to be more descriptive of the problem.

borisson_’s picture

I guess this makes sense, no idea why this happens though, do you think it's possible to provide a test?

ndrake86’s picture

@borisson_ Sorry for the delay. I will put together a test patch for the issue when I have a bit of free time. But just to layout the general scenario.

Facet on Content Type.

  1. Create facet on content type without any processors
  2. Add a basic page content
  3. Current display will be page
  4. Add the list processor
  5. Error
  6. Add the patched code
  7. Displays Basic Page
borisson_’s picture

Status: Needs review » Needs work

@ndrake86: oh, don't worry, you can take all the time you need :) I'm currently focused on #2794745: Use Search API's display plugin to fix facets

ndrake86’s picture

FileSize
2.22 KB

@borrison_ here is a first go at a webtest for the processor. Let me know your thoughts. This is actually the first time I have written a test so if bare with me as I figure this stuff all out.

ndrake86’s picture

Status: Needs work » Needs review
ndrake86’s picture

FileSize
2.5 KB
1.42 KB

Small changes trying to get this simpletests to work.

The last submitted patch, 11: test_only.patch, failed testing.

Status: Needs review » Needs work

The last submitted patch, 13: 2773113-test-only.patch, failed testing.

The last submitted patch, 11: test_only.patch, failed testing.

The last submitted patch, 13: 2773113-test-only.patch, failed testing.

borisson_’s picture

  1. +++ b/src/Tests/ProcessorIntegrationTest.php
    @@ -534,4 +535,36 @@ class ProcessorIntegrationTest extends WebTestBase {
    +  protected function checkListProcessor() {
    

    This needs a docblock.

    /**
     * Tests the list processor.
     */
    
  2. +++ b/src/Tests/ProcessorIntegrationTest.php
    @@ -534,4 +535,36 @@ class ProcessorIntegrationTest extends WebTestBase {
    +    $this->
    

    Not sure what this is supposed to be, but I guess this should be removed?

ndrake86’s picture

FileSize
101.44 KB

Some of the code review changes from #18 for the test branch.

ndrake86’s picture

Status: Needs work » Needs review
ndrake86’s picture

Wrong patch. My bad.

borisson_’s picture

Can you rename the file to .patch, so the testbot can pick it up?

ndrake86’s picture

FileSize
3.96 KB

Re-roll to the tests patch as I realized I was a bit behind and the fix all in one patch.

ndrake86’s picture

borrison_, just saw the comment. Sorry about the patch names I thought as it was a test only patch you wouldn't want the test bot to pick it up. I did however re-roll the patch and test into one patch. Let me know if there is anything else I can do for this guy and thanks for reviewing.

Status: Needs review » Needs work

borisson_’s picture

FileSize
2.07 KB
4.21 KB

I changed some docs around. I think the fails here are not specific to this issue but rather related to something else, I just committed something that should fix this.

borisson_’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work

The last submitted patch, 27: using_the_list_value-2773113-27.patch, failed testing.

The last submitted patch, 27: using_the_list_value-2773113-27.patch, failed testing.

ndrake86’s picture

I am not sure exactly with this is failing still. The test looks correct? Did I miss anything when creating it?

borisson_’s picture

I'll have a look at the tests tonight.

andypost’s picture

Core provides interface \Drupal\Core\TypedData\OptionsProviderInterface that should be used

+++ b/src/Plugin/facets/processor/ListItemProcessor.php
@@ -116,13 +117,18 @@ class ListItemProcessor extends ProcessorPluginBase implements BuildProcessorInt
+      if (!$field instanceof FieldInterface) {
+        $function = $field->getSetting('allowed_values_function');
...
+        if (empty($function)) {
+          $allowed_values = $field->getSetting('allowed_values');
+        }
+        else {
+          $allowed_values = ${$function}($field);
+        }

Here should be check for \Drupal\Core\TypedData\OptionsProviderInterface
and it's methods used instead of direct settings access

YurkinPark’s picture

Didn't find a solution with \Drupal\Core\TypedData\OptionsProviderInterface, but covered many case with this patch.

borisson_’s picture

Status: Needs work » Needs review

Setting to needs review for the testbot, not sure if that's the way to go though. At least we should also implement the integration test from #27.

The patch in #34 makes this already very unreadable / complex method even worse, I'm not too happy with that - but that might be fixed in a follow-up.

@andypost: the optionsProvider might be a good thing to do here - getPossibleOptions on that interface does look like what we need.

Status: Needs review » Needs work

The last submitted patch, 34: using_the_list_value-2773113-34.patch, failed testing.

The last submitted patch, 34: using_the_list_value-2773113-34.patch, failed testing.

andypost’s picture

I debugged that a bit, and here's another bug - instead of $field_identifier (that is index related) you should use $index->getField($field_identifier)->propertyPath

Because mapping to fields should be done through typed data, without property path a lot of errors possible caused by name collisions
For example Node has field *labels* and Node attache Term has field *labels* - facet will try to use node field but should take property path in account

ndrake86’s picture

@_borrison, what are we still looking for on this? Any ideas about \Drupal\Core\TypedData\OptionsProviderInterface I am not to sure what @andypost was mentioning. I have some time this week if you have a suggestion on where to start.

borisson_’s picture

We're looking for a solution based on #27 (as that has tests + the code that @andypost mentioned.

+++ b/src/Plugin/facets/processor/ListItemProcessor.php
@@ -116,13 +117,18 @@ class ListItemProcessor extends ProcessorPluginBase implements BuildProcessorInt
+      if (!$field instanceof FieldInterface) {
+        $function = $field->getSetting('allowed_values_function');
...
+        if (empty($function)) {
+          $allowed_values = $field->getSetting('allowed_values');
+        }
+        else {
+          $allowed_values = ${$function}($field);
+        }

We're looking for a way to do this trough the entity API; in pseudocode

if ($field instanceof OptionsProviderInterface) {
$allowed_values = $field-> getPossibleOptions ();
}

Apart from that, we'd need to fix the test + if possible add additional unit / kernel test coverage. However that extra testcoverage is very low priority.

borisson_’s picture

Status: Needs work » Needs review
FileSize
2.54 KB
5.58 KB

options_allowed_values should be an easier way to do this, thanks @swentel

This patch also makes some other changes for reducing the complexity of the plugin

Status: Needs review » Needs work

The last submitted patch, 41: using_the_list_value-2773113-41.patch, failed testing.

andypost’s picture

+++ b/src/Plugin/facets/processor/ListItemProcessor.php
@@ -108,6 +109,7 @@ class ListItemProcessor extends ProcessorPluginBase implements BuildProcessorInt
+    $field = FALSE;

@@ -115,31 +117,28 @@ class ListItemProcessor extends ProcessorPluginBase implements BuildProcessorInt
-    if ($field) {
-      $function = $field->getSetting('allowed_values_function');
+    if (!$field) {
+      return $results;

I'd better use !empty() here and added interface check for field interface

borisson_’s picture

FileSize
3.35 KB
6.29 KB

Thanks for that suggestion @andypost, I did some additional refactoring of the code to make it somewhat easier to read.

No idea how to fix the tests - but manual testing confirms that it works.

borisson_’s picture

Status: Needs work » Needs review

Go testbot, go!

Status: Needs review » Needs work

The last submitted patch, 44: using_the_list_value-2773113-44.patch, failed testing.

borisson_’s picture

I think the integration test fail is related to #2809797: Create test for multiple facets on a page. - so I'll go there to figure that out.

borisson_’s picture

So - just to keep everything updated in the issue queue and not just in my head:

- this patch needs to updated to fix the failing unit tests.
- the issue #47 links to should be the one where we fix the integration test so that this can be fixed.

borisson_’s picture

Looks like #2809797: Create test for multiple facets on a page. is not the reason for the fails here. Diving back in.

borisson_’s picture

Status: Needs work » Needs review
FileSize
1.24 KB
10.14 KB

The work I did on the plane.

Status: Needs review » Needs work

The last submitted patch, 50: using_the_list_value-2773113-50.patch, failed testing.

borisson_’s picture

Status: Needs work » Needs review
FileSize
5.4 KB
13.33 KB

Fixes unit tests.

Status: Needs review » Needs work

The last submitted patch, 52: using_the_list_value-2773113-52.patch, failed testing.

borisson_’s picture

Status: Needs work » Needs review
FileSize
4.21 KB
13.93 KB
sukanya.ramakrishnan’s picture

The List item processor doesnt work for fields that are on an entity reference field on a document. Before this patch , we could get the field settings using the datadefinition method like in this patch https://www.drupal.org/files/issues/facets-Fix_TranslateEntityProcessor-... , but i wonder why we take a longer route like in this patch?

Thanks,
Sukanya

borisson_’s picture

@sukanya.ramakrishnan: I don't think we were explicitly supporting that use-case. I don't mind adding it back in though if it's not hard to do. In any case, adding/supporting that usecase means that we'd need a test for that as well. I think we should probably do that in a seperate issue? Not sure. Maybe we can do that here as well.

Anyway, the datadefinition that we get from search api is not sufficient to get the information needed here.

sukanya.ramakrishnan’s picture

Ok will create a new issue for this usecase so that this issue doesnt get blocked. Thanks!

regards,
Sukanya

  • borisson_ committed 5132b29 on 8.x-1.x
    Issue #2773113 by borisson_, ndrake86, YurkinPark, swentel: Using the...

borisson_ credited swentel.

borisson_ credited swentel.

borisson_’s picture

Committed, thanks!

  • borisson_ committed 65e4a1b on 8.x-1.x
    Revert "Issue #2773113 by borisson_, ndrake86, YurkinPark, swentel:...
borisson_’s picture

Reverted, tests were failing because of this.

andypost’s picture

+++ b/src/Plugin/facets/processor/ListItemProcessor.php
@@ -115,34 +118,45 @@ class ListItemProcessor extends ProcessorPluginBase implements BuildProcessorInt
+    if ($field instanceof FieldStorageDefinitionInterface) {
+      if ($field->getType() !== 'entity_reference' && $field->getName() !== 'type') {
+        $allowed_values = options_allowed_values($field);
+        return $this->overWriteDisplayValues($results, $allowed_values);
...
+    // If no values are found for the current field, try to see if this is a
+    // bundle field.
+    $list_bundles = $this->entityTypeBundleInfo->getBundleInfo($entity);
+    if ($list_bundles) {
+      foreach ($list_bundles as $key => $bundle) {
+        $allowed_values[$key] = $bundle['label'];

Why not allow ER field type?
And limit for "type" field name?

before using bundles you need to make sure that entity type support bundles

ndrake86’s picture

I am not sure why test would fail with this, I was having trouble running any tests with or without the patch. The tests would simply timeout locally and fail around the second test. Either way, for #64 I think @andypost is right I dont think there is a reason (that I have found at least that) ER field types have to be excluded. As for the second part I think $list_bundles = $this->entityTypeBundleInfo->getBundleInfo($entity) returns an empty array if the $entity doesn't support bundles so maybe just an !empty check would be enough. I have manually tested the committed/reverted patch and it works great for what I originally was solving. Thoughts about what still needs to be done here?

borisson_’s picture

I can't remember why I did this. I'll update if I remember.

ndrake86’s picture

FileSize
16.21 KB
3.87 KB

So I spent some time getting this working for a couple more scenarios, both for list fields created in code using basefieldDefinition::create and for an ER field. There are a couple of things that I had questions on and wasn't 100% sure if they were correct: The facet was checking if the source was an instance of SearchApiFacetSourceInterface did that need to be a SearchApiDisplay now? Also I was hoping someone with a better knowledge of ER fields and the search API could comment. I think having to digg down through the field definitions is a bit commbersome. Maybe a new processor is needed there but I figured I could start with it here and someone could give some context.

Thanks,

Nick

ndrake86’s picture

FileSize
16.54 KB
4.21 KB

I actually ran into an instance where I broke my own patch. There was a search API field being added by a processor and there is no of course no fieldDefinition for that so this patch should fix that. Interdiff still with #54

borisson_’s picture

FileSize
3.22 KB
16.42 KB

I think we can commit this, looks good. Going to give the testbot some time to look at this first - I made some small changes for readability.

borisson_’s picture

Changing author.

  • borisson_ committed aeec56f on 8.x-1.x authored by ndrake86
    Issue #2773113 by borisson_, ndrake86, YurkinPark, swentel: Using the...
borisson_’s picture

Status: Needs review » Fixed

Committed and pushed, thanks for sticking with this.

Status: Fixed » Closed (fixed)

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