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