Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
| Total | |
0.00% |
0 / 1 |
|
66.67% |
4 / 6 |
CRAP | |
90.24% |
37 / 41 |
| CheckProvider | |
0.00% |
0 / 1 |
|
66.67% |
4 / 6 |
23.49 | |
90.24% |
37 / 41 |
| addCheckService | |
0.00% |
0 / 1 |
3.03 | |
85.71% |
6 / 7 |
|||
| getChecksNeedRequest | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
| setChecks | |
100.00% |
1 / 1 |
3 | |
100.00% |
5 / 5 |
|||
| loadCheck | |
0.00% |
0 / 1 |
5.68 | |
70.00% |
7 / 10 |
|||
| applies | |
100.00% |
1 / 1 |
6 | |
100.00% |
9 / 9 |
|||
| loadDynamicRequirementMap | |
100.00% |
1 / 1 |
5 | |
100.00% |
9 / 9 |
|||
| <?php | |
| /** | |
| * @file | |
| * Contains \Drupal\Core\Access\CheckProvider. | |
| */ | |
| namespace Drupal\Core\Access; | |
| use Drupal\Core\Routing\Access\AccessInterface; | |
| use Symfony\Component\DependencyInjection\ContainerAware; | |
| use Symfony\Component\Routing\Route; | |
| use Symfony\Component\Routing\RouteCollection; | |
| /** | |
| * Loads access checkers from the container. | |
| */ | |
| class CheckProvider extends ContainerAware implements CheckProviderInterface { | |
| /** | |
| * Array of registered access check service ids. | |
| * | |
| * @var array | |
| */ | |
| protected $checkIds = array(); | |
| /** | |
| * Array of access check objects keyed by service id. | |
| * | |
| * @var \Drupal\Core\Routing\Access\AccessInterface[] | |
| */ | |
| protected $checks; | |
| /** | |
| * Array of access check method names keyed by service ID. | |
| * | |
| * @var array | |
| */ | |
| protected $checkMethods = array(); | |
| /** | |
| * Array of access checks which only will be run on the incoming request. | |
| */ | |
| protected $checksNeedsRequest = array(); | |
| /** | |
| * An array to map static requirement keys to service IDs. | |
| * | |
| * @var array | |
| */ | |
| protected $staticRequirementMap; | |
| /** | |
| * An array to map dynamic requirement keys to service IDs. | |
| * | |
| * @var array | |
| */ | |
| protected $dynamicRequirementMap; | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public function addCheckService($service_id, $service_method, array $applies_checks = array(), $needs_incoming_request = FALSE) { | |
| $this->checkIds[] = $service_id; | |
| $this->checkMethods[$service_id] = $service_method; | |
| if ($needs_incoming_request) { | |
| $this->checksNeedsRequest[$service_id] = $service_id; | |
| } | |
| foreach ($applies_checks as $applies_check) { | |
| $this->staticRequirementMap[$applies_check][] = $service_id; | |
| } | |
| } | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public function getChecksNeedRequest() { | |
| return $this->checksNeedsRequest; | |
| } | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public function setChecks(RouteCollection $routes) { | |
| $this->loadDynamicRequirementMap(); | |
| foreach ($routes as $route) { | |
| if ($checks = $this->applies($route)) { | |
| $route->setOption('_access_checks', $checks); | |
| } | |
| } | |
| } | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public function loadCheck($service_id) { | |
| if (empty($this->checks[$service_id])) { | |
| if (!in_array($service_id, $this->checkIds)) { | |
| throw new \InvalidArgumentException(sprintf('No check has been registered for %s', $service_id)); | |
| } | |
| $check = $this->container->get($service_id); | |
| if (!($check instanceof AccessInterface)) { | |
| throw new AccessException('All access checks must implement AccessInterface.'); | |
| } | |
| if (!is_callable(array($check, $this->checkMethods[$service_id]))) { | |
| throw new AccessException(sprintf('Access check method %s in service %s must be callable.', $this->checkMethods[$service_id], $service_id)); | |
| } | |
| $this->checks[$service_id] = $check; | |
| } | |
| return [$this->checks[$service_id], $this->checkMethods[$service_id]]; | |
| } | |
| /** | |
| * Determine which registered access checks apply to a route. | |
| * | |
| * @param \Symfony\Component\Routing\Route $route | |
| * The route to get list of access checks for. | |
| * | |
| * @return array | |
| * An array of service ids for the access checks that apply to passed | |
| * route. | |
| */ | |
| protected function applies(Route $route) { | |
| $checks = array(); | |
| // Iterate through map requirements from appliesTo() on access checkers. | |
| // Only iterate through all checkIds if this is not used. | |
| foreach ($route->getRequirements() as $key => $value) { | |
| if (isset($this->staticRequirementMap[$key])) { | |
| foreach ($this->staticRequirementMap[$key] as $service_id) { | |
| $checks[] = $service_id; | |
| } | |
| } | |
| } | |
| // Finally, see if any dynamic access checkers apply. | |
| foreach ($this->dynamicRequirementMap as $service_id) { | |
| if ($this->checks[$service_id]->applies($route)) { | |
| $checks[] = $service_id; | |
| } | |
| } | |
| return $checks; | |
| } | |
| /** | |
| * Compiles a mapping of requirement keys to access checker service IDs. | |
| */ | |
| protected function loadDynamicRequirementMap() { | |
| if (isset($this->dynamicRequirementMap)) { | |
| return; | |
| } | |
| // Set them here, so we can use the isset() check above. | |
| $this->dynamicRequirementMap = array(); | |
| foreach ($this->checkIds as $service_id) { | |
| if (empty($this->checks[$service_id])) { | |
| $this->loadCheck($service_id); | |
| } | |
| // Add the service ID to an array that will be iterated over. | |
| if ($this->checks[$service_id] instanceof AccessCheckInterface) { | |
| $this->dynamicRequirementMap[] = $service_id; | |
| } | |
| } | |
| } | |
| } |