Code Coverage
 
Lines
Branches
Paths
Functions and Methods
Classes and Traits
Total
85.71% covered (warning)
85.71%
12 / 14
81.82% covered (warning)
81.82%
9 / 11
50.00% covered (danger)
50.00%
4 / 8
33.33% covered (danger)
33.33%
1 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
InstanceAccessControlHandler
85.71% covered (warning)
85.71%
12 / 14
81.82% covered (warning)
81.82%
9 / 11
50.00% covered (danger)
50.00%
4 / 8
33.33% covered (danger)
33.33%
1 / 3
13.12
0.00% covered (danger)
0.00%
0 / 1
 checkAccess
80.00% covered (warning)
80.00%
4 / 5
66.67% covered (warning)
66.67%
2 / 3
50.00% covered (danger)
50.00%
1 / 2
0.00% covered (danger)
0.00%
0 / 1
2.50
 checkProfileAccess
66.67% covered (warning)
66.67%
2 / 3
66.67% covered (warning)
66.67%
2 / 3
50.00% covered (danger)
50.00%
1 / 2
0.00% covered (danger)
0.00%
0 / 1
2.50
 checkBuildableAccess
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
5 / 5
50.00% covered (danger)
50.00%
2 / 4
100.00% covered (success)
100.00%
1 / 1
4.12
1<?php
2
3declare(strict_types=1);
4
5namespace Drupal\display_builder;
6
7use Drupal\Core\Access\AccessResult;
8use Drupal\Core\Access\AccessResultInterface;
9use Drupal\Core\Entity\EntityAccessControlHandler;
10use Drupal\Core\Entity\EntityInterface;
11use Drupal\Core\Session\AccountInterface;
12
13/**
14 * Defines the access control handler for the instance entity type.
15 */
16final class InstanceAccessControlHandler extends EntityAccessControlHandler {
17
18  /**
19   * {@inheritdoc}
20   */
21  protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account): AccessResultInterface {
22    // dump(get_class($entity));
23    /** @var \Drupal\display_builder\InstanceInterface $entity */
24    // 1. Profile-related access.
25    $profile_result = $this->checkProfileAccess($entity, $account);
26
27    if ($profile_result->isForbidden()) {
28      return $profile_result;
29    }
30    // 2. Access to DisplayBuildableInterface implementation.
31    $buildable_result = $this->checkBuildableAccess($entity, $account);
32
33    return $profile_result->andIf($buildable_result);
34  }
35
36  /**
37   * Checks permission to use the profile.
38   *
39   * @param \Drupal\display_builder\InstanceInterface $instance
40   *   The entity for which to check access.
41   * @param \Drupal\Core\Session\AccountInterface $account
42   *   The user session for which to check access.
43   *
44   * @return \Drupal\Core\Access\AccessResultInterface
45   *   The access result.
46   */
47  private function checkProfileAccess(InstanceInterface $instance, AccountInterface $account): AccessResultInterface {
48    if ($profile = $instance->getProfile()) {
49      return $profile->access('view', $account, TRUE);
50    }
51
52    // If the profile does not exist, forbid access to this instance.
53    return AccessResult::forbidden('Invalid profileId on display_builder_instance.');
54  }
55
56  /**
57   * Checks access based on instance prefix/type.
58   *
59   * @param \Drupal\display_builder\InstanceInterface $instance
60   *   The entity for which to check access.
61   * @param \Drupal\Core\Session\AccountInterface $account
62   *   The user session for which to check access.
63   *
64   * @return \Drupal\Core\Access\AccessResultInterface
65   *   The access result.
66   */
67  private function checkBuildableAccess(InstanceInterface $instance, AccountInterface $account): AccessResultInterface {
68    $instance_id = (string) $instance->id();
69    // "Providers" are implementations of
70    // \Drupal\display_builder\DisplayBuildableInterface.
71    $providers = $this->moduleHandler->invokeAll('display_builder_provider_info');
72
73    foreach ($providers as $provider) {
74      if (\str_starts_with($instance_id, $provider['prefix'])) {
75        return $provider['class']::checkAccess($instance_id, $account);
76      }
77    }
78
79    // If an instance is not managed by a provider (for example: a demo or a
80    // test), we allow.
81    return AccessResult::allowed();
82  }
83
84}