Skip to content
Snippets Groups Projects
Commit 764fb436 authored by dpi's avatar dpi
Browse files

Enable administrators to prevent rule customisation.

Fixed #72
parent fe058228
No related branches found
No related tags found
No related merge requests found
......@@ -38,6 +38,9 @@ rng.event_type.*.*:
mirror_operation_to_event_manage:
type: string
label: 'Mirrors another operation grant from the event to event manage.'
custom_rules:
type: boolean
label: 'Allow event managers to customise default rules.'
condition.plugin.rng_user_role:
......
......@@ -25,6 +25,11 @@ services:
arguments: ['@rng.event_manager']
tags:
- { name: access_check, applies_to: _entity_is_event }
access_check.rng.event_rule_reset:
class: Drupal\rng\Access\EventRuleResetCheck
arguments: ['@rng.event_manager']
tags:
- { name: access_check, applies_to: _event_rule_reset }
access_check.rng.event_registrations_allowed:
class: Drupal\rng\Access\RegistrationAddAccessCheck
arguments: ['@entity.manager']
......
......@@ -44,7 +44,14 @@ class EntityIsEventCheck implements AccessInterface {
if ($event = $route->getDefault('event')) {
$event = $route_match->getParameter($event);
if ($event instanceof EntityInterface) {
return AccessResult::allowedIf($this->eventManager->isEvent($event));
$event_type = $this->eventManager->eventType($event->getEntityTypeId(), $event->bundle());
if ($event_type) {
return AccessResult::allowed()
->addCacheableDependency($event)
->addCacheableDependency($event_type);
}
return AccessResult::neutral()
->addCacheableDependency($event);
}
}
return AccessResult::neutral();
......
<?php
/**
* @file
* Contains \Drupal\rng\Access\EventRuleResetCheck.
*/
namespace Drupal\rng\Access;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Routing\Access\AccessInterface;
use Drupal\rng\EventManagerInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Session\AccountInterface;
use Symfony\Component\Routing\Route;
use Drupal\Core\Entity\EntityInterface;
/**
* Checks that an entity is an event type.
*/
class EventRuleResetCheck implements AccessInterface {
/**
* The RNG event manager.
*
* @var \Drupal\rng\EventManagerInterface
*/
protected $eventManager;
/**
* Constructs a new EntityIsEventCheck object.
*
* @param \Drupal\rng\EventManagerInterface $event_manager
* The RNG event manager.
*/
public function __construct(EventManagerInterface $event_manager) {
$this->eventManager = $event_manager;
}
/**
* Checks that an entity is an event type.
*/
public function access(Route $route, RouteMatchInterface $route_match, AccountInterface $account) {
if ($event = $route->getDefault('event')) {
$event = $route_match->getParameter($event);
if ($event instanceof EntityInterface) {
$event_type = $this->eventManager->eventType($event->getEntityTypeId(), $event->bundle());
if ($event_type) {
if ($event_type->getAllowCustomRules()) {
return AccessResult::allowed()
->addCacheableDependency($event)
->addCacheableDependency($event_type);
}
$event_meta = $this->eventManager->getMeta($event);
// If not default rules, then allow event manager to reset back.
if (!$event_meta->isDefaultRules('rng_event.register')) {
return AccessResult::allowed()
->addCacheableDependency($event)
->addCacheableDependency($event_type);
}
return AccessResult::neutral()
->addCacheableDependency($event)
->addCacheableDependency($event_type);
}
}
return AccessResult::neutral()
->addCacheableDependency($event);
}
return AccessResult::neutral();
}
}
......@@ -87,6 +87,13 @@ class EventType extends ConfigEntityBase implements EventTypeInterface {
*/
public $mirror_operation_to_event_manage;
/**
* Allow event managers to customize default rules.
*
* @var boolean
*/
public $custom_rules = TRUE;
/**
* Fields to add to event bundles.
*
......@@ -146,6 +153,21 @@ class EventType extends ConfigEntityBase implements EventTypeInterface {
return $this;
}
/**
* {@inheritdoc}
*/
function getAllowCustomRules() {
return $this->custom_rules;
}
/**
* {@inheritdoc}
*/
function setAllowCustomRules($allow) {
$this->custom_rules = $allow;
return $this;
}
/**
* {@inheritdoc}
*/
......
......@@ -272,6 +272,10 @@ class EventMeta implements EventMetaInterface {
public function getDefaultRules($trigger = NULL) {
$rules = [];
if ($trigger != 'rng_event.register') {
return $rules;
}
/** @var \Drupal\rng\EventTypeRuleInterface[] $default_rules */
$default_rules = $this
->entityManager
......
......@@ -58,6 +58,25 @@ interface EventTypeInterface extends ConfigEntityInterface {
*/
function setEventManageOperation($permission);
/**
* Whether to allow event managers to customize default rules.
*
* @return boolean
* Whether event managers are allowed to customize default rules.
*/
function getAllowCustomRules();
/**
* Set whether event managers can customize default rules.
*
* @param boolean $allow
* Whether event managers are allowed to customize default rules.
*
* @return $this
* Return this event type for chaining.
*/
function setAllowCustomRules($allow);
/**
* Create or clean up courier_context if none exist for an entity type.
*
......
......@@ -143,11 +143,11 @@ class EventAccessResetForm extends ConfirmFormBase {
foreach ($rules as $rule) {
$rule->delete();
}
drupal_set_message(t('Access rules reset to site defaults.'));
drupal_set_message($this->t('Access rules reset to site defaults.'));
}
else {
$this->eventMeta->addDefaultAccess();
drupal_set_message(t('Access rules can now be customized using edit operations.'));
drupal_set_message($this->t('Access rules can now be customized using edit operations.'));
}
Cache::invalidateTags($this->event->getCacheTagsToInvalidate());
$form_state->setRedirectUrl($this->getCancelUrl());
......
......@@ -11,10 +11,12 @@ use Drupal\Core\Entity\EntityForm;
use Drupal\Core\Routing\RedirectDestinationInterface;
use Drupal\Core\Action\ActionManager;
use Drupal\Core\Condition\ConditionManager;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Form\FormStateInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\rng\EventManagerInterface;
use Drupal\rng\RNGConditionInterface;
use Drupal\Core\Cache\Cache;
/**
* Form for event type access defaults.
......@@ -42,6 +44,13 @@ class EventTypeAccessDefaultsForm extends EntityForm {
*/
protected $conditionManager;
/**
* Event type rule storage.
*
* @var \Drupal\Core\Entity\EntityStorageInterface
*/
protected $eventTypeRuleStorage;
/**
* The RNG event manager.
*
......@@ -65,13 +74,16 @@ class EventTypeAccessDefaultsForm extends EntityForm {
* The action manager.
* @param \Drupal\Core\Condition\ConditionManager $conditionManager
* The condition manager.
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager.
* @param \Drupal\rng\EventManagerInterface $event_manager
* The RNG event manager.
*/
public function __construct(RedirectDestinationInterface $redirect_destination, ActionManager $actionManager, ConditionManager $conditionManager, EventManagerInterface $event_manager) {
public function __construct(RedirectDestinationInterface $redirect_destination, ActionManager $actionManager, ConditionManager $conditionManager, EntityTypeManagerInterface $entity_type_manager, EventManagerInterface $event_manager) {
$this->redirectDestination = $redirect_destination;
$this->actionManager = $actionManager;
$this->conditionManager = $conditionManager;
$this->eventTypeRuleStorage = $entity_type_manager->getStorage('rng_event_type_rule');
$this->eventManager = $event_manager;
}
......@@ -83,6 +95,7 @@ class EventTypeAccessDefaultsForm extends EntityForm {
$container->get('redirect.destination'),
$container->get('plugin.manager.action'),
$container->get('plugin.manager.condition'),
$container->get('entity_type.manager'),
$container->get('rng.event_manager')
);
}
......@@ -141,13 +154,12 @@ class EventTypeAccessDefaultsForm extends EntityForm {
$i = 0;
$etm = \Drupal::entityTypeManager();
$storage = $etm->getStorage('rng_event_type_rule');
$this->rules = $storage->loadByProperties([
'entity_type' => $event_type->getEventEntityTypeId(),
'bundle' => $event_type->getEventBundle(),
'trigger' => $trigger,
]);
$this->rules = $this->eventTypeRuleStorage
->loadByProperties([
'entity_type' => $event_type->getEventEntityTypeId(),
'bundle' => $event_type->getEventBundle(),
'trigger' => $trigger,
]);
foreach ($this->rules as $rule_id => $rule) {
$i++;
......@@ -225,7 +237,16 @@ class EventTypeAccessDefaultsForm extends EntityForm {
}
$form['settings'] = [
'#type' => 'fieldset',
'#title' => $this->t('Settings'),
];
$form['settings']['custom_rules'] = [
'#title' => $this->t('Allow default rules customization'),
'#description' => $this->t('Allow event managers to customize event default rules. Changing this setting does not affect existing rules.'),
'#type' => 'checkbox',
'#default_value' => $event_type->getAllowCustomRules(),
];
return $form;
}
......@@ -280,6 +301,16 @@ class EventTypeAccessDefaultsForm extends EntityForm {
$rule->save();
}
$event_type
->setAllowCustomRules($form_state->getValue('custom_rules'))
->save();
// Site cache needs to be cleared after enabling this setting as there are
// issue regarding caching.
// For some reason actions access is not reset if pages are rendered with no
// access/viability.
Cache::invalidateTags(['rendered']);
drupal_set_message($this->t('Event type access defaults saved.'));
$this->eventManager->invalidateEventType($event_type);
}
......
......@@ -97,7 +97,9 @@ class RouteSubscriber extends RouteSubscriberBase {
'_title' => 'Reset access to default',
'event' => $entity_type,
),
$manage_requirements,
$manage_requirements + [
'_event_rule_reset' => 'TRUE',
],
$options
);
$collection->add("rng.event.$entity_type.access.reset", $route);
......
......@@ -9,7 +9,6 @@ namespace Drupal\Tests\rng\Kernel;
use Drupal\simpletest\UserCreationTrait;
use Drupal\rng\EventManagerInterface;
use Drupal\rng\Entity\EventTypeRule;
/**
* Tests ability to register for events..
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment