Skip to content
Snippets Groups Projects
Commit 090d5d0e authored by Camilo Ernesto  Escobar Bedoya's avatar Camilo Ernesto Escobar Bedoya Committed by Owen Bush
Browse files

Issue #3391389 by camilo.escobar, owenbush: Adding an instance to a Series:...

Issue #3391389 by camilo.escobar, owenbush: Adding an instance to a Series: Computed fields bring down the database server
parent 98ab1fa5
No related branches found
No related tags found
No related merge requests found
......@@ -5,18 +5,69 @@ namespace Drupal\recurring_events_registration\Plugin\ComputedField;
use Drupal\Core\Field\FieldItemList;
use Drupal\Core\TypedData\ComputedItemListTrait;
use Drupal\recurring_events_registration\Traits\RegistrationCreationServiceTrait;
use Drupal\Core\TypedData\DataDefinitionInterface;
use Drupal\Core\TypedData\TypedDataInterface;
/**
* A computed field that provides the availabilty count of an Event Instance.
*/
class AvailabilityCount extends FieldItemList {
use ComputedItemListTrait;
use RegistrationCreationServiceTrait;
/**
* The Request stack.
*
* @var \Drupal\Core\Http\RequestStack
*/
protected $requestStack;
/**
* {@inheritdoc}
*/
public function __construct(DataDefinitionInterface $definition, $name = NULL, TypedDataInterface $parent = NULL) {
parent::__construct($definition, $name, $parent);
// @todo Look for a better way to inject this service.
$this->requestStack = \Drupal::service('request_stack');
}
/**
* {@inheritDoc}
*/
protected function computeValue() {
$entity = $this->getEntity();
$this->list[0] = $this->createItem(0, $this->getRegistrationCreationService($entity)->retrieveAvailability());
// When saving or editing some entities, we are not interested in
// calculating the values for its computed fields. The resulting values of
// these computed fields are actually useful when getting/viewing/reading
// the entities, for example, when retrieving an entity data from a GET
// request to a REST or JSON:API endpoint.
// If the request has the 'POST' method, assign an empty value to the
// computed field and return.
$current_request = $this->requestStack->getCurrentRequest();
$route_name = $current_request->attributes->get('_route');
// Exclude 'entity.eventseries.add_instance_form': When a new Event
// Instance is being created via the "Add instance" option from the Series,
// we do not want the computation to be done during the POST request.
// @see https://www.drupal.org/project/recurring_events/issues/3391389
$excluded_routes = [
'entity.eventseries.add_instance_form',
];
if ($current_request->getMethod() == 'POST' && in_array($route_name, $excluded_routes)) {
$this->list[0] = $this->createItem(0, 0);
return;
}
/*
* The ComputedItemListTrait only calls this once on the same instance; from
* then on, the value is automatically cached in $this->items, for use by
* methods like getValue().
*/
if (!isset($this->list[0])) {
$entity = $this->getEntity();
$this->list[0] = $this->createItem(0, $this->getRegistrationCreationService($entity)->retrieveAvailability());
}
}
}
......@@ -5,21 +5,69 @@ namespace Drupal\recurring_events_registration\Plugin\ComputedField;
use Drupal\Core\Field\FieldItemList;
use Drupal\Core\TypedData\ComputedItemListTrait;
use Drupal\recurring_events_registration\Traits\RegistrationCreationServiceTrait;
use Drupal\Core\TypedData\DataDefinitionInterface;
use Drupal\Core\TypedData\TypedDataInterface;
/**
* Class RegistrationCount.
* A computed field that provides the registration count of an Event Instance.
*/
class RegistrationCount extends FieldItemList {
use ComputedItemListTrait;
use RegistrationCreationServiceTrait;
/**
* The Request stack.
*
* @var \Drupal\Core\Http\RequestStack
*/
protected $requestStack;
/**
* {@inheritdoc}
*/
public function __construct(DataDefinitionInterface $definition, $name = NULL, TypedDataInterface $parent = NULL) {
parent::__construct($definition, $name, $parent);
// @todo Look for a better way to inject this service.
$this->requestStack = \Drupal::service('request_stack');
}
/**
* {@inheritDoc}
*/
protected function computeValue() {
$entity = $this->getEntity();
$this->list[0] = $this->createItem(0, count($this->getRegistrationCreationService($entity)->retrieveRegisteredParties(TRUE, FALSE)));
// When saving or editing some entities, we are not interested in
// calculating the values for its computed fields. The resulting values of
// these computed fields are actually useful when getting/viewing/reading
// the entities, for example, when retrieving an entity data from a GET
// request to a REST or JSON:API endpoint.
// If the request has the 'POST' method, assign an empty value to the
// computed field and return.
$current_request = $this->requestStack->getCurrentRequest();
$route_name = $current_request->attributes->get('_route');
// Exclude 'entity.eventseries.add_instance_form': When a new Event
// Instance is being created via the "Add instance" option from the Series,
// we do not want the computation to be done during the POST request.
// @see https://www.drupal.org/project/recurring_events/issues/3391389
$excluded_routes = [
'entity.eventseries.add_instance_form',
];
if ($current_request->getMethod() == 'POST' && in_array($route_name, $excluded_routes)) {
$this->list[0] = $this->createItem(0, 0);
return;
}
/*
* The ComputedItemListTrait only calls this once on the same instance; from
* then on, the value is automatically cached in $this->items, for use by
* methods like getValue().
*/
if (!isset($this->list[0])) {
$entity = $this->getEntity();
$this->list[0] = $this->createItem(0, $this->getRegistrationCreationService($entity)->retrieveRegisteredPartiesCount(TRUE, FALSE));
}
}
}
......@@ -5,21 +5,69 @@ namespace Drupal\recurring_events_registration\Plugin\ComputedField;
use Drupal\Core\Field\FieldItemList;
use Drupal\Core\TypedData\ComputedItemListTrait;
use Drupal\recurring_events_registration\Traits\RegistrationCreationServiceTrait;
use Drupal\Core\TypedData\DataDefinitionInterface;
use Drupal\Core\TypedData\TypedDataInterface;
/**
* Class WaitlistCount.
* A computed field that provides the waitlist count of an Event Instance.
*/
class WaitlistCount extends FieldItemList {
use ComputedItemListTrait;
use RegistrationCreationServiceTrait;
/**
* The Request stack.
*
* @var \Drupal\Core\Http\RequestStack
*/
protected $requestStack;
/**
* {@inheritdoc}
*/
public function __construct(DataDefinitionInterface $definition, $name = NULL, TypedDataInterface $parent = NULL) {
parent::__construct($definition, $name, $parent);
// @todo Look for a better way to inject this service.
$this->requestStack = \Drupal::service('request_stack');
}
/**
* {@inheritDoc}
*/
protected function computeValue() {
$entity = $this->getEntity();
$this->list[0] = $this->createItem(0, count($this->getRegistrationCreationService($entity)->retrieveRegisteredParties(FALSE, TRUE)));
// When saving or editing some entities, we are not interested in
// calculating the values for its computed fields. The resulting values of
// these computed fields are actually useful when getting/viewing/reading
// the entities, for example, when retrieving an entity data from a GET
// request to a REST or JSON:API endpoint.
// If the request has the 'POST' method, assign an empty value to the
// computed field and return.
$current_request = $this->requestStack->getCurrentRequest();
$route_name = \Drupal::routeMatch()->getRouteName();
// Exclude 'entity.eventseries.add_instance_form': When a new Event
// Instance is being created via the "Add instance" option from the Series,
// we do not want the computation to be done during the POST request.
// @see https://www.drupal.org/project/recurring_events/issues/3391389
$excluded_routes = [
'entity.eventseries.add_instance_form',
];
if ($current_request->getMethod() == 'POST' && in_array($route_name, $excluded_routes)) {
$this->list[0] = $this->createItem(0, 0);
return;
}
/*
* The ComputedItemListTrait only calls this once on the same instance; from
* then on, the value is automatically cached in $this->items, for use by
* methods like getValue().
*/
if (!isset($this->list[0])) {
$entity = $this->getEntity();
$this->list[0] = $this->createItem(0, $this->getRegistrationCreationService($entity)->retrieveRegisteredPartiesCount(FALSE, TRUE));
}
}
}
......@@ -168,7 +168,7 @@ class RegistrationCreationService {
}
/**
* Retreive all registered parties.
* Retrieve all registered parties.
*
* @param bool $include_nonwaitlisted
* Whether or not to include non-waitlisted registrants.
......@@ -220,6 +220,56 @@ class RegistrationCreationService {
return $parties;
}
/**
* Retrieves the count of all registered parties.
*
* @param bool $include_nonwaitlisted
* Whether or not to include non-waitlisted registrants.
* @param bool $include_waitlisted
* Whether or not to include waitlisted registrants.
* @param int $uid
* The user ID for whom to retrieve registrants.
*
* @return int
* The count of registrants.
*/
public function retrieveRegisteredPartiesCount($include_nonwaitlisted = TRUE, $include_waitlisted = TRUE, $uid = FALSE) {
$query = $this->storage->getQuery();
if ($include_nonwaitlisted && !$include_waitlisted) {
$query->condition('waitlist', 0);
}
elseif (!$include_nonwaitlisted && $include_waitlisted) {
$query->condition('waitlist', 1);
}
if (!$include_waitlisted) {
$query->condition('waitlist', 0);
}
if ($uid) {
$query->condition('user_id', $uid);
}
switch ($this->getRegistrationType()) {
case 'series':
if (!empty($this->eventSeries->id())) {
$query->condition('eventseries_id', $this->eventSeries->id());
}
break;
case 'instance':
if (!empty($this->eventInstance->id())) {
$query->condition('eventinstance_id', $this->eventInstance->id());
}
break;
}
$result = $query->count()->execute();
return $result;
}
/**
* Retreive all registered parties for a series.
*
......@@ -302,14 +352,15 @@ class RegistrationCreationService {
*/
public function retrieveAvailability() {
$availability = 0;
$parties = $this->retrieveRegisteredParties(TRUE, FALSE);
$parties_count = $this->retrieveRegisteredPartiesCount(TRUE, FALSE);
$capacity = $this->eventSeries->event_registration->capacity;
if (empty($capacity)) {
// Set capacity to unlimited if no capacity is specified.
return -1;
}
$availability = $capacity - count($parties);
$availability = $capacity - $parties_count;
if ($availability < 0) {
$availability = 0;
}
......@@ -828,14 +879,15 @@ class RegistrationCreationService {
* An array of roles that are allowed to register for this event.
*/
public function registrationPermittedRoles() {
// Remove extra spaces from the list of roles
// Remove extra spaces from the list of roles.
$permitted_roles_string = str_replace(' ', '', $this->eventSeries->event_registration->permitted_roles);
// Convert the string into an array of roles
// Convert the string into an array of roles.
$permitted_roles = [];
if (!empty($permitted_roles_string)) {
if (strpos($permitted_roles_string, ','))
if (strpos($permitted_roles_string, ',')) {
$permitted_roles = explode(',', $permitted_roles_string);
}
else {
$permitted_roles[] = $permitted_roles_string;
}
......@@ -843,5 +895,4 @@ class RegistrationCreationService {
return $permitted_roles;
}
}
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