Loading README.md +67 −52 Original line number Diff line number Diff line # Bookable Calendar This aim to be a very easy to use Bookable Calendar module. Whether you're giving lessons and want your students to be able to book a lesson or a business trying to stagger traffic into your building, this module aims to get you up and running as fast as possible. This aim to be a very easy to use Bookable Calendar module. Whether you're giving lessons and want your students to be able to book a lesson or a business trying to stagger traffic into your building, this module aims to get you up and running as fast as possible. ## Steps to create your first Calendar and take a Booking Loading @@ -14,54 +15,65 @@ this module aims to get you up and running as fast as possible. ### As an user (currently though admin interface UI coming soon) 1. Create a new Booking Contact filling out what Instance you want and party size. 2. On save it will tell you whether or not that will work based on max slots available and other things. 1. Create a new Booking Contact filling out what Instance you want and party size. 2. On save it will tell you whether or not that will work based on max slots available and other things. ## Entities and what they do ### Bookable Calendar This is the main Calendar that will be user facing. The thought would be if you're an individual giving lessons it could be called "Piano Lessons" or if you're a company selling spots in line for Santa it would say "Santa at the Mall" or whatever. It's fieldable so you can add any extra fields needed for your situation by default it has the following fields: This is the main Calendar that will be user facing. The thought would be if you're an individual giving lessons it could be called "Piano Lessons" or if you're a company selling spots in line for Santa it would say "Santa at the Mall" or whatever. It's fieldable so you can add any extra fields needed for your situation by default it has the following fields: - **Title:** The name of your Calendar - **Active:** Whether or not you are currently allowing more bookings, this is so you can still show the calendar but freeze Bookings. - **Active:** Whether or not you are currently allowing more bookings, this is so you can still show the calendar but freeze Bookings. - **Status:** Standard Drupal status, will hide this calendar from non admins. - **Description:** This is a long text field that can be filled out to show any sort of body text you want to show to users about this calendar. - **Max Party Size:** Limit the max amount of bookings an individual contact can make to a single Opening. - **Slots Per Opening:** How many bookings you want to allow per opening, if you're giving individual lessons this might be 1 but if you're booking our an event space this might be 100 or whatever you need. - **Booking Future Time:** This will limit user's ability to book openings more than X days/weeks/months in the future. - **Booking Lead Time:** This is the minimum amount time in the future a Booking can take place. This can be used to limit users booking same day/week/month booking - **Calendar Openings:** This is not user created but is an entity reference to each opening for this Calendar. - **Description:** This is a long text field that can be filled out to show any sort of body text you want to show to users about this calendar. - **Max Party Size:** Limit the max amount of bookings an individual contact can make to a single Opening. - **Slots Per Opening:** How many bookings you want to allow per opening, if you're giving individual lessons this might be 1 but if you're booking our an event space this might be 100 or whatever you need. - **Booking Future Time:** This will limit user's ability to book openings more than X days/weeks/months in the future. - **Booking Lead Time:** This is the minimum amount time in the future a Booking can take place. This can be used to limit users booking same day/week/month booking - **Calendar Openings:** This is not user created but is an entity reference to each opening for this Calendar. ### Bookable Calendar Opening The individual openings for your Bookable Calendar. You can create as many of these as you'd like for your calendar. This is where you define what dates and times are available to book. Due to it being a multiple date value with repeat it's possible you could create only one of these per Bookable Calendar but the option is there to create as many as needed. The advantage af splitting them out is then it's easier to turn of a certain Opening whether that be a single day or opening as there is the status field to quickly turn it on or off vs editing your repeating date field to remove a day. - **Title:** Only shown to admins to quickly let you know what opening you're looking at. - **Status:** Easy turn it on/off for booking, you can turn the whole calendar off in the Bookable Calendar or here to turn off a single Opening. The individual openings for your Bookable Calendar. You can create as many of these as you'd like for your calendar. This is where you define what dates and times are available to book. Due to it being a multiple date value with repeat it's possible you could create only one of these per Bookable Calendar but the option is there to create as many as needed. The advantage af splitting them out is then it's easier to turn of a certain Opening whether that be a single day or opening as there is the status field to quickly turn it on or off vs editing your repeating date field to remove a day. - **Title:** Only shown to admins to quickly let you know what opening you're looking at. - **Status:** Easy turn it on/off for booking, you can turn the whole calendar off in the Bookable Calendar or here to turn off a single Opening. - **Bookable Calendar:** Reference to the calendar this opening is for. - **Booking Instance:** Not user created but links openings to instances. - **Date:** The date field that is repeatable for when this Opening occurs. ### Bookable Calendar Opening Instance This is an entity that you don't create directly, but per time slot that is open based on the date field on Bookable Calendar Opening an instance is created. Then users will register for indivdual instances. The indivdual instances are also what shows up on the listing of all bookings you book. This is an entity that you don't create directly, but per time slot that is open based on the date field on Bookable Calendar Opening an instance is created. Then users will register for indivdual instances. The indivdual instances are also what shows up on the listing of all bookings you book. - **Booking:** Points to all the Bookings that have Booked this Instance. - **Booking Opening:** Points to the parent Opening. Loading @@ -71,30 +83,33 @@ listing of all bookings you book. This is the entity that a front end user will be creating when they register. - **Email:** The email for this booking, this is used emails to confirm the booking and a link to edit the booking. - **Party Size:** The amount of people this booking is for, this lets us know how many slots are being taken by this booking. - **Email:** The email for this booking, this is used emails to confirm the booking and a link to edit the booking. - **Party Size:** The amount of people this booking is for, this lets us know how many slots are being taken by this booking. - **Booking Instance:** The instance this booking points to. - **Booking:** Not user created, the bookings this contact is linked to. ### Booking This is another entity no one creates directly, but when a new Contact is created a new Booking is created per person in the party size. This is how we know how many people have booked each instance easily. This is another entity no one creates directly, but when a new Contact is created a new Booking is created per person in the party size. This is how we know how many people have booked each instance easily. - **Created:** Time Booking was created. - **Booking Instance:** The Booking Instance this Booking is for. - **Booking Calendar:** The parent calendar this Booking is for. (this seems redundant but Instances might get cleaned up over time) - **Booking Calendar:** The parent calendar this Booking is for. (this seems redundant but Instances might get cleaned up over time) - **Contact:** The conctact that owns this Booking. - **Booking Date:** The date this Booking is for. This is because I see a situation where you need to clean up old Instances as you will most likely have thousands over the course of a year, but you might still want historic records of Bookings and what timeslot they booked. - **Booking Date:** The date this Booking is for. This is because I see a situation where you need to clean up old Instances as you will most likely have thousands over the course of a year, but you might still want historic records of Bookings and what timeslot they booked. ## API There are some API endpoints exposed so you can create new Bookings however you'd like. There are some API endpoints exposed so you can create new Bookings however you'd like. ### Book an Instance Loading Loading @@ -130,8 +145,8 @@ fetch("/bookable-calendar/{$instance_id}/book", requestOptions) ## Todo - Cleanup no longer matching instances maybe on cron. - Allow for cleanup on Cron based on settings of old Instances, Bookings and Contacts if you don't care about things older than X months. - Allow for cleanup on Cron based on settings of old Instances, Bookings and Contacts if you don't care about things older than X months. ## Quickly Delete Everything Loading @@ -146,13 +161,13 @@ $openings = $opening_storage->loadMultiple(); foreach ($openings as $opening) { $opening->delete(); } $instance_storage = \Drupal::entityTypeManager()->getStorage('bookable_calendar_opening_inst'); $instances = $instance_storage->loadMultiple(); $instanceStorage = \Drupal::entityTypeManager()->getStorage('bookable_calendar_opening_inst'); $instances = $instanceStorage->loadMultiple(); foreach ($instances as $instance) { $instance->delete(); } $booking_contact_storage = \Drupal::entityTypeManager()->getStorage('booking_contact'); $booking_contacts = $booking_contact_storage->loadMultiple(); $booking_contactStorage = \Drupal::entityTypeManager()->getStorage('booking_contact'); $booking_contacts = $booking_contactStorage->loadMultiple(); foreach ($booking_contacts as $contact) { $contact->delete(); } Loading bookable_calendar.module +22 −22 Original line number Diff line number Diff line Loading @@ -91,11 +91,10 @@ function bookable_calendar_views_data_alter(array &$data) { } /** * Replace all titles on pages to make them easier to understand as there are no real titles. * Replace all titles on pages to make them easier to understand. * * @param array $variables * * @return void * Variables associated with hook_page_title. */ function template_preprocess_page_title(array &$variables) { $route_name = \Drupal::routeMatch()->getRouteName(); Loading Loading @@ -161,13 +160,13 @@ function template_preprocess_page_title(array &$variables) { * * @param array $variables * An associative array containing: * - elements: An associative array containing the bookable calendar information and any * fields attached to the entity. * - elements: An associative array containing the bookable calendar * information and any fields attached to the entity. * - attributes: HTML attributes for the containing element. */ function template_preprocess_bookable_calendar(array &$variables) { $entity_type_manager = \Drupal::service('entity_type.manager'); $instance_storage = $entity_type_manager->getStorage('bookable_calendar_opening_inst'); $entityTypeManager = \Drupal::service('entity_type.manager'); $instanceStorage = $entityTypeManager->getStorage('bookable_calendar_opening_inst'); $this_calendar = $variables['content']['#bookable_calendar']; $query = \Drupal::database()->select('bookable_calendar__calendar_openings', 'cal'); $query->fields('cal', [ Loading @@ -183,7 +182,7 @@ function template_preprocess_bookable_calendar(array &$variables) { $opening_instances = $query->execute()->fetchAllAssoc('id'); if ($opening_instances) { $instances = array_keys($opening_instances); $loaded_instances = $instance_storage->loadMultiple($instances); $loaded_instances = $instanceStorage->loadMultiple($instances); $variables['content']['instances'] = []; foreach ($loaded_instances as $key => $instance) { $render_instance = Drupal::entityTypeManager()->getViewBuilder('bookable_calendar_opening_inst')->view($instance); Loading @@ -199,18 +198,18 @@ function template_preprocess_bookable_calendar(array &$variables) { * * @param array $variables * An associative array containing: * - elements: An associative array containing the booking calendar opening information and any * fields attached to the entity. * - elements: An associative array containing the booking calendar opening * information and any fields attached to the entity. * - attributes: HTML attributes for the containing element. */ function template_preprocess_bookable_calendar_opening(array &$variables) { $entity_type_manager = \Drupal::service('entity_type.manager'); $instance_storage = $entity_type_manager->getStorage('bookable_calendar_opening_inst'); $entityTypeManager = \Drupal::service('entity_type.manager'); $instanceStorage = $entityTypeManager->getStorage('bookable_calendar_opening_inst'); $this_opening = $variables['content']['#bookable_calendar_opening']; $instances = $this_opening->get('booking_instance')->getValue(); $variables['instances'] = []; foreach ($instances as $key => $instance_id) { $instance = $instance_storage->load($instance_id['target_id']); $instance = $instanceStorage->load($instance_id['target_id']); if ($instance) { $render_instance = Drupal::entityTypeManager()->getViewBuilder('bookable_calendar_opening_inst')->view($instance); $variables['instances'][$key] = $render_instance; Loading @@ -226,8 +225,8 @@ function template_preprocess_bookable_calendar_opening(array &$variables) { * * @param array $variables * An associative array containing: * - elements: An associative array containing the booking contact information and any * fields attached to the entity. * - elements: An associative array containing the booking contact * information and any fields attached to the entity. * - attributes: HTML attributes for the containing element. */ function template_preprocess_booking_contact(array &$variables) { Loading @@ -241,8 +240,8 @@ function template_preprocess_booking_contact(array &$variables) { * * @param array $variables * An associative array containing: * - elements: An associative array containing the booking information and any * fields attached to the entity. * - elements: An associative array containing the booking information * and any fields attached to the entity. * - attributes: HTML attributes for the containing element. */ function template_preprocess_booking(array &$variables) { Loading @@ -256,8 +255,8 @@ function template_preprocess_booking(array &$variables) { * * @param array $variables * An associative array containing: * - elements: An associative array containing the bookable calendar opening instance information and any * fields attached to the entity. * - elements: An associative array containing the bookable calendar * opening instance information and any fields attached to the entity. * - attributes: HTML attributes for the containing element. */ function template_preprocess_bookable_calendar_opening_inst(array &$variables) { Loading Loading @@ -468,7 +467,7 @@ function bookable_calendar_tokens($type, $tokens, array $data, array $options, B } /** * * Form alters. */ function bookable_calendar_form_alter(&$form, FormStateInterface $form_state, $form_id) { if ($form_id === 'booking_contact_add_form') { Loading Loading @@ -517,7 +516,7 @@ function bookable_calendar_form_alter(&$form, FormStateInterface $form_state, $f } /** * * Redirect to front page when you delete your own booking. */ function bookable_calendar_delete_set_redirect($form, FormStateInterface $form_state) { $form_state->setRedirect('<front>'); Loading @@ -531,7 +530,8 @@ function bookable_calendar_views_post_execute(ViewExecutable $view) { if ($view->getBaseTables()['bookable_calendar_opening_inst'] ?? NULL) { // Handle available slots filter. if ($slots_filter = $view->storage->get('bookable_calendar_available_slots_filter')) { // Get filter values & operator and apply logic based on the instance's available slots. // Get filter values & operator and apply logic // based on the instance's available slots. $value = $slots_filter['value']['value'] ?? NULL; $min = $slots_filter['value']['min'] ?? NULL; $max = $slots_filter['value']['max'] ?? NULL; Loading src/AvailableSlotsItemList.php +1 −1 Original line number Diff line number Diff line Loading @@ -7,7 +7,7 @@ use Drupal\Core\Field\FieldItemList; use Drupal\Core\TypedData\ComputedItemListTrait; /** * Item list for a computed field that displays the available slots for a bookable calendar opening instance. * Item list for a computed field that displays the available slots. */ class AvailableSlotsItemList extends FieldItemList { Loading src/BookableCalendarAccessControlHandler.php +12 −3 Original line number Diff line number Diff line Loading @@ -22,10 +22,16 @@ class BookableCalendarAccessControlHandler extends EntityAccessControlHandler { return AccessResult::allowedIfHasPermission($account, 'view bookable calendar'); case 'update': return AccessResult::allowedIfHasPermissions($account, ['edit bookable calendar', 'administer bookable calendar'], 'OR'); return AccessResult::allowedIfHasPermissions($account, [ 'edit bookable calendar', 'administer bookable calendar', ], 'OR'); case 'delete': return AccessResult::allowedIfHasPermissions($account, ['delete bookable calendar', 'administer bookable calendar'], 'OR'); return AccessResult::allowedIfHasPermissions($account, [ 'delete bookable calendar', 'administer bookable calendar', ], 'OR'); default: // No opinion. Loading @@ -38,7 +44,10 @@ class BookableCalendarAccessControlHandler extends EntityAccessControlHandler { * {@inheritdoc} */ protected function checkCreateAccess(AccountInterface $account, array $context, $entity_bundle = NULL) { return AccessResult::allowedIfHasPermissions($account, ['create bookable calendar', 'administer bookable calendar'], 'OR'); return AccessResult::allowedIfHasPermissions($account, [ 'create bookable calendar', 'administer bookable calendar', ], 'OR'); } } src/BookableCalendarOpeningAccessControlHandler.php +13 −4 Original line number Diff line number Diff line Loading @@ -8,7 +8,7 @@ use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Session\AccountInterface; /** * Defines the access control handler for the bookable calendar opening entity type. * Defines the access control handler for the bookable calendar opening. */ class BookableCalendarOpeningAccessControlHandler extends EntityAccessControlHandler { Loading @@ -22,10 +22,16 @@ class BookableCalendarOpeningAccessControlHandler extends EntityAccessControlHan return AccessResult::allowedIfHasPermission($account, 'view bookable calendar opening'); case 'update': return AccessResult::allowedIfHasPermissions($account, ['edit bookable calendar opening', 'administer bookable calendar opening'], 'OR'); return AccessResult::allowedIfHasPermissions($account, [ 'edit bookable calendar opening', 'administer bookable calendar opening', ], 'OR'); case 'delete': return AccessResult::allowedIfHasPermissions($account, ['delete bookable calendar opening', 'administer bookable calendar opening'], 'OR'); return AccessResult::allowedIfHasPermissions($account, [ 'delete bookable calendar opening', 'administer bookable calendar opening', ], 'OR'); default: // No opinion. Loading @@ -38,7 +44,10 @@ class BookableCalendarOpeningAccessControlHandler extends EntityAccessControlHan * {@inheritdoc} */ protected function checkCreateAccess(AccountInterface $account, array $context, $entity_bundle = NULL) { return AccessResult::allowedIfHasPermissions($account, ['create bookable calendar opening', 'administer bookable calendar opening'], 'OR'); return AccessResult::allowedIfHasPermissions($account, [ 'create bookable calendar opening', 'administer bookable calendar opening', ], 'OR'); } } Loading
README.md +67 −52 Original line number Diff line number Diff line # Bookable Calendar This aim to be a very easy to use Bookable Calendar module. Whether you're giving lessons and want your students to be able to book a lesson or a business trying to stagger traffic into your building, this module aims to get you up and running as fast as possible. This aim to be a very easy to use Bookable Calendar module. Whether you're giving lessons and want your students to be able to book a lesson or a business trying to stagger traffic into your building, this module aims to get you up and running as fast as possible. ## Steps to create your first Calendar and take a Booking Loading @@ -14,54 +15,65 @@ this module aims to get you up and running as fast as possible. ### As an user (currently though admin interface UI coming soon) 1. Create a new Booking Contact filling out what Instance you want and party size. 2. On save it will tell you whether or not that will work based on max slots available and other things. 1. Create a new Booking Contact filling out what Instance you want and party size. 2. On save it will tell you whether or not that will work based on max slots available and other things. ## Entities and what they do ### Bookable Calendar This is the main Calendar that will be user facing. The thought would be if you're an individual giving lessons it could be called "Piano Lessons" or if you're a company selling spots in line for Santa it would say "Santa at the Mall" or whatever. It's fieldable so you can add any extra fields needed for your situation by default it has the following fields: This is the main Calendar that will be user facing. The thought would be if you're an individual giving lessons it could be called "Piano Lessons" or if you're a company selling spots in line for Santa it would say "Santa at the Mall" or whatever. It's fieldable so you can add any extra fields needed for your situation by default it has the following fields: - **Title:** The name of your Calendar - **Active:** Whether or not you are currently allowing more bookings, this is so you can still show the calendar but freeze Bookings. - **Active:** Whether or not you are currently allowing more bookings, this is so you can still show the calendar but freeze Bookings. - **Status:** Standard Drupal status, will hide this calendar from non admins. - **Description:** This is a long text field that can be filled out to show any sort of body text you want to show to users about this calendar. - **Max Party Size:** Limit the max amount of bookings an individual contact can make to a single Opening. - **Slots Per Opening:** How many bookings you want to allow per opening, if you're giving individual lessons this might be 1 but if you're booking our an event space this might be 100 or whatever you need. - **Booking Future Time:** This will limit user's ability to book openings more than X days/weeks/months in the future. - **Booking Lead Time:** This is the minimum amount time in the future a Booking can take place. This can be used to limit users booking same day/week/month booking - **Calendar Openings:** This is not user created but is an entity reference to each opening for this Calendar. - **Description:** This is a long text field that can be filled out to show any sort of body text you want to show to users about this calendar. - **Max Party Size:** Limit the max amount of bookings an individual contact can make to a single Opening. - **Slots Per Opening:** How many bookings you want to allow per opening, if you're giving individual lessons this might be 1 but if you're booking our an event space this might be 100 or whatever you need. - **Booking Future Time:** This will limit user's ability to book openings more than X days/weeks/months in the future. - **Booking Lead Time:** This is the minimum amount time in the future a Booking can take place. This can be used to limit users booking same day/week/month booking - **Calendar Openings:** This is not user created but is an entity reference to each opening for this Calendar. ### Bookable Calendar Opening The individual openings for your Bookable Calendar. You can create as many of these as you'd like for your calendar. This is where you define what dates and times are available to book. Due to it being a multiple date value with repeat it's possible you could create only one of these per Bookable Calendar but the option is there to create as many as needed. The advantage af splitting them out is then it's easier to turn of a certain Opening whether that be a single day or opening as there is the status field to quickly turn it on or off vs editing your repeating date field to remove a day. - **Title:** Only shown to admins to quickly let you know what opening you're looking at. - **Status:** Easy turn it on/off for booking, you can turn the whole calendar off in the Bookable Calendar or here to turn off a single Opening. The individual openings for your Bookable Calendar. You can create as many of these as you'd like for your calendar. This is where you define what dates and times are available to book. Due to it being a multiple date value with repeat it's possible you could create only one of these per Bookable Calendar but the option is there to create as many as needed. The advantage af splitting them out is then it's easier to turn of a certain Opening whether that be a single day or opening as there is the status field to quickly turn it on or off vs editing your repeating date field to remove a day. - **Title:** Only shown to admins to quickly let you know what opening you're looking at. - **Status:** Easy turn it on/off for booking, you can turn the whole calendar off in the Bookable Calendar or here to turn off a single Opening. - **Bookable Calendar:** Reference to the calendar this opening is for. - **Booking Instance:** Not user created but links openings to instances. - **Date:** The date field that is repeatable for when this Opening occurs. ### Bookable Calendar Opening Instance This is an entity that you don't create directly, but per time slot that is open based on the date field on Bookable Calendar Opening an instance is created. Then users will register for indivdual instances. The indivdual instances are also what shows up on the listing of all bookings you book. This is an entity that you don't create directly, but per time slot that is open based on the date field on Bookable Calendar Opening an instance is created. Then users will register for indivdual instances. The indivdual instances are also what shows up on the listing of all bookings you book. - **Booking:** Points to all the Bookings that have Booked this Instance. - **Booking Opening:** Points to the parent Opening. Loading @@ -71,30 +83,33 @@ listing of all bookings you book. This is the entity that a front end user will be creating when they register. - **Email:** The email for this booking, this is used emails to confirm the booking and a link to edit the booking. - **Party Size:** The amount of people this booking is for, this lets us know how many slots are being taken by this booking. - **Email:** The email for this booking, this is used emails to confirm the booking and a link to edit the booking. - **Party Size:** The amount of people this booking is for, this lets us know how many slots are being taken by this booking. - **Booking Instance:** The instance this booking points to. - **Booking:** Not user created, the bookings this contact is linked to. ### Booking This is another entity no one creates directly, but when a new Contact is created a new Booking is created per person in the party size. This is how we know how many people have booked each instance easily. This is another entity no one creates directly, but when a new Contact is created a new Booking is created per person in the party size. This is how we know how many people have booked each instance easily. - **Created:** Time Booking was created. - **Booking Instance:** The Booking Instance this Booking is for. - **Booking Calendar:** The parent calendar this Booking is for. (this seems redundant but Instances might get cleaned up over time) - **Booking Calendar:** The parent calendar this Booking is for. (this seems redundant but Instances might get cleaned up over time) - **Contact:** The conctact that owns this Booking. - **Booking Date:** The date this Booking is for. This is because I see a situation where you need to clean up old Instances as you will most likely have thousands over the course of a year, but you might still want historic records of Bookings and what timeslot they booked. - **Booking Date:** The date this Booking is for. This is because I see a situation where you need to clean up old Instances as you will most likely have thousands over the course of a year, but you might still want historic records of Bookings and what timeslot they booked. ## API There are some API endpoints exposed so you can create new Bookings however you'd like. There are some API endpoints exposed so you can create new Bookings however you'd like. ### Book an Instance Loading Loading @@ -130,8 +145,8 @@ fetch("/bookable-calendar/{$instance_id}/book", requestOptions) ## Todo - Cleanup no longer matching instances maybe on cron. - Allow for cleanup on Cron based on settings of old Instances, Bookings and Contacts if you don't care about things older than X months. - Allow for cleanup on Cron based on settings of old Instances, Bookings and Contacts if you don't care about things older than X months. ## Quickly Delete Everything Loading @@ -146,13 +161,13 @@ $openings = $opening_storage->loadMultiple(); foreach ($openings as $opening) { $opening->delete(); } $instance_storage = \Drupal::entityTypeManager()->getStorage('bookable_calendar_opening_inst'); $instances = $instance_storage->loadMultiple(); $instanceStorage = \Drupal::entityTypeManager()->getStorage('bookable_calendar_opening_inst'); $instances = $instanceStorage->loadMultiple(); foreach ($instances as $instance) { $instance->delete(); } $booking_contact_storage = \Drupal::entityTypeManager()->getStorage('booking_contact'); $booking_contacts = $booking_contact_storage->loadMultiple(); $booking_contactStorage = \Drupal::entityTypeManager()->getStorage('booking_contact'); $booking_contacts = $booking_contactStorage->loadMultiple(); foreach ($booking_contacts as $contact) { $contact->delete(); } Loading
bookable_calendar.module +22 −22 Original line number Diff line number Diff line Loading @@ -91,11 +91,10 @@ function bookable_calendar_views_data_alter(array &$data) { } /** * Replace all titles on pages to make them easier to understand as there are no real titles. * Replace all titles on pages to make them easier to understand. * * @param array $variables * * @return void * Variables associated with hook_page_title. */ function template_preprocess_page_title(array &$variables) { $route_name = \Drupal::routeMatch()->getRouteName(); Loading Loading @@ -161,13 +160,13 @@ function template_preprocess_page_title(array &$variables) { * * @param array $variables * An associative array containing: * - elements: An associative array containing the bookable calendar information and any * fields attached to the entity. * - elements: An associative array containing the bookable calendar * information and any fields attached to the entity. * - attributes: HTML attributes for the containing element. */ function template_preprocess_bookable_calendar(array &$variables) { $entity_type_manager = \Drupal::service('entity_type.manager'); $instance_storage = $entity_type_manager->getStorage('bookable_calendar_opening_inst'); $entityTypeManager = \Drupal::service('entity_type.manager'); $instanceStorage = $entityTypeManager->getStorage('bookable_calendar_opening_inst'); $this_calendar = $variables['content']['#bookable_calendar']; $query = \Drupal::database()->select('bookable_calendar__calendar_openings', 'cal'); $query->fields('cal', [ Loading @@ -183,7 +182,7 @@ function template_preprocess_bookable_calendar(array &$variables) { $opening_instances = $query->execute()->fetchAllAssoc('id'); if ($opening_instances) { $instances = array_keys($opening_instances); $loaded_instances = $instance_storage->loadMultiple($instances); $loaded_instances = $instanceStorage->loadMultiple($instances); $variables['content']['instances'] = []; foreach ($loaded_instances as $key => $instance) { $render_instance = Drupal::entityTypeManager()->getViewBuilder('bookable_calendar_opening_inst')->view($instance); Loading @@ -199,18 +198,18 @@ function template_preprocess_bookable_calendar(array &$variables) { * * @param array $variables * An associative array containing: * - elements: An associative array containing the booking calendar opening information and any * fields attached to the entity. * - elements: An associative array containing the booking calendar opening * information and any fields attached to the entity. * - attributes: HTML attributes for the containing element. */ function template_preprocess_bookable_calendar_opening(array &$variables) { $entity_type_manager = \Drupal::service('entity_type.manager'); $instance_storage = $entity_type_manager->getStorage('bookable_calendar_opening_inst'); $entityTypeManager = \Drupal::service('entity_type.manager'); $instanceStorage = $entityTypeManager->getStorage('bookable_calendar_opening_inst'); $this_opening = $variables['content']['#bookable_calendar_opening']; $instances = $this_opening->get('booking_instance')->getValue(); $variables['instances'] = []; foreach ($instances as $key => $instance_id) { $instance = $instance_storage->load($instance_id['target_id']); $instance = $instanceStorage->load($instance_id['target_id']); if ($instance) { $render_instance = Drupal::entityTypeManager()->getViewBuilder('bookable_calendar_opening_inst')->view($instance); $variables['instances'][$key] = $render_instance; Loading @@ -226,8 +225,8 @@ function template_preprocess_bookable_calendar_opening(array &$variables) { * * @param array $variables * An associative array containing: * - elements: An associative array containing the booking contact information and any * fields attached to the entity. * - elements: An associative array containing the booking contact * information and any fields attached to the entity. * - attributes: HTML attributes for the containing element. */ function template_preprocess_booking_contact(array &$variables) { Loading @@ -241,8 +240,8 @@ function template_preprocess_booking_contact(array &$variables) { * * @param array $variables * An associative array containing: * - elements: An associative array containing the booking information and any * fields attached to the entity. * - elements: An associative array containing the booking information * and any fields attached to the entity. * - attributes: HTML attributes for the containing element. */ function template_preprocess_booking(array &$variables) { Loading @@ -256,8 +255,8 @@ function template_preprocess_booking(array &$variables) { * * @param array $variables * An associative array containing: * - elements: An associative array containing the bookable calendar opening instance information and any * fields attached to the entity. * - elements: An associative array containing the bookable calendar * opening instance information and any fields attached to the entity. * - attributes: HTML attributes for the containing element. */ function template_preprocess_bookable_calendar_opening_inst(array &$variables) { Loading Loading @@ -468,7 +467,7 @@ function bookable_calendar_tokens($type, $tokens, array $data, array $options, B } /** * * Form alters. */ function bookable_calendar_form_alter(&$form, FormStateInterface $form_state, $form_id) { if ($form_id === 'booking_contact_add_form') { Loading Loading @@ -517,7 +516,7 @@ function bookable_calendar_form_alter(&$form, FormStateInterface $form_state, $f } /** * * Redirect to front page when you delete your own booking. */ function bookable_calendar_delete_set_redirect($form, FormStateInterface $form_state) { $form_state->setRedirect('<front>'); Loading @@ -531,7 +530,8 @@ function bookable_calendar_views_post_execute(ViewExecutable $view) { if ($view->getBaseTables()['bookable_calendar_opening_inst'] ?? NULL) { // Handle available slots filter. if ($slots_filter = $view->storage->get('bookable_calendar_available_slots_filter')) { // Get filter values & operator and apply logic based on the instance's available slots. // Get filter values & operator and apply logic // based on the instance's available slots. $value = $slots_filter['value']['value'] ?? NULL; $min = $slots_filter['value']['min'] ?? NULL; $max = $slots_filter['value']['max'] ?? NULL; Loading
src/AvailableSlotsItemList.php +1 −1 Original line number Diff line number Diff line Loading @@ -7,7 +7,7 @@ use Drupal\Core\Field\FieldItemList; use Drupal\Core\TypedData\ComputedItemListTrait; /** * Item list for a computed field that displays the available slots for a bookable calendar opening instance. * Item list for a computed field that displays the available slots. */ class AvailableSlotsItemList extends FieldItemList { Loading
src/BookableCalendarAccessControlHandler.php +12 −3 Original line number Diff line number Diff line Loading @@ -22,10 +22,16 @@ class BookableCalendarAccessControlHandler extends EntityAccessControlHandler { return AccessResult::allowedIfHasPermission($account, 'view bookable calendar'); case 'update': return AccessResult::allowedIfHasPermissions($account, ['edit bookable calendar', 'administer bookable calendar'], 'OR'); return AccessResult::allowedIfHasPermissions($account, [ 'edit bookable calendar', 'administer bookable calendar', ], 'OR'); case 'delete': return AccessResult::allowedIfHasPermissions($account, ['delete bookable calendar', 'administer bookable calendar'], 'OR'); return AccessResult::allowedIfHasPermissions($account, [ 'delete bookable calendar', 'administer bookable calendar', ], 'OR'); default: // No opinion. Loading @@ -38,7 +44,10 @@ class BookableCalendarAccessControlHandler extends EntityAccessControlHandler { * {@inheritdoc} */ protected function checkCreateAccess(AccountInterface $account, array $context, $entity_bundle = NULL) { return AccessResult::allowedIfHasPermissions($account, ['create bookable calendar', 'administer bookable calendar'], 'OR'); return AccessResult::allowedIfHasPermissions($account, [ 'create bookable calendar', 'administer bookable calendar', ], 'OR'); } }
src/BookableCalendarOpeningAccessControlHandler.php +13 −4 Original line number Diff line number Diff line Loading @@ -8,7 +8,7 @@ use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Session\AccountInterface; /** * Defines the access control handler for the bookable calendar opening entity type. * Defines the access control handler for the bookable calendar opening. */ class BookableCalendarOpeningAccessControlHandler extends EntityAccessControlHandler { Loading @@ -22,10 +22,16 @@ class BookableCalendarOpeningAccessControlHandler extends EntityAccessControlHan return AccessResult::allowedIfHasPermission($account, 'view bookable calendar opening'); case 'update': return AccessResult::allowedIfHasPermissions($account, ['edit bookable calendar opening', 'administer bookable calendar opening'], 'OR'); return AccessResult::allowedIfHasPermissions($account, [ 'edit bookable calendar opening', 'administer bookable calendar opening', ], 'OR'); case 'delete': return AccessResult::allowedIfHasPermissions($account, ['delete bookable calendar opening', 'administer bookable calendar opening'], 'OR'); return AccessResult::allowedIfHasPermissions($account, [ 'delete bookable calendar opening', 'administer bookable calendar opening', ], 'OR'); default: // No opinion. Loading @@ -38,7 +44,10 @@ class BookableCalendarOpeningAccessControlHandler extends EntityAccessControlHan * {@inheritdoc} */ protected function checkCreateAccess(AccountInterface $account, array $context, $entity_bundle = NULL) { return AccessResult::allowedIfHasPermissions($account, ['create bookable calendar opening', 'administer bookable calendar opening'], 'OR'); return AccessResult::allowedIfHasPermissions($account, [ 'create bookable calendar opening', 'administer bookable calendar opening', ], 'OR'); } }