Paragraphs Editor
ContextAccessCheck.php
Go to the documentation of this file.
1 <?php
2 
4 
11 
12 /**
13  * An access check handler for checking user access to an editor context.
14  */
15 class ContextAccessCheck implements AccessInterface {
16 
17  /**
18  * The Drupal entity type manager.
19  *
20  * @var \Drupal\Core\Entity\EntityTypeManagerInterface
21  */
22  protected $entityTypeManager;
23 
24  /**
25  * The key used by the routing requirement.
26  *
27  * @var string
28  */
29  protected $requirementsKey = '_paragraphs_editor_access_context';
30 
31  /**
32  * Creates a context access check object.
33  *
34  * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
35  * The entity type manager service.
36  */
37  public function __construct(EntityTypeManagerInterface $entity_type_manager) {
38  $this->entityTypeManager = $entity_type_manager;
39  }
40 
41  /**
42  * Determines if the user has access to manipulate the requested entity.
43  *
44  * In order to perform any command on an editor instance, the user must have
45  * access to edit the entity the instance is attached to, or for new entities,
46  * the user must have access to create entities.
47  *
48  * This method will also filter out "invalid" context objects before the
49  * actual controller method that executes the request is called.
50  *
51  * @param \Symfony\Component\Routing\Route $route
52  * The route the user is attempting to access.
53  * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
54  * The route match for the route the user is attempting to access.
55  * @param \Drupal\Core\Session\AccountInterface $account
56  * The account to check access against.
57  *
58  * @return \Drupal\Core\Access\AccessResultInterface
59  * The access result for the user.
60  */
61  public function access(Route $route, RouteMatchInterface $route_match, AccountInterface $account) {
62  // Load the context from the parameters.
63  $requirement = $route->getRequirement($this->requirementsKey);
64  $ands = explode('+', $requirement);
65  $chain = [];
66  foreach ($ands as $requirement) {
67  $context = static::extractContext($route_match, $requirement);
68  if (empty($context)) {
69  return AccessResult::forbidden();
70  }
71 
72  // If no field config could be loaded for the context, we treat this as
73  // the user not being able to access the endpoint.
74  $field_config = $context->getFieldConfig();
75  if ($field_config) {
76  $entity_type = $field_config->getTargetEntityTypeId();
77  $entity_bundle = $field_config->getTargetBundle();
78  $entity = $context->getEntity();
79 
80  // If the operation pertains to an existing entity, the user must have
81  // edit access to perform editor commands. If it is a new entity, the
82  // user must have create access.
83  if ($entity) {
84  $chain[] = $entity->access('edit', $account, TRUE);
85  }
86  else {
87  $chain[] = $this->entityTypeManager->getAccessControlHandler($entity_type)
88  ->createAccess($entity_bundle, $account, [], TRUE);
89  }
90  }
91  else {
92  return AccessResult::forbidden();
93  }
94  }
95 
96  if (!empty($chain)) {
97  $access = AccessResult::allowed();
98  foreach ($chain as $next_access) {
99  $access = $access->andIf($next_access);
100  }
101  }
102  else {
103  $access = AccessResult::neutral();
104  }
105 
106  return $access;
107  }
108 
109  /**
110  * Extracts the context from a route match, given a requirement.
111  *
112  * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
113  * The route match for the route the user is attempting to access.
114  * @param string $requirement
115  * The requirement string to get the parameter name from.
116  *
117  * @return \Drupal\paragraphs_editor\EditorCommand\CommandContextInterface|null
118  * The extracted context id or NULL if none could be extracted.
119  */
120  public static function extractContext(RouteMatchInterface $route_match, $requirement) {
121  if (preg_match('/\{(.*)\}$/', $requirement, $matches)) {
122  return $route_match->getParameter($matches[1]);
123  }
124  else {
125  return NULL;
126  }
127  }
128 
129 }
__construct(EntityTypeManagerInterface $entity_type_manager)
static extractContext(RouteMatchInterface $route_match, $requirement)
access(Route $route, RouteMatchInterface $route_match, AccountInterface $account)