MDL-59750 calendar: render day view using templates

This commit is contained in:
Simey Lameze 2017-09-18 10:53:26 +08:00
parent ac671b3739
commit 146d371344
8 changed files with 368 additions and 49 deletions

View File

@ -46,6 +46,10 @@ class day_exporter extends exporter {
*/
protected $calendar;
/**
* @var moodle_url
*/
protected $url;
/**
* Constructor.
*
@ -55,7 +59,11 @@ class day_exporter extends exporter {
*/
public function __construct(\calendar_information $calendar, $data, $related) {
$this->calendar = $calendar;
$this->url = new moodle_url('/calendar/view.php', [
'view' => 'day',
'time' => $calendar->time,
'course' => $this->calendar->course->id,
]);
parent::__construct($data, $related);
}
@ -89,15 +97,6 @@ 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,
],
];
}
@ -126,6 +125,15 @@ class day_exporter extends exporter {
'type' => PARAM_RAW,
'multiple' => true,
],
'previousperiod' => [
'type' => PARAM_INT,
],
'nextperiod' => [
'type' => PARAM_INT,
],
'navigation' => [
'type' => PARAM_RAW,
],
'popovertitle' => [
'type' => PARAM_RAW,
'default' => '',
@ -134,6 +142,12 @@ class day_exporter extends exporter {
'type' => PARAM_BOOL,
'default' => false,
],
'filter_selector' => [
'type' => PARAM_RAW,
],
'new_event_button' => [
'type' => PARAM_RAW,
],
];
}
@ -144,6 +158,7 @@ class day_exporter extends exporter {
* @return array Keys are the property names, values are their values.
*/
protected function get_other_values(renderer_base $output) {
$daytimestamp = $this->calendar->time;
$timestamp = $this->data[0];
// Need to account for user's timezone.
$usernow = usergetdate(time());
@ -158,24 +173,24 @@ class day_exporter extends exporter {
$return = [
'timestamp' => $timestamp,
'neweventtimestamp' => $neweventstarttime->getTimestamp()
'neweventtimestamp' => $neweventstarttime->getTimestamp(),
'previousperiod' => $this->get_previous_day_timestamp($daytimestamp),
'nextperiod' => $this->get_next_day_timestamp($daytimestamp),
'navigation' => $this->get_navigation(),
'filter_selector' => $this->get_course_filter_selector($output),
'new_event_button' => $this->get_new_event_button(),
];
$url = new moodle_url('/calendar/view.php', [
'view' => 'day',
'time' => $timestamp,
'course' => $this->calendar->course->id,
]);
$return['viewdaylink'] = $url->out(false);
$return['viewdaylink'] = $this->url->out(false);
$cache = $this->related['cache'];
$eventexporters = array_map(function($event) use ($cache, $output, $url) {
$eventexporters = array_map(function($event) use ($cache, $output) {
$context = $cache->get_context($event);
$course = $cache->get_course($event);
$exporter = new calendar_event_exporter($event, [
'context' => $context,
'course' => $course,
'daylink' => $url,
'daylink' => $this->url,
'type' => $this->related['type'],
'today' => $this->data[0],
]);
@ -187,9 +202,7 @@ class day_exporter extends exporter {
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();
@ -221,24 +234,112 @@ class day_exporter extends exporter {
}
/**
* Get the title for this popover.
* Get the previous day timestamp.
*
* @return string
* @param int $daytimestamp The current day timestamp.
* @return int The previous day timestamp.
*/
protected function get_popover_title() {
$title = null;
protected function get_previous_day_timestamp($daytimestamp) {
return $this->related['type']->get_prev_day($daytimestamp);
}
$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;
/**
* Get the next day timestamp.
*
* @param int $daytimestamp The current day timestamp.
* @return int The next day timestamp.
*/
protected function get_next_day_timestamp($daytimestamp) {
return $this->related['type']->get_next_day($daytimestamp);
}
/**
* Get the calendar navigation controls.
*
* @return string The html code to the calendar top navigation.
*/
protected function get_navigation() {
return calendar_top_controls('day', [
'id' => $this->calendar->courseid,
'time' => $this->calendar->time,
]);
}
/**
* Get the course filter selector.
*
* This is a temporary solution, this code will be removed by MDL-60096.
*
* @param renderer_base $output
* @return string The html code for the course filter selector.
*/
protected function get_course_filter_selector(renderer_base $output) {
global $CFG;
// TODO remove this code on MDL-60096.
if (!isloggedin() or isguestuser()) {
return '';
}
if ($this->data['istoday']) {
$title = get_string('todayplustitle', 'calendar', $userdate);
if (has_capability('moodle/calendar:manageentries', \context_system::instance()) && !empty($CFG->calendar_adminseesall)) {
$courses = get_courses('all', 'c.shortname', 'c.id, c.shortname');
} else {
$courses = enrol_get_my_courses();
}
return $title;
unset($courses[SITEID]);
$courseoptions = array();
$courseoptions[SITEID] = get_string('fulllistofcourses');
foreach ($courses as $course) {
$coursecontext = \context_course::instance($course->id);
$courseoptions[$course->id] = format_string($course->shortname, true, array('context' => $coursecontext));
}
if ($this->calendar->courseid !== SITEID) {
$selected = $this->calendar->courseid;
} else {
$selected = '';
}
$courseurl = new moodle_url($this->url);
$courseurl->remove_params('course');
$select = new \single_select($courseurl, 'courseselect', $courseoptions, $selected, null);
$select->class = 'm-r-1';
$label = get_string('dayviewfor', 'calendar');
if ($label !== null) {
$select->set_label($label);
} else {
$select->set_label(get_string('listofcourses'), array('class' => 'accesshide'));
}
return $output->render($select);
}
/**
* Get the course filter selector.
*
* This is a temporary solution, this code will be removed by MDL-60096.
*
* @return string The html code for the course filter selector.
*/
protected function get_new_event_button() {
// TODO remove this code on MDL-60096.
$output = \html_writer::start_tag('div', array('class' => 'buttons'));
$output .= \html_writer::start_tag('form',
array('action' => CALENDAR_URL . 'event.php', 'method' => 'get'));
$output .= \html_writer::start_tag('div');
$output .= \html_writer::empty_tag('input',
array('type' => 'hidden', 'name' => 'action', 'value' => 'new'));
$output .= \html_writer::empty_tag('input',
array('type' => 'hidden', 'name' => 'course', 'value' => $this->calendar->courseid));
$output .= \html_writer::empty_tag('input',
array('type' => 'hidden', 'name' => 'time', 'value' => $this->calendar->time));
$attributes = array('type' => 'submit', 'value' => get_string('newevent', 'calendar'),
'class' => 'btn btn-secondary');
$output .= \html_writer::empty_tag('input', $attributes);
$output .= \html_writer::end_tag('div');
$output .= \html_writer::end_tag('form');
$output .= \html_writer::end_tag('div');
return $output;
}
}

View File

@ -38,6 +38,27 @@ use moodle_url;
*/
class week_day_exporter extends day_exporter {
/**
* Return the list of properties.
*
* @return array
*/
protected static function define_properties() {
$return = parent::define_properties();
$return = array_merge($return, [
// These are additional params.
'istoday' => [
'type' => PARAM_BOOL,
'default' => false,
],
'isweekend' => [
'type' => PARAM_BOOL,
'default' => false,
],
]);
return $return;
}
/**
* Return the list of additional properties.
*
@ -92,18 +113,18 @@ class week_day_exporter extends day_exporter {
$usernow['seconds']
);
$return = [
'timestamp' => $timestamp,
'neweventtimestamp' => $neweventstarttime->getTimestamp()
];
$return = parent::get_other_values($output);
$url = new moodle_url('/calendar/view.php', [
'view' => 'day',
'time' => $timestamp,
'course' => $this->calendar->course->id,
]);
$return['viewdaylink'] = $url->out(false);
]);
$return['viewdaylink'] = $url->out(false);
if ($popovertitle = $this->get_popover_title()) {
$return['popovertitle'] = $popovertitle;
}
$cache = $this->related['cache'];
$eventexporters = array_map(function($event) use ($cache, $output, $url) {
$context = $cache->get_context($event);

View File

@ -3019,20 +3019,20 @@ function calendar_get_view(\calendar_information $calendar, $view, $includenavig
// Calculate the bounds of the month.
$date = $type->timestamp_to_date_array($calendar->time);
$tstart = $type->convert_to_timestamp($date['year'], $date['mon'], 1);
if ($view === 'day') {
$tstart = $type->convert_to_timestamp($date['year'], $date['mon'], $date['mday']);
$tend = $tstart + DAYSECS - 1;
$selectortitle = get_string('dayviewfor', 'calendar');
} else if ($view === 'upcoming') {
if (isset($CFG->calendar_lookahead)) {
$defaultlookahead = intval($CFG->calendar_lookahead);
} else {
$defaultlookahead = CALENDAR_DEFAULT_UPCOMING_LOOKAHEAD;
}
$tstart = $type->convert_to_timestamp($date['year'], $date['mon'], 1);
$tend = $tstart + get_user_preferences('calendar_lookahead', $defaultlookahead);
$selectortitle = get_string('upcomingeventsfor', 'calendar');
} else {
$tstart = $type->convert_to_timestamp($date['year'], $date['mon'], 1);
$monthdays = $type->get_num_days_in_month($date['year'], $date['mon']);
$tend = $tstart + ($monthdays * DAYSECS) - 1;
$selectortitle = get_string('detailedmonthviewfor', 'calendar');
@ -3091,13 +3091,20 @@ function calendar_get_view(\calendar_information $calendar, $view, $includenavig
$related = [
'events' => $events,
'cache' => new \core_calendar\external\events_related_objects_cache($events),
'type' => $type,
];
$month = new \core_calendar\external\month_exporter($calendar, $type, $related);
$month->set_includenavigation($includenavigation);
$data = $month->export($renderer);
$data = [];
if ($view == "month" || $view == "mini") {
$month = new \core_calendar\external\month_exporter($calendar, $type, $related);
$month->set_includenavigation($includenavigation);
$data = $month->export($renderer);
} else if ($view == "day") {
$daydata = $type->timestamp_to_date_array($tstart);
$day = new \core_calendar\external\day_exporter($calendar, $daydata, $related);
$data = $day->export($renderer);
$template = 'core_calendar/day_detailed';
}
return [$data, $template];
}

View File

@ -0,0 +1,39 @@
{{!
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 <http://www.gnu.org/licenses/>.
}}
{{!
@template calendar/day_detailed
Calendar day view.
The purpose of this template is to render the calendar day view.
Classes required for JS:
* none
Data attributes required for JS:
* none
Example context (json):
{
}
}}
<div class="header">
{{{filter_selector}}}
{{{new_event_button}}}
</div>
{{> core_calendar/day_navigation }}
{{> core_calendar/event_list }}

View File

@ -0,0 +1,39 @@
{{!
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 <http://www.gnu.org/licenses/>.
}}
{{!
@template calendar/day_navigation
Calendar day navigation.
The purpose of this template is to render the navigation to switch to previous and next months.
Classes required for JS:
* none
Data attributes required for JS:
* none
Example context (json):
{
}
}}
{{#navigation}}
<div class="controls" data-view="{{view}}">
{{{navigation}}}
</div>
{{/navigation}}

View File

@ -0,0 +1,68 @@
{{!
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 <http://www.gnu.org/licenses/>.
}}
{{!
@template calendar/event_item
Calendar event item.
The purpose of this template is to render the event item.
Classes required for JS:
* none
Data attributes required for JS:
* none
Example context (json):
{
}
}}
<div class="event">
<div class="card">
<div class="box card-header clearfix p-y-1">
<div class="commands pull-xs-right">
{{#canedit}}
{{#candelete}}
<a href="{{deleteurl}}">
{{#pix}}t/delete, core, {{#str}}delete{{/str}}{{/pix}}
</a>
{{/candelete}}
<a href="{{editurl}}">
{{#pix}}t/edit, core, {{#str}}edit{{/str}}{{/pix}}
</a>
{{/canedit}}
</div>
{{#icon}}{{#pix}} {{key}}, {{component}}, {{alttext}} {{/pix}}{{/icon}}
<h3 class="name d-inline-block">{{name}}</h3>
<span class="date pull-xs-right m-r-1">{{{formattedtime}}}</span>
</div>
<div class="description card-block calendar_event_{{eventtype}}">
<p>{{{description}}}</p>
{{#iscourseevent}}
<div><a href="{{url}}">{{course.fullname}}</a></div>
{{/iscourseevent}}
{{> core_calendar/event_subscription}}
{{#isactionevent}}
<a href="{{url}}">{{#str}} gotoactivity, core_calendar {{/str}}</a>
{{/isactionevent}}
{{#groupname}}
<div><a href="{{url}}">{{{course.fullname}}}</a></div>
<div>{{{groupname}}}</div>
{{/groupname}}
</div>
</div>
</div>

View File

@ -0,0 +1,43 @@
{{!
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 <http://www.gnu.org/licenses/>.
}}
{{!
@template calendar/event_list
Calendar event list.
The purpose of this template is to render a list of events.
Classes required for JS:
* none
Data attributes required for JS:
* none
Example context (json):
{
}
}}
<div class="eventlist">
{{#events}}
{{> core_calendar/event_item }}
{{/events}}
{{^events}}
<span class="calendar-information calendar-no-results">
{{#str}}daywithnoevents, calendar{{/str}}
</span>
{{/events}}
</div>

View File

@ -123,7 +123,8 @@ echo $OUTPUT->heading(get_string('calendar', 'calendar'));
if ($view == 'day' || $view == 'upcoming') {
switch($view) {
case 'day':
echo $renderer->show_day($calendar);
list($data, $template) = calendar_get_view($calendar, $view);
echo $renderer->render_from_template($template, $data);
break;
case 'upcoming':
$defaultlookahead = CALENDAR_DEFAULT_UPCOMING_LOOKAHEAD;