From 6397ec545284d3e19dfbaeffc7331cbc7d9bd9c9 Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Tue, 5 Sep 2017 15:14:00 +0800 Subject: [PATCH 1/9] MDL-59392 calendar: ViewManager should take a root --- calendar/amd/build/calendar.min.js | 2 +- calendar/amd/build/view_manager.min.js | 2 +- calendar/amd/src/calendar.js | 12 ++++++------ calendar/amd/src/view_manager.js | 18 ++++++++---------- 4 files changed, 16 insertions(+), 18 deletions(-) diff --git a/calendar/amd/build/calendar.min.js b/calendar/amd/build/calendar.min.js index aac1c29032b..19997029788 100644 --- a/calendar/amd/build/calendar.min.js +++ b/calendar/amd/build/calendar.min.js @@ -1 +1 @@ -define(["jquery","core/ajax","core/str","core/templates","core/notification","core/custom_interaction_events","core/modal_events","core/modal_factory","core_calendar/modal_event_form","core_calendar/summary_modal","core_calendar/repository","core_calendar/events","core_calendar/view_manager"],function(a,b,c,d,e,f,g,h,i,j,k,l,m){var n={ROOT:"[data-region='calendar']",DAY:"[data-region='day']",EVENT_ITEM:"[data-region='event-item']",EVENT_LINK:"[data-action='view-event']",NEW_EVENT_BUTTON:"[data-action='new-event-button']",DAY_CONTENT:"[data-region='day-content']",LOADING_ICON:".loading-icon",VIEW_DAY_LINK:"[data-action='view-day-link']",CALENDAR_MONTH_WRAPPER:".calendarwrapper",COURSE_SELECTOR:'select[name="course"]'},o=function(a){var b="type"+a;return c.get_string(b,"core_calendar").then(function(a){return a})},p=function(a){return c.get_string("subsource","core_calendar",a).then(function(b){return a.url?''+b+"":b})},q=function(b){k.getEventById(b).then(function(c){if(!c.event)throw new Error("Error encountered while trying to fetch calendar event with ID: "+b);var d=c.event,e=o(d.eventtype);if(d.displayeventsource){d.subscription=JSON.parse(d.subscription);var f={url:d.subscription.url,name:d.subscription.name},g=p(f);return a.when(e,g).then(function(a,b){return d.eventtype=a,d.source=b,d})}return e.then(function(a){return d.eventtype=a,d})}).then(function(a){var b={title:a.name,type:j.TYPE,body:d.render("core_calendar/event_summary_body",a),templateContext:{canedit:a.canedit,candelete:a.candelete,isactionevent:a.isactionevent,url:a.url}};return h.create(b)}).done(function(a){a.getRoot().on(g.hidden,function(){a.destroy()}),a.show()}).fail(e.exception)},r=function(b,c,f,g){var h=null,i=g.attr("data-day-timestamp");f&&(h=f.attr("data-day-timestamp")),f&&h==i||d.render("core/loading",{}).then(function(a,b){g.find(n.DAY_CONTENT).addClass("hidden"),d.appendNodeContents(g,a,b),f&&(f.find(n.DAY_CONTENT).addClass("hidden"),d.appendNodeContents(f,a,b))}).then(function(){return k.updateEventStartDay(c,i)}).then(function(){a("body").trigger(l.eventMoved,[c,f,g])}).always(function(){var a=g.find(n.LOADING_ICON);if(g.find(n.DAY_CONTENT).removeClass("hidden"),d.replaceNode(a,"",""),f){var b=f.find(n.LOADING_ICON);f.find(n.DAY_CONTENT).removeClass("hidden"),d.replaceNode(b,"","")}}).fail(e.exception)},s=function(a){var b=a.find(n.NEW_EVENT_BUTTON),c=b.attr("data-context-id");return h.create({type:i.TYPE,large:!0,templateContext:{contextid:c}},[a,n.NEW_EVENT_BUTTON])},t=function(b,c){var d=a("body"),e=a(b).find(n.CALENDAR_MONTH_WRAPPER).data("courseid");d.on(l.created,function(){m.reloadCurrentMonth(b)}),d.on(l.deleted,function(){m.reloadCurrentMonth(b)}),d.on(l.updated,function(){m.reloadCurrentMonth(b)}),d.on(l.editActionEvent,function(a,b){window.location.assign(b)}),d.on(l.moveEvent,r),d.on(l.eventMoved,function(){m.reloadCurrentMonth(b)}),c.then(function(a){d.on(l.editEvent,function(b,c){a.setEventId(c),a.show()}),a.setCourseId(e)})},u=function(){var b=a(n.ROOT);b.on("click",n.EVENT_ITEM,function(b){b.preventDefault(),b.stopPropagation();var c=a(b.target),d=null;d=c.is(n.EVENT_LINK)?c.attr("data-event-id"):c.find(n.EVENT_LINK).attr("data-event-id"),q(d)}),b.on("change",n.COURSE_SELECTOR,function(){var c=a(this),d=c.val();m.reloadCurrentMonth(b,d).then(function(){return b.find(n.COURSE_SELECTOR).val(d)}).fail(e.exception)});var c=s(b);t(b,c),b.on("click",n.DAY,function(b){var d=a(b.target);if(!d.is(n.VIEW_DAY_LINK)){var e=a(this).attr("data-new-event-timestamp");c.then(function(a){a.setStartTime(e),a.show()}),b.preventDefault()}})};return{init:function(){m.init(),u()}}}); \ No newline at end of file +define(["jquery","core/ajax","core/str","core/templates","core/notification","core/custom_interaction_events","core/modal_events","core/modal_factory","core_calendar/modal_event_form","core_calendar/summary_modal","core_calendar/repository","core_calendar/events","core_calendar/view_manager"],function(a,b,c,d,e,f,g,h,i,j,k,l,m){var n={ROOT:"[data-region='calendar']",DAY:"[data-region='day']",EVENT_ITEM:"[data-region='event-item']",EVENT_LINK:"[data-action='view-event']",NEW_EVENT_BUTTON:"[data-action='new-event-button']",DAY_CONTENT:"[data-region='day-content']",LOADING_ICON:".loading-icon",VIEW_DAY_LINK:"[data-action='view-day-link']",CALENDAR_MONTH_WRAPPER:".calendarwrapper",COURSE_SELECTOR:'select[name="course"]'},o=function(a){var b="type"+a;return c.get_string(b,"core_calendar").then(function(a){return a})},p=function(a){return c.get_string("subsource","core_calendar",a).then(function(b){return a.url?''+b+"":b})},q=function(b){k.getEventById(b).then(function(c){if(!c.event)throw new Error("Error encountered while trying to fetch calendar event with ID: "+b);var d=c.event,e=o(d.eventtype);if(d.displayeventsource){d.subscription=JSON.parse(d.subscription);var f={url:d.subscription.url,name:d.subscription.name},g=p(f);return a.when(e,g).then(function(a,b){return d.eventtype=a,d.source=b,d})}return e.then(function(a){return d.eventtype=a,d})}).then(function(a){var b={title:a.name,type:j.TYPE,body:d.render("core_calendar/event_summary_body",a),templateContext:{canedit:a.canedit,candelete:a.candelete,isactionevent:a.isactionevent,url:a.url}};return h.create(b)}).done(function(a){a.getRoot().on(g.hidden,function(){a.destroy()}),a.show()}).fail(e.exception)},r=function(b,c,f,g){var h=null,i=g.attr("data-day-timestamp");f&&(h=f.attr("data-day-timestamp")),f&&h==i||d.render("core/loading",{}).then(function(a,b){g.find(n.DAY_CONTENT).addClass("hidden"),d.appendNodeContents(g,a,b),f&&(f.find(n.DAY_CONTENT).addClass("hidden"),d.appendNodeContents(f,a,b))}).then(function(){return k.updateEventStartDay(c,i)}).then(function(){a("body").trigger(l.eventMoved,[c,f,g])}).always(function(){var a=g.find(n.LOADING_ICON);if(g.find(n.DAY_CONTENT).removeClass("hidden"),d.replaceNode(a,"",""),f){var b=f.find(n.LOADING_ICON);f.find(n.DAY_CONTENT).removeClass("hidden"),d.replaceNode(b,"","")}}).fail(e.exception)},s=function(a){var b=a.find(n.NEW_EVENT_BUTTON),c=b.attr("data-context-id");return h.create({type:i.TYPE,large:!0,templateContext:{contextid:c}},[a,n.NEW_EVENT_BUTTON])},t=function(b,c){var d=a("body"),e=a(b).find(n.CALENDAR_MONTH_WRAPPER).data("courseid");d.on(l.created,function(){m.reloadCurrentMonth(b)}),d.on(l.deleted,function(){m.reloadCurrentMonth(b)}),d.on(l.updated,function(){m.reloadCurrentMonth(b)}),d.on(l.editActionEvent,function(a,b){window.location.assign(b)}),d.on(l.moveEvent,r),d.on(l.eventMoved,function(){m.reloadCurrentMonth(b)}),c.then(function(a){d.on(l.editEvent,function(b,c){a.setEventId(c),a.show()}),a.setCourseId(e)})},u=function(b){b.on("click",n.EVENT_ITEM,function(b){b.preventDefault(),b.stopPropagation();var c=a(b.target),d=null;d=c.is(n.EVENT_LINK)?c.attr("data-event-id"):c.find(n.EVENT_LINK).attr("data-event-id"),q(d)}),b.on("change",n.COURSE_SELECTOR,function(){var c=a(this),d=c.val();m.reloadCurrentMonth(b,d).then(function(){return b.find(n.COURSE_SELECTOR).val(d)}).fail(e.exception)});var c=s(b);t(b,c),b.on("click",n.DAY,function(b){var d=a(b.target);if(!d.is(n.VIEW_DAY_LINK)){var e=a(this).attr("data-new-event-timestamp");c.then(function(a){a.setStartTime(e),a.show()}),b.preventDefault()}})};return{init:function(b){b=a(b),m.init(b),u(b)}}}); \ No newline at end of file diff --git a/calendar/amd/build/view_manager.min.js b/calendar/amd/build/view_manager.min.js index d50282461f1..1d8bdff35b2 100644 --- a/calendar/amd/build/view_manager.min.js +++ b/calendar/amd/build/view_manager.min.js @@ -1 +1 @@ -define(["jquery","core/templates","core/notification","core_calendar/repository","core_calendar/events"],function(a,b,c,d,e){var f={ROOT:"[data-region='calendar']",CALENDAR_NAV_LINK:".calendarwrapper .arrow_link",CALENDAR_MONTH_WRAPPER:".calendarwrapper",LOADING_ICON_CONTAINER:'[data-region="overlay-icon-container"]'},g=function(b){b=a(b),b.on("click",f.CALENDAR_NAV_LINK,function(c){var d=a(b).find(f.CALENDAR_MONTH_WRAPPER).data("courseid"),e=a(c.currentTarget);i(e.attr("href"),e.data("time"),d),c.preventDefault()})},h=function(e,g){var h=a(f.ROOT);return k(h),d.getCalendarMonthData(e,g).then(function(a){return b.render("core_calendar/month_detailed",a)}).then(function(a,c){return b.replaceNode(f.CALENDAR_MONTH_WRAPPER,a,c)}).always(function(){return l(h)}).fail(c.exception)},i=function(b,c,d){return h(c,d).then(function(){return window.history.pushState({},"",b),arguments}).then(function(){return a("body").trigger(e.monthChanged,[c,d]),arguments})},j=function(a,b){var c=a.find(f.CALENDAR_MONTH_WRAPPER).data("current-time");return b||(b=a.find(f.CALENDAR_MONTH_WRAPPER).data("courseid")),h(c,b)},k=function(a){var b=a.find(f.LOADING_ICON_CONTAINER);b.removeClass("hidden")},l=function(a){var b=a.find(f.LOADING_ICON_CONTAINER);b.addClass("hidden")};return{init:function(){g(f.ROOT)},reloadCurrentMonth:j,changeMonth:i,refreshMonthContent:h}}); \ No newline at end of file +define(["jquery","core/templates","core/notification","core_calendar/repository","core_calendar/events"],function(a,b,c,d,e){var f={ROOT:"[data-region='calendar']",CALENDAR_NAV_LINK:".calendarwrapper .arrow_link",CALENDAR_MONTH_WRAPPER:".calendarwrapper",LOADING_ICON_CONTAINER:'[data-region="overlay-icon-container"]'},g=function(b){b=a(b),b.on("click",f.CALENDAR_NAV_LINK,function(c){var d=a(b).find(f.CALENDAR_MONTH_WRAPPER).data("courseid"),e=a(c.currentTarget);i(b,e.attr("href"),e.data("time"),d),c.preventDefault()})},h=function(a,e,g){return k(a),d.getCalendarMonthData(e,g).then(function(a){return b.render("core_calendar/month_detailed",a)}).then(function(c,d){return b.replaceNode(a.find(f.CALENDAR_MONTH_WRAPPER),c,d)}).always(function(){return l(a)}).fail(c.exception)},i=function(b,c,d,f){return h(b,d,f).then(function(){return window.history.pushState({},"",c),arguments}).then(function(){return a("body").trigger(e.monthChanged,[d,f]),arguments})},j=function(a,b){var c=a.find(f.CALENDAR_MONTH_WRAPPER).data("current-time");return b||(b=a.find(f.CALENDAR_MONTH_WRAPPER).data("courseid")),h(a,c,b)},k=function(a){var b=a.find(f.LOADING_ICON_CONTAINER);b.removeClass("hidden")},l=function(a){var b=a.find(f.LOADING_ICON_CONTAINER);b.addClass("hidden")};return{init:function(a){g(a)},reloadCurrentMonth:j,changeMonth:i,refreshMonthContent:h}}); \ No newline at end of file diff --git a/calendar/amd/src/calendar.js b/calendar/amd/src/calendar.js index 947bac06cdb..2958c837534 100644 --- a/calendar/amd/src/calendar.js +++ b/calendar/amd/src/calendar.js @@ -296,9 +296,7 @@ define([ /** * Register event listeners for the module. */ - var registerEventListeners = function() { - var root = $(SELECTORS.ROOT); - + var registerEventListeners = function(root) { // Bind click events to event links. root.on('click', SELECTORS.EVENT_ITEM, function(e) { e.preventDefault(); @@ -350,9 +348,11 @@ define([ }; return { - init: function() { - CalendarViewManager.init(); - registerEventListeners(); + init: function(root) { + root = $(root); + + CalendarViewManager.init(root); + registerEventListeners(root); } }; }); diff --git a/calendar/amd/src/view_manager.js b/calendar/amd/src/view_manager.js index 5604d6eeb6d..f1468613d75 100644 --- a/calendar/amd/src/view_manager.js +++ b/calendar/amd/src/view_manager.js @@ -42,7 +42,7 @@ define(['jquery', 'core/templates', 'core/notification', 'core_calendar/reposito root.on('click', SELECTORS.CALENDAR_NAV_LINK, function(e) { var courseId = $(root).find(SELECTORS.CALENDAR_MONTH_WRAPPER).data('courseid'); var link = $(e.currentTarget); - changeMonth(link.attr('href'), link.data('time'), courseId); + changeMonth(root, link.attr('href'), link.data('time'), courseId); e.preventDefault(); }); @@ -55,9 +55,7 @@ define(['jquery', 'core/templates', 'core/notification', 'core_calendar/reposito * @param {Number} courseid The id of the course whose events are shown * @return {promise} */ - var refreshMonthContent = function(time, courseid) { - var root = $(SELECTORS.ROOT); - + var refreshMonthContent = function(root, time, courseid) { startLoading(root); return CalendarRepository.getCalendarMonthData(time, courseid) @@ -65,7 +63,7 @@ define(['jquery', 'core/templates', 'core/notification', 'core_calendar/reposito return Templates.render('core_calendar/month_detailed', context); }) .then(function(html, js) { - return Templates.replaceNode(SELECTORS.CALENDAR_MONTH_WRAPPER, html, js); + return Templates.replaceNode(root.find(SELECTORS.CALENDAR_MONTH_WRAPPER), html, js); }) .always(function() { return stopLoading(root); @@ -81,8 +79,8 @@ define(['jquery', 'core/templates', 'core/notification', 'core_calendar/reposito * @param {Number} courseid The id of the course whose events are shown * @return {promise} */ - var changeMonth = function(url, time, courseid) { - return refreshMonthContent(time, courseid) + var changeMonth = function(root, url, time, courseid) { + return refreshMonthContent(root, time, courseid) .then(function() { window.history.pushState({}, '', url); return arguments; @@ -106,7 +104,7 @@ define(['jquery', 'core/templates', 'core/notification', 'core_calendar/reposito if (!courseId) { courseId = root.find(SELECTORS.CALENDAR_MONTH_WRAPPER).data('courseid'); } - return refreshMonthContent(time, courseId); + return refreshMonthContent(root, time, courseId); }; /** @@ -134,8 +132,8 @@ define(['jquery', 'core/templates', 'core/notification', 'core_calendar/reposito }; return { - init: function() { - registerEventListeners(SELECTORS.ROOT); + init: function(root) { + registerEventListeners(root); }, reloadCurrentMonth: reloadCurrentMonth, changeMonth: changeMonth, From 2281a835c9886af92e3517a024824b6592fc3c7b Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Tue, 5 Sep 2017 15:14:54 +0800 Subject: [PATCH 2/9] MDL-59392 calendar: Move template to parent Node --- calendar/amd/build/view_manager.min.js | 2 +- calendar/amd/src/view_manager.js | 2 +- calendar/lib.php | 2 +- calendar/templates/calendar_month.mustache | 41 ++++++++++++++++++++++ calendar/view.php | 1 - 5 files changed, 44 insertions(+), 4 deletions(-) create mode 100644 calendar/templates/calendar_month.mustache diff --git a/calendar/amd/build/view_manager.min.js b/calendar/amd/build/view_manager.min.js index 1d8bdff35b2..62a980bc34e 100644 --- a/calendar/amd/build/view_manager.min.js +++ b/calendar/amd/build/view_manager.min.js @@ -1 +1 @@ -define(["jquery","core/templates","core/notification","core_calendar/repository","core_calendar/events"],function(a,b,c,d,e){var f={ROOT:"[data-region='calendar']",CALENDAR_NAV_LINK:".calendarwrapper .arrow_link",CALENDAR_MONTH_WRAPPER:".calendarwrapper",LOADING_ICON_CONTAINER:'[data-region="overlay-icon-container"]'},g=function(b){b=a(b),b.on("click",f.CALENDAR_NAV_LINK,function(c){var d=a(b).find(f.CALENDAR_MONTH_WRAPPER).data("courseid"),e=a(c.currentTarget);i(b,e.attr("href"),e.data("time"),d),c.preventDefault()})},h=function(a,e,g){return k(a),d.getCalendarMonthData(e,g).then(function(a){return b.render("core_calendar/month_detailed",a)}).then(function(c,d){return b.replaceNode(a.find(f.CALENDAR_MONTH_WRAPPER),c,d)}).always(function(){return l(a)}).fail(c.exception)},i=function(b,c,d,f){return h(b,d,f).then(function(){return window.history.pushState({},"",c),arguments}).then(function(){return a("body").trigger(e.monthChanged,[d,f]),arguments})},j=function(a,b){var c=a.find(f.CALENDAR_MONTH_WRAPPER).data("current-time");return b||(b=a.find(f.CALENDAR_MONTH_WRAPPER).data("courseid")),h(a,c,b)},k=function(a){var b=a.find(f.LOADING_ICON_CONTAINER);b.removeClass("hidden")},l=function(a){var b=a.find(f.LOADING_ICON_CONTAINER);b.addClass("hidden")};return{init:function(a){g(a)},reloadCurrentMonth:j,changeMonth:i,refreshMonthContent:h}}); \ No newline at end of file +define(["jquery","core/templates","core/notification","core_calendar/repository","core_calendar/events"],function(a,b,c,d,e){var f={ROOT:"[data-region='calendar']",CALENDAR_NAV_LINK:".calendarwrapper .arrow_link",CALENDAR_MONTH_WRAPPER:".calendarwrapper",LOADING_ICON_CONTAINER:'[data-region="overlay-icon-container"]'},g=function(b){b=a(b),b.on("click",f.CALENDAR_NAV_LINK,function(c){var d=a(b).find(f.CALENDAR_MONTH_WRAPPER).data("courseid"),e=a(c.currentTarget);i(b,e.attr("href"),e.data("time"),d),c.preventDefault()})},h=function(a,e,g){return k(a),d.getCalendarMonthData(e,g).then(function(c){return b.render(a.attr("data-template"),c)}).then(function(c,d){return b.replaceNode(a.find(f.CALENDAR_MONTH_WRAPPER),c,d)}).always(function(){return l(a)}).fail(c.exception)},i=function(b,c,d,f){return h(b,d,f).then(function(){return window.history.pushState({},"",c),arguments}).then(function(){return a("body").trigger(e.monthChanged,[d,f]),arguments})},j=function(a,b){var c=a.find(f.CALENDAR_MONTH_WRAPPER).data("current-time");return b||(b=a.find(f.CALENDAR_MONTH_WRAPPER).data("courseid")),h(a,c,b)},k=function(a){var b=a.find(f.LOADING_ICON_CONTAINER);b.removeClass("hidden")},l=function(a){var b=a.find(f.LOADING_ICON_CONTAINER);b.addClass("hidden")};return{init:function(a){g(a)},reloadCurrentMonth:j,changeMonth:i,refreshMonthContent:h}}); \ No newline at end of file diff --git a/calendar/amd/src/view_manager.js b/calendar/amd/src/view_manager.js index f1468613d75..58f9ac788ff 100644 --- a/calendar/amd/src/view_manager.js +++ b/calendar/amd/src/view_manager.js @@ -60,7 +60,7 @@ define(['jquery', 'core/templates', 'core/notification', 'core_calendar/reposito return CalendarRepository.getCalendarMonthData(time, courseid) .then(function(context) { - return Templates.render('core_calendar/month_detailed', context); + return Templates.render(root.attr('data-template'), context); }) .then(function(html, js) { return Templates.replaceNode(root.find(SELECTORS.CALENDAR_MONTH_WRAPPER), html, js); diff --git a/calendar/lib.php b/calendar/lib.php index f574472f314..8df62f0b91d 100644 --- a/calendar/lib.php +++ b/calendar/lib.php @@ -3518,7 +3518,7 @@ function calendar_get_view(\calendar_information $calendar, $view) { $month = new \core_calendar\external\month_exporter($calendar, $type, $related); $data = $month->export($renderer); - $template = 'core_calendar/month_detailed'; + $template = 'core_calendar/calendar_month'; return [$data, $template]; } diff --git a/calendar/templates/calendar_month.mustache b/calendar/templates/calendar_month.mustache new file mode 100644 index 00000000000..9e5866b68be --- /dev/null +++ b/calendar/templates/calendar_month.mustache @@ -0,0 +1,41 @@ +{{! + This file is part of Moodle - http://moodle.org/ + + Moodle is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Moodle is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Moodle. If not, see . +}} +{{! + @template calendar/calendar_month + + Calendar month view for blcoks. + + The purpose of this template is to render the main, detailed monthly view. + + Classes required for JS: + * none + + Data attributes required for JS: + * none + + Example context (json): + { + } +}} +
+ {{> core_calendar/month_detailed}} +
+{{#js}} +require(['jquery', 'core_calendar/calendar'], function($, Calendar) { + Calendar.init($("#calendar-month-{{uniqid}}")); +}); +{{/js}} diff --git a/calendar/view.php b/calendar/view.php index ba0bc947c6d..6447c8d906a 100644 --- a/calendar/view.php +++ b/calendar/view.php @@ -161,5 +161,4 @@ echo html_writer::end_tag('div'); list($data, $template) = calendar_get_footer_options($calendar); echo $renderer->render_from_template($template, $data); -$PAGE->requires->js_call_amd('core_calendar/calendar', 'init'); echo $OUTPUT->footer(); From fb9be2712798045a3d81f005828038ebb55e0895 Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Mon, 11 Sep 2017 09:57:54 +0800 Subject: [PATCH 3/9] MDL-59392 calendar: Split day exporter to week exporter --- calendar/classes/external/day_exporter.php | 8 - .../classes/external/week_day_exporter.php | 180 ++++++++++++++++++ calendar/classes/external/week_exporter.php | 4 +- 3 files changed, 182 insertions(+), 10 deletions(-) create mode 100644 calendar/classes/external/week_day_exporter.php diff --git a/calendar/classes/external/day_exporter.php b/calendar/classes/external/day_exporter.php index 4a713bc0d9a..eec64847461 100644 --- a/calendar/classes/external/day_exporter.php +++ b/calendar/classes/external/day_exporter.php @@ -85,14 +85,6 @@ class day_exporter extends exporter { 'neweventtimestamp' => [ 'type' => PARAM_INT, ], - 'istoday' => [ - 'type' => PARAM_BOOL, - 'default' => false, - ], - 'isweekend' => [ - 'type' => PARAM_BOOL, - 'default' => false, - ], 'viewdaylink' => [ 'type' => PARAM_URL, 'optional' => true, diff --git a/calendar/classes/external/week_day_exporter.php b/calendar/classes/external/week_day_exporter.php new file mode 100644 index 00000000000..67442f55296 --- /dev/null +++ b/calendar/classes/external/week_day_exporter.php @@ -0,0 +1,180 @@ +. + +/** + * Contains event class for displaying the day on month view. + * + * @package core_calendar + * @copyright 2017 Andrew Nicols + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace core_calendar\external; + +defined('MOODLE_INTERNAL') || die(); + +use renderer_base; +use moodle_url; + +/** + * Class for displaying the day on month view. + * + * @package core_calendar + * @copyright 2017 Andrew Nicols + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class week_day_exporter extends day_exporter { + + /** + * Return the list of additional properties. + * + * @return array + */ + protected static function define_other_properties() { + $return = parent::define_other_properties(); + $return = array_merge($return, [ + 'timestamp' => [ + 'type' => PARAM_INT, + ], + 'neweventtimestamp' => [ + 'type' => PARAM_INT, + ], + 'viewdaylink' => [ + 'type' => PARAM_URL, + 'optional' => true, + ], + 'calendareventtypes' => [ + 'type' => PARAM_RAW, + 'multiple' => true, + ], + 'popovertitle' => [ + 'type' => PARAM_RAW, + 'default' => '', + ], + 'haslastdayofevent' => [ + 'type' => PARAM_BOOL, + 'default' => false, + ], + ]); + + return $return; + } + + /** + * Get the additional values to inject while exporting. + * + * @param renderer_base $output The renderer. + * @return array Keys are the property names, values are their values. + */ + protected function get_other_values(renderer_base $output) { + $timestamp = $this->data[0]; + // Need to account for user's timezone. + $usernow = usergetdate(time()); + $today = new \DateTimeImmutable(); + // The start time should use the day's date but the current + // time of the day (adjusted for user's timezone). + $neweventstarttime = $today->setTimestamp($timestamp)->setTime( + $usernow['hours'], + $usernow['minutes'], + $usernow['seconds'] + ); + + $return = [ + 'timestamp' => $timestamp, + 'neweventtimestamp' => $neweventstarttime->getTimestamp() + ]; + + $url = new moodle_url('/calendar/view.php', [ + 'view' => 'day', + 'time' => $timestamp, + 'course' => $this->calendar->course->id, + ]); + $return['viewdaylink'] = $url->out(false); + + $cache = $this->related['cache']; + $eventexporters = array_map(function($event) use ($cache, $output, $url) { + $context = $cache->get_context($event); + $course = $cache->get_course($event); + $exporter = new calendar_event_exporter($event, [ + 'context' => $context, + 'course' => $course, + 'daylink' => $url, + 'type' => $this->related['type'], + 'today' => $this->data[0], + ]); + + return $exporter; + }, $this->related['events']); + + $return['events'] = array_map(function($exporter) use ($output) { + return $exporter->export($output); + }, $eventexporters); + + if ($popovertitle = $this->get_popover_title()) { + $return['popovertitle'] = $popovertitle; + } + + $return['calendareventtypes'] = array_map(function($exporter) { + return $exporter->get_calendar_event_type(); + }, $eventexporters); + $return['calendareventtypes'] = array_values(array_unique($return['calendareventtypes'])); + + $return['haslastdayofevent'] = false; + foreach ($return['events'] as $event) { + if ($event->islastday) { + $return['haslastdayofevent'] = true; + break; + } + } + + return $return; + } + + /** + * Returns a list of objects that are related. + * + * @return array + */ + protected static function define_related() { + return [ + 'events' => '\core_calendar\local\event\entities\event_interface[]', + 'cache' => '\core_calendar\external\events_related_objects_cache', + 'type' => '\core_calendar\type_base', + ]; + } + + /** + * Get the title for this popover. + * + * @return string + */ + protected function get_popover_title() { + $title = null; + + $userdate = userdate($this->data[0], get_string('strftimedayshort')); + if (count($this->related['events'])) { + $title = get_string('eventsfor', 'calendar', $userdate); + } else if ($this->data['istoday']) { + $title = $userdate; + } + + if ($this->data['istoday']) { + $title = get_string('todayplustitle', 'calendar', $userdate); + } + + return $title; + } +} diff --git a/calendar/classes/external/week_exporter.php b/calendar/classes/external/week_exporter.php index afc92b2f012..b8bb4da63fc 100644 --- a/calendar/classes/external/week_exporter.php +++ b/calendar/classes/external/week_exporter.php @@ -85,7 +85,7 @@ class week_exporter extends exporter { 'multiple' => true, ], 'days' => [ - 'type' => day_exporter::read_properties_definition(), + 'type' => week_day_exporter::read_properties_definition(), 'multiple' => true, ], ]; @@ -132,7 +132,7 @@ class week_exporter extends exporter { $events[] = $event; } - $day = new day_exporter($daydata, [ + $day = new week_day_exporter($daydata, [ 'events' => $events, 'cache' => $this->related['cache'], 'type' => $this->related['type'], From 39e40fda71a1aa40e9f9a4a70703b0a0913f136e Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Tue, 5 Sep 2017 15:17:50 +0800 Subject: [PATCH 4/9] MDL-59392 calendar: Add the calendar info to the exporter --- calendar/classes/external/day_exporter.php | 18 ++++++++++++++++++ calendar/classes/external/month_exporter.php | 4 ++-- calendar/classes/external/week_exporter.php | 10 +++++++++- 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/calendar/classes/external/day_exporter.php b/calendar/classes/external/day_exporter.php index eec64847461..90b5c73e3ae 100644 --- a/calendar/classes/external/day_exporter.php +++ b/calendar/classes/external/day_exporter.php @@ -39,6 +39,24 @@ use moodle_url; */ class day_exporter extends exporter { + /** + * @var \calendar_information $calendar The calendar being displayed. + */ + protected $calendar; + + /** + * Constructor. + * + * @param \calendar_information $calendar The calendar information for the period being displayed + * @param mixed $data Either an stdClass or an array of values. + * @param array $related Related objects. + */ + public function __construct(\calendar_information $calendar, $data, $related) { + $this->calendar = $calendar; + + parent::__construct($data, $related); + } + /** * Return the list of properties. * diff --git a/calendar/classes/external/month_exporter.php b/calendar/classes/external/month_exporter.php index 9b99498e910..870687e9637 100644 --- a/calendar/classes/external/month_exporter.php +++ b/calendar/classes/external/month_exporter.php @@ -213,13 +213,13 @@ class month_exporter extends exporter { $prepadding = ($firstdayno + $daysinweek - 1) % $daysinweek; $daysinfirstweek = $daysinweek - $prepadding; $days = array_slice($alldays, 0, $daysinfirstweek); - $week = new week_exporter($days, $prepadding, ($daysinweek - count($days) - $prepadding), $this->related); + $week = new week_exporter($this->calendar, $days, $prepadding, ($daysinweek - count($days) - $prepadding), $this->related); $weeks[] = $week->export($output); // Now chunk up the remaining day. and turn them into weeks. $daychunks = array_chunk(array_slice($alldays, $daysinfirstweek), $daysinweek); foreach ($daychunks as $days) { - $week = new week_exporter($days, 0, ($daysinweek - count($days)), $this->related); + $week = new week_exporter($this->calendar, $days, 0, ($daysinweek - count($days)), $this->related); $weeks[] = $week->export($output); } diff --git a/calendar/classes/external/week_exporter.php b/calendar/classes/external/week_exporter.php index b8bb4da63fc..f0b6c4d7d4e 100644 --- a/calendar/classes/external/week_exporter.php +++ b/calendar/classes/external/week_exporter.php @@ -53,18 +53,26 @@ class week_exporter extends exporter { */ protected $postpadding = 0; + + /** + * @var \calendar_information $calendar The calendar being displayed. + */ + protected $calendar; + /** * Constructor. * + * @param \calendar_information $calendar The calendar information for the period being displayed * @param mixed $days An array of day_exporter objects. * @param int $prepadding The number of pre-padding days at the start of the week. * @param int $postpadding The number of post-padding days at the start of the week. * @param array $related Related objects. */ - public function __construct($days, $prepadding, $postpadding, $related) { + public function __construct(\calendar_information $calendar, $days, $prepadding, $postpadding, $related) { $this->days = $days; $this->prepadding = $prepadding; $this->postpadding = $postpadding; + $this->calendar = $calendar; parent::__construct([], $related); } From 6ff225f57eeabaab605dc01dd5206f38fd8ca17b Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Tue, 5 Sep 2017 15:22:18 +0800 Subject: [PATCH 5/9] MDL-59392 calendar: Correct the next period (add vs sub) --- calendar/classes/external/month_exporter.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/calendar/classes/external/month_exporter.php b/calendar/classes/external/month_exporter.php index 870687e9637..2a1988f459e 100644 --- a/calendar/classes/external/month_exporter.php +++ b/calendar/classes/external/month_exporter.php @@ -279,7 +279,7 @@ class month_exporter extends exporter { */ protected function get_next_month_timestamp() { $date = $this->related['type']->timestamp_to_date_array($this->calendar->time); - $month = calendar_sub_month($date['mon'], $date['year']); + $month = calendar_add_month($date['mon'], $date['year']); $monthtime = $this->related['type']->convert_to_gregorian($month[1], $month[0], 1); return make_timestamp($monthtime['year'], $monthtime['month'], $monthtime['day'], $monthtime['hour'], $monthtime['minute']); From 41fa6a24be709c4fdbe5114a12231fa0451d23d6 Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Fri, 8 Sep 2017 08:53:24 +0800 Subject: [PATCH 6/9] MDL-59392 calendar: Stop polluting history with useless URLs --- calendar/amd/build/view_manager.min.js | 2 +- calendar/amd/src/view_manager.js | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/calendar/amd/build/view_manager.min.js b/calendar/amd/build/view_manager.min.js index 62a980bc34e..88812a5d84d 100644 --- a/calendar/amd/build/view_manager.min.js +++ b/calendar/amd/build/view_manager.min.js @@ -1 +1 @@ -define(["jquery","core/templates","core/notification","core_calendar/repository","core_calendar/events"],function(a,b,c,d,e){var f={ROOT:"[data-region='calendar']",CALENDAR_NAV_LINK:".calendarwrapper .arrow_link",CALENDAR_MONTH_WRAPPER:".calendarwrapper",LOADING_ICON_CONTAINER:'[data-region="overlay-icon-container"]'},g=function(b){b=a(b),b.on("click",f.CALENDAR_NAV_LINK,function(c){var d=a(b).find(f.CALENDAR_MONTH_WRAPPER).data("courseid"),e=a(c.currentTarget);i(b,e.attr("href"),e.data("time"),d),c.preventDefault()})},h=function(a,e,g){return k(a),d.getCalendarMonthData(e,g).then(function(c){return b.render(a.attr("data-template"),c)}).then(function(c,d){return b.replaceNode(a.find(f.CALENDAR_MONTH_WRAPPER),c,d)}).always(function(){return l(a)}).fail(c.exception)},i=function(b,c,d,f){return h(b,d,f).then(function(){return window.history.pushState({},"",c),arguments}).then(function(){return a("body").trigger(e.monthChanged,[d,f]),arguments})},j=function(a,b){var c=a.find(f.CALENDAR_MONTH_WRAPPER).data("current-time");return b||(b=a.find(f.CALENDAR_MONTH_WRAPPER).data("courseid")),h(a,c,b)},k=function(a){var b=a.find(f.LOADING_ICON_CONTAINER);b.removeClass("hidden")},l=function(a){var b=a.find(f.LOADING_ICON_CONTAINER);b.addClass("hidden")};return{init:function(a){g(a)},reloadCurrentMonth:j,changeMonth:i,refreshMonthContent:h}}); \ No newline at end of file +define(["jquery","core/templates","core/notification","core_calendar/repository","core_calendar/events"],function(a,b,c,d,e){var f={ROOT:"[data-region='calendar']",CALENDAR_NAV_LINK:".calendarwrapper .arrow_link",CALENDAR_MONTH_WRAPPER:".calendarwrapper",LOADING_ICON_CONTAINER:'[data-region="overlay-icon-container"]'},g=function(b){b=a(b),b.on("click",f.CALENDAR_NAV_LINK,function(c){var d=a(b).find(f.CALENDAR_MONTH_WRAPPER).data("courseid"),e=a(c.currentTarget);i(b,e.attr("href"),e.data("time"),d),c.preventDefault()})},h=function(a,e,g){return k(a),d.getCalendarMonthData(e,g).then(function(c){return b.render(a.attr("data-template"),c)}).then(function(c,d){return b.replaceNode(a.find(f.CALENDAR_MONTH_WRAPPER),c,d)}).always(function(){return l(a)}).fail(c.exception)},i=function(b,c,d,f){return h(b,d,f).then(function(){return c.length&&"#"!==c&&window.history.pushState({},"",c),arguments}).then(function(){return a("body").trigger(e.monthChanged,[d,f]),arguments})},j=function(a,b){var c=a.find(f.CALENDAR_MONTH_WRAPPER).data("current-time");return b||(b=a.find(f.CALENDAR_MONTH_WRAPPER).data("courseid")),h(a,c,b)},k=function(a){var b=a.find(f.LOADING_ICON_CONTAINER);b.removeClass("hidden")},l=function(a){var b=a.find(f.LOADING_ICON_CONTAINER);b.addClass("hidden")};return{init:function(a){g(a)},reloadCurrentMonth:j,changeMonth:i,refreshMonthContent:h}}); \ No newline at end of file diff --git a/calendar/amd/src/view_manager.js b/calendar/amd/src/view_manager.js index 58f9ac788ff..2c9791bc365 100644 --- a/calendar/amd/src/view_manager.js +++ b/calendar/amd/src/view_manager.js @@ -82,7 +82,9 @@ define(['jquery', 'core/templates', 'core/notification', 'core_calendar/reposito var changeMonth = function(root, url, time, courseid) { return refreshMonthContent(root, time, courseid) .then(function() { - window.history.pushState({}, '', url); + if (url.length && url !== '#') { + window.history.pushState({}, '', url); + } return arguments; }) .then(function() { From c8b6e9ab3461f9beb97c3c01036fcc3d2458583f Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Fri, 1 Sep 2017 14:58:14 +0800 Subject: [PATCH 7/9] MDL-59392 calendar: Switch to templates in the cal block This commit adds a set of templates for the calendar month block, and the events filter. The same data exporters used in the main calendar view are utilised and the same logic. Some additional data was added to the exporters, and in the long term this will be used in the main monthly view so I did not feel it was prudent to strip it out into a different view of the model. AMOS BEGIN MOV [monthnext,access],[monthnext,calendar] AMOS END --- .../calendar_month/block_calendar_month.php | 31 ++-- .../tests/behat/block_calendar_month.feature | 18 +- calendar/amd/build/calendar_filter.min.js | 1 + calendar/amd/build/calendar_mini.min.js | 1 + calendar/amd/build/events.min.js | 2 +- calendar/amd/build/selectors.min.js | 1 + calendar/amd/build/view_manager.min.js | 2 +- calendar/amd/src/calendar_filter.js | 119 ++++++++++++++ calendar/amd/src/calendar_mini.js | 57 +++++++ calendar/amd/src/events.js | 4 +- calendar/amd/src/selectors.js | 40 +++++ calendar/amd/src/view_manager.js | 4 + .../external/calendar_event_exporter.php | 78 +++++++++ calendar/classes/external/day_exporter.php | 73 ++++++++- calendar/classes/external/month_exporter.php | 59 ++++++- calendar/classes/external/week_exporter.php | 19 ++- calendar/lib.php | 30 +++- calendar/renderer.php | 12 ++ calendar/templates/calendar_mini.mustache | 45 +++++ calendar/templates/event_filter.mustache | 45 +++++ calendar/templates/event_filter_key.mustache | 45 +++++ .../templates/minicalendar_day_link.mustache | 6 +- calendar/templates/month_mini.mustache | 154 ++++++++++++++++++ calendar/tests/behat/behat_calendar.php | 5 +- lang/en/access.php | 6 +- lang/en/calendar.php | 14 +- lang/en/deprecated.txt | 2 + theme/boost/scss/moodle/calendar.scss | 10 ++ .../minicalendar_day_link.mustache | 44 ++++- theme/bootstrapbase/less/moodle/calendar.less | 5 + theme/bootstrapbase/style/moodle.css | 3 + .../minicalendar_day_link.mustache | 40 +++-- 32 files changed, 909 insertions(+), 66 deletions(-) create mode 100644 calendar/amd/build/calendar_filter.min.js create mode 100644 calendar/amd/build/calendar_mini.min.js create mode 100644 calendar/amd/build/selectors.min.js create mode 100644 calendar/amd/src/calendar_filter.js create mode 100644 calendar/amd/src/calendar_mini.js create mode 100644 calendar/amd/src/selectors.js create mode 100644 calendar/templates/calendar_mini.mustache create mode 100644 calendar/templates/event_filter.mustache create mode 100644 calendar/templates/event_filter_key.mustache create mode 100644 calendar/templates/month_mini.mustache diff --git a/blocks/calendar_month/block_calendar_month.php b/blocks/calendar_month/block_calendar_month.php index cc3d6f69f61..18a57d72e13 100644 --- a/blocks/calendar_month/block_calendar_month.php +++ b/blocks/calendar_month/block_calendar_month.php @@ -70,29 +70,26 @@ class block_calendar_month extends block_base { if ($issite) { // Being displayed at site level. This will cause the filter to fall back to auto-detecting // the list of courses it will be grabbing events from. - $filtercourse = calendar_get_default_courses(); + $course = get_site(); + $courses = calendar_get_default_courses(); } else { // Forcibly filter events to include only those from the particular course we are in. - $filtercourse = array($courseid => $this->page->course); + $course = $this->page->course; + $courses = [$course->id => $course]; } - list($courses, $group, $user) = calendar_set_filters($filtercourse); - if ($issite) { - // For the front page. - $this->content->text .= calendar_get_mini($courses, $group, $user, false, false, - 'frontpage', $courseid, $time); - // No filters for now. - } else { - // For any other course. - $this->content->text .= calendar_get_mini($courses, $group, $user, false, false, - 'course', $courseid, $time); - $this->content->text .= '

'.get_string('eventskey', 'calendar').'

'; - $this->content->text .= '
' . - calendar_filter_controls($this->page->url) . '
'; + $renderer = $this->page->get_renderer('core_calendar'); + + $calendar = new calendar_information(0, 0, 0, $time); + $calendar->prepare_for_view($course, $courses); + + list($data, $template) = calendar_get_view($calendar, 'mini'); + $this->content->text .= $renderer->render_from_template($template, $data); + + if (!$issite) { + $this->content->text .= $renderer->event_filter(); } return $this->content; } } - - diff --git a/blocks/calendar_month/tests/behat/block_calendar_month.feature b/blocks/calendar_month/tests/behat/block_calendar_month.feature index 8753167f63b..86baea3b524 100644 --- a/blocks/calendar_month/tests/behat/block_calendar_month.feature +++ b/blocks/calendar_month/tests/behat/block_calendar_month.feature @@ -23,7 +23,7 @@ Feature: Enable the calendar block in a course and test it's functionality Given I log in as "teacher1" And I am on "Course 1" course homepage with editing mode on When I add the "Calendar" block - Then I should see "Events key" in the "Calendar" "block" + Then "Calendar" "block" should exist @javascript Scenario: View a global event in the calendar block @@ -136,9 +136,14 @@ Feature: Enable the calendar block in a course and test it's functionality And I press "Save and display" And I turn editing mode on And I add the "Calendar" block - And I create a calendar event with form data: + And I click on "This month" "link" + And I click on "New event" "button" + And I set the following fields to these values: | id_eventtype | Group | | id_name | Group Event | + And I set the following fields to these values: + | Group | Group 1 | + And I press "Save" And I log out Then I log in as "student1" And I am on "Course 1" course homepage @@ -150,7 +155,7 @@ Feature: Enable the calendar block in a course and test it's functionality And I hover over today in the calendar And I should not see "Group Event" - @javascript + @javascript @arn Scenario: Filter group events in the calendar block Given the following "groups" exist: | name | course | idnumber | @@ -173,9 +178,14 @@ Feature: Enable the calendar block in a course and test it's functionality | id_eventtype | Course | | id_name | Course Event 1 | And I am on "Course 1" course homepage - And I create a calendar event with form data: + And I click on "This month" "link" + And I click on "New event" "button" + And I set the following fields to these values: | id_eventtype | Group | | id_name | Group Event 1 | + And I set the following fields to these values: + | Group | Group 1 | + And I press "Save" And I log out Then I log in as "student1" And I am on "Course 1" course homepage diff --git a/calendar/amd/build/calendar_filter.min.js b/calendar/amd/build/calendar_filter.min.js new file mode 100644 index 00000000000..ef94d150844 --- /dev/null +++ b/calendar/amd/build/calendar_filter.min.js @@ -0,0 +1 @@ +define(["jquery","core_calendar/selectors","core_calendar/events","core/str","core/templates"],function(a,b,c,d,e){var f=function(d){d.on("click",b.eventFilterItem,function(b){var c=a(b.currentTarget);g(c),b.preventDefault()}),a("body").on(c.viewUpdated,function(){var c=d.find(b.eventFilterItem);c.each(function(b,c){if(c=a(c),c.data("eventtype-hidden")){var d=i(c);h(d)}})})},g=function(a){var b=i(a);return b.hidden=!b.hidden,d.get_string("eventtype"+b.type,"calendar").then(function(a){return b.name=a,b}).then(function(a){return e.render("core_calendar/event_filter_key",a)}).then(function(b,c){return e.replaceNode(a,b,c)}).then(function(){h(b)})},h=function(b){M.util.js_pending("month-mini-filterChanged"),a("body").trigger(c.filterChanged,{type:b.type,hidden:b.hidden}),M.util.js_complete("month-mini-filterChanged")},i=function(a){return{type:a.data("eventtype"),hidden:a.data("eventtype-hidden")}};return{init:function(b){b=a(b),f(b)}}}); \ No newline at end of file diff --git a/calendar/amd/build/calendar_mini.min.js b/calendar/amd/build/calendar_mini.min.js new file mode 100644 index 00000000000..979e92e5ebd --- /dev/null +++ b/calendar/amd/build/calendar_mini.min.js @@ -0,0 +1 @@ +define(["jquery","core_calendar/selectors","core_calendar/events","core_calendar/view_manager"],function(a,b,c,d){var e=function(d){a("body").on(c.filterChanged,function(a,c){var e=d.find(b.eventType[c.type]);e.toggleClass("calendar_event_"+c.type,!c.hidden)})};return{init:function(b){b=a(b),d.init(b),e(b)}}}); \ No newline at end of file diff --git a/calendar/amd/build/events.min.js b/calendar/amd/build/events.min.js index 762a824034c..77b21536776 100644 --- a/calendar/amd/build/events.min.js +++ b/calendar/amd/build/events.min.js @@ -1 +1 @@ -define([],function(){return{created:"calendar-events:created",deleted:"calendar-events:deleted",updated:"calendar-events:updated",editEvent:"calendar-events:edit_event",editActionEvent:"calendar-events:edit_action_event",eventMoved:"calendar-events:event_moved",monthChanged:"calendar-events:month_changed",moveEvent:"calendar-events:move_event"}}); \ No newline at end of file +define([],function(){return{created:"calendar-events:created",deleted:"calendar-events:deleted",updated:"calendar-events:updated",editEvent:"calendar-events:edit_event",editActionEvent:"calendar-events:edit_action_event",eventMoved:"calendar-events:event_moved",monthChanged:"calendar-events:month_changed",moveEvent:"calendar-events:move_event",filterChanged:"calendar-events:filter_changed",viewUpdated:"calendar-events:view_updated"}}); \ No newline at end of file diff --git a/calendar/amd/build/selectors.min.js b/calendar/amd/build/selectors.min.js new file mode 100644 index 00000000000..8dbeb185f37 --- /dev/null +++ b/calendar/amd/build/selectors.min.js @@ -0,0 +1 @@ +define([],function(){return{eventFilterItem:"[data-action='filter-event-type']",eventType:{site:"[data-eventtype-site]",course:"[data-eventtype-course]",group:"[data-eventtype-group]",user:"[data-eventtype-user]"},popoverType:{site:"[data-popover-eventtype-site]",course:"[data-popover-eventtype-course]",group:"[data-popover-eventtype-group]",user:"[data-popover-eventtype-user]"}}}); \ No newline at end of file diff --git a/calendar/amd/build/view_manager.min.js b/calendar/amd/build/view_manager.min.js index 88812a5d84d..301ef420904 100644 --- a/calendar/amd/build/view_manager.min.js +++ b/calendar/amd/build/view_manager.min.js @@ -1 +1 @@ -define(["jquery","core/templates","core/notification","core_calendar/repository","core_calendar/events"],function(a,b,c,d,e){var f={ROOT:"[data-region='calendar']",CALENDAR_NAV_LINK:".calendarwrapper .arrow_link",CALENDAR_MONTH_WRAPPER:".calendarwrapper",LOADING_ICON_CONTAINER:'[data-region="overlay-icon-container"]'},g=function(b){b=a(b),b.on("click",f.CALENDAR_NAV_LINK,function(c){var d=a(b).find(f.CALENDAR_MONTH_WRAPPER).data("courseid"),e=a(c.currentTarget);i(b,e.attr("href"),e.data("time"),d),c.preventDefault()})},h=function(a,e,g){return k(a),d.getCalendarMonthData(e,g).then(function(c){return b.render(a.attr("data-template"),c)}).then(function(c,d){return b.replaceNode(a.find(f.CALENDAR_MONTH_WRAPPER),c,d)}).always(function(){return l(a)}).fail(c.exception)},i=function(b,c,d,f){return h(b,d,f).then(function(){return c.length&&"#"!==c&&window.history.pushState({},"",c),arguments}).then(function(){return a("body").trigger(e.monthChanged,[d,f]),arguments})},j=function(a,b){var c=a.find(f.CALENDAR_MONTH_WRAPPER).data("current-time");return b||(b=a.find(f.CALENDAR_MONTH_WRAPPER).data("courseid")),h(a,c,b)},k=function(a){var b=a.find(f.LOADING_ICON_CONTAINER);b.removeClass("hidden")},l=function(a){var b=a.find(f.LOADING_ICON_CONTAINER);b.addClass("hidden")};return{init:function(a){g(a)},reloadCurrentMonth:j,changeMonth:i,refreshMonthContent:h}}); \ No newline at end of file +define(["jquery","core/templates","core/notification","core_calendar/repository","core_calendar/events"],function(a,b,c,d,e){var f={ROOT:"[data-region='calendar']",CALENDAR_NAV_LINK:".calendarwrapper .arrow_link",CALENDAR_MONTH_WRAPPER:".calendarwrapper",LOADING_ICON_CONTAINER:'[data-region="overlay-icon-container"]'},g=function(b){b=a(b),b.on("click",f.CALENDAR_NAV_LINK,function(c){var d=a(b).find(f.CALENDAR_MONTH_WRAPPER).data("courseid"),e=a(c.currentTarget);i(b,e.attr("href"),e.data("time"),d),c.preventDefault()})},h=function(g,h,i){return k(g),d.getCalendarMonthData(h,i).then(function(a){return b.render(g.attr("data-template"),a)}).then(function(a,c){return b.replaceNode(g.find(f.CALENDAR_MONTH_WRAPPER),a,c)}).then(function(){a("body").trigger(e.viewUpdated)}).always(function(){return l(g)}).fail(c.exception)},i=function(b,c,d,f){return h(b,d,f).then(function(){return c.length&&"#"!==c&&window.history.pushState({},"",c),arguments}).then(function(){return a("body").trigger(e.monthChanged,[d,f]),arguments})},j=function(a,b){var c=a.find(f.CALENDAR_MONTH_WRAPPER).data("current-time");return b||(b=a.find(f.CALENDAR_MONTH_WRAPPER).data("courseid")),h(a,c,b)},k=function(a){var b=a.find(f.LOADING_ICON_CONTAINER);b.removeClass("hidden")},l=function(a){var b=a.find(f.LOADING_ICON_CONTAINER);b.addClass("hidden")};return{init:function(a){g(a)},reloadCurrentMonth:j,changeMonth:i,refreshMonthContent:h}}); \ No newline at end of file diff --git a/calendar/amd/src/calendar_filter.js b/calendar/amd/src/calendar_filter.js new file mode 100644 index 00000000000..5352a7c038f --- /dev/null +++ b/calendar/amd/src/calendar_filter.js @@ -0,0 +1,119 @@ +// This file is part of Moodle - http://moodle.org/ +// +// Moodle is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Moodle is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Moodle. If not, see . + +/** + * This module is responsible for the calendar filter. + * + * @module core_calendar/calendar_filter + * @package core_calendar + * @copyright 2017 Andrew Nicols + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +define([ + 'jquery', + 'core_calendar/selectors', + 'core_calendar/events', + 'core/str', + 'core/templates', +], +function( + $, + CalendarSelectors, + CalendarEvents, + Str, + Templates +) { + + var registerEventListeners = function(root) { + root.on('click', CalendarSelectors.eventFilterItem, function(e) { + var target = $(e.currentTarget); + + toggleFilter(target); + + e.preventDefault(); + }); + + $('body').on(CalendarEvents.viewUpdated, function() { + var filters = root.find(CalendarSelectors.eventFilterItem); + + filters.each(function(i, filter) { + filter = $(filter); + if (filter.data('eventtype-hidden')) { + var data = getFilterData(filter); + fireFilterChangedEvent(data); + } + }); + }); + }; + + var toggleFilter = function(target) { + var data = getFilterData(target); + + // Toggle the hidden. We need to render the template before we change the value. + data.hidden = !data.hidden; + + return Str.get_string('eventtype' + data.type, 'calendar') + .then(function(nameStr) { + data.name = nameStr; + + return data; + }) + .then(function(context) { + return Templates.render('core_calendar/event_filter_key', context); + }) + .then(function(html, js) { + return Templates.replaceNode(target, html, js); + }) + .then(function() { + fireFilterChangedEvent(data); + return; + }); + }; + + /** + * Fire the filterChanged event for the specified data. + * + * @param {object} data The data to include + */ + var fireFilterChangedEvent = function(data) { + M.util.js_pending("month-mini-filterChanged"); + $('body').trigger(CalendarEvents.filterChanged, { + type: data.type, + hidden: data.hidden, + }); + M.util.js_complete("month-mini-filterChanged"); + }; + + /** + * Get the filter data for the specified target. + * + * @param {jQuery} target The target node + * @return {Object} + */ + var getFilterData = function(target) { + return { + type: target.data('eventtype'), + hidden: target.data('eventtype-hidden'), + }; + }; + + return { + init: function(root) { + root = $(root); + + registerEventListeners(root); + } + }; +}); diff --git a/calendar/amd/src/calendar_mini.js b/calendar/amd/src/calendar_mini.js new file mode 100644 index 00000000000..48a4f441e9d --- /dev/null +++ b/calendar/amd/src/calendar_mini.js @@ -0,0 +1,57 @@ +// This file is part of Moodle - http://moodle.org/ +// +// Moodle is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Moodle is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Moodle. If not, see . + +/** + * This module is the highest level module for the calendar. It is + * responsible for initialising all of the components required for + * the calendar to run. It also coordinates the interaction between + * components by listening for and responding to different events + * triggered within the calendar UI. + * + * @module core_calendar/calendar + * @package core_calendar + * @copyright 2017 Andrew Nicols + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +define([ + 'jquery', + 'core_calendar/selectors', + 'core_calendar/events', + 'core_calendar/view_manager', +], +function( + $, + CalendarSelectors, + CalendarEvents, + CalendarViewManager +) { + + var registerEventListeners = function(root) { + $('body').on(CalendarEvents.filterChanged, function(e, data) { + var daysWithEvent = root.find(CalendarSelectors.eventType[data.type]); + + daysWithEvent.toggleClass('calendar_event_' + data.type, !data.hidden); + }); + }; + + return { + init: function(root) { + root = $(root); + + CalendarViewManager.init(root); + registerEventListeners(root); + } + }; +}); diff --git a/calendar/amd/src/events.js b/calendar/amd/src/events.js index 95e0968d726..29b5fd263cb 100644 --- a/calendar/amd/src/events.js +++ b/calendar/amd/src/events.js @@ -31,6 +31,8 @@ define([], function() { editActionEvent: 'calendar-events:edit_action_event', eventMoved: 'calendar-events:event_moved', monthChanged: 'calendar-events:month_changed', - moveEvent: 'calendar-events:move_event' + moveEvent: 'calendar-events:move_event', + filterChanged: 'calendar-events:filter_changed', + viewUpdated: 'calendar-events:view_updated', }; }); diff --git a/calendar/amd/src/selectors.js b/calendar/amd/src/selectors.js new file mode 100644 index 00000000000..89bb65a5126 --- /dev/null +++ b/calendar/amd/src/selectors.js @@ -0,0 +1,40 @@ +// This file is part of Moodle - http://moodle.org/ +// +// Moodle is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Moodle is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Moodle. If not, see . + +/** + * This module is responsible for the calendar filter. + * + * @module core_calendar/calendar_selectors + * @package core_calendar + * @copyright 2017 Andrew Nicols + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +define([], function() { + return { + eventFilterItem: "[data-action='filter-event-type']", + eventType: { + site: "[data-eventtype-site]", + course: "[data-eventtype-course]", + group: "[data-eventtype-group]", + user: "[data-eventtype-user]", + }, + popoverType: { + site: "[data-popover-eventtype-site]", + course: "[data-popover-eventtype-course]", + group: "[data-popover-eventtype-group]", + user: "[data-popover-eventtype-user]", + }, + }; +}); diff --git a/calendar/amd/src/view_manager.js b/calendar/amd/src/view_manager.js index 2c9791bc365..f8636ef6049 100644 --- a/calendar/amd/src/view_manager.js +++ b/calendar/amd/src/view_manager.js @@ -65,6 +65,10 @@ define(['jquery', 'core/templates', 'core/notification', 'core_calendar/reposito .then(function(html, js) { return Templates.replaceNode(root.find(SELECTORS.CALENDAR_MONTH_WRAPPER), html, js); }) + .then(function() { + $('body').trigger(CalendarEvents.viewUpdated); + return; + }) .always(function() { return stopLoading(root); }) diff --git a/calendar/classes/external/calendar_event_exporter.php b/calendar/classes/external/calendar_event_exporter.php index 7ba5805ddf5..f83f2738267 100644 --- a/calendar/classes/external/calendar_event_exporter.php +++ b/calendar/classes/external/calendar_event_exporter.php @@ -47,6 +47,16 @@ class calendar_event_exporter extends event_exporter_base { $values = parent::define_other_properties(); $values['url'] = ['type' => PARAM_URL]; + $values['islastday'] = [ + 'type' => PARAM_BOOL, + 'default' => false, + ]; + $values['calendareventtype'] = [ + 'type' => PARAM_TEXT, + ]; + $values['popupname'] = [ + 'type' => PARAM_RAW, + ]; return $values; } @@ -58,6 +68,8 @@ class calendar_event_exporter extends event_exporter_base { * @return array Keys are the property names, values are their values. */ protected function get_other_values(renderer_base $output) { + global $CFG; + $values = parent::get_other_values($output); $eventid = $this->event->get_id(); @@ -65,6 +77,55 @@ class calendar_event_exporter extends event_exporter_base { $url = new \moodle_url($this->related['daylink'], [], "event_{$eventid}"); $values['url'] = $url->out(false); + $values['islastday'] = false; + $today = $this->related['type']->timestamp_to_date_array($this->related['today']); + + $values['popupname'] = $this->event->get_name(); + + $times = $this->event->get_times(); + if ($duration = $times->get_duration()) { + $enddate = $this->related['type']->timestamp_to_date_array($times->get_end_time()->getTimestamp()); + $values['islastday'] = true; + $values['islastday'] = $values['islastday'] && $enddate['year'] == $today['year']; + $values['islastday'] = $values['islastday'] && $enddate['mon'] == $today['mon']; + $values['islastday'] = $values['islastday'] && $enddate['mday'] == $today['mday']; + } + + $subscription = $this->event->get_subscription(); + if ($subscription && !empty($subscription->get('id')) && $CFG->calendar_showicalsource) { + $a = (object) [ + 'name' => $values['popupname'], + 'source' => $subscription->get('name'), + ]; + $values['popupname'] = get_string('namewithsource', 'calendar', $a); + } else { + if ($values['islastday']) { + $startdate = $this->related['type']->timestamp_to_date_array($times->get_start_time()->getTimestamp()); + $samedate = true; + $samedate = $samedate && $startdate['mon'] == $enddate['mon']; + $samedate = $samedate && $startdate['year'] == $enddate['year']; + $samedate = $samedate && $startdate['mday'] == $enddate['mday']; + + if (!$samedate) { + $values['popupname'] = get_string('eventendtimewrapped', 'calendar', $values['popupname']); + } + } + } + + // Include course's shortname into the event name, if applicable. + $course = $this->event->get_course(); + if ($course && $course->get('id') && $course->get('id') !== SITEID) { + $eventnameparams = (object) [ + 'name' => $values['popupname'], + 'course' => format_string($course->get('shortname'), true, [ + 'context' => $this->related['context'], + ]) + ]; + $values['popupname'] = get_string('eventnameandcourse', 'calendar', $eventnameparams); + } + + $values['calendareventtype'] = $this->get_calendar_event_type(); + return $values; } @@ -76,7 +137,24 @@ class calendar_event_exporter extends event_exporter_base { protected static function define_related() { $related = parent::define_related(); $related['daylink'] = \moodle_url::class; + $related['type'] = '\core_calendar\type_base'; + $related['today'] = 'int'; return $related; } + + /** + * Return the normalised event type. + * Activity events are normalised to be course events. + * + * @return string + */ + public function get_calendar_event_type() { + $type = $this->event->get_type(); + if ($type == 'open' || $type == 'close') { + $type = 'course'; + } + + return $type; + } } diff --git a/calendar/classes/external/day_exporter.php b/calendar/classes/external/day_exporter.php index 90b5c73e3ae..0f5b92b2bac 100644 --- a/calendar/classes/external/day_exporter.php +++ b/calendar/classes/external/day_exporter.php @@ -87,6 +87,15 @@ class day_exporter extends exporter { 'yday' => [ 'type' => PARAM_INT, ], + // These are additional params. + 'istoday' => [ + 'type' => PARAM_BOOL, + 'default' => false, + ], + 'isweekend' => [ + 'type' => PARAM_BOOL, + 'default' => false, + ], ]; } @@ -110,7 +119,19 @@ class day_exporter extends exporter { 'events' => [ 'type' => calendar_event_exporter::read_properties_definition(), 'multiple' => true, - ] + ], + 'calendareventtypes' => [ + 'type' => PARAM_RAW, + 'multiple' => true, + ], + 'popovertitle' => [ + 'type' => PARAM_RAW, + 'default' => '', + ], + 'haslastdayofevent' => [ + 'type' => PARAM_BOOL, + 'default' => false, + ], ]; } @@ -141,22 +162,46 @@ class day_exporter extends exporter { $url = new moodle_url('/calendar/view.php', [ 'view' => 'day', 'time' => $timestamp, + 'course' => $this->calendar->course->id, ]); $return['viewdaylink'] = $url->out(false); $cache = $this->related['cache']; - $return['events'] = array_map(function($event) use ($cache, $output, $url) { + $eventexporters = array_map(function($event) use ($cache, $output, $url) { $context = $cache->get_context($event); $course = $cache->get_course($event); $exporter = new calendar_event_exporter($event, [ 'context' => $context, 'course' => $course, 'daylink' => $url, + 'type' => $this->related['type'], + 'today' => $this->data[0], ]); - return $exporter->export($output); + return $exporter; }, $this->related['events']); + $return['events'] = array_map(function($exporter) use ($output) { + return $exporter->export($output); + }, $eventexporters); + + if ($popovertitle = $this->get_popover_title()) { + $return['popovertitle'] = $popovertitle; + } + + $return['calendareventtypes'] = array_map(function($exporter) { + return $exporter->get_calendar_event_type(); + }, $eventexporters); + $return['calendareventtypes'] = array_values(array_unique($return['calendareventtypes'])); + + $return['haslastdayofevent'] = false; + foreach ($return['events'] as $event) { + if ($event->islastday) { + $return['haslastdayofevent'] = true; + break; + } + } + return $return; } @@ -172,4 +217,26 @@ class day_exporter extends exporter { 'type' => '\core_calendar\type_base', ]; } + + /** + * Get the title for this popover. + * + * @return string + */ + protected function get_popover_title() { + $title = null; + + $userdate = userdate($this->data[0], get_string('strftimedayshort')); + if (count($this->related['events'])) { + $title = get_string('eventsfor', 'calendar', $userdate); + } else if ($this->data['istoday']) { + $title = $userdate; + } + + if ($this->data['istoday']) { + $title = get_string('todayplustitle', 'calendar', $userdate); + } + + return $title; + } } diff --git a/calendar/classes/external/month_exporter.php b/calendar/classes/external/month_exporter.php index 2a1988f459e..6d180aa4ee1 100644 --- a/calendar/classes/external/month_exporter.php +++ b/calendar/classes/external/month_exporter.php @@ -76,7 +76,19 @@ class month_exporter extends exporter { $related['type'] = $type; - parent::__construct([], $related); + $data = [ + 'url' => $this->url->out(false), + ]; + + parent::__construct($data, $related); + } + + protected static function define_properties() { + return [ + 'url' => [ + 'type' => PARAM_URL, + ], + ]; } /** @@ -106,15 +118,38 @@ class month_exporter extends exporter { 'view' => [ 'type' => PARAM_ALPHA, ], + 'time' => [ + 'type' => PARAM_INT, + ], + 'periodname' => [ + // Note: We must use RAW here because the calendar type returns the formatted month name based on a + // calendar format. + 'type' => PARAM_RAW, + ], 'previousperiod' => [ 'type' => PARAM_INT, ], + 'previousperiodname' => [ + // Note: We must use RAW here because the calendar type returns the formatted month name based on a + // calendar format. + 'type' => PARAM_RAW, + ], 'nextperiod' => [ 'type' => PARAM_INT, ], - 'time' => [ - 'type' => PARAM_INT, - ] + 'nextperiodname' => [ + // Note: We must use RAW here because the calendar type returns the formatted month name based on a + // calendar format. + 'type' => PARAM_RAW, + ], + 'larrow' => [ + // The left arrow defined by the theme. + 'type' => PARAM_RAW, + ], + 'rarrow' => [ + // The right arrow defined by the theme. + 'type' => PARAM_RAW, + ], ]; } @@ -125,16 +160,24 @@ class month_exporter extends exporter { * @return array Keys are the property names, values are their values. */ protected function get_other_values(renderer_base $output) { + $previousperiod = $this->get_previous_month_timestamp(); + $nextperiod = $this->get_next_month_timestamp(); + return [ 'courseid' => $this->calendar->courseid, - 'view' => 'month', - 'previousperiod' => $this->get_previous_month_timestamp(), - 'nextperiod' => $this->get_next_month_timestamp(), 'filter_selector' => $this->get_course_filter_selector($output), 'navigation' => $this->get_navigation($output), 'weeks' => $this->get_weeks($output), 'daynames' => $this->get_day_names($output), - 'time' => $this->calendar->time + 'view' => 'month', + 'time' => $this->calendar->time, + 'periodname' => userdate($this->calendar->time, get_string('strftimemonthyear')), + 'previousperiod' => $previousperiod, + 'previousperiodname' => userdate($previousperiod, get_string('strftimemonthyear')), + 'nextperiod' => $nextperiod, + 'nextperiodname' => userdate($nextperiod, get_string('strftimemonthyear')), + 'larrow' => $output->larrow(), + 'rarrow' => $output->rarrow(), ]; } diff --git a/calendar/classes/external/week_exporter.php b/calendar/classes/external/week_exporter.php index f0b6c4d7d4e..ff75a35d328 100644 --- a/calendar/classes/external/week_exporter.php +++ b/calendar/classes/external/week_exporter.php @@ -53,7 +53,6 @@ class week_exporter extends exporter { */ protected $postpadding = 0; - /** * @var \calendar_information $calendar The calendar being displayed. */ @@ -106,6 +105,7 @@ class week_exporter extends exporter { * @return array Keys are the property names, values are their values. */ protected function get_other_values(renderer_base $output) { + global $CFG; $return = [ 'prepadding' => [], 'postpadding' => [], @@ -120,6 +120,14 @@ class week_exporter extends exporter { } $return['days'] = []; + $today = $this->related['type']->timestamp_to_date_array(time()); + + $weekend = CALENDAR_DEFAULT_WEEKEND; + if (isset($CFG->calendar_weekend)) { + $weekend = intval($CFG->calendar_weekend); + } + $numberofdaysinweek = $this->related['type']->get_num_weekdays(); + foreach ($this->days as $daydata) { $events = []; foreach ($this->related['events'] as $event) { @@ -140,7 +148,14 @@ class week_exporter extends exporter { $events[] = $event; } - $day = new week_day_exporter($daydata, [ + $istoday = true; + $istoday = $istoday && $today['year'] == $daydata['year']; + $istoday = $istoday && $today['yday'] == $daydata['yday']; + $daydata['istoday'] = $istoday; + + $daydata['isweekend'] = !!($weekend & (1 << ($daydata['wday'] % $numberofdaysinweek))); + + $day = new week_day_exporter($this->calendar, $daydata, [ 'events' => $events, 'cache' => $this->related['cache'], 'type' => $this->related['type'], diff --git a/calendar/lib.php b/calendar/lib.php index 8df62f0b91d..34bd7b421b2 100644 --- a/calendar/lib.php +++ b/calendar/lib.php @@ -1478,7 +1478,7 @@ function calendar_get_mini($courses, $groups, $users, $calmonth = false, $calyea // Class and cell content. if (isset($typesbyday[$day]['startglobal'])) { - $class .= ' calendar_event_global'; + $class .= ' calendar_event_site'; } else if (isset($typesbyday[$day]['startcourse'])) { $class .= ' calendar_event_course'; } else if (isset($typesbyday[$day]['startgroup'])) { @@ -3464,6 +3464,11 @@ function calendar_get_view(\calendar_information $calendar, $view) { $monthdays = $type->get_num_days_in_month($date['year'], $date['mon']); $tend = $tstart + ($monthdays * DAYSECS) - 1; $selectortitle = get_string('detailedmonthviewfor', 'calendar'); + if ($view === 'mini') { + $template = 'core_calendar/calendar_mini'; + } else { + $template = 'core_calendar/calendar_month'; + } } list($userparam, $groupparam, $courseparam) = array_map(function($param) { @@ -3518,7 +3523,6 @@ function calendar_get_view(\calendar_information $calendar, $view) { $month = new \core_calendar\external\month_exporter($calendar, $type, $related); $data = $month->export($renderer); - $template = 'core_calendar/calendar_month'; return [$data, $template]; } @@ -3654,3 +3658,25 @@ function calendar_get_footer_options($calendar) { return [$data, $template]; } + +/** + * Get the list of potential calendar filter types as a type => name + * combination. + * + * @return array + */ +function calendar_get_filter_types() { + $types = [ + 'site', + 'course', + 'group', + 'user', + ]; + + return array_map(function($type) { + return [ + 'type' => $type, + 'name' => get_string("eventtype{$type}", "calendar"), + ]; + }, $types); +} diff --git a/calendar/renderer.php b/calendar/renderer.php index 181823461a1..d0fdec6cd66 100644 --- a/calendar/renderer.php +++ b/calendar/renderer.php @@ -502,4 +502,16 @@ class core_calendar_renderer extends plugin_renderer_base { $html .= html_writer::end_tag('form'); return $html; } + + /** + * Render the event filter region. + * + * @return string + */ + public function event_filter() { + $data = [ + 'eventtypes' => calendar_get_filter_types(), + ]; + return $this->render_from_template('core_calendar/event_filter', $data); + } } diff --git a/calendar/templates/calendar_mini.mustache b/calendar/templates/calendar_mini.mustache new file mode 100644 index 00000000000..6e28cbfab57 --- /dev/null +++ b/calendar/templates/calendar_mini.mustache @@ -0,0 +1,45 @@ +{{! + This file is part of Moodle - http://moodle.org/ + + Moodle is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Moodle is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Moodle. If not, see . +}} +{{! + @template calendar/calendar_mini + + Calendar month view for blocks. + + The purpose of this template is to render the month view for blocks. + + Classes required for JS: + * none + + Data attributes required for JS: + * none + + Example context (json): + { + } +}} + + {{> core_calendar/month_mini}} + +{{#js}} +require(['jquery', 'core_calendar/calendar_mini'], function($, CalendarMini) { + CalendarMini.init($("#calendar-month-{{uniqid}}-{{time}}")); +}); +{{/js}} diff --git a/calendar/templates/event_filter.mustache b/calendar/templates/event_filter.mustache new file mode 100644 index 00000000000..4e6e789e143 --- /dev/null +++ b/calendar/templates/event_filter.mustache @@ -0,0 +1,45 @@ +{{! + This file is part of Moodle - http://moodle.org/ + + Moodle is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Moodle is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Moodle. If not, see . +}} +{{! + @template calendar/event_filter + + Filter to select which event types displayed on this page. + + Classes required for JS: + * none + + Data attributes required for JS: + * none + + Example context (json): + { + } +}} +
+
    + {{#eventtypes}} +
  • + {{> core_calendar/event_filter_key }} +
  • + {{/eventtypes}} +
+
+{{#js}} +require(['jquery', 'core_calendar/calendar_filter'], function($, CalendarFilter) { + CalendarFilter.init($("#event-filter-{{uniqid}}")); +}); +{{/js}} diff --git a/calendar/templates/event_filter_key.mustache b/calendar/templates/event_filter_key.mustache new file mode 100644 index 00000000000..be1154b035c --- /dev/null +++ b/calendar/templates/event_filter_key.mustache @@ -0,0 +1,45 @@ +{{! + This file is part of Moodle - http://moodle.org/ + + Moodle is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Moodle is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Moodle. If not, see . +}} +{{! + @template calendar/event_filter_key + + Key item for the event filter. + + Classes required for JS: + * none + + Data attributes required for JS: + * none + + Example context (json): + { + } +}} + + {{^hidden}} + + {{#pix}}i/hide, core, {{#str}}hideeventtype, calendar, {{name}}{{/str}}{{/pix}} + + {{#str}}hideeventtype, calendar, {{name}}{{/str}} + {{/hidden}} + {{#hidden}} + + {{#pix}}i/show, core, {{#str}}showeventtype, calendar, {{name}}{{/str}}{{/pix}} + + {{#str}}showeventtype, calendar, {{name}}{{/str}} + {{/hidden}} + diff --git a/calendar/templates/minicalendar_day_link.mustache b/calendar/templates/minicalendar_day_link.mustache index bdb5e676181..d6c91afc76b 100644 --- a/calendar/templates/minicalendar_day_link.mustache +++ b/calendar/templates/minicalendar_day_link.mustache @@ -29,10 +29,10 @@ }} {{< core/hover_tooltip }} {{$anchor}} - {{day}} + {{$day}}{{day}}{{/day}} {{/anchor}} {{$tooltip}} - {{title}} - {{{content}}} + {{$title}}{{title}}{{/title}} + {{$content}}{{{content}}}{{/content}} {{/tooltip}} {{/ core/hover_tooltip }} diff --git a/calendar/templates/month_mini.mustache b/calendar/templates/month_mini.mustache new file mode 100644 index 00000000000..b14afc906c0 --- /dev/null +++ b/calendar/templates/month_mini.mustache @@ -0,0 +1,154 @@ +{{! + This file is part of Moodle - http://moodle.org/ + + Moodle is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Moodle is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Moodle. If not, see . +}} +{{! + @template calendar/month_mini + + Calendar month view for blocks. + + The purpose of this template is to render the month view for blocks. + + Classes required for JS: + * none + + Data attributes required for JS: + * none + + Example context (json): + { + } +}} +
+ {{> core/overlay_loading}} + + + + + {{# daynames }} + + {{/ daynames }} + + + +{{#weeks}} + + {{#prepadding}} + + {{/prepadding}} + {{#days}} + + {{/days}} + {{#postpadding}} + + {{/postpadding}} + +{{/weeks}} + +
+ + | + + {{periodname}} + + | + +
+ {{shortname}} +
 {{! + }}{{#popovertitle}} + {{< core_calendar/minicalendar_day_link }} + {{$day}}{{mday}}{{/day}} + {{$url}}{{viewdaylink}}{{/url}} + {{$title}}{{popovertitle}}{{/title}} + {{$nocontent}}{{#str}}eventnone, calendar{{/str}}{{/nocontent}} + {{$content}} + {{#events}} +
+ {{#modulename}} + {{#pix}} icon, {{modulename}} {{/pix}} + {{/modulename}} + {{^modulename}} + {{#pix}} i/{{eventtype}}event, core {{/pix}} + {{/modulename}} + {{{popupname}}} +
+ {{/events}} + {{/content}} + {{/ core_calendar/minicalendar_day_link }} + {{/popovertitle}}{{! + }}{{^popovertitle}} + {{mday}} + {{/popovertitle}}{{! + }}
 
+
+{{#js}} +require([ + 'jquery', + 'core_calendar/selectors', + 'core_calendar/events', +], function( + $, + CalendarSelectors, + CalendarEvents +) { + + $('body').on(CalendarEvents.filterChanged, function(e, data) { + M.util.js_pending("month-mini-{{uniqid}}-filterChanged"); + // A filter value has been changed. + // Find all matching cells in the popover data, and hide them. + $("#month-mini-{{uniqid}}-{{time}}") + .find(CalendarSelectors.popoverType[data.type]) + .toggleClass('hidden', !!data.hidden); + M.util.js_complete("month-mini-{{uniqid}}-filterChanged"); + }); +}); +{{/js}} diff --git a/calendar/tests/behat/behat_calendar.php b/calendar/tests/behat/behat_calendar.php index ef8fa66aa9f..0bd835cc666 100644 --- a/calendar/tests/behat/behat_calendar.php +++ b/calendar/tests/behat/behat_calendar.php @@ -84,9 +84,9 @@ class behat_calendar extends behat_base { * @param int $day The day of the current month */ public function i_hover_over_day_of_this_month_in_calendar($day) { - $summarytitle = get_string('calendarheading', 'calendar', userdate(time(), get_string('strftimemonthyear'))); + $summarytitle = userdate(time(), get_string('strftimemonthyear')); // The current month table. - $currentmonth = "table[contains(concat(' ', normalize-space(@summary), ' '), ' {$summarytitle} ')]"; + $currentmonth = "table[descendant::*[self::caption[contains(concat(' ', normalize-space(.), ' '), ' {$summarytitle} ')]]]"; // Strings for the class cell match. $cellclasses = "contains(concat(' ', normalize-space(@class), ' '), ' day ')"; @@ -95,6 +95,7 @@ class behat_calendar extends behat_base { $dayofmonth = "a[{$daycontains}]"; $xpath = '//' . $currentmonth . '/descendant::' . $daycell . '/' . $dayofmonth; + $this->execute("behat_general::wait_until_the_page_is_ready"); $this->execute("behat_general::i_hover", array($xpath, "xpath_element")); } diff --git a/lang/en/access.php b/lang/en/access.php index 6e8789ee219..9eb6d21fbaf 100644 --- a/lang/en/access.php +++ b/lang/en/access.php @@ -30,8 +30,6 @@ $string['activitynext'] = 'Next activity'; $string['activityprev'] = 'Previous activity'; $string['breadcrumb'] = 'Breadcrumb trail'; $string['hideblocka'] = 'Hide {$a} block'; -$string['monthnext'] = 'Next month'; -$string['monthprev'] = 'Previous month'; $string['showblocka'] = 'Show {$a} block'; $string['sitemap'] = 'Site map'; $string['skipa'] = 'Skip {$a}'; @@ -41,3 +39,7 @@ $string['skipto'] = 'Skip to {$a}'; $string['tocontent'] = 'Skip to main content'; $string['tonavigation'] = 'Go to navigation'; $string['youarehere'] = 'You are here'; + +// Deprecated since Moodle 3.4. +$string['monthnext'] = 'Next month'; +$string['monthprev'] = 'Previous month'; diff --git a/lang/en/calendar.php b/lang/en/calendar.php index 405046de3d0..aad2d9138e4 100644 --- a/lang/en/calendar.php +++ b/lang/en/calendar.php @@ -90,6 +90,7 @@ $string['eventdate'] = 'Date'; $string['eventdescription'] = 'Description'; $string['eventduration'] = 'Duration'; $string['eventendtime'] = 'End time'; +$string['eventendtimewrapped'] = '{$a} (End time)'; $string['eventinstanttime'] = 'Time'; $string['eventkind'] = 'Type of event'; $string['eventname'] = 'Event title'; @@ -138,7 +139,16 @@ $string['groupevents'] = 'Group events'; $string['hidecourseevents'] = 'Hide course events'; $string['hideglobalevents'] = 'Hide global events'; $string['hidegroupsevents'] = 'Hide group events'; +$string['hidemoduleevents'] = 'Hide module events'; $string['hideuserevents'] = 'Hide user events'; +$string['eventtypeglobal'] = 'global'; +$string['eventtypesite'] = 'global'; +$string['eventtypecourse'] = 'course'; +$string['eventtypemodule'] = 'module'; +$string['eventtypegroup'] = 'group'; +$string['eventtypeuser'] = 'user'; +$string['hideeventtype'] = 'Hide {$a} events'; +$string['showeventtype'] = 'Show {$a} events'; $string['hourly'] = 'Hourly'; $string['ical'] = 'iCal'; $string['importcalendar'] = 'Import calendar'; @@ -159,9 +169,10 @@ $string['monday'] = 'Monday'; $string['monthly'] = 'Monthly'; $string['monthlyview'] = 'Monthly view'; $string['monthnext'] = 'Next month'; +$string['monthprev'] = 'Previous month'; $string['monththis'] = 'This month'; $string['more'] = 'More'; -$string['namewithsource'] = '{$a->name}({$a->source})'; +$string['namewithsource'] = '{$a->name} ({$a->source})'; $string['never'] = 'Never'; $string['newevent'] = 'New event'; $string['notitle'] = 'no title'; @@ -214,6 +225,7 @@ $string['timeformat_12'] = '12-hour (am/pm)'; $string['timeformat_24'] = '24-hour'; $string['timeperiod'] = 'Time period'; $string['today'] = 'Today'; +$string['todayplustitle'] = 'Today {$a}'; $string['tomorrow'] = 'Tomorrow'; $string['tt_deleteevent'] = 'Delete event'; $string['tt_editevent'] = 'Edit event'; diff --git a/lang/en/deprecated.txt b/lang/en/deprecated.txt index 55a0e70b83b..995f16bc483 100644 --- a/lang/en/deprecated.txt +++ b/lang/en/deprecated.txt @@ -61,3 +61,5 @@ error:backpackloginfailed,core_badges signinwithyouremail,core_badges sectionusedefaultname,core registermoochtips,core_hub +monthnext,core_access +monthprev,core_access diff --git a/theme/boost/scss/moodle/calendar.scss b/theme/boost/scss/moodle/calendar.scss index 2c047052fc3..b13af94c9bd 100644 --- a/theme/boost/scss/moodle/calendar.scss +++ b/theme/boost/scss/moodle/calendar.scss @@ -355,3 +355,13 @@ table.calendartable caption { } } } + +.calendarwrapper { + position: relative; +} + +.day-popover-content { + &:empty + .day-popover-alternate { + display: block; + } +} diff --git a/theme/boost/templates/core_calendar/minicalendar_day_link.mustache b/theme/boost/templates/core_calendar/minicalendar_day_link.mustache index d4ce07caca4..072345dad23 100644 --- a/theme/boost/templates/core_calendar/minicalendar_day_link.mustache +++ b/theme/boost/templates/core_calendar/minicalendar_day_link.mustache @@ -27,12 +27,38 @@ "content": "Test site event" } }} -{{day}} +{{$day}}{{day}}{{/day}} + +{{#js}} +require(['jquery'], function($) { + require(['theme_boost/popover'], function() { + var target = $("#calendar-day-popover-link-{{courseid}}-{{year}}-{{yday}}-{{uniqid}}"); + target.popover({ + content: function() { + var source = target.next().find("> *:not('.hidden')"); + var content = $('
'); + + if (source.length) { + content.html(source.clone(false)); + } else { + content.html(target.data('alternate')); + } + + return content.html(); + } + }); + }); +}); +{{/js}} diff --git a/theme/bootstrapbase/less/moodle/calendar.less b/theme/bootstrapbase/less/moodle/calendar.less index 0e84a086b1d..72fb4a48402 100644 --- a/theme/bootstrapbase/less/moodle/calendar.less +++ b/theme/bootstrapbase/less/moodle/calendar.less @@ -345,3 +345,8 @@ } } } + + +.calendarwrapper { + position: relative; +} diff --git a/theme/bootstrapbase/style/moodle.css b/theme/bootstrapbase/style/moodle.css index b6f4cfd6caa..2e34106198f 100644 --- a/theme/bootstrapbase/style/moodle.css +++ b/theme/bootstrapbase/style/moodle.css @@ -5852,6 +5852,9 @@ img.iconsmall { min-width: 1024px; } } +.calendarwrapper { + position: relative; +} /* course.less */ /* COURSE CONTENT */ /* stylelint-disable unit-blacklist */ diff --git a/theme/bootstrapbase/templates/core_calendar/minicalendar_day_link.mustache b/theme/bootstrapbase/templates/core_calendar/minicalendar_day_link.mustache index c3a003417c7..56f0e7bb463 100644 --- a/theme/bootstrapbase/templates/core_calendar/minicalendar_day_link.mustache +++ b/theme/bootstrapbase/templates/core_calendar/minicalendar_day_link.mustache @@ -27,18 +27,38 @@ "content": "Test site event" } }} -{{day}} +{{$day}}{{day}}{{/day}} + {{#js}} -require(['jquery'], function($) { +require(['jquery', 'theme_bootstrapbase/bootstrap'], function($) { require(['theme_bootstrapbase/bootstrap'], function() { - $('#{{uniqid}}').popover(); + var target = $("#calendar-day-popover-link-{{courseid}}-{{year}}-{{yday}}-{{uniqid}}"); + target.popover({ + content: function() { + var source = target.next().find("> *:not('.hidden')"); + var content = $('
'); + + if (source.length) { + content.html(source.clone(false)); + } else { + content.html(target.data('alternate')); + } + + return content.html(); + } + }); }); }); {{/js}} From fc60d3194fba740fc9a5ba1f4dcb7a052edf944e Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Fri, 8 Sep 2017 13:45:38 +0800 Subject: [PATCH 8/9] MDL-59392 calendar: Apply event filters to main calendar view --- calendar/lib.php | 2 +- calendar/templates/month_detailed.mustache | 25 ++++++++++++++++++++-- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/calendar/lib.php b/calendar/lib.php index 34bd7b421b2..11df73fc61c 100644 --- a/calendar/lib.php +++ b/calendar/lib.php @@ -1049,7 +1049,7 @@ class calendar_information { public function add_sidecalendar_blocks(core_calendar_renderer $renderer, $showfilters=false, $view=null) { if ($showfilters) { $filters = new block_contents(); - $filters->content = $renderer->fake_block_filters($this->courseid, 0, 0, 0, $view, $this->courses); + $filters->content = $renderer->event_filter(); $filters->footer = ''; $filters->title = get_string('eventskey', 'calendar'); $renderer->add_pretend_calendar_block($filters, BLOCK_POS_RIGHT); diff --git a/calendar/templates/month_detailed.mustache b/calendar/templates/month_detailed.mustache index 80005dc134c..463b687216b 100644 --- a/calendar/templates/month_detailed.mustache +++ b/calendar/templates/month_detailed.mustache @@ -77,8 +77,9 @@
  • [{{name}}]
  • {{/underway}} {{^underway}} -
  • {{#js}} -require(['jquery', 'core_calendar/month_view_drag_drop'], function($, DragDrop) { +require([ + 'jquery', + 'core_calendar/month_view_drag_drop', + 'core_calendar/selectors', + 'core_calendar/events', +], function( + $, + DragDrop, + CalendarSelectors, + CalendarEvents +) { var root = $('#month-detailed-{{uniqid}}'); DragDrop.init(root); + + $('body').on(CalendarEvents.filterChanged, function(e, data) { + M.util.js_pending("month-detailed-{{uniqid}}-filterChanged"); + // A filter value has been changed. + // Find all matching cells in the popover data, and hide them. + $("#month-detailed-{{uniqid}}") + .find(CalendarSelectors.eventType[data.type]) + .toggleClass('hidden', !!data.hidden); + M.util.js_complete("month-detailed-{{uniqid}}-filterChanged"); + }); }); {{/js}} From 7aaca085fb4de37d378add1f08b3d8b1ef61c291 Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Fri, 8 Sep 2017 13:51:40 +0800 Subject: [PATCH 9/9] MDL-59392 calendar: Deprecate old event filters --- calendar/lib.php | 82 ------------------------------------------ calendar/renderer.php | 18 ---------- calendar/set.php | 60 ------------------------------- lang/en/calendar.php | 35 +++++++++--------- lang/en/deprecated.txt | 16 +++++++++ 5 files changed, 34 insertions(+), 177 deletions(-) delete mode 100644 calendar/set.php diff --git a/calendar/lib.php b/calendar/lib.php index 11df73fc61c..c1b342b9629 100644 --- a/calendar/lib.php +++ b/calendar/lib.php @@ -1981,88 +1981,6 @@ function calendar_top_controls($type, $data) { return $content; } -/** - * Formats a filter control element. - * - * @param moodle_url $url of the filter - * @param int $type constant defining the type filter - * @return string html content of the element - */ -function calendar_filter_controls_element(moodle_url $url, $type) { - global $OUTPUT; - - switch ($type) { - case CALENDAR_EVENT_GLOBAL: - $typeforhumans = 'global'; - $class = 'calendar_event_global'; - break; - case CALENDAR_EVENT_COURSE: - $typeforhumans = 'course'; - $class = 'calendar_event_course'; - break; - case CALENDAR_EVENT_GROUP: - $typeforhumans = 'groups'; - $class = 'calendar_event_group'; - break; - case CALENDAR_EVENT_USER: - $typeforhumans = 'user'; - $class = 'calendar_event_user'; - break; - } - - if (calendar_show_event_type($type)) { - $icon = $OUTPUT->pix_icon('t/hide', get_string('hide')); - $str = get_string('hide' . $typeforhumans . 'events', 'calendar'); - } else { - $icon = $OUTPUT->pix_icon('t/show', get_string('show')); - $str = get_string('show' . $typeforhumans . 'events', 'calendar'); - } - $content = \html_writer::start_tag('li', array('class' => 'calendar_event')); - $content .= \html_writer::start_tag('a', array('href' => $url, 'rel' => 'nofollow')); - $content .= \html_writer::tag('span', $icon, array('class' => $class)); - $content .= \html_writer::tag('span', $str, array('class' => 'eventname')); - $content .= \html_writer::end_tag('a'); - $content .= \html_writer::end_tag('li'); - - return $content; -} - -/** - * Get the controls filter for calendar. - * - * Filter is used to hide calendar info from the display page. - * - - * @param moodle_url $returnurl return-url for filter controls - * @return string $content return filter controls in html - */ -function calendar_filter_controls(moodle_url $returnurl) { - $groupevents = true; - - $seturl = new \moodle_url('/calendar/set.php', array('return' => base64_encode($returnurl->out_as_local_url(false)), - 'sesskey' => sesskey())); - $content = \html_writer::start_tag('ul'); - - $seturl->param('var', 'showglobal'); - $content .= calendar_filter_controls_element($seturl, CALENDAR_EVENT_GLOBAL); - - $seturl->param('var', 'showcourses'); - $content .= calendar_filter_controls_element($seturl, CALENDAR_EVENT_COURSE); - - if (isloggedin() && !isguestuser()) { - if ($groupevents) { - // This course MIGHT have group events defined, so show the filter. - $seturl->param('var', 'showgroups'); - $content .= calendar_filter_controls_element($seturl, CALENDAR_EVENT_GROUP); - } - $seturl->param('var', 'showuser'); - $content .= calendar_filter_controls_element($seturl, CALENDAR_EVENT_USER); - } - $content .= \html_writer::end_tag('ul'); - - return $content; -} - /** * Return the representation day. * diff --git a/calendar/renderer.php b/calendar/renderer.php index d0fdec6cd66..dc597abf2e6 100644 --- a/calendar/renderer.php +++ b/calendar/renderer.php @@ -50,24 +50,6 @@ class core_calendar_renderer extends plugin_renderer_base { return html_writer::end_tag('div'); } - /** - * Produces the content for the filters block (pretend block) - * - * @param int $courseid - * @param int $day - * @param int $month - * @param int $year - * @param int $view - * @param int $courses - * @return string - */ - public function fake_block_filters($courseid, $day, $month, $year, $view, $courses) { - $returnurl = $this->page->url; - $returnurl->param('course', $courseid); - return html_writer::tag('div', calendar_filter_controls($returnurl), - array('class' => 'calendar_filters filters')); - } - /** * Produces the content for the three months block (pretend block) * diff --git a/calendar/set.php b/calendar/set.php deleted file mode 100644 index c69de934a1a..00000000000 --- a/calendar/set.php +++ /dev/null @@ -1,60 +0,0 @@ -. - -/** - * Sets the events filter for the calendar view. - * - * @package core_calendar - * @copyright 2003 Jon Papaioannou (pj@moodle.org) - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -require_once('../config.php'); -require_once($CFG->dirroot.'/calendar/lib.php'); - -$var = required_param('var', PARAM_ALPHA); -$return = clean_param(base64_decode(required_param('return', PARAM_RAW)), PARAM_LOCALURL); -$courseid = optional_param('id', -1, PARAM_INT); -if ($courseid != -1) { - $return = new moodle_url($return, array('course' => $courseid)); -} else { - $return = new moodle_url($return); -} - -if (!confirm_sesskey()) { - // Do not call require_sesskey() since this page may be accessed without session (for example by bots). - redirect($return); -} - -$url = new moodle_url('/calendar/set.php', array('return'=>base64_encode($return->out_as_local_url(false)), 'course' => $courseid, 'var'=>$var, 'sesskey'=>sesskey())); -$PAGE->set_url($url); -$PAGE->set_context(context_system::instance()); - -switch($var) { - case 'showgroups': - calendar_set_event_type_display(CALENDAR_EVENT_GROUP); - break; - case 'showcourses': - calendar_set_event_type_display(CALENDAR_EVENT_COURSE); - break; - case 'showglobal': - calendar_set_event_type_display(CALENDAR_EVENT_GLOBAL); - break; - case 'showuser': - calendar_set_event_type_display(CALENDAR_EVENT_USER); - break; -} - -redirect($return); diff --git a/lang/en/calendar.php b/lang/en/calendar.php index aad2d9138e4..30a936c1387 100644 --- a/lang/en/calendar.php +++ b/lang/en/calendar.php @@ -136,11 +136,6 @@ $string['gotocalendar'] = 'Go to calendar'; $string['group'] = 'Group'; $string['groupevent'] = 'Group event'; $string['groupevents'] = 'Group events'; -$string['hidecourseevents'] = 'Hide course events'; -$string['hideglobalevents'] = 'Hide global events'; -$string['hidegroupsevents'] = 'Hide group events'; -$string['hidemoduleevents'] = 'Hide module events'; -$string['hideuserevents'] = 'Hide user events'; $string['eventtypeglobal'] = 'global'; $string['eventtypesite'] = 'global'; $string['eventtypecourse'] = 'course'; @@ -205,10 +200,6 @@ $string['repeatweeksl'] = 'Repeat weekly, creating altogether'; $string['repeatweeksr'] = 'events'; $string['sat'] = 'Sat'; $string['saturday'] = 'Saturday'; -$string['showcourseevents'] = 'Show course events'; -$string['showglobalevents'] = 'Show global events'; -$string['showgroupsevents'] = 'Show group events'; -$string['showuserevents'] = 'Show user events'; $string['shown'] = 'shown'; $string['siteevents'] = 'Site events'; $string['spanningevents'] = 'Events underway'; @@ -229,14 +220,6 @@ $string['todayplustitle'] = 'Today {$a}'; $string['tomorrow'] = 'Tomorrow'; $string['tt_deleteevent'] = 'Delete event'; $string['tt_editevent'] = 'Edit event'; -$string['tt_hidecourse'] = 'Course events are shown (click to hide)'; -$string['tt_hideglobal'] = 'Global events are shown (click to hide)'; -$string['tt_hidegroups'] = 'Group events are shown (click to hide)'; -$string['tt_hideuser'] = 'User events are shown (click to hide)'; -$string['tt_showcourse'] = 'Course events are hidden (click to show)'; -$string['tt_showglobal'] = 'Global events are hidden (click to show)'; -$string['tt_showgroups'] = 'Group events are hidden (click to show)'; -$string['tt_showuser'] = 'User events are hidden (click to show)'; $string['tue'] = 'Tue'; $string['tuesday'] = 'Tuesday'; $string['typeclose'] = 'Close event'; @@ -264,3 +247,21 @@ $string['youcandeleteallrepeats'] = 'This event is part of a repeating event ser // Deprecated since Moodle 3.2. $string['for'] = 'for'; + +// Deprecated since Moodle 3.4. +$string['tt_hidecourse'] = 'Course events are shown (click to hide)'; +$string['tt_hideglobal'] = 'Global events are shown (click to hide)'; +$string['tt_hidegroups'] = 'Group events are shown (click to hide)'; +$string['tt_hideuser'] = 'User events are shown (click to hide)'; +$string['tt_showcourse'] = 'Course events are hidden (click to show)'; +$string['tt_showglobal'] = 'Global events are hidden (click to show)'; +$string['tt_showgroups'] = 'Group events are hidden (click to show)'; +$string['tt_showuser'] = 'User events are hidden (click to show)'; +$string['hidecourseevents'] = 'Hide course events'; +$string['hideglobalevents'] = 'Hide global events'; +$string['hidegroupsevents'] = 'Hide group events'; +$string['hideuserevents'] = 'Hide user events'; +$string['showcourseevents'] = 'Show course events'; +$string['showglobalevents'] = 'Show global events'; +$string['showgroupsevents'] = 'Show group events'; +$string['showuserevents'] = 'Show user events'; diff --git a/lang/en/deprecated.txt b/lang/en/deprecated.txt index 995f16bc483..cd7bb58f4ea 100644 --- a/lang/en/deprecated.txt +++ b/lang/en/deprecated.txt @@ -63,3 +63,19 @@ sectionusedefaultname,core registermoochtips,core_hub monthnext,core_access monthprev,core_access +tt_hidecourse,core_calendar +tt_hideglobal,core_calendar +tt_hidegroups,core_calendar +tt_hideuser,core_calendar +tt_showcourse,core_calendar +tt_showglobal,core_calendar +tt_showgroups,core_calendar +tt_showuser,core_calendar +hidecourseevents,core_calendar +hideglobalevents,core_calendar +hidegroupsevents,core_calendar +hideuserevents,core_calendar +showcourseevents,core_calendar +showglobalevents,core_calendar +showgroupsevents,core_calendar +showuserevents,core_calendar