Peter Lindstrom
6 years ago
101 changed files with 8818 additions and 0 deletions
@ -0,0 +1,14 @@ |
|||||||
|
{ |
||||||
|
"name": "drupal/reserve", |
||||||
|
"type": "drupal-module", |
||||||
|
"description": "Reservation system.", |
||||||
|
"keywords": ["Drupal"], |
||||||
|
"license": "GPL-2.0+", |
||||||
|
"homepage": "https://www.drupal.org/project/reserve", |
||||||
|
"minimum-stability": "dev", |
||||||
|
"support": { |
||||||
|
"issues": "https://www.drupal.org/project/issues/reserve", |
||||||
|
"source": "http://cgit.drupalcode.org/reserve" |
||||||
|
}, |
||||||
|
"require": { } |
||||||
|
} |
@ -0,0 +1,63 @@ |
|||||||
|
langcode: en |
||||||
|
status: true |
||||||
|
dependencies: |
||||||
|
config: |
||||||
|
- field.field.reserve_category.reserve_category.reserve_setup_buffer |
||||||
|
- field.field.reserve_category.reserve_category.reserve_takedown_buffer |
||||||
|
- field.field.reserve_category.reserve_category.reserve_minadv_std |
||||||
|
- field.field.reserve_category.reserve_category.reserve_minadv_ext |
||||||
|
- field.field.reserve_category.reserve_category.reserve_maxadv_std |
||||||
|
- field.field.reserve_category.reserve_category.reserve_maxadv_ext |
||||||
|
module: |
||||||
|
- reserve |
||||||
|
id: reserve_category.reserve_category.default |
||||||
|
targetEntityType: reserve_category |
||||||
|
bundle: reserve_category |
||||||
|
mode: default |
||||||
|
content: |
||||||
|
name: |
||||||
|
weight: -10 |
||||||
|
type: string_textfield |
||||||
|
region: content |
||||||
|
settings: |
||||||
|
size: 60 |
||||||
|
placeholder: '' |
||||||
|
third_party_settings: { } |
||||||
|
reserve_setup_buffer: |
||||||
|
weight: 1 |
||||||
|
settings: { } |
||||||
|
third_party_settings: { } |
||||||
|
type: options_select |
||||||
|
region: content |
||||||
|
reserve_takedown_buffer: |
||||||
|
weight: 2 |
||||||
|
settings: { } |
||||||
|
third_party_settings: { } |
||||||
|
type: options_select |
||||||
|
region: content |
||||||
|
reserve_minadv_std: |
||||||
|
weight: 3 |
||||||
|
settings: { } |
||||||
|
third_party_settings: { } |
||||||
|
type: options_select |
||||||
|
region: content |
||||||
|
reserve_minadv_ext: |
||||||
|
weight: 4 |
||||||
|
settings: { } |
||||||
|
third_party_settings: { } |
||||||
|
type: options_select |
||||||
|
region: content |
||||||
|
reserve_maxadv_std: |
||||||
|
weight: 5 |
||||||
|
settings: { } |
||||||
|
third_party_settings: { } |
||||||
|
type: options_select |
||||||
|
region: content |
||||||
|
reserve_maxadv_ext: |
||||||
|
weight: 6 |
||||||
|
settings: { } |
||||||
|
third_party_settings: { } |
||||||
|
type: options_select |
||||||
|
region: content |
||||||
|
hidden: |
||||||
|
user_id: true |
@ -0,0 +1,108 @@ |
|||||||
|
langcode: en |
||||||
|
status: true |
||||||
|
dependencies: |
||||||
|
config: |
||||||
|
- field.field.reserve_reservation.reserve_reservation.reservable_content_type |
||||||
|
- field.field.reserve_reservation.reserve_reservation.reservable_id |
||||||
|
- field.field.reserve_reservation.reserve_reservation.reservation_date |
||||||
|
- field.field.reserve_reservation.reserve_reservation.reservation_ebundle |
||||||
|
- field.field.reserve_reservation.reserve_reservation.reservation_length |
||||||
|
- field.field.reserve_reservation.reserve_reservation.reservation_private |
||||||
|
- field.field.reserve_reservation.reserve_reservation.reservation_repeat_type |
||||||
|
- field.field.reserve_reservation.reserve_reservation.reservation_repeat_until |
||||||
|
- field.field.reserve_reservation.reserve_reservation.reservation_series_id |
||||||
|
- field.field.reserve_reservation.reserve_reservation.reservation_time |
||||||
|
module: |
||||||
|
- datetime |
||||||
|
- reserve |
||||||
|
_core: |
||||||
|
default_config_hash: LCDU3FONhj8ylh6Px2atCBl0dR8sFemI3vnXDt5TyCE |
||||||
|
id: reserve_reservation.reserve_reservation.default |
||||||
|
targetEntityType: reserve_reservation |
||||||
|
bundle: reserve_reservation |
||||||
|
mode: default |
||||||
|
content: |
||||||
|
name: |
||||||
|
type: string_textfield |
||||||
|
weight: 0 |
||||||
|
settings: |
||||||
|
size: 60 |
||||||
|
placeholder: '' |
||||||
|
third_party_settings: { } |
||||||
|
region: content |
||||||
|
reservable_content_type: |
||||||
|
type: options_select |
||||||
|
weight: 9 |
||||||
|
region: content |
||||||
|
settings: { } |
||||||
|
third_party_settings: { } |
||||||
|
reservable_id: |
||||||
|
weight: 9 |
||||||
|
settings: |
||||||
|
placeholder: '' |
||||||
|
third_party_settings: { } |
||||||
|
type: number |
||||||
|
region: content |
||||||
|
reservation_date: |
||||||
|
weight: 2 |
||||||
|
settings: { } |
||||||
|
third_party_settings: { } |
||||||
|
type: datetime_default |
||||||
|
region: content |
||||||
|
reservation_length: |
||||||
|
weight: 4 |
||||||
|
settings: { } |
||||||
|
third_party_settings: { } |
||||||
|
type: options_select |
||||||
|
region: content |
||||||
|
reservation_private: |
||||||
|
weight: 1 |
||||||
|
settings: |
||||||
|
display_label: true |
||||||
|
third_party_settings: { } |
||||||
|
type: boolean_checkbox |
||||||
|
region: content |
||||||
|
reservation_repeat_type: |
||||||
|
weight: 5 |
||||||
|
settings: { } |
||||||
|
third_party_settings: { } |
||||||
|
type: options_select |
||||||
|
region: content |
||||||
|
reservation_repeat_until: |
||||||
|
weight: 6 |
||||||
|
settings: { } |
||||||
|
third_party_settings: { } |
||||||
|
type: datetime_default |
||||||
|
region: content |
||||||
|
reservation_series_id: |
||||||
|
weight: 7 |
||||||
|
settings: |
||||||
|
placeholder: '' |
||||||
|
third_party_settings: { } |
||||||
|
type: number |
||||||
|
region: content |
||||||
|
reservation_time: |
||||||
|
weight: 3 |
||||||
|
settings: |
||||||
|
size: 60 |
||||||
|
placeholder: '' |
||||||
|
third_party_settings: { } |
||||||
|
type: string_textfield |
||||||
|
region: content |
||||||
|
user_id: |
||||||
|
type: entity_reference_autocomplete |
||||||
|
weight: 8 |
||||||
|
settings: |
||||||
|
match_operator: CONTAINS |
||||||
|
size: 60 |
||||||
|
placeholder: '' |
||||||
|
third_party_settings: { } |
||||||
|
region: content |
||||||
|
reservation_ebundle: |
||||||
|
weight: 9 |
||||||
|
settings: |
||||||
|
size: 60 |
||||||
|
placeholder: '' |
||||||
|
third_party_settings: { } |
||||||
|
type: string_textfield |
||||||
|
region: content |
@ -0,0 +1,72 @@ |
|||||||
|
langcode: en |
||||||
|
status: true |
||||||
|
dependencies: |
||||||
|
config: |
||||||
|
- field.field.reserve_category.reserve_category.reserve_setup_buffer |
||||||
|
- field.field.reserve_category.reserve_category.reserve_takedown_buffer |
||||||
|
- field.field.reserve_category.reserve_category.reserve_minadv_std |
||||||
|
- field.field.reserve_category.reserve_category.reserve_minadv_ext |
||||||
|
- field.field.reserve_category.reserve_category.reserve_maxadv_std |
||||||
|
- field.field.reserve_category.reserve_category.reserve_maxadv_ext |
||||||
|
module: |
||||||
|
- options |
||||||
|
- reserve |
||||||
|
- user |
||||||
|
id: reserve_category.reserve_category.default |
||||||
|
targetEntityType: reserve_category |
||||||
|
bundle: reserve_category |
||||||
|
mode: default |
||||||
|
content: |
||||||
|
name: |
||||||
|
weight: -10 |
||||||
|
label: hidden |
||||||
|
type: string |
||||||
|
region: content |
||||||
|
settings: |
||||||
|
link_to_entity: false |
||||||
|
third_party_settings: { } |
||||||
|
reserve_setup_buffer: |
||||||
|
weight: 1 |
||||||
|
label: inline |
||||||
|
type: list_default |
||||||
|
region: content |
||||||
|
settings: { } |
||||||
|
third_party_settings: { } |
||||||
|
reserve_takedown_buffer: |
||||||
|
weight: 2 |
||||||
|
label: inline |
||||||
|
type: list_default |
||||||
|
region: content |
||||||
|
settings: { } |
||||||
|
third_party_settings: { } |
||||||
|
reserve_minadv_std: |
||||||
|
weight: 3 |
||||||
|
label: inline |
||||||
|
type: list_default |
||||||
|
region: content |
||||||
|
settings: { } |
||||||
|
third_party_settings: { } |
||||||
|
reserve_minadv_ext: |
||||||
|
weight: 4 |
||||||
|
label: inline |
||||||
|
type: list_default |
||||||
|
region: content |
||||||
|
settings: { } |
||||||
|
third_party_settings: { } |
||||||
|
reserve_maxadv_std: |
||||||
|
weight: 5 |
||||||
|
label: inline |
||||||
|
type: list_default |
||||||
|
region: content |
||||||
|
settings: { } |
||||||
|
third_party_settings: { } |
||||||
|
reserve_maxadv_ext: |
||||||
|
weight: 6 |
||||||
|
label: inline |
||||||
|
type: list_default |
||||||
|
region: content |
||||||
|
settings: { } |
||||||
|
third_party_settings: { } |
||||||
|
hidden: |
||||||
|
user_id: true |
||||||
|
|
@ -0,0 +1,104 @@ |
|||||||
|
langcode: en |
||||||
|
status: true |
||||||
|
dependencies: |
||||||
|
config: |
||||||
|
- field.field.reserve_reservation.reserve_reservation.reservable_content_type |
||||||
|
- field.field.reserve_reservation.reserve_reservation.reservable_id |
||||||
|
- field.field.reserve_reservation.reserve_reservation.reservation_date |
||||||
|
- field.field.reserve_reservation.reserve_reservation.reservation_ebundle |
||||||
|
- field.field.reserve_reservation.reserve_reservation.reservation_length |
||||||
|
- field.field.reserve_reservation.reserve_reservation.reservation_private |
||||||
|
- field.field.reserve_reservation.reserve_reservation.reservation_repeat_type |
||||||
|
- field.field.reserve_reservation.reserve_reservation.reservation_repeat_until |
||||||
|
- field.field.reserve_reservation.reserve_reservation.reservation_series_id |
||||||
|
- field.field.reserve_reservation.reserve_reservation.reservation_time |
||||||
|
module: |
||||||
|
- datetime |
||||||
|
- options |
||||||
|
- reserve |
||||||
|
- user |
||||||
|
_core: |
||||||
|
default_config_hash: 2s_-pGyf2O4EgKGyzwqMfNGNDoQcLHAdTET2ioShrjo |
||||||
|
id: reserve_reservation.reserve_reservation.default |
||||||
|
targetEntityType: reserve_reservation |
||||||
|
bundle: reserve_reservation |
||||||
|
mode: default |
||||||
|
content: |
||||||
|
name: |
||||||
|
label: above |
||||||
|
type: string |
||||||
|
weight: -4 |
||||||
|
settings: |
||||||
|
link_to_entity: false |
||||||
|
third_party_settings: { } |
||||||
|
region: content |
||||||
|
reservation_date: |
||||||
|
weight: 7 |
||||||
|
label: above |
||||||
|
settings: |
||||||
|
format_type: medium |
||||||
|
timezone_override: '' |
||||||
|
third_party_settings: { } |
||||||
|
type: datetime_default |
||||||
|
region: content |
||||||
|
reservation_length: |
||||||
|
weight: 2 |
||||||
|
label: above |
||||||
|
settings: { } |
||||||
|
third_party_settings: { } |
||||||
|
type: list_default |
||||||
|
region: content |
||||||
|
reservation_private: |
||||||
|
weight: 1 |
||||||
|
label: above |
||||||
|
settings: |
||||||
|
format: default |
||||||
|
format_custom_false: '' |
||||||
|
format_custom_true: '' |
||||||
|
third_party_settings: { } |
||||||
|
type: boolean |
||||||
|
region: content |
||||||
|
reservation_repeat_type: |
||||||
|
weight: 3 |
||||||
|
label: above |
||||||
|
settings: { } |
||||||
|
third_party_settings: { } |
||||||
|
type: list_default |
||||||
|
region: content |
||||||
|
reservation_repeat_until: |
||||||
|
weight: 4 |
||||||
|
label: above |
||||||
|
settings: |
||||||
|
format_type: medium |
||||||
|
timezone_override: '' |
||||||
|
third_party_settings: { } |
||||||
|
type: datetime_default |
||||||
|
region: content |
||||||
|
reservation_series_id: |
||||||
|
weight: 6 |
||||||
|
label: above |
||||||
|
settings: |
||||||
|
thousand_separator: '' |
||||||
|
prefix_suffix: true |
||||||
|
third_party_settings: { } |
||||||
|
type: number_integer |
||||||
|
region: content |
||||||
|
reservation_time: |
||||||
|
weight: 5 |
||||||
|
label: above |
||||||
|
settings: |
||||||
|
link_to_entity: false |
||||||
|
third_party_settings: { } |
||||||
|
type: string |
||||||
|
region: content |
||||||
|
user_id: |
||||||
|
label: hidden |
||||||
|
type: author |
||||||
|
weight: 0 |
||||||
|
settings: { } |
||||||
|
third_party_settings: { } |
||||||
|
region: content |
||||||
|
hidden: |
||||||
|
reservable_content_type: true |
||||||
|
reservable_id: true |
||||||
|
reservation_ebundle: true |
@ -0,0 +1,22 @@ |
|||||||
|
langcode: en |
||||||
|
status: true |
||||||
|
dependencies: |
||||||
|
config: |
||||||
|
- field.storage.reserve_category.reserve_maxadv_ext |
||||||
|
module: |
||||||
|
- options |
||||||
|
- reserve |
||||||
|
id: reserve_category.reserve_category.reserve_maxadv_ext |
||||||
|
field_name: reserve_maxadv_ext |
||||||
|
entity_type: reserve_category |
||||||
|
bundle: reserve_category |
||||||
|
label: 'Maximum Advanced Booking (extended)' |
||||||
|
description: 'Maximum number of days in advance that a booking may be made (extended user). Default value is 180.' |
||||||
|
required: true |
||||||
|
translatable: false |
||||||
|
default_value: |
||||||
|
- |
||||||
|
value: 180 |
||||||
|
default_value_callback: '' |
||||||
|
settings: { } |
||||||
|
field_type: list_integer |
@ -0,0 +1,22 @@ |
|||||||
|
langcode: en |
||||||
|
status: true |
||||||
|
dependencies: |
||||||
|
config: |
||||||
|
- field.storage.reserve_category.reserve_maxadv_std |
||||||
|
module: |
||||||
|
- options |
||||||
|
- reserve |
||||||
|
id: reserve_category.reserve_category.reserve_maxadv_std |
||||||
|
field_name: reserve_maxadv_std |
||||||
|
entity_type: reserve_category |
||||||
|
bundle: reserve_category |
||||||
|
label: 'Maximum Advanced Booking (standard)' |
||||||
|
description: 'Maximum number of days in advance that a booking may be made (standard user). Default value is 14.' |
||||||
|
required: true |
||||||
|
translatable: false |
||||||
|
default_value: |
||||||
|
- |
||||||
|
value: 14 |
||||||
|
default_value_callback: '' |
||||||
|
settings: { } |
||||||
|
field_type: list_integer |
@ -0,0 +1,22 @@ |
|||||||
|
langcode: en |
||||||
|
status: true |
||||||
|
dependencies: |
||||||
|
config: |
||||||
|
- field.storage.reserve_category.reserve_minadv_ext |
||||||
|
module: |
||||||
|
- options |
||||||
|
- reserve |
||||||
|
id: reserve_category.reserve_category.reserve_minadv_ext |
||||||
|
field_name: reserve_minadv_ext |
||||||
|
entity_type: reserve_category |
||||||
|
bundle: reserve_category |
||||||
|
label: 'Minimum Advance Booking (extended)' |
||||||
|
description: 'Minimum number of days in advance that a booking may be made (extended user). Default value is 0.' |
||||||
|
required: true |
||||||
|
translatable: false |
||||||
|
default_value: |
||||||
|
- |
||||||
|
value: 0 |
||||||
|
default_value_callback: '' |
||||||
|
settings: { } |
||||||
|
field_type: list_integer |
@ -0,0 +1,22 @@ |
|||||||
|
langcode: en |
||||||
|
status: true |
||||||
|
dependencies: |
||||||
|
config: |
||||||
|
- field.storage.reserve_category.reserve_minadv_std |
||||||
|
module: |
||||||
|
- options |
||||||
|
- reserve |
||||||
|
id: reserve_category.reserve_category.reserve_minadv_std |
||||||
|
field_name: reserve_minadv_std |
||||||
|
entity_type: reserve_category |
||||||
|
bundle: reserve_category |
||||||
|
label: 'Minimum Advanced Booking (standard)' |
||||||
|
description: 'Minimum number of days in advance that a booking may be made (standard user). Default value is 0.' |
||||||
|
required: true |
||||||
|
translatable: false |
||||||
|
default_value: |
||||||
|
- |
||||||
|
value: 0 |
||||||
|
default_value_callback: '' |
||||||
|
settings: { } |
||||||
|
field_type: list_integer |
@ -0,0 +1,22 @@ |
|||||||
|
langcode: en |
||||||
|
status: true |
||||||
|
dependencies: |
||||||
|
config: |
||||||
|
- field.storage.reserve_category.reserve_setup_buffer |
||||||
|
module: |
||||||
|
- options |
||||||
|
- reserve |
||||||
|
id: reserve_category.reserve_category.reserve_setup_buffer |
||||||
|
field_name: reserve_setup_buffer |
||||||
|
entity_type: reserve_category |
||||||
|
bundle: reserve_category |
||||||
|
label: 'Setup Buffer' |
||||||
|
description: 'Setup time required for reservations for all items in this category. This time will be added to each reservation to extend the reserved calendar time.' |
||||||
|
required: true |
||||||
|
translatable: false |
||||||
|
default_value: |
||||||
|
- |
||||||
|
value: 0 |
||||||
|
default_value_callback: '' |
||||||
|
settings: { } |
||||||
|
field_type: list_integer |
@ -0,0 +1,22 @@ |
|||||||
|
langcode: en |
||||||
|
status: true |
||||||
|
dependencies: |
||||||
|
config: |
||||||
|
- field.storage.reserve_category.reserve_takedown_buffer |
||||||
|
module: |
||||||
|
- options |
||||||
|
- reserve |
||||||
|
id: reserve_category.reserve_category.reserve_takedown_buffer |
||||||
|
field_name: reserve_takedown_buffer |
||||||
|
entity_type: reserve_category |
||||||
|
bundle: reserve_category |
||||||
|
label: 'Takedown Buffer' |
||||||
|
description: 'Takedown time required for reservations for all items in this category. This time will be added to each reservation to extend the reserved calendar time.' |
||||||
|
required: true |
||||||
|
translatable: false |
||||||
|
default_value: |
||||||
|
- |
||||||
|
value: 0 |
||||||
|
default_value_callback: '' |
||||||
|
settings: { } |
||||||
|
field_type: list_integer |
@ -0,0 +1,21 @@ |
|||||||
|
langcode: en |
||||||
|
status: true |
||||||
|
dependencies: |
||||||
|
config: |
||||||
|
- field.storage.reserve_reservation.reservable_content_type |
||||||
|
module: |
||||||
|
- options |
||||||
|
- reserve |
||||||
|
id: reserve_reservation.reserve_reservation.reservable_content_type |
||||||
|
field_name: reservable_content_type |
||||||
|
entity_type: reserve_reservation |
||||||
|
bundle: reserve_reservation |
||||||
|
label: 'Reservable Entity Type' |
||||||
|
description: 'Holds the type of content entity that this reservation is being made on. Set through the UI.' |
||||||
|
required: false |
||||||
|
translatable: false |
||||||
|
default_value: |
||||||
|
default_value_callback: '' |
||||||
|
settings: { } |
||||||
|
field_type: list_string |
||||||
|
locked: true |
@ -0,0 +1,24 @@ |
|||||||
|
langcode: en |
||||||
|
status: true |
||||||
|
dependencies: |
||||||
|
config: |
||||||
|
- field.storage.reserve_reservation.reservable_id |
||||||
|
module: |
||||||
|
- reserve |
||||||
|
id: reserve_reservation.reserve_reservation.reservable_id |
||||||
|
field_name: reservable_id |
||||||
|
entity_type: reserve_reservation |
||||||
|
bundle: reserve_reservation |
||||||
|
label: 'Reservable ID' |
||||||
|
description: 'Holds the entity id of the item being reserved. Automatically added through the calendar UI.' |
||||||
|
required: false |
||||||
|
translatable: false |
||||||
|
default_value: { } |
||||||
|
default_value_callback: '' |
||||||
|
settings: |
||||||
|
min: null |
||||||
|
max: null |
||||||
|
prefix: '' |
||||||
|
suffix: '' |
||||||
|
field_type: integer |
||||||
|
locked: true |
@ -0,0 +1,21 @@ |
|||||||
|
langcode: en |
||||||
|
status: true |
||||||
|
dependencies: |
||||||
|
config: |
||||||
|
- field.storage.reserve_reservation.reservation_date |
||||||
|
module: |
||||||
|
- datetime |
||||||
|
- reserve |
||||||
|
id: reserve_reservation.reserve_reservation.reservation_date |
||||||
|
field_name: reservation_date |
||||||
|
entity_type: reserve_reservation |
||||||
|
bundle: reserve_reservation |
||||||
|
label: Date |
||||||
|
description: '' |
||||||
|
required: false |
||||||
|
translatable: false |
||||||
|
default_value: { } |
||||||
|
default_value_callback: '' |
||||||
|
settings: { } |
||||||
|
field_type: datetime |
||||||
|
locked: true |
@ -0,0 +1,19 @@ |
|||||||
|
langcode: en |
||||||
|
status: true |
||||||
|
dependencies: |
||||||
|
config: |
||||||
|
- field.storage.reserve_reservation.reservation_ebundle |
||||||
|
module: |
||||||
|
- reserve |
||||||
|
id: reserve_reservation.reserve_reservation.reservation_ebundle |
||||||
|
field_name: reservation_ebundle |
||||||
|
entity_type: reserve_reservation |
||||||
|
bundle: reserve_reservation |
||||||
|
label: Ebundle |
||||||
|
description: '' |
||||||
|
required: false |
||||||
|
translatable: false |
||||||
|
default_value: { } |
||||||
|
default_value_callback: '' |
||||||
|
settings: { } |
||||||
|
field_type: string |
@ -0,0 +1,20 @@ |
|||||||
|
langcode: en |
||||||
|
status: true |
||||||
|
dependencies: |
||||||
|
config: |
||||||
|
- field.storage.reserve_reservation.reservation_length |
||||||
|
module: |
||||||
|
- options |
||||||
|
- reserve |
||||||
|
id: reserve_reservation.reserve_reservation.reservation_length |
||||||
|
field_name: reservation_length |
||||||
|
entity_type: reserve_reservation |
||||||
|
bundle: reserve_reservation |
||||||
|
label: 'Length' |
||||||
|
description: '' |
||||||
|
required: true |
||||||
|
translatable: false |
||||||
|
default_value: { } |
||||||
|
default_value_callback: '' |
||||||
|
settings: { } |
||||||
|
field_type: list_integer |
@ -0,0 +1,23 @@ |
|||||||
|
langcode: en |
||||||
|
status: true |
||||||
|
dependencies: |
||||||
|
config: |
||||||
|
- field.storage.reserve_reservation.reservation_private |
||||||
|
module: |
||||||
|
- reserve |
||||||
|
id: reserve_reservation.reserve_reservation.reservation_private |
||||||
|
field_name: reservation_private |
||||||
|
entity_type: reserve_reservation |
||||||
|
bundle: reserve_reservation |
||||||
|
label: Private |
||||||
|
description: 'Check this to hide the Group Name for this reservation.' |
||||||
|
required: false |
||||||
|
translatable: false |
||||||
|
default_value: |
||||||
|
- |
||||||
|
value: 0 |
||||||
|
default_value_callback: '' |
||||||
|
settings: |
||||||
|
on_label: Private |
||||||
|
off_label: Public |
||||||
|
field_type: boolean |
@ -0,0 +1,22 @@ |
|||||||
|
langcode: en |
||||||
|
status: true |
||||||
|
dependencies: |
||||||
|
config: |
||||||
|
- field.storage.reserve_reservation.reservation_repeat_type |
||||||
|
module: |
||||||
|
- options |
||||||
|
- reserve |
||||||
|
id: reserve_reservation.reserve_reservation.reservation_repeat_type |
||||||
|
field_name: reservation_repeat_type |
||||||
|
entity_type: reserve_reservation |
||||||
|
bundle: reserve_reservation |
||||||
|
label: 'Repeat Type' |
||||||
|
description: '' |
||||||
|
required: true |
||||||
|
translatable: false |
||||||
|
default_value: |
||||||
|
- |
||||||
|
value: 0 |
||||||
|
default_value_callback: '' |
||||||
|
settings: { } |
||||||
|
field_type: list_integer |
@ -0,0 +1,20 @@ |
|||||||
|
langcode: en |
||||||
|
status: true |
||||||
|
dependencies: |
||||||
|
config: |
||||||
|
- field.storage.reserve_reservation.reservation_repeat_until |
||||||
|
module: |
||||||
|
- datetime |
||||||
|
- reserve |
||||||
|
id: reserve_reservation.reserve_reservation.reservation_repeat_until |
||||||
|
field_name: reservation_repeat_until |
||||||
|
entity_type: reserve_reservation |
||||||
|
bundle: reserve_reservation |
||||||
|
label: 'Repeat Until' |
||||||
|
description: '' |
||||||
|
required: false |
||||||
|
translatable: false |
||||||
|
default_value: { } |
||||||
|
default_value_callback: '' |
||||||
|
settings: { } |
||||||
|
field_type: datetime |
@ -0,0 +1,23 @@ |
|||||||
|
langcode: en |
||||||
|
status: true |
||||||
|
dependencies: |
||||||
|
config: |
||||||
|
- field.storage.reserve_reservation.reservation_series_id |
||||||
|
module: |
||||||
|
- reserve |
||||||
|
id: reserve_reservation.reserve_reservation.reservation_series_id |
||||||
|
field_name: reservation_series_id |
||||||
|
entity_type: reserve_reservation |
||||||
|
bundle: reserve_reservation |
||||||
|
label: 'Series ID' |
||||||
|
description: '' |
||||||
|
required: false |
||||||
|
translatable: false |
||||||
|
default_value: { } |
||||||
|
default_value_callback: '' |
||||||
|
settings: |
||||||
|
min: null |
||||||
|
max: null |
||||||
|
prefix: '' |
||||||
|
suffix: '' |
||||||
|
field_type: integer |
@ -0,0 +1,19 @@ |
|||||||
|
langcode: en |
||||||
|
status: true |
||||||
|
dependencies: |
||||||
|
config: |
||||||
|
- field.storage.reserve_reservation.reservation_time |
||||||
|
module: |
||||||
|
- reserve |
||||||
|
id: reserve_reservation.reserve_reservation.reservation_time |
||||||
|
field_name: reservation_time |
||||||
|
entity_type: reserve_reservation |
||||||
|
bundle: reserve_reservation |
||||||
|
label: Time |
||||||
|
description: '' |
||||||
|
required: false |
||||||
|
translatable: false |
||||||
|
default_value: { } |
||||||
|
default_value_callback: '' |
||||||
|
settings: { } |
||||||
|
field_type: string |
@ -0,0 +1,34 @@ |
|||||||
|
langcode: en |
||||||
|
status: true |
||||||
|
dependencies: |
||||||
|
module: |
||||||
|
- options |
||||||
|
- reserve |
||||||
|
id: reserve_category.reserve_maxadv_ext |
||||||
|
field_name: reserve_maxadv_ext |
||||||
|
entity_type: reserve_category |
||||||
|
type: list_integer |
||||||
|
settings: |
||||||
|
allowed_values: |
||||||
|
- |
||||||
|
value: 30 |
||||||
|
label: 30 |
||||||
|
- |
||||||
|
value: 60 |
||||||
|
label: 60 |
||||||
|
- |
||||||
|
value: 90 |
||||||
|
label: 90 |
||||||
|
- |
||||||
|
value: 180 |
||||||
|
label: 180 |
||||||
|
- |
||||||
|
value: 360 |
||||||
|
label: 360 |
||||||
|
module: options |
||||||
|
locked: true |
||||||
|
cardinality: 1 |
||||||
|
translatable: false |
||||||
|
indexes: { } |
||||||
|
persist_with_no_fields: false |
||||||
|
custom_storage: false |
@ -0,0 +1,34 @@ |
|||||||
|
langcode: en |
||||||
|
status: true |
||||||
|
dependencies: |
||||||
|
module: |
||||||
|
- options |
||||||
|
- reserve |
||||||
|
id: reserve_category.reserve_maxadv_std |
||||||
|
field_name: reserve_maxadv_std |
||||||
|
entity_type: reserve_category |
||||||
|
type: list_integer |
||||||
|
settings: |
||||||
|
allowed_values: |
||||||
|
- |
||||||
|
value: 7 |
||||||
|
label: 7 |
||||||
|
- |
||||||
|
value: 14 |
||||||
|
label: 14 |
||||||
|
- |
||||||
|
value: 30 |
||||||
|
label: 30 |
||||||
|
- |
||||||
|
value: 60 |
||||||
|
label: 60 |
||||||
|
- |
||||||
|
value: 90 |
||||||
|
label: 90 |
||||||
|
module: options |
||||||
|
locked: true |
||||||
|
cardinality: 1 |
||||||
|
translatable: false |
||||||
|
indexes: { } |
||||||
|
persist_with_no_fields: false |
||||||
|
custom_storage: false |
@ -0,0 +1,34 @@ |
|||||||
|
langcode: en |
||||||
|
status: true |
||||||
|
dependencies: |
||||||
|
module: |
||||||
|
- options |
||||||
|
- reserve |
||||||
|
id: reserve_category.reserve_minadv_ext |
||||||
|
field_name: reserve_minadv_ext |
||||||
|
entity_type: reserve_category |
||||||
|
type: list_integer |
||||||
|
settings: |
||||||
|
allowed_values: |
||||||
|
- |
||||||
|
value: 0 |
||||||
|
label: 0 |
||||||
|
- |
||||||
|
value: 1 |
||||||
|
label: 1 |
||||||
|
- |
||||||
|
value: 7 |
||||||
|
label: 7 |
||||||
|
- |
||||||
|
value: 14 |
||||||
|
label: 14 |
||||||
|
- |
||||||
|
value: 30 |
||||||
|
label: 30 |
||||||
|
module: options |
||||||
|
locked: true |
||||||
|
cardinality: 1 |
||||||
|
translatable: false |
||||||
|
indexes: { } |
||||||
|
persist_with_no_fields: false |
||||||
|
custom_storage: false |
@ -0,0 +1,34 @@ |
|||||||
|
langcode: en |
||||||
|
status: true |
||||||
|
dependencies: |
||||||
|
module: |
||||||
|
- options |
||||||
|
- reserve |
||||||
|
id: reserve_category.reserve_minadv_std |
||||||
|
field_name: reserve_minadv_std |
||||||
|
entity_type: reserve_category |
||||||
|
type: list_integer |
||||||
|
settings: |
||||||
|
allowed_values: |
||||||
|
- |
||||||
|
value: 0 |
||||||
|
label: 0 |
||||||
|
- |
||||||
|
value: 1 |
||||||
|
label: 1 |
||||||
|
- |
||||||
|
value: 7 |
||||||
|
label: 7 |
||||||
|
- |
||||||
|
value: 14 |
||||||
|
label: 14 |
||||||
|
- |
||||||
|
value: 30 |
||||||
|
label: 30 |
||||||
|
module: options |
||||||
|
locked: true |
||||||
|
cardinality: 1 |
||||||
|
translatable: false |
||||||
|
indexes: { } |
||||||
|
persist_with_no_fields: false |
||||||
|
custom_storage: false |
@ -0,0 +1,35 @@ |
|||||||
|
langcode: en |
||||||
|
status: true |
||||||
|
dependencies: |
||||||
|
module: |
||||||
|
- options |
||||||
|
- reserve |
||||||
|
id: reserve_category.reserve_setup_buffer |
||||||
|
field_name: reserve_setup_buffer |
||||||
|
entity_type: reserve_category |
||||||
|
type: list_integer |
||||||
|
settings: |
||||||
|
allowed_values: |
||||||
|
- |
||||||
|
value: 0 |
||||||
|
label: none |
||||||
|
- |
||||||
|
value: 30 |
||||||
|
label: '30 minutes' |
||||||
|
- |
||||||
|
value: 60 |
||||||
|
label: '1 hour' |
||||||
|
- |
||||||
|
value: 90 |
||||||
|
label: '90 minutes' |
||||||
|
- |
||||||
|
value: 120 |
||||||
|
label: '2 hours' |
||||||
|
allowed_values_function: '' |
||||||
|
module: options |
||||||
|
locked: true |
||||||
|
cardinality: 1 |
||||||
|
translatable: true |
||||||
|
indexes: { } |
||||||
|
persist_with_no_fields: false |
||||||
|
custom_storage: false |
@ -0,0 +1,35 @@ |
|||||||
|
langcode: en |
||||||
|
status: true |
||||||
|
dependencies: |
||||||
|
module: |
||||||
|
- options |
||||||
|
- reserve |
||||||
|
id: reserve_category.reserve_takedown_buffer |
||||||
|
field_name: reserve_takedown_buffer |
||||||
|
entity_type: reserve_category |
||||||
|
type: list_integer |
||||||
|
settings: |
||||||
|
allowed_values: |
||||||
|
- |
||||||
|
value: 0 |
||||||
|
label: none |
||||||
|
- |
||||||
|
value: 30 |
||||||
|
label: '30 minutes' |
||||||
|
- |
||||||
|
value: 60 |
||||||
|
label: '1 hour' |
||||||
|
- |
||||||
|
value: 90 |
||||||
|
label: '90 minutes' |
||||||
|
- |
||||||
|
value: 120 |
||||||
|
label: '2 hours' |
||||||
|
allowed_values_function: '' |
||||||
|
module: options |
||||||
|
locked: true |
||||||
|
cardinality: 1 |
||||||
|
translatable: true |
||||||
|
indexes: { } |
||||||
|
persist_with_no_fields: false |
||||||
|
custom_storage: false |
@ -0,0 +1,19 @@ |
|||||||
|
langcode: en |
||||||
|
status: true |
||||||
|
dependencies: |
||||||
|
module: |
||||||
|
- options |
||||||
|
- reserve |
||||||
|
id: reserve_reservation.reservable_content_type |
||||||
|
field_name: reservable_content_type |
||||||
|
entity_type: reserve_reservation |
||||||
|
type: list_string |
||||||
|
settings: |
||||||
|
allowed_values_function: 'reserve_site_entity_types' |
||||||
|
module: options |
||||||
|
locked: true |
||||||
|
cardinality: 1 |
||||||
|
translatable: true |
||||||
|
indexes: { } |
||||||
|
persist_with_no_fields: false |
||||||
|
custom_storage: false |
@ -0,0 +1,19 @@ |
|||||||
|
langcode: en |
||||||
|
status: true |
||||||
|
dependencies: |
||||||
|
module: |
||||||
|
- reserve |
||||||
|
id: reserve_reservation.reservable_id |
||||||
|
field_name: reservable_id |
||||||
|
entity_type: reserve_reservation |
||||||
|
type: integer |
||||||
|
settings: |
||||||
|
unsigned: true |
||||||
|
size: normal |
||||||
|
module: core |
||||||
|
locked: true |
||||||
|
cardinality: 1 |
||||||
|
translatable: false |
||||||
|
indexes: { } |
||||||
|
persist_with_no_fields: false |
||||||
|
custom_storage: false |
@ -0,0 +1,19 @@ |
|||||||
|
langcode: en |
||||||
|
status: true |
||||||
|
dependencies: |
||||||
|
module: |
||||||
|
- datetime |
||||||
|
- reserve |
||||||
|
id: reserve_reservation.reservation_date |
||||||
|
field_name: reservation_date |
||||||
|
entity_type: reserve_reservation |
||||||
|
type: datetime |
||||||
|
settings: |
||||||
|
datetime_type: date |
||||||
|
module: datetime |
||||||
|
locked: true |
||||||
|
cardinality: 1 |
||||||
|
translatable: true |
||||||
|
indexes: { } |
||||||
|
persist_with_no_fields: false |
||||||
|
custom_storage: false |
@ -0,0 +1,20 @@ |
|||||||
|
langcode: en |
||||||
|
status: true |
||||||
|
dependencies: |
||||||
|
module: |
||||||
|
- reserve |
||||||
|
id: reserve_reservation.reservation_ebundle |
||||||
|
field_name: reservation_ebundle |
||||||
|
entity_type: reserve_reservation |
||||||
|
type: string |
||||||
|
settings: |
||||||
|
max_length: 255 |
||||||
|
is_ascii: false |
||||||
|
case_sensitive: false |
||||||
|
module: core |
||||||
|
locked: true |
||||||
|
cardinality: 1 |
||||||
|
translatable: false |
||||||
|
indexes: { } |
||||||
|
persist_with_no_fields: false |
||||||
|
custom_storage: false |
@ -0,0 +1,49 @@ |
|||||||
|
langcode: en |
||||||
|
status: true |
||||||
|
dependencies: |
||||||
|
module: |
||||||
|
- reserve |
||||||
|
- options |
||||||
|
id: reserve_reservation.reservation_length |
||||||
|
field_name: reservation_length |
||||||
|
entity_type: reserve_reservation |
||||||
|
type: list_integer |
||||||
|
settings: |
||||||
|
allowed_values: |
||||||
|
- |
||||||
|
value: 30 |
||||||
|
label: '30 minutes' |
||||||
|
- |
||||||
|
value: 60 |
||||||
|
label: '1 hour' |
||||||
|
- |
||||||
|
value: 90 |
||||||
|
label: '1.5 hours' |
||||||
|
- |
||||||
|
value: 120 |
||||||
|
label: '2 hours' |
||||||
|
- |
||||||
|
value: 150 |
||||||
|
label: '2.5 hours' |
||||||
|
- |
||||||
|
value: 180 |
||||||
|
label: '3 hours' |
||||||
|
- |
||||||
|
value: 210 |
||||||
|
label: '3.5 hours' |
||||||
|
- |
||||||
|
value: 240 |
||||||
|
label: '4 hours' |
||||||
|
- |
||||||
|
value: 270 |
||||||
|
label: '4.5 hours' |
||||||
|
- |
||||||
|
value: 300 |
||||||
|
label: '5 hours' |
||||||
|
module: core |
||||||
|
locked: true |
||||||
|
cardinality: 1 |
||||||
|
translatable: false |
||||||
|
indexes: { } |
||||||
|
persist_with_no_fields: false |
||||||
|
custom_storage: false |
@ -0,0 +1,17 @@ |
|||||||
|
langcode: en |
||||||
|
status: true |
||||||
|
dependencies: |
||||||
|
module: |
||||||
|
- reserve |
||||||
|
id: reserve_reservation.reservation_private |
||||||
|
field_name: reservation_private |
||||||
|
entity_type: reserve_reservation |
||||||
|
type: boolean |
||||||
|
settings: { } |
||||||
|
module: core |
||||||
|
locked: true |
||||||
|
cardinality: 1 |
||||||
|
translatable: true |
||||||
|
indexes: { } |
||||||
|
persist_with_no_fields: false |
||||||
|
custom_storage: false |
@ -0,0 +1,29 @@ |
|||||||
|
langcode: en |
||||||
|
status: true |
||||||
|
dependencies: |
||||||
|
module: |
||||||
|
- options |
||||||
|
- reserve |
||||||
|
id: reserve_reservation.reservation_repeat_type |
||||||
|
field_name: reservation_repeat_type |
||||||
|
entity_type: reserve_reservation |
||||||
|
type: list_integer |
||||||
|
settings: |
||||||
|
allowed_values: |
||||||
|
- |
||||||
|
value: 0 |
||||||
|
label: 'No repeat' |
||||||
|
- |
||||||
|
value: 1 |
||||||
|
label: 'Repeat all days until' |
||||||
|
- |
||||||
|
value: 2 |
||||||
|
label: 'Repeat this day of the week until' |
||||||
|
allowed_values_function: '' |
||||||
|
module: options |
||||||
|
locked: true |
||||||
|
cardinality: 1 |
||||||
|
translatable: true |
||||||
|
indexes: { } |
||||||
|
persist_with_no_fields: false |
||||||
|
custom_storage: false |
@ -0,0 +1,19 @@ |
|||||||
|
langcode: en |
||||||
|
status: true |
||||||
|
dependencies: |
||||||
|
module: |
||||||
|
- datetime |
||||||
|
- reserve |
||||||
|
id: reserve_reservation.reservation_repeat_until |
||||||
|
field_name: reservation_repeat_until |
||||||
|
entity_type: reserve_reservation |
||||||
|
type: datetime |
||||||
|
settings: |
||||||
|
datetime_type: date |
||||||
|
module: datetime |
||||||
|
locked: true |
||||||
|
cardinality: 1 |
||||||
|
translatable: true |
||||||
|
indexes: { } |
||||||
|
persist_with_no_fields: false |
||||||
|
custom_storage: false |
@ -0,0 +1,19 @@ |
|||||||
|
langcode: en |
||||||
|
status: true |
||||||
|
dependencies: |
||||||
|
module: |
||||||
|
- reserve |
||||||
|
id: reserve_reservation.reservation_series_id |
||||||
|
field_name: reservation_series_id |
||||||
|
entity_type: reserve_reservation |
||||||
|
type: integer |
||||||
|
settings: |
||||||
|
unsigned: false |
||||||
|
size: normal |
||||||
|
module: core |
||||||
|
locked: true |
||||||
|
cardinality: 1 |
||||||
|
translatable: true |
||||||
|
indexes: { } |
||||||
|
persist_with_no_fields: false |
||||||
|
custom_storage: false |
@ -0,0 +1,20 @@ |
|||||||
|
langcode: en |
||||||
|
status: true |
||||||
|
dependencies: |
||||||
|
module: |
||||||
|
- reserve |
||||||
|
id: reserve_reservation.reservation_time |
||||||
|
field_name: reservation_time |
||||||
|
entity_type: reserve_reservation |
||||||
|
type: string |
||||||
|
settings: |
||||||
|
max_length: 255 |
||||||
|
is_ascii: false |
||||||
|
case_sensitive: false |
||||||
|
module: core |
||||||
|
locked: true |
||||||
|
cardinality: 1 |
||||||
|
translatable: true |
||||||
|
indexes: { } |
||||||
|
persist_with_no_fields: false |
||||||
|
custom_storage: false |
@ -0,0 +1,3 @@ |
|||||||
|
hour_format: 0 |
||||||
|
max_length_standard: 120 |
||||||
|
max_length_admin: 180 |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,13 @@ |
|||||||
|
field.field_settings.reserve_category: |
||||||
|
type: mapping |
||||||
|
label: 'Reserve Category settings' |
||||||
|
mapping: |
||||||
|
categories: |
||||||
|
type: int |
||||||
|
label: 'Allowable Categories' |
||||||
|
calendar_header: |
||||||
|
type: text |
||||||
|
label: 'Calendar Header' |
||||||
|
reservation_instructions: |
||||||
|
type: text |
||||||
|
label: 'Reservation Instructions' |
@ -0,0 +1,90 @@ |
|||||||
|
{ |
||||||
|
"_links": { |
||||||
|
"self": { |
||||||
|
"href": "http:\/\/default\/admin\/structure\/reserve_category\/3?_format=hal_json" |
||||||
|
}, |
||||||
|
"type": { |
||||||
|
"href": "http:\/\/drupal.org\/rest\/type\/reserve_category\/reserve_category" |
||||||
|
}, |
||||||
|
"http:\/\/drupal.org\/rest\/relation\/reserve_category\/reserve_category\/user_id": [ |
||||||
|
{ |
||||||
|
"href": "http:\/\/default\/user\/1?_format=hal_json", |
||||||
|
"lang": "en" |
||||||
|
} |
||||||
|
] |
||||||
|
}, |
||||||
|
"id": [ |
||||||
|
{ |
||||||
|
"value": 3 |
||||||
|
} |
||||||
|
], |
||||||
|
"uuid": [ |
||||||
|
{ |
||||||
|
"value": "99996f75-ab71-4ab0-b8af-9c0df45c15c9" |
||||||
|
} |
||||||
|
], |
||||||
|
"langcode": [ |
||||||
|
{ |
||||||
|
"value": "en", |
||||||
|
"lang": "en" |
||||||
|
} |
||||||
|
], |
||||||
|
"_embedded": { |
||||||
|
"http:\/\/drupal.org\/rest\/relation\/reserve_category\/reserve_category\/user_id": [ |
||||||
|
{ |
||||||
|
"_links": { |
||||||
|
"self": { |
||||||
|
"href": "http:\/\/default\/user\/1?_format=hal_json" |
||||||
|
}, |
||||||
|
"type": { |
||||||
|
"href": "http:\/\/drupal.org\/rest\/type\/user\/user" |
||||||
|
} |
||||||
|
}, |
||||||
|
"uuid": [ |
||||||
|
{ |
||||||
|
"value": "1b16703e-48a1-4e8b-9611-3b1efbafb90d" |
||||||
|
} |
||||||
|
], |
||||||
|
"lang": "en" |
||||||
|
} |
||||||
|
] |
||||||
|
}, |
||||||
|
"name": [ |
||||||
|
{ |
||||||
|
"value": "Digital" |
||||||
|
} |
||||||
|
], |
||||||
|
"status": [ |
||||||
|
{ |
||||||
|
"value": true |
||||||
|
} |
||||||
|
], |
||||||
|
"created": [ |
||||||
|
{ |
||||||
|
"value": "2018-01-10T20:41:46+00:00", |
||||||
|
"format": "Y-m-d\\TH:i:sP" |
||||||
|
} |
||||||
|
], |
||||||
|
"changed": [ |
||||||
|
{ |
||||||
|
"value": "2018-01-10T20:41:46+00:00", |
||||||
|
"format": "Y-m-d\\TH:i:sP" |
||||||
|
} |
||||||
|
], |
||||||
|
"default_langcode": [ |
||||||
|
{ |
||||||
|
"value": true, |
||||||
|
"lang": "en" |
||||||
|
} |
||||||
|
], |
||||||
|
"reserve_setup_buffer": [ |
||||||
|
{ |
||||||
|
"value": 0 |
||||||
|
} |
||||||
|
], |
||||||
|
"reserve_takedown_buffer": [ |
||||||
|
{ |
||||||
|
"value": 0 |
||||||
|
} |
||||||
|
] |
||||||
|
} |
@ -0,0 +1,90 @@ |
|||||||
|
{ |
||||||
|
"_links": { |
||||||
|
"self": { |
||||||
|
"href": "http:\/\/default\/admin\/structure\/reserve_category\/4?_format=hal_json" |
||||||
|
}, |
||||||
|
"type": { |
||||||
|
"href": "http:\/\/drupal.org\/rest\/type\/reserve_category\/reserve_category" |
||||||
|
}, |
||||||
|
"http:\/\/drupal.org\/rest\/relation\/reserve_category\/reserve_category\/user_id": [ |
||||||
|
{ |
||||||
|
"href": "http:\/\/default\/user\/1?_format=hal_json", |
||||||
|
"lang": "en" |
||||||
|
} |
||||||
|
] |
||||||
|
}, |
||||||
|
"id": [ |
||||||
|
{ |
||||||
|
"value": 4 |
||||||
|
} |
||||||
|
], |
||||||
|
"uuid": [ |
||||||
|
{ |
||||||
|
"value": "c3c9f13e-d620-4ef0-983f-6372b6f00e70" |
||||||
|
} |
||||||
|
], |
||||||
|
"langcode": [ |
||||||
|
{ |
||||||
|
"value": "en", |
||||||
|
"lang": "en" |
||||||
|
} |
||||||
|
], |
||||||
|
"_embedded": { |
||||||
|
"http:\/\/drupal.org\/rest\/relation\/reserve_category\/reserve_category\/user_id": [ |
||||||
|
{ |
||||||
|
"_links": { |
||||||
|
"self": { |
||||||
|
"href": "http:\/\/default\/user\/1?_format=hal_json" |
||||||
|
}, |
||||||
|
"type": { |
||||||
|
"href": "http:\/\/drupal.org\/rest\/type\/user\/user" |
||||||
|
} |
||||||
|
}, |
||||||
|
"uuid": [ |
||||||
|
{ |
||||||
|
"value": "1b16703e-48a1-4e8b-9611-3b1efbafb90d" |
||||||
|
} |
||||||
|
], |
||||||
|
"lang": "en" |
||||||
|
} |
||||||
|
] |
||||||
|
}, |
||||||
|
"name": [ |
||||||
|
{ |
||||||
|
"value": "Instant" |
||||||
|
} |
||||||
|
], |
||||||
|
"status": [ |
||||||
|
{ |
||||||
|
"value": true |
||||||
|
} |
||||||
|
], |
||||||
|
"created": [ |
||||||
|
{ |
||||||
|
"value": "2018-01-11T06:40:53+00:00", |
||||||
|
"format": "Y-m-d\\TH:i:sP" |
||||||
|
} |
||||||
|
], |
||||||
|
"changed": [ |
||||||
|
{ |
||||||
|
"value": "2018-01-11T06:40:53+00:00", |
||||||
|
"format": "Y-m-d\\TH:i:sP" |
||||||
|
} |
||||||
|
], |
||||||
|
"default_langcode": [ |
||||||
|
{ |
||||||
|
"value": true, |
||||||
|
"lang": "en" |
||||||
|
} |
||||||
|
], |
||||||
|
"reserve_setup_buffer": [ |
||||||
|
{ |
||||||
|
"value": 0 |
||||||
|
} |
||||||
|
], |
||||||
|
"reserve_takedown_buffer": [ |
||||||
|
{ |
||||||
|
"value": 0 |
||||||
|
} |
||||||
|
] |
||||||
|
} |
@ -0,0 +1,90 @@ |
|||||||
|
{ |
||||||
|
"_links": { |
||||||
|
"self": { |
||||||
|
"href": "http:\/\/default\/admin\/structure\/reserve_category\/1?_format=hal_json" |
||||||
|
}, |
||||||
|
"type": { |
||||||
|
"href": "http:\/\/drupal.org\/rest\/type\/reserve_category\/reserve_category" |
||||||
|
}, |
||||||
|
"http:\/\/drupal.org\/rest\/relation\/reserve_category\/reserve_category\/user_id": [ |
||||||
|
{ |
||||||
|
"href": "http:\/\/default\/user\/1?_format=hal_json", |
||||||
|
"lang": "en" |
||||||
|
} |
||||||
|
] |
||||||
|
}, |
||||||
|
"id": [ |
||||||
|
{ |
||||||
|
"value": 1 |
||||||
|
} |
||||||
|
], |
||||||
|
"uuid": [ |
||||||
|
{ |
||||||
|
"value": "148994b4-dece-4323-9dfa-d6e9f86b3395" |
||||||
|
} |
||||||
|
], |
||||||
|
"langcode": [ |
||||||
|
{ |
||||||
|
"value": "en", |
||||||
|
"lang": "en" |
||||||
|
} |
||||||
|
], |
||||||
|
"_embedded": { |
||||||
|
"http:\/\/drupal.org\/rest\/relation\/reserve_category\/reserve_category\/user_id": [ |
||||||
|
{ |
||||||
|
"_links": { |
||||||
|
"self": { |
||||||
|
"href": "http:\/\/default\/user\/1?_format=hal_json" |
||||||
|
}, |
||||||
|
"type": { |
||||||
|
"href": "http:\/\/drupal.org\/rest\/type\/user\/user" |
||||||
|
} |
||||||
|
}, |
||||||
|
"uuid": [ |
||||||
|
{ |
||||||
|
"value": "1b16703e-48a1-4e8b-9611-3b1efbafb90d" |
||||||
|
} |
||||||
|
], |
||||||
|
"lang": "en" |
||||||
|
} |
||||||
|
] |
||||||
|
}, |
||||||
|
"name": [ |
||||||
|
{ |
||||||
|
"value": "Large" |
||||||
|
} |
||||||
|
], |
||||||
|
"status": [ |
||||||
|
{ |
||||||
|
"value": true |
||||||
|
} |
||||||
|
], |
||||||
|
"created": [ |
||||||
|
{ |
||||||
|
"value": "2018-01-02T23:05:14+00:00", |
||||||
|
"format": "Y-m-d\\TH:i:sP" |
||||||
|
} |
||||||
|
], |
||||||
|
"changed": [ |
||||||
|
{ |
||||||
|
"value": "2018-01-02T23:05:14+00:00", |
||||||
|
"format": "Y-m-d\\TH:i:sP" |
||||||
|
} |
||||||
|
], |
||||||
|
"default_langcode": [ |
||||||
|
{ |
||||||
|
"value": true, |
||||||
|
"lang": "en" |
||||||
|
} |
||||||
|
], |
||||||
|
"reserve_setup_buffer": [ |
||||||
|
{ |
||||||
|
"value": 0 |
||||||
|
} |
||||||
|
], |
||||||
|
"reserve_takedown_buffer": [ |
||||||
|
{ |
||||||
|
"value": 0 |
||||||
|
} |
||||||
|
] |
||||||
|
} |
@ -0,0 +1,90 @@ |
|||||||
|
{ |
||||||
|
"_links": { |
||||||
|
"self": { |
||||||
|
"href": "http:\/\/default\/admin\/structure\/reserve_category\/2?_format=hal_json" |
||||||
|
}, |
||||||
|
"type": { |
||||||
|
"href": "http:\/\/drupal.org\/rest\/type\/reserve_category\/reserve_category" |
||||||
|
}, |
||||||
|
"http:\/\/drupal.org\/rest\/relation\/reserve_category\/reserve_category\/user_id": [ |
||||||
|
{ |
||||||
|
"href": "http:\/\/default\/user\/1?_format=hal_json", |
||||||
|
"lang": "en" |
||||||
|
} |
||||||
|
] |
||||||
|
}, |
||||||
|
"id": [ |
||||||
|
{ |
||||||
|
"value": 2 |
||||||
|
} |
||||||
|
], |
||||||
|
"uuid": [ |
||||||
|
{ |
||||||
|
"value": "89a908f8-e90d-4536-a747-c411598fad89" |
||||||
|
} |
||||||
|
], |
||||||
|
"langcode": [ |
||||||
|
{ |
||||||
|
"value": "en", |
||||||
|
"lang": "en" |
||||||
|
} |
||||||
|
], |
||||||
|
"_embedded": { |
||||||
|
"http:\/\/drupal.org\/rest\/relation\/reserve_category\/reserve_category\/user_id": [ |
||||||
|
{ |
||||||
|
"_links": { |
||||||
|
"self": { |
||||||
|
"href": "http:\/\/default\/user\/1?_format=hal_json" |
||||||
|
}, |
||||||
|
"type": { |
||||||
|
"href": "http:\/\/drupal.org\/rest\/type\/user\/user" |
||||||
|
} |
||||||
|
}, |
||||||
|
"uuid": [ |
||||||
|
{ |
||||||
|
"value": "1b16703e-48a1-4e8b-9611-3b1efbafb90d" |
||||||
|
} |
||||||
|
], |
||||||
|
"lang": "en" |
||||||
|
} |
||||||
|
] |
||||||
|
}, |
||||||
|
"name": [ |
||||||
|
{ |
||||||
|
"value": "Small" |
||||||
|
} |
||||||
|
], |
||||||
|
"status": [ |
||||||
|
{ |
||||||
|
"value": true |
||||||
|
} |
||||||
|
], |
||||||
|
"created": [ |
||||||
|
{ |
||||||
|
"value": "2018-01-10T20:41:23+00:00", |
||||||
|
"format": "Y-m-d\\TH:i:sP" |
||||||
|
} |
||||||
|
], |
||||||
|
"changed": [ |
||||||
|
{ |
||||||
|
"value": "2018-01-10T20:41:23+00:00", |
||||||
|
"format": "Y-m-d\\TH:i:sP" |
||||||
|
} |
||||||
|
], |
||||||
|
"default_langcode": [ |
||||||
|
{ |
||||||
|
"value": true, |
||||||
|
"lang": "en" |
||||||
|
} |
||||||
|
], |
||||||
|
"reserve_setup_buffer": [ |
||||||
|
{ |
||||||
|
"value": 0 |
||||||
|
} |
||||||
|
], |
||||||
|
"reserve_takedown_buffer": [ |
||||||
|
{ |
||||||
|
"value": 0 |
||||||
|
} |
||||||
|
] |
||||||
|
} |
@ -0,0 +1,90 @@ |
|||||||
|
{ |
||||||
|
"_links": { |
||||||
|
"self": { |
||||||
|
"href": "http:\/\/default\/admin\/structure\/reserve_category\/5?_format=hal_json" |
||||||
|
}, |
||||||
|
"type": { |
||||||
|
"href": "http:\/\/drupal.org\/rest\/type\/reserve_category\/reserve_category" |
||||||
|
}, |
||||||
|
"http:\/\/drupal.org\/rest\/relation\/reserve_category\/reserve_category\/user_id": [ |
||||||
|
{ |
||||||
|
"href": "http:\/\/default\/user\/1?_format=hal_json", |
||||||
|
"lang": "en" |
||||||
|
} |
||||||
|
] |
||||||
|
}, |
||||||
|
"id": [ |
||||||
|
{ |
||||||
|
"value": 5 |
||||||
|
} |
||||||
|
], |
||||||
|
"uuid": [ |
||||||
|
{ |
||||||
|
"value": "a5eea3e2-e717-4428-9d86-fe0681daf653" |
||||||
|
} |
||||||
|
], |
||||||
|
"langcode": [ |
||||||
|
{ |
||||||
|
"value": "en", |
||||||
|
"lang": "en" |
||||||
|
} |
||||||
|
], |
||||||
|
"_embedded": { |
||||||
|
"http:\/\/drupal.org\/rest\/relation\/reserve_category\/reserve_category\/user_id": [ |
||||||
|
{ |
||||||
|
"_links": { |
||||||
|
"self": { |
||||||
|
"href": "http:\/\/default\/user\/1?_format=hal_json" |
||||||
|
}, |
||||||
|
"type": { |
||||||
|
"href": "http:\/\/drupal.org\/rest\/type\/user\/user" |
||||||
|
} |
||||||
|
}, |
||||||
|
"uuid": [ |
||||||
|
{ |
||||||
|
"value": "1b16703e-48a1-4e8b-9611-3b1efbafb90d" |
||||||
|
} |
||||||
|
], |
||||||
|
"lang": "en" |
||||||
|
} |
||||||
|
] |
||||||
|
}, |
||||||
|
"name": [ |
||||||
|
{ |
||||||
|
"value": "Video" |
||||||
|
} |
||||||
|
], |
||||||
|
"status": [ |
||||||
|
{ |
||||||
|
"value": true |
||||||
|
} |
||||||
|
], |
||||||
|
"created": [ |
||||||
|
{ |
||||||
|
"value": "2018-01-11T06:43:23+00:00", |
||||||
|
"format": "Y-m-d\\TH:i:sP" |
||||||
|
} |
||||||
|
], |
||||||
|
"changed": [ |
||||||
|
{ |
||||||
|
"value": "2018-01-11T06:43:23+00:00", |
||||||
|
"format": "Y-m-d\\TH:i:sP" |
||||||
|
} |
||||||
|
], |
||||||
|
"default_langcode": [ |
||||||
|
{ |
||||||
|
"value": true, |
||||||
|
"lang": "en" |
||||||
|
} |
||||||
|
], |
||||||
|
"reserve_setup_buffer": [ |
||||||
|
{ |
||||||
|
"value": 0 |
||||||
|
} |
||||||
|
], |
||||||
|
"reserve_takedown_buffer": [ |
||||||
|
{ |
||||||
|
"value": 0 |
||||||
|
} |
||||||
|
] |
||||||
|
} |
@ -0,0 +1,259 @@ |
|||||||
|
/* ----------------------------- ROOM RESERVATIONS ---------------------------- */ |
||||||
|
|
||||||
|
#rooms-calendar .slink { |
||||||
|
margin-right: 40px; |
||||||
|
} |
||||||
|
|
||||||
|
.reservations-block ul { |
||||||
|
list-style-image: url(images/bullet.gif); |
||||||
|
} |
||||||
|
|
||||||
|
.reservations-block #reservations { |
||||||
|
margin-bottom: 5px; |
||||||
|
} |
||||||
|
|
||||||
|
#rooms-calendar .room-tabs { |
||||||
|
margin: 0 0 0 7px; |
||||||
|
padding: 0; |
||||||
|
} |
||||||
|
|
||||||
|
#rooms-calendar ul li, |
||||||
|
#rooms-calendar ul.menu li, |
||||||
|
#rooms-calendar .item-list ul li, |
||||||
|
#rooms-calendar li.leaf { |
||||||
|
background: none; |
||||||
|
padding: 0 0.75em 0.2em 0.75em; |
||||||
|
} |
||||||
|
|
||||||
|
#rooms-calendar .room-tabs li { |
||||||
|
float: left; |
||||||
|
list-style: none; |
||||||
|
margin: 0 0 -3px 0; |
||||||
|
padding: 2px 3px; |
||||||
|
} |
||||||
|
|
||||||
|
#rooms-calendar .room-tabs li a { |
||||||
|
background: #dddddd; |
||||||
|
border: 1px solid #999999; |
||||||
|
border-top-left-radius: 7px; |
||||||
|
border-top-right-radius: 7px; |
||||||
|
display: block; |
||||||
|
-moz-border-radius-topleft: 7px; |
||||||
|
-moz-border-radius-topright: 7px; |
||||||
|
padding: 3px 5px; |
||||||
|
text-decoration: none; |
||||||
|
-webkit-border-top-left-radius: 7px; |
||||||
|
-webkit-border-top-right-radius: 7px; |
||||||
|
} |
||||||
|
|
||||||
|
#rooms-calendar .room-tabs li a.active { |
||||||
|
background: #ffffff; |
||||||
|
border-bottom: 1px solid #ffffff; |
||||||
|
} |
||||||
|
|
||||||
|
#rooms-calendar .panelContainer { |
||||||
|
border: 1px solid #999; |
||||||
|
clear: left; |
||||||
|
} |
||||||
|
|
||||||
|
#rooms-calendar .panelContainer:after { |
||||||
|
content: " "; |
||||||
|
display: table; |
||||||
|
clear: both; |
||||||
|
min-height: 20px; |
||||||
|
} |
||||||
|
|
||||||
|
#rooms-calendar .panel { |
||||||
|
padding: 0 10px; |
||||||
|
} |
||||||
|
|
||||||
|
#rooms-calendar #tabbedPanels .date { |
||||||
|
clear: both; |
||||||
|
margin: 0; |
||||||
|
text-align: center; |
||||||
|
} |
||||||
|
|
||||||
|
#rooms-calendar #tabbedPanels .hours { |
||||||
|
color: #666666; |
||||||
|
font-weight: bold; |
||||||
|
margin-bottom: 5px; |
||||||
|
text-align: center; |
||||||
|
} |
||||||
|
|
||||||
|
#rooms-calendar #date-change, |
||||||
|
#rooms-calendar .reserve-center { |
||||||
|
text-align: center; |
||||||
|
} |
||||||
|
|
||||||
|
#rooms-calendar .panel .gcolumns .grid-column { |
||||||
|
float: left; |
||||||
|
} |
||||||
|
|
||||||
|
#rooms-calendar div.grid-column { |
||||||
|
max-width: 113px; |
||||||
|
} |
||||||
|
|
||||||
|
#rooms-calendar .panel .gcolumns ul { |
||||||
|
padding: 0 1px; |
||||||
|
} |
||||||
|
|
||||||
|
#rooms-calendar .panel .gcolumns li { |
||||||
|
border: 1px solid #dddddd; |
||||||
|
font-size: 85%; |
||||||
|
height: 1.33em; |
||||||
|
line-height: 15px; |
||||||
|
list-style-type: none; |
||||||
|
/* margin: -1px auto 0; */ |
||||||
|
padding: 2px 0; |
||||||
|
text-align: center; |
||||||
|
} |
||||||
|
|
||||||
|
/*#rooms-calendar .panel .gcolumns li.odd { |
||||||
|
border-top: 1px solid #999999; |
||||||
|
} |
||||||
|
*/ |
||||||
|
#rooms-calendar .panel .gcolumns li.room-info { |
||||||
|
border: none; |
||||||
|
} |
||||||
|
|
||||||
|
#rooms-calendar .panel .gcolumns li.room-info-heading { |
||||||
|
padding-bottom: 5px; |
||||||
|
} |
||||||
|
|
||||||
|
#rooms-calendar .panel .gcolumns li.room-info-footer { |
||||||
|
padding-top: 5px; |
||||||
|
} |
||||||
|
|
||||||
|
#rooms-calendar .panel .gcolumns .hours-column li { |
||||||
|
width: 112px; |
||||||
|
} |
||||||
|
|
||||||
|
#rooms-calendar .panel .gcolumns .room-column li { |
||||||
|
width: 115px; |
||||||
|
} |
||||||
|
|
||||||
|
#rooms-calendar .panel .gcolumns li.timeslot { |
||||||
|
background-color: #fff; |
||||||
|
*height: 1.33em; |
||||||
|
*margin-bottom: 2px; |
||||||
|
} |
||||||
|
|
||||||
|
#rooms-calendar .panel .gcolumns li.reservable { |
||||||
|
background-color: #fff; |
||||||
|
} |
||||||
|
|
||||||
|
#rooms-calendar .panel .gcolumns li.open { |
||||||
|
background-color: #fff; |
||||||
|
width: 112px !important; |
||||||
|
} |
||||||
|
|
||||||
|
#rooms-calendar .panel .gcolumns li.booked { |
||||||
|
background-color: #ddd; |
||||||
|
/*width: 109px !important;*/ |
||||||
|
} |
||||||
|
|
||||||
|
#rooms-calendar .gcolumns li.setup { |
||||||
|
background-color: #eee; |
||||||
|
} |
||||||
|
|
||||||
|
#rooms-calendar .panel .gcolumns li.closed { |
||||||
|
background-color: #d1dfdf; |
||||||
|
border: 1px solid #d1dfdf; |
||||||
|
} |
||||||
|
|
||||||
|
#rooms-calendar .hide { |
||||||
|
display: none; |
||||||
|
} |
||||||
|
|
||||||
|
.page-room-reservations .form-item label { |
||||||
|
display: inline; |
||||||
|
} |
||||||
|
|
||||||
|
#txtmsg-fields { |
||||||
|
display: none; |
||||||
|
} |
||||||
|
|
||||||
|
#date-change { |
||||||
|
margin-bottom:20px; |
||||||
|
} |
||||||
|
.clear {clear:both;} |
||||||
|
|
||||||
|
/* QTIP Overrides */ |
||||||
|
|
||||||
|
.qtip { |
||||||
|
box-shadow: -2px 2px 8px rgba(0,0,0,0.3); |
||||||
|
} |
||||||
|
|
||||||
|
.qtip canvas { |
||||||
|
display: none; |
||||||
|
width: 400px; |
||||||
|
} |
||||||
|
.qtip-link, .qtip-additional-element { |
||||||
|
border-bottom: 1px dotted #999; |
||||||
|
} |
||||||
|
|
||||||
|
.qtip h4 { |
||||||
|
margin: 0px; |
||||||
|
margin-top: 0.5em; |
||||||
|
font-size: 12px; |
||||||
|
color: #999; |
||||||
|
font-family: 'AvenirNextLTW01-Regular', Arial; |
||||||
|
} |
||||||
|
|
||||||
|
.qtip-tooltip { |
||||||
|
font-family: 'AvenirNextLTW01-Regular', Arial; |
||||||
|
font-size: 12px; |
||||||
|
margin-bottom: 0.5em; |
||||||
|
width: 400px; |
||||||
|
} |
||||||
|
|
||||||
|
/*! Light tooltip style */ |
||||||
|
.ui-tooltip-light .ui-tooltip-titlebar, |
||||||
|
.ui-tooltip-light .ui-tooltip-content{ |
||||||
|
border-color: transparent; |
||||||
|
color: #333; |
||||||
|
} |
||||||
|
|
||||||
|
.ui-tooltip-light .ui-tooltip-content { |
||||||
|
background-color: white; |
||||||
|
width: 270px !important; |
||||||
|
} |
||||||
|
|
||||||
|
.ui-tooltip-light .ui-tooltip-titlebar { |
||||||
|
width: 244px !important; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
#ui-datepicker-div { |
||||||
|
z-index:2 !important; |
||||||
|
} |
||||||
|
|
||||||
|
#rooms-calendar ul li.reservable:hover, #rooms-calendar ul li.open:hover { |
||||||
|
background-color:#FFF; |
||||||
|
} |
||||||
|
|
||||||
|
#rooms-calendar .panel .gcolumns li.reservable { |
||||||
|
text-align:center; |
||||||
|
vertical-align:middle; |
||||||
|
background-color:#fff; |
||||||
|
border:1px solid #ccc; |
||||||
|
} |
||||||
|
|
||||||
|
#rooms-calendar .panelContainer .grid-column li.highlighted { |
||||||
|
background-color:#999; |
||||||
|
} |
||||||
|
|
||||||
|
#rooms-calendar .reserve-group { |
||||||
|
/*border: 1px solid blue;*/ |
||||||
|
outline: 1px solid blue; |
||||||
|
width: 111px; |
||||||
|
position: relative; |
||||||
|
} |
||||||
|
|
||||||
|
#rooms-calendar .panel .gcolumns .reserve-series li.booked { |
||||||
|
background-color: lightgreen; |
||||||
|
} |
||||||
|
|
||||||
|
.gcolumns a, .gcolumns a.link { |
||||||
|
border-bottom: none !important; |
||||||
|
} |
@ -0,0 +1,252 @@ |
|||||||
|
/* ----------------------------- ROOM RESERVATIONS ---------------------------- */ |
||||||
|
|
||||||
|
#rooms-calendar .slink { |
||||||
|
margin-right: 40px; |
||||||
|
} |
||||||
|
|
||||||
|
.reservations-block ul { |
||||||
|
list-style-image: url(images/bullet.gif); |
||||||
|
} |
||||||
|
|
||||||
|
.reservations-block #reservations { |
||||||
|
margin-bottom: 5px; |
||||||
|
} |
||||||
|
|
||||||
|
#rooms-calendar .room-tabs { |
||||||
|
margin: 0 0 0 7px; |
||||||
|
padding: 0; |
||||||
|
} |
||||||
|
|
||||||
|
#rooms-calendar ul li, |
||||||
|
#rooms-calendar ul.menu li, |
||||||
|
#rooms-calendar .item-list ul li, |
||||||
|
#rooms-calendar li.leaf { |
||||||
|
background: none; |
||||||
|
padding: 0 0.75em 0.2em 0.75em; |
||||||
|
} |
||||||
|
|
||||||
|
#rooms-calendar .room-tabs li { |
||||||
|
float: left; |
||||||
|
list-style: none; |
||||||
|
margin: 0 0 -3px 0; |
||||||
|
padding: 2px 3px; |
||||||
|
} |
||||||
|
|
||||||
|
#rooms-calendar .room-tabs li a { |
||||||
|
background: #dddddd; |
||||||
|
border: 1px solid #999999; |
||||||
|
border-top-left-radius: 7px; |
||||||
|
border-top-right-radius: 7px; |
||||||
|
display: block; |
||||||
|
-moz-border-radius-topleft: 7px; |
||||||
|
-moz-border-radius-topright: 7px; |
||||||
|
padding: 3px 5px; |
||||||
|
text-decoration: none; |
||||||
|
-webkit-border-top-left-radius: 7px; |
||||||
|
-webkit-border-top-right-radius: 7px; |
||||||
|
} |
||||||
|
|
||||||
|
#rooms-calendar .room-tabs li a.active { |
||||||
|
background: #ffffff; |
||||||
|
border-bottom: 1px solid #ffffff; |
||||||
|
} |
||||||
|
|
||||||
|
#rooms-calendar .panelContainer { |
||||||
|
border: 1px solid #999; |
||||||
|
clear: left; |
||||||
|
} |
||||||
|
|
||||||
|
#rooms-calendar .panelContainer:after { |
||||||
|
content: " "; |
||||||
|
display: table; |
||||||
|
clear: both; |
||||||
|
min-height: 20px; |
||||||
|
} |
||||||
|
|
||||||
|
#rooms-calendar .panel { |
||||||
|
padding: 0 10px; |
||||||
|
} |
||||||
|
|
||||||
|
#rooms-calendar #tabbedPanels .date { |
||||||
|
clear: both; |
||||||
|
margin: 0; |
||||||
|
text-align: center; |
||||||
|
} |
||||||
|
|
||||||
|
#rooms-calendar #tabbedPanels .hours { |
||||||
|
color: #666666; |
||||||
|
font-weight: bold; |
||||||
|
margin-bottom: 5px; |
||||||
|
text-align: center; |
||||||
|
} |
||||||
|
|
||||||
|
#rooms-calendar #date-change, |
||||||
|
#rooms-calendar .reserve-center { |
||||||
|
text-align: center; |
||||||
|
} |
||||||
|
|
||||||
|
#rooms-calendar .panel .gcolumns .grid-column { |
||||||
|
float: left; |
||||||
|
} |
||||||
|
|
||||||
|
#rooms-calendar div.grid-column { |
||||||
|
max-width: 115px; |
||||||
|
} |
||||||
|
|
||||||
|
#rooms-calendar .panel .gcolumns ul { |
||||||
|
padding: 0 1px; |
||||||
|
} |
||||||
|
|
||||||
|
#rooms-calendar .panel .gcolumns li { |
||||||
|
border: 1px solid #dddddd; |
||||||
|
font-size: 85%; |
||||||
|
height: 1.33em; |
||||||
|
line-height: 15px; |
||||||
|
list-style-type: none; |
||||||
|
margin: -1px auto 0; |
||||||
|
padding: 2px 0; |
||||||
|
text-align: center; |
||||||
|
} |
||||||
|
|
||||||
|
/*#rooms-calendar .panel .gcolumns li.odd { |
||||||
|
border-top: 1px solid #999999; |
||||||
|
} |
||||||
|
*/ |
||||||
|
#rooms-calendar .panel .gcolumns li.room-info { |
||||||
|
border: none; |
||||||
|
} |
||||||
|
|
||||||
|
#rooms-calendar .panel .gcolumns li.room-info-heading { |
||||||
|
padding-bottom: 5px; |
||||||
|
} |
||||||
|
|
||||||
|
#rooms-calendar .panel .gcolumns li.room-info-footer { |
||||||
|
padding-top: 5px; |
||||||
|
} |
||||||
|
|
||||||
|
#rooms-calendar .panel .gcolumns .hours-column li { |
||||||
|
width: 120px; |
||||||
|
} |
||||||
|
|
||||||
|
#rooms-calendar .panel .gcolumns .room-column li { |
||||||
|
width: 115px; |
||||||
|
} |
||||||
|
|
||||||
|
#rooms-calendar .panel .gcolumns li.timeslot { |
||||||
|
background-color: #fff; |
||||||
|
*height: 1.33em; |
||||||
|
*margin-bottom: 2px; |
||||||
|
} |
||||||
|
|
||||||
|
#rooms-calendar .panel .gcolumns li.reservable { |
||||||
|
background-color: #fff; |
||||||
|
} |
||||||
|
|
||||||
|
#rooms-calendar .panel .gcolumns li.open { |
||||||
|
background-color: #fff; |
||||||
|
} |
||||||
|
|
||||||
|
#rooms-calendar .panel .gcolumns li.booked { |
||||||
|
background-color: #ddd; |
||||||
|
} |
||||||
|
|
||||||
|
#rooms-calendar .gcolumns li.setup { |
||||||
|
background-color: #eee; |
||||||
|
} |
||||||
|
|
||||||
|
#rooms-calendar .panel .gcolumns li.closed { |
||||||
|
background-color: #d1dfdf; |
||||||
|
border: 1px solid #d1dfdf; |
||||||
|
} |
||||||
|
|
||||||
|
#rooms-calendar .hide { |
||||||
|
display: none; |
||||||
|
} |
||||||
|
|
||||||
|
.page-room-reservations .form-item label { |
||||||
|
display: inline; |
||||||
|
} |
||||||
|
|
||||||
|
#txtmsg-fields { |
||||||
|
display: none; |
||||||
|
} |
||||||
|
|
||||||
|
#date-change { |
||||||
|
margin-bottom:20px; |
||||||
|
} |
||||||
|
.clear {clear:both;} |
||||||
|
|
||||||
|
/* QTIP Overrides */ |
||||||
|
|
||||||
|
.qtip { |
||||||
|
box-shadow: -2px 2px 8px rgba(0,0,0,0.3); |
||||||
|
} |
||||||
|
|
||||||
|
.qtip canvas { |
||||||
|
display: none; |
||||||
|
width: 400px; |
||||||
|
} |
||||||
|
.qtip-link, .qtip-additional-element { |
||||||
|
border-bottom: 1px dotted #999; |
||||||
|
} |
||||||
|
|
||||||
|
.qtip h4 { |
||||||
|
margin: 0px; |
||||||
|
margin-top: 0.5em; |
||||||
|
font-size: 12px; |
||||||
|
color: #999; |
||||||
|
font-family: 'AvenirNextLTW01-Regular', Arial; |
||||||
|
} |
||||||
|
|
||||||
|
.qtip-tooltip { |
||||||
|
font-family: 'AvenirNextLTW01-Regular', Arial; |
||||||
|
font-size: 12px; |
||||||
|
margin-bottom: 0.5em; |
||||||
|
width: 400px; |
||||||
|
} |
||||||
|
|
||||||
|
/*! Light tooltip style */ |
||||||
|
.ui-tooltip-light .ui-tooltip-titlebar, |
||||||
|
.ui-tooltip-light .ui-tooltip-content{ |
||||||
|
border-color: transparent; |
||||||
|
color: #333; |
||||||
|
} |
||||||
|
|
||||||
|
.ui-tooltip-light .ui-tooltip-content { |
||||||
|
background-color: white; |
||||||
|
width: 270px !important; |
||||||
|
} |
||||||
|
|
||||||
|
.ui-tooltip-light .ui-tooltip-titlebar { |
||||||
|
width: 244px !important; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
#ui-datepicker-div { |
||||||
|
z-index:2 !important; |
||||||
|
} |
||||||
|
|
||||||
|
#rooms-calendar ul li.reservable:hover, #rooms-calendar ul li.open:hover { |
||||||
|
background-color:#FFF; |
||||||
|
} |
||||||
|
|
||||||
|
#rooms-calendar .panel .gcolumns li.reservable { |
||||||
|
text-align:center; |
||||||
|
vertical-align:middle; |
||||||
|
background-color:#fff; |
||||||
|
border:1px solid #ccc; |
||||||
|
} |
||||||
|
|
||||||
|
#rooms-calendar .panelContainer .grid-column li.highlighted { |
||||||
|
background-color:#999; |
||||||
|
} |
||||||
|
|
||||||
|
#rooms-calendar .reserve-group { |
||||||
|
border: 1px solid blue; |
||||||
|
padding: 1px 0 1px 0 !important; |
||||||
|
width: 122px !important; |
||||||
|
} |
||||||
|
|
||||||
|
#rooms-calendar .panel .gcolumns .reserve-series li.booked { |
||||||
|
background-color: lightgreen; |
||||||
|
} |
After Width: | Height: | Size: 8.8 KiB |
After Width: | Height: | Size: 2.8 KiB |
@ -0,0 +1,135 @@ |
|||||||
|
(function ($, Drupal) { |
||||||
|
|
||||||
|
Drupal.behaviors.reserve = { |
||||||
|
attach: function (context, settings) { |
||||||
|
// set default Category tab if one is set in URL anchor
|
||||||
|
var anchor = window.location.hash; |
||||||
|
if (anchor) { |
||||||
|
$('.room-tabs a.active').removeClass('active'); |
||||||
|
$('.room-tabs li a[href=' + anchor + ']').addClass('active'); |
||||||
|
$('.panel').hide(); |
||||||
|
$(anchor).show(); |
||||||
|
} |
||||||
|
|
||||||
|
// show the selected category panel
|
||||||
|
$('.room-tabs a').click(function () { |
||||||
|
$this = $(this); |
||||||
|
$('.panel').hide(); |
||||||
|
$('.room-tabs a.active').removeClass('active'); |
||||||
|
$this.addClass('active').blur(); |
||||||
|
var panel = $this.attr('href'); |
||||||
|
$(panel).fadeIn(250); |
||||||
|
return false; |
||||||
|
}); |
||||||
|
|
||||||
|
// change calendar date displayed
|
||||||
|
$('#edit-date').change(function () { |
||||||
|
var datebits = $(this).val().split('-'); |
||||||
|
var formatarr = drupalSettings.reserve.dateFormat.split('/'); |
||||||
|
var dateobj = new Object(); |
||||||
|
$.each(formatarr, function (index, value) { |
||||||
|
dateobj[value] = datebits[index]; |
||||||
|
}); |
||||||
|
var val = dateobj.m + '/' + dateobj.d; |
||||||
|
var newpath = '/reserve/' + drupalSettings.reserve.ebundle + '/calendar/' + val; |
||||||
|
window.location.href = newpath; |
||||||
|
}); |
||||||
|
|
||||||
|
// show form fields for text message confirmation and reminder
|
||||||
|
$('#edit-textmsg').each(function () { |
||||||
|
if ($(this).attr('checked')) { |
||||||
|
$('#txtmsg-fields').slideDown('fast'); |
||||||
|
} |
||||||
|
else { |
||||||
|
$('#txtmsg-fields').slideUp('fast'); |
||||||
|
} |
||||||
|
}); |
||||||
|
$('#edit-textmsg').click(function () { |
||||||
|
if ($(this).attr('checked')) { |
||||||
|
$('#txtmsg-fields').slideDown('fast'); |
||||||
|
} |
||||||
|
else { |
||||||
|
$('#txtmsg-fields').slideUp('fast'); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
var isMouseDown = false, isHighlighted; |
||||||
|
var maxLength = drupalSettings.reserve.maxLength / 30; |
||||||
|
$("#rooms-calendar .panel li.reservable") |
||||||
|
|
||||||
|
.mousedown(function () { |
||||||
|
isMouseDown = true; |
||||||
|
// original code used toggleClass; but addClass works better
|
||||||
|
$(this).addClass("highlighted"); |
||||||
|
isHighlighted = $(this).hasClass("highlighted"); |
||||||
|
return false; // prevent text selection
|
||||||
|
}) |
||||||
|
|
||||||
|
.mouseover(function () { |
||||||
|
if (isMouseDown) { |
||||||
|
$(this).addClass("highlighted", isHighlighted); |
||||||
|
|
||||||
|
// Limit the selection of cells equal to maxLength parameter
|
||||||
|
var limitselect = document.querySelectorAll('.highlighted').length - 1; |
||||||
|
if (limitselect >= maxLength) { |
||||||
|
isMouseDown = false; |
||||||
|
} |
||||||
|
|
||||||
|
// Disable further selection when drag on lunch / booked time slot
|
||||||
|
$('.booked').mouseover(function () { |
||||||
|
isMouseDown = false; |
||||||
|
}); |
||||||
|
$('.closed').mouseover(function () { |
||||||
|
isMouseDown = false; |
||||||
|
}); |
||||||
|
|
||||||
|
// Restrict horizontal selection
|
||||||
|
$('.grid-column').mouseleave(function () { |
||||||
|
isMouseDown = false; |
||||||
|
}); |
||||||
|
} |
||||||
|
}) |
||||||
|
|
||||||
|
.bind("selectstart", function () { |
||||||
|
return false; |
||||||
|
}) |
||||||
|
|
||||||
|
.mouseup(function () { |
||||||
|
isMouseDown = false; |
||||||
|
var link = $('li.highlighted:first a'); |
||||||
|
var count = $('li.highlighted').length; |
||||||
|
var href = $(link).attr('href'); |
||||||
|
|
||||||
|
// not sure why the count == 0 case is required; but it occurs 2nd+ times modal is opened
|
||||||
|
if (count == 0) return false; |
||||||
|
if (count == 1) { |
||||||
|
$('li.highlighted:first a').click(); |
||||||
|
} |
||||||
|
else { |
||||||
|
var callback = 'reserve/ajax/reservation_add'; |
||||||
|
$.ajax({ |
||||||
|
async: false, |
||||||
|
url: Drupal.url(callback), |
||||||
|
data: { |
||||||
|
count: count, |
||||||
|
path: href |
||||||
|
}, |
||||||
|
//dataType: 'json',
|
||||||
|
success: function success(data) { |
||||||
|
if (data) { |
||||||
|
var $myDialog = $('<div>' + data + '</div>').appendTo('body'); |
||||||
|
var options = { |
||||||
|
title: 'Add Reservation', |
||||||
|
width: 700, |
||||||
|
}; |
||||||
|
Drupal.dialog($myDialog, options).showModal(); |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
$("#rooms-calendar .panel li.reservable").removeClass("highlighted"); |
||||||
|
}); |
||||||
|
} |
||||||
|
}; |
||||||
|
})(jQuery, Drupal); |
@ -0,0 +1,252 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
/** |
||||||
|
* alters for Reservation form |
||||||
|
*/ |
||||||
|
|
||||||
|
use Drupal\Core\Form\FormStateInterface; |
||||||
|
use Drupal\Core\Datetime\DrupalDateTime; |
||||||
|
use Drupal\Core\Link; |
||||||
|
use Drupal\Core\Url; |
||||||
|
|
||||||
|
function reserve_form_reserve_reservation_form_alter(array &$form, FormStateInterface $form_state) { |
||||||
|
// params either passed in on url - CREATE |
||||||
|
// or pulled from node - EDIT |
||||||
|
|
||||||
|
$_SESSION['reserve_delete_type'] = null; |
||||||
|
|
||||||
|
// Retrieve an array which contains the path pieces. |
||||||
|
$current_path = \Drupal::service('path.current')->getPath(); |
||||||
|
$path_args = explode('/', $current_path); |
||||||
|
|
||||||
|
// for case of std reservation add form - this should likely be blocked; but leave for development |
||||||
|
if (count($path_args) <= 3) return; |
||||||
|
|
||||||
|
$length = 30; |
||||||
|
// for modal form call |
||||||
|
if ($path_args[2] == 'ajax') { |
||||||
|
$path_args = explode('/', $_GET['path'] ); |
||||||
|
$length = 30 * $_GET['count']; |
||||||
|
}; |
||||||
|
|
||||||
|
//if (user_access('administer site configuration') && isset($_GET['edit']) && $_GET['edit'] == 'standard') { |
||||||
|
// return; |
||||||
|
//} |
||||||
|
|
||||||
|
// EDIT |
||||||
|
// only allow editing: Group Name, Private, Duration (shorten or longer if available to extend) |
||||||
|
// also, allow Cancelling |
||||||
|
$edit = false; |
||||||
|
if ($path_args[3] == 'edit') { |
||||||
|
$edit = true; |
||||||
|
$res = $form_state->getFormObject()->getEntity(); |
||||||
|
$rid = $res->id(); |
||||||
|
$eid = $res->reservable_id->getString(); |
||||||
|
$entity_type = $res->reservable_content_type->getString(); |
||||||
|
$series_id = $res->reservation_series_id->getString(); |
||||||
|
$d = $res->reservation_date->getString(); |
||||||
|
$yyyymmdd = date('Y-m-d', strtotime($d)); |
||||||
|
$t = $res->reservation_time->getString(); |
||||||
|
} |
||||||
|
|
||||||
|
// CREATE NEW |
||||||
|
else { |
||||||
|
$month = $path_args[3]; |
||||||
|
$day = $path_args[4]; |
||||||
|
$t = $path_args[5]; |
||||||
|
$eid = $path_args[6]; |
||||||
|
$ebundle = $path_args[7]; |
||||||
|
$entity_type = ebundle_split($ebundle, 'type'); |
||||||
|
// determine if this year or next year |
||||||
|
$year = reserve_which_year($month, $day); |
||||||
|
$yyyymmdd = date('Y-m-d', strtotime($year . '-' . $month . '-' . $day)); |
||||||
|
$d = $yyyymmdd . ' 00:00:00'; |
||||||
|
} |
||||||
|
|
||||||
|
$entity = entity_load($entity_type, $eid); |
||||||
|
$bundle = $entity->bundle(); |
||||||
|
$date = date('l, M d, Y', strtotime($d)); |
||||||
|
$time = reserve_display_time($t); |
||||||
|
$bundle_info = \Drupal::service("entity_type.bundle.info")->getAllBundleInfo(); |
||||||
|
$bundleName = $bundle_info[$entity->getEntityTypeId()][$entity->bundle()]['label']; |
||||||
|
|
||||||
|
// set default Group Name as name of current user |
||||||
|
$form['name']['widget'][0]['value']['#default_value'] = $form['name']['widget'][0]['value']['#default_value'] ? |
||||||
|
$form['name']['widget'][0]['value']['#default_value'] : |
||||||
|
\Drupal::currentUser()->getDisplayName(); |
||||||
|
|
||||||
|
// set values taken from URL |
||||||
|
$form['reservation_date']['widget'][0]['value']['#default_value'] = DrupalDateTime::createFromTimestamp(strtotime($yyyymmdd)); |
||||||
|
$form['reservation_time']['widget'][0]['value']['#default_value'] = $t; |
||||||
|
$form['reservation_length']['widget']['#default_value'] = $form['reservation_length']['widget']['#default_value'] ? |
||||||
|
$form['reservation_length']['widget']['#default_value'] : |
||||||
|
$length; |
||||||
|
$form['reservable_id']['widget'][0]['value']['#default_value'] = $entity->id(); |
||||||
|
$form['reservable_content_type']['widget']['#default_value'] = $entity_type; |
||||||
|
$form['reservation_ebundle']['widget'][0]['value']['#default_value'] = isset($form['reservation_ebundle']['widget'][0]['value']['#default_value']) ? |
||||||
|
$form['reservation_ebundle']['widget'][0]['value']['#default_value'] : |
||||||
|
$ebundle; |
||||||
|
|
||||||
|
if (!$GLOBALS['debug']) { |
||||||
|
// hide fields that have been filled from URL |
||||||
|
$form['reservation_date']['#access'] = false; |
||||||
|
$form['reservation_time']['#access'] = false; |
||||||
|
$form['user_id']['#access'] = false; |
||||||
|
$form['reservable_id']['#access'] = false; |
||||||
|
$form['reservable_content_type']['#access'] = false; |
||||||
|
|
||||||
|
// in prep for having better lockout of having slot taken by another user; let's also hide Length |
||||||
|
$form['reservation_length']['#access'] = false; |
||||||
|
|
||||||
|
// hide other fields we don't want to show |
||||||
|
$form['user_id']['#access'] = false; |
||||||
|
$form['reservation_series_id']['#access'] = false; |
||||||
|
$form['reservation_ebundle']['#access'] = false; |
||||||
|
} |
||||||
|
|
||||||
|
// if we are editing; let's do some extra things: |
||||||
|
// - disable Repeat options |
||||||
|
// - (series) add msg that we are editing a series and link to edit just that entry |
||||||
|
if ($edit) { |
||||||
|
//$bundle = $entity->getType(); |
||||||
|
$ebundle = $entity_type . '.' . $bundle; |
||||||
|
|
||||||
|
// Special handling for Series reservations |
||||||
|
if ($series_id) { |
||||||
|
$modal = ['attributes' => [ |
||||||
|
'class' => ['use-ajax'], |
||||||
|
'data-dialog-type' => 'modal', |
||||||
|
'data-dialog-options' => json_encode(['width' => 700]) |
||||||
|
]]; |
||||||
|
// if we are in a Series, lets disable selectors so we can still show what type of series, but not allow changing |
||||||
|
$form['reservation_repeat_type']['#disabled'] = TRUE; |
||||||
|
$form['reservation_repeat_until']['#disabled'] = TRUE; |
||||||
|
|
||||||
|
if (isset($_GET['single'])) { |
||||||
|
$series_link = Link::fromTextAndUrl(t('Click here'), Url::fromUri('internal:/reserve_reservation/' . $rid . '/edit', $modal))->toString(); |
||||||
|
$message = t('NOTE: you are editing a SINGLE day in a SERIES of reservations. Any changes made here will impact only the reservation |
||||||
|
for this day. %link if you want to edit the entire series.', array('%link' => $series_link)); |
||||||
|
// relabel Delete |
||||||
|
$form['actions']['delete']['#title'] = t('Cancel Reservation for This Day'); |
||||||
|
} |
||||||
|
else { |
||||||
|
$single_link = Link::fromTextAndUrl('Click here', Url::fromUri('internal:/reserve_reservation/' . $rid . '/edit', |
||||||
|
['query' => ['single' => 1]] + $modal))->toString(); |
||||||
|
$message = t('NOTE: you are editing a SERIES of reservations. Any changes made here will impact all reservations in this |
||||||
|
series. %link if you only want to edit this specific day in this series.', array('%link' => $single_link)); |
||||||
|
// remove single node delete and add Delete Series button |
||||||
|
//unset($form['actions']['delete']); |
||||||
|
/*$form['actions']['delete_series'] = array( |
||||||
|
'#type' => 'submit', |
||||||
|
'#value' => t('Cancel Entire Reservation Series'), |
||||||
|
'#weight' => 20, |
||||||
|
'#submit' => array('_reserve_series_delete'), |
||||||
|
);*/ |
||||||
|
$form['series'] = ['#type' => 'hidden', '#value' => true]; |
||||||
|
$form['actions']['delete']['#title'] = t('Cancel Entire Reservation Series'); |
||||||
|
|
||||||
|
// not sure any other way to pass info from here to delete hook |
||||||
|
$_SESSION['reserve_delete_type'] = 'series'; |
||||||
|
} |
||||||
|
|
||||||
|
// add psuedo message for Series forms. Can't use std drupal messages as they do not work in modals |
||||||
|
$form['message'] = [ |
||||||
|
'#type' => 'markup', |
||||||
|
'#weight' => -25, |
||||||
|
'#markup' => ' |
||||||
|
<div class="messages__wrapper layout-container"> |
||||||
|
<div role="contentinfo" aria-label="Warning message" class="messages messages--warning">' . |
||||||
|
$message . |
||||||
|
'</div></div>', |
||||||
|
]; |
||||||
|
} |
||||||
|
else { |
||||||
|
// but if not in Series, lets remove altogether |
||||||
|
$form['reservation_repeat_type']['#access'] = FALSE; |
||||||
|
$form['reservation_repeat_until']['#access'] = FALSE; |
||||||
|
// and if not part of a series; let's change DELETE button |
||||||
|
$form['actions']['delete']['#title'] = t('Cancel Reservation'); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// this is required to post drupal_messages as this is not in modal tpl by default |
||||||
|
$form['status_messages'] = [ |
||||||
|
'#type' => 'status_messages', |
||||||
|
'#weight' => -50, |
||||||
|
]; |
||||||
|
|
||||||
|
$lengthDisplay = $form['reservation_length']['widget']['#options'][$length]; |
||||||
|
$form['reservation_heading'] = [ |
||||||
|
'#type' => 'markup', |
||||||
|
'#weight' => -20, |
||||||
|
'#markup' => ' |
||||||
|
<h2 class="reservation-h2">' . t('Reservation booking for') . ':</h2><div><strong>' . $bundleName . ': ' . $entity->label() . '</strong></div> |
||||||
|
<div><strong>' . t('Date') . ': ' . $date . '</strong></div> |
||||||
|
<div><strong>' . t('Time') . ': ' . $time . '</strong></div> |
||||||
|
<div><strong>' . t('Length') . ': ' . $lengthDisplay . '</strong></div> |
||||||
|
<br>', |
||||||
|
]; |
||||||
|
|
||||||
|
// always redirect back to reservations calendar page |
||||||
|
$form['ebundle'] = ['#type' => 'hidden', '#value' => $ebundle]; |
||||||
|
$form['month'] = ['#type' => 'hidden', '#value' => date('m', strtotime($yyyymmdd))]; |
||||||
|
$form['day'] = ['#type' => 'hidden', '#value' => date('d', strtotime($yyyymmdd))]; |
||||||
|
$form['actions']['submit']['#submit'][] = 'reserve_return_to_reservations_page'; |
||||||
|
|
||||||
|
// limit valid lengths so we have no overlaps |
||||||
|
// this really only applies for EDIT now as we pick length in UI for CREATE |
||||||
|
$validlengths = reserve_valid_lengths($eid, $ebundle, $yyyymmdd, $t); |
||||||
|
foreach ($validlengths as $length) { |
||||||
|
if ($length['is_valid']) { |
||||||
|
$lengths[] = $length['length']; |
||||||
|
} |
||||||
|
} |
||||||
|
foreach ($form['reservation_length']['widget']['#options'] as $slot => &$option) { |
||||||
|
if (!in_array($slot, $lengths)) { |
||||||
|
unset($form['reservation_length']['widget']['#options'][$slot]); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
$form['reservation_repeat_until']['#states'] = array( |
||||||
|
'visible' => array( |
||||||
|
':input[name="reservation_repeat_type"]' => array('!value' => '0'), |
||||||
|
), |
||||||
|
); |
||||||
|
|
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
/* |
||||||
|
* redirect Delete confirmation form back to Calendar |
||||||
|
* there should be a pass arg info to this form like we do from edit form; but until i figure that out.. |
||||||
|
*/ |
||||||
|
function reserve_form_reserve_reservation_delete_form_alter(array &$form, FormStateInterface $form_state) { |
||||||
|
// Retrieve an array which contains the path pieces. |
||||||
|
$refer_path = $_SERVER[HTTP_REFERER]; |
||||||
|
$path_args = explode('/', $refer_path); |
||||||
|
|
||||||
|
$month = $path_args[6]; |
||||||
|
$day = $path_args[7]; |
||||||
|
$ebundle = $path_args[4]; |
||||||
|
|
||||||
|
$year = reserve_which_year($month, $day); |
||||||
|
$yyyymmdd = date('Y-m-d', strtotime($year . '-' . $month . '-' . $day)); |
||||||
|
|
||||||
|
$form['ebundle'] = ['#type' => 'hidden', '#value' => $ebundle]; |
||||||
|
$form['month'] = ['#type' => 'hidden', '#value' => date('m', strtotime($yyyymmdd))]; |
||||||
|
$form['day'] = ['#type' => 'hidden', '#value' => date('d', strtotime($yyyymmdd))]; |
||||||
|
|
||||||
|
$form['actions']['submit']['#submit'][] = 'reserve_return_to_reservations_page'; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Custom submit handler for login form. |
||||||
|
*/ |
||||||
|
function reserve_return_to_reservations_page($form, FormStateInterface $form_state) { |
||||||
|
$arguments = [ |
||||||
|
'ebundle' => $form_state->getValue('ebundle'), |
||||||
|
'selected_month' => $form_state->getValue('month'), |
||||||
|
'selected_day' => $form_state->getValue('day'), |
||||||
|
]; |
||||||
|
$form_state->setRedirect('reserve.calendar', $arguments); |
||||||
|
} |
@ -0,0 +1,5 @@ |
|||||||
|
name: Reserve |
||||||
|
type: module |
||||||
|
description: Reservation system. |
||||||
|
core: 8.x |
||||||
|
package: Reserve |
@ -0,0 +1,11 @@ |
|||||||
|
reserve: |
||||||
|
version: 1.x |
||||||
|
css: |
||||||
|
theme: |
||||||
|
css/reserve-calendar.css: {} |
||||||
|
js: |
||||||
|
js/reserve.js: {} |
||||||
|
dependencies: |
||||||
|
- core/jquery |
||||||
|
- core/drupalSettings |
||||||
|
- core/drupal.dialog.ajax |
@ -0,0 +1,10 @@ |
|||||||
|
entity.reserve_reservation.add_form: |
||||||
|
route_name: entity.reserve_reservation.add_form |
||||||
|
title: 'Add Reservation' |
||||||
|
appears_on: |
||||||
|
- entity.reserve_reservation.collection |
||||||
|
entity.reserve_category.add_form: |
||||||
|
route_name: entity.reserve_category.add_form |
||||||
|
title: 'Add Reservation Category' |
||||||
|
appears_on: |
||||||
|
- entity.reserve_category.collection |
@ -0,0 +1,38 @@ |
|||||||
|
|
||||||
|
# Reservation menu items definition |
||||||
|
entity.reserve_reservation.collection: |
||||||
|
title: 'Reservations' |
||||||
|
route_name: entity.reserve_reservation.collection |
||||||
|
description: 'List reservations' |
||||||
|
parent: system.admin_structure |
||||||
|
|
||||||
|
reserve_reservation.admin.structure.settings: |
||||||
|
title: Reservation settings |
||||||
|
description: 'Configure reservations' |
||||||
|
route_name: reserve_reservation.settings |
||||||
|
parent: entity.reserve_reservation.collection |
||||||
|
|
||||||
|
# Reservation Category menu items definition |
||||||
|
entity.reserve_category.collection: |
||||||
|
title: 'Reservation Categories' |
||||||
|
route_name: entity.reserve_category.collection |
||||||
|
description: 'List reservation categories' |
||||||
|
parent: entity.reserve_reservation.collection |
||||||
|
|
||||||
|
reserve_category.admin.structure.settings: |
||||||
|
title: Reservation Category settings |
||||||
|
description: 'Configure reservation categories' |
||||||
|
route_name: reserve_category.settings |
||||||
|
parent: entity.reserve_category.collection |
||||||
|
|
||||||
|
reserve.admin.system.settings: |
||||||
|
title: Reserve |
||||||
|
description: 'Configure Reserve' |
||||||
|
route_name: reserve.settings |
||||||
|
parent: 'system.admin_config_system' |
||||||
|
reserve.admin.system.settings.hours: |
||||||
|
title: Hours |
||||||
|
description: 'Configure Reserve Hours' |
||||||
|
route_name: reserve.settings.hours |
||||||
|
parent: 'reserve.admin.system.settings' |
||||||
|
weight: -10 |
@ -0,0 +1,81 @@ |
|||||||
|
# Reservation routing definition |
||||||
|
reserve_reservation.settings_tab: |
||||||
|
route_name: reserve_reservation.settings |
||||||
|
title: 'Settings' |
||||||
|
base_route: reserve_reservation.settings |
||||||
|
|
||||||
|
entity.reserve_reservation.canonical: |
||||||
|
route_name: entity.reserve_reservation.canonical |
||||||
|
base_route: entity.reserve_reservation.canonical |
||||||
|
title: 'View' |
||||||
|
|
||||||
|
entity.reserve_reservation.edit_form: |
||||||
|
route_name: entity.reserve_reservation.edit_form |
||||||
|
base_route: entity.reserve_reservation.canonical |
||||||
|
title: 'Edit' |
||||||
|
|
||||||
|
entity.reserve_reservation.delete_form: |
||||||
|
route_name: entity.reserve_reservation.delete_form |
||||||
|
base_route: entity.reserve_reservation.canonical |
||||||
|
title: Delete |
||||||
|
weight: 10 |
||||||
|
|
||||||
|
# Reservation Category routing definition |
||||||
|
reserve_category.settings_tab: |
||||||
|
route_name: reserve_category.settings |
||||||
|
title: 'Settings' |
||||||
|
base_route: reserve_category.settings |
||||||
|
|
||||||
|
entity.reserve_category.edit_form: |
||||||
|
route_name: entity.reserve_category.edit_form |
||||||
|
base_route: entity.reserve_category.canonical |
||||||
|
title: 'Edit' |
||||||
|
entity.reserve_category.canonical: |
||||||
|
route_name: entity.reserve_category.canonical |
||||||
|
base_route: entity.reserve_category.canonical |
||||||
|
title: 'View' |
||||||
|
entity.reserve_category.delete_form: |
||||||
|
route_name: entity.reserve_category.delete_form |
||||||
|
base_route: entity.reserve_category.canonical |
||||||
|
title: Delete |
||||||
|
weight: 10 |
||||||
|
|
||||||
|
# Reserve Settings |
||||||
|
reserve.settings: |
||||||
|
title: 'Settings' |
||||||
|
route_name: reserve.settings |
||||||
|
base_route: reserve.settings |
||||||
|
|
||||||
|
reserve.settings.hours: |
||||||
|
title: 'Hours' |
||||||
|
route_name: reserve.settings.hours |
||||||
|
base_route: reserve.settings |
||||||
|
|
||||||
|
reserve.settings.display: |
||||||
|
title: 'Display' |
||||||
|
route_name: reserve.settings.display |
||||||
|
base_route: reserve.settings |
||||||
|
weight: 10 |
||||||
|
|
||||||
|
reserve.settings.hours.default: |
||||||
|
title: 'Default Hours' |
||||||
|
route_name: reserve.settings.hours |
||||||
|
parent_id: reserve.settings.hours |
||||||
|
|
||||||
|
reserve.settings.hours.daily: |
||||||
|
title: 'Daily Overrides' |
||||||
|
route_name: reserve.settings.hours.daily |
||||||
|
parent_id: reserve.settings.hours |
||||||
|
|
||||||
|
reserve.calendar: |
||||||
|
title: 'Calendar' |
||||||
|
route_name: reserve.calendar |
||||||
|
base_route: reserve.calendar |
||||||
|
|
||||||
|
reserve.myreservation: |
||||||
|
title: 'My Reservations' |
||||||
|
route_name: view.reservations.page_2 |
||||||
|
base_route: reserve.calendar |
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,71 @@ |
|||||||
|
# Reservation routing definition |
||||||
|
reserve_reservation.settings_tab: |
||||||
|
route_name: reserve_reservation.settings |
||||||
|
title: 'Settings' |
||||||
|
base_route: reserve_reservation.settings |
||||||
|
|
||||||
|
entity.reserve_reservation.canonical: |
||||||
|
route_name: entity.reserve_reservation.canonical |
||||||
|
base_route: entity.reserve_reservation.canonical |
||||||
|
title: 'View' |
||||||
|
|
||||||
|
entity.reserve_reservation.edit_form: |
||||||
|
route_name: entity.reserve_reservation.edit_form |
||||||
|
base_route: entity.reserve_reservation.canonical |
||||||
|
title: 'Edit' |
||||||
|
|
||||||
|
entity.reserve_reservation.delete_form: |
||||||
|
route_name: entity.reserve_reservation.delete_form |
||||||
|
base_route: entity.reserve_reservation.canonical |
||||||
|
title: Delete |
||||||
|
weight: 10 |
||||||
|
|
||||||
|
# Reservation Category routing definition |
||||||
|
reserve_categories.settings_tab: |
||||||
|
route_name: reserve_categories.settings |
||||||
|
title: 'Settings' |
||||||
|
base_route: reserve_categories.settings |
||||||
|
|
||||||
|
entity.reserve_category.edit_form: |
||||||
|
route_name: entity.reserve_category.edit_form |
||||||
|
base_route: entity.reserve_category.canonical |
||||||
|
title: 'Edit' |
||||||
|
entity.reserve_category.canonical: |
||||||
|
route_name: entity.reserve_category.canonical |
||||||
|
base_route: entity.reserve_category.canonical |
||||||
|
title: 'View' |
||||||
|
entity.reserve_category.delete_form: |
||||||
|
route_name: entity.reserve_category.delete_form |
||||||
|
base_route: entity.reserve_category.canonical |
||||||
|
title: Delete |
||||||
|
weight: 10 |
||||||
|
|
||||||
|
# Reserve Settings |
||||||
|
reserve.settings: |
||||||
|
title: 'Settings' |
||||||
|
route_name: reserve.settings |
||||||
|
base_route: reserve.settings |
||||||
|
|
||||||
|
reserve.settings.hours: |
||||||
|
title: 'Hours' |
||||||
|
route_name: reserve.settings.hours |
||||||
|
base_route: reserve.settings |
||||||
|
|
||||||
|
reserve.settings.display: |
||||||
|
title: 'Display' |
||||||
|
route_name: reserve.settings.display |
||||||
|
base_route: reserve.settings |
||||||
|
weight: 10 |
||||||
|
|
||||||
|
reserve.settings.hours.default: |
||||||
|
title: 'Default Hours' |
||||||
|
route_name: reserve.settings.hours |
||||||
|
parent_id: reserve.settings.hours |
||||||
|
|
||||||
|
reserve.settings.hours.daily: |
||||||
|
title: 'Daily Overrides' |
||||||
|
route_name: reserve.settings.hours.daily |
||||||
|
parent_id: reserve.settings.hours |
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,113 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
/** |
||||||
|
* @file |
||||||
|
* Contains reserve.module.. |
||||||
|
* |
||||||
|
* @todo: fix reserve cat field with cardinality of 1 |
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
use Drupal\Core\Routing\RouteMatchInterface; |
||||||
|
use Drupal\Core\Entity\BundleEntityFormBase; |
||||||
|
use Drupal\Core\Entity\EntityInterface; |
||||||
|
use Drupal\Core\Form\FormStateInterface; |
||||||
|
use Drupal\reserve\BundleFormAlter; |
||||||
|
|
||||||
|
define ('RESERVE_SAVE_CONFIRMATION_MSG', t('Configuration settings have been saved')); |
||||||
|
define ('RESERVE_RESET_CONFIRMATION_MSG', t('Configuration settings have been reset to their default values')); |
||||||
|
|
||||||
|
module_load_include('inc', 'reserve', 'reserve'); |
||||||
|
module_load_include('inc', 'reserve', 'reserve.series'); |
||||||
|
module_load_include('inc', 'reserve', 'reservation'); |
||||||
|
|
||||||
|
$GLOBALS['debug'] = false; |
||||||
|
|
||||||
|
/** |
||||||
|
* Implements hook_help(). |
||||||
|
*/ |
||||||
|
function reserve_help($route_name, RouteMatchInterface $route_match) { |
||||||
|
switch ($route_name) { |
||||||
|
// Main module help for the reserve module. |
||||||
|
case 'help.page.reserve': |
||||||
|
$output = ''; |
||||||
|
$output .= '<h3>' . t('Overview') . '</h3>'; |
||||||
|
$output .= '<p>' . t('The Reserve module allows for the "booking" of entities. It provides a calendar for each bundle which is set up to be bookable. |
||||||
|
From this calendar you can see what time slots have been booked as well as select a time slot to book. Many options are provided to make a very flexible |
||||||
|
booking system.') . '</p>'; |
||||||
|
$output .= '<h3>' . t('Setup') . '</h3>'; |
||||||
|
$output .= '<p>' . t('A few things must be set up before you may use the booking system:') . '</p> |
||||||
|
<ul> |
||||||
|
<li>' . t('Create the content bundle which is to be reservable. E.g. Room') . '</li> |
||||||
|
<li>' . t('Create Reservation Categories as required. E.g. Large, Small. Set required values for each category.') . '</li> |
||||||
|
<li>' . t('Add the Reservation Category field type to the bundle which you want to make reservable. Select which Reservation Categories |
||||||
|
will apply to this bundle.') . '</li> |
||||||
|
<li>' . t('Review the settings under Reserve Settings and modify as required.') . '</li> |
||||||
|
<li>' . t('Set required permissions.') . '</li> |
||||||
|
<li>' . t('Finally, define the default times that entities are reservable. You may also set any daily overrides that may be required (optional).') . '</li> |
||||||
|
</ul> |
||||||
|
<p>' . t('The booking calendar will now be available at /reserve/{entitytype.bundle}/calendar. E.g. /reserve/node.room/calendar') . '</p>'; |
||||||
|
|
||||||
|
return $output; |
||||||
|
|
||||||
|
default: |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Implements hook_form_alter(). |
||||||
|
*/ |
||||||
|
function reserve_form_alter(array &$form, FormStateInterface $form_state, $form_id) { |
||||||
|
if ($form_state->getFormObject() instanceof BundleEntityFormBase) { |
||||||
|
(new BundleFormAlter($form_state->getFormObject()->getEntity())) |
||||||
|
->formAlter($form, $form_state); |
||||||
|
} |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Implements hook_entity_insert(). |
||||||
|
*/ |
||||||
|
function reserve_entity_insert(EntityInterface $entity) { |
||||||
|
reserve_entity_type_save($entity); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Implements hook_entity_update(). |
||||||
|
*/ |
||||||
|
function reserve_entity_update(EntityInterface $entity) { |
||||||
|
reserve_entity_type_save($entity); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Helper to save group information. |
||||||
|
* |
||||||
|
* @param \Drupal\Core\Entity\EntityInterface $entity |
||||||
|
* The entity object. |
||||||
|
*/ |
||||||
|
function reserve_entity_type_save(EntityInterface $entity) { |
||||||
|
$bundle = $entity->id(); |
||||||
|
$definition = \Drupal::entityTypeManager()->getDefinition($entity->getEntityTypeId()); |
||||||
|
$entity_type_id = $definition->getBundleOf(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Implements hook_theme(). |
||||||
|
*/ |
||||||
|
function reserve_theme($existing, $type, $theme, $path) { |
||||||
|
return array( |
||||||
|
'calendar_template' => array( |
||||||
|
'variables' => array( |
||||||
|
'date_picker' => NULL, |
||||||
|
'arrow' => NULL, |
||||||
|
'date' => NULL, |
||||||
|
'calendar_text' => NULL, |
||||||
|
'dates' => NULL, |
||||||
|
'categories' => NULL, |
||||||
|
'calendar_header' => NULL, |
||||||
|
'reservation_instructions' => NULL, |
||||||
|
'building_hours_display' => NULL, |
||||||
|
), |
||||||
|
), |
||||||
|
); |
||||||
|
} |
@ -0,0 +1,58 @@ |
|||||||
|
# Admin |
||||||
|
administer reservations: |
||||||
|
title: 'Administer Reservations' |
||||||
|
description: 'Allow access to the administration form to configure Reservations.' |
||||||
|
restrict access: true |
||||||
|
|
||||||
|
administer reservation categories: |
||||||
|
title: 'Administer Reservation Categories' |
||||||
|
description: 'Allow access to the administration form to configure Reservation Categories.' |
||||||
|
restrict access: true |
||||||
|
|
||||||
|
# Reservations |
||||||
|
add reservations: |
||||||
|
title: 'Create new Reservations' |
||||||
|
|
||||||
|
add reservations extended: |
||||||
|
title: 'Create new Reservations (extended)' |
||||||
|
|
||||||
|
edit reservations: |
||||||
|
title: 'Edit Reservations' |
||||||
|
|
||||||
|
delete reservations: |
||||||
|
title: 'Delete Reservations' |
||||||
|
|
||||||
|
view published reservations: |
||||||
|
title: 'View published Reservations' |
||||||
|
|
||||||
|
view unpublished reservations: |
||||||
|
title: 'View unpublished Reservations' |
||||||
|
|
||||||
|
book over reservation buffer: |
||||||
|
title: 'Book over reservation buffer' |
||||||
|
|
||||||
|
access reservation overview: |
||||||
|
title: 'Access the Reservation overview page' |
||||||
|
|
||||||
|
# Categories |
||||||
|
add reservation categories: |
||||||
|
title: 'Create new Reservation Categories' |
||||||
|
|
||||||
|
edit reservation categories: |
||||||
|
title: 'Edit Reservation Categories' |
||||||
|
|
||||||
|
delete reservation categories: |
||||||
|
title: 'Delete Reservation Categories' |
||||||
|
|
||||||
|
view published reservation categories: |
||||||
|
title: 'View published Reservation Categories' |
||||||
|
|
||||||
|
view unpublished reservation categories: |
||||||
|
title: 'View unpublished Reservation Categories' |
||||||
|
|
||||||
|
access reservation category overview: |
||||||
|
title: 'Access the Reservation Category overview page' |
||||||
|
|
||||||
|
permission_callbacks: |
||||||
|
- Drupal\reserve\Controller\ReservePermissions::permissions |
||||||
|
|
@ -0,0 +1,61 @@ |
|||||||
|
# Route name can be used in several places; e.g. links, redirects, and local |
||||||
|
# actions. |
||||||
|
|
||||||
|
reserve.settings: |
||||||
|
path: '/admin/config/system/reserve' |
||||||
|
defaults: |
||||||
|
_form: '\Drupal\reserve\Form\ReserveSettingsForm' |
||||||
|
_title: 'Reserve Settings' |
||||||
|
requirements: |
||||||
|
_permission: 'administer reservation categories' |
||||||
|
|
||||||
|
reserve.settings.hours: |
||||||
|
path: '/admin/config/system/reserve/hours' |
||||||
|
defaults: |
||||||
|
_form: '\Drupal\reserve\Form\ReserveDefaultHoursForm' |
||||||
|
_title: 'Reserve Settings (Default Hours)' |
||||||
|
requirements: |
||||||
|
_permission: 'administer reservation categories' |
||||||
|
|
||||||
|
reserve.settings.hours.daily: |
||||||
|
path: '/admin/config/system/reserve/hours/daily/{passed_month}' |
||||||
|
defaults: |
||||||
|
_form: '\Drupal\reserve\Form\ReserveDailyHoursForm' |
||||||
|
_title: 'Reserve Settings (Daily Overrides)' |
||||||
|
passed_month: 'yyyy_mm' |
||||||
|
requirements: |
||||||
|
_permission: 'administer reservation categories' |
||||||
|
passed_month: '20[0-9][0-9]_[0-1][0-9]' |
||||||
|
|
||||||
|
reserve.settings.display: |
||||||
|
path: '/admin/config/system/reserve/diplay' |
||||||
|
defaults: |
||||||
|
_form: '\Drupal\reserve\Form\ReserveDisplayForm' |
||||||
|
_title: 'Reserve Settings (Display)' |
||||||
|
requirements: |
||||||
|
_permission: 'administer reservation categories' |
||||||
|
|
||||||
|
reserve.calendar: |
||||||
|
path: '/reserve/{ebundle}/calendar/{selected_month}/{selected_day}' |
||||||
|
defaults: |
||||||
|
_controller: '\Drupal\reserve\Controller\CalendarController::calendar' |
||||||
|
_title_callback: '\Drupal\reserve\Controller\CalendarController::calendarTitle' |
||||||
|
selected_month: '' |
||||||
|
selected_day: '' |
||||||
|
requirements: |
||||||
|
_custom_access: '\Drupal\reserve\Controller\CalendarController::accessCalendarPage' |
||||||
|
|
||||||
|
reserve.reservation.add: |
||||||
|
path: '/reserve_reservation/add/{month}/{day}/{time}/{id}/{ebundle}' |
||||||
|
defaults: |
||||||
|
_entity_form: 'reserve_reservation.default' |
||||||
|
_title: 'Add Reservation' |
||||||
|
requirements: |
||||||
|
_permission: 'access content' |
||||||
|
|
||||||
|
reserve.reservation.add.callback: |
||||||
|
path: '/reserve/ajax/reservation_add' |
||||||
|
defaults: |
||||||
|
_controller: '\Drupal\reserve\Controller\CalendarController::reservationAddModalCallback' |
||||||
|
requirements: |
||||||
|
_permission: 'access content' |
@ -0,0 +1,21 @@ |
|||||||
|
field.storage_settings.reserve_category_reference: |
||||||
|
type: mapping |
||||||
|
label: 'Reserve Category reference field storage settings' |
||||||
|
mapping: |
||||||
|
target_type: |
||||||
|
type: string |
||||||
|
label: 'Type of entity to reference' |
||||||
|
|
||||||
|
field.field_settings.reserve_category_reference: |
||||||
|
type: mapping |
||||||
|
label: 'Reserve Category reference field settings' |
||||||
|
mapping: |
||||||
|
handler: |
||||||
|
type: string |
||||||
|
label: 'Reference method' |
||||||
|
handler_settings: |
||||||
|
type: entity_reference_selection.[%parent.handler] |
||||||
|
label: 'Reserve Category reference selection plugin settings' |
||||||
|
access_override: |
||||||
|
type: boolean |
||||||
|
label: 'Reserve Cateegories' |
@ -0,0 +1,192 @@ |
|||||||
|
<?php
|
||||||
|
|
||||||
|
/** |
||||||
|
* Reservation CRUD for supporting Series |
||||||
|
*/ |
||||||
|
|
||||||
|
use Drupal\Core\Render\Markup; |
||||||
|
|
||||||
|
/** |
||||||
|
* Create REPEATING reservations |
||||||
|
* |
||||||
|
* NOTE: first reservation has aready been saved at this point - we are just saving the others in series |
||||||
|
* BUT - we do need to update the original entity with the Series ID |
||||||
|
* |
||||||
|
* @param mixed $node |
||||||
|
*/ |
||||||
|
function reserve_reserve_reservation_insert($entity) { |
||||||
|
|
||||||
|
// when we do a node_save below; it will hit this hook; so if this routine just did the save lets bail |
||||||
|
if (isset($entity->saved)){ |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
$repeat_type = $entity->reservation_repeat_type->getString(); |
||||||
|
|
||||||
|
// if No Repeat, do nothing |
||||||
|
if (!$repeat_type) { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
$eid = $entity->id(); |
||||||
|
$start = $entity->reservation_date->getString(); |
||||||
|
$start_yyyy_mm_dd = date('Y-m-d', strtotime($start)); |
||||||
|
$end = date('Y-m-d', strtotime($entity->reservation_repeat_until->getString())); |
||||||
|
$time = $entity->reservation_time->getString(); |
||||||
|
$length = $entity->reservation_length->getString(); |
||||||
|
$rid = $entity->reservable_id->getString(); |
||||||
|
$rtype = $entity->reservable_content_type->getString(); |
||||||
|
$ebundle = $rtype . '.' . entity_load($rtype, $rid)->bundle(); |
||||||
|
$day = date('l', strtotime($start)); |
||||||
|
|
||||||
|
$msg = ''; |
||||||
|
switch ($repeat_type) { |
||||||
|
// every day until.... |
||||||
|
case 1: |
||||||
|
$skip = '+1 day'; |
||||||
|
$back = '-1 day'; |
||||||
|
$msg = t('You have booked every day from %start until %end', array('%start' => $start_yyyy_mm_dd, '%end' => $end)); |
||||||
|
break; |
||||||
|
|
||||||
|
// this day of the week until.. |
||||||
|
case 2: |
||||||
|
$skip = '+7 day'; |
||||||
|
$back = '-7 day'; |
||||||
|
$msg = t('You have booked every %day from %start until %end', array('%day' => $day, '%start' => $start_yyyy_mm_dd, '%end' => $end)); |
||||||
|
break; |
||||||
|
} |
||||||
|
|
||||||
|
// set NID as Series ID for both the primary entity and the repeat nodes |
||||||
|
$entity->set('reservation_series_id', $eid); |
||||||
|
|
||||||
|
// then lets save the original reservation with Series ID but set SAVED so we skip the update hook |
||||||
|
$entity->saved = true; |
||||||
|
$entity->save(); |
||||||
|
|
||||||
|
// lets build the rest of the reservations in the series |
||||||
|
$tmp = $entity->createDuplicate(); |
||||||
|
$date = $start; |
||||||
|
$failed = array(); |
||||||
|
while (strtotime($date) <= strtotime($back, strtotime($end))) { |
||||||
|
$date = date('Y-m-d', strtotime($skip, strtotime($date))); |
||||||
|
|
||||||
|
// must check to see if next booking is available |
||||||
|
// the first one we don't check as we could not have picked it if it wasn't |
||||||
|
if (reserve_is_slot_free($rid, $ebundle, $date, $time, $length)) { |
||||||
|
$new = $tmp->createDuplicate(); |
||||||
|
$new->set('reservation_date', $date); |
||||||
|
$new->saved = true; |
||||||
|
$new->save(); |
||||||
|
} |
||||||
|
else { |
||||||
|
$failed[] = $date; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// lets spit out some useful msgs |
||||||
|
// first clear the msg stating we just created the reservation entity |
||||||
|
drupal_get_messages('status'); |
||||||
|
drupal_set_message(t('Your reservation series has been booked.')); |
||||||
|
drupal_set_message($msg); |
||||||
|
if (count($failed)) { |
||||||
|
$dates = Markup::create('<br>' . implode('<br>', $failed)); |
||||||
|
drupal_set_message(t('The following dates were not booked due to scheduling conflicts: %dates', array('%dates' => $dates)), 'warning'); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/* |
||||||
|
* to handle Series edits |
||||||
|
* |
||||||
|
* this is only run on the OTHER reservations in series triggered from submitting changes to one of the |
||||||
|
* reservations in that series |
||||||
|
* |
||||||
|
* the changes to which ever reservation is being edited will be done in normal entity_save() |
||||||
|
* |
||||||
|
*/ |
||||||
|
function reserve_reserve_reservation_update($entity) { |
||||||
|
// when we do a node_save below or when we insert from hook_insert above; it will hit this hook - so lets skip |
||||||
|
if (isset($entity->saved)){ |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
$sid = $entity->reservation_series_id->getString(); |
||||||
|
|
||||||
|
// if not part of a Series or special single only url -> do nothing |
||||||
|
if (!$sid || isset($_GET['single'])) { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
// reservation details |
||||||
|
$start = $entity->reservation_date->getString(); |
||||||
|
$time = $entity->reservation_time->getString(); |
||||||
|
$length = $entity->reservation_length->getString(); |
||||||
|
$rid = $entity->reservable_id->getString(); |
||||||
|
$rtype = $entity->reservable_content_type->getString(); |
||||||
|
$ebundle = $rtype . '.' . entity_load($rtype, $rid)->bundle(); |
||||||
|
$private = $entity->reservation_private->getString(); |
||||||
|
|
||||||
|
// grab all reservations in this series except the one being submitted |
||||||
|
$ids = \Drupal::service('entity.query') |
||||||
|
->get('reserve_reservation') |
||||||
|
->condition('status', TRUE) |
||||||
|
->condition('reservation_series_id', $sid) |
||||||
|
->condition('id', $entity->id(), '!=') |
||||||
|
->execute(); |
||||||
|
$results = \Drupal::entityTypeManager()->getStorage('reserve_reservation')->loadMultiple($ids); |
||||||
|
|
||||||
|
$failed = array(); |
||||||
|
foreach ($results as $data) { |
||||||
|
// for now, only allow changing Title, Privacy, Length |
||||||
|
// first 2 are easy; but to change length we need to check if that period is available and if not delete entry from Series |
||||||
|
$data->set('name', $entity->getName()); |
||||||
|
$data->set('reservation_private', $private); |
||||||
|
|
||||||
|
$date = date('Y-m-d', strtotime($data->reservation_date->getString())); |
||||||
|
if (reserve_is_slot_free($rid, $ebundle, $date, $time, $length)) { |
||||||
|
$data->set('reservation_length', $length); |
||||||
|
} |
||||||
|
// if slot is not available; do not update the length of this reservation |
||||||
|
// this is different than D7 version - in D7 we simply deleted the reservation; which seems silly. |
||||||
|
else { |
||||||
|
$failed[] = $date; |
||||||
|
} |
||||||
|
// update this reservation in our series |
||||||
|
$data->saved = true; |
||||||
|
$data->save(); |
||||||
|
} |
||||||
|
|
||||||
|
// lets spit out some useful msgs |
||||||
|
drupal_set_message(t('Your reservation series has been modified.')); |
||||||
|
if (count($failed)) { |
||||||
|
$dates = Markup::create('<br>' . implode('<br>', $failed)); |
||||||
|
drupal_set_message(t('NOTE: The following dates did not have their length changed due to scheduling conflicts: %dates', array('%dates' => $dates)), 'warning'); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* |
||||||
|
* Handle deleting other reservations in a series (selected reservation should already be handle through entity->delete() |
||||||
|
* |
||||||
|
* @param $entity |
||||||
|
*/ |
||||||
|
function reserve_reserve_reservation_delete($entity) { |
||||||
|
if($_SESSION['reserve_delete_type']) { |
||||||
|
_reserve_series_delete($entity); |
||||||
|
} |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
function _reserve_series_delete($entity) { |
||||||
|
$sid = $entity->get('reservation_series_id')->getString(); |
||||||
|
// grab all reservations in this series |
||||||
|
$ids = \Drupal::service('entity.query') |
||||||
|
->get('reserve_reservation') |
||||||
|
->condition('reservation_series_id', $sid) |
||||||
|
->execute(); |
||||||
|
$results = \Drupal::entityTypeManager()->getStorage('reserve_reservation')->loadMultiple($ids); |
||||||
|
foreach ($results as $result) { |
||||||
|
$result->delete(); |
||||||
|
} |
||||||
|
$title = $entity->get('name')->getString(); |
||||||
|
drupal_set_message(t('The reservation series @title was deleted.', array('@title' => $title))); |
||||||
|
} |
@ -0,0 +1,32 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
/** |
||||||
|
* @file |
||||||
|
* Contains reserve_category.page.inc. |
||||||
|
* |
||||||
|
* Page callback for reservation categories. |
||||||
|
*/ |
||||||
|
|
||||||
|
use Drupal\Core\Render\Element; |
||||||
|
use Drupal\Core\Link; |
||||||
|
use Drupal\Core\Url; |
||||||
|
|
||||||
|
/** |
||||||
|
* Prepares variables for Reservation Category templates. |
||||||
|
* |
||||||
|
* Default template: reserve_category.html.twig. |
||||||
|
* |
||||||
|
* @param array $variables |
||||||
|
* An associative array containing: |
||||||
|
* - elements: An associative array containing the user information and any |
||||||
|
* - attributes: HTML attributes for the containing element. |
||||||
|
*/ |
||||||
|
function template_preprocess_reserve_category(array &$variables) { |
||||||
|
// Fetch ReserveCategory Entity Object. |
||||||
|
$reserve_category = $variables['elements']['#reserve_category']; |
||||||
|
|
||||||
|
// Helpful $content variable for templates. |
||||||
|
foreach (Element::children($variables['elements']) as $key) { |
||||||
|
$variables['content'][$key] = $variables['elements'][$key]; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,32 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
/** |
||||||
|
* @file |
||||||
|
* Contains reserve_reservation.page.inc. |
||||||
|
* |
||||||
|
* Page callback for reservations. |
||||||
|
*/ |
||||||
|
|
||||||
|
use Drupal\Core\Render\Element; |
||||||
|
use Drupal\Core\Link; |
||||||
|
use Drupal\Core\Url; |
||||||
|
|
||||||
|
/** |
||||||
|
* Prepares variables for Reservation templates. |
||||||
|
* |
||||||
|
* Default template: reserve_reservation.html.twig. |
||||||
|
* |
||||||
|
* @param array $variables |
||||||
|
* An associative array containing: |
||||||
|
* - elements: An associative array containing the user information and any |
||||||
|
* - attributes: HTML attributes for the containing element. |
||||||
|
*/ |
||||||
|
function template_preprocess_reserve_reservation(array &$variables) { |
||||||
|
// Fetch ReserveReservation Entity Object. |
||||||
|
$reserve_reservation = $variables['elements']['#reserve_reservation']; |
||||||
|
|
||||||
|
// Helpful $content variable for templates. |
||||||
|
foreach (Element::children($variables['elements']) as $key) { |
||||||
|
$variables['content'][$key] = $variables['elements'][$key]; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,113 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace Drupal\reserve; |
||||||
|
|
||||||
|
use Drupal\Component\Utility\Unicode; |
||||||
|
use Drupal\Core\Entity\EntityInterface; |
||||||
|
use Drupal\Core\Form\FormStateInterface; |
||||||
|
use Drupal\field\Entity\FieldConfig; |
||||||
|
|
||||||
|
/** |
||||||
|
* Helper for reserve_form_alter(). |
||||||
|
*/ |
||||||
|
class BundleFormAlter { |
||||||
|
|
||||||
|
/** |
||||||
|
* Entity type definition. |
||||||
|
* |
||||||
|
* @var \Drupal\Core\Entity\ContentEntityTypeInterface |
||||||
|
*/ |
||||||
|
protected $definition; |
||||||
|
|
||||||
|
/** |
||||||
|
* The entity bundle. |
||||||
|
* |
||||||
|
* @var string |
||||||
|
*/ |
||||||
|
protected $bundle; |
||||||
|
|
||||||
|
/** |
||||||
|
* The bundle label. |
||||||
|
* |
||||||
|
* @var string |
||||||
|
*/ |
||||||
|
protected $bundleLabel; |
||||||
|
|
||||||
|
/** |
||||||
|
* The entity type ID. |
||||||
|
* |
||||||
|
* @var string |
||||||
|
*/ |
||||||
|
protected $entityTypeId; |
||||||
|
|
||||||
|
/** |
||||||
|
* The form entity which has been used for populating form element defaults. |
||||||
|
* |
||||||
|
* @var \Drupal\Core\Entity\EntityInterface |
||||||
|
*/ |
||||||
|
protected $entity; |
||||||
|
|
||||||
|
/** |
||||||
|
* Construct a BundleFormAlter object. |
||||||
|
* |
||||||
|
* @param \Drupal\Core\Entity\EntityInterface $entity |
||||||
|
* The entity object. |
||||||
|
*/ |
||||||
|
public function __construct(EntityInterface $entity) { |
||||||
|
$this->entity = $entity; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* This is a helper for og_ui_form_alter(). |
||||||
|
* |
||||||
|
* @param array $form |
||||||
|
* The form variable. |
||||||
|
* @param \Drupal\Core\Form\FormStateInterface $form_state |
||||||
|
* The form state object. |
||||||
|
*/ |
||||||
|
public function formAlter(array &$form, FormStateInterface $form_state) { |
||||||
|
$this->prepare($form, $form_state); |
||||||
|
$this->addReserveCategories($form, $form_state); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Prepares object properties and adds the og details element. |
||||||
|
* |
||||||
|
* @param array $form |
||||||
|
* The form variable. |
||||||
|
* @param \Drupal\Core\Form\FormStateInterface $form_state |
||||||
|
* The form state object. |
||||||
|
*/ |
||||||
|
protected function prepare(array &$form, FormStateInterface $form_state) { |
||||||
|
// Example: article. |
||||||
|
$this->bundle = $this->entity->id(); |
||||||
|
// Example: Article. |
||||||
|
$this->bundleLabel = Unicode::lcfirst($this->entity->label()); |
||||||
|
$this->definition = $this->entity->getEntityType(); |
||||||
|
// Example: node. |
||||||
|
$this->entityTypeId = $this->definition->getBundleOf(); |
||||||
|
|
||||||
|
$form['reserve'] = [ |
||||||
|
'#type' => 'details', |
||||||
|
'#title' => t('Reserve'), |
||||||
|
'#collapsible' => TRUE, |
||||||
|
'#group' => 'additional_settings', |
||||||
|
'#description' => t('If any Reserve Categories are selected here; this bundle will be reservable.'), |
||||||
|
]; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Adds the "is group?" checkbox. |
||||||
|
*/ |
||||||
|
protected function addReserveCategories(array &$form, FormStateInterface $form_state) { |
||||||
|
$options = array('big', 'small'); |
||||||
|
$form['reserve']['reserve_categories'] = [ |
||||||
|
'#type' => 'checkboxes', |
||||||
|
'#title' => t('Categories'), |
||||||
|
'#options' => array_combine($options, $options), |
||||||
|
//'#default_value' => Og::isGroup($this->entityTypeId, $this->bundle), |
||||||
|
|
||||||
|
]; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,665 @@ |
|||||||
|
<?php |
||||||
|
namespace Drupal\reserve\Controller; |
||||||
|
|
||||||
|
use Drupal\Core\Controller\ControllerBase; |
||||||
|
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; |
||||||
|
use Drupal\Core\Link; |
||||||
|
use Drupal\Core\Url; |
||||||
|
use Drupal\Core\Render\Markup; |
||||||
|
use Symfony\Component\HttpFoundation\JsonResponse; |
||||||
|
use Drupal\reserve\Entity\ReserveReservation; |
||||||
|
use Drupal\Core\Access\AccessResult; |
||||||
|
use Drupal\Core\Session\AccountInterface; |
||||||
|
|
||||||
|
/** |
||||||
|
* Provides route responses for the Example module. |
||||||
|
*/ |
||||||
|
class CalendarController extends ControllerBase { |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns a simple page. |
||||||
|
* |
||||||
|
* Param: $ebundle, e.g. node.room |
||||||
|
* |
||||||
|
* @return array |
||||||
|
* A simple renderable array. |
||||||
|
*/ |
||||||
|
public function calendar($ebundle, $selected_month = null, $selected_day = null) { |
||||||
|
$ebundles = reserve_get_reserve_bundles(); |
||||||
|
if(!in_array($ebundle, $ebundles)) { |
||||||
|
throw new NotFoundHttpException(); |
||||||
|
} |
||||||
|
else { |
||||||
|
return $this->getBundleCalendar($ebundle, $selected_month, $selected_day); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public function calendarTitle($ebundle) { |
||||||
|
$bundle = ebundle_split($ebundle, 'bundle'); |
||||||
|
return t('@bundle Calendar', array('@bundle' => ucwords($bundle))); |
||||||
|
} |
||||||
|
|
||||||
|
private function getBundleCalendar($ebundle, $selected_month = null, $selected_day = null) { |
||||||
|
$config = \Drupal::config('reserve.settings'); |
||||||
|
// likely no need for this as not used anywhere else; but maybe for external modules |
||||||
|
global $yyyy_mmdd; |
||||||
|
|
||||||
|
//$entity_type = ebundle_split($ebundle, 'type'); |
||||||
|
//$bundle = ebundle_split($ebundle, 'bundle'); |
||||||
|
$category_field = reserve_category_fields($ebundle); |
||||||
|
|
||||||
|
// dates are now keyed by Cat ID; but we only need one of these to build calendar but make sure its the one which starts earliest |
||||||
|
$datesbycat = reserve_dates($ebundle, $selected_month, $selected_day); |
||||||
|
$categories = reserve_categories($ebundle); |
||||||
|
|
||||||
|
// allow other modules to alter the categories |
||||||
|
\Drupal::moduleHandler()->alter('reserve_categories', $categories); |
||||||
|
|
||||||
|
// if no Categories left; we should not bother with the rest of this |
||||||
|
if (!count($categories)) { |
||||||
|
drupal_set_message(t('There are no configured Reserve Categories. Please contact the System Administrator'), 'warning'); |
||||||
|
return ''; |
||||||
|
} |
||||||
|
|
||||||
|
$earliest = $this->reserve_earliest_category($categories); |
||||||
|
$dates = $datesbycat[$earliest]; |
||||||
|
|
||||||
|
// Determine which day has been selected by the user. If the user has entered a url that specifies a day outside of the |
||||||
|
// allowable reservation window, then set the current day as the selected day. |
||||||
|
$yyyy_mmdd = $dates[0]['yyyymmdd']; |
||||||
|
foreach ($dates as $day) { |
||||||
|
if ($day['selected']) { |
||||||
|
$yyyy_mmdd = $day['yyyymmdd']; |
||||||
|
} |
||||||
|
} |
||||||
|
if ($yyyy_mmdd == $dates[0]['yyyymmdd']) { |
||||||
|
$dates[0]['selected'] = TRUE; |
||||||
|
$dates[0]['today'] = TRUE; |
||||||
|
} |
||||||
|
|
||||||
|
// a bit hacky; but we need to store what the calendar is using for its date so we can use this in theme functions later |
||||||
|
//$_SESSION['reservations_current_day'] = $yyyy_mmdd; |
||||||
|
|
||||||
|
// If the day being displayed is today, only display time slots that are later than the current time minus two hours. |
||||||
|
$today_displayed = FALSE; |
||||||
|
foreach ($dates as $day) { |
||||||
|
if (($day['selected']) && $day['today']) { |
||||||
|
$today_displayed = TRUE; |
||||||
|
} |
||||||
|
} |
||||||
|
if ($today_displayed) { |
||||||
|
$hours = reserve_hours('limited'); |
||||||
|
} |
||||||
|
else { |
||||||
|
$hours = reserve_hours(); |
||||||
|
} |
||||||
|
|
||||||
|
// Determine the open hours (display version) for the date selected by the user. |
||||||
|
$building_hours_day = reserve_facility_hours($yyyy_mmdd); |
||||||
|
$building_hours_display = $building_hours_day['display']; |
||||||
|
|
||||||
|
// For each time slot, determine if the rooms are open or closed. |
||||||
|
$int_first_shift_open = intval($building_hours_day['first_shift_open']); |
||||||
|
$int_first_shift_close = intval($building_hours_day['first_shift_close']); |
||||||
|
$int_second_shift_open = intval($building_hours_day['second_shift_open']); |
||||||
|
$int_second_shift_close = intval($building_hours_day['second_shift_close']); |
||||||
|
$open_24 = $building_hours_day['open_24_hours']; |
||||||
|
$x = 0; |
||||||
|
$buffer = $config->get('show_before_after_hours') * 100; |
||||||
|
foreach ($hours as $time_slot) { |
||||||
|
$int_time_slot_time = intval($time_slot['time']); |
||||||
|
if ($building_hours_day['open_24_hours']) { |
||||||
|
$time_slot['open'] = TRUE; |
||||||
|
} |
||||||
|
elseif ((($int_time_slot_time >= $int_first_shift_open) && ($int_time_slot_time < $int_first_shift_close)) || |
||||||
|
(($int_time_slot_time >= $int_second_shift_open) && ($int_time_slot_time < $int_second_shift_close))) { |
||||||
|
$time_slot['open'] = TRUE; |
||||||
|
} |
||||||
|
else { |
||||||
|
$time_slot['open'] = FALSE; |
||||||
|
} |
||||||
|
|
||||||
|
// if not open ALL day let's limit display to start just before first open shift (or 2nd if only one used) |
||||||
|
// this assume you must have 1st shift defined and possible 2nd (i.e. can't define only 2nd shift) |
||||||
|
if (!$open_24 && $buffer != 300) { |
||||||
|
if ($int_first_shift_open < 9999 && ($hours[$x]['time'] < $int_first_shift_open - $buffer)) { |
||||||
|
unset($hours[$x]); |
||||||
|
} |
||||||
|
else { |
||||||
|
$hours[$x] = $time_slot; |
||||||
|
} |
||||||
|
// and do the same for closing |
||||||
|
if (isset($hours[$x])) { |
||||||
|
if ($int_second_shift_close < 9999) { |
||||||
|
if ($hours[$x]['time'] >= $int_second_shift_close + $buffer) { |
||||||
|
unset($hours[$x]); |
||||||
|
} |
||||||
|
} |
||||||
|
elseif ($int_first_shift_close < 9999) { |
||||||
|
if ($hours[$x]['time'] >= $int_first_shift_close + $buffer) { |
||||||
|
unset($hours[$x]); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
else { |
||||||
|
$hours[$x] = $time_slot; |
||||||
|
} |
||||||
|
$x++; |
||||||
|
} |
||||||
|
$times = reserve_times(); |
||||||
|
$entities = reserve_entities($ebundle); |
||||||
|
|
||||||
|
// Initialize the $reservations array. |
||||||
|
$reservations = array(); |
||||||
|
foreach ($entities as $entity) { |
||||||
|
$entity_name = $entity->label(); |
||||||
|
foreach ($hours as $time_slot) { |
||||||
|
$time = $time_slot['time']; |
||||||
|
$reservations[$entity->id()][$time] = array( |
||||||
|
'time' => $time, |
||||||
|
'display' => $time_slot['display'], |
||||||
|
'class' => $time_slot['class'], |
||||||
|
'id' => '', |
||||||
|
'booked' => FALSE, |
||||||
|
'start' => FALSE, |
||||||
|
'end' => FALSE, |
||||||
|
'user' => '', |
||||||
|
'name' => '', |
||||||
|
); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
$results = array(); |
||||||
|
$ids = \Drupal::service('entity.query') |
||||||
|
->get('reserve_reservation') |
||||||
|
->condition('status', TRUE) |
||||||
|
->condition('reservation_date', $yyyy_mmdd . '%', 'like') |
||||||
|
->condition('reservation_ebundle', $ebundle) |
||||||
|
//->sort('reservation_time', 'DESC') |
||||||
|
//->sort('reservations_display_order', 'ASC'); |
||||||
|
->accessCheck(FALSE) |
||||||
|
->execute(); |
||||||
|
|
||||||
|
$results = \Drupal::entityTypeManager()->getStorage('reserve_reservation')->loadMultiple($ids); |
||||||
|
|
||||||
|
foreach ($results as $data) { |
||||||
|
$id = $data->id(); |
||||||
|
$time = $data->reservation_time->getString(); |
||||||
|
$rid = $data->reservable_id->getString(); |
||||||
|
$name = $data->label(); |
||||||
|
$user = $data->getOwner(); |
||||||
|
$reservations[$rid][$time]['booked'] = TRUE; |
||||||
|
$reservations[$rid][$time]['class'] .= ' booked'; |
||||||
|
$reservations[$rid][$time]['name'] = $name; |
||||||
|
$reservations[$rid][$time]['user_name'] = $user->getDisplayName(); |
||||||
|
$reservations[$rid][$time]['id'] = $id; |
||||||
|
$reservations[$rid][$time]['series_id'] = $data->reservation_series_id->getString() ? $data->reservation_series_id->getString() : ''; |
||||||
|
$reservations[$rid][$time]['user'] = $user->id(); |
||||||
|
$reservations[$rid][$time]['blocked'] = $data->reservation_private->getString() ? $data->reservation_private->getString() : FALSE; |
||||||
|
|
||||||
|
// add rest of slots as booked for the length of this reservation |
||||||
|
$length = $data->reservation_length->getString();; |
||||||
|
$time_slots = $length / 30; |
||||||
|
$reservations[$rid][$time]['slots'] = $time_slots; |
||||||
|
$remainder = $length % 30; |
||||||
|
if ($remainder > 1) { |
||||||
|
$time_slots++; |
||||||
|
} |
||||||
|
$key = array_search($time, $times); |
||||||
|
$x = 2; |
||||||
|
while ($x <= $time_slots) { |
||||||
|
$key++; |
||||||
|
$next_time = $times[$key]; |
||||||
|
$reservations[$rid][$next_time]['booked'] = TRUE; |
||||||
|
$reservations[$rid][$next_time]['class'] .= ' booked'; |
||||||
|
$x++; |
||||||
|
// reservation time slots can't go passed midnight; i.e. slot 47 |
||||||
|
if ($key == 47) { |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// add in pre/post buffer for setup/takedown (rev 7.x-1.3+) |
||||||
|
// - if the slot is part of buffer we add "setup" to class |
||||||
|
// - if we don't have admin rights; we also mark it as booked so no one can book in these slots |
||||||
|
$category = $categories[$entities[$rid]->$category_field->getString()]; |
||||||
|
$preslots = $category['prebuffer'] / 30; |
||||||
|
$postslots = $category['postbuffer'] / 30; |
||||||
|
$startkey = array_search($reservations[$rid][$time]['time'], $times); |
||||||
|
$endkey = $startkey + $time_slots; |
||||||
|
$k = $startkey - $preslots; |
||||||
|
$bookover = \Drupal::currentUser()->hasPermission('book over reservation buffer'); |
||||||
|
while ($k < $startkey) { |
||||||
|
if (!$reservations[$rid][$times[$k]]['booked']) { |
||||||
|
$reservations[$rid][$times[$k]]['class'] .= ' setup'; |
||||||
|
} |
||||||
|
$reservations[$rid][$times[$k]]['booked'] = $bookover ? $reservations[$rid][$times[$k]]['booked'] : true; |
||||||
|
$k++; |
||||||
|
} |
||||||
|
$k = $endkey; |
||||||
|
while ($k < $endkey + $postslots) { |
||||||
|
if (!$reservations[$rid][$times[$k]]['booked']) { |
||||||
|
$reservations[$rid][$times[$k]]['class'] .= ' setup'; |
||||||
|
} |
||||||
|
$reservations[$rid][$times[$k]]['booked'] = $bookover ? $reservations[$rid][$times[$k]]['booked'] : true; |
||||||
|
$k++; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
$vars = array( |
||||||
|
'ebundle' => $ebundle, |
||||||
|
'dates' => $dates, |
||||||
|
'categories' => $categories, |
||||||
|
'reservations' => $reservations, |
||||||
|
'hours' => $hours, |
||||||
|
'rooms' => $entities, |
||||||
|
'user_reservations' => reserve_user_reservations(), |
||||||
|
); |
||||||
|
|
||||||
|
// @todo: should do something here with render array and tpl file |
||||||
|
$variables = $this->calenderPage($vars); |
||||||
|
$variables['#theme'] = 'calendar_template'; |
||||||
|
$variables['#attached']['library'] = 'reserve/reserve'; |
||||||
|
$variables['#building_hours_display'] = $building_hours_display; |
||||||
|
|
||||||
|
return $variables; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Theme the reservation calendar page. |
||||||
|
* |
||||||
|
* @global object $user |
||||||
|
* Drupal user object. |
||||||
|
* @global type $base_url |
||||||
|
* Application base url. |
||||||
|
* |
||||||
|
* @param array $dates |
||||||
|
* An array containing information about all the possible days for which a |
||||||
|
* reservtion can be made. |
||||||
|
* @param array $categories |
||||||
|
* An array of all the room categories. |
||||||
|
* @param array $reservations |
||||||
|
* An array representing all the reservations that have been made for the |
||||||
|
* day that is being displayed on the calendar. |
||||||
|
* @param array $hours |
||||||
|
* An array representing every half hour time slot in a single day. |
||||||
|
* @param string $building_hours_display |
||||||
|
* A user friendly string of the open hours for the day being displayed |
||||||
|
* on the calendar. |
||||||
|
* @param array $rooms |
||||||
|
* An array representing all of the ENTITIES that can be reserved. |
||||||
|
* @param array $user_reservations |
||||||
|
* An array representing the current user's reservations for the allowable |
||||||
|
* reservation period. |
||||||
|
* |
||||||
|
* @return string |
||||||
|
* The html for displaying the page. |
||||||
|
*/ |
||||||
|
private function calenderPage($vars) { |
||||||
|
/** |
||||||
|
* @var $ebundle |
||||||
|
* @var $dates |
||||||
|
* @var $categories |
||||||
|
* @var $reservations |
||||||
|
* @var $hours |
||||||
|
* @var $building_hours_display |
||||||
|
* @var $rooms |
||||||
|
* @var $user_reservations |
||||||
|
*/ |
||||||
|
extract($vars); |
||||||
|
|
||||||
|
if (!count($rooms)) { |
||||||
|
$this->messenger()->addError(t('You will need to first add entities which can be reserved.')); |
||||||
|
throw new NotFoundHttpException(); |
||||||
|
} |
||||||
|
|
||||||
|
global $base_url; |
||||||
|
$user = \Drupal::currentUser(); |
||||||
|
$extended = \Drupal::currentUser()->hasPermission('add reservations extended'); |
||||||
|
$config = \Drupal::config('reserve.settings'); |
||||||
|
$category_field = reserve_category_fields($ebundle); |
||||||
|
$clearimg = '<img src="' . base_path() . drupal_get_path('module', 'reserve') . '/images/clear.png" />'; |
||||||
|
$modal = ['attributes' => [ |
||||||
|
'class' => ['use-ajax'], |
||||||
|
'data-dialog-type' => 'modal', |
||||||
|
'data-dialog-options' => json_encode(['width' => 700]) |
||||||
|
]]; |
||||||
|
|
||||||
|
$entity_type = ebundle_split($ebundle, 'type'); |
||||||
|
$bundle = ebundle_split($ebundle, 'bundle'); |
||||||
|
|
||||||
|
// to support minimum adv booking per category; let's get available dates per cat |
||||||
|
$datespercat = reserve_dates($ebundle,null, null, true); |
||||||
|
|
||||||
|
// pass some variables to JS |
||||||
|
$format = strtolower($config->get('date_format') ? $config->get('date_format') : 'y/m/d'); |
||||||
|
$variables['#attached']['drupalSettings']['reserve']['dateFormat'] = $format; |
||||||
|
$variables['#attached']['drupalSettings']['reserve']['ebundle'] = $ebundle; |
||||||
|
$max_length = $extended ? |
||||||
|
($config->get('reservation_max_length_admin') ? $config->get('reservation_max_length_admin') : 120) : |
||||||
|
($config->get('reservation_max_length_standard') ? $config->get('reservation_max_length_standard') : 120); |
||||||
|
$variables['#attached']['drupalSettings']['reserve']['maxLength'] = $max_length; |
||||||
|
|
||||||
|
// Determine which date has been selected by the user. |
||||||
|
foreach ($dates as $day) { |
||||||
|
if ($day['selected'] == TRUE) { |
||||||
|
$day_of_week = $day['day-of-week']; |
||||||
|
$month_number = $day['month-number']; |
||||||
|
$month = $day['month']; |
||||||
|
$xday = $day['day']; |
||||||
|
$year = $day['year']; |
||||||
|
$yyyymmdd = $day['yyyymmdd']; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
$variables['#calendar-text'] = $config->get('calendar_text'); |
||||||
|
$variables['#reserve_room_instructions_text'] = $config->get('reserve_instructions') ? $config->get('reserve_instructions') : |
||||||
|
t('To make a reservation, click on the desired time/day in the calendar below. You will be asked to login.'); |
||||||
|
$variables['#arrow'] = base_path() . drupal_get_path('module', 'reserve') . '/images/arrow-icon.png'; |
||||||
|
$variables['#date'] = format_date(strtotime($month . ' ' . $xday . ', ' . $year), 'custom', 'l, F d, Y'); |
||||||
|
$variables['#date_picker'] = \Drupal::formBuilder()->getForm('Drupal\reserve\Form\CalendarDatePicker'); |
||||||
|
|
||||||
|
$field = reserve_category_fields($ebundle); |
||||||
|
$fconfig = \Drupal\field\Entity\FieldConfig::loadByName($entity_type, $bundle, $field)->getSettings(); |
||||||
|
$variables['#calendar_header'] = $fconfig['calendar_header']; |
||||||
|
$variables['#reservation_instructions'] = $fconfig['reservation_instructions']; |
||||||
|
|
||||||
|
// Bundle name (or Entity Type name if no bundles) |
||||||
|
$bundle_info = \Drupal::service("entity_type.bundle.info")->getAllBundleInfo(); |
||||||
|
$bundle = $bundle_info[current($rooms)->getEntityTypeId()][current($rooms)->bundle()]['label']; |
||||||
|
|
||||||
|
// Reservation calendar grid: |
||||||
|
// |
||||||
|
// Each block on the grid is assigned one (or more) of the following classes: |
||||||
|
// |
||||||
|
// closed - the building is closed; |
||||||
|
// booked - the building is open and the time slot has been reserved; |
||||||
|
// open - the building is open, the time slot has not been reserved, but the user must login to reserve the time slot; |
||||||
|
// reservable - the building is open, the time slot has not been reserved and the user is able to reserve the time slot. |
||||||
|
// setup - buffer zones added before/after bookings to allow for setup/takedown (per category) |
||||||
|
// |
||||||
|
|
||||||
|
// Panel container. |
||||||
|
|
||||||
|
// If the user is logged in, the class for each unbooked time slot is 'reservable'. If the user is not logged in, the class is 'open'. |
||||||
|
// Only logged in users can click a block of time to open the reservation form. |
||||||
|
$unbooked_class = ($user->id()) ? 'reservable' : 'open'; |
||||||
|
|
||||||
|
// Create a tab for each room category. Each tab contains a grid of time slots and rooms. |
||||||
|
$i = 0; |
||||||
|
foreach ($categories as $index => $category) { |
||||||
|
$table = array(); |
||||||
|
|
||||||
|
// Category TABS |
||||||
|
$categories[$index]['active'] = ($i == 0) ? 'active' : ''; |
||||||
|
$categories[$index]['tag'] = strtolower(preg_replace('/[^a-zA-Z0-9-]+/', '-', $category['title'])); |
||||||
|
|
||||||
|
// Show the first tab and hide all others. |
||||||
|
//// @todo: use JS to set active based on anchor |
||||||
|
$categories[$index]['show'] = ($i == 0) ? 'show' : 'hide'; |
||||||
|
|
||||||
|
$i++; |
||||||
|
$r = 0; $c = 0; |
||||||
|
|
||||||
|
// Date and building hours. |
||||||
|
$flipped = $config->get('calendar_flipped'); |
||||||
|
$orientclass = $flipped ? 'orient-horiz' : 'orient-vert'; |
||||||
|
|
||||||
|
$table[$r][$c] = '<li class="room-info">' . $bundle . '</li>' . "\n"; |
||||||
|
$r++; |
||||||
|
|
||||||
|
// Available hours column. |
||||||
|
foreach ($hours as $time_slot) { |
||||||
|
$time_display = ($time_slot['class'] == 'odd') ? t($time_slot['display']) : ""; |
||||||
|
$table[$r][$c] = '<li class="' . $time_slot['class'] . ' timeslot" time="' . $time_slot['time'] . '">' . $time_display . '</li>' . "\n"; |
||||||
|
$r++; |
||||||
|
} |
||||||
|
$table[$r][$c] = '<li class="room-info room-info-footer">' . $bundle . '</li>' . "\n"; |
||||||
|
$r++; |
||||||
|
|
||||||
|
// Column for each room in the category. |
||||||
|
$rooms_per_category = 0; |
||||||
|
foreach ($rooms as $room) { |
||||||
|
$rid = $room->id(); |
||||||
|
// Count the number of rooms in the selected category. |
||||||
|
if ($room->$category_field->getString() == $category['id']) { |
||||||
|
$rooms_per_category++; |
||||||
|
} |
||||||
|
$room_name = $room->label(); |
||||||
|
$room_link = Link::fromTextAndUrl($room_name, Url::fromUri('internal:/' . $entity_type . '/' . $rid))->toString(); |
||||||
|
|
||||||
|
// use qtip if we have it |
||||||
|
if (\Drupal::moduleHandler()->moduleExists('qtip')) { |
||||||
|
$variables['#room_desc'] = $room->body->getString(); |
||||||
|
$room_info = '<span class="qtip-link"><span class="qtip-tooltip">' . $room_desc . '</span>' . $room_link . '</span>'; |
||||||
|
} |
||||||
|
else { |
||||||
|
$room_info = $room_link; |
||||||
|
} |
||||||
|
|
||||||
|
if ($room->$category_field->getString() == $category['id']) { |
||||||
|
$c++; $r = 0; |
||||||
|
|
||||||
|
// Room name |
||||||
|
$cell = '<li class="room-info">' . $room_info . '</li>'; |
||||||
|
$r++; |
||||||
|
|
||||||
|
// Populate each time slot. |
||||||
|
foreach ($hours as $time_slot) { |
||||||
|
$r++; |
||||||
|
$time = $time_slot['time']; |
||||||
|
$open = $time_slot['open']; |
||||||
|
|
||||||
|
// lets use slot class from reservation if it is set |
||||||
|
$slotclass = isset($reservations[$rid][$time_slot['time']]['class']) ? $reservations[$rid][$time_slot['time']]['class'] : $time_slot['class']; |
||||||
|
|
||||||
|
// to support min adv booking per cat; let's simply mark all slots as closed for dates not available to this user for this cat |
||||||
|
if (!isset($datespercat[$category['id']][$yyyymmdd])) { |
||||||
|
$open = false; |
||||||
|
} |
||||||
|
|
||||||
|
// Determine if the building is open or closed for this time slot. |
||||||
|
if ($open) { |
||||||
|
$booked_class = ($reservations[$rid][$time]['booked']) ? '' : $unbooked_class; |
||||||
|
} |
||||||
|
else { |
||||||
|
$booked_class = 'closed'; |
||||||
|
} |
||||||
|
// The time slot can be reserved by the current user. |
||||||
|
$viewable_class = ''; |
||||||
|
$widthclass = ''; |
||||||
|
if ($booked_class == 'reservable' && $user->hasPermission('add reservations')) { |
||||||
|
$link = Link::fromTextAndUrl( |
||||||
|
Markup::create($clearimg), |
||||||
|
Url::fromUri('internal:/reserve_reservation/add/' . |
||||||
|
$month_number . '/' . $xday . '/' . $time_slot['time'] . '/' . $rid . '/' . $ebundle, $modal)) |
||||||
|
->toString(); |
||||||
|
} |
||||||
|
// The time slot can be reserved, but the user must login first. |
||||||
|
elseif ($booked_class == 'open') { |
||||||
|
$link = Link::fromTextAndUrl( |
||||||
|
Markup::create($clearimg), |
||||||
|
Url::fromUri('internal:/user/login?destination=/reserve_reservation/add/' . |
||||||
|
$month_number . '/' . $xday . '/' . $time_slot['time'] . '/' . $rid . '/' . $ebundle, $modal)) |
||||||
|
->toString(); |
||||||
|
} |
||||||
|
elseif ($booked_class == 'closed') { |
||||||
|
$link = ''; |
||||||
|
} |
||||||
|
else { |
||||||
|
// if the slot has no ID this means it is the latter slots of the booking |
||||||
|
$viewable_class = ''; |
||||||
|
$link = ''; |
||||||
|
|
||||||
|
// The time slot has a reservation that can be edited by the current user. |
||||||
|
if ($id = $reservations[$rid][$time]['id']) { |
||||||
|
$reservation = entity_load('reserve_reservation', $id); |
||||||
|
$viewable_class = $reservation->access('update') ? 'viewable' : ''; |
||||||
|
if ($viewable_class == 'viewable') { |
||||||
|
$options = array_merge_recursive($modal, array( |
||||||
|
'attributes' => array( |
||||||
|
'title' => $reservations[$rid][$time]['name'], |
||||||
|
'class' => 'booking-span'), |
||||||
|
'absolute' => TRUE, |
||||||
|
)); |
||||||
|
$link = Link::fromTextAndUrl( |
||||||
|
$reservations[$rid][$time]['name'], |
||||||
|
Url::fromUri('internal:/reserve_reservation/' . $id . '/edit', $options)) |
||||||
|
->toString(); |
||||||
|
} |
||||||
|
|
||||||
|
// The time slot has a reservation that cannot be viewed by the current user. and we are NOT allowed to see the Title |
||||||
|
else if (isset($reservations[$rid][$time]['blocked']) && $reservations[$rid][$time]['blocked']) { |
||||||
|
$link = t('Booked'); |
||||||
|
} |
||||||
|
|
||||||
|
// The time slot has a reservation that cannot be edited by the current user. but we are allowed to see the Title |
||||||
|
else { |
||||||
|
$link = $reservations[$rid][$time]['name']; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
$slots = isset($reservations[$rid][$time]['slots']) ? $reservations[$rid][$time]['slots'] : ''; |
||||||
|
$widthclass = $slots ? 'colspan' . $reservations[$rid][$time]['slots'] : ''; |
||||||
|
} |
||||||
|
|
||||||
|
// allow other modules to modify the $link |
||||||
|
\Drupal::moduleHandler()->alter('reserve_reservations_link', $link, $reservations[$rid][$time]); |
||||||
|
|
||||||
|
// allow other modules to add a custom class to slots |
||||||
|
$custom_class = ''; |
||||||
|
\Drupal::moduleHandler()->alter('reserve_reservations_custom_class', $custom_class, $reservations[$rid][$time]); |
||||||
|
|
||||||
|
// add div wrapper to display better |
||||||
|
$link = $link ? '<div class="booking-span">' . $link . '</div>' : ''; |
||||||
|
|
||||||
|
// we used book class to determine if linked or not; which we needed for pre/post slots as well as actual reservation slots |
||||||
|
// but we don't want to show booked class now for the slots which are just buffer slots |
||||||
|
if (stristr($slotclass, 'setup')) { |
||||||
|
$booked_class = ''; |
||||||
|
} |
||||||
|
|
||||||
|
if ($reservations[$rid][$time]['id']) { |
||||||
|
$ingroup = true; |
||||||
|
$numslots = $reservations[$rid][$time]['slots']; |
||||||
|
if ($reservations[$rid][$time]['series_id']) { |
||||||
|
$cell .= '<div class="reserve-group reserve-series">'; |
||||||
|
} |
||||||
|
else { |
||||||
|
$cell .= '<div class="reserve-group">'; |
||||||
|
} |
||||||
|
$numslots--; |
||||||
|
} |
||||||
|
|
||||||
|
$cell .= '<li class="' . $slotclass . ' ' . $booked_class . ' ' . $custom_class . ' ' . |
||||||
|
$viewable_class . ' ' . $widthclass . '">' . $link . '</li>' . "\n"; |
||||||
|
|
||||||
|
if (isset($ingroup) && $ingroup) { |
||||||
|
if ($numslots) { |
||||||
|
$numslots--; |
||||||
|
} |
||||||
|
else { |
||||||
|
$cell .= '</div>'; |
||||||
|
$ingroup = false; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
$table[$r][$c] = $cell; |
||||||
|
|
||||||
|
// Room name and capacity. |
||||||
|
$r++; |
||||||
|
$table[$r][$c] = '<li class="room-info">' . $room_info . '</li>' . "\n"; |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// remove extra table labels based on admin setting |
||||||
|
$compressed = false; |
||||||
|
if ($config->get('calendar_compressed_labels')) { |
||||||
|
$compressed = true; |
||||||
|
} |
||||||
|
|
||||||
|
// dump our table contents in std or flipped orientation |
||||||
|
if ($flipped) { |
||||||
|
$table = $this->reserve_transpose($table); |
||||||
|
$m = $r; |
||||||
|
$n = $c; |
||||||
|
} |
||||||
|
else { |
||||||
|
$m = $c; |
||||||
|
$n = $r; |
||||||
|
} |
||||||
|
|
||||||
|
// @todo: this should be done as variables passed to twig |
||||||
|
$table_markup = ''; |
||||||
|
for ($x = 0; $x <= $m; $x++){ |
||||||
|
if ($flipped && $compressed && ($x == 1 || $x == $m || $x == $m - 1)) continue; |
||||||
|
$table_markup .= '<div class="grid-column hours-column"> |
||||||
|
<ul> |
||||||
|
'; |
||||||
|
for ($y = 0; $y <= $n; $y++) { |
||||||
|
if (!$flipped && $compressed && ($y == 1 || $y == $n || $y == $n - 1)) continue; |
||||||
|
if (isset($table[$y][$x])) { |
||||||
|
$table_markup .= $table[$y][$x]; |
||||||
|
} |
||||||
|
} |
||||||
|
$table_markup .= '</ul> |
||||||
|
</div> |
||||||
|
'; |
||||||
|
} |
||||||
|
|
||||||
|
if ($rooms_per_category) { |
||||||
|
$categories[$index]['table'] = Markup::create($table_markup); |
||||||
|
} |
||||||
|
else { |
||||||
|
$nothing_to_book = t('There are no %bundles to book in this category. You will need to assign this Reserve Category to at least 1 %bundle.', |
||||||
|
['%bundles' => $bundle . 's', '%bundle' => $bundle]); |
||||||
|
$categories[$index]['table'] = Markup::create('<strong>' . $nothing_to_book . '</strong>' . $table_markup); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
$variables['#categories'] = $categories; |
||||||
|
|
||||||
|
// if we have no bookable entities, lets put out helpful message |
||||||
|
// @todo - possibly this could be done much earlier and then skip alot of the code above; but just processing empty arrays so likely not a big deal |
||||||
|
|
||||||
|
return $variables; |
||||||
|
} |
||||||
|
|
||||||
|
private function reserve_transpose($array) { |
||||||
|
array_unshift($array, null); |
||||||
|
return call_user_func_array('array_map', $array); |
||||||
|
} |
||||||
|
|
||||||
|
private function reserve_earliest_category($categories) { |
||||||
|
$earliest = 1000; |
||||||
|
$extended = \Drupal::currentUser()->hasPermission('add reservations extended'); |
||||||
|
$catmin = $extended ? 'minadvext' : 'minadvstd'; |
||||||
|
foreach ($categories as $cat) { |
||||||
|
if ($cat[$catmin] < $earliest) { |
||||||
|
$earliest = $cat[$catmin]; |
||||||
|
$result = $cat['id']; |
||||||
|
} |
||||||
|
} |
||||||
|
return $result; |
||||||
|
} |
||||||
|
|
||||||
|
public function reservationAddModalCallback() { |
||||||
|
$response = new jsonResponse(); |
||||||
|
|
||||||
|
$entity = ReserveReservation::create(); |
||||||
|
$editForm = \Drupal::service('entity.form_builder')->getForm($entity, 'default'); |
||||||
|
$form = \Drupal::service('renderer')->renderPlain($editForm); |
||||||
|
|
||||||
|
$response->setData($form); |
||||||
|
|
||||||
|
return $response; |
||||||
|
} |
||||||
|
|
||||||
|
public function accessCalendarPage(AccountInterface $account, $ebundle) { |
||||||
|
return AccessResult::allowedIf($account->hasPermission('access calendar for ' . $ebundle)); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,60 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
|
||||||
|
namespace Drupal\reserve\Controller; |
||||||
|
|
||||||
|
use Drupal\Core\DependencyInjection\ContainerInjectionInterface; |
||||||
|
use Drupal\Core\Entity\EntityManagerInterface; |
||||||
|
use Drupal\Core\StringTranslation\StringTranslationTrait; |
||||||
|
use Symfony\Component\DependencyInjection\ContainerInterface; |
||||||
|
|
||||||
|
class ReservePermissions implements ContainerInjectionInterface { |
||||||
|
|
||||||
|
use StringTranslationTrait; |
||||||
|
|
||||||
|
/** |
||||||
|
* The entity manager. |
||||||
|
* |
||||||
|
* @var \Drupal\Core\Entity\EntityManagerInterface |
||||||
|
*/ |
||||||
|
protected $entityManager; |
||||||
|
|
||||||
|
/** |
||||||
|
* Constructs a TaxonomyViewsIntegratorPermissions instance. |
||||||
|
* |
||||||
|
* @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager |
||||||
|
* The entity manager. |
||||||
|
*/ |
||||||
|
public function __construct(EntityManagerInterface $entity_manager) { |
||||||
|
$this->entityManager = $entity_manager; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public static function create(ContainerInterface $container) { |
||||||
|
return new static($container->get('entity.manager')); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Get permissions for Taxonomy Views Integrator. |
||||||
|
* |
||||||
|
* @return array |
||||||
|
* Permissions array. |
||||||
|
*/ |
||||||
|
public function permissions() { |
||||||
|
$permissions = []; |
||||||
|
|
||||||
|
$ebundles = ebundles_formatted(); |
||||||
|
|
||||||
|
foreach ($ebundles as $ebundle => $bundle) { |
||||||
|
$permissions += [ |
||||||
|
'access calendar for ' . $ebundle => [ |
||||||
|
'title' => $this->t('Allow access to the calendar for ' . $bundle), |
||||||
|
] |
||||||
|
]; |
||||||
|
} |
||||||
|
|
||||||
|
return $permissions; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,222 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace Drupal\reserve\Entity; |
||||||
|
|
||||||
|
use Drupal\Core\Entity\EntityStorageInterface; |
||||||
|
use Drupal\Core\Field\BaseFieldDefinition; |
||||||
|
use Drupal\Core\Entity\ContentEntityBase; |
||||||
|
use Drupal\Core\Entity\EntityChangedTrait; |
||||||
|
use Drupal\Core\Entity\EntityTypeInterface; |
||||||
|
use Drupal\user\UserInterface; |
||||||
|
|
||||||
|
/** |
||||||
|
* Defines the Reservation Category entity. |
||||||
|
* |
||||||
|
* @ingroup reserve |
||||||
|
* |
||||||
|
* @ContentEntityType( |
||||||
|
* id = "reserve_category", |
||||||
|
* label = @Translation("Reservation Category"), |
||||||
|
* handlers = { |
||||||
|
* "view_builder" = "Drupal\Core\Entity\EntityViewBuilder", |
||||||
|
* "list_builder" = "Drupal\reserve\ReserveCategoryListBuilder", |
||||||
|
* "views_data" = "Drupal\reserve\Entity\ReserveCategoryViewsData", |
||||||
|
* "translation" = "Drupal\reserve\ReserveCategoryTranslationHandler", |
||||||
|
* |
||||||
|
* "form" = { |
||||||
|
* "default" = "Drupal\reserve\Form\ReserveCategoryForm", |
||||||
|
* "add" = "Drupal\reserve\Form\ReserveCategoryForm", |
||||||
|
* "edit" = "Drupal\reserve\Form\ReserveCategoryForm", |
||||||
|
* "delete" = "Drupal\reserve\Form\ReserveCategoryDeleteForm", |
||||||
|
* }, |
||||||
|
* "access" = "Drupal\reserve\ReserveCategoryAccessControlHandler", |
||||||
|
* "route_provider" = { |
||||||
|
* "html" = "Drupal\reserve\ReserveCategoryHtmlRouteProvider", |
||||||
|
* }, |
||||||
|
* }, |
||||||
|
* base_table = "reserve_category", |
||||||
|
* data_table = "reserve_category_field_data", |
||||||
|
* translatable = TRUE, |
||||||
|
* admin_permission = "administer reservation categories", |
||||||
|
* entity_keys = { |
||||||
|
* "id" = "id", |
||||||
|
* "label" = "name", |
||||||
|
* "uuid" = "uuid", |
||||||
|
* "uid" = "user_id", |
||||||
|
* "langcode" = "langcode", |
||||||
|
* "status" = "status", |
||||||
|
* }, |
||||||
|
* links = { |
||||||
|
* "canonical" = "/admin/structure/reserve_category/{reserve_category}", |
||||||
|
* "add-form" = "/admin/structure/reserve_category/add", |
||||||
|
* "edit-form" = "/admin/structure/reserve_category/{reserve_category}/edit", |
||||||
|
* "delete-form" = "/admin/structure/reserve_category/{reserve_category}/delete", |
||||||
|
* "collection" = "/admin/structure/reserve_category", |
||||||
|
* }, |
||||||
|
* field_ui_base_route = "reserve_category.settings" |
||||||
|
* ) |
||||||
|
*/ |
||||||
|
class ReserveCategory extends ContentEntityBase implements ReserveCategoryInterface { |
||||||
|
|
||||||
|
use EntityChangedTrait; |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public static function preCreate(EntityStorageInterface $storage_controller, array &$values) { |
||||||
|
parent::preCreate($storage_controller, $values); |
||||||
|
$values += array( |
||||||
|
'user_id' => \Drupal::currentUser()->id(), |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function postCreate(EntityStorageInterface $storage) { |
||||||
|
$this->newRevision = TRUE; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function getName() { |
||||||
|
return $this->get('name')->value; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function setName($name) { |
||||||
|
$this->set('name', $name); |
||||||
|
return $this; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function getCreatedTime() { |
||||||
|
return $this->get('created')->value; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function setCreatedTime($timestamp) { |
||||||
|
$this->set('created', $timestamp); |
||||||
|
return $this; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function getOwner() { |
||||||
|
return $this->get('user_id')->entity; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function getOwnerId() { |
||||||
|
return $this->get('user_id')->target_id; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function setOwnerId($uid) { |
||||||
|
$this->set('user_id', $uid); |
||||||
|
return $this; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function setOwner(UserInterface $account) { |
||||||
|
$this->set('user_id', $account->id()); |
||||||
|
return $this; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function isPublished() { |
||||||
|
return (bool) $this->getEntityKey('status'); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function setPublished($published) { |
||||||
|
$this->set('status', $published ? TRUE : FALSE); |
||||||
|
return $this; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { |
||||||
|
$fields = parent::baseFieldDefinitions($entity_type); |
||||||
|
|
||||||
|
$fields['user_id'] = BaseFieldDefinition::create('entity_reference') |
||||||
|
->setLabel(t('Authored by')) |
||||||
|
->setDescription(t('The user ID of author of the Reservation Category entity.')) |
||||||
|
->setRevisionable(TRUE) |
||||||
|
->setSetting('target_type', 'user') |
||||||
|
->setSetting('handler', 'default') |
||||||
|
->setTranslatable(TRUE) |
||||||
|
->setDisplayOptions('view', array( |
||||||
|
'label' => 'hidden', |
||||||
|
'type' => 'author', |
||||||
|
'weight' => 0, |
||||||
|
)) |
||||||
|
->setDisplayOptions('form', array( |
||||||
|
'type' => 'entity_reference_autocomplete', |
||||||
|
'weight' => 5, |
||||||
|
'settings' => array( |
||||||
|
'match_operator' => 'CONTAINS', |
||||||
|
'size' => '60', |
||||||
|
'autocomplete_type' => 'tags', |
||||||
|
'placeholder' => '', |
||||||
|
), |
||||||
|
)) |
||||||
|
->setDisplayConfigurable('form', true) |
||||||
|
->setDisplayConfigurable('view', true); |
||||||
|
|
||||||
|
$fields['name'] = BaseFieldDefinition::create('string') |
||||||
|
->setLabel(t('Name')) |
||||||
|
->setDescription(t('The name of the Reservation Category entity.')) |
||||||
|
->setSettings(array( |
||||||
|
'max_length' => 50, |
||||||
|
'text_processing' => 0, |
||||||
|
)) |
||||||
|
->setDefaultValue('') |
||||||
|
->setDisplayOptions('view', array( |
||||||
|
'label' => 'above', |
||||||
|
'type' => 'string', |
||||||
|
'weight' => -4, |
||||||
|
)) |
||||||
|
->setDisplayOptions('form', array( |
||||||
|
'type' => 'string_textfield', |
||||||
|
'weight' => -4, |
||||||
|
)) |
||||||
|
->setDisplayConfigurable('form', TRUE) |
||||||
|
->setDisplayConfigurable('view', TRUE); |
||||||
|
|
||||||
|
$fields['status'] = BaseFieldDefinition::create('boolean') |
||||||
|
->setLabel(t('Publishing status')) |
||||||
|
->setDescription(t('A boolean indicating whether the Reservation Category is published.')) |
||||||
|
->setDefaultValue(TRUE); |
||||||
|
|
||||||
|
$fields['created'] = BaseFieldDefinition::create('created') |
||||||
|
->setLabel(t('Created')) |
||||||
|
->setDescription(t('The time that the entity was created.')); |
||||||
|
|
||||||
|
$fields['changed'] = BaseFieldDefinition::create('changed') |
||||||
|
->setLabel(t('Changed')) |
||||||
|
->setDescription(t('The time that the entity was last edited.')); |
||||||
|
|
||||||
|
return $fields; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,58 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace Drupal\reserve\Entity; |
||||||
|
|
||||||
|
use Drupal\Core\Entity\ContentEntityInterface; |
||||||
|
use Drupal\Core\Entity\EntityChangedInterface; |
||||||
|
use Drupal\user\EntityOwnerInterface; |
||||||
|
|
||||||
|
/** |
||||||
|
* Provides an interface for defining reservation categories. |
||||||
|
* |
||||||
|
* @ingroup reserve |
||||||
|
*/ |
||||||
|
interface ReserveCategoryInterface extends ContentEntityInterface, EntityChangedInterface, EntityOwnerInterface { |
||||||
|
|
||||||
|
// Add get/set methods for your configuration properties here. |
||||||
|
|
||||||
|
/** |
||||||
|
* Gets the Reservation Category name. |
||||||
|
* |
||||||
|
* @return string |
||||||
|
* Name of the Reservation Category. |
||||||
|
*/ |
||||||
|
public function getName(); |
||||||
|
|
||||||
|
/** |
||||||
|
* Sets the Reservation Category name. |
||||||
|
* |
||||||
|
* @param string $name |
||||||
|
* The Reservation Category name. |
||||||
|
* |
||||||
|
* @return \Drupal\reserve\Entity\ReserveCategoryInterface |
||||||
|
* The called Reservation Category entity. |
||||||
|
*/ |
||||||
|
public function setName($name); |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns the Reservation Category published status indicator. |
||||||
|
* |
||||||
|
* Unpublished Reservation Category are only visible to restricted users. |
||||||
|
* |
||||||
|
* @return bool |
||||||
|
* TRUE if the Reservation Category is published. |
||||||
|
*/ |
||||||
|
public function isPublished(); |
||||||
|
|
||||||
|
/** |
||||||
|
* Sets the published status of a Reservation Category. |
||||||
|
* |
||||||
|
* @param bool $published |
||||||
|
* TRUE to set this Reservation Category to published, FALSE to set it to unpublished. |
||||||
|
* |
||||||
|
* @return \Drupal\reserve\Entity\ReserveCategoryInterface |
||||||
|
* The called Reservation Category entity. |
||||||
|
*/ |
||||||
|
public function setPublished($published); |
||||||
|
|
||||||
|
} |
@ -0,0 +1,28 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace Drupal\reserve\Entity; |
||||||
|
|
||||||
|
use Drupal\views\EntityViewsData; |
||||||
|
use Drupal\views\EntityViewsDataInterface; |
||||||
|
|
||||||
|
/** |
||||||
|
* Provides Views data for reservation categories. |
||||||
|
*/ |
||||||
|
class ReserveCategoryViewsData extends EntityViewsData implements EntityViewsDataInterface { |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function getViewsData() { |
||||||
|
$data = parent::getViewsData(); |
||||||
|
|
||||||
|
$data['reserve_category']['table']['base'] = array( |
||||||
|
'field' => 'id', |
||||||
|
'title' => $this->t('Reservation Category'), |
||||||
|
'help' => $this->t('The Reservation Category ID.'), |
||||||
|
); |
||||||
|
|
||||||
|
return $data; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,216 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace Drupal\reserve\Entity; |
||||||
|
|
||||||
|
use Drupal\Core\Entity\EntityStorageInterface; |
||||||
|
use Drupal\Core\Field\BaseFieldDefinition; |
||||||
|
use Drupal\Core\Entity\ContentEntityBase; |
||||||
|
use Drupal\Core\Entity\EntityChangedTrait; |
||||||
|
use Drupal\Core\Entity\EntityTypeInterface; |
||||||
|
use Drupal\user\UserInterface; |
||||||
|
|
||||||
|
/** |
||||||
|
* Defines the Reservation entity. |
||||||
|
* |
||||||
|
* @ingroup reserve |
||||||
|
* |
||||||
|
* @ContentEntityType( |
||||||
|
* id = "reserve_reservation", |
||||||
|
* label = @Translation("Reservation"), |
||||||
|
* handlers = { |
||||||
|
* "view_builder" = "Drupal\Core\Entity\EntityViewBuilder", |
||||||
|
* "list_builder" = "Drupal\reserve\ReserveReservationListBuilder", |
||||||
|
* "views_data" = "Drupal\reserve\Entity\ReserveReservationViewsData", |
||||||
|
* "translation" = "Drupal\reserve\ReserveReservationTranslationHandler", |
||||||
|
* |
||||||
|
* "form" = { |
||||||
|
* "default" = "Drupal\reserve\Form\ReserveReservationForm", |
||||||
|
* "add" = "Drupal\reserve\Form\ReserveReservationForm", |
||||||
|
* "edit" = "Drupal\reserve\Form\ReserveReservationForm", |
||||||
|
* "delete" = "Drupal\reserve\Form\ReserveReservationDeleteForm", |
||||||
|
* }, |
||||||
|
* "access" = "Drupal\reserve\ReserveReservationAccessControlHandler", |
||||||
|
* "route_provider" = { |
||||||
|
* "html" = "Drupal\reserve\ReserveReservationHtmlRouteProvider", |
||||||
|
* }, |
||||||
|
* }, |
||||||
|
* base_table = "reserve_reservation", |
||||||
|
* data_table = "reserve_reservation_field_data", |
||||||
|
* translatable = TRUE, |
||||||
|
* admin_permission = "administer reservations", |
||||||
|
* entity_keys = { |
||||||
|
* "id" = "id", |
||||||
|
* "label" = "name", |
||||||
|
* "uuid" = "uuid", |
||||||
|
* "uid" = "user_id", |
||||||
|
* "langcode" = "langcode", |
||||||
|
* "status" = "status", |
||||||
|
* }, |
||||||
|
* links = { |
||||||
|
* "canonical" = "/reserve_reservation/{reserve_reservation}", |
||||||
|
* "add-form" = "/reserve_reservation/add", |
||||||
|
* "edit-form" = "/reserve_reservation/{reserve_reservation}/edit", |
||||||
|
* "delete-form" = "/reserve_reservation/{reserve_reservation}/delete", |
||||||
|
* "collection" = "/admin/structure/reservations/reserve_reservation", |
||||||
|
* }, |
||||||
|
* field_ui_base_route = "reserve_reservation.settings" |
||||||
|
* ) |
||||||
|
*/ |
||||||
|
class ReserveReservation extends ContentEntityBase implements ReserveReservationInterface { |
||||||
|
|
||||||
|
use EntityChangedTrait; |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public static function preCreate(EntityStorageInterface $storage_controller, array &$values) { |
||||||
|
parent::preCreate($storage_controller, $values); |
||||||
|
$values += array( |
||||||
|
'user_id' => \Drupal::currentUser()->id(), |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function getName() { |
||||||
|
return $this->get('name')->value; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function setName($name) { |
||||||
|
$this->set('name', $name); |
||||||
|
return $this; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function getCreatedTime() { |
||||||
|
return $this->get('created')->value; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function setCreatedTime($timestamp) { |
||||||
|
$this->set('created', $timestamp); |
||||||
|
return $this; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function getOwner() { |
||||||
|
return $this->get('user_id')->entity; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function getOwnerId() { |
||||||
|
return $this->get('user_id')->target_id; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function setOwnerId($uid) { |
||||||
|
$this->set('user_id', $uid); |
||||||
|
return $this; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function setOwner(UserInterface $account) { |
||||||
|
$this->set('user_id', $account->id()); |
||||||
|
return $this; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function isPublished() { |
||||||
|
return (bool) $this->getEntityKey('status'); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function setPublished($published) { |
||||||
|
$this->set('status', $published ? TRUE : FALSE); |
||||||
|
return $this; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { |
||||||
|
$fields = parent::baseFieldDefinitions($entity_type); |
||||||
|
|
||||||
|
$fields['user_id'] = BaseFieldDefinition::create('entity_reference') |
||||||
|
->setLabel(t('Authored by')) |
||||||
|
->setDescription(t('The user ID of author of the Reservation entity.')) |
||||||
|
->setRevisionable(TRUE) |
||||||
|
->setSetting('target_type', 'user') |
||||||
|
->setSetting('handler', 'default') |
||||||
|
->setTranslatable(TRUE) |
||||||
|
->setDisplayOptions('view', array( |
||||||
|
'label' => 'hidden', |
||||||
|
'type' => 'author', |
||||||
|
'weight' => 0, |
||||||
|
)) |
||||||
|
->setDisplayOptions('form', array( |
||||||
|
'type' => 'entity_reference_autocomplete', |
||||||
|
'weight' => 5, |
||||||
|
'settings' => array( |
||||||
|
'match_operator' => 'CONTAINS', |
||||||
|
'size' => '60', |
||||||
|
'autocomplete_type' => 'tags', |
||||||
|
'placeholder' => '', |
||||||
|
), |
||||||
|
)) |
||||||
|
->setDisplayConfigurable('form', TRUE) |
||||||
|
->setDisplayConfigurable('view', TRUE); |
||||||
|
|
||||||
|
$fields['name'] = BaseFieldDefinition::create('string') |
||||||
|
->setLabel(t('Group Name')) |
||||||
|
->setDescription(t('The person or group making the reservation.')) |
||||||
|
->setSettings(array( |
||||||
|
'max_length' => 50, |
||||||
|
'text_processing' => 0, |
||||||
|
)) |
||||||
|
->setDefaultValue('') |
||||||
|
->setDisplayOptions('view', array( |
||||||
|
'label' => 'above', |
||||||
|
'type' => 'string', |
||||||
|
'weight' => -4, |
||||||
|
)) |
||||||
|
->setDisplayOptions('form', array( |
||||||
|
'type' => 'string_textfield', |
||||||
|
'weight' => -4, |
||||||
|
)) |
||||||
|
->setDisplayConfigurable('form', TRUE) |
||||||
|
->setDisplayConfigurable('view', TRUE); |
||||||
|
|
||||||
|
$fields['status'] = BaseFieldDefinition::create('boolean') |
||||||
|
->setLabel(t('Publishing status')) |
||||||
|
->setDescription(t('A boolean indicating whether the Reservation is published.')) |
||||||
|
->setDefaultValue(TRUE); |
||||||
|
|
||||||
|
$fields['created'] = BaseFieldDefinition::create('created') |
||||||
|
->setLabel(t('Created')) |
||||||
|
->setDescription(t('The time that the entity was created.')); |
||||||
|
|
||||||
|
$fields['changed'] = BaseFieldDefinition::create('changed') |
||||||
|
->setLabel(t('Changed')) |
||||||
|
->setDescription(t('The time that the entity was last edited.')); |
||||||
|
|
||||||
|
return $fields; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
} |
@ -0,0 +1,77 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace Drupal\reserve\Entity; |
||||||
|
|
||||||
|
use Drupal\Core\Entity\ContentEntityInterface; |
||||||
|
use Drupal\Core\Entity\EntityChangedInterface; |
||||||
|
use Drupal\user\EntityOwnerInterface; |
||||||
|
|
||||||
|
/** |
||||||
|
* Provides an interface for defining reservations. |
||||||
|
* |
||||||
|
* @ingroup reserve |
||||||
|
*/ |
||||||
|
interface ReserveReservationInterface extends ContentEntityInterface, EntityChangedInterface, EntityOwnerInterface { |
||||||
|
|
||||||
|
// Add get/set methods for your configuration properties here. |
||||||
|
|
||||||
|
/** |
||||||
|
* Gets the Reservation name. |
||||||
|
* |
||||||
|
* @return string |
||||||
|
* Name of the Reservation. |
||||||
|
*/ |
||||||
|
public function getName(); |
||||||
|
|
||||||
|
/** |
||||||
|
* Sets the Reservation name. |
||||||
|
* |
||||||
|
* @param string $name |
||||||
|
* The Reservation name. |
||||||
|
* |
||||||
|
* @return \Drupal\reserve\Entity\ReserveReservationInterface |
||||||
|
* The called Reservation entity. |
||||||
|
*/ |
||||||
|
public function setName($name); |
||||||
|
|
||||||
|
/** |
||||||
|
* Gets the Reservation creation timestamp. |
||||||
|
* |
||||||
|
* @return int |
||||||
|
* Creation timestamp of the Reservation. |
||||||
|
*/ |
||||||
|
public function getCreatedTime(); |
||||||
|
|
||||||
|
/** |
||||||
|
* Sets the Reservation creation timestamp. |
||||||
|
* |
||||||
|
* @param int $timestamp |
||||||
|
* The Reservation creation timestamp. |
||||||
|
* |
||||||
|
* @return \Drupal\reserve\Entity\ReserveReservationInterface |
||||||
|
* The called Reservation entity. |
||||||
|
*/ |
||||||
|
public function setCreatedTime($timestamp); |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns the Reservation published status indicator. |
||||||
|
* |
||||||
|
* Unpublished Reservation are only visible to restricted users. |
||||||
|
* |
||||||
|
* @return bool |
||||||
|
* TRUE if the Reservation is published. |
||||||
|
*/ |
||||||
|
public function isPublished(); |
||||||
|
|
||||||
|
/** |
||||||
|
* Sets the published status of a Reservation. |
||||||
|
* |
||||||
|
* @param bool $published |
||||||
|
* TRUE to set this Reservation to published, FALSE to set it to unpublished. |
||||||
|
* |
||||||
|
* @return \Drupal\reserve\Entity\ReserveReservationInterface |
||||||
|
* The called Reservation entity. |
||||||
|
*/ |
||||||
|
public function setPublished($published); |
||||||
|
|
||||||
|
} |
@ -0,0 +1,14 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace Drupal\reserve\Entity; |
||||||
|
|
||||||
|
use Drupal\views\EntityViewsData; |
||||||
|
use Drupal\views\EntityViewsDataInterface; |
||||||
|
|
||||||
|
/** |
||||||
|
* Provides Views data for reservations. |
||||||
|
*/ |
||||||
|
class ReserveReservationViewsData extends EntityViewsData implements EntityViewsDataInterface { |
||||||
|
|
||||||
|
|
||||||
|
} |
@ -0,0 +1,56 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace Drupal\reserve\Form; |
||||||
|
|
||||||
|
use Drupal\Core\Form\FormBase; |
||||||
|
use Drupal\Core\Form\FormStateInterface; |
||||||
|
use Drupal\Core\Datetime\DrupalDateTime; |
||||||
|
|
||||||
|
/** |
||||||
|
* Class CalendarDatePicker. |
||||||
|
*/ |
||||||
|
class CalendarDatePicker extends FormBase { |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function getFormId() { |
||||||
|
return 'calendarDatePicker'; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function buildForm(array $form, FormStateInterface $form_state) { |
||||||
|
// Retrieve an array which contains the path pieces. |
||||||
|
$current_path = \Drupal::service('path.current')->getPath(); |
||||||
|
$path_args = explode('/', $current_path); |
||||||
|
|
||||||
|
$form['date'] = [ |
||||||
|
'#type' => 'date', |
||||||
|
'#description' => $this->t('Click in box to select date.'), |
||||||
|
]; |
||||||
|
|
||||||
|
if (count($path_args) == 5) { |
||||||
|
$date = date('Y') . '-' . $path_args[4] . '-' . $path_args[5]; |
||||||
|
$form['date']['#default_value'] = $date; |
||||||
|
} |
||||||
|
else { |
||||||
|
$form['date']['#default_value'] = date('Y-m-d'); |
||||||
|
} |
||||||
|
|
||||||
|
return $form; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function submitForm(array &$form, FormStateInterface $form_state) { |
||||||
|
// Display result. |
||||||
|
foreach ($form_state->getValues() as $key => $value) { |
||||||
|
drupal_set_message($key . ': ' . $value); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,15 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace Drupal\reserve\Form; |
||||||
|
|
||||||
|
use Drupal\Core\Entity\ContentEntityDeleteForm; |
||||||
|
|
||||||
|
/** |
||||||
|
* Provides a form for deleting reservation categories. |
||||||
|
* |
||||||
|
* @ingroup reserve |
||||||
|
*/ |
||||||
|
class ReserveCategoryDeleteForm extends ContentEntityDeleteForm { |
||||||
|
|
||||||
|
|
||||||
|
} |
@ -0,0 +1,50 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace Drupal\reserve\Form; |
||||||
|
|
||||||
|
use Drupal\Core\Entity\ContentEntityForm; |
||||||
|
use Drupal\Core\Form\FormStateInterface; |
||||||
|
|
||||||
|
/** |
||||||
|
* Form controller for Reservation Category edit forms. |
||||||
|
* |
||||||
|
* @ingroup reserve |
||||||
|
*/ |
||||||
|
class ReserveCategoryForm extends ContentEntityForm { |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function buildForm(array $form, FormStateInterface $form_state) { |
||||||
|
/* @var $entity \Drupal\reserve\Entity\ReserveCategory */ |
||||||
|
$form = parent::buildForm($form, $form_state); |
||||||
|
|
||||||
|
$entity = $this->entity; |
||||||
|
|
||||||
|
return $form; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function save(array $form, FormStateInterface $form_state) { |
||||||
|
$entity = &$this->entity; |
||||||
|
|
||||||
|
$status = parent::save($form, $form_state); |
||||||
|
|
||||||
|
switch ($status) { |
||||||
|
case SAVED_NEW: |
||||||
|
drupal_set_message($this->t('Created the %label Reservation Category.', [ |
||||||
|
'%label' => $entity->label(), |
||||||
|
])); |
||||||
|
break; |
||||||
|
|
||||||
|
default: |
||||||
|
drupal_set_message($this->t('Saved the %label Reservation Category.', [ |
||||||
|
'%label' => $entity->label(), |
||||||
|
])); |
||||||
|
} |
||||||
|
$form_state->setRedirect('entity.reserve_category.canonical', ['reserve_category' => $entity->id()]); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,55 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace Drupal\reserve\Form; |
||||||
|
|
||||||
|
use Drupal\Core\Form\FormBase; |
||||||
|
use Drupal\Core\Form\FormStateInterface; |
||||||
|
|
||||||
|
/** |
||||||
|
* Class ReserveCategorySettingsForm. |
||||||
|
* |
||||||
|
* @package Drupal\reserve\Form |
||||||
|
* |
||||||
|
* @ingroup reserve |
||||||
|
*/ |
||||||
|
class ReserveCategorySettingsForm extends FormBase { |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns a unique string identifying the form. |
||||||
|
* |
||||||
|
* @return string |
||||||
|
* The unique string identifying the form. |
||||||
|
*/ |
||||||
|
public function getFormId() { |
||||||
|
return 'ReserveCategory_settings'; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Form submission handler. |
||||||
|
* |
||||||
|
* @param array $form |
||||||
|
* An associative array containing the structure of the form. |
||||||
|
* @param \Drupal\Core\Form\FormStateInterface $form_state |
||||||
|
* The current state of the form. |
||||||
|
*/ |
||||||
|
public function submitForm(array &$form, FormStateInterface $form_state) { |
||||||
|
// Empty implementation of the abstract submit class. |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Defines the settings form for reservation categories. |
||||||
|
* |
||||||
|
* @param array $form |
||||||
|
* An associative array containing the structure of the form. |
||||||
|
* @param \Drupal\Core\Form\FormStateInterface $form_state |
||||||
|
* The current state of the form. |
||||||
|
* |
||||||
|
* @return array |
||||||
|
* Form definition array. |
||||||
|
*/ |
||||||
|
public function buildForm(array $form, FormStateInterface $form_state) { |
||||||
|
$form['ReserveCategory_settings']['#markup'] = 'Settings form for reservation categories. Manage field settings here.'; |
||||||
|
return $form; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,250 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace Drupal\reserve\Form; |
||||||
|
|
||||||
|
use Drupal\Core\Form\ConfigFormBase; |
||||||
|
use Drupal\Core\Form\FormStateInterface; |
||||||
|
|
||||||
|
module_load_include('inc', 'reserve', 'reserve.admin'); |
||||||
|
|
||||||
|
/** |
||||||
|
* Class ReserveCategorySettingsForm. |
||||||
|
* |
||||||
|
* @package Drupal\reserve\Form |
||||||
|
* |
||||||
|
* @ingroup reserve |
||||||
|
*/ |
||||||
|
|
||||||
|
class ReserveDailyHoursForm extends ConfigFormBase { |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns a unique string identifying the form. |
||||||
|
* |
||||||
|
* @return string |
||||||
|
* The unique string identifying the form. |
||||||
|
*/ |
||||||
|
public function getFormId() { |
||||||
|
return 'ReserveDailyHours'; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
protected function getEditableConfigNames() { |
||||||
|
return [ |
||||||
|
'reserve.monthly_hours', |
||||||
|
]; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Form constructor for the Hours / Daily Hours configuration page. |
||||||
|
* |
||||||
|
*/ |
||||||
|
public function buildForm(array $form, FormStateInterface $form_state, $passed_month = null) { |
||||||
|
$cur_months = reserve_current_months(); |
||||||
|
$selected_month = ($passed_month == 'yyyy_mm') ? date('Y_m') : $passed_month; |
||||||
|
$monthly_hours = $this->config('reserve.monthly_hours')->get($selected_month); |
||||||
|
|
||||||
|
// create a form to pick a month. |
||||||
|
$month_options = array(); |
||||||
|
$first = current($cur_months); |
||||||
|
foreach ($cur_months as $cur_month) { |
||||||
|
$yyyy_mm = $cur_month['YYYY_MM']; |
||||||
|
$display = t($cur_month['display']); |
||||||
|
$month_options[$yyyy_mm] = t($cur_month['display']); |
||||||
|
} |
||||||
|
$form['select_month'] = array( |
||||||
|
'#type' => 'container', |
||||||
|
'#weight' => -2000, |
||||||
|
); |
||||||
|
$form['select_month']['month'] = array( |
||||||
|
'#title' => t('Month'), |
||||||
|
'#type' => 'select', |
||||||
|
'#options' => $month_options, |
||||||
|
'#default_value' => $selected_month, |
||||||
|
); |
||||||
|
$form['select_month']['save'] = array( |
||||||
|
'#type' => 'submit', |
||||||
|
'#value' => t('Select a month'), |
||||||
|
'#name' => 'select', |
||||||
|
); |
||||||
|
|
||||||
|
// Return a form to update the hours for each day of selected month. |
||||||
|
$hours = reserve_hours(); |
||||||
|
// Select box options. |
||||||
|
$options = array(); |
||||||
|
$options['9999'] = t('Select the time'); |
||||||
|
$options['0000'] = t('Midnight - start of day'); |
||||||
|
foreach ($hours as $hour) { |
||||||
|
$time = $hour['time']; |
||||||
|
$display = t($hour['display']); |
||||||
|
if ($time != '0000') { |
||||||
|
$options[$time] = $display; |
||||||
|
} |
||||||
|
} |
||||||
|
$options['2400'] = t('Midnight - end of day'); |
||||||
|
|
||||||
|
$yyyy_mm = $selected_month; |
||||||
|
$month = intval(substr($yyyy_mm, 5)); |
||||||
|
$year = substr($yyyy_mm, 0, 4); |
||||||
|
$month_display = date('F Y', mktime(0, 0, 0, $month, 1, $year)); |
||||||
|
// Days in the month. |
||||||
|
$days = date('t', mktime(0, 0, 0, $month, 1, $year)); |
||||||
|
|
||||||
|
// if we don't have Hours set for this Month, let's use default values |
||||||
|
if (isset($monthly_hours)) { |
||||||
|
$mo_hours = $monthly_hours; |
||||||
|
} |
||||||
|
else { |
||||||
|
$mo_hours = reserve_default_monthly_hours($year, $month); |
||||||
|
} |
||||||
|
|
||||||
|
// From Header |
||||||
|
$form['#tree'] = TRUE; |
||||||
|
$form['month_display'] = array( |
||||||
|
'#prefix' => '<br /><b>', |
||||||
|
'#suffix' => '</b><br />', |
||||||
|
'#markup' => $month_display, |
||||||
|
'#weight' => -100, |
||||||
|
); |
||||||
|
$form['note'] = array( |
||||||
|
'#markup' => t('Asterisk (*) indicates that the hours have been changed from the default'), |
||||||
|
'#weight' => -99, |
||||||
|
); |
||||||
|
|
||||||
|
for ($day = 0; $day < $days; $day++) { |
||||||
|
// Day of week. |
||||||
|
$dow = date('l', mktime(0, 0, 0, $month, $day + 1, $year)); |
||||||
|
$changed_hours = ($mo_hours[($day * 5)] == 'O') ? '*' : ''; |
||||||
|
$day_hours = array(); |
||||||
|
$day_hours[] = $mo_hours[($day * 5) + 1]; |
||||||
|
$day_hours[] = $mo_hours[($day * 5) + 2]; |
||||||
|
$day_hours[] = $mo_hours[($day * 5) + 3]; |
||||||
|
$day_hours[] = $mo_hours[($day * 5) + 4]; |
||||||
|
$display_hours = reserve_hours_display($day_hours); |
||||||
|
$title = ($day + 1) . ' ' . $dow . ' (' . $display_hours . ') ' . $changed_hours; |
||||||
|
$form['day_' . $day] = array( |
||||||
|
'#type' => 'details', |
||||||
|
'#title' => $title, |
||||||
|
'#open' => FALSE, |
||||||
|
'#weight' => -9 + ($day * 2), |
||||||
|
); |
||||||
|
$form['day_' . $day]['first_shift_open_' . $day] = array( |
||||||
|
'#title' => t('First shift open'), |
||||||
|
'#type' => 'select', |
||||||
|
'#options' => $options, |
||||||
|
'#default_value' => $mo_hours[($day * 5) + 1], |
||||||
|
//'#weight' => -9 + ($day * 2) + 1, |
||||||
|
); |
||||||
|
$form['day_' . $day]['first_shift_close_' . $day] = array( |
||||||
|
'#title' => t('First shift close'), |
||||||
|
'#type' => 'select', |
||||||
|
'#options' => $options, |
||||||
|
'#default_value' => $mo_hours[($day * 5) + 2], |
||||||
|
//'#weight' => -9 + ($day * 10) + 2, |
||||||
|
); |
||||||
|
$form['day_' . $day]['second_shift_open_' . $day] = array( |
||||||
|
'#title' => t('Second shift open'), |
||||||
|
'#type' => 'select', |
||||||
|
'#options' => $options, |
||||||
|
'#default_value' => $mo_hours[($day * 5) + 3], |
||||||
|
//'#weight' => -90 + ($day * 10) + 3, |
||||||
|
); |
||||||
|
$form['day_' . $day]['second_shift_close_' . $day] = array( |
||||||
|
'#title' => t('Second shift close'), |
||||||
|
'#type' => 'select', |
||||||
|
'#options' => $options, |
||||||
|
'#default_value' => $mo_hours[($day * 5) + 4], |
||||||
|
//'#weight' => -90 + ($day * 10) + 4, |
||||||
|
); |
||||||
|
} |
||||||
|
$form['save'] = array( |
||||||
|
'#type' => 'submit', |
||||||
|
'#value' => t('Save configuration'), |
||||||
|
'#weight' => 400, |
||||||
|
'#name' => 'save', |
||||||
|
); |
||||||
|
$form['reset'] = array( |
||||||
|
'#type' => 'submit', |
||||||
|
'#value' => t('Reset to defaults'), |
||||||
|
'#weight' => 401, |
||||||
|
'#name' => 'reset', |
||||||
|
); |
||||||
|
$form['month'] = array( |
||||||
|
'#type' => 'value', |
||||||
|
'#value' => $selected_month, |
||||||
|
); |
||||||
|
|
||||||
|
return $form; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Form submission handler. |
||||||
|
* |
||||||
|
* @param array $form |
||||||
|
* An associative array containing the structure of the form. |
||||||
|
* @param \Drupal\Core\Form\FormStateInterface $form_state |
||||||
|
* The current state of the form. |
||||||
|
*/ |
||||||
|
public function submitForm(array &$form, FormStateInterface $form_state) { |
||||||
|
$values = $form_state->getValues(); |
||||||
|
$yyyy_mm = $form_state->getUserInput()['select_month']['month']; |
||||||
|
$month = intval(substr($yyyy_mm, 5)); |
||||||
|
$year = substr($yyyy_mm, 0, 4); |
||||||
|
|
||||||
|
if ($form_state->getTriggeringElement()['#name'] == 'select') { |
||||||
|
$form_state->setRedirect('reserve.settings.hours.daily', array('passed_month' => $yyyy_mm)); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
if ($form_state->getTriggeringElement()['#name'] == 'save') { |
||||||
|
// Days in the month. |
||||||
|
$days = date('t', mktime(0, 0, 0, $month, 1, $year)); |
||||||
|
|
||||||
|
$updated_mo_hours = array(); |
||||||
|
$default_hours = \Drupal::config('reserve.default_hours')->get('data'); |
||||||
|
for ($day = 0; $day < $days; $day++) { |
||||||
|
// User entered hours for a single day. |
||||||
|
$day_first_open = $values['day_' . $day]['first_shift_open_' . $day]; |
||||||
|
$day_first_close = $values['day_' . $day]['first_shift_close_' . $day]; |
||||||
|
$day_second_open = $values['day_' . $day]['second_shift_open_' . $day]; |
||||||
|
$day_second_close = $values['day_' . $day]['second_shift_close_' . $day]; |
||||||
|
// Default hours for the day of the week. |
||||||
|
// Day of week. |
||||||
|
$dow = date('w', mktime(0, 0, 0, $month, $day + 1, $year)); |
||||||
|
$default_first_open = $default_hours[($dow * 4) + 0]; |
||||||
|
$default_first_close = $default_hours[($dow * 4) + 1]; |
||||||
|
$default_second_open = $default_hours[($dow * 4) + 2]; |
||||||
|
$default_second_close = $default_hours[($dow * 4) + 3]; |
||||||
|
// Compare user entered hours to default for the day of the week. |
||||||
|
if (($day_first_open == $default_first_open) && |
||||||
|
($day_first_close == $default_first_close) && |
||||||
|
($day_second_open == $default_second_open) && |
||||||
|
($day_second_close == $default_second_close)) { |
||||||
|
$day_is_default = TRUE; |
||||||
|
} |
||||||
|
else { |
||||||
|
$day_is_default = FALSE; |
||||||
|
} |
||||||
|
// Update the monthly hours record. |
||||||
|
$updated_mo_hours[($day * 5)] = ($day_is_default) ? 'D' : 'O'; |
||||||
|
$updated_mo_hours[($day * 5) + 1] = $day_first_open; |
||||||
|
$updated_mo_hours[($day * 5) + 2] = $day_first_close; |
||||||
|
$updated_mo_hours[($day * 5) + 3] = $day_second_open; |
||||||
|
$updated_mo_hours[($day * 5) + 4] = $day_second_close; |
||||||
|
} |
||||||
|
$confirmation = t('Daily overrides set for %month', array('%month' => date('F', mktime(0, 0, 0, $month, 10)))); |
||||||
|
} |
||||||
|
|
||||||
|
if ($form_state->getTriggeringElement()['#name'] == 'reset') { |
||||||
|
$updated_mo_hours = reserve_default_monthly_hours($year, $month); |
||||||
|
$confirmation = t('Daily overrides cleared for %month', array('%month' => date('F', mktime(0, 0, 0, $month, 10)))); |
||||||
|
} |
||||||
|
|
||||||
|
// save updates or defaults (reset) for this month |
||||||
|
$this->config('reserve.monthly_hours') |
||||||
|
->set($yyyy_mm, $updated_mo_hours) |
||||||
|
->save(); |
||||||
|
drupal_set_message($confirmation); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,308 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace Drupal\reserve\Form; |
||||||
|
|
||||||
|
use Drupal\Core\Form\ConfigFormBase; |
||||||
|
use Drupal\Core\Form\FormStateInterface; |
||||||
|
|
||||||
|
module_load_include('inc', 'reserve', 'reserve.admin'); |
||||||
|
|
||||||
|
/** |
||||||
|
* Class ReserveCategorySettingsForm. |
||||||
|
* |
||||||
|
* @package Drupal\reserve\Form |
||||||
|
* |
||||||
|
* @ingroup reserve |
||||||
|
*/ |
||||||
|
|
||||||
|
class ReserveDefaultHoursForm extends ConfigFormBase { |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns a unique string identifying the form. |
||||||
|
* |
||||||
|
* @return string |
||||||
|
* The unique string identifying the form. |
||||||
|
*/ |
||||||
|
public function getFormId() { |
||||||
|
return 'ReserveDefaultHours'; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
protected function getEditableConfigNames() { |
||||||
|
return [ |
||||||
|
'reserve.default_hours', |
||||||
|
'reserve.monthly_hours', |
||||||
|
]; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Defines the settings form for reservation categories. |
||||||
|
* |
||||||
|
* @param array $form |
||||||
|
* An associative array containing the structure of the form. |
||||||
|
* @param \Drupal\Core\Form\FormStateInterface $form_state |
||||||
|
* The current state of the form. |
||||||
|
* |
||||||
|
* @return array |
||||||
|
* Form definition array. |
||||||
|
*/ |
||||||
|
public function buildForm(array $form, FormStateInterface $form_state) { |
||||||
|
$default_hours = $this->config('reserve.default_hours')->get('data'); |
||||||
|
|
||||||
|
$hours = reserve_hours(); |
||||||
|
|
||||||
|
// Select box options. |
||||||
|
$options = array(); |
||||||
|
$options['9999'] = t('Select the time'); |
||||||
|
$options['0000'] = t('Midnight - start of day'); |
||||||
|
foreach ($hours as $hour) { |
||||||
|
$time = $hour['time']; |
||||||
|
$display = t($hour['display']); |
||||||
|
if ($time != '0000') { |
||||||
|
$options[$time] = $display; |
||||||
|
} |
||||||
|
} |
||||||
|
$options['2400'] = t('Midnight - end of day'); |
||||||
|
// Get saved default hours. |
||||||
|
if (!$default_hours) { |
||||||
|
for ($x = 0; $x < 28; $x++) { |
||||||
|
$default_hours[$x] = '9999'; |
||||||
|
} |
||||||
|
} |
||||||
|
$days = array( |
||||||
|
t('Sunday'), |
||||||
|
t('Monday'), |
||||||
|
t('Tuesday'), |
||||||
|
t('Wednesday'), |
||||||
|
t('Thursday'), |
||||||
|
t('Friday'), |
||||||
|
t('Saturday'), |
||||||
|
); |
||||||
|
$form['#tree'] = TRUE; |
||||||
|
for ($day = 0; $day < 7; $day++) { |
||||||
|
$day_hours = array(); |
||||||
|
$day_hours[] = $default_hours[($day * 4)]; |
||||||
|
$day_hours[] = $default_hours[($day * 4) + 1]; |
||||||
|
$day_hours[] = $default_hours[($day * 4) + 2]; |
||||||
|
$day_hours[] = $default_hours[($day * 4) + 3]; |
||||||
|
$display_hours = reserve_hours_display($day_hours); |
||||||
|
$form['day_' . $day] = array( |
||||||
|
'#type' => 'details', |
||||||
|
'#title' => $days[$day] . ' (' . $display_hours . ')', |
||||||
|
'#open' => FALSE, |
||||||
|
'#weight' => -90 + ($day * 10), |
||||||
|
); |
||||||
|
$form['day_' . $day]['first_shift_open_' . $day] = array( |
||||||
|
'#title' => t('First shift open'), |
||||||
|
'#type' => 'select', |
||||||
|
'#options' => $options, |
||||||
|
'#default_value' => $default_hours[($day * 4)], |
||||||
|
'#weight' => -90 + ($day * 10) + 1, |
||||||
|
); |
||||||
|
$form['day_' . $day]['first_shift_close_' . $day] = array( |
||||||
|
'#title' => t('First shift close'), |
||||||
|
'#type' => 'select', |
||||||
|
'#options' => $options, |
||||||
|
'#default_value' => $default_hours[($day * 4) + 1], |
||||||
|
'#weight' => -90 + ($day * 10) + 2, |
||||||
|
); |
||||||
|
$form['day_' . $day]['second_shift_open_' . $day] = array( |
||||||
|
'#title' => t('Second shift open'), |
||||||
|
'#type' => 'select', |
||||||
|
'#options' => $options, |
||||||
|
'#default_value' => $default_hours[($day * 4) + 2], |
||||||
|
'#weight' => -90 + ($day * 10) + 3, |
||||||
|
); |
||||||
|
$form['day_' . $day]['second_shift_close_' . $day] = array( |
||||||
|
'#title' => t('Second shift close'), |
||||||
|
'#type' => 'select', |
||||||
|
'#options' => $options, |
||||||
|
'#default_value' => $default_hours[($day * 4) + 3], |
||||||
|
'#weight' => -90 + ($day * 10) + 4, |
||||||
|
); |
||||||
|
} |
||||||
|
$form['save'] = array( |
||||||
|
'#type' => 'submit', |
||||||
|
'#value' => t('Save configuration'), |
||||||
|
'#weight' => 100, |
||||||
|
'#name' => 'save', |
||||||
|
); |
||||||
|
$form['reset'] = array( |
||||||
|
'#type' => 'submit', |
||||||
|
'#value' => t('Reset to defaults'), |
||||||
|
'#weight' => 101, |
||||||
|
'#name' => 'reset', |
||||||
|
); |
||||||
|
|
||||||
|
return $form; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function validateForm(array &$form, FormStateInterface $form_state) { |
||||||
|
$values = $form_state->getValues(); |
||||||
|
$days = array( |
||||||
|
t('Sunday'), |
||||||
|
t('Monday'), |
||||||
|
t('Tuesday'), |
||||||
|
t('Wednesday'), |
||||||
|
t('Thursday'), |
||||||
|
t('Friday'), |
||||||
|
t('Saturday'), |
||||||
|
); |
||||||
|
if ($form_state->getTriggeringElement()['#name'] == 'save') { |
||||||
|
for ($day = 0; $day < 7; $day++) { |
||||||
|
$open = TRUE; |
||||||
|
$second_shift = FALSE; |
||||||
|
$first_shift_open = $values['day_' . $day]['first_shift_open_' . $day]; |
||||||
|
$first_shift_close = $values['day_' . $day]['first_shift_close_' . $day]; |
||||||
|
$second_shift_open = $values['day_' . $day]['second_shift_open_' . $day]; |
||||||
|
$second_shift_close = $values['day_' . $day]['second_shift_close_' . $day]; |
||||||
|
$int_first_shift_open = intval($values['day_' . $day]['first_shift_open_' . $day]); |
||||||
|
$int_first_shift_close = intval($values['day_' . $day]['first_shift_close_' . $day]); |
||||||
|
$int_second_shift_open = intval($values['day_' . $day]['second_shift_open_' . $day]); |
||||||
|
$int_second_shift_close = intval($values['day_' . $day]['second_shift_close_' . $day]); |
||||||
|
// Closed. |
||||||
|
if (($int_first_shift_open == 9999) && ($int_first_shift_close == 9999) && ($int_second_shift_open == 9999) && ($int_second_shift_close == 9999)) { |
||||||
|
$open = FALSE; |
||||||
|
} |
||||||
|
// First shift. |
||||||
|
if ($open) { |
||||||
|
if ($int_first_shift_open == 9999) { |
||||||
|
$field = $form_state->getCompleteForm()['day_' . $day]['first_shift_open_' . $day]; |
||||||
|
$message = t('%day - First shift open is required.', array('%day' => $days[$day])); |
||||||
|
$form_state->setError($field, $message); |
||||||
|
} |
||||||
|
elseif ($int_first_shift_close == 9999) { |
||||||
|
$field = $form_state->getCompleteForm()['day_' . $day]['first_shift_close_' . $day]; |
||||||
|
$message = t('%day - First shift close is required.', array('%day' => $days[$day])); |
||||||
|
$form_state->setError($field, $message); |
||||||
|
} |
||||||
|
elseif ($int_first_shift_open >= $int_first_shift_close) { |
||||||
|
$field = $form_state->getCompleteForm()['day_' . $day]['first_shift_close_' . $day]; |
||||||
|
$message = t('%day - First shift close must be later than first shift open.', array('%day' => $days[$day])); |
||||||
|
$form_state->setError($field, $message); |
||||||
|
} |
||||||
|
} |
||||||
|
// Second shift. |
||||||
|
if ($open) { |
||||||
|
if (($int_second_shift_open != 9999) || ($int_second_shift_close != 9999)) { |
||||||
|
$second_shift = TRUE; |
||||||
|
} |
||||||
|
} |
||||||
|
if ($second_shift) { |
||||||
|
if (($int_first_shift_open == 9999) && ($int_first_shift_close == 9999)) { |
||||||
|
$field = 'day_' . $day . '][second_shift_open_' . $day; |
||||||
|
$field = $form_state->getCompleteForm()['day_' . $day]['second_shift_open_' . $day]; |
||||||
|
$message = t('%day - Cannot have a second shift without a first shift.', array('%day' => $days[$day])); |
||||||
|
$form_state->setError($field, $message); |
||||||
|
} |
||||||
|
elseif ($int_second_shift_open == 9999) { |
||||||
|
$field = $form_state->getCompleteForm()['day_' . $day]['second_shift_open_' . $day]; |
||||||
|
$message = t('%day - Second shift open is missing.', array('%day' => $days[$day])); |
||||||
|
$form_state->setError($field, $message); |
||||||
|
} |
||||||
|
elseif ($int_second_shift_close == 9999) { |
||||||
|
$field = $form_state->getCompleteForm()['day_' . $day]['second_shift_close_' . $day]; |
||||||
|
$message = t('%day - Second shift close is missing.', array('%day' => $days[$day])); |
||||||
|
$form_state->setError($field, $message); |
||||||
|
} |
||||||
|
elseif ($int_second_shift_open <= $int_first_shift_close) { |
||||||
|
$field = $form_state->getCompleteForm()['day_' . $day]['second_shift_open_' . $day]; |
||||||
|
$message = t('%day - Second shift open must be later than first shift close.', array('%day' => $days[$day])); |
||||||
|
$form_state->setError($field, $message); |
||||||
|
} |
||||||
|
elseif ($int_second_shift_open >= $int_second_shift_close) { |
||||||
|
$field = $form_state->getCompleteForm()['day_' . $day]['second_shift_close_' . $day]; |
||||||
|
$message = t('%day - Second shift close must be later than second shift opten.', array('%day' => $days[$day])); |
||||||
|
$form_state->setError($field, $message); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Form submission handler. |
||||||
|
* |
||||||
|
* @param array $form |
||||||
|
* An associative array containing the structure of the form. |
||||||
|
* @param \Drupal\Core\Form\FormStateInterface $form_state |
||||||
|
* The current state of the form. |
||||||
|
*/ |
||||||
|
public function submitForm(array &$form, FormStateInterface $form_state) { |
||||||
|
$values = $form_state->getValues(); |
||||||
|
|
||||||
|
$default_hours = array(); |
||||||
|
if ($form_state->getTriggeringElement()['#name'] == 'save') { |
||||||
|
for ($day = 0; $day < 7; $day++) { |
||||||
|
$default_hours[] = $values['day_' . $day]['first_shift_open_' . $day]; |
||||||
|
$default_hours[] = $values['day_' . $day]['first_shift_close_' . $day]; |
||||||
|
$default_hours[] = $values['day_' . $day]['second_shift_open_' . $day]; |
||||||
|
$default_hours[] = $values['day_' . $day]['second_shift_close_' . $day]; |
||||||
|
} |
||||||
|
$confirmation = t(RESERVE_SAVE_CONFIRMATION_MSG); |
||||||
|
} |
||||||
|
if ($form_state->getTriggeringElement()['#name'] == 'reset') { |
||||||
|
for ($day = 0; $day < 7; $day++) { |
||||||
|
$default_hours[] = '9999'; |
||||||
|
$default_hours[] = '9999'; |
||||||
|
$default_hours[] = '9999'; |
||||||
|
$default_hours[] = '9999'; |
||||||
|
} |
||||||
|
$confirmation = t(RESERVE_RESET_CONFIRMATION_MSG); |
||||||
|
} |
||||||
|
|
||||||
|
// Update monthly hours based on changes to defaults. |
||||||
|
$monthly_hours = \Drupal::config('reserve.monthly_hours')->get('data'); |
||||||
|
foreach ($monthly_hours as $yyyy_mm => $mo_hours) { |
||||||
|
// this shouldnt be required; but just here until i figure out where monthly hours is being corrupted |
||||||
|
if (!is_array($mo_hours)) { |
||||||
|
unset($monthly_hours[$yyyy_mm]); |
||||||
|
continue; |
||||||
|
} |
||||||
|
$month = intval(substr($yyyy_mm, 5)); |
||||||
|
$year = substr($yyyy_mm, 0, 4); |
||||||
|
// Days in the month. |
||||||
|
$days = date('t', mktime(0, 0, 0, $month, 1, (int) $year)); |
||||||
|
$updated_mo_hours = array(); |
||||||
|
for ($day = 0; $day < $days; $day++) { |
||||||
|
$default_ind = $mo_hours[($day * 5)]; |
||||||
|
if ($default_ind == 'D') { |
||||||
|
// Update monthly hours with default day of week hours. |
||||||
|
// Day of the week. |
||||||
|
$dow = date('w', mktime(0, 0, 0, $month, $day + 1, (int) $year)); |
||||||
|
$updated_mo_hours[($day * 5)] = 'D'; |
||||||
|
$updated_mo_hours[($day * 5) + 1] = $default_hours[($dow * 4)]; |
||||||
|
$updated_mo_hours[($day * 5) + 2] = $default_hours[($dow * 4) + 1]; |
||||||
|
$updated_mo_hours[($day * 5) + 3] = $default_hours[($dow * 4) + 2]; |
||||||
|
$updated_mo_hours[($day * 5) + 4] = $default_hours[($dow * 4) + 3]; |
||||||
|
} |
||||||
|
elseif ($default_ind == 'O') { |
||||||
|
// Leave monthly hours unchanged. |
||||||
|
$updated_mo_hours[($day * 5)] = 'O'; |
||||||
|
$updated_mo_hours[($day * 5) + 1] = $mo_hours[($day * 5) + 1]; |
||||||
|
$updated_mo_hours[($day * 5) + 2] = $mo_hours[($day * 5) + 2]; |
||||||
|
$updated_mo_hours[($day * 5) + 3] = $mo_hours[($day * 5) + 3]; |
||||||
|
$updated_mo_hours[($day * 5) + 4] = $mo_hours[($day * 5) + 4]; |
||||||
|
} |
||||||
|
} |
||||||
|
$monthly_hours[$yyyy_mm] = $updated_mo_hours; |
||||||
|
} |
||||||
|
|
||||||
|
$this->config('reserve.default_hours') |
||||||
|
->set('data', $default_hours) |
||||||
|
->save(); |
||||||
|
drupal_set_message($confirmation); |
||||||
|
|
||||||
|
// save updated monthly override hours |
||||||
|
$this->config('reserve.monthly_hours') |
||||||
|
->set('data', $monthly_hours) |
||||||
|
->save(); |
||||||
|
drupal_set_message(t('Daily overrides updated with new defaults.')); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,86 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace Drupal\reserve\Form; |
||||||
|
|
||||||
|
use Drupal\Core\Form\ConfigFormBase; |
||||||
|
use Drupal\Core\Form\FormStateInterface; |
||||||
|
|
||||||
|
/** |
||||||
|
* Class ReserveCategorySettingsForm. |
||||||
|
* |
||||||
|
* @package Drupal\reserve\Form |
||||||
|
* |
||||||
|
* @ingroup reserve |
||||||
|
*/ |
||||||
|
|
||||||
|
class ReserveDisplayForm extends ConfigFormBase { |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns a unique string identifying the form. |
||||||
|
* |
||||||
|
* @return string |
||||||
|
* The unique string identifying the form. |
||||||
|
*/ |
||||||
|
public function getFormId() { |
||||||
|
return 'ReserveDisplaySettings'; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
protected function getEditableConfigNames() { |
||||||
|
return [ |
||||||
|
'reserve.display', |
||||||
|
]; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Defines the settings form for reservation categories. |
||||||
|
* |
||||||
|
* @param array $form |
||||||
|
* An associative array containing the structure of the form. |
||||||
|
* @param \Drupal\Core\Form\FormStateInterface $form_state |
||||||
|
* The current state of the form. |
||||||
|
* |
||||||
|
* @return array |
||||||
|
* Form definition array. |
||||||
|
*/ |
||||||
|
public function buildForm(array $form, FormStateInterface $form_state) { |
||||||
|
$config = $this->config('reserve.display'); |
||||||
|
$form['ReserveDisplay']['#markup'] = 'Settings form for text displayed throughout the Reserve UI.'; |
||||||
|
|
||||||
|
$length_options = array( |
||||||
|
'30' => '30', |
||||||
|
'60' => '60', |
||||||
|
'90' => '90', |
||||||
|
'120' => '120', |
||||||
|
'150' => '150', |
||||||
|
'180' => '180', |
||||||
|
'240' => '240', |
||||||
|
'360' => '360', |
||||||
|
'480' => '480', |
||||||
|
'600' => '600', |
||||||
|
'720' => '720', |
||||||
|
); |
||||||
|
|
||||||
|
return parent::buildForm($form, $form_state); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Form submission handler. |
||||||
|
* |
||||||
|
* @param array $form |
||||||
|
* An associative array containing the structure of the form. |
||||||
|
* @param \Drupal\Core\Form\FormStateInterface $form_state |
||||||
|
* The current state of the form. |
||||||
|
*/ |
||||||
|
public function submitForm(array &$form, FormStateInterface $form_state) { |
||||||
|
/*$values = $form_state->getValues(); |
||||||
|
$this->config('reserve.category.hours.settings') |
||||||
|
->set('calendar_title', $values['calendar_title']) |
||||||
|
->set('advanced_booking_standard', $values['advanced_booking_standard']) |
||||||
|
->set('advanced_booking_admin', $values['advanced_booking_admin']) |
||||||
|
->save();*/ |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,15 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace Drupal\reserve\Form; |
||||||
|
|
||||||
|
use Drupal\Core\Entity\ContentEntityDeleteForm; |
||||||
|
|
||||||
|
/** |
||||||
|
* Provides a form for deleting reservations. |
||||||
|
* |
||||||
|
* @ingroup reserve |
||||||
|
*/ |
||||||
|
class ReserveReservationDeleteForm extends ContentEntityDeleteForm { |
||||||
|
|
||||||
|
|
||||||
|
} |
@ -0,0 +1,50 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace Drupal\reserve\Form; |
||||||
|
|
||||||
|
use Drupal\Core\Entity\ContentEntityForm; |
||||||
|
use Drupal\Core\Form\FormStateInterface; |
||||||
|
|
||||||
|
/** |
||||||
|
* Form controller for Reservation edit forms. |
||||||
|
* |
||||||
|
* @ingroup reserve |
||||||
|
*/ |
||||||
|
class ReserveReservationForm extends ContentEntityForm { |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function buildForm(array $form, FormStateInterface $form_state) { |
||||||
|
/* @var $entity \Drupal\reserve\Entity\ReserveReservation */ |
||||||
|
$form = parent::buildForm($form, $form_state); |
||||||
|
|
||||||
|
$entity = $this->entity; |
||||||
|
|
||||||
|
return $form; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function save(array $form, FormStateInterface $form_state) { |
||||||
|
$entity = &$this->entity; |
||||||
|
|
||||||
|
$status = parent::save($form, $form_state); |
||||||
|
|
||||||
|
switch ($status) { |
||||||
|
case SAVED_NEW: |
||||||
|
drupal_set_message($this->t('Created the %label Reservation.', [ |
||||||
|
'%label' => $entity->label(), |
||||||
|
])); |
||||||
|
break; |
||||||
|
|
||||||
|
default: |
||||||
|
drupal_set_message($this->t('Saved the %label Reservation.', [ |
||||||
|
'%label' => $entity->label(), |
||||||
|
])); |
||||||
|
} |
||||||
|
$form_state->setRedirect('entity.reserve_reservation.canonical', ['reserve_reservation' => $entity->id()]); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,55 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace Drupal\reserve\Form; |
||||||
|
|
||||||
|
use Drupal\Core\Form\FormBase; |
||||||
|
use Drupal\Core\Form\FormStateInterface; |
||||||
|
|
||||||
|
/** |
||||||
|
* Class ReserveReservationSettingsForm. |
||||||
|
* |
||||||
|
* @package Drupal\reserve\Form |
||||||
|
* |
||||||
|
* @ingroup reserve |
||||||
|
*/ |
||||||
|
class ReserveReservationSettingsForm extends FormBase { |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns a unique string identifying the form. |
||||||
|
* |
||||||
|
* @return string |
||||||
|
* The unique string identifying the form. |
||||||
|
*/ |
||||||
|
public function getFormId() { |
||||||
|
return 'ReserveReservation_settings'; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Form submission handler. |
||||||
|
* |
||||||
|
* @param array $form |
||||||
|
* An associative array containing the structure of the form. |
||||||
|
* @param \Drupal\Core\Form\FormStateInterface $form_state |
||||||
|
* The current state of the form. |
||||||
|
*/ |
||||||
|
public function submitForm(array &$form, FormStateInterface $form_state) { |
||||||
|
// Empty implementation of the abstract submit class. |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Defines the settings form for reservations. |
||||||
|
* |
||||||
|
* @param array $form |
||||||
|
* An associative array containing the structure of the form. |
||||||
|
* @param \Drupal\Core\Form\FormStateInterface $form_state |
||||||
|
* The current state of the form. |
||||||
|
* |
||||||
|
* @return array |
||||||
|
* Form definition array. |
||||||
|
*/ |
||||||
|
public function buildForm(array $form, FormStateInterface $form_state) { |
||||||
|
$form['ReserveReservation_settings']['#markup'] = 'Settings form for reservations. Manage field settings here.'; |
||||||
|
return $form; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,183 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace Drupal\reserve\Form; |
||||||
|
|
||||||
|
use Drupal\Core\Form\ConfigFormBase; |
||||||
|
//use Drupal\Core\Form\FormBase; |
||||||
|
use Drupal\Core\Form\FormStateInterface; |
||||||
|
|
||||||
|
/** |
||||||
|
* Class ReserveCategorySettingsForm. |
||||||
|
* |
||||||
|
* @package Drupal\reserve\Form |
||||||
|
* |
||||||
|
* @ingroup reserve |
||||||
|
*/ |
||||||
|
|
||||||
|
class ReserveSettingsForm extends ConfigFormBase { |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns a unique string identifying the form. |
||||||
|
* |
||||||
|
* @return string |
||||||
|
* The unique string identifying the form. |
||||||
|
*/ |
||||||
|
public function getFormId() { |
||||||
|
return 'ReserveSettings'; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
protected function getEditableConfigNames() { |
||||||
|
return [ |
||||||
|
'reserve.settings', |
||||||
|
]; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Defines the settings form for reservation categories. |
||||||
|
* |
||||||
|
* @param array $form |
||||||
|
* An associative array containing the structure of the form. |
||||||
|
* @param \Drupal\Core\Form\FormStateInterface $form_state |
||||||
|
* The current state of the form. |
||||||
|
* |
||||||
|
* @return array |
||||||
|
* Form definition array. |
||||||
|
*/ |
||||||
|
public function buildForm(array $form, FormStateInterface $form_state) { |
||||||
|
$config = $this->config('reserve.settings'); |
||||||
|
$form['header']['#markup'] = 'Settings form for general Reserve settings. @TODO - make Category based'; |
||||||
|
|
||||||
|
$options = array( |
||||||
|
'30' => '30', |
||||||
|
'60' => '60', |
||||||
|
'90' => '90', |
||||||
|
'120' => '120', |
||||||
|
'150' => '150', |
||||||
|
'180' => '180', |
||||||
|
'210' => '210', |
||||||
|
'240' => '240', |
||||||
|
'270' => '270', |
||||||
|
'300' => '300', |
||||||
|
); |
||||||
|
|
||||||
|
$form['reservations_per_user'] = array( |
||||||
|
'#title' => t('Open reservations per user'), |
||||||
|
'#type' => 'textfield', |
||||||
|
'#maxlength' => 2, |
||||||
|
'#size' => 2, |
||||||
|
'#description' => t('The maximum number of reservations that one particular user can have open at any time. Default is 4. Enter 0 to indicate |
||||||
|
no limit.'), |
||||||
|
'#default_value' => $config->get('reservations_per_user') ? $config->get('reservations_per_user') : 4, |
||||||
|
); |
||||||
|
|
||||||
|
$form['reservations_per_day'] = array( |
||||||
|
'#title' => t('Reservations per day'), |
||||||
|
'#type' => 'textfield', |
||||||
|
'#maxlength' => 2, |
||||||
|
'#size' => 2, |
||||||
|
'#description' => t('The maximum number of reservations that one user can make for a single day. Default is 1. Enter 0 to indicate |
||||||
|
no limit.'), |
||||||
|
'#default_value' => $config->get('reservations_per_day') ? $config->get('reservations_per_day') : 1, |
||||||
|
); |
||||||
|
|
||||||
|
$form['reservation_max_length_standard'] = array( |
||||||
|
'#title' => t('Maximum reservation length (standard)'), |
||||||
|
'#type' => 'select', |
||||||
|
'#options' => $options, |
||||||
|
'#default_value' => $config->get('reservation_max_length_standard') ? $config->get('reservation_max_length_standard') : 120, |
||||||
|
'#description' => t('The maximum amount of time (in minutes) which a reservation can be made by a user with "Create new reservations (extended)" |
||||||
|
privilege. Default is 120.'), |
||||||
|
); |
||||||
|
|
||||||
|
$form['reservation_max_length_extended'] = array( |
||||||
|
'#title' => t('Maximum reservation length (extended)'), |
||||||
|
'#type' => 'select', |
||||||
|
'#options' => $options, |
||||||
|
'#default_value' => $config->get('reservation_max_length_extended') ? $config->get('reservation_max_length_extended') : 120, |
||||||
|
'#description' => t('The maximum amount of time (in minutes) which a reservation can be made by a user with "Create new reservations (extended)" |
||||||
|
privilege. Default is 120.'), |
||||||
|
); |
||||||
|
|
||||||
|
// @todo what is this for? |
||||||
|
$form['reservation_end_early'] = array( |
||||||
|
'#title' => t('End reservations 15 minutes before closing time.'), |
||||||
|
'#type' => 'checkbox', |
||||||
|
'#return_value' => 1, |
||||||
|
'#default_value' => $config->get('reservation_end_early') ? $config->get('reservation_end_early') : 0, |
||||||
|
'#description' => t('All reservations end 15 minutes before closing time.'), |
||||||
|
); |
||||||
|
|
||||||
|
$form['show_before_after_hours'] = array( |
||||||
|
'#title' => t('Time to show on calendar before/after open slots'), |
||||||
|
'#type' => 'select', |
||||||
|
'#options' => array(0 => '0 hours', 1 => t('1 hour'), 2 => t('2 hours'), '3' => t('All day')), |
||||||
|
'#default_value' => $config->get('show_before_after_hours') ? $config->get('advanced_booking_admin') : 3, |
||||||
|
'#description' => t('The number of hours before the first and last open slots for the day that are shown on the calendar. The default is to display the entire day.'), |
||||||
|
); |
||||||
|
|
||||||
|
// @todo decide if worth porting this to D8 |
||||||
|
$form['calendar_flipped'] = array( |
||||||
|
'#title' => t('Flip orientation of calendar display.'), |
||||||
|
'#type' => 'checkbox', |
||||||
|
'#return_value' => 1, |
||||||
|
'#default_value' => $config->get('calendar_flipped') ? $config->get('calendar_flipped') : 0, |
||||||
|
'#description' => t('The default orientation of the calendar display has rooms listed along the top and hours along the left side. Selecting this checkbox will |
||||||
|
flip this to display hours along the top and the rooms listed along the left side. This can be useful for categories with a very large number of rooms. NOTE: |
||||||
|
custom CSS will most likely be required to allow all the hour slots to fit the width of your theme.'), |
||||||
|
); |
||||||
|
|
||||||
|
$form['calendar_compressed_labels'] = array( |
||||||
|
'#title' => t('Use smaller labels on calendar display.'), |
||||||
|
'#type' => 'checkbox', |
||||||
|
'#return_value' => 1, |
||||||
|
'#default_value' => $config->get('calendar_compressed_labels') ? $config->get('calendar_compressed_labels') : 0, |
||||||
|
'#description' => t('The default display shows the reserve entity title on both sides of the calendar display. Selecting this option shows only the room title on one side.'), |
||||||
|
); |
||||||
|
|
||||||
|
$form['date_displays'] = array( |
||||||
|
'#type' => 'details', |
||||||
|
'#title' => t('Date and time display formats'), |
||||||
|
'#open' => FALSE, |
||||||
|
); |
||||||
|
|
||||||
|
$form['date_displays']['date_format'] = array( |
||||||
|
'#type' => 'textfield', |
||||||
|
'#title' => t('Date format for the popup date picker to select calendar date.'), |
||||||
|
'#description' => t('Enter format in the form "y/m/d", "m/d/y", etc.'), |
||||||
|
'#default_value' => $config->get('date_format') ? $config->get('date_format') : 'y/m/d', |
||||||
|
); |
||||||
|
|
||||||
|
$form['date_displays']['hour_format'] = array( |
||||||
|
'#type' => 'radios', |
||||||
|
'#title' => t('Hour format for the calendar display.'), |
||||||
|
'#description' => t('Select either 2:00 PM or 14:00 display format.'), |
||||||
|
'#default_value' => $config->get('hour_format') ? $config->get('hour_format') : 0, |
||||||
|
'#options' => array(0 => '1:00 PM', 1 => '13:00'), |
||||||
|
); |
||||||
|
|
||||||
|
return parent::buildForm($form, $form_state); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Form submission handler. |
||||||
|
* |
||||||
|
* @param array $form |
||||||
|
* An associative array containing the structure of the form. |
||||||
|
* @param \Drupal\Core\Form\FormStateInterface $form_state |
||||||
|
* The current state of the form. |
||||||
|
*/ |
||||||
|
public function submitForm(array &$form, FormStateInterface $form_state) { |
||||||
|
$values = $form_state->getValues(); |
||||||
|
foreach ($values as $key => $value) { |
||||||
|
if (stristr('form_', $key)) continue; |
||||||
|
if (is_object($values[$key])) continue; |
||||||
|
$this->config('reserve.settings')->set($key, $value); |
||||||
|
} |
||||||
|
$this->config('reserve.settings')->save(); |
||||||
|
drupal_set_message(RESERVE_SAVE_CONFIRMATION_MSG); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,49 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace Drupal\reserve\Plugin\Field\FieldFormatter; |
||||||
|
|
||||||
|
use Drupal\Core\Field\FormatterBase; |
||||||
|
use Drupal\Core\Field\FieldItemListInterface; |
||||||
|
|
||||||
|
/** |
||||||
|
* Plugin implementation of the 'Random_default' formatter. |
||||||
|
* |
||||||
|
* @FieldFormatter( |
||||||
|
* id = "reserve_category_formatter", |
||||||
|
* label = @Translation("Default"), |
||||||
|
* field_types = { |
||||||
|
* "reserve_category" |
||||||
|
* } |
||||||
|
* ) |
||||||
|
*/ |
||||||
|
class ReserveCategoryFormatter extends FormatterBase { |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function settingsSummary() { |
||||||
|
$summary = []; |
||||||
|
$settings = $this->getSettings(); |
||||||
|
$summary[] = t('Displays the Reserve Category.'); |
||||||
|
return $summary; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function viewElements(FieldItemListInterface $items, $langcode) { |
||||||
|
$element = []; |
||||||
|
|
||||||
|
foreach ($items as $delta => $item) { |
||||||
|
$category = \Drupal\reserve\Entity\ReserveCategory::load($item->cid); |
||||||
|
// Render each element as markup. |
||||||
|
$element[$delta] = [ |
||||||
|
'#type' => 'markup', |
||||||
|
'#markup' => $category->label(), |
||||||
|
]; |
||||||
|
} |
||||||
|
|
||||||
|
return $element; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,116 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace Drupal\reserve\Plugin\Field\FieldType; |
||||||
|
|
||||||
|
use Drupal\Core\Field\FieldItemBase; |
||||||
|
use Drupal\Core\Field\FieldItemInterface; |
||||||
|
use Drupal\Core\Form\FormStateInterface; |
||||||
|
use Drupal\Core\Field\FieldStorageDefinitionInterface; |
||||||
|
use Drupal\Core\TypedData\DataDefinition; |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* Class ReserveCategory for Category selection field type |
||||||
|
* |
||||||
|
* @FieldType( |
||||||
|
* id = "reserve_category", |
||||||
|
* label = @Translation("Reserve Category"), |
||||||
|
* description = @Translation("A selection field to assign which Reserve Category this entity is grouped under."), |
||||||
|
* default_widget = "reserve_category_select", |
||||||
|
* default_formatter = "reserve_category_formatter", |
||||||
|
* category = @Translation("Reference"), |
||||||
|
* cardinality = 1, |
||||||
|
* ) |
||||||
|
* |
||||||
|
*/ |
||||||
|
class ReserveCategory extends FieldItemBase implements FieldItemInterface { |
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public static function schema(FieldStorageDefinitionInterface $field_definition) { |
||||||
|
return array( |
||||||
|
'columns' => array( |
||||||
|
'cid' => array( |
||||||
|
'type' => 'int', |
||||||
|
'not null' => TRUE, |
||||||
|
), |
||||||
|
), |
||||||
|
'indexes' => array( |
||||||
|
'cid' => array('cid'), |
||||||
|
), |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function isEmpty() { |
||||||
|
$value = $this->get('cid')->getValue(); |
||||||
|
return $value === NULL || $value === ''; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) { |
||||||
|
$properties['cid'] = DataDefinition::create('integer') |
||||||
|
->setLabel(t('Category')); |
||||||
|
|
||||||
|
return $properties; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function fieldSettingsForm(array $form, FormStateInterface $form_state) { |
||||||
|
// get a list of all Reserve Categories |
||||||
|
$ids = \Drupal::entityQuery('reserve_category')->sort('name', 'ASC')->execute(); |
||||||
|
$categories = \Drupal\reserve\Entity\ReserveCategory::loadMultiple($ids); |
||||||
|
$options = array(); |
||||||
|
foreach ($categories as $cat) { |
||||||
|
$options[$cat->id()] = $cat->label(); |
||||||
|
} |
||||||
|
|
||||||
|
$element = []; |
||||||
|
|
||||||
|
$element['categories'] = [ |
||||||
|
'#type' => 'checkboxes', |
||||||
|
'#title' => t('Allowed categories'), |
||||||
|
'#description' => t('Select which categories should be available for this bundle.'), |
||||||
|
'#default_value' => $this->getSetting('categories'), |
||||||
|
'#options' => $options, |
||||||
|
]; |
||||||
|
|
||||||
|
$element['calendar_header'] = [ |
||||||
|
'#type' => 'textarea', |
||||||
|
'#title' => t('Calendar header'), |
||||||
|
'#description' => t('Optional header text to add above the calendar for this bundle.'), |
||||||
|
'#default_value' => $this->getSetting('calendar_header') ? |
||||||
|
$this->getSetting('calendar_header') : |
||||||
|
t('You may set optional header text under the field settings for the Reserve Category field for this bundle.') |
||||||
|
]; |
||||||
|
|
||||||
|
$element['reservation_instructions'] = [ |
||||||
|
'#type' => 'textarea', |
||||||
|
'#title' => t('Reservation instructions'), |
||||||
|
'#description' => t('Optional reservation instructions to add below the calendar for this bundle.'), |
||||||
|
'#default_value' => $this->getSetting('reservation_instructions') ? |
||||||
|
$this->getSetting('reservation_instructions') : |
||||||
|
t('You may set optional reservation instructions under the field settings for the Reserve Category field for this bundle.') |
||||||
|
]; |
||||||
|
|
||||||
|
return $element; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public static function defaultFieldSettings() { |
||||||
|
return [ |
||||||
|
'categories' => [], |
||||||
|
'calendar_header' => null, |
||||||
|
'reservation_instructions' => null, |
||||||
|
] + parent::defaultFieldSettings(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,49 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace Drupal\reserve\Plugin\Field\FieldWidget; |
||||||
|
|
||||||
|
use Drupal\Core\Field\FieldItemListInterface; |
||||||
|
use Drupal\Core\Field\WidgetBase; |
||||||
|
use Drupal\Core\Form\FormStateInterface; |
||||||
|
|
||||||
|
/** |
||||||
|
* Plugin implementation of the 'reserve_category_select' widget. |
||||||
|
* |
||||||
|
* @FieldWidget( |
||||||
|
* id = "reserve_category_select", |
||||||
|
* module = "reserve", |
||||||
|
* label = @Translation("Select list"), |
||||||
|
* field_types = { |
||||||
|
* "reserve_category" |
||||||
|
* } |
||||||
|
* ) |
||||||
|
*/ |
||||||
|
class ReserveCategorySelect extends WidgetBase { |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) { |
||||||
|
$cid = isset($items[$delta]->cid) ? $items[$delta]->cid : ''; |
||||||
|
|
||||||
|
// get a list of all Reserve Categories for this bundle |
||||||
|
$set = $items->getSettings()['categories']; |
||||||
|
|
||||||
|
$ids = \Drupal::entityQuery('reserve_category')->sort('name', 'ASC')->execute(); |
||||||
|
$categories = \Drupal\reserve\Entity\ReserveCategory::loadMultiple($ids); |
||||||
|
$options = array(); |
||||||
|
foreach ($categories as $key => $cat) { |
||||||
|
if (!in_array($key, $set)) continue; |
||||||
|
$options[$cat->id()] = $cat->label(); |
||||||
|
} |
||||||
|
|
||||||
|
$element += [ |
||||||
|
'#type' => 'select', |
||||||
|
'#options' => $options, |
||||||
|
'#default_value' => $cid, |
||||||
|
]; |
||||||
|
|
||||||
|
return array('cid' => $element); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,47 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace Drupal\reserve; |
||||||
|
|
||||||
|
use Drupal\Core\Entity\EntityAccessControlHandler; |
||||||
|
use Drupal\Core\Entity\EntityInterface; |
||||||
|
use Drupal\Core\Session\AccountInterface; |
||||||
|
use Drupal\Core\Access\AccessResult; |
||||||
|
|
||||||
|
/** |
||||||
|
* Access controller for the Reservation Category entity. |
||||||
|
* |
||||||
|
* @see \Drupal\reserve\Entity\ReserveCategory. |
||||||
|
*/ |
||||||
|
class ReserveCategoryAccessControlHandler extends EntityAccessControlHandler { |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) { |
||||||
|
/** @var \Drupal\reserve\Entity\ReserveCategoryInterface $entity */ |
||||||
|
switch ($operation) { |
||||||
|
case 'view': |
||||||
|
if (!$entity->isPublished()) { |
||||||
|
return AccessResult::allowedIfHasPermission($account, 'view unpublished reservation categories'); |
||||||
|
} |
||||||
|
return AccessResult::allowedIfHasPermission($account, 'view published reservation categories'); |
||||||
|
|
||||||
|
case 'update': |
||||||
|
return AccessResult::allowedIfHasPermission($account, 'edit reservation categories'); |
||||||
|
|
||||||
|
case 'delete': |
||||||
|
return AccessResult::allowedIfHasPermission($account, 'delete reservation categories'); |
||||||
|
} |
||||||
|
|
||||||
|
// Unknown operation, no opinion. |
||||||
|
return AccessResult::neutral(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
protected function checkCreateAccess(AccountInterface $account, array $context, $entity_bundle = NULL) { |
||||||
|
return AccessResult::allowedIfHasPermission($account, 'add reservation categories'); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,85 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace Drupal\reserve; |
||||||
|
|
||||||
|
use Drupal\Core\Entity\EntityTypeInterface; |
||||||
|
use Drupal\Core\Entity\Routing\AdminHtmlRouteProvider; |
||||||
|
use Symfony\Component\Routing\Route; |
||||||
|
|
||||||
|
/** |
||||||
|
* Provides routes for reservation categories. |
||||||
|
* |
||||||
|
* @see Drupal\Core\Entity\Routing\AdminHtmlRouteProvider |
||||||
|
* @see Drupal\Core\Entity\Routing\DefaultHtmlRouteProvider |
||||||
|
*/ |
||||||
|
class ReserveCategoryHtmlRouteProvider extends AdminHtmlRouteProvider { |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function getRoutes(EntityTypeInterface $entity_type) { |
||||||
|
$collection = parent::getRoutes($entity_type); |
||||||
|
|
||||||
|
$entity_type_id = $entity_type->id(); |
||||||
|
|
||||||
|
if ($collection_route = $this->getCollectionRoute($entity_type)) { |
||||||
|
$collection->add("entity.{$entity_type_id}.collection", $collection_route); |
||||||
|
} |
||||||
|
|
||||||
|
if ($settings_form_route = $this->getSettingsFormRoute($entity_type)) { |
||||||
|
$collection->add("$entity_type_id.settings", $settings_form_route); |
||||||
|
} |
||||||
|
|
||||||
|
return $collection; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Gets the collection route. |
||||||
|
* |
||||||
|
* @param \Drupal\Core\Entity\EntityTypeInterface $entity_type |
||||||
|
* The entity type. |
||||||
|
* |
||||||
|
* @return \Symfony\Component\Routing\Route|null |
||||||
|
* The generated route, if available. |
||||||
|
*/ |
||||||
|
protected function getCollectionRoute(EntityTypeInterface $entity_type) { |
||||||
|
if ($entity_type->hasLinkTemplate('collection') && $entity_type->hasListBuilderClass()) { |
||||||
|
$entity_type_id = $entity_type->id(); |
||||||
|
$route = new Route($entity_type->getLinkTemplate('collection')); |
||||||
|
$route |
||||||
|
->setDefaults([ |
||||||
|
'_entity_list' => $entity_type_id, |
||||||
|
'_title' => "{$entity_type->getLabel()} list", |
||||||
|
]) |
||||||
|
->setRequirement('_permission', 'access reservation category overview') |
||||||
|
->setOption('_admin_route', TRUE); |
||||||
|
|
||||||
|
return $route; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Gets the settings form route. |
||||||
|
* |
||||||
|
* @param \Drupal\Core\Entity\EntityTypeInterface $entity_type |
||||||
|
* The entity type. |
||||||
|
* |
||||||
|
* @return \Symfony\Component\Routing\Route|null |
||||||
|
* The generated route, if available. |
||||||
|
*/ |
||||||
|
protected function getSettingsFormRoute(EntityTypeInterface $entity_type) { |
||||||
|
if (!$entity_type->getBundleEntityType()) { |
||||||
|
$route = new Route("/admin/structure/{$entity_type->id()}/settings"); |
||||||
|
$route |
||||||
|
->setDefaults([ |
||||||
|
'_form' => 'Drupal\reserve\Form\ReserveCategorySettingsForm', |
||||||
|
'_title' => "{$entity_type->getLabel()} settings", |
||||||
|
]) |
||||||
|
->setRequirement('_permission', $entity_type->getAdminPermission()) |
||||||
|
->setOption('_admin_route', TRUE); |
||||||
|
|
||||||
|
return $route; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,45 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace Drupal\reserve; |
||||||
|
|
||||||
|
use Drupal\Core\Entity\EntityInterface; |
||||||
|
use Drupal\Core\Entity\EntityListBuilder; |
||||||
|
use Drupal\Core\Routing\LinkGeneratorTrait; |
||||||
|
use Drupal\Core\Url; |
||||||
|
|
||||||
|
/** |
||||||
|
* Defines a class to build a listing of reservation categories. |
||||||
|
* |
||||||
|
* @ingroup reserve |
||||||
|
*/ |
||||||
|
class ReserveCategoryListBuilder extends EntityListBuilder { |
||||||
|
|
||||||
|
use LinkGeneratorTrait; |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function buildHeader() { |
||||||
|
$header['id'] = $this->t('Reservation Category ID'); |
||||||
|
$header['name'] = $this->t('Name'); |
||||||
|
return $header + parent::buildHeader(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function buildRow(EntityInterface $entity) { |
||||||
|
/* @var $entity \Drupal\reserve\Entity\ReserveCategory */ |
||||||
|
$row['id'] = $entity->id(); |
||||||
|
$row['name'] = $this->l( |
||||||
|
$entity->label(), |
||||||
|
new Url( |
||||||
|
'entity.reserve_category.edit_form', array( |
||||||
|
'reserve_category' => $entity->id(), |
||||||
|
) |
||||||
|
) |
||||||
|
); |
||||||
|
return $row + parent::buildRow($entity); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,14 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace Drupal\reserve; |
||||||
|
|
||||||
|
use Drupal\content_translation\ContentTranslationHandler; |
||||||
|
|
||||||
|
/** |
||||||
|
* Defines the translation handler for reserve_category. |
||||||
|
*/ |
||||||
|
class ReserveCategoryTranslationHandler extends ContentTranslationHandler { |
||||||
|
|
||||||
|
// Override here the needed methods from ContentTranslationHandler. |
||||||
|
|
||||||
|
} |
@ -0,0 +1,47 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace Drupal\reserve; |
||||||
|
|
||||||
|
use Drupal\Core\Entity\EntityAccessControlHandler; |
||||||
|
use Drupal\Core\Entity\EntityInterface; |
||||||
|
use Drupal\Core\Session\AccountInterface; |
||||||
|
use Drupal\Core\Access\AccessResult; |
||||||
|
|
||||||
|
/** |
||||||
|
* Access controller for the Reservation entity. |
||||||
|
* |
||||||
|
* @see \Drupal\reserve\Entity\ReserveReservation. |
||||||
|
*/ |
||||||
|
class ReserveReservationAccessControlHandler extends EntityAccessControlHandler { |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) { |
||||||
|
/** @var \Drupal\reserve\Entity\ReserveReservationInterface $entity */ |
||||||
|
switch ($operation) { |
||||||
|
case 'view': |
||||||
|
if (!$entity->isPublished()) { |
||||||
|
return AccessResult::allowedIfHasPermission($account, 'view unpublished reservations'); |
||||||
|
} |
||||||
|
return AccessResult::allowedIfHasPermission($account, 'view published reservations'); |
||||||
|
|
||||||
|
case 'update': |
||||||
|
return AccessResult::allowedIfHasPermission($account, 'edit reservations'); |
||||||
|
|
||||||
|
case 'delete': |
||||||
|
return AccessResult::allowedIfHasPermission($account, 'delete reservations'); |
||||||
|
} |
||||||
|
|
||||||
|
// Unknown operation, no opinion. |
||||||
|
return AccessResult::neutral(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
protected function checkCreateAccess(AccountInterface $account, array $context, $entity_bundle = NULL) { |
||||||
|
return AccessResult::allowedIfHasPermission($account, 'add reservations'); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,85 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace Drupal\reserve; |
||||||
|
|
||||||
|
use Drupal\Core\Entity\EntityTypeInterface; |
||||||
|
use Drupal\Core\Entity\Routing\AdminHtmlRouteProvider; |
||||||
|
use Symfony\Component\Routing\Route; |
||||||
|
|
||||||
|
/** |
||||||
|
* Provides routes for reservations. |
||||||
|
* |
||||||
|
* @see Drupal\Core\Entity\Routing\AdminHtmlRouteProvider |
||||||
|
* @see Drupal\Core\Entity\Routing\DefaultHtmlRouteProvider |
||||||
|
*/ |
||||||
|
class ReserveReservationHtmlRouteProvider extends AdminHtmlRouteProvider { |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function getRoutes(EntityTypeInterface $entity_type) { |
||||||
|
$collection = parent::getRoutes($entity_type); |
||||||
|
|
||||||
|
$entity_type_id = $entity_type->id(); |
||||||
|
|
||||||
|
if ($collection_route = $this->getCollectionRoute($entity_type)) { |
||||||
|
$collection->add("entity.{$entity_type_id}.collection", $collection_route); |
||||||
|
} |
||||||
|
|
||||||
|
if ($settings_form_route = $this->getSettingsFormRoute($entity_type)) { |
||||||
|
$collection->add("$entity_type_id.settings", $settings_form_route); |
||||||
|
} |
||||||
|
|
||||||
|
return $collection; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Gets the collection route. |
||||||
|
* |
||||||
|
* @param \Drupal\Core\Entity\EntityTypeInterface $entity_type |
||||||
|
* The entity type. |
||||||
|
* |
||||||
|
* @return \Symfony\Component\Routing\Route|null |
||||||
|
* The generated route, if available. |
||||||
|
*/ |
||||||
|
protected function getCollectionRoute(EntityTypeInterface $entity_type) { |
||||||
|
if ($entity_type->hasLinkTemplate('collection') && $entity_type->hasListBuilderClass()) { |
||||||
|
$entity_type_id = $entity_type->id(); |
||||||
|
$route = new Route($entity_type->getLinkTemplate('collection')); |
||||||
|
$route |
||||||
|
->setDefaults([ |
||||||
|
'_entity_list' => $entity_type_id, |
||||||
|
'_title' => "{$entity_type->getLabel()} list", |
||||||
|
]) |
||||||
|
->setRequirement('_permission', 'access reservation overview') |
||||||
|
->setOption('_admin_route', TRUE); |
||||||
|
|
||||||
|
return $route; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Gets the settings form route. |
||||||
|
* |
||||||
|
* @param \Drupal\Core\Entity\EntityTypeInterface $entity_type |
||||||
|
* The entity type. |
||||||
|
* |
||||||
|
* @return \Symfony\Component\Routing\Route|null |
||||||
|
* The generated route, if available. |
||||||
|
*/ |
||||||
|
protected function getSettingsFormRoute(EntityTypeInterface $entity_type) { |
||||||
|
if (!$entity_type->getBundleEntityType()) { |
||||||
|
$route = new Route("/admin/structure/{$entity_type->id()}/settings"); |
||||||
|
$route |
||||||
|
->setDefaults([ |
||||||
|
'_form' => 'Drupal\reserve\Form\ReserveReservationSettingsForm', |
||||||
|
'_title' => "{$entity_type->getLabel()} settings", |
||||||
|
]) |
||||||
|
->setRequirement('_permission', $entity_type->getAdminPermission()) |
||||||
|
->setOption('_admin_route', TRUE); |
||||||
|
|
||||||
|
return $route; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,45 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace Drupal\reserve; |
||||||
|
|
||||||
|
use Drupal\Core\Entity\EntityInterface; |
||||||
|
use Drupal\Core\Entity\EntityListBuilder; |
||||||
|
use Drupal\Core\Routing\LinkGeneratorTrait; |
||||||
|
use Drupal\Core\Url; |
||||||
|
|
||||||
|
/** |
||||||
|
* Defines a class to build a listing of reservations. |
||||||
|
* |
||||||
|
* @ingroup reserve |
||||||
|
*/ |
||||||
|
class ReserveReservationListBuilder extends EntityListBuilder { |
||||||
|
|
||||||
|
use LinkGeneratorTrait; |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function buildHeader() { |
||||||
|
$header['id'] = $this->t('Reservation ID'); |
||||||
|
$header['name'] = $this->t('Name'); |
||||||
|
return $header + parent::buildHeader(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function buildRow(EntityInterface $entity) { |
||||||
|
/* @var $entity \Drupal\reserve\Entity\ReserveReservation */ |
||||||
|
$row['id'] = $entity->id(); |
||||||
|
$row['name'] = $this->l( |
||||||
|
$entity->label(), |
||||||
|
new Url( |
||||||
|
'entity.reserve_reservation.edit_form', array( |
||||||
|
'reserve_reservation' => $entity->id(), |
||||||
|
) |
||||||
|
) |
||||||
|
); |
||||||
|
return $row + parent::buildRow($entity); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,14 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace Drupal\reserve; |
||||||
|
|
||||||
|
use Drupal\content_translation\ContentTranslationHandler; |
||||||
|
|
||||||
|
/** |
||||||
|
* Defines the translation handler for reserve_reservation. |
||||||
|
*/ |
||||||
|
class ReserveReservationTranslationHandler extends ContentTranslationHandler { |
||||||
|
|
||||||
|
// Override here the needed methods from ContentTranslationHandler. |
||||||
|
|
||||||
|
} |
@ -0,0 +1,46 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace Drupal\reserve\Tests; |
||||||
|
|
||||||
|
use Drupal\Core\Url; |
||||||
|
use Drupal\simpletest\WebTestBase; |
||||||
|
|
||||||
|
/** |
||||||
|
* Simple test to ensure that main page loads with module enabled. |
||||||
|
* |
||||||
|
* @group reserve |
||||||
|
*/ |
||||||
|
class LoadTest extends WebTestBase{ |
||||||
|
|
||||||
|
/** |
||||||
|
* Modules to enable. |
||||||
|
* |
||||||
|
* @var array |
||||||
|
*/ |
||||||
|
public static $modules = ['reserve']; |
||||||
|
|
||||||
|
/** |
||||||
|
* A user with permission to administer site configuration. |
||||||
|
* |
||||||
|
* @var \Drupal\user\UserInterface |
||||||
|
*/ |
||||||
|
protected $user; |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
protected function setUp() { |
||||||
|
parent::setUp(); |
||||||
|
$this->user = $this->drupalCreateUser(['administer site configuration']); |
||||||
|
$this->drupalLogin($this->user); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Tests that the home page loads with a 200 response. |
||||||
|
*/ |
||||||
|
public function testLoad() { |
||||||
|
$this->drupalGet(Url::fromRoute('<front>')); |
||||||
|
$this->assertResponse(200); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,37 @@ |
|||||||
|
<div id="rooms-calendar"> |
||||||
|
<div id="tabbedPanels"> |
||||||
|
<div id="info"> |
||||||
|
<div>{{ calendar_header }}</div> |
||||||
|
<hr> |
||||||
|
<div id="start">{{ reservation_instructions }}</div> |
||||||
|
</div> |
||||||
|
<br> |
||||||
|
<h3 class="date">{{ 'Reservation Calendar'|t }}</h3> |
||||||
|
<div class="hours">{{ date }} </div> |
||||||
|
<div class="hours">{{ building_hours_display }}</div> |
||||||
|
|
||||||
|
<div class="reserve-center"><img id="arrow" src="{{ arrow }}" /></div> |
||||||
|
<div id="date-change">{{ date_picker }}</div> |
||||||
|
|
||||||
|
<!-- Tabs --> |
||||||
|
<ul class="room-tabs"> |
||||||
|
{% for cat in categories %} |
||||||
|
<li><a class="{{ cat.active }}" href="#{{ cat.tag }}">{{ cat.title }}</a></li> |
||||||
|
{% endfor %} |
||||||
|
</ul> |
||||||
|
|
||||||
|
<div class="panelContainer"> |
||||||
|
{% for cat1 in categories %} |
||||||
|
<div id="{{ cat1.tag }}" class="panel {{ cat1.show }}"> |
||||||
|
<div class="gcolumns {{ orientclass }}"> |
||||||
|
{# $table from D7 #} |
||||||
|
{{ cat1.table }} |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
{% endfor %} |
||||||
|
</div> |
||||||
|
|
||||||
|
<div class="clear"></div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
@ -0,0 +1,22 @@ |
|||||||
|
{# |
||||||
|
/** |
||||||
|
* @file reserve_category.html.twig |
||||||
|
* Default theme implementation to present Reservation Category data. |
||||||
|
* |
||||||
|
* This template is used when viewing Reservation Category pages. |
||||||
|
* |
||||||
|
* |
||||||
|
* Available variables: |
||||||
|
* - content: A list of content items. Use 'content' to print all content, or |
||||||
|
* - attributes: HTML attributes for the container element. |
||||||
|
* |
||||||
|
* @see template_preprocess_reserve_category() |
||||||
|
* |
||||||
|
* @ingroup themeable |
||||||
|
*/ |
||||||
|
#} |
||||||
|
<div{{ attributes.addClass('reserve_category') }}> |
||||||
|
{% if content %} |
||||||
|
{{- content -}} |
||||||
|
{% endif %} |
||||||
|
</div> |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue