";
+
+ $elements['add_more'] = [
+ '#type' => 'container',
+ 'add_more' => [
+ '#type' => 'link',
+ '#title' => t('Add item'),
+ '#url' => Url::fromRoute('openy_ds_playlist_item.modal_add', [
+ 'openy_digital_signage_playlist' => $playlist->id(),
+ 'js' => 'nojs',
+ ]),
+ '#attributes' => [
+ 'class' => [
+ 'use-ajax',
+ 'button',
+ 'field-add-more-submit',
+ ],
+ ],
+ ],
+ 'refresh' => [
+ '#type' => 'submit',
+ '#value' => $this->t('Refresh'),
+ '#name' => 'refresh-playlist-item',
+ '#submit' => [[get_class($this), 'refreshSubmit']],
+ '#attributes' => [
+ 'class' => ['button-playlist_items-refresh', 'js-hide'],
+ ],
+ '#ajax' => [
+ 'callback' => [get_class($this), 'ajaxItemRefreshCallback'],
+ 'wrapper' => $new_wrapper_id,
+ 'effect' => 'fade',
+ 'progress' => ['type' => 'none'],
+ ],
+ ],
+ ];
+ $elements['assign_to_screen'] = [
+ '#type' => 'container',
+ 'assign_to_screen' => [
+ '#type' => 'link',
+ '#title' => t('Assign to screen'),
+ '#url' => Url::fromRoute('openy_ds_playlist_item.add_schedule_item', [
+ 'openy_digital_signage_playlist' => $playlist->id(),
+ 'js' => 'nojs',
+ ]),
+ '#attributes' => [
+ 'class' => [
+ 'use-ajax',
+ 'button',
+ 'field-add-more-submit',
+ ],
+ ],
+ ],
+ ];
+
+ return $elements;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function extractFormValues(FieldItemListInterface $items, array $form, FormStateInterface $form_state) {
+ if ($this->isDefaultValueWidget($form_state)) {
+ $items->filterEmptyItems();
+ return;
+ }
+
+ $field_name = $this->fieldDefinition->getName();
+ $parents = array_merge($form['#parents'], [$field_name]);
+ $submitted_values = $form_state->getValue($parents);
+ $values = [];
+ foreach ($items as $delta => $value) {
+ $element = NestedArray::getValue($form, [$field_name, 'widget', $delta]);
+ $entity = isset($element['#entity']) ? $element['#entity'] : NULL;
+ $weight = isset($submitted_values[$delta]['_weight']) ? $submitted_values[$delta]['_weight'] : 0;
+ $values[$weight] = ['entity' => $entity];
+ }
+
+ // Sort items base on weights.
+ ksort($values);
+ $values = array_values($values);
+
+ // Let the widget massage the submitted values.
+ $values = $this->massageFormValues($values, $form, $form_state);
+
+ // Assign the values and remove the empty ones.
+ $items->setValue($values);
+ $items->filterEmptyItems();
+
+ // Put delta mapping in $form_state, so that flagErrors() can use it.
+ $field_name = $this->fieldDefinition->getName();
+ $field_state = WidgetBase::getWidgetState($form['#parents'], $field_name, $form_state);
+ foreach ($items as $delta => $item) {
+ $field_state['original_deltas'][$delta] = isset($item->_original_delta) ? $item->_original_delta : $delta;
+ unset($item->_original_delta, $item->weight);
+ }
+ WidgetBase::setWidgetState($form['#parents'], $field_name, $form_state, $field_state);
+ }
+
+ /**
+ * Ajax callback for the refresh item action.
+ */
+ public static function ajaxItemRefreshCallback(array $form, FormStateInterface $form_state) {
+ $element = $form_state->getTriggeringElement();
+ // Go 3 level up in the form, to the widgets container.
+ $array_parents = array_slice($element['#array_parents'], 0, -3);
+ $element = NestedArray::getValue($form, $array_parents);
+
+ return $element;
+ }
+
+ /**
+ * Submit callback for ajax buttons.
+ */
+ public static function refreshSubmit(array $form, FormStateInterface &$form_state) {
+ $form_state->disableCache();
+ $form_state->setRebuild();
+ }
+
+}
diff --git a/modules/openy_digital_signage_playlist/src/Plugin/Field/FieldWidget/TimeOnlyWidget.php b/modules/openy_digital_signage_playlist/src/Plugin/Field/FieldWidget/TimeOnlyWidget.php
new file mode 100644
index 0000000..37dadc2
--- /dev/null
+++ b/modules/openy_digital_signage_playlist/src/Plugin/Field/FieldWidget/TimeOnlyWidget.php
@@ -0,0 +1,36 @@
+dateStorage->load('html_time')->getPattern();
+ $element['value']['#date_time_element'] = 'time';
+ $element['value']['#title'] = $this->fieldDefinition->getLabel();
+ $element['value']['#description'] = $this->fieldDefinition->getDescription();
+ $element["#theme_wrappers"] = [];
+ return $element;
+ }
+
+}
diff --git a/modules/openy_digital_signage_playlist/src/Plugin/ScheduleItemDataType/Playlist.php b/modules/openy_digital_signage_playlist/src/Plugin/ScheduleItemDataType/Playlist.php
new file mode 100644
index 0000000..301b199
--- /dev/null
+++ b/modules/openy_digital_signage_playlist/src/Plugin/ScheduleItemDataType/Playlist.php
@@ -0,0 +1,23 @@
+
+ {% if teaser %}
+ {# Teaser markup #}
+
+
+ {% if type == 'media' %}
+ {{- content.media -}}
+ {% else %}
+
+ Playlist
+
+ {% endif %}
+
+
+ {% if type == 'media' %}
+ {{- content.name -}}
+ {% else %}
+
+ {{ entity.playlist.entity.name.value }}
+
+ {% endif %}
+
+
+ {{- content.type -}}
+
+ {% if type == 'playlist' %}
+ {% set count = entity.playlist.entity.field_items.getvalue|length %}
+ {% trans %}
+ ({{ count }} item)
+ {% plural count %}
+ ({{ count }} items)
+ {% endtrans %}
+ {% endif %}
+
+
+ {% if type == 'playlist' %}
+ {{ 'auto'|t }}
+ {% else %}
+ {{- content.duration -}}
+ {% endif %}
+
+
+ {% if entity.date_start.value %}
+ {{- content.date_start -}}
+ {% else %}
+ —
+ {% endif %}
+
+ {% if entity.date_end.value %}
+ {{- content.date_end -}}
+ {% else %}
+ —
+ {% endif %}
+
+
+ {% if entity.time_start.value %}
+ {{- content.time_start -}}
+ {% else %}
+ —
+ {% endif %}
+
+ {% if entity.time_end.value %}
+ {{- content.time_end -}}
+ {% else %}
+ —
+ {% endif %}
+
+
+ {% else %}
+
+ {# Default markup #}
+ {% if content %}
+ {{- content -}}
+ {% endif %}
+
+ {% endif %}
+
+
diff --git a/modules/openy_digital_signage_playlist/templates/openy_digital_signage_playlist.html.twig b/modules/openy_digital_signage_playlist/templates/openy_digital_signage_playlist.html.twig
new file mode 100644
index 0000000..18f5dd3
--- /dev/null
+++ b/modules/openy_digital_signage_playlist/templates/openy_digital_signage_playlist.html.twig
@@ -0,0 +1,22 @@
+{#
+/**
+ * @file openy_digital_signage_playlist.html.twig
+ * Default theme implementation to present Digital Signage Playlist data.
+ *
+ * This template is used when viewing Digital Signage Playlist 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_openy_digital_signage_playlist()
+ *
+ * @ingroup themeable
+ */
+#}
+moduleHandler->alter('openy_digital_signage_screen_view', $build, $entity);
+
return $build;
}
diff --git a/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/config/install/core.entity_form_display.block_content.digital_signage_block_free_html.default.yml b/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/config/install/core.entity_form_display.block_content.digital_signage_block_free_html.default.yml
index c242d1d..91783b5 100644
--- a/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/config/install/core.entity_form_display.block_content.digital_signage_block_free_html.default.yml
+++ b/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/config/install/core.entity_form_display.block_content.digital_signage_block_free_html.default.yml
@@ -3,9 +3,9 @@ status: true
dependencies:
config:
- block_content.type.digital_signage_block_free_html
+ - entity_browser.browser.digital_signage_images_library
- field.field.block_content.digital_signage_block_free_html.body
- - field.field.block_content.digital_signage_block_free_html.field_ds_background_image
- - entity_browser.browser.images_library
+ - field.field.block_content.digital_signage_block_free_html.field_ds_background_image_media
module:
- entity_browser
- text
@@ -23,17 +23,17 @@ content:
placeholder: ''
third_party_settings: { }
region: content
- field_ds_background_image:
+ field_ds_background_image_media:
weight: 1
settings:
- entity_browser: images_library
+ entity_browser: digital_signage_images_library
field_widget_display: rendered_entity
field_widget_edit: true
field_widget_remove: true
+ open: true
selection_mode: selection_append
field_widget_display_settings:
- view_mode: thumbnail_for_preview
- open: false
+ view_mode: teaser
third_party_settings: { }
type: entity_browser_entity_reference
region: content
diff --git a/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/config/install/core.entity_form_display.block_content.digital_signage_promotional.default.yml b/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/config/install/core.entity_form_display.block_content.digital_signage_promotional.default.yml
index 0496f16..e772e84 100644
--- a/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/config/install/core.entity_form_display.block_content.digital_signage_promotional.default.yml
+++ b/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/config/install/core.entity_form_display.block_content.digital_signage_promotional.default.yml
@@ -3,8 +3,9 @@ status: true
dependencies:
config:
- block_content.type.digital_signage_promotional
+ - entity_browser.browser.digital_signage_images_library
- field.field.block_content.digital_signage_promotional.field_ds_background_color
- - field.field.block_content.digital_signage_promotional.field_ds_background_image
+ - field.field.block_content.digital_signage_promotional.field_ds_background_image_media
- field.field.block_content.digital_signage_promotional.field_ds_background_position
- field.field.block_content.digital_signage_promotional.field_ds_background_scheme
- field.field.block_content.digital_signage_promotional.field_ds_background_size
@@ -14,10 +15,9 @@ dependencies:
- field.field.block_content.digital_signage_promotional.field_ds_message
- field.field.block_content.digital_signage_promotional.field_ds_message_position
- field.field.block_content.digital_signage_promotional.field_ds_subheading
- - entity_browser.browser.images_library
module:
- - field_group
- entity_browser
+ - field_group
third_party_settings:
field_group:
group_ds_layout:
@@ -36,7 +36,7 @@ third_party_settings:
group_ds_background:
children:
- field_ds_background_color
- - field_ds_background_image
+ - field_ds_background_image_media
- field_ds_background_position
- field_ds_background_size
parent_name: ''
@@ -74,22 +74,22 @@ content:
third_party_settings: { }
type: string_textfield
region: content
- field_ds_background_image:
- weight: 6
+ field_ds_background_image_media:
+ weight: 7
settings:
- entity_browser: images_library
+ entity_browser: digital_signage_images_library
field_widget_display: rendered_entity
field_widget_edit: true
field_widget_remove: true
+ open: true
selection_mode: selection_append
field_widget_display_settings:
view_mode: thumbnail_for_preview
- open: false
third_party_settings: { }
type: entity_browser_entity_reference
region: content
field_ds_background_position:
- weight: 7
+ weight: 8
settings: { }
third_party_settings: { }
type: options_select
@@ -101,7 +101,7 @@ content:
type: options_buttons
region: content
field_ds_background_size:
- weight: 8
+ weight: 9
settings: { }
third_party_settings: { }
type: options_buttons
diff --git a/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/config/install/core.entity_view_display.block_content.digital_signage_block_free_html.default.yml b/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/config/install/core.entity_view_display.block_content.digital_signage_block_free_html.default.yml
index d81e3ed..8dc3582 100644
--- a/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/config/install/core.entity_view_display.block_content.digital_signage_block_free_html.default.yml
+++ b/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/config/install/core.entity_view_display.block_content.digital_signage_block_free_html.default.yml
@@ -4,7 +4,7 @@ dependencies:
config:
- block_content.type.digital_signage_block_free_html
- field.field.block_content.digital_signage_block_free_html.body
- - field.field.block_content.digital_signage_block_free_html.field_ds_background_image
+ - field.field.block_content.digital_signage_block_free_html.field_ds_background_image_media
module:
- text
id: block_content.digital_signage_block_free_html.default
@@ -18,6 +18,7 @@ content:
label: hidden
settings: { }
third_party_settings: { }
+ region: content
field_ds_background_image:
type: entity_reference_entity_view
weight: 1
@@ -26,5 +27,14 @@ content:
view_mode: default
link: false
third_party_settings: { }
+ region: content
+ field_ds_background_image_media:
+ weight: 2
+ label: above
+ settings:
+ link: true
+ third_party_settings: { }
+ type: entity_reference_label
+ region: content
hidden:
langcode: true
diff --git a/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/config/install/core.entity_view_display.block_content.digital_signage_promotional.default.yml b/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/config/install/core.entity_view_display.block_content.digital_signage_promotional.default.yml
index 4917b74..c221e07 100644
--- a/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/config/install/core.entity_view_display.block_content.digital_signage_promotional.default.yml
+++ b/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/config/install/core.entity_view_display.block_content.digital_signage_promotional.default.yml
@@ -4,7 +4,7 @@ dependencies:
config:
- block_content.type.digital_signage_promotional
- field.field.block_content.digital_signage_promotional.field_ds_background_color
- - field.field.block_content.digital_signage_promotional.field_ds_background_image
+ - field.field.block_content.digital_signage_promotional.field_ds_background_image_media
- field.field.block_content.digital_signage_promotional.field_ds_background_position
- field.field.block_content.digital_signage_promotional.field_ds_background_scheme
- field.field.block_content.digital_signage_promotional.field_ds_background_size
@@ -30,6 +30,14 @@ content:
third_party_settings: { }
type: image
region: content
+ field_ds_background_image_media:
+ weight: 4
+ label: above
+ settings:
+ link: true
+ third_party_settings: { }
+ type: entity_reference_label
+ region: content
field_ds_headline:
weight: 1
label: hidden
diff --git a/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/config/install/field.field.block_content.digital_signage_block_free_html.field_ds_background_image_media.yml b/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/config/install/field.field.block_content.digital_signage_block_free_html.field_ds_background_image_media.yml
new file mode 100644
index 0000000..ec0d398
--- /dev/null
+++ b/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/config/install/field.field.block_content.digital_signage_block_free_html.field_ds_background_image_media.yml
@@ -0,0 +1,27 @@
+langcode: en
+status: true
+dependencies:
+ config:
+ - block_content.type.digital_signage_block_free_html
+ - field.storage.block_content.field_ds_background_image_media
+ - media_entity.bundle.image
+id: block_content.digital_signage_block_free_html.field_ds_background_image_media
+field_name: field_ds_background_image_media
+entity_type: block_content
+bundle: digital_signage_block_free_html
+label: 'Background image'
+description: 'This image is used as a background for the content on the screen.'
+required: false
+translatable: true
+default_value: { }
+default_value_callback: ''
+settings:
+ handler: 'default:media'
+ handler_settings:
+ target_bundles:
+ image: image
+ sort:
+ field: _none
+ auto_create: false
+ auto_create_bundle: ''
+field_type: entity_reference
diff --git a/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/config/install/field.field.block_content.digital_signage_promotional.field_ds_background_image_media.yml b/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/config/install/field.field.block_content.digital_signage_promotional.field_ds_background_image_media.yml
new file mode 100644
index 0000000..8da6b48
--- /dev/null
+++ b/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/config/install/field.field.block_content.digital_signage_promotional.field_ds_background_image_media.yml
@@ -0,0 +1,27 @@
+langcode: en
+status: true
+dependencies:
+ config:
+ - block_content.type.digital_signage_promotional
+ - field.storage.block_content.field_ds_background_image_media
+ - media_entity.bundle.image
+id: block_content.digital_signage_promotional.field_ds_background_image_media
+field_name: field_ds_background_image_media
+entity_type: block_content
+bundle: digital_signage_promotional
+label: 'Background image'
+description: 'This image is used as a background for the content on the screen.'
+required: false
+translatable: false
+default_value: { }
+default_value_callback: ''
+settings:
+ handler: 'default:media'
+ handler_settings:
+ target_bundles:
+ image: image
+ sort:
+ field: _none
+ auto_create: false
+ auto_create_bundle: ''
+field_type: entity_reference
diff --git a/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/config/install/field.storage.block_content.field_ds_background_image_media.yml b/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/config/install/field.storage.block_content.field_ds_background_image_media.yml
new file mode 100644
index 0000000..52793af
--- /dev/null
+++ b/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/config/install/field.storage.block_content.field_ds_background_image_media.yml
@@ -0,0 +1,19 @@
+langcode: en
+status: true
+dependencies:
+ module:
+ - block_content
+ - media_entity
+id: block_content.field_ds_background_image_media
+field_name: field_ds_background_image_media
+entity_type: block_content
+type: entity_reference
+settings:
+ target_type: media
+module: core
+locked: false
+cardinality: 1
+translatable: true
+indexes: { }
+persist_with_no_fields: false
+custom_storage: false
diff --git a/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/css/complete-schedule.css b/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/css/complete-schedule.css
new file mode 100644
index 0000000..307abaa
--- /dev/null
+++ b/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/css/complete-schedule.css
@@ -0,0 +1,120 @@
+.block-complete-schedule {
+ font-size: 1.625vw;
+ line-height: 1.2;
+ font-family: "Cachet W01 Book", Verdana, sans-serif;
+ background-color: #636466;
+}
+
+.schedule-header {
+ background-color: #333333;
+ color: #ffffff;
+}
+
+.schedule-table {
+ color: #ffffff;
+ display: flex;
+ flex-direction: column;
+ min-height: 100vh;
+}
+
+.schedule-table-ongoing, .schedule-table-upcoming {
+ text-align: center;
+ text-transform: uppercase;
+ font-weight: 700;
+ font-size: 150%;
+}
+
+.schedule-table-ongoing {
+ order: -2;
+}
+
+.schedule-table-upcoming {
+ order: 1;
+}
+
+.schedule-row {
+ display: flex;
+ position: relative;
+}
+
+.schedule-row-class {
+ transition: height 500ms;
+ order: 2;
+ border-top: 0.5px solid rgba(0, 0, 0, 0.25);
+ border-bottom: 0.5px solid rgba(0, 0, 0, 0.25);
+}
+.schedule-row-class-past {
+ height: 0;
+ border: none;
+}
+
+.schedule-row-class-ongoing {
+ order: -1;
+}
+
+.schedule-row-column {
+ display: block;
+ flex-basis: 0;
+ flex-grow: 2;
+ padding: 0.1vw 0.8vw;
+ z-index: 2;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ white-space: nowrap;
+}
+
+.class-trainer {
+ text-align: center;
+}
+
+.trainer__substitute__icon {}
+
+.trainer__substituted {}
+
+.class-name {
+ flex-grow: 5;
+}
+
+.class-time-frame {
+ flex-grow: 1;
+ text-align: right;
+ padding-right: 0;
+}
+
+.class-time-frame-from {}
+
+.class-duration {
+ flex-grow: 1;
+}
+
+span.class-duration:before {
+ content: "(";
+ padding-right: 0.2vw;
+}
+
+span.class-duration:after {
+ content: ")";
+ padding-left: 0.2vw;
+}
+
+.class-room {
+ flex-grow: 3;
+}
+
+.class-progress {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+}
+
+.class-progress-bar {
+ top: 0;
+ left: 0;
+ width: 0%;
+ /*background-color: #0060af;*/
+ background-color: rgba(0, 96, 175, 0.5);
+ height: 100%;
+ z-index: 1;
+}
diff --git a/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/js/class-current.js b/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/js/class-current.js
index 0ca9479..cf03fc7 100644
--- a/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/js/class-current.js
+++ b/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/js/class-current.js
@@ -337,10 +337,13 @@
var countdown_is_visible = parseFloat($('.class-time-countdown', activeClass).css('opacity'));
var height_percent = countdown_is_visible === 0 ? 31 : 27;
var size = parseInt($('.class-name', activeClass).css('font-size').slice(0, -2));
+ var original_size = size;
+ var transition = $('.class-name', activeClass).css('transition');
var class_height = activeClass.height();
var class_name_height = $('.class-name', activeClass).height();
var percent = Math.round((class_name_height * 100) / class_height);
var i = 0;
+ $('.class-name', activeClass).css('transition', 'none');
do {
size -=1;
$('.class-name', activeClass).css('font-size', size);
@@ -349,6 +352,10 @@
i++;
}
while (percent > height_percent && i < 30);
+ $('.class-name', activeClass)
+ .css('font-size', original_size)
+ .css('transition', transition)
+ .css('font-size', size);
};
return this;
diff --git a/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/js/complete-schedule.js b/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/js/complete-schedule.js
new file mode 100644
index 0000000..4c3b1a1
--- /dev/null
+++ b/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/js/complete-schedule.js
@@ -0,0 +1,170 @@
+/**
+ * @file
+ * Block behaviors.
+ */
+(function ($, window, Drupal) {
+
+ 'use strict';
+
+ /**
+ * Block current class storage.
+ */
+ Drupal.openyDigitalSignageBlocks.currentClass = Drupal.openyDigitalSignageBlocks.currentClass || {};
+
+ /**
+ * Static bar specific behaviour.
+ *
+ * @type {Drupal~behavior}
+ *
+ * @prop {Drupal~behaviorAttach} attach
+ * Attaches the behavior for the block.
+ */
+ Drupal.behaviors.openyDigitalSignageBlockClassCurrent = {
+ attach: function (context, settings) {
+ $('.block-complete-schedule', context).once().each(function () {
+ if (!(Drupal.openyDigitalSignageBlocks.completeSchedule instanceof OpenYDigitalSignageBlockCompleteSchedule)) {
+ Drupal.openyDigitalSignageBlocks.completeSchedule = new OpenYDigitalSignageBlockCompleteSchedule(this);
+ }
+ Drupal.openyDigitalSignageBlocks.completeSchedule.deactivate();
+ Drupal.openyDigitalSignageBlocks.completeSchedule.updateContext(this);
+ Drupal.openyDigitalSignageBlocks.completeSchedule.init();
+ });
+ }
+ };
+
+ /**
+ * Block current class handler.
+ *
+ * @param context
+ * Block.
+ *
+ * @returns {OpenYDigitalSignageBlockCompleteSchedule}
+ */
+ function OpenYDigitalSignageBlockCompleteSchedule(context) {
+ var self = this;
+ this.context = context;
+ this.activated = 0;
+
+ // General loop – basically swaps classes.
+ this.loop = function () {
+
+ };
+
+ // Fast loop - basically updates the awaiting class.
+ this.fastloop = function () {
+ self.updateProgressBars();
+ };
+
+ // Formats time.
+ this.formatTime = function (seconds) {
+ var fHours, fMinutes, fSeconds, separator;
+ separator = Math.floor(seconds) % 2 ? '
:' : '
:';
+ if (seconds < 3600) {
+ fMinutes = Math.floor(seconds / 60);
+ fSeconds = Math.floor(seconds - fMinutes * 60);
+ if (fSeconds < 10) fSeconds = '0' + fSeconds;
+ if (fMinutes < 10) fMinutes = '0' + fMinutes;
+
+ return {
+ suffix: seconds > 59 ? 'minutes' : 'seconds',
+ string: fMinutes + separator + fSeconds
+ };
+ }
+
+ fHours = Math.floor(seconds / 3600);
+ fMinutes = Math.floor((seconds - fHours * 3600) / 60);
+ if (fMinutes < 10) fMinutes = '0' + fMinutes;
+
+ return {
+ suffix: 'hours',
+ string: fHours + separator + fMinutes
+ };
+ };
+
+ // Updates progress bar of the current class.
+ this.updateProgressBars = function () {
+ var $classes = $('.schedule-row-class', self.context);
+ $classes.each(function () {
+ let $class = $(this);
+ let offset = self.getTimeOffset();
+ let from = $class.data('from');
+ let to = $class.data('to');
+ let duration = to - from;
+ let progress = 100 * (offset - from) / duration;
+ let past = offset > (to + 5);
+ progress = Math.max(0, Math.min(progress, 100));
+ $(this)
+ .find('.class-progress-bar')
+ .css('width', progress + '%')
+ if (offset >= from && offset <= to) {
+ $(this).addClass('schedule-row-class-ongoing');
+ }
+ if (past) {
+ $(this).addClass('schedule-row-class-past');
+ }
+ });
+ };
+
+ /**
+ * Returns current time.
+ */
+ this.getTimeOffset = function () {
+ return window.tm.getTime();
+ };
+
+ /**
+ * Activates the block.
+ */
+ this.activate = function () {
+ self.fastloop();
+ self.timer = setInterval(self.loop, 5000);
+ self.fasttimer = setInterval(self.fastloop, 1000 / window.tm.speed);
+ self.activated = self.getTimeOffset();
+ };
+
+ /**
+ * Deactivates the block.
+ */
+ this.deactivate = function () {
+ clearInterval(self.timer);
+ clearInterval(self.fasttimer);
+ self.activated = 0;
+ };
+
+ /**
+ * Initialize block.
+ */
+ this.init = function () {
+ self.blockObject = ObjectsManager.getObject(self.context);
+ self.blockObject.activate = self.activate;
+ self.blockObject.deactivate = self.deactivate;
+ if (self.blockObject.isActive() || $(self.context).parents('.screen').length === 0) {
+ self.activate();
+ }
+ };
+
+ /**
+ * Check is block active and initialized or not.
+ *
+ * @returns {boolean}
+ * Status.
+ */
+ this.isActive = function () {
+ return self.activated !== 0;
+ };
+
+ /**
+ * Update class context.
+ *
+ * @param context
+ * Block.
+ */
+ this.updateContext = function (context) {
+ this.context = context;
+ self = this;
+ };
+
+ return this;
+ }
+
+})(jQuery, window, Drupal);
diff --git a/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/openy_digital_signage_blocks.info.yml b/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/openy_digital_signage_blocks.info.yml
index 131065c..96abb11 100644
--- a/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/openy_digital_signage_blocks.info.yml
+++ b/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/openy_digital_signage_blocks.info.yml
@@ -6,3 +6,4 @@ package: "OpenY: Digital Signage"
dependencies:
- openy_digital_signage_screen_content
- openy_digital_signage_room
+
diff --git a/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/openy_digital_signage_blocks.install b/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/openy_digital_signage_blocks.install
index a2acb93..5ff6c9a 100644
--- a/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/openy_digital_signage_blocks.install
+++ b/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/openy_digital_signage_blocks.install
@@ -102,6 +102,41 @@ function openy_digital_signage_blocks_install() {
$config->save();
}
+/**
+ * Replace the 'field_ds_background_image' file field with Media.
+ */
+function openy_digital_signage_blocks_update_8001(&$sandbox) {
+ // @todo migrate files from the old field to the new field.
+ /* @var $entityFieldManager Drupal\Core\Entity\EntityFieldManager */
+ $entityFieldManager = Drupal::service('entity_field.manager');
+
+ $ds_bundles = [
+ OPENY_DS_BLOCK_PROMOTIONAL,
+ OPENY_DS_BLOCK_HTML_BUNDLE,
+ ];
+
+ foreach ($ds_bundles as $bundle) {
+ $fields = $entityFieldManager->getFieldDefinitions('block_content', $bundle);
+
+ if (isset($fields['field_ds_background_image'])) {
+ $fields['field_ds_background_image']->delete();
+ }
+ }
+
+ $config_dir = drupal_get_path('module', 'openy_digital_signage_blocks') . '/config/install';
+ $config_importer = \Drupal::service('openy_upgrade_tool.importer');
+ $config_importer->setDirectory($config_dir);
+ $config_importer->importConfigs([
+ 'core.entity_form_display.block_content.digital_signage_block_free_html.default',
+ 'core.entity_form_display.block_content.digital_signage_promotional.default',
+ 'core.entity_view_display.block_content.digital_signage_block_free_html.default',
+ 'core.entity_view_display.block_content.digital_signage_promotional.default',
+ 'field.field.block_content.digital_signage_block_free_html.field_ds_background_image_media',
+ 'field.field.block_content.digital_signage_promotional.field_ds_background_image_media',
+ 'field.storage.block_content.field_ds_background_image_media',
+ ]);
+}
+
/**
* Implements hook_uninstall().
*/
diff --git a/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/openy_digital_signage_blocks.libraries.yml b/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/openy_digital_signage_blocks.libraries.yml
index b434087..349a213 100644
--- a/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/openy_digital_signage_blocks.libraries.yml
+++ b/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/openy_digital_signage_blocks.libraries.yml
@@ -64,3 +64,11 @@ promotional_layout_preview:
css:
component:
css/promo-block-form-preview.css: {}
+
+complete_schedule:
+ version: VERSION
+ js:
+ js/complete-schedule.js: {}
+ css:
+ component:
+ css/complete-schedule.css: {}
diff --git a/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/openy_digital_signage_blocks.module b/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/openy_digital_signage_blocks.module
index c1d5203..fcd1713 100644
--- a/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/openy_digital_signage_blocks.module
+++ b/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/openy_digital_signage_blocks.module
@@ -66,6 +66,14 @@ function openy_digital_signage_blocks_theme($existing, $type, $theme, $path) {
'wrapper_attributes' => NULL,
],
],
+ 'openy_digital_signage_blocks_complete_schedule' => [
+ 'template' => 'openy-digital-signage-blocks-complete-schedule',
+ 'variables' => [
+ 'room' => '',
+ 'classes' => NULL,
+ 'wrapper_attributes' => NULL,
+ ],
+ ],
];
}
@@ -114,8 +122,8 @@ function openy_digital_signage_blocks_preprocess_block(&$variables) {
$attributes->addClass('block-promotional-message-position-' . $block->field_ds_message_position->value);
$attributes->addClass('block-promotional-layout-' . $block->field_ds_layout->value);
$background_styles = ['background-color: ' . $block->field_ds_background_color->value . ';'];
- if ($background_image = $block->field_ds_background_image->entity) {
- $background_styles[] = 'background-image:url(' . file_create_url($background_image->getFileUri()) . ');';
+ if ($url = openy_digital_signage_blocks_get_background_url($block)) {
+ $background_styles[] = 'background-image:url(' . $url . ');';
}
$attributes->setAttribute('style', $background_styles);
$variables['wrapper_attributes'] = $attributes;
@@ -123,12 +131,10 @@ function openy_digital_signage_blocks_preprocess_block(&$variables) {
case OPENY_DS_BLOCK_HTML_BUNDLE:
// Do not display image.
- $variables['content']['field_ds_background_image']['#access'] = FALSE;
+ $variables['content']['field_ds_background_image_media']['#access'] = FALSE;
$variables['background_image'] = '';
- if (!empty($variables['content']['field_ds_background_image'][0]['#file'])) {
- /* @var \Drupal\file_entity\Entity\FileEntity $file */
- $file = $variables['content']['field_ds_background_image'][0]['#file'];
- $variables['background_image'] = file_create_url($file->getFileUri());
+ if ($url = openy_digital_signage_blocks_get_background_url($block)) {
+ $variables['background_image'] = $url;
}
break;
}
@@ -158,10 +164,10 @@ function openy_digital_signage_blocks_form_alter(&$form, FormStateInterface $for
'#type' => 'fieldset',
'#title' => t('Background Image settings'),
'#collapsible' => TRUE,
- '#weight' => $form['field_ds_background_image']['#weight'],
+ '#weight' => $form['field_ds_background_image_media']['#weight'],
];
- $form['background_image_settings']['field_ds_background_image'] = $form['field_ds_background_image'];
- unset($form['field_ds_background_image']);
+ $form['background_image_settings']['field_ds_background_image_media'] = $form['field_ds_background_image_media'];
+ unset($form['field_ds_background_image_media']);
$form['background_image_settings']['field_ds_background_position'] = $form['field_ds_background_position'];
unset($form['field_ds_background_position']);
$form['background_image_settings']['field_ds_background_size'] = $form['field_ds_background_size'];
@@ -267,3 +273,30 @@ function openy_digital_signage_blocks_hide_text_format_switcher($form_element, F
return $form_element;
}
+
+/**
+ * Gets background file URL from media of content block.
+ *
+ * @param \Drupal\block_content\Entity\BlockContent $block
+ * DS content block.
+ *
+ * @return string|null
+ * URL or NULL.
+ */
+function openy_digital_signage_blocks_get_background_url(BlockContent $block) {
+ $ds_bundles = [
+ OPENY_DS_BLOCK_PROMOTIONAL,
+ OPENY_DS_BLOCK_HTML_BUNDLE,
+ ];
+
+ if (!in_array($block->bundle(), $ds_bundles)) {
+ return NULL;
+ }
+
+ if ($background_media = $block->field_ds_background_image_media->entity) {
+ $file = $background_media->field_media_image->entity;
+ return file_create_url($file->getFileUri());
+ }
+
+ return NULL;
+}
diff --git a/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/src/Plugin/Block/OpenYDigitalSignageBlockClassCurrent.php b/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/src/Plugin/Block/OpenYDigitalSignageBlockClassCurrent.php
index 6829b10..8e31140 100644
--- a/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/src/Plugin/Block/OpenYDigitalSignageBlockClassCurrent.php
+++ b/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/src/Plugin/Block/OpenYDigitalSignageBlockClassCurrent.php
@@ -6,7 +6,6 @@
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Template\Attribute;
-use Drupal\openy_digital_signage_classes_schedule\OpenYClassesScheduleManagerInterface;
use Drupal\openy_digital_signage_room\OpenYRoomManagerInterface;
use Drupal\openy_digital_signage_screen\OpenYScreenManagerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -26,8 +25,6 @@ class OpenYDigitalSignageBlockClassCurrent extends BlockBase implements Containe
/**
* The Classes Schedule Manager.
- *
- * @var OpenYClassesScheduleManagerInterface
*/
protected $scheduleManager;
@@ -45,6 +42,13 @@ class OpenYDigitalSignageBlockClassCurrent extends BlockBase implements Containe
*/
protected $roomManager;
+ /**
+ * The container.
+ *
+ * @var \Symfony\Component\DependencyInjection\ContainerInterface
+ */
+ protected $container;
+
/**
* OpenYDigitalSignageBlockClassCurrent constructor.
*
@@ -54,17 +58,19 @@ class OpenYDigitalSignageBlockClassCurrent extends BlockBase implements Containe
* The plugin id.
* @param mixed $plugin_definition
* The plugin definition.
- * @param \Drupal\openy_digital_signage_classes_schedule\OpenYClassesScheduleManagerInterface $schedule_manager
- * The Open Y DS Classes Schedule Manager.
+ * @param \Symfony\Component\DependencyInjection\ContainerInterface $container
+ * The container.
* @param \Drupal\openy_digital_signage_screen\OpenYScreenManagerInterface $screen_manager
* The Open Y DS Screen Manager.
+ * @param \Drupal\openy_digital_signage_room\OpenYRoomManagerInterface $room_manager
+ * The Open Y DS Room Manager.
*/
- public function __construct(array $configuration, $plugin_id, $plugin_definition, OpenYClassesScheduleManagerInterface $schedule_manager, OpenYScreenManagerInterface $screen_manager, OpenYRoomManagerInterface $room_manager) {
+ public function __construct(array $configuration, $plugin_id, $plugin_definition, ContainerInterface $container, OpenYScreenManagerInterface $screen_manager, OpenYRoomManagerInterface $room_manager) {
// Call parent construct method.
parent::__construct($configuration, $plugin_id, $plugin_definition);
- $this->scheduleManager = $schedule_manager;
$this->screenManager = $screen_manager;
$this->roomManager = $room_manager;
+ $this->container = $container;
}
/**
@@ -75,7 +81,7 @@ public static function create(ContainerInterface $container, array $configuratio
$configuration,
$plugin_id,
$plugin_definition,
- $container->get('openy_digital_signage_classes_schedule.manager'),
+ $container,
$container->get('openy_digital_signage_screen.manager'),
$container->get('openy_digital_signage_room.manager')
);
@@ -87,6 +93,8 @@ public static function create(ContainerInterface $container, array $configuratio
public function defaultConfiguration() {
return [
'room' => 0,
+ 'source' => 'pef',
+ 'category' => [],
];
}
@@ -94,6 +102,13 @@ public function defaultConfiguration() {
* {@inheritdoc}
*/
public function blockForm($form, FormStateInterface $form_state) {
+ $form['source'] = [
+ '#type' => 'select',
+ '#title' => $this->t('Data source'),
+ '#description' => $this->t('Specify where the class schedule comes from'),
+ '#default_value' => $this->getDataSource(),
+ '#options' => $this->getSourceOptions(),
+ ];
$form['room'] = [
'#type' => 'select',
'#title' => $this->t('Room'),
@@ -101,6 +116,27 @@ public function blockForm($form, FormStateInterface $form_state) {
'#default_value' => $this->configuration['room'],
'#options' => $this->roomManager->getAllRoomOptions(),
];
+ $form['category'] = [
+ '#type' => 'select',
+ '#multiple' => TRUE,
+ '#chosen' => TRUE,
+ '#title' => $this->t('Category'),
+ '#description' => $this->t('Additionally filter schedule by activity category'),
+ '#default_value' => $this->getCategories(),
+ '#options' => $this->getAllCategoryOptions(),
+ '#states' => [
+ 'visible' => [
+ '[name="settings[source]"' => ['value' => 'pef'],
+ ],
+ ],
+ ];
+
+ // Prevents the chosen dropdown from being cut off.
+ $form['styles'] = [
+ '#type' => 'inline_template',
+ '#template' => "",
+ ];
+
return $form;
}
@@ -108,7 +144,12 @@ public function blockForm($form, FormStateInterface $form_state) {
* {@inheritdoc}
*/
public function blockSubmit($form, FormStateInterface $form_state) {
+ $this->configuration['source'] = $form_state->getValue('source');
$this->configuration['room'] = $form_state->getValue('room');
+ $this->configuration['category'] = [];
+ if ($this->configuration['source'] == 'pef') {
+ $this->configuration['category'] = array_filter($form_state->getValue('category'));
+ }
}
/**
@@ -120,8 +161,21 @@ public function build() {
$attributes->addClass('block-class-current');
$period = $this->getSchedulePeriod();
+
+ $classes = [];
if ($room = $this->getRoom()) {
- $classes = $this->scheduleManager->getClassesSchedule($period, $room);
+ if ($this->getDataSource() == 'pef') {
+ if ($this->container->has('openy_ds_pef_schedule.manager')) {
+ $this->scheduleManager = $this->container->get('openy_ds_pef_schedule.manager');
+ $classes = $this->scheduleManager->getClassesSchedule($period, $this->scheduleManager->getNextDayAlways(), null, [$room], $this->getCategories());
+ }
+ }
+ else {
+ if ($this->container->has('openy_digital_signage_classes_schedule.manager')) {
+ $this->scheduleManager = $this->container->get('openy_digital_signage_classes_schedule.manager');
+ $classes = $this->scheduleManager->getClassesSchedule($period, $room, $this->getCategories());
+ }
+ }
}
else {
$classes = $this->getDummyClassesSchedule($period);
@@ -159,6 +213,67 @@ private function getRoom() {
return $screen_room ? $screen_room->id() : $this->configuration['room'];
}
+ /**
+ * Retrieves data source.
+ *
+ * @return int|null
+ * The room id context.
+ */
+ private function getDataSource() {
+ $data_source = $this->defaultConfiguration()['source'];
+ if (!empty($this->configuration['source'])) {
+ $data_source = $this->configuration['source'];
+ }
+
+ return $data_source;
+ }
+
+ /**
+ * Retrieves category configuration.
+ *
+ * @return array
+ */
+ private function getCategories() {
+ $category = $this->defaultConfiguration()['category'];
+ if (!empty($this->configuration['category'])) {
+ $category = $this->configuration['category'];
+ }
+
+ return $category;
+ }
+
+ /**
+ * Returns available datasource options.
+ *
+ * @return array
+ */
+ public function getSourceOptions() {
+ $options = [];
+ if ($this->container->has('openy_ds_pef_schedule.manager')) {
+ $options['pef'] = $this->t('Program Event Framework');
+ }
+ if ($this->container->has('openy_digital_signage_classes_schedule.manager')) {
+ $options['ds'] = $this->t('Open Y Digital Signage classes and session');
+ }
+
+ return $options;
+ }
+
+ /**
+ * Retrieves all available category options.
+ *
+ * @return array
+ */
+ public function getAllCategoryOptions() {
+ $categories = [];
+ if ($this->container->has('openy_ds_pef_schedule.manager')) {
+ $this->scheduleManager = $this->container->get('openy_ds_pef_schedule.manager');
+ $categories = $this->scheduleManager->getAllCategories();
+ }
+
+ return $categories;
+ }
+
/**
* Retrieve schedule period.
*
diff --git a/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/src/Plugin/Block/OpenYDigitalSignageBlockClassTicker.php b/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/src/Plugin/Block/OpenYDigitalSignageBlockClassTicker.php
index 505a4ec..d857a1f 100644
--- a/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/src/Plugin/Block/OpenYDigitalSignageBlockClassTicker.php
+++ b/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/src/Plugin/Block/OpenYDigitalSignageBlockClassTicker.php
@@ -6,7 +6,6 @@
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Template\Attribute;
-use Drupal\openy_digital_signage_classes_schedule\OpenYClassesScheduleManagerInterface;
use Drupal\openy_digital_signage_room\OpenYRoomManagerInterface;
use Drupal\openy_digital_signage_screen\Entity\OpenYScreenInterface;
use Drupal\openy_digital_signage_screen\OpenYScreenManagerInterface;
@@ -27,8 +26,6 @@ class OpenYDigitalSignageBlockClassTicker extends BlockBase implements Container
/**
* The Classes Schedule Manager.
- *
- * @var OpenYClassesScheduleManagerInterface
*/
protected $scheduleManager;
@@ -46,6 +43,13 @@ class OpenYDigitalSignageBlockClassTicker extends BlockBase implements Container
*/
protected $roomManager;
+ /**
+ * The container.
+ *
+ * @var \Symfony\Component\DependencyInjection\ContainerInterface
+ */
+ protected $container;
+
/**
* OpenYDigitalSignageBlockClassTicker constructor.
*
@@ -55,17 +59,19 @@ class OpenYDigitalSignageBlockClassTicker extends BlockBase implements Container
* The plugin id.
* @param mixed $plugin_definition
* The plugin definition.
- * @param \Drupal\openy_digital_signage_classes_schedule\OpenYClassesScheduleManagerInterface $schedule_manager
- * The Open Y DS Classes Schedule Manager.
+ * @param \Symfony\Component\DependencyInjection\ContainerInterface $container
+ * The container.
* @param \Drupal\openy_digital_signage_screen\OpenYScreenManagerInterface $screen_manager
* The Open Y DS Screen Manager.
+ * @param \Drupal\openy_digital_signage_room\OpenYRoomManagerInterface $room_manager
+ * The Open Y DS Room Manager.
*/
- public function __construct(array $configuration, $plugin_id, $plugin_definition, OpenYClassesScheduleManagerInterface $schedule_manager, OpenYScreenManagerInterface $screen_manager, OpenYRoomManagerInterface $room_manager) {
+ public function __construct(array $configuration, $plugin_id, $plugin_definition, ContainerInterface $container, OpenYScreenManagerInterface $screen_manager, OpenYRoomManagerInterface $room_manager) {
// Call parent construct method.
parent::__construct($configuration, $plugin_id, $plugin_definition);
- $this->scheduleManager = $schedule_manager;
$this->screenManager = $screen_manager;
$this->roomManager = $room_manager;
+ $this->container = $container;
}
/**
@@ -76,7 +82,7 @@ public static function create(ContainerInterface $container, array $configuratio
$configuration,
$plugin_id,
$plugin_definition,
- $container->get('openy_digital_signage_classes_schedule.manager'),
+ $container,
$container->get('openy_digital_signage_screen.manager'),
$container->get('openy_digital_signage_room.manager')
);
@@ -88,6 +94,8 @@ public static function create(ContainerInterface $container, array $configuratio
public function defaultConfiguration() {
return [
'room' => 0,
+ 'source' => 'pef',
+ 'category' => [],
];
}
@@ -95,6 +103,13 @@ public function defaultConfiguration() {
* {@inheritdoc}
*/
public function blockForm($form, FormStateInterface $form_state) {
+ $form['source'] = [
+ '#type' => 'select',
+ '#title' => $this->t('Data source'),
+ '#description' => $this->t('Specify where the class schedule comes from'),
+ '#default_value' => $this->getDataSource(),
+ '#options' => $this->getSourceOptions(),
+ ];
$form['room'] = [
'#type' => 'select',
'#title' => $this->t('Room'),
@@ -102,6 +117,27 @@ public function blockForm($form, FormStateInterface $form_state) {
'#default_value' => $this->configuration['room'],
'#options' => $this->roomManager->getAllRoomOptions(),
];
+ $form['category'] = [
+ '#type' => 'select',
+ '#multiple' => TRUE,
+ '#chosen' => TRUE,
+ '#title' => $this->t('Category'),
+ '#description' => $this->t('Additionally filter schedule by activity category'),
+ '#default_value' => $this->getCategories(),
+ '#options' => $this->getAllCategoryOptions(),
+ '#states' => [
+ 'visible' => [
+ '[name="settings[source]"' => ['value' => 'pef'],
+ ],
+ ],
+ ];
+
+ // Prevents the chosen dropdown from being cut off.
+ $form['styles'] = [
+ '#type' => 'inline_template',
+ '#template' => "",
+ ];
+
return $form;
}
@@ -109,7 +145,12 @@ public function blockForm($form, FormStateInterface $form_state) {
* {@inheritdoc}
*/
public function blockSubmit($form, FormStateInterface $form_state) {
+ $this->configuration['source'] = $form_state->getValue('source');
$this->configuration['room'] = $form_state->getValue('room');
+ $this->configuration['category'] = [];
+ if ($this->configuration['source'] == 'pef') {
+ $this->configuration['category'] = array_filter($form_state->getValue('category'));
+ }
}
/**
@@ -121,8 +162,21 @@ public function build() {
$attributes->addClass('block-class-ticker');
$period = $this->getSchedulePeriod();
+
+ $classes = [];
if ($room = $this->getRoom()) {
- $classes = $this->scheduleManager->getClassesSchedule($period, $room);
+ if ($this->getDataSource() == 'pef') {
+ if ($this->container->has('openy_ds_pef_schedule.manager')) {
+ $this->scheduleManager = $this->container->get('openy_ds_pef_schedule.manager');
+ $classes = $this->scheduleManager->getClassesSchedule($period, $this->scheduleManager->getNextDayAlways(), null, [$room], $this->getCategories());
+ }
+ }
+ else {
+ if ($this->container->has('openy_digital_signage_classes_schedule.manager')) {
+ $this->scheduleManager = $this->container->get('openy_digital_signage_classes_schedule.manager');
+ $classes = $this->scheduleManager->getClassesSchedule($period, $room, $this->getCategories());
+ }
+ }
}
else {
$classes = $this->getDummyClassesSchedule($period);
@@ -153,11 +207,72 @@ public function build() {
* The room id context.
*/
private function getRoom() {
- $screen = $this->screenManager->getScreenContext();
- if ($screen && $screen->room->entity) {
- return $screen->room->entity->id();
+ if (!$screen = $this->screenManager->getScreenContext()) {
+ return $this->configuration['room'];
}
- return $this->configuration['room'];
+ $screen_room = $screen->room->entity;
+ return $screen_room ? $screen_room->id() : $this->configuration['room'];
+ }
+
+ /**
+ * Retrieves data source.
+ *
+ * @return int|null
+ * The room id context.
+ */
+ private function getDataSource() {
+ $data_source = $this->defaultConfiguration()['source'];
+ if (!empty($this->configuration['source'])) {
+ $data_source = $this->configuration['source'];
+ }
+
+ return $data_source;
+ }
+
+ /**
+ * Retrieves category configuration.
+ *
+ * @return array
+ */
+ private function getCategories() {
+ $category = $this->defaultConfiguration()['category'];
+ if (!empty($this->configuration['category'])) {
+ $category = $this->configuration['category'];
+ }
+
+ return $category;
+ }
+
+ /**
+ * Returns available datasource options.
+ *
+ * @return array
+ */
+ public function getSourceOptions() {
+ $options = [];
+ if ($this->container->has('openy_ds_pef_schedule.manager')) {
+ $options['pef'] = $this->t('Program Event Framework');
+ }
+ if ($this->container->has('openy_digital_signage_classes_schedule.manager')) {
+ $options['ds'] = $this->t('Open Y Digital Signage classes and session');
+ }
+
+ return $options;
+ }
+
+ /**
+ * Retrieves all available category options.
+ *
+ * @return array
+ */
+ public function getAllCategoryOptions() {
+ $categories = [];
+ if ($this->container->has('openy_ds_pef_schedule.manager')) {
+ $this->scheduleManager = $this->container->get('openy_ds_pef_schedule.manager');
+ $categories = $this->scheduleManager->getAllCategories();
+ }
+
+ return $categories;
}
/**
diff --git a/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/src/Plugin/Block/OpenYDigitalSignageBlockCompleteSchedule.php b/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/src/Plugin/Block/OpenYDigitalSignageBlockCompleteSchedule.php
new file mode 100644
index 0000000..16caba7
--- /dev/null
+++ b/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/src/Plugin/Block/OpenYDigitalSignageBlockCompleteSchedule.php
@@ -0,0 +1,338 @@
+screenManager = $screen_manager;
+ $this->roomManager = $room_manager;
+ $this->container = $container;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+ return new static(
+ $configuration,
+ $plugin_id,
+ $plugin_definition,
+ $container,
+ $container->get('openy_digital_signage_screen.manager'),
+ $container->get('openy_digital_signage_room.manager')
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function defaultConfiguration() {
+ return [
+ 'room' => 0,
+ 'source' => 'pef',
+ 'category' => [],
+ ];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function blockForm($form, FormStateInterface $form_state) {
+ $form['source'] = [
+ '#type' => 'select',
+ '#title' => $this->t('Data source'),
+ '#description' => $this->t('Specify where the class schedule comes from'),
+ '#default_value' => $this->getDataSource(),
+ '#options' => $this->getSourceOptions(),
+ ];
+ $form['room'] = [
+ '#type' => 'select',
+ '#multiple' => TRUE,
+ '#title' => $this->t('Room'),
+ '#description' => $this->t('The block is shown in context of the screen. If the screen has no room/studio specified, this value is used'),
+ '#default_value' => $this->configuration['room'],
+ '#options' => $this->roomManager->getAllRoomOptions(),
+ ];
+ $form['category'] = [
+ '#type' => 'select',
+ '#multiple' => TRUE,
+ '#chosen' => TRUE,
+ '#title' => $this->t('Category'),
+ '#description' => $this->t('Additionally filter schedule by activity category'),
+ '#default_value' => $this->getCategories(),
+ '#options' => $this->getAllCategoryOptions(),
+ '#states' => [
+ 'visible' => [
+ '[name="settings[source]"' => ['value' => 'pef'],
+ ],
+ ],
+ ];
+
+ // Prevents the chosen dropdown from being cut off.
+ $form['styles'] = [
+ '#type' => 'inline_template',
+ '#template' => "",
+ ];
+
+ return $form;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function blockSubmit($form, FormStateInterface $form_state) {
+ $this->configuration['source'] = $form_state->getValue('source');
+ $this->configuration['room'] = $form_state->getValue('room');
+ $this->configuration['category'] = [];
+ if ($this->configuration['source'] == 'pef') {
+ $this->configuration['category'] = array_filter($form_state->getValue('category'));
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function build() {
+ $attributes = new Attribute();
+ $attributes->addClass('block');
+ $attributes->addClass('block-class-current');
+
+ $period = $this->getSchedulePeriod();
+
+ $classes = [];
+ if ($this->getDataSource() == 'pef') {
+ if ($this->container->has('openy_ds_pef_schedule.manager')) {
+ $this->scheduleManager = $this->container->get('openy_ds_pef_schedule.manager');
+ $classes = $this->scheduleManager->getClassesSchedule($period, $this->scheduleManager->getNextDayIfEmpty(), $this->getLocation(), $this->getRooms(), $this->getCategories()); }
+ }
+ else {
+ if ($this->container->has('openy_digital_signage_classes_schedule.manager')) {
+ $this->scheduleManager = $this->container->get('openy_digital_signage_classes_schedule.manager');
+ $classes = $this->scheduleManager->getClassesSchedule($period, $this->getRooms(), $this->getCategories());
+ }
+ }
+
+ $build = [
+ '#theme' => 'openy_digital_signage_blocks_complete_schedule',
+ '#attached' => [
+ 'library' => [
+ 'openy_digital_signage_blocks/complete_schedule',
+ ],
+ ],
+ '#cache' => [
+ 'max-age' => 0,
+ ],
+ '#room' => $this->configuration['room'],
+ '#classes' => $classes,
+ '#wrapper_attributes' => $attributes,
+ ];
+
+ return $build;
+ }
+
+ /**
+ * Retrieves room.
+ *
+ * @return int|null
+ * The room id context.
+ */
+ private function getRooms() {
+ return $this->configuration['room'];
+ }
+
+ private function getLocation() {
+ if (!$screen = $this->screenManager->getScreenContext()) {
+ return 0;
+ }
+ $screen_location = $screen->field_screen_location->entity;
+ return $screen_location ? $screen_location->id() : null;
+ }
+
+ /**
+ * Retrieves data source.
+ *
+ * @return int|null
+ * The room id context.
+ */
+ private function getDataSource() {
+ $data_source = $this->defaultConfiguration()['source'];
+ if (!empty($this->configuration['source'])) {
+ $data_source = $this->configuration['source'];
+ }
+
+ return $data_source;
+ }
+
+ /**
+ * Retrieves category configuration.
+ *
+ * @return array
+ */
+ private function getCategories() {
+ $category = $this->defaultConfiguration()['category'];
+ if (!empty($this->configuration['category'])) {
+ $category = $this->configuration['category'];
+ }
+
+ return $category;
+ }
+
+ /**
+ * Returns available datasource options.
+ *
+ * @return array
+ */
+ public function getSourceOptions() {
+ $options = [];
+ if ($this->container->has('openy_ds_pef_schedule.manager')) {
+ $options['pef'] = $this->t('Program Event Framework');
+ }
+ if ($this->container->has('openy_digital_signage_classes_schedule.manager')) {
+ $options['ds'] = $this->t('Open Y Digital Signage classes and session');
+ }
+
+ return $options;
+ }
+
+ /**
+ * Retrieves all available category options.
+ *
+ * @return array
+ */
+ public function getAllCategoryOptions() {
+ $categories = [];
+ if ($this->container->has('openy_ds_pef_schedule.manager')) {
+ $this->scheduleManager = $this->container->get('openy_ds_pef_schedule.manager');
+ $categories = $this->scheduleManager->getAllCategories();
+ }
+
+ return $categories;
+ }
+
+ /**
+ * Retrieve schedule period.
+ *
+ * @return array
+ * The schedule period.
+ */
+ private function getSchedulePeriod() {
+ $period = &drupal_static('schedule_item_period', NULL);
+
+ if (isset($period)) {
+ return $period;
+ }
+
+ if (isset($_GET['from'], $_GET['to'])) {
+ return [
+ 'from' => $_GET['from'],
+ 'to' => $_GET['to'],
+ ];
+
+ }
+ return [
+ 'from' => time(),
+ 'to' => time() + $this::DEFAULT_PERIOD_LENGTH,
+ ];
+ }
+
+ /**
+ * Generates dummy class schedule.
+ *
+ * @param array $period
+ * Period of time the schedule to be generated.
+ *
+ * @return array
+ * The generated schedule.
+ */
+ private function getDummyClassesSchedule($period) {
+ $classes = [];
+ $time = $period['from'];
+ $cnt = 19;
+ $duration = ceil(($period['to'] - $period['from']) / ($cnt));
+ $break_duration = intval($duration * 4 / 13);
+ $duration -= $break_duration;
+ for ($i = 0; $i < $cnt; $i++) {
+ $from = $time;
+ $to = $from + $duration;
+ $time = $to + $break_duration;
+ $classes[] = [
+ 'from' => $from,
+ 'to' => $to,
+ 'duration_raw' => $duration,
+ 'duration' => $duration . 'm',
+ 'trainer' => 'Nichole C.',
+ 'substitute_trainer' => rand(0, 10) < 5 ? 'Substitute T.' : '',
+ 'name' => 'OULA
® Dance Fitness',
+ 'from_formatted' => date('g:ia', $from),
+ 'to_formatted' => date('g:ia', $to),
+ ];
+ }
+
+ return $classes;
+ }
+
+}
diff --git a/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/templates/block--digital-signage-block-free-html.html.twig b/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/templates/block--digital-signage-block-free-html.html.twig
index b4b5f42..2f11f32 100755
--- a/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/templates/block--digital-signage-block-free-html.html.twig
+++ b/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/templates/block--digital-signage-block-free-html.html.twig
@@ -27,7 +27,7 @@
* @ingroup themeable
*/
#}
-
+
{{ title_prefix }}
diff --git a/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/templates/block--digital-signage-promotional.html.twig b/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/templates/block--digital-signage-promotional.html.twig
index 127c8a8..6f52a41 100644
--- a/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/templates/block--digital-signage-promotional.html.twig
+++ b/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/templates/block--digital-signage-promotional.html.twig
@@ -28,7 +28,7 @@
*/
#}
-
+
{% block content %}
@@ -45,7 +45,7 @@
{% if content.field_ds_message[0]['#context'].value %}
{% endif %}
diff --git a/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/templates/openy-digital-signage-blocks-class-current.html.twig b/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/templates/openy-digital-signage-blocks-class-current.html.twig
index e0aadae..0399363 100644
--- a/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/templates/openy-digital-signage-blocks-class-current.html.twig
+++ b/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/templates/openy-digital-signage-blocks-class-current.html.twig
@@ -18,7 +18,7 @@
-
{{ "Coming next"|t }}
+
{{ "Up next"|t }}
diff --git a/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/templates/openy-digital-signage-blocks-complete-schedule.html.twig b/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/templates/openy-digital-signage-blocks-complete-schedule.html.twig
new file mode 100644
index 0000000..22aec89
--- /dev/null
+++ b/modules/openy_digital_signage_screen_content/modules/openy_digital_signage_blocks/templates/openy-digital-signage-blocks-complete-schedule.html.twig
@@ -0,0 +1,64 @@
+{#
+/**
+ * @file
+ * Default theme implementation to display a System Message block.
+ *
+ * Available variables:
+ * - wrapper_attributes: array of HTML attributes, intended to be added to the main
+ * container tag of this template.
+ * - classes: A list of classes to identify position and styles of the block.
+ * - room: The room.
+ * - classes: The array of classes.
+ *
+ * @ingroup themeable
+ */
+#}
+
+
+
+
+
Ongoing
+
Upcoming
+ {% for class in classes %}
+
+
+ {{ class.from_formatted }}
+
+
+ {{ class.duration }}
+
+
{{ class.name|raw }}
+
+ {% if class.substitute_trainer %}
+
+ {{ class.trainer }}
+ {% else %}
+ {{ class.trainer }}
+ {% endif %}
+
+
{{ class.room|raw }}
+
+
+ {% endfor %}
+
+
diff --git a/modules/openy_digital_signage_screen_content/src/Controller/OpenYDSPanelsIPEPageController.php b/modules/openy_digital_signage_screen_content/src/Controller/OpenYDSPanelsIPEPageController.php
index 9ae4bd1..53df623 100644
--- a/modules/openy_digital_signage_screen_content/src/Controller/OpenYDSPanelsIPEPageController.php
+++ b/modules/openy_digital_signage_screen_content/src/Controller/OpenYDSPanelsIPEPageController.php
@@ -20,11 +20,19 @@ class OpenYDSPanelsIPEPageController extends PanelsIPEPageController {
* Status.
*/
public function isEntityScreenContent($panels_storage_id) {
+ if (strrpos($panels_storage_id, 'screen_content')) {
+ return TRUE;
+ }
+
$storage_keys = explode(':', $panels_storage_id);
$entity_manager = \Drupal::entityTypeManager();
$entity = $entity_manager->getStorage('node')
->load($storage_keys[1]);
- return $entity->bundle() == 'screen_content';
+ if ($entity) {
+ return $entity->bundle() == 'screen_content';
+ }
+
+ return FALSE;
}
/**
@@ -94,6 +102,11 @@ public function getBlockPluginsData($panels_storage_type, $panels_storage_id) {
}
$panels_display = $this->loadPanelsDisplay($panels_storage_type, $panels_storage_id);
+ $contexts = $this->tempStore->get($panels_display->getStorageId() . '-context');
+ if ($contexts) {
+ $panels_display->setContexts($contexts);
+ }
+
// Get block plugin definitions from the server.
$definitions = $this->blockManager->getDefinitionsForContexts($panels_display->getContexts());
diff --git a/modules/openy_ds_media_library/config/install/core.entity_form_display.media.image.digital_signage_media.yml b/modules/openy_ds_media_library/config/install/core.entity_form_display.media.image.digital_signage_media.yml
new file mode 100644
index 0000000..2ae5399
--- /dev/null
+++ b/modules/openy_ds_media_library/config/install/core.entity_form_display.media.image.digital_signage_media.yml
@@ -0,0 +1,62 @@
+uuid: ec0a1b2d-26a8-480f-8a9c-33051d5bc358
+langcode: en
+status: true
+dependencies:
+ config:
+ - core.entity_form_mode.media.digital_signage_media
+ - field.field.media.image.field_media_caption
+ - field.field.media.image.field_media_image
+ - field.field.media.image.field_media_in_library
+ - field.field.media.image.field_media_tags
+ - image.style.thumbnail_focal_point
+ - media_entity.bundle.image
+ module:
+ - focal_point
+_core:
+ default_config_hash: rRJJPqkvU7b4dP6du23LZDutvvFh28WOAdHCbbf0xhI
+id: media.image.digital_signage_media
+targetEntityType: media
+bundle: image
+mode: digital_signage_media
+content:
+ field_media_image:
+ weight: 3
+ settings:
+ preview_image_style: thumbnail_focal_point
+ progress_indicator: throbber
+ preview_link: true
+ offsets: '50,50'
+ third_party_settings: { }
+ type: image_focal_point
+ region: content
+ field_media_tags:
+ weight: 1
+ settings:
+ match_operator: CONTAINS
+ size: 60
+ placeholder: ''
+ third_party_settings: { }
+ type: entity_reference_autocomplete_tags
+ region: content
+ langcode:
+ type: language_select
+ weight: 2
+ region: content
+ settings:
+ include_locked: true
+ third_party_settings: { }
+ name:
+ type: string_textfield
+ weight: 0
+ settings:
+ size: 60
+ placeholder: ''
+ third_party_settings: { }
+ region: content
+hidden:
+ created: true
+ field_media_caption: true
+ field_media_in_library: true
+ moderation_state: true
+ path: true
+ uid: true
diff --git a/modules/openy_ds_media_library/config/install/core.entity_form_mode.media.digital_signage_media.yml b/modules/openy_ds_media_library/config/install/core.entity_form_mode.media.digital_signage_media.yml
new file mode 100644
index 0000000..9f43251
--- /dev/null
+++ b/modules/openy_ds_media_library/config/install/core.entity_form_mode.media.digital_signage_media.yml
@@ -0,0 +1,10 @@
+uuid: fbd16cc9-7326-42c0-82e6-8fdeaecf6d0d
+langcode: en
+status: true
+dependencies:
+ module:
+ - media_entity
+id: media.digital_signage_media
+label: 'Digital signage media'
+targetEntityType: media
+cache: true
diff --git a/modules/openy_ds_media_library/config/install/entity_browser.browser.digital_signage_images_library.yml b/modules/openy_ds_media_library/config/install/entity_browser.browser.digital_signage_images_library.yml
new file mode 100644
index 0000000..a390622
--- /dev/null
+++ b/modules/openy_ds_media_library/config/install/entity_browser.browser.digital_signage_images_library.yml
@@ -0,0 +1,55 @@
+uuid: 11bf921a-ef5c-459e-a48c-b62c66992692
+langcode: en
+status: true
+dependencies:
+ config:
+ - media_entity.bundle.image
+ - views.view.digital_signage_images_library
+ module:
+ - dropzonejs_eb_widget
+ - media_entity
+ - views
+_core:
+ default_config_hash: _MNAphXAG4qCL7nCsXV_1Gb2RCao0OiXgG-bPo76P0A
+name: digital_signage_images_library
+label: 'Digital Signage Images Library'
+display: modal
+display_configuration:
+ width: '1166'
+ height: '600'
+ link_text: 'Select images'
+ auto_open: false
+selection_display: no_display
+selection_display_configuration: { }
+widget_selector: tabs
+widget_selector_configuration: { }
+widgets:
+ 066bf7d9-6d8d-46cd-ac5c-a0944058e8c4:
+ settings:
+ view: digital_signage_images_library
+ view_display: images_library
+ submit_text: 'Select images'
+ auto_select: false
+ uuid: 066bf7d9-6d8d-46cd-ac5c-a0944058e8c4
+ weight: -8
+ label: 'All Images'
+ id: view
+ 89e6e16d-6b22-45f4-b91a-f37edaa85f64:
+ settings:
+ form_mode: digital_signage_media
+ media_entity_bundle: image
+ upload_location: 'public://digital_signage/[date:custom:Y]-[date:custom:m]'
+ dropzone_description: 'Drop files here to upload them'
+ max_filesize: 10M
+ extensions: 'png jpg jpeg gif svg'
+ clientside_resize: false
+ resize_width: 0
+ resize_height: 0
+ resize_quality: !!float 1
+ resize_method: contain
+ thumbnail_method: contain
+ submit_text: 'Select images'
+ uuid: 89e6e16d-6b22-45f4-b91a-f37edaa85f64
+ weight: -10
+ label: 'Upload images'
+ id: dropzonejs_media_entity_inline_entity_form
diff --git a/modules/openy_ds_media_library/config/install/views.view.digital_signage_images_library.yml b/modules/openy_ds_media_library/config/install/views.view.digital_signage_images_library.yml
new file mode 100644
index 0000000..d895ab9
--- /dev/null
+++ b/modules/openy_ds_media_library/config/install/views.view.digital_signage_images_library.yml
@@ -0,0 +1,448 @@
+uuid: 08326bcf-62b6-493e-b131-1738beb120a1
+langcode: en
+status: true
+dependencies:
+ config:
+ - image.style.browser_thumbnail
+ - media_entity.bundle.image
+ module:
+ - entity_browser
+ - image
+ - media_entity
+ - user
+_core:
+ default_config_hash: L82HYSEP88PlPW6rB_VIk8v2kK8RZ6tw4XYfQ8ujPxM
+id: digital_signage_images_library
+label: 'Digital Signage Images Library'
+module: views
+description: 'Provides images library for images_library entity browser.'
+tag: ''
+base_table: media_field_data
+base_field: mid
+core: 8.x
+display:
+ default:
+ display_plugin: default
+ id: default
+ display_title: Master
+ position: 0
+ display_options:
+ access:
+ type: perm
+ options:
+ perm: 'access media overview'
+ cache:
+ type: tag
+ options: { }
+ query:
+ type: views_query
+ options:
+ disable_sql_rewrite: false
+ distinct: false
+ replica: false
+ query_comment: ''
+ query_tags: { }
+ exposed_form:
+ type: basic
+ options:
+ submit_button: Apply
+ reset_button: false
+ reset_button_label: Reset
+ exposed_sorts_label: 'Sort by'
+ expose_sort_order: true
+ sort_asc_label: Asc
+ sort_desc_label: Desc
+ pager:
+ type: mini
+ options:
+ items_per_page: 12
+ offset: 0
+ id: 0
+ total_pages: null
+ tags:
+ previous: ‹‹
+ next: ››
+ expose:
+ items_per_page: false
+ items_per_page_label: 'Items per page'
+ items_per_page_options: '5, 10, 25, 50'
+ items_per_page_options_all: false
+ items_per_page_options_all_label: '- All -'
+ offset: false
+ offset_label: Offset
+ style:
+ type: grid
+ options:
+ grouping: { }
+ columns: 4
+ automatic_width: true
+ alignment: horizontal
+ col_class_default: true
+ col_class_custom: ''
+ row_class_default: true
+ row_class_custom: ''
+ row:
+ type: fields
+ options:
+ inline: { }
+ separator: ''
+ hide_empty: false
+ default_field_elements: true
+ fields:
+ thumbnail__target_id:
+ id: thumbnail__target_id
+ table: media_field_data
+ field: thumbnail__target_id
+ relationship: none
+ group_type: group
+ admin_label: ''
+ label: ''
+ exclude: false
+ alter:
+ alter_text: false
+ text: ''
+ make_link: false
+ path: ''
+ absolute: false
+ external: false
+ replace_spaces: false
+ path_case: none
+ trim_whitespace: false
+ alt: ''
+ rel: ''
+ link_class: ''
+ prefix: ''
+ suffix: ''
+ target: ''
+ nl2br: false
+ max_length: 0
+ word_boundary: true
+ ellipsis: true
+ more_link: false
+ more_link_text: ''
+ more_link_path: ''
+ strip_tags: false
+ trim: false
+ preserve_tags: ''
+ html: false
+ element_type: ''
+ element_class: ''
+ element_label_type: ''
+ element_label_class: ''
+ element_label_colon: false
+ element_wrapper_type: ''
+ element_wrapper_class: ''
+ element_default_classes: true
+ empty: ''
+ hide_empty: false
+ empty_zero: false
+ hide_alter_empty: true
+ click_sort_column: target_id
+ type: image
+ settings:
+ image_style: browser_thumbnail
+ image_link: ''
+ group_column: ''
+ group_columns: { }
+ group_rows: true
+ delta_limit: 0
+ delta_offset: 0
+ delta_reversed: false
+ delta_first_last: false
+ multi_type: separator
+ separator: ', '
+ field_api_classes: false
+ entity_type: media
+ entity_field: thumbnail
+ plugin_id: field
+ entity_browser_select:
+ id: entity_browser_select
+ table: media
+ field: entity_browser_select
+ relationship: none
+ group_type: group
+ admin_label: ''
+ label: ''
+ exclude: false
+ alter:
+ alter_text: false
+ text: ''
+ make_link: false
+ path: ''
+ absolute: false
+ external: false
+ replace_spaces: false
+ path_case: none
+ trim_whitespace: false
+ alt: ''
+ rel: ''
+ link_class: ''
+ prefix: ''
+ suffix: ''
+ target: ''
+ nl2br: false
+ max_length: 0
+ word_boundary: true
+ ellipsis: true
+ more_link: false
+ more_link_text: ''
+ more_link_path: ''
+ strip_tags: false
+ trim: false
+ preserve_tags: ''
+ html: false
+ element_type: ''
+ element_class: ''
+ element_label_type: ''
+ element_label_class: ''
+ element_label_colon: false
+ element_wrapper_type: ''
+ element_wrapper_class: visually-hidden
+ element_default_classes: false
+ empty: ''
+ hide_empty: false
+ empty_zero: false
+ hide_alter_empty: true
+ entity_type: media
+ plugin_id: entity_browser_select
+ filters:
+ name:
+ id: name
+ table: media_field_data
+ field: name
+ relationship: none
+ group_type: group
+ admin_label: ''
+ operator: contains
+ value: ''
+ group: 1
+ exposed: true
+ expose:
+ operator_id: name_op
+ label: 'Image name'
+ description: ''
+ use_operator: false
+ operator: name_op
+ identifier: name
+ required: false
+ remember: false
+ multiple: false
+ remember_roles:
+ authenticated: authenticated
+ anonymous: '0'
+ administrator: '0'
+ is_grouped: false
+ group_info:
+ label: ''
+ description: ''
+ identifier: ''
+ optional: true
+ widget: select
+ multiple: false
+ remember: false
+ default_group: All
+ default_group_multiple: { }
+ group_items: { }
+ entity_type: media
+ entity_field: name
+ plugin_id: string
+ bundle:
+ id: bundle
+ table: media_field_data
+ field: bundle
+ relationship: none
+ group_type: group
+ admin_label: ''
+ operator: in
+ value:
+ image: image
+ group: 1
+ exposed: false
+ expose:
+ operator_id: ''
+ label: ''
+ description: ''
+ use_operator: false
+ operator: ''
+ identifier: ''
+ required: false
+ remember: false
+ multiple: false
+ remember_roles:
+ authenticated: authenticated
+ reduce: false
+ is_grouped: false
+ group_info:
+ label: ''
+ description: ''
+ identifier: ''
+ optional: true
+ widget: select
+ multiple: false
+ remember: false
+ default_group: All
+ default_group_multiple: { }
+ group_items: { }
+ entity_type: media
+ entity_field: bundle
+ plugin_id: bundle
+ status:
+ id: status
+ table: media_field_data
+ field: status
+ relationship: none
+ group_type: group
+ admin_label: ''
+ operator: '='
+ value: '1'
+ group: 1
+ exposed: true
+ expose:
+ operator_id: ''
+ label: 'Publishing status'
+ description: ''
+ use_operator: false
+ operator: status_op
+ identifier: status
+ required: true
+ remember: false
+ multiple: false
+ remember_roles:
+ authenticated: authenticated
+ anonymous: '0'
+ administrator: '0'
+ is_grouped: false
+ group_info:
+ label: ''
+ description: ''
+ identifier: ''
+ optional: true
+ widget: select
+ multiple: false
+ remember: false
+ default_group: All
+ default_group_multiple: { }
+ group_items: { }
+ plugin_id: boolean
+ entity_type: media
+ entity_field: status
+ field_media_in_library_value:
+ id: field_media_in_library_value
+ table: media__field_media_in_library
+ field: field_media_in_library_value
+ relationship: none
+ group_type: group
+ admin_label: ''
+ operator: '='
+ value: '1'
+ group: 1
+ exposed: false
+ expose:
+ operator_id: ''
+ label: ''
+ description: ''
+ use_operator: false
+ operator: ''
+ identifier: ''
+ required: false
+ remember: false
+ multiple: false
+ remember_roles:
+ authenticated: authenticated
+ is_grouped: false
+ group_info:
+ label: ''
+ description: ''
+ identifier: ''
+ optional: true
+ widget: select
+ multiple: false
+ remember: false
+ default_group: All
+ default_group_multiple: { }
+ group_items: { }
+ plugin_id: boolean
+ sorts:
+ created:
+ id: created
+ table: media_field_data
+ field: created
+ relationship: none
+ group_type: group
+ admin_label: ''
+ order: DESC
+ exposed: true
+ expose:
+ label: Created
+ granularity: second
+ entity_type: media
+ entity_field: created
+ plugin_id: date
+ name:
+ id: name
+ table: media_field_data
+ field: name
+ relationship: none
+ group_type: group
+ admin_label: ''
+ order: ASC
+ exposed: true
+ expose:
+ label: 'Media name'
+ entity_type: media
+ entity_field: name
+ plugin_id: standard
+ header: { }
+ footer: { }
+ empty:
+ area:
+ id: area
+ table: views
+ field: area
+ relationship: none
+ group_type: group
+ admin_label: ''
+ empty: true
+ tokenize: false
+ content:
+ value: 'No results found'
+ format: full_html
+ plugin_id: text
+ relationships: { }
+ arguments: { }
+ display_extenders: { }
+ title: 'Images Library'
+ filter_groups:
+ operator: AND
+ groups:
+ 1: AND
+ css_class: eb-media
+ cache_metadata:
+ max-age: -1
+ contexts:
+ - 'languages:language_content'
+ - 'languages:language_interface'
+ - url
+ - url.query_args
+ - 'url.query_args:sort_by'
+ - 'url.query_args:sort_order'
+ - user.permissions
+ tags: { }
+ images_library:
+ display_plugin: entity_browser
+ id: images_library
+ display_title: 'Entity browser'
+ position: 1
+ display_options:
+ display_extenders: { }
+ cache_metadata:
+ max-age: -1
+ contexts:
+ - 'languages:language_content'
+ - 'languages:language_interface'
+ - url
+ - url.query_args
+ - 'url.query_args:sort_by'
+ - 'url.query_args:sort_order'
+ - user.permissions
+ tags: { }
diff --git a/modules/openy_ds_media_library/config/install/views.view.digital_signage_media.yml b/modules/openy_ds_media_library/config/install/views.view.digital_signage_media.yml
new file mode 100644
index 0000000..b8f3e74
--- /dev/null
+++ b/modules/openy_ds_media_library/config/install/views.view.digital_signage_media.yml
@@ -0,0 +1,807 @@
+uuid: c679ca7e-3973-4ca5-b27c-190e27864799
+langcode: en
+status: true
+dependencies:
+ config:
+ - image.style.thumbnail
+ - system.menu.admin
+ module:
+ - image
+ - media_entity
+ - user
+_core:
+ default_config_hash: i7kD7PlSfZhwyTiOigjWRiiTzuVJjp5dsvjRbSDvP5c
+id: digital_signage_media
+label: 'Digital Signage Media'
+module: views
+description: ''
+tag: ''
+base_table: media_field_data
+base_field: mid
+core: 8.x
+display:
+ default:
+ display_plugin: default
+ id: default
+ display_title: Master
+ position: 0
+ display_options:
+ access:
+ type: perm
+ options:
+ perm: 'access media overview'
+ cache:
+ type: tag
+ options: { }
+ query:
+ type: views_query
+ options:
+ disable_sql_rewrite: false
+ distinct: false
+ replica: false
+ query_comment: ''
+ query_tags: { }
+ exposed_form:
+ type: basic
+ options:
+ submit_button: Apply
+ reset_button: false
+ reset_button_label: Reset
+ exposed_sorts_label: 'Sort by'
+ expose_sort_order: true
+ sort_asc_label: Asc
+ sort_desc_label: Desc
+ pager:
+ type: full
+ options:
+ items_per_page: 50
+ offset: 0
+ id: 0
+ total_pages: null
+ expose:
+ items_per_page: false
+ items_per_page_label: 'Items per page'
+ items_per_page_options: '5, 10, 25, 50'
+ items_per_page_options_all: false
+ items_per_page_options_all_label: '- All -'
+ offset: false
+ offset_label: Offset
+ tags:
+ previous: '‹ Previous'
+ next: 'Next ›'
+ first: '« First'
+ last: 'Last »'
+ quantity: 9
+ style:
+ type: table
+ options:
+ grouping: { }
+ row_class: ''
+ default_row_class: true
+ override: true
+ sticky: false
+ caption: ''
+ summary: ''
+ description: ''
+ columns:
+ name: name
+ bundle: bundle
+ changed: changed
+ uid: uid
+ status: status
+ thumbnail__target_id: thumbnail__target_id
+ info:
+ name:
+ sortable: true
+ default_sort_order: asc
+ align: ''
+ separator: ''
+ empty_column: false
+ responsive: ''
+ bundle:
+ sortable: true
+ default_sort_order: asc
+ align: ''
+ separator: ''
+ empty_column: false
+ responsive: ''
+ changed:
+ sortable: true
+ default_sort_order: desc
+ align: ''
+ separator: ''
+ empty_column: false
+ responsive: ''
+ uid:
+ sortable: false
+ default_sort_order: asc
+ align: ''
+ separator: ''
+ empty_column: false
+ responsive: ''
+ status:
+ sortable: true
+ default_sort_order: asc
+ align: ''
+ separator: ''
+ empty_column: false
+ responsive: ''
+ thumbnail__target_id:
+ sortable: false
+ default_sort_order: asc
+ align: ''
+ separator: ''
+ empty_column: false
+ responsive: ''
+ default: changed
+ empty_table: false
+ row:
+ type: fields
+ fields:
+ thumbnail__target_id:
+ id: thumbnail__target_id
+ table: media_field_data
+ field: thumbnail__target_id
+ relationship: none
+ group_type: group
+ admin_label: ''
+ label: Thumbnail
+ exclude: false
+ alter:
+ alter_text: false
+ text: ''
+ make_link: false
+ path: ''
+ absolute: false
+ external: false
+ replace_spaces: false
+ path_case: none
+ trim_whitespace: false
+ alt: ''
+ rel: ''
+ link_class: ''
+ prefix: ''
+ suffix: ''
+ target: ''
+ nl2br: false
+ max_length: 0
+ word_boundary: true
+ ellipsis: true
+ more_link: false
+ more_link_text: ''
+ more_link_path: ''
+ strip_tags: false
+ trim: false
+ preserve_tags: ''
+ html: false
+ element_type: ''
+ element_class: ''
+ element_label_type: ''
+ element_label_class: ''
+ element_label_colon: true
+ element_wrapper_type: ''
+ element_wrapper_class: ''
+ element_default_classes: true
+ empty: ''
+ hide_empty: false
+ empty_zero: false
+ hide_alter_empty: true
+ click_sort_column: target_id
+ type: image
+ settings:
+ image_style: thumbnail
+ image_link: ''
+ group_column: ''
+ group_columns: { }
+ group_rows: true
+ delta_limit: 0
+ delta_offset: 0
+ delta_reversed: false
+ delta_first_last: false
+ multi_type: separator
+ separator: ', '
+ field_api_classes: false
+ entity_type: media
+ entity_field: thumbnail
+ plugin_id: field
+ name:
+ id: name
+ table: media_field_data
+ field: name
+ entity_type: media
+ entity_field: media
+ alter:
+ alter_text: false
+ make_link: false
+ absolute: false
+ trim: false
+ word_boundary: false
+ ellipsis: false
+ strip_tags: false
+ html: false
+ hide_empty: false
+ empty_zero: false
+ settings:
+ link_to_entity: true
+ plugin_id: field
+ relationship: none
+ group_type: group
+ admin_label: ''
+ label: 'Media name'
+ exclude: false
+ element_type: ''
+ element_class: ''
+ element_label_type: ''
+ element_label_class: ''
+ element_label_colon: true
+ element_wrapper_type: ''
+ element_wrapper_class: ''
+ element_default_classes: true
+ empty: ''
+ hide_alter_empty: true
+ click_sort_column: value
+ type: string
+ group_column: value
+ group_columns: { }
+ group_rows: true
+ delta_limit: 0
+ delta_offset: 0
+ delta_reversed: false
+ delta_first_last: false
+ multi_type: separator
+ separator: ', '
+ field_api_classes: false
+ bundle:
+ id: bundle
+ table: media_field_data
+ field: bundle
+ relationship: none
+ group_type: group
+ admin_label: ''
+ label: Provider
+ exclude: false
+ alter:
+ alter_text: false
+ text: ''
+ make_link: false
+ path: ''
+ absolute: false
+ external: false
+ replace_spaces: false
+ path_case: none
+ trim_whitespace: false
+ alt: ''
+ rel: ''
+ link_class: ''
+ prefix: ''
+ suffix: ''
+ target: ''
+ nl2br: false
+ max_length: 0
+ word_boundary: true
+ ellipsis: true
+ more_link: false
+ more_link_text: ''
+ more_link_path: ''
+ strip_tags: false
+ trim: false
+ preserve_tags: ''
+ html: false
+ element_type: ''
+ element_class: ''
+ element_label_type: ''
+ element_label_class: ''
+ element_label_colon: true
+ element_wrapper_type: ''
+ element_wrapper_class: ''
+ element_default_classes: true
+ empty: ''
+ hide_empty: false
+ empty_zero: false
+ hide_alter_empty: true
+ click_sort_column: target_id
+ type: entity_reference_label
+ settings:
+ link: true
+ group_column: target_id
+ group_columns: { }
+ group_rows: true
+ delta_limit: 0
+ delta_offset: 0
+ delta_reversed: false
+ delta_first_last: false
+ multi_type: separator
+ separator: ', '
+ field_api_classes: false
+ entity_type: media
+ entity_field: bundle
+ plugin_id: field
+ uid:
+ id: uid
+ table: media_field_data
+ field: uid
+ relationship: none
+ group_type: group
+ admin_label: ''
+ label: Author
+ exclude: false
+ alter:
+ alter_text: false
+ text: ''
+ make_link: false
+ path: ''
+ absolute: false
+ external: false
+ replace_spaces: false
+ path_case: none
+ trim_whitespace: false
+ alt: ''
+ rel: ''
+ link_class: ''
+ prefix: ''
+ suffix: ''
+ target: ''
+ nl2br: false
+ max_length: 0
+ word_boundary: true
+ ellipsis: true
+ more_link: false
+ more_link_text: ''
+ more_link_path: ''
+ strip_tags: false
+ trim: false
+ preserve_tags: ''
+ html: false
+ element_type: ''
+ element_class: ''
+ element_label_type: ''
+ element_label_class: ''
+ element_label_colon: true
+ element_wrapper_type: ''
+ element_wrapper_class: ''
+ element_default_classes: true
+ empty: ''
+ hide_empty: false
+ empty_zero: false
+ hide_alter_empty: true
+ click_sort_column: target_id
+ type: entity_reference_label
+ settings:
+ link: true
+ group_column: target_id
+ group_columns: { }
+ group_rows: true
+ delta_limit: 0
+ delta_offset: 0
+ delta_reversed: false
+ delta_first_last: false
+ multi_type: separator
+ separator: ', '
+ field_api_classes: false
+ entity_type: media
+ entity_field: uid
+ plugin_id: field
+ status:
+ id: status
+ table: media_field_data
+ field: status
+ relationship: none
+ group_type: group
+ admin_label: ''
+ label: Status
+ exclude: false
+ alter:
+ alter_text: false
+ text: ''
+ make_link: false
+ path: ''
+ absolute: false
+ external: false
+ replace_spaces: false
+ path_case: none
+ trim_whitespace: false
+ alt: ''
+ rel: ''
+ link_class: ''
+ prefix: ''
+ suffix: ''
+ target: ''
+ nl2br: false
+ max_length: 0
+ word_boundary: true
+ ellipsis: true
+ more_link: false
+ more_link_text: ''
+ more_link_path: ''
+ strip_tags: false
+ trim: false
+ preserve_tags: ''
+ html: false
+ element_type: ''
+ element_class: ''
+ element_label_type: ''
+ element_label_class: ''
+ element_label_colon: true
+ element_wrapper_type: ''
+ element_wrapper_class: ''
+ element_default_classes: true
+ empty: ''
+ hide_empty: false
+ empty_zero: false
+ hide_alter_empty: true
+ click_sort_column: value
+ type: boolean
+ settings:
+ format: custom
+ format_custom_true: Published
+ format_custom_false: Unpublished
+ group_column: value
+ group_columns: { }
+ group_rows: true
+ delta_limit: 0
+ delta_offset: 0
+ delta_reversed: false
+ delta_first_last: false
+ multi_type: separator
+ separator: ', '
+ field_api_classes: false
+ entity_type: media
+ entity_field: status
+ plugin_id: field
+ changed:
+ id: changed
+ table: media_field_data
+ field: changed
+ relationship: none
+ group_type: group
+ admin_label: ''
+ label: Updated
+ exclude: false
+ alter:
+ alter_text: false
+ text: ''
+ make_link: false
+ path: ''
+ absolute: false
+ external: false
+ replace_spaces: false
+ path_case: none
+ trim_whitespace: false
+ alt: ''
+ rel: ''
+ link_class: ''
+ prefix: ''
+ suffix: ''
+ target: ''
+ nl2br: false
+ max_length: 0
+ word_boundary: true
+ ellipsis: true
+ more_link: false
+ more_link_text: ''
+ more_link_path: ''
+ strip_tags: false
+ trim: false
+ preserve_tags: ''
+ html: false
+ element_type: ''
+ element_class: ''
+ element_label_type: ''
+ element_label_class: ''
+ element_label_colon: true
+ element_wrapper_type: ''
+ element_wrapper_class: ''
+ element_default_classes: true
+ empty: ''
+ hide_empty: false
+ empty_zero: false
+ hide_alter_empty: true
+ click_sort_column: value
+ type: timestamp
+ settings:
+ date_format: short
+ custom_date_format: ''
+ timezone: ''
+ group_column: value
+ group_columns: { }
+ group_rows: true
+ delta_limit: 0
+ delta_offset: 0
+ delta_reversed: false
+ delta_first_last: false
+ multi_type: separator
+ separator: ', '
+ field_api_classes: false
+ entity_type: media
+ entity_field: changed
+ plugin_id: field
+ operations:
+ id: operations
+ table: media
+ field: operations
+ relationship: none
+ group_type: group
+ admin_label: ''
+ label: Operations
+ exclude: false
+ alter:
+ alter_text: false
+ text: ''
+ make_link: false
+ path: ''
+ absolute: false
+ external: false
+ replace_spaces: false
+ path_case: none
+ trim_whitespace: false
+ alt: ''
+ rel: ''
+ link_class: ''
+ prefix: ''
+ suffix: ''
+ target: ''
+ nl2br: false
+ max_length: 0
+ word_boundary: true
+ ellipsis: true
+ more_link: false
+ more_link_text: ''
+ more_link_path: ''
+ strip_tags: false
+ trim: false
+ preserve_tags: ''
+ html: false
+ element_type: ''
+ element_class: ''
+ element_label_type: ''
+ element_label_class: ''
+ element_label_colon: true
+ element_wrapper_type: ''
+ element_wrapper_class: ''
+ element_default_classes: true
+ empty: ''
+ hide_empty: false
+ empty_zero: false
+ hide_alter_empty: true
+ destination: true
+ entity_type: media
+ plugin_id: entity_operations
+ filters:
+ status:
+ id: status
+ table: media_field_data
+ field: status
+ relationship: none
+ group_type: group
+ admin_label: ''
+ operator: '='
+ value: '1'
+ group: 1
+ exposed: true
+ expose:
+ operator_id: ''
+ label: 'True'
+ description: null
+ use_operator: false
+ operator: status_op
+ identifier: status
+ required: true
+ remember: false
+ multiple: false
+ remember_roles:
+ authenticated: authenticated
+ is_grouped: true
+ group_info:
+ label: 'Publishing status'
+ description: ''
+ identifier: status
+ optional: true
+ widget: select
+ multiple: false
+ remember: false
+ default_group: All
+ default_group_multiple: { }
+ group_items:
+ 1:
+ title: Published
+ operator: '='
+ value: '1'
+ 2:
+ title: Unpublished
+ operator: '='
+ value: '0'
+ plugin_id: boolean
+ entity_type: media
+ entity_field: status
+ bundle:
+ id: bundle
+ table: media_field_data
+ field: bundle
+ relationship: none
+ group_type: group
+ admin_label: ''
+ operator: in
+ value: { }
+ group: 1
+ exposed: true
+ expose:
+ operator_id: bundle_op
+ label: Provider
+ description: ''
+ use_operator: false
+ operator: bundle_op
+ identifier: provider
+ required: false
+ remember: false
+ multiple: false
+ remember_roles:
+ authenticated: authenticated
+ anonymous: '0'
+ administrator: '0'
+ reduce: false
+ is_grouped: false
+ group_info:
+ label: ''
+ description: ''
+ identifier: ''
+ optional: true
+ widget: select
+ multiple: false
+ remember: false
+ default_group: All
+ default_group_multiple: { }
+ group_items: { }
+ entity_type: media
+ entity_field: bundle
+ plugin_id: bundle
+ name:
+ id: name
+ table: media_field_data
+ field: name
+ relationship: none
+ group_type: group
+ admin_label: ''
+ operator: contains
+ value: ''
+ group: 1
+ exposed: true
+ expose:
+ operator_id: name_op
+ label: 'Media name'
+ description: ''
+ use_operator: false
+ operator: name_op
+ identifier: name
+ required: false
+ remember: false
+ multiple: false
+ remember_roles:
+ authenticated: authenticated
+ anonymous: '0'
+ administrator: '0'
+ is_grouped: false
+ group_info:
+ label: ''
+ description: ''
+ identifier: ''
+ optional: true
+ widget: select
+ multiple: false
+ remember: false
+ default_group: All
+ default_group_multiple: { }
+ group_items: { }
+ entity_type: media
+ entity_field: name
+ plugin_id: string
+ langcode:
+ id: langcode
+ table: media_field_data
+ field: langcode
+ relationship: none
+ group_type: group
+ admin_label: ''
+ operator: in
+ value: { }
+ group: 1
+ exposed: true
+ expose:
+ operator_id: langcode_op
+ label: Language
+ description: ''
+ use_operator: false
+ operator: langcode_op
+ identifier: langcode
+ required: false
+ remember: false
+ multiple: false
+ remember_roles:
+ authenticated: authenticated
+ anonymous: '0'
+ administrator: '0'
+ reduce: false
+ is_grouped: false
+ group_info:
+ label: ''
+ description: ''
+ identifier: ''
+ optional: true
+ widget: select
+ multiple: false
+ remember: false
+ default_group: All
+ default_group_multiple: { }
+ group_items: { }
+ entity_type: media
+ entity_field: langcode
+ plugin_id: language
+ sorts:
+ created:
+ id: created
+ table: media_field_data
+ field: created
+ order: DESC
+ entity_type: media
+ entity_field: created
+ plugin_id: date
+ relationship: none
+ group_type: group
+ admin_label: ''
+ exposed: false
+ expose:
+ label: ''
+ granularity: second
+ title: Media
+ header: { }
+ footer: { }
+ empty:
+ area_text_custom:
+ id: area_text_custom
+ table: views
+ field: area_text_custom
+ relationship: none
+ group_type: group
+ admin_label: ''
+ empty: true
+ tokenize: false
+ content: 'No content available.'
+ plugin_id: text_custom
+ relationships: { }
+ arguments: { }
+ display_extenders: { }
+ cache_metadata:
+ max-age: 0
+ contexts:
+ - 'languages:language_content'
+ - 'languages:language_interface'
+ - url
+ - url.query_args
+ - user.permissions
+ tags: { }
+ media_page_list:
+ display_plugin: page
+ id: media_page_list
+ display_title: Media
+ position: 1
+ display_options:
+ display_extenders: { }
+ path: admin/digital-signage/media
+ menu:
+ type: normal
+ title: Media
+ description: 'Individual slides and images'
+ expanded: false
+ parent: system.admin_openy_digital_signage
+ weight: 0
+ context: '0'
+ menu_name: admin
+ display_description: ''
+ cache_metadata:
+ max-age: 0
+ contexts:
+ - 'languages:language_content'
+ - 'languages:language_interface'
+ - url
+ - url.query_args
+ - user.permissions
+ tags: { }
diff --git a/modules/openy_ds_media_library/css/browser.css b/modules/openy_ds_media_library/css/browser.css
new file mode 100644
index 0000000..8953a47
--- /dev/null
+++ b/modules/openy_ds_media_library/css/browser.css
@@ -0,0 +1,7 @@
+/**
+ * @file browser.css
+ */
+
+.view.view-digital-signage-images-library .views-col.selected img {
+ box-shadow: 0 0 10px #0089d0;
+}
diff --git a/modules/openy_ds_media_library/openy_ds_media_library.info.yml b/modules/openy_ds_media_library/openy_ds_media_library.info.yml
new file mode 100644
index 0000000..78c1c14
--- /dev/null
+++ b/modules/openy_ds_media_library/openy_ds_media_library.info.yml
@@ -0,0 +1,9 @@
+name: Open Y Digital Signage Media Library
+type: module
+description: Provides separate Media library to Open Y Digital Signage.
+core: 8.x
+package: "OpenY: Digital Signage"
+dependencies:
+ - media_entity
+ - openy_media_image
+ - entity_browser
diff --git a/modules/openy_ds_media_library/openy_ds_media_library.install b/modules/openy_ds_media_library/openy_ds_media_library.install
new file mode 100644
index 0000000..40642dc
--- /dev/null
+++ b/modules/openy_ds_media_library/openy_ds_media_library.install
@@ -0,0 +1,33 @@
+ DigitalSignageMediaLibrary::DS_MARKER_TAG_NAME,
+ 'vid' => 'media_tags',
+ ])->save();
+}
+
+/**
+ * Implements hook_uninstall().
+ */
+function openy_ds_media_library_uninstall() {
+ /** @var Drupal\openy_ds_media_library\DigitalSignageMediaLibrary $media_library_helper */
+ $media_library_helper = \Drupal::service('openy_ds_media_library.helper');
+ $term = $media_library_helper->loadMarkerMediaTag();
+ if ($term) {
+ $storage = \Drupal::entityTypeManager()->getStorage('taxonomy_term');
+ $storage->delete([$term]);
+ }
+}
diff --git a/modules/openy_ds_media_library/openy_ds_media_library.libraries.yml b/modules/openy_ds_media_library/openy_ds_media_library.libraries.yml
new file mode 100644
index 0000000..d30a848
--- /dev/null
+++ b/modules/openy_ds_media_library/openy_ds_media_library.libraries.yml
@@ -0,0 +1,7 @@
+browser:
+ version: VERSION
+ css:
+ theme:
+ css/browser.css: {}
+ dependencies:
+ - openy_media/browser
diff --git a/modules/openy_ds_media_library/openy_ds_media_library.module b/modules/openy_ds_media_library/openy_ds_media_library.module
new file mode 100644
index 0000000..2827b94
--- /dev/null
+++ b/modules/openy_ds_media_library/openy_ds_media_library.module
@@ -0,0 +1,146 @@
+loadMarkerMediaTag();
+ $views_join_plugin_manager = Drupal::service('plugin.manager.views.join');
+
+ // digital signage media must be excluded from default media dashboard,
+ // and must be displayed on special digital signage media dashboard instead.
+ if ($term) {
+ switch ($view->id()) {
+ case 'media':
+ $definition = _openy_ds_media_library_get_media_tag_join_definition();
+ $definition['extra'][] = [
+ 'field' => 'field_media_tags_target_id',
+ 'value' => $term->id(),
+ ];
+
+ /** @var \Drupal\views\Plugin\views\join\Standard $join */
+ $join = $views_join_plugin_manager->createInstance('standard', $definition);
+ /** @var \Drupal\views\Plugin\views\query\Sql $query */
+ $query->addRelationship('media__field_media_tags', $join, 'node');
+ $query->addWhereExpression(1, 'media__field_media_tags.field_media_tags_target_id IS NULL');
+ break;
+
+ case 'digital_signage_media':
+ case 'digital_signage_images_library':
+ $definition = _openy_ds_media_library_get_media_tag_join_definition();
+ /** @var \Drupal\views\Plugin\views\join\Standard $join */
+ $join = $views_join_plugin_manager->createInstance('standard', $definition);
+ /** @var \Drupal\views\Plugin\views\query\Sql $query */
+ $query->addRelationship('media__field_media_tags', $join, 'node');
+ $query->addWhere(1, 'media__field_media_tags.field_media_tags_target_id', $term->id());
+ break;
+ }
+ }
+}
+
+/**
+ * Implements hook_form_FORM_ID_alter().
+ */
+function openy_ds_media_library_form_entity_browser_digital_signage_images_library_form_alter(&$form, FormStateInterface $form_state, $form_id) {
+ $form['#attached']['library'][] = 'openy_ds_media_library/browser';
+}
+
+/**
+ * Implements hook_preprocess_HOOK().
+ */
+function openy_ds_media_library_preprocess_views_view_grid(array &$variables) {
+ if ($variables['view']->storage->id() == 'digital_signage_images_library') {
+ foreach ($variables['items'] as &$item) {
+ foreach ($item['content'] as &$column) {
+ $column['attributes']['data-selectable'] = 'true';
+ }
+ }
+ }
+}
+
+/**
+ * Implements hook_form_FORM_ID_alter().
+ */
+function openy_ds_media_library_form_media_image_edit_form_alter(&$form, FormStateInterface $form_state, $form_id) {
+ /** @var Drupal\openy_ds_media_library\DigitalSignageMediaLibrary $media_library_helper */
+ $media_library_helper = \Drupal::service('openy_ds_media_library.helper');
+ $term = $media_library_helper->loadMarkerMediaTag();
+ /** @var \Drupal\media_entity\Entity\Media $media_entity */
+ $media_entity = $form_state->getFormObject()->getEntity();
+
+ // Digital signage media is already marked with special tag on edit.
+ if ($term && !$media_entity->get('field_media_tags')->isEmpty()) {
+ $media_tags = $media_entity->get('field_media_tags')->getValue();
+ if (in_array($term->id(), array_column($media_tags, 'target_id'))) {
+ _openy_ds_media_library_set_media_form_default_values($form);
+ }
+ }
+}
+
+/**
+ * Implements hook_inline_entity_form_entity_form_alter().
+ */
+function openy_ds_media_library_inline_entity_form_entity_form_alter(&$entity_form, &$form_state) {
+ /** @var Drupal\openy_ds_media_library\DigitalSignageMediaLibrary $media_library_helper */
+ $media_library_helper = \Drupal::service('openy_ds_media_library.helper');
+ $term = $media_library_helper->loadMarkerMediaTag();
+
+ // Automatically mark media entity created in digital signage entity browser.
+ // So we can to distinguish common media and digital signage media entities.
+ $input = $form_state->getUserInput();
+ if ($term && isset($input['form_id']) && $input['form_id'] == 'entity_browser_digital_signage_images_library_form') {
+ $entity_form['field_media_tags']['widget']['target_id']['#default_value'] = $term;
+ _openy_ds_media_library_set_media_form_default_values($entity_form);
+ }
+}
+
+/**
+ * Gets views join plugin definition for relation to media tags taxonomy.
+ *
+ * @return array
+ * The array of definition data.
+ */
+function _openy_ds_media_library_get_media_tag_join_definition() {
+ return [
+ 'table' => 'media__field_media_tags',
+ 'field' => 'entity_id',
+ 'left_table' => 'media_field_data',
+ 'left_field' => 'mid',
+ ];
+}
+
+/**
+ * Sets default values and hide unnecessary fields.
+ *
+ * @param $form
+ * Nested array of form elements that comprise the form.
+ */
+function _openy_ds_media_library_set_media_form_default_values(&$form) {
+ // @TODO most of fields will be hidden after solving of entity_browser issue.
+ // @see https://www.drupal.org/project/entity_browser/issues/2821917
+ $form['field_media_tags']['#access'] = FALSE;
+
+ $image_widget = &$form['field_media_image']['widget'];
+ $image_widget[0]['#alt_field'] = FALSE;
+ $image_widget['#title_field_required'] = FALSE;
+
+ $form['field_media_caption']['#access'] = FALSE;
+
+ $form['field_media_in_library']['widget']['value']['#default_value'] = TRUE;
+ $form['field_media_in_library']['#access'] = FALSE;
+
+ $form['langcode']['#access'] = FALSE;
+ $form['path']['#access'] = FALSE;
+ $form['revision_information']['#access'] = FALSE;
+}
diff --git a/modules/openy_ds_media_library/openy_ds_media_library.services.yml b/modules/openy_ds_media_library/openy_ds_media_library.services.yml
new file mode 100644
index 0000000..eb16180
--- /dev/null
+++ b/modules/openy_ds_media_library/openy_ds_media_library.services.yml
@@ -0,0 +1,4 @@
+services:
+ openy_ds_media_library.helper:
+ class: Drupal\openy_ds_media_library\DigitalSignageMediaLibrary
+ arguments: ['@entity_type.manager']
diff --git a/modules/openy_ds_media_library/src/DigitalSignageMediaLibrary.php b/modules/openy_ds_media_library/src/DigitalSignageMediaLibrary.php
new file mode 100644
index 0000000..c181c16
--- /dev/null
+++ b/modules/openy_ds_media_library/src/DigitalSignageMediaLibrary.php
@@ -0,0 +1,48 @@
+entityTypeManager = $entity_type_manager;
+ }
+
+ /**
+ * Loads taxonomy term which is used as marker for DS media entities.
+ *
+ * @return \Drupal\Core\Entity\EntityInterface|mixed
+ * Taxonomy term entity.
+ *
+ * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
+ */
+ public function loadMarkerMediaTag() {
+ $storage = $this->entityTypeManager->getStorage('taxonomy_term');
+ $properties = ['name' => static::DS_MARKER_TAG_NAME, 'vid' => 'media_tags'];
+ $terms = $storage->loadByProperties($properties);
+ if ($terms) {
+ return reset($terms);
+ }
+
+ return NULL;
+ }
+
+}
diff --git a/modules/openy_ds_pef_schedule/openy_ds_pef_schedule.info.yml b/modules/openy_ds_pef_schedule/openy_ds_pef_schedule.info.yml
new file mode 100644
index 0000000..ea8ba24
--- /dev/null
+++ b/modules/openy_ds_pef_schedule/openy_ds_pef_schedule.info.yml
@@ -0,0 +1,7 @@
+name: Digital Signage Classes PEF Schedule integration
+type: module
+description: Digital Signage Classes Schedule.
+core: 8.x
+package: "OpenY: Digital Signage"
+dependencies:
+ - openy_ds_room_pef
diff --git a/modules/openy_ds_pef_schedule/openy_ds_pef_schedule.services.yml b/modules/openy_ds_pef_schedule/openy_ds_pef_schedule.services.yml
new file mode 100644
index 0000000..89cf9fc
--- /dev/null
+++ b/modules/openy_ds_pef_schedule/openy_ds_pef_schedule.services.yml
@@ -0,0 +1,4 @@
+services:
+ openy_ds_pef_schedule.manager:
+ class: Drupal\openy_ds_pef_schedule\OpenYPEFScheduleManager
+ arguments: ['@entity.manager', '@entity.query', '@logger.factory', '@database']
diff --git a/modules/openy_ds_pef_schedule/src/OpenYPEFScheduleManager.php b/modules/openy_ds_pef_schedule/src/OpenYPEFScheduleManager.php
new file mode 100644
index 0000000..0d5844f
--- /dev/null
+++ b/modules/openy_ds_pef_schedule/src/OpenYPEFScheduleManager.php
@@ -0,0 +1,332 @@
+entityQuery = $entity_query;
+ $this->entityTypeManager = $entity_type_manager;
+ $this->logger = $logger_factory->get(self::CHANNEL);
+ $this->database = $database;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getClassesSchedule($period, $nextday, $location = null, $room_id = [], $category = []) {
+ $datetime = new \DateTime();
+ $datetime->setTimezone(new \DateTimeZone('UTC'));
+ $datetime->setTimestamp($period['from']);
+ $period_from = $datetime->format('c');
+ $datetime->add(new \DateInterval('P1D'));
+ $period_nextday = $datetime->format('c');
+
+ $rooms = [];
+
+ if ($room_id) {
+ foreach ($room_id as $rid) {
+ $room = $this->entityTypeManager
+ ->getStorage('openy_ds_room')
+ ->load($rid);
+
+ foreach ($room->field_room_origin as $value) {
+ if ($value->origin != 'pef') {
+ continue;
+ }
+ $rooms[] = $value->id;
+ }
+ }
+ }
+
+ if (!$location && $room) {
+ $location = $room->location->target_id;
+ }
+
+ $results = $this->getDataForADate($period_from, $location, $rooms, $category);
+ switch ($nextday) {
+ case static::NEXT_DAY_ALWAYS:
+ $results_nd = $this->getDataForADate($period_nextday, $location, $rooms, $category);
+ foreach ($results_nd as $result) {
+ $results[] = $result;
+ }
+ break;
+ case static::NEXT_DAY_IF_EMPTY:
+ if (!$results) {
+ $results = $this->getDataForADate($period_nextday, $location, $rooms, $category);
+ }
+ break;
+ }
+
+ return $results;
+ }
+
+ /**
+ * Retrieves class schedule for a whole day.
+ *
+ * @param string $date
+ * Date string.
+ * @param $location
+ * Location Id
+ * @param array $rooms
+ * @param array $category
+ *
+ * @return array
+ */
+ private function getDataForADate($date, $location, $rooms = [], $category = []) {
+ $date = strtotime($date);
+
+ $year = date('Y', $date);
+ $month = date('m', $date);
+ $day = date('d', $date);
+ $week = date('W', $date);
+ $weekday = date('N', $date);
+
+ $timestamp_start = $date;
+ // Next day.
+ $timestamp_end = $date + 24 * 60 * 60;
+
+ $sql = "SELECT DISTINCT
+ n.nid,
+ re.id,
+ nd.title as location,
+ nds.title as name,
+ re.class,
+ re.session,
+ re.room,
+ re.instructor as instructor,
+ re.category,
+ re.register_url as register_url,
+ re.register_text as register_text,
+ re.start as start_timestamp,
+ re.end as end_timestamp,
+ re.duration as duration
+ FROM {node} n
+ RIGHT JOIN {repeat_event} re ON re.session = n.nid
+ INNER JOIN node_field_data nd ON re.location = nd.nid
+ INNER JOIN node_field_data nds ON n.nid = nds.nid
+ WHERE
+ n.type = 'session'
+ AND
+ (
+ (re.year = :year OR re.year = '*')
+ AND
+ (re.month = :month OR re.month = '*')
+ AND
+ (re.day = :day OR re.day = '*')
+ AND
+ (re.week = :week OR re.week = '*')
+ AND
+ (re.weekday = :weekday OR re.weekday = '*')
+ AND
+ (re.start <= :timestamp_end)
+ AND
+ (re.end >= :timestamp_start)
+ AND
+ (re.location = :location)
+ )";
+
+ $values = [];
+ if (!empty($category)) {
+ $sql .= "AND re.category IN ( :categories[] )";
+ $values[':categories[]'] = $category;
+ }
+
+ if (!empty($rooms)) {
+ $sql .= "AND re.room IN ( :rooms[] )";
+ $values[':rooms[]'] = $rooms;
+ }
+
+ $values[':location'] = $location;
+ $values[':year'] = $year;
+ $values[':month'] = $month;
+ $values[':day'] = $day;
+ $values[':week'] = $week;
+ $values[':weekday'] = $weekday;
+ $values[':timestamp_start'] = $timestamp_start;
+ $values[':timestamp_end'] = $timestamp_end;
+
+ $query = $this->database->query($sql, $values);
+ $results = $query->fetchAll();
+
+ $classes = [];
+ foreach ($results as $result) {
+ $from = $result->start_timestamp;
+ $to = $result->end_timestamp;
+ $from_str = $year . '-' . $month . '-' . $day . ' ' . date('H:i:s', $from);
+ $to_str = $year . '-' . $month . '-' . $day . ' ' . date('H:i:s', $to);
+ $duration_str = $result->duration . 'm';
+ if ($result->duration > 90) {
+ $duration_str = intval($result->duration / 60) . 'h ' . ($result->duration % 60) . 'm';
+ }
+ $from = strtotime($from_str);
+ $to = strtotime($to_str);
+ $classes[] = [
+ 'from' => $from,
+ 'to' => $to,
+ 'duration_raw' => $result->duration,
+ 'duration' => $duration_str,
+ 'room' => $result->room,
+ 'trainer' => $this->prepareTrainerName($result->instructor),
+ 'substitute_trainer' => '',
+ 'name' => $this->prepareClassName($result->name),
+ 'from_formatted' => date('g:ia', $from),
+ 'to_formatted' => date('g:ia', $to),
+ ];
+ }
+
+ usort($classes, function ($a, $b) {
+ if ($a['from'] == $b['from']) {
+ return 0;
+ }
+ return ($a['from'] < $b['from']) ? -1 : 1;
+ });
+
+ return $classes;
+ }
+
+ /**
+ * Prepare class name to display.
+ *
+ * @param string $name
+ * Class name.
+ *
+ * @return string
+ * Prepared to display class name.
+ */
+ protected function prepareClassName($name) {
+ $name = str_replace('®', '
®', trim($name));
+ $name = str_replace('™', '
™', $name);
+
+ return $name;
+ }
+
+ /**
+ * Truncate last name into short version.
+ *
+ * @param string $name
+ * Trainer name.
+ *
+ * @return string
+ * Return first name and only first letter of last name.
+ */
+ protected function prepareTrainerName($name) {
+ $new_name = '';
+ if (empty($name)) {
+ return $new_name;
+ }
+ // Divide name into 2 parts.
+ $array = explode(' ', trim($name));
+ $array = array_values(array_filter($array, 'trim'));
+ // Add first name to the new name.
+ $new_name .= $array[0];
+ if (empty($array[1])) {
+ return $new_name;
+ }
+ // Verify is last name full or already cut to one symbol and point.
+ if (strlen($array[1]) == 2 && substr($array[1], 1, 1) == '.') {
+ // Leave as is.
+ $new_name .= ' ' . $array[1];
+ }
+ else {
+ // Add only first latter of last name..
+ $new_name .= ' ' . strtoupper(substr($array[1], 0, 1)) . '.';
+ }
+
+ return $new_name;
+ }
+
+ public function getAllCategories() {
+ $query = $this->database
+ ->select('node_field_data', 'n')
+ ->fields('n', ['title'])
+ ->condition('n.type', 'activity')
+ ->condition('n.status', NodeInterface::PUBLISHED)
+ ->orderBy('n.title', 'ASC');
+
+ $result = $query->execute()->fetchAllKeyed(0, 0);
+ natsort($result);
+
+ return $result;
+ }
+
+ /**
+ * Returns NEXT_DAY_NEVER constant.
+ *
+ * @return int
+ */
+ public static function getNextDayNever() {
+ return static::NEXT_DAY_NEVER;
+ }
+
+ /**
+ * Returns NEXT_DAY_ALWAYS constant.
+ *
+ * @return int
+ */
+ public static function getNextDayAlways() {
+ return static::NEXT_DAY_ALWAYS;
+ }
+
+ /**
+ * Returns NEXT_DAY_IF_EMPTY constant.
+ *
+ * @return int
+ */
+ public static function getNextDayIfEmpty() {
+ return static::NEXT_DAY_IF_EMPTY;
+ }
+
+}
diff --git a/modules/openy_ds_pef_schedule/src/OpenYPEFScheduleManagerInterface.php b/modules/openy_ds_pef_schedule/src/OpenYPEFScheduleManagerInterface.php
new file mode 100644
index 0000000..aba91a8
--- /dev/null
+++ b/modules/openy_ds_pef_schedule/src/OpenYPEFScheduleManagerInterface.php
@@ -0,0 +1,31 @@
+