Commit 93d15374 authored by dpi's avatar dpi

Init

parents
This diff is collapsed.
Prevent registrations when a registrant is registered for a similar event.
Copyright (C) 2016 Daniel Phin (@dpi)
# License
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
# Notice
This module is UNSUPPORTED in ALL WAYS imaginable. Do not expect any upgrade
paths.
Things may not work. Your site may break and/or explode. Use with caution.
# Installation
Make sure you are running RNG 8.x-1.0-rc4 or later (not released as of this
writing). Otherwise run RNG -dev release if 8.x-1.0-rc4 is not out yet.
# Configuration
1. Go to `rng_conflict.module`, change values `['field_date', 'field_track']`
to whatever combination of fields you like. Make sure the values are field
IDs.
2. Go to `ConflictForm.php`, do the same with `['field_date', 'field_track']`
as previously mentioned.
3. Go to the 'Conflicts' tab located inside an event to see conflicting events.
Registrants will be prevented from registering for the viewed event, and the
events listed on the 'Conflicts' tab.
\ No newline at end of file
name: RNG Conflict (Experimental)
type: module
description: 'Prevent registrations when a registrant is registered for a similar event.'
package: RNG
core: 8.x
dependencies:
- rng
rng_conflict.local_tasks:
class: \Drupal\Core\Menu\LocalTaskDefault
deriver: \Drupal\rng_conflict\Plugin\Derivative\LocalTasks
<?php
use Drupal\Core\Database\Query\AlterableInterface;
/**
* Implements hook_query_alter().
*/
function rng_conflict_query_alter(AlterableInterface $query) {
if ($query->hasTag('rng_register')) {
/** @var \Drupal\rng\Plugin\EntityReferenceSelection\RNGSelectionBase $handler */
$handler = $query->getMetaData('entity_reference_selection_handler');
$event = $handler->eventMeta->getEvent();
$storage = \Drupal::entityTypeManager()->getStorage($event->getEntityTypeId());
$event_query = $storage->getQuery();
foreach (['field_date', 'field_track'] as $field_name) {
$value = $event->{$field_name}->value;
$event_query->condition($field_name, $value);
}
// Similar event entity ID's.
$ids = $event_query->execute();
// Unset this event.
unset($ids[$event->id()]);
/** @var \Drupal\rng\EventManagerInterface $event_manager */
$event_manager = \Drupal::service('rng.event_manager');
$registrant_ids = [];
foreach ($ids as $id) {
$event = $storage->load($id);
$event_meta = $event_manager->getMeta($event);
/** @var \Drupal\rng\RegistrantInterface $registrant */
foreach ($event_meta->getRegistrants($handler->entityType->id()) as $registrant) {
if ($identity = $registrant->getIdentity()) {
$registrant_ids[$identity->id()] = $identity->id();
}
}
}
if ($registrant_ids) {
$query->condition('base_table.' . $handler->entityType->getKey('id'), $registrant_ids, 'NOT IN');
}
}
}
services:
rng_conflict.route_subscriber:
class: Drupal\rng_conflict\Routing\RouteSubscriber
arguments: ['@entity_type.manager', '@rng.event_manager']
tags:
- { name: event_subscriber }
<?php
/**
* @file
* Contains \Drupal\rng_conflict\Form\ConflictForm.
*/
namespace Drupal\rng_conflict\Form;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Form\FormBase;
use Drupal\rng\EventManagerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\Element;
use Drupal\Core\Routing\RouteMatchInterface;
/**
* Configure event conflict settings.
*/
class ConflictForm extends FormBase {
/**
* The RNG event manager.
*
* @var \Drupal\rng\EventManagerInterface
*/
protected $eventManager;
/**
* Constructs a new MessageActionForm object.
*
* @param \Drupal\rng\EventManagerInterface $event_manager
* The RNG event manager.
*/
public function __construct(EventManagerInterface $event_manager) {
$this->eventManager = $event_manager;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('rng.event_manager')
);
}
/**
* {@inheritdoc}
*/
public function getFormId() {
return 'rng_event_conflict';
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state, RouteMatchInterface $route_match = NULL, $event = NULL) {
/** @var EntityInterface $event_entity */
$event_entity = $route_match->getParameter($event);
$storage = \Drupal::entityTypeManager()->getStorage($event_entity->getEntityTypeId());
$query = $storage->getQuery();
$values = [];
foreach (['field_date', 'field_track'] as $field_name) {
$values[$field_name] = $event_entity->{$field_name}->value;
$value = $event_entity->{$field_name}->value;
$query->condition($field_name, $value);
}
// Similar event entity ID's.
$ids = $query->execute();
// Unset this event.
unset($ids[$event_entity->id()]);
//
// foreach ($ids as $id) {
// $event = $storage->load($id);
// $event_meta = $this->eventManager->getMeta($event);
// $registrant_query = $event_meta->buildRegistrantQuery('user');
// }
$form['help']['#plain_text'] = $this->t('A registrant will not be able to register for this event if they are also registered for the following events:');
$form['events'] = [
'#type' => 'table',
'#header' => [$this->t('Label')],
'#empty' => $this->t('No conflicting events found.'),
];
foreach ($ids as $id) {
$row = [];;
$event = $storage->load($id);
$row['entity']['#markup'] = $event->link();
$form['events'][] = $row;
}
return $form;
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
}
}
<?php
/**
* @file
* Contains \Drupal\rng_conflict\Plugin\Derivative\LocalTasks.
*/
namespace Drupal\rng_conflict\Plugin\Derivative;
use Drupal\Component\Plugin\Derivative\DeriverBase;
use Drupal\Core\Plugin\Discovery\ContainerDeriverInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Routing\RouteProviderInterface;
use Drupal\rng\EventManagerInterface;
/**
* Provides dynamic tasks.
*/
class LocalTasks extends DeriverBase implements ContainerDeriverInterface {
/**
* The RNG event manager.
*
* @var \Drupal\rng\EventManagerInterface
*/
protected $eventManager;
/**
* Constructs a LocalTasks object.
*
* @param \Drupal\Core\Routing\RouteProviderInterface $route_provider
* The route provider.
* @param \Drupal\rng\EventManagerInterface $event_manager
* The RNG event manager.
*/
public function __construct(RouteProviderInterface $route_provider, EventManagerInterface $event_manager) {
$this->routeProvider = $route_provider;
$this->eventManager = $event_manager;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, $base_plugin_id) {
return new static(
$container->get('router.route_provider'),
$container->get('rng.event_manager')
);
}
/**
* {@inheritdoc}
*/
public function getDerivativeDefinitions($base_plugin_definition) {
$this->derivatives = [];
$event_types = $this->eventManager->getEventTypes();
foreach (array_keys($event_types) as $entity_type) {
// Only need one set of tasks task per entity type.
if ($this->routeProvider->getRouteByName("entity.$entity_type.canonical")) {
$event_default = "rng.event.$entity_type.event.default";
$this->derivatives["rng.event.$entity_type.event.conflicts"] = array(
'title' => t('Conflicts'),
'route_name' => "rng.event.$entity_type.conflicts",
'parent_id' => 'rng.local_tasks:' . $event_default,
'weight' => 20,
);
}
}
foreach ($this->derivatives as &$entry) {
$entry += $base_plugin_definition;
}
return parent::getDerivativeDefinitions($base_plugin_definition);
}
}
<?php
/**
* @file
* Contains \Drupal\rng_conflict\Routing\RouteSubscriber.
*/
namespace Drupal\rng_conflict\Routing;
use Drupal\Core\Routing\RouteSubscriberBase;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\rng\EventManagerInterface;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;
/**
* Dynamic routes.
*/
class RouteSubscriber extends RouteSubscriberBase {
/**
* The entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* The RNG event manager.
*
* @var \Drupal\rng\EventManagerInterface
*/
protected $eventManager;
/**
* Constructs a RouteSubscriber object.
*
* @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(EntityTypeManagerInterface $entity_type_manager, EventManagerInterface $event_manager) {
$this->entityTypeManager = $entity_type_manager;
$this->eventManager = $event_manager;
}
/**
* {@inheritdoc}
*/
protected function alterRoutes(RouteCollection $collection) {
$event_types = $this->eventManager->getEventTypes();
foreach (array_keys($event_types) as $entity_type) {
$definition = $this->entityTypeManager->getDefinition($entity_type);
if ($canonical_path = $definition->getLinkTemplate('canonical')) {
$manage_requirements = [
'_entity_access' => $entity_type . '.manage event',
'_entity_is_event' => 'TRUE',
];
$options = [];
$options['parameters'][$entity_type]['type'] = 'entity:' . $entity_type;
$route = new Route(
$canonical_path . '/event/conflicts',
array(
'_form' => '\Drupal\rng_conflict\Form\ConflictForm',
'_title' => 'Conflicts',
'event' => $entity_type,
),
$manage_requirements,
$options
);
$collection->add("rng.event.$entity_type.conflicts", $route);
}
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment