Code Coverage
 
Lines
Branches
Paths
Functions and Methods
Classes and Traits
Total
89.47% covered (warning)
89.47%
17 / 19
85.71% covered (warning)
85.71%
12 / 14
60.00% covered (warning)
60.00%
6 / 10
60.00% covered (warning)
60.00%
3 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
InstanceAccessControlHandler
89.47% covered (warning)
89.47%
17 / 19
85.71% covered (warning)
85.71%
12 / 14
60.00% covered (warning)
60.00%
6 / 10
60.00% covered (warning)
60.00%
3 / 5
14.18
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 createInstance
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
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%
6 / 6
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\EntityHandlerInterface;
11use Drupal\Core\Entity\EntityInterface;
12use Drupal\Core\Entity\EntityTypeInterface;
13use Drupal\Core\Session\AccountInterface;
14use Symfony\Component\DependencyInjection\ContainerInterface;
15
16/**
17 * Defines the access control handler for the instance entity type.
18 */
19final class InstanceAccessControlHandler extends EntityAccessControlHandler implements EntityHandlerInterface {
20
21  /**
22   * {@inheritdoc}
23   */
24  public function __construct(
25    EntityTypeInterface $entity_type,
26    protected readonly DisplayBuildablePluginManager $displayBuildableManager,
27  ) {
28    parent::__construct($entity_type);
29  }
30
31  /**
32   * {@inheritdoc}
33   */
34  public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type): static {
35    return new self(
36      $entity_type,
37      $container->get('plugin.manager.display_buildable'),
38    );
39  }
40
41  /**
42   * {@inheritdoc}
43   */
44  protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account): AccessResultInterface {
45    /** @var \Drupal\display_builder\InstanceInterface $entity */
46    // 1. Profile-related access.
47    $profile_result = $this->checkProfileAccess($entity, $account);
48
49    if ($profile_result->isForbidden()) {
50      return $profile_result;
51    }
52    // 2. Access to DisplayBuildableInterface implementation.
53    $buildable_result = $this->checkBuildableAccess($entity, $account);
54
55    return $profile_result->andIf($buildable_result);
56  }
57
58  /**
59   * Checks permission to use the profile.
60   *
61   * @param \Drupal\display_builder\InstanceInterface $instance
62   *   The entity for which to check access.
63   * @param \Drupal\Core\Session\AccountInterface $account
64   *   The user session for which to check access.
65   *
66   * @return \Drupal\Core\Access\AccessResultInterface
67   *   The access result.
68   */
69  private function checkProfileAccess(InstanceInterface $instance, AccountInterface $account): AccessResultInterface {
70    if ($profile = $instance->getProfile()) {
71      return $profile->access('view', $account, TRUE);
72    }
73
74    // If the profile does not exist, forbid access to this instance.
75    return AccessResult::forbidden('Invalid profileId on display_builder_instance.');
76  }
77
78  /**
79   * Checks access based on instance prefix/type.
80   *
81   * @param \Drupal\display_builder\InstanceInterface $instance
82   *   The entity for which to check access.
83   * @param \Drupal\Core\Session\AccountInterface $account
84   *   The user session for which to check access.
85   *
86   * @return \Drupal\Core\Access\AccessResultInterface
87   *   The access result.
88   */
89  private function checkBuildableAccess(InstanceInterface $instance, AccountInterface $account): AccessResultInterface {
90    $instance_id = (string) $instance->id();
91    $providers = $this->displayBuildableManager->getDefinitions();
92
93    foreach ($providers as $provider) {
94      if (\str_starts_with($instance_id, $provider['instance_prefix'])) {
95        return $provider['class']::checkAccess($instance_id, $account);
96      }
97    }
98
99    // If an instance is not managed by a provider (for example: a demo or a
100    // test), we allow.
101    return AccessResult::allowed();
102  }
103
104}

Branches

Below are the source code lines that represent each code branch as identified by Xdebug. Please note a branch is not necessarily coterminous with a line, a line may contain multiple branches and therefore show up more than once. Please also be aware that some branches may be implicit rather than explicit, e.g. an if statement always has an else as part of its logical flow even if you didn't write one.

InstanceAccessControlHandler->__construct
25    EntityTypeInterface $entity_type,
26    protected readonly DisplayBuildablePluginManager $displayBuildableManager,
27  ) {
28    parent::__construct($entity_type);
29  }
InstanceAccessControlHandler->checkAccess
44  protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account): AccessResultInterface {
45    /** @var \Drupal\display_builder\InstanceInterface $entity */
46    // 1. Profile-related access.
47    $profile_result = $this->checkProfileAccess($entity, $account);
48
49    if ($profile_result->isForbidden()) {
50      return $profile_result;
53    $buildable_result = $this->checkBuildableAccess($entity, $account);
54
55    return $profile_result->andIf($buildable_result);
56  }
InstanceAccessControlHandler->checkBuildableAccess
89  private function checkBuildableAccess(InstanceInterface $instance, AccountInterface $account): AccessResultInterface {
90    $instance_id = (string) $instance->id();
91    $providers = $this->displayBuildableManager->getDefinitions();
92
93    foreach ($providers as $provider) {
93    foreach ($providers as $provider) {
94      if (\str_starts_with($instance_id, $provider['instance_prefix'])) {
95        return $provider['class']::checkAccess($instance_id, $account);
93    foreach ($providers as $provider) {
93    foreach ($providers as $provider) {
94      if (\str_starts_with($instance_id, $provider['instance_prefix'])) {
95        return $provider['class']::checkAccess($instance_id, $account);
96      }
97    }
98
99    // If an instance is not managed by a provider (for example: a demo or a
100    // test), we allow.
101    return AccessResult::allowed();
102  }
InstanceAccessControlHandler->checkProfileAccess
69  private function checkProfileAccess(InstanceInterface $instance, AccountInterface $account): AccessResultInterface {
70    if ($profile = $instance->getProfile()) {
71      return $profile->access('view', $account, TRUE);
75    return AccessResult::forbidden('Invalid profileId on display_builder_instance.');
76  }
InstanceAccessControlHandler->createInstance
34  public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type): static {
35    return new self(
36      $entity_type,
37      $container->get('plugin.manager.display_buildable'),
38    );
39  }