I created a Search API index which indexes both Commerce Product entities as well as standard nodes. I then tried to create a view showing that index. It seems that no matter what settings I choose on the initial page to create the view, when I submit the following exception is thrown:

Drupal\Component\Plugin\Exception\PluginNotFoundException: The "" entity type does not exist. in Drupal\Core\Entity\EntityTypeManager->getDefinition() (line 133 of core/lib/Drupal/Core/Entity/EntityTypeManager.php).

Should I be able to use a multi-entity-type index in Views?

1. If so, any idea what's causing it not to work in my case?
2. If not, should that be made clearer somewhere, or perhaps should those indexes be not made available as sources for Views at all?

CommentFileSizeAuthor
#38 2839932-38--rendered_item_views_field_handler.patch10.58 KBdrunken monkey
#38 2839932-38--rendered_item_views_field_handler--interdiff.txt1.78 KBdrunken monkey
#35 2839932-35--rendered_item_views_field_handler.patch9.29 KBdrunken monkey
#35 2839932-35--rendered_item_views_field_handler--tests_only.patch3.68 KBdrunken monkey
#35 2839932-35--rendered_item_views_field_handler--interdiff.txt742 bytesdrunken monkey
#27 2839932-27--rendered_item_views_field_handler.patch8.75 KBdrunken monkey
#27 2839932-27--rendered_item_views_field_handler--tests_only.patch3.15 KBdrunken monkey
#27 2839932-27--rendered_item_views_field_handler--interdiff.txt992 bytesdrunken monkey
#24 2839932-24--rendered_item_views_field_handler.patch8.33 KBdrunken monkey
#24 2839932-24--rendered_item_views_field_handler--tests_only.patch2.72 KBdrunken monkey
#24 2839932-24--rendered_item_views_field_handler--interdiff.txt840 bytesdrunken monkey
#21 2839932-21--rendered_item_views_field_handler.patch7.93 KBdrunken monkey
#21 2839932-21--rendered_item_views_field_handler--tests_only.patch1.11 KBdrunken monkey
#5 2839932-5--rendered_item_views_field_handler.patch2.78 KBdrunken monkey
#7 2839932-7--rendered_item_views_field_handler--interdiff.txt4.6 KBdrunken monkey
#7 2839932-7--rendered_item_views_field_handler.patch6.8 KBdrunken monkey
#10 2839932-10--rendered_item_views_field_handler--interdiff.txt1.22 KBdrunken monkey
#10 2839932-10--rendered_item_views_field_handler.patch8.03 KBdrunken monkey
#15 2839932-15--rendered_item_views_field_handler.patch7.61 KBreplicaobscura
#19 interdiff.txt833 bytesjacktonkin
#19 2839932-19--rendered_item_views_field_handler.patch6.82 KBjacktonkin

Comments

bmcclure created an issue. See original summary.

replicaobscura’s picture

Issue summary: View changes
replicaobscura’s picture

It seems to be because there is no 'entity_type' key in the Views field definition it's trying to read. It seems like that key is normally added in _search_api_views_get_field_handler_for_property(), but must be failing somewhere along the line in this case.

replicaobscura’s picture

Actually, I think I've narrowed this down:

It seems to be because the first field in my index was the Rendered HTML Output field, which must have been the field being passed to something by default in Views. When I removed that field, my view started working. Here's hoping I can add it back now!

drunken monkey’s picture

Status: Active » Needs review
StatusFileSize
new2.78 KB

Thanks a lot for reporting this problem, and already investigating thoroughly!
Trying this myself, I can indeed reproduce the problem: creating a new view based on a search index results in an uncaught exception.

Seems we introduced this problem in #2826822: The "text" plugin does not exist., by changing the property type of the "Rendered item" field added by the processor of the same name. The problem is that our Views integration code treats everything with field_item: prefix as an entity field, without checking further. While we could arguably "just" change the "Rendered item" type back and solve the original problem in some other way, I think the better (more future-proof) solution is to check whether a Search API field is actually based on an entity field before assigning the entity field-specific field handler.

Patch attached, please test/review!
It changes the value passed in hook_search_api_views_field_handler_mapping_alter() slightly, so people implementing that hook would need to update it, but otherwise this should be fine and seems to fix the problem exactly (when I compare search_api_views_data() output before and after the patch). It also adds the correct sanitization for the field as a by-product.

replicaobscura’s picture

Confirmed that the patch does fix the exception I was getting. I created a new index with the first field added being Rendered HTML Output, and creating a view from that works fine.

However, whenever the "Rendered HTML output" field is actually in the view (which it is by default), I can't preview the results as I get an AJAX error. It is:

An AJAX HTTP error occurred.
HTTP Result Code: 500
Debugging information follows.
Path: /admin/structure/views/view/test/preview/default
StatusText: Internal Server Error
ResponseText: {"message":"A fatal error occurred: The \u0022field_item:text_long.string\u0022 plugin does not exist."}"

Should that be a separate issue or is that related?

drunken monkey’s picture

That's related enough, I'd say. And a bit of a problem, I'd say – it seems we have no real way of specifying a processor-added property as "fulltext" content by default. All the mappings we currently have use a parent/child type combination, which we use internally but can't use for a real data definition (as we see here).

I think this is the proper fix (which we should probably have done right from the start): define our own data type(s) just for this purpose. Once at it, I went all the way and added two: one for normal text and one for HTML, so it's easily possible to differentiate between the two. (As we now do for our Views field data definitions.)

Please test/review! Just applying the patch and clearing the cache should be enough to make a view with a "Rendered item" field work fine.

drunken monkey’s picture

Component: General code » Framework

Status: Needs review » Needs work

The last submitted patch, 7: 2839932-7--rendered_item_views_field_handler.patch, failed testing.

drunken monkey’s picture

Status: Needs work » Needs review
StatusFileSize
new1.22 KB
new8.03 KB
drunken monkey’s picture

Status: Needs review » Needs work

The last submitted patch, 10: 2839932-10--rendered_item_views_field_handler.patch, failed testing.

replicaobscura’s picture

I have not had a chance to test this fully yet, but I was using the last patch without any errors, and I will test this new one ASAP as well. Thanks!

replicaobscura’s picture

Patch isn't applying cleanly for me on the latest search_api dev. Not entirely sure yet, just noticed that composer failed to apply the patch, and I'm starting to investigate why now.

replicaobscura’s picture

StatusFileSize
new7.61 KB

It was just one use line that was the main issue. Here's a re-rolled patch that fixes that I think.

jacktonkin’s picture

Status: Needs work » Needs review

The patch in #15 fixes this issue for me (I have only given cursory manual testing so far). Setting to needs review for testbot.

drunken monkey’s picture

@ bmcclure: Thanks a lot for re-rolling! Don't know what happened there, my patch doesn't apply cleanly to any module version I can find.

borisson_’s picture

Status: Needs review » Needs work
+++ b/src/Plugin/views/field/SearchApiFieldTrait.php
@@ -438,7 +438,8 @@ trait SearchApiFieldTrait {
-                    $typed_data = \Drupal::service('typed_data_manager')
+                    $typed_data = \Drupal::getContainer()
+                      ->get('typed_data_manager')

I don't understand this change. Let's not do this. \Drupal::service and \Drupal::getContainer()->get() suck just as hard. With the first being shorter.

jacktonkin’s picture

Status: Needs work » Needs review
StatusFileSize
new6.82 KB
new833 bytes

This removes the change in SearchApiFieldTrait as per #18.

kevinquillen’s picture

When applying the patch and clearing caches, when I add "Rendered Item" from the index to the view, I get a fatal error:

Drupal\Component\Plugin\Exception\PluginNotFoundException: The "search_api_html" plugin does not exist. in Drupal\Core\Plugin\DefaultPluginManager->doGetDefinition() (line 52 of core/lib/Drupal/Component/Plugin/Discovery/DiscoveryTrait.php).
Drupal\Core\Plugin\DefaultPluginManager->getDefinition('search_api_html') (Line: 78)
Drupal\Core\TypedData\TypedDataManager->createInstance('search_api_html', Array) (Line: 104)
Drupal\Core\TypedData\TypedDataManager->create(Object, Object) (Line: 444)
Drupal\search_api\Plugin\views\field\SearchApiStandard->preRender(Array) (Line: 1490)
Drupal\views\ViewExecutable->render() (Line: 171)
Drupal\views\Plugin\views\display\Page->execute() (Line: 1617)
Drupal\views\ViewExecutable->executeDisplay('results', Array) (Line: 78)
Drupal\views\Element\View::preRenderViewElement(Array)
call_user_func(Array, Array) (Line: 376)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 195)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 226)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 574)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 227)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 117)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object) (Line: 111)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch('kernel.view', Object) (Line: 149)
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)
drunken monkey’s picture

I don't understand this change. Let's not do this. \Drupal::service and \Drupal::getContainer()->get() suck just as hard. With the first being shorter.

And the second leading to correct type hints in PhpStorm. I don't like it either, but I'd rather have type hinting than shorter code. (Should ultimately be fixed in PhpStorm, resp. the Symfony (or Drupal-Symfony bridge?) plugin, of course.)
That being said, the change doesn't really belong into this patch, so I'm fine with skipping it here.

Attached: a tentative try for a test for this. (Interdiff == tests-only.)

@ kevinquillen: That doesn't really seem possible, the patch adds exactly that plugin. Maybe try clearing the caches again? Or maybe you didn't apply the patch properly?

Status: Needs review » Needs work

The last submitted patch, 21: 2839932-21--rendered_item_views_field_handler.patch, failed testing.

drunken monkey’s picture

That didn't get far …

Status: Needs review » Needs work

The last submitted patch, 24: 2839932-24--rendered_item_views_field_handler.patch, failed testing.

drunken monkey’s picture

Status: Needs review » Needs work

The last submitted patch, 27: 2839932-27--rendered_item_views_field_handler.patch, failed testing.

criscom’s picture

Hallo Thomas,

I successfully applied your pacth in #27. Issue resolved for me.

Thanks!

Chris

flebrenn’s picture

Hello,

I applied #27 patch (2839932-27--rendered_item_views_field_handler.patch). This patch fix my issue.

Thanks,

veronicaseveryn’s picture

@drunken monkey,

Did I miss anything or everyone's else set up is somewhat different?

#27 patch (2839932-27--rendered_item_views_field_handler.patch) does work for me to some point (though it doesn't apply cleanly on Search API 8.x-1.0-beta4, I adjusted it).

With the patch applied I was able to index successfully the FULL HTML output of the whole entity. I can see when the search is run, it returns the full output (with all of the markup - divs, comments, other elements - produced by Twig file) - SUCCESS !! .

The issue I am seeing, is when I try to display the RENDERED field in the View (Search API based view), because the value of the field is sanitized in class SearchApiStandard render_item() function, all of the markup of this HTML output is stripped by XSS filter (only tags remain in my case, if any.

  public function render_item($count, $item) {
    $type = !empty($this->definition['filter_type']) ? $this->definition['filter_type'] : 'plain';
      return $this->sanitizeValue($item['value'], $type);
  }

All divs, spans, article tags and others are gone).

If I skip sanitization in class SearchApiStandard render_item() function and change it to this:

  public function render_item($count, $item) {
    $type = !empty($this->definition['filter_type']) ? $this->definition['filter_type'] : 'plain';
    if ($this->realField == 'rendered_item') {
      return ViewsRenderPipelineMarkup::create($item['value']);
    }
    else {
      return $this->sanitizeValue($item['value'], $type);
    }
  }

it will print all of the markup as it should, with all of the data correctly. Otherwise - it's pretty much blank value.

Did anyone else see this issue ?

vierlex’s picture

@veronicaSeveryn

Yes you are right, i had the same problem.

This patch is only for getting the correct theme for the entity to be rendered in while indexing.

The escaping of the html when displaying this field in a view is actually intentional.
It is discussed here:
https://www.drupal.org/node/2742027

In my case, I looks a bit different, but does the same.
With this I avoided modyfing the search_api module code directly.

// Somewhere in some Module..
function ao_utility_search_api_views_field_handler_mapping_alter(array &$mapping) {
  // Dont filter the HTML for our HTML fields, we need to display them like that.
  if ( !empty($mapping['search_api_html']) ) {
    $mapping['search_api_html']['id'] = 'search_api_my_html';
  }
}

and under [your_module]/src/Plugin/view/field
SearchApiMyHtml.php


namespace Drupal\search_api\Plugin\views\field;
namespace Drupal\ao_quicksearch\Plugin\views\field;

use Drupal\views\Plugin\views\field\FieldPluginBase;
use Drupal\views\Plugin\views\field\MultiItemsFieldHandlerInterface;
use Drupal\search_api\Plugin\views\field\SearchApiFieldTrait;

/**
 * Provides a default handler for fields in Search API Views.
 *
 * @ingroup views_field_handlers
 *
 * @ViewsField("search_api_my_html")
 */
class SearchApiMyHtml extends FieldPluginBase implements MultiItemsFieldHandlerInterface {

  use SearchApiFieldTrait;

  /**
   * {@inheritdoc}
   */
  public function render_item($count, $item) {
    return check_markup($item['value'], 'full_html');
  }

}

You probably can use your render_item Code here too :)

veronicaseveryn’s picture

Thanks @vierlex, good tip !

drunken monkey’s picture

Good to hear it works, thanks a lot for testing, everyone! And sorry for the long delay!
The attached should/might fix the tests, otherwise I need to investigate more. Would probably nice to get this in before RC.

Status: Needs review » Needs work

The last submitted patch, 35: 2839932-35--rendered_item_views_field_handler.patch, failed testing.

drunken monkey’s picture

Status: Needs work » Needs review
StatusFileSize
new1.78 KB
new10.58 KB

Wow, did that really just get set back to "Needs work" because of coding standards problems? Awesome! (Could be communicated a bit more clearly, but still.)
This patch would fix those (though, I think, none of them was introduced by this patch), let's see if that helps.

borisson_’s picture

Status: Needs review » Reviewed & tested by the community

Looks good.

  • drunken monkey committed c8faf2b on 8.x-1.x
    Issue #2839932 by drunken monkey,  borisson_, bmcclure, jacktonkin:...
drunken monkey’s picture

Status: Reviewed & tested by the community » Fixed

Great, thanks for reviewing!
Committed.
Thanks again to everyone here!

Status: Fixed » Closed (fixed)

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