How to programmatically fetch the results of a view with facet filtering Setup


Drupal 8.2 + Views + Facets
View articles …


… with first sub-view page_1
… has facets

View filter: field_title
View facet: field_facet allows multiple values, e.g. A and B


Concept

I would like to fetch the view results programmatically by reusing the $_GET query values. (The $_GET values are serialized and stored for later usage.)

Problem

The results are correct when working with only non-facet filters. Facet filter values are ignored and won't be filtering the results by the provided snippet.

Is the View working as expected?

Yes, the view is working as expected: Filtering works when visiting the website with a HTTP client and the query ?field_title=Hello&amp;field_facet[0]=A&amp;field_facet[1]=B.

Snippet

&lt;?php

use Drupal\views\Views;

$view = Views::getView('articles');

$query = [
    // Filters results with title `Hello` as expected.
    'field_title' =&gt; 'Hello',

    // The programatically executed View ignores
    // the following facet based values for filtering.
    'field_facet' =&gt; ['A', 'B'],
];

$view-&gt;setExposedInput($query);

// bool(true)
var_dump($view-&gt;execute('page_1'));

$result = [];

/** @var Drupal\views\ResultRow $row */
foreach ($view-&gt;result as $row) {
    /** @var Drupal\search_api\Item\Item $item */
    $item = $row-&gt;_item;

    /** @var Drupal\node\Entity\Node $node */
    $node = $item-&gt;getOriginalObject()-&gt;getValue();

    $result[] = [
        'nid' =&gt; $node-&gt;id(),
        'title ($item)' =&gt; $item-&gt;getField('title')-&gt;getValues()[0],
        'title ($node)' =&gt; $node-&gt;get('title')-&gt;getValue(),
    ];
}


Experiments with the REST module

The REST module allows to create views with JSON results.
Sadly, this module is also ignoring facet based filters.

Question

How do I inject/attach the facets to use their filters?
Kinda old question but i just needed the same thing and here is how i did it.

use Drupal\views\Views;
use Symfony\Component\HttpFoundation\Request;


$view_id = 'VIEWID';
$display_id = 'rest_export_1';
$filters = [
  // Filters results with title `Hello` as expected.
  'field_title' =&gt; 'Hello',

  // The programatically executed View ignores
  // the following facet based values for filtering.
  'field_facet' =&gt; ['A', 'B'],
];

$view = Views::getView($view_id);
$view-&gt;setDisplay($display_id);

// Here comes the part that did the trick for my REST JSON request.
// Create a new request with your filters / url query and set that.
$request = new Request($filters);
$view-&gt;setRequest($request);

$view-&gt;execute();

//TMP debug the json decoded value
$view_result = \Drupal::service('renderer')-&gt;renderRoot($view-&gt;render());
$view_json_decode = json_decode($view_result);


The rest export view puts the exposed filter inside the view request so instead of setting the exposedfilters i made a request with the query args and it worked fine.

The documentation is missing a lot so if anyone finds a better way then let me know.