Repository URL to install this package:
|
Version:
1.23.0 ▾
|
<?php
namespace Drupal\custom_forms\Access;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Routing\Access\AccessInterface;
use Drupal\custom_forms\CustomFormInterface;
use Symfony\Component\Routing\Route;
/**
* Class CustomFormRevisionAccessCheck
*
* @package Drupal\custom_forms\Access
*/
class CustomFormRevisionAccessCheck implements AccessInterface {
/**
* The sql content entity storage.
*
* @var \Drupal\Core\Entity\Sql\SqlContentEntityStorage
*/
protected $sqlContentEntityStorage;
/**
* The custom form access control handler.
*
* @var \Drupal\custom_forms\CustomFormAccessControlHandler
*/
protected $formAccess;
/**
* A static cache of access checks.
*
* @var array
*/
protected $access = [];
/**
* Constructs a new CustomFormRevisionAccessCheck.
*
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
*/
public function __construct(EntityTypeManagerInterface $entity_type_manager) {
$this->sqlContentEntityStorage = $entity_type_manager->getStorage('custom_form');
$this->formAccess = $entity_type_manager->getAccessControlHandler('custom_form');
}
/**
* Checks routing access for the custom form revision.
*
* @param \Symfony\Component\Routing\Route $route
* The route to check against.
* @param \Drupal\Core\Session\AccountInterface $account
* The currently logged in account.
* @param int $custom_form_revision
* (optional) The custom form revision ID. If not specified, but $custom_form is, access
* is checked for that object's revision.
* @param \Drupal\custom_forms\CustomFormInterface $custom_form
* (optional) A custom form object. Used for checking access to a custom form's default
* revision when $custom_form_revision is unspecified. Ignored when $custom_form_revision
* is specified. If neither $custom_form_revision nor $custom_form are specified, then
* access is denied.
*
* @return \Drupal\Core\Access\AccessResultInterface
* The access result.
*/
public function access(Route $route, AccountInterface $account, $custom_form_revision = NULL, CustomFormInterface $custom_form = NULL) {
if ($custom_form_revision) {
$custom_form = $this->sqlContentEntityStorage->loadRevision($custom_form_revision);
}
$operation = $route->getRequirement('_access_custom_form_revision');
return AccessResult::allowedIf($custom_form && $this->checkAccess($custom_form, $account, $operation))->cachePerPermissions()->addCacheableDependency($custom_form);
}
/**
* Checks custom form revision access.
*
* @param \Drupal\custom_forms\CustomFormInterface $custom_form
* The custom form to check.
* @param \Drupal\Core\Session\AccountInterface $account
* A user object representing the user for whom the operation is to be
* performed.
* @param string $op
* (optional) The specific operation being checked. Defaults to 'view.'
*
* @return bool
* TRUE if the operation may be performed, FALSE otherwise.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
*/
public function checkAccess(CustomFormInterface $custom_form, AccountInterface $account, $op = 'view') {
$map = [
'view' => 'view all revisions',
'update' => 'revert all revisions',
'delete' => 'delete all revisions',
];
$bundle = $custom_form->bundle();
$type_map = [
'view' => "view $bundle revisions",
'update' => "revert $bundle revisions",
'delete' => "delete $bundle revisions",
];
if (!$custom_form || !isset($map[$op]) || !isset($type_map[$op])) {
// If there was no custom form to check against, or the $op was not one of the
// supported ones, we return access denied.
return FALSE;
}
// Statically cache access by revision ID, language code, user account ID,
// and operation.
$langcode = $custom_form->language()->getId();
$cid = $custom_form->getRevisionId() . ':' . $langcode . ':' . $account->id() . ':' . $op;
if (!isset($this->access[$cid])) {
// Perform basic permission checks first.
if (!$account->hasPermission($map[$op]) && !$account->hasPermission($type_map[$op]) && !$account->hasPermission('administer custom forms')) {
$this->access[$cid] = FALSE;
return FALSE;
}
// If the revisions checkbox is selected for the content type, display the
// revisions tab.
$bundle_entity_type = $custom_form->getEntityType()->getBundleEntityType();
/** @var \Drupal\custom_forms\Entity\CustomFormType $bundle_entity */
$bundle_entity = \Drupal::entityTypeManager()->getStorage($bundle_entity_type)->load($bundle);
if ($bundle_entity->shouldCreateNewRevision() && $op === 'view') {
$this->access[$cid] = TRUE;
}
else {
// There should be at least two revisions. If the vid of the given custom form
// and the vid of the default revision differ, then we already have two
// different revisions so there is no need for a separate database
// check. Also, if you try to revert to or delete the default revision,
// that's not good.
if ($custom_form->isDefaultRevision() && ($this->sqlContentEntityStorage->countDefaultLanguageRevisions($custom_form) == 1 || $op === 'update' || $op === 'delete')) {
$this->access[$cid] = FALSE;
}
elseif ($account->hasPermission('administer custom forms')) {
$this->access[$cid] = TRUE;
}
else {
// First check the access to the default revision and finally, if the
// custom form passed in is not the default revision then check access to
// that, too.
$this->access[$cid] = $this->formAccess->access($this->sqlContentEntityStorage->load($custom_form->id()), $op, $account) && ($custom_form->isDefaultRevision() || $this->formAccess->access($custom_form, $op, $account));
}
}
}
return $this->access[$cid];
}
}