How do I filter a view by the results of hook_node_access? I have been trying to wrap my head around a specific problem for a few days now and have been unable to find a solution. Here's my problem:

In my LMS I'm performing pretty complex access checks. (In particular, I need to check permissions over references: A lesson should be accessible, if it's part of some course that's marked accessible for that specific user.) I have already written a module implementing hook_node_access and, so far, everything is working fine. Here's part of the code:

function mymodule_node_access(\Drupal\node\NodeInterface $node, $op, \Drupal\Core\Session\AccountInterface $account){
  $type = $node-&gt;bundle();
  $user = $account-&gt;getAccount();
  $uid = $user-&gt;id();

  // only handle the lesson content type
  if ($type === 'lesson') {

    if ($account-&gt;id() !== 1) {

      // first, check the user's access to the lesson itself
      $lessonaccess = ...

      // then, check the user's access to the referring courses
      $courseaccess = FALSE;
      if ($node-&gt;hasField('reverse_entity_reference')) {
        $parentcourses = $node-&gt;get('reverse_entity_reference')-&gt;getValue();

        foreach ($parentcourses as $course) {
          $coursenode = \Drupal\node\Entity\Node::load($course['target_id']);
          // perform access checks for the referring course
          $courseaccess = $courseaccess || ...
        }
      }

      // combine the results; teasers should always be accessible
      if ($lessonisteaser || ($lessonaccess &amp;&amp; $courseaccess)) {
        return AccessResult::allowed();
      } else {
        return AccessResult::forbidden();
      }
    }
  }

  else {
    return AccessResult::neutral();
  }
}


The problem is that I would now like to create a view listing all lessons that are accessible to the current user. So, simply filtering by node access -- as is straightforward to achieve in Views -- is not sufficient, as I need to filter by what is returned from the access checks in hook_node_access.

Can anybody think of a way to make that possible? Maybe storing the result somewhere?
The problem here is that hook_node_access is a PHP function that has nodes passed through it, but Views is doing a database query for the relevant nodes. These two are incompatible, as Views would have to fetch every node in the system from the DB, then pass them all through that function, which would add major overhead.

Drupal's solution to this is the node grants system, which writes a set of grants to the {node_access} table, which can then be used in querying nodes.

To implement a grants system, you'll need to implement hook_node_access_records(), which is called when each node is saved, and sets up a number of rules by which the node being save is allowed to be accessed. Then you implement hook_node_grants(), which generates a set of potential grants for the current user, and tries to match them with the grants created in hook_node_access_records(). When there is a match, the user is granted permission to access, and this will work with DB queries.