Commit 3c172655 authored by Josh Fabean's avatar Josh Fabean Committed by Josh Fabean
Browse files

Issue #3317302 by josh.fabean: Add the ability to limit the max amount of openings a user can claim

parent fb67c0c4
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -160,3 +160,16 @@ function bookable_calendar_update_8112() {
  \Drupal::entityDefinitionUpdateManager()
    ->installFieldStorageDefinition('book_in_progress', 'bookable_calendar', 'bookable_calendar', $field_storage_definition);
}

/**
 * Add ability to limit a single user from booking too much at once.
 */
function bookable_calendar_update_8113() {
  $field_storage_definition = BaseFieldDefinition::create('integer')
    ->setLabel(t('Max Open Bookings Per User'))
    ->setDescription(t('Limit the amount of future bookings a single user can do, will limit off email address.'))
    ->setCardinality(1)
    ->setDefaultValue(NULL);
  \Drupal::entityDefinitionUpdateManager()
    ->installFieldStorageDefinition('max_open_bookings', 'bookable_calendar', 'bookable_calendar', $field_storage_definition);
}
 No newline at end of file
+13 −0
Original line number Diff line number Diff line
@@ -267,6 +267,19 @@ class BookableCalendar extends RevisionableContentEntityBase implements Bookable
      ->setDisplayConfigurable('form', TRUE)
      ->setDisplayConfigurable('view', FALSE);

    $fields['max_open_bookings'] = BaseFieldDefinition::create('integer')
      ->setLabel(t('Max Open Bookings Per User'))
      ->setDescription(t('Limit the amount of future bookings a single user can do, will limit off of email address.'))
      ->setDisplayOptions('form', [
        'type' => 'number',
        'settings' => [
          'display_label' => FALSE,
        ],
        'weight' => 0,
      ])
      ->setDisplayConfigurable('form', TRUE)
      ->setDisplayConfigurable('view', FALSE);

    $fields['slots_per_opening'] = BaseFieldDefinition::create('integer')
      ->setLabel(t('Slots Per Opening'))
      ->setDescription(t("The amount of Bookings that can claim a single opening. For example if your event has hour long openings you let people register for and you can handle 10 people per hour set this field to '10.'"))
+1 −0
Original line number Diff line number Diff line
@@ -119,6 +119,7 @@ class BookingContact extends ContentEntityBase implements BookingContactInterfac
      ->addConstraint('CalendarOpeningNotInPast')
      ->addConstraint('CalendarOpeningTooSoon')
      ->addConstraint('CalendarOpeningTooFarAway')
      ->addConstraint('CalendarOpeningMaxBookingsClaimedByUser')
      ->setDisplayOptions('form', [
        'type' => 'number',
        'settings' => [
+20 −0
Original line number Diff line number Diff line
<?php

namespace Drupal\bookable_calendar\Plugin\Validation\Constraint;

use Symfony\Component\Validator\Constraint;

/**
 * Stops users from Booking more spots than allowed on Calendar Opennings.
 *
 * @Constraint(
 *   id = "CalendarOpeningMaxBookingsClaimedByUser",
 *   label = @Translation("Calendar Opening Max Bookings Claimed By User", context = "Validation"),
 *   type = "string"
 * )
 */
class CalendarOpeningMaxBookingsClaimedByUser extends Constraint {

  public $overLimit = 'You have already claimed the max amount of upcoming spots for this calendar of %max-bookings.';

}
+50 −0
Original line number Diff line number Diff line
<?php

namespace Drupal\bookable_calendar\Plugin\Validation\Constraint;

use Drupal\Core\Entity\ContentEntityInterface;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;

/**
 * Validates the CalendarOpeningMaxBookingsClaimedByUser constraint.
 */
class CalendarOpeningMaxBookingsClaimedByUserValidator extends ConstraintValidator {

  /**
   * {@inheritdoc}
   */
  public function validate($value, Constraint $constraint) {
    /** @var ContentEntityInterface $entity */
    $entity = $this->context->getRoot()->getValue();
    $parent_calendar = $entity->getParentCalendar();
    $max_open_bookings = (int) $parent_calendar->max_open_bookings->value;

    if (!is_null($max_open_bookings) & $max_open_bookings !== 0) {
      // Get all opening bookings by this user for this calendar.
      $query = \Drupal::database()->select('booking_contact', 'contact');
      $query->fields('contact', [
        'email',
        'booking_instance'
      ]);
      $query->condition('contact.email', $entity->email->value);
      $query->leftJoin('bookable_calendar_opening_inst', 'inst', 'inst.id = contact.booking_instance');
      $query->condition('inst.date__end_value', strtotime('now'), '>');
      $query->fields('inst', [
        'date__end_value',
        'booking_opening'
      ]);
      $query->leftJoin('bookable_calendar_opening_field_data', 'opening', 'opening.id = inst.booking_opening');
      $query->fields('opening', [
        'bookable_calendar'
      ]);
      $query->condition('opening.bookable_calendar', $parent_calendar->id());
      $user_open_bookings = $query->execute()->fetchAll();
      if (count($user_open_bookings) >= $max_open_bookings) {
        $this->context->addViolation($constraint->overLimit, [
          '%max-bookings' => $max_open_bookings,
        ]);
      }
    }
  }
}