first commit

This commit is contained in:
CHIEFSOFT\ameye
2024-09-30 18:11:26 -04:00
commit e592ca6823
27270 changed files with 5002257 additions and 0 deletions
+279
View File
@@ -0,0 +1,279 @@
<?php
// 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/>.
namespace core_calendar\external;
use core\external\exporter;
use core_date;
use DateTimeImmutable;
use renderer_base;
use moodle_url;
use core_calendar\local\event\container;
/**
* Class for displaying the day view.
*
* @package core_calendar
* @copyright 2017 Simey Lameze <simey@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class calendar_day_exporter extends exporter {
/**
* @var \calendar_information $calendar The calendar to be rendered.
*/
protected $calendar;
/**
* @var moodle_url $url The URL for the day view page.
*/
protected $url;
/**
* Constructor for day exporter.
*
* @param \calendar_information $calendar The calendar being represented.
* @param array $related The related information
*/
public function __construct(\calendar_information $calendar, $related) {
$this->calendar = $calendar;
parent::__construct([], $related);
}
/**
* Return the list of additional properties.
*
* @return array
*/
protected static function define_other_properties() {
return [
'events' => [
'type' => calendar_event_exporter::read_properties_definition(),
'multiple' => true,
],
'defaulteventcontext' => [
'type' => PARAM_INT,
'default' => 0,
],
'filter_selector' => [
'type' => PARAM_RAW,
],
'courseid' => [
'type' => PARAM_INT,
],
'categoryid' => [
'type' => PARAM_INT,
'optional' => true,
'default' => 0,
],
'neweventtimestamp' => [
'type' => PARAM_INT,
],
'date' => [
'type' => date_exporter::read_properties_definition(),
],
'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' => date_exporter::read_properties_definition(),
],
'previousperiodlink' => [
'type' => PARAM_URL,
],
'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' => date_exporter::read_properties_definition(),
],
'nextperiodname' => [
// Note: We must use RAW here because the calendar type returns the formatted month name based on a
// calendar format.
'type' => PARAM_RAW,
],
'nextperiodlink' => [
'type' => PARAM_URL,
],
'larrow' => [
// The left arrow defined by the theme.
'type' => PARAM_RAW,
],
'rarrow' => [
// The right arrow defined by the theme.
'type' => PARAM_RAW,
],
];
}
/**
* 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->calendar->time;
$cache = $this->related['cache'];
$url = new moodle_url('/calendar/view.php', [
'view' => 'day',
'time' => $timestamp,
]);
if ($this->calendar->course && SITEID !== $this->calendar->course->id) {
$url->param('course', $this->calendar->course->id);
} else if ($this->calendar->categoryid) {
$url->param('category', $this->calendar->categoryid);
}
$this->url = $url;
$return['events'] = array_map(function($event) use ($cache, $output, $url) {
$context = $cache->get_context($event);
$course = $cache->get_course($event);
$moduleinstance = $cache->get_module_instance($event);
$exporter = new calendar_event_exporter($event, [
'context' => $context,
'course' => $course,
'moduleinstance' => $moduleinstance,
'daylink' => $url,
'type' => $this->related['type'],
'today' => $this->calendar->time,
]);
$data = $exporter->export($output);
// We need to override default formatted time because it differs from day view.
// Formatted time for day view adds a link to the day view.
$legacyevent = container::get_event_mapper()->from_event_to_legacy_event($event);
$data->formattedtime = calendar_format_event_time($legacyevent, time(), null);
return $data;
}, $this->related['events']);
if ($context = $this->get_default_add_context()) {
$return['defaulteventcontext'] = $context->id;
}
if ($this->calendar->categoryid) {
$return['categoryid'] = $this->calendar->categoryid;
}
$return['filter_selector'] = $this->get_course_filter_selector($output);
$return['courseid'] = $this->calendar->courseid;
$previousperiod = $this->get_previous_day_data();
$nextperiod = $this->get_next_day_data();
$date = $this->related['type']->timestamp_to_date_array($this->calendar->time);
$nextperiodlink = new moodle_url($this->url);
$nextperiodlink->param('time', $nextperiod[0]);
$previousperiodlink = new moodle_url($this->url);
$previousperiodlink->param('time', $previousperiod[0]);
$days = calendar_get_days();
$return['date'] = (new date_exporter($date))->export($output);
$return['periodname'] = userdate($this->calendar->time, get_string('strftimedaydate'));
$return['previousperiod'] = (new date_exporter($previousperiod))->export($output);
$return['previousperiodname'] = $days[$previousperiod['wday']]['fullname'];
$return['previousperiodlink'] = $previousperiodlink->out(false);
$return['nextperiod'] = (new date_exporter($nextperiod))->export($output);
$return['nextperiodname'] = $days[$nextperiod['wday']]['fullname'];
$return['nextperiodlink'] = $nextperiodlink->out(false);
$return['larrow'] = $output->larrow();
$return['rarrow'] = $output->rarrow();
// Need to account for user's timezone.
$usernow = usergetdate(time());
$today = new DateTimeImmutable(
timezone: core_date::get_user_timezone_object(),
);
// The start time should use the day's date but the current
// time of the day (adjusted for user's timezone).
$neweventtimestamp = $today->setTimestamp($date[0])->setTime(
$usernow['hours'],
$usernow['minutes'],
$usernow['seconds']
);
$return['neweventtimestamp'] = $neweventtimestamp->getTimestamp();
return $return;
}
/**
* Get the default context for use when adding a new event.
*
* @return null|\context
*/
protected function get_default_add_context() {
if (calendar_user_can_add_event($this->calendar->course)) {
return \context_course::instance($this->calendar->course->id);
}
return null;
}
/**
* Get the course filter selector.
*
* @param renderer_base $output
* @return string The html code for the course filter selector.
*/
protected function get_course_filter_selector(renderer_base $output) {
return $output->course_filter_selector($this->url, '', $this->calendar->course->id);
}
/**
* 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 previous day timestamp.
*
* @return int The previous day timestamp.
*/
protected function get_previous_day_data() {
$type = $this->related['type'];
$time = $type->get_prev_day($this->calendar->time);
return $type->timestamp_to_date_array($time);
}
/**
* Get the next day timestamp.
*
* @return int The next day timestamp.
*/
protected function get_next_day_data() {
$type = $this->related['type'];
$time = $type->get_next_day($this->calendar->time);
return $type->timestamp_to_date_array($time);
}
}
+405
View File
@@ -0,0 +1,405 @@
<?php
// 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/>.
/**
* Contains event class for displaying a calendar event.
*
* @package core_calendar
* @copyright 2017 Ryan Wyllie <ryan@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_calendar\external;
defined('MOODLE_INTERNAL') || die();
use \core_calendar\local\event\container;
use \renderer_base;
require_once($CFG->dirroot . '/course/lib.php');
/**
* Class for displaying a calendar event.
*
* @package core_calendar
* @copyright 2017 Ryan Wyllie <ryan@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class calendar_event_exporter extends event_exporter_base {
/**
* Return the list of additional properties.
*
* @return array
*/
protected static function define_other_properties() {
$values = parent::define_other_properties();
$values['url'] = ['type' => PARAM_URL];
$values['islastday'] = [
'type' => PARAM_BOOL,
'default' => false,
];
$values['popupname'] = [
'type' => PARAM_RAW,
];
$values['mindaytimestamp'] = [
'type' => PARAM_INT,
'optional' => true
];
$values['mindayerror'] = [
'type' => PARAM_TEXT,
'optional' => true
];
$values['maxdaytimestamp'] = [
'type' => PARAM_INT,
'optional' => true
];
$values['maxdayerror'] = [
'type' => PARAM_TEXT,
'optional' => true
];
$values['draggable'] = [
'type' => PARAM_BOOL,
'default' => false
];
return $values;
}
/**
* 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) {
global $CFG;
$values = parent::get_other_values($output);
$event = $this->event;
$course = $this->related['course'];
$hascourse = !empty($course);
// By default all events that can be edited are
// draggable.
$values['draggable'] = $values['canedit'];
if ($moduleproxy = $event->get_course_module()) {
$modulename = $moduleproxy->get('modname');
$moduleid = $moduleproxy->get('id');
$url = new \moodle_url(sprintf('/mod/%s/view.php', $modulename), ['id' => $moduleid]);
// Build edit event url for action events.
$params = array('update' => $moduleid, 'return' => true, 'sesskey' => sesskey());
$editurl = new \moodle_url('/course/mod.php', $params);
$values['editurl'] = $editurl->out(false);
} else if ($event->get_type() == 'category') {
$url = $event->get_category()->get_proxied_instance()->get_view_link();
} else {
$url = course_get_url($hascourse ? $course : SITEID);
}
$values['url'] = $url->out(false);
$values['islastday'] = false;
$today = $this->related['type']->timestamp_to_date_array($this->related['today']);
if ($hascourse) {
$values['popupname'] = \core_external\util::format_string(
$this->event->get_name(),
\context_course::instance($course->id),
true
);
} else {
$values['popupname'] = \core_external\util::format_string($this->event->get_name(), \context_system::instance(), true);
}
$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 category name into the event name, if applicable.
$proxy = $this->event->get_category();
if ($proxy && $proxy->get('id')) {
$category = $proxy->get_proxied_instance();
$eventnameparams = (object) [
'name' => $values['popupname'],
'category' => $category->get_formatted_name(),
];
$values['popupname'] = get_string('eventnameandcategory', 'calendar', $eventnameparams);
}
// Include course's shortname into the event name, if applicable.
if ($hascourse && $course->id !== SITEID) {
$eventnameparams = (object) [
'name' => $values['popupname'],
'course' => $values['course']->shortname,
];
$values['popupname'] = get_string('eventnameandcourse', 'calendar', $eventnameparams);
}
if ($event->get_course_module()) {
$values = array_merge($values, $this->get_module_timestamp_limits($event));
} else if ($hascourse && $course->id != SITEID && empty($event->get_group())) {
// This is a course event.
$values = array_merge($values, $this->get_course_timestamp_limits($event));
}
return $values;
}
/**
* Returns a list of objects that are related.
*
* @return array
*/
protected static function define_related() {
$related = parent::define_related();
$related['daylink'] = \moodle_url::class;
$related['type'] = '\core_calendar\type_base';
$related['today'] = 'int';
$related['moduleinstance'] = 'stdClass?';
return $related;
}
/**
* Return the normalised event type.
* Activity events are normalised to be course events.
*
* @return string
*/
public function get_calendar_event_type() {
if ($this->event->get_course_module()) {
return 'course';
}
return $this->event->get_type();
}
/**
* Return the set of minimum and maximum date timestamp values
* for the given event.
*
* @param \core_calendar\local\event\entities\event_interface $event
* @return array
*/
protected function get_course_timestamp_limits($event) {
$values = [];
$mapper = container::get_event_mapper();
$starttime = $event->get_times()->get_start_time();
list($min, $max) = component_callback(
'core_course',
'core_calendar_get_valid_event_timestart_range',
[$mapper->from_event_to_legacy_event($event), $event->get_course()->get_proxied_instance()],
[false, false]
);
// The callback will return false for either of the
// min or max cutoffs to indicate that there are no
// valid timestart values. In which case the event is
// not draggable.
if ($min === false || $max === false) {
return ['draggable' => false];
}
if ($min) {
$values = array_merge($values, $this->get_timestamp_min_limit($starttime, $min));
}
if ($max) {
$values = array_merge($values, $this->get_timestamp_max_limit($starttime, $max));
}
return $values;
}
/**
* Return the set of minimum and maximum date timestamp values
* for the given event.
*
* @param \core_calendar\local\event\entities\event_interface $event
* @return array
*/
protected function get_module_timestamp_limits($event) {
$values = [];
$mapper = container::get_event_mapper();
$starttime = $event->get_times()->get_start_time();
$modname = $event->get_course_module()->get('modname');
$moduleinstance = $this->related['moduleinstance'];
list($min, $max) = component_callback(
'mod_' . $modname,
'core_calendar_get_valid_event_timestart_range',
[$mapper->from_event_to_legacy_event($event), $moduleinstance],
[false, false]
);
// The callback will return false for either of the
// min or max cutoffs to indicate that there are no
// valid timestart values. In which case the event is
// not draggable.
if ($min === false || $max === false) {
return ['draggable' => false];
}
if ($min) {
$values = array_merge($values, $this->get_timestamp_min_limit($starttime, $min));
}
if ($max) {
$values = array_merge($values, $this->get_timestamp_max_limit($starttime, $max));
}
return $values;
}
/**
* Get the correct minimum midnight day limit based on the event start time
* and the minimum timestamp limit of what the event belongs to.
*
* @param DateTimeInterface $starttime The event start time
* @param array $min The module's minimum limit for the event
* @return array Returns an array with mindaytimestamp and mindayerror keys.
*/
protected function get_timestamp_min_limit(\DateTimeInterface $starttime, $min) {
// We need to check that the minimum valid time is earlier in the
// day than the current event time so that if the user drags and drops
// the event to this day (which changes the date but not the time) it
// will result in a valid time start for the event.
//
// For example:
// An event that starts on 2017-01-10 08:00 with a minimum cutoff
// of 2017-01-05 09:00 means that 2017-01-05 is not a valid start day
// for the drag and drop because it would result in the event start time
// being set to 2017-01-05 08:00, which is invalid. Instead the minimum
// valid start day would be 2017-01-06.
$values = [];
$timestamp = $min[0];
$errorstring = $min[1];
$mindate = (new \DateTimeImmutable())->setTimestamp($timestamp);
$minstart = $mindate->setTime(
$starttime->format('H'),
$starttime->format('i'),
$starttime->format('s')
);
$midnight = usergetmidnight($timestamp);
if ($mindate <= $minstart) {
$values['mindaytimestamp'] = $midnight;
} else {
$tomorrow = (new \DateTime())->setTimestamp($midnight)->modify('+1 day');
$values['mindaytimestamp'] = $tomorrow->getTimestamp();
}
// Get the human readable error message to display if the min day
// timestamp is violated.
$values['mindayerror'] = $errorstring;
return $values;
}
/**
* Get the correct maximum midnight day limit based on the event start time
* and the maximum timestamp limit of what the event belongs to.
*
* @param DateTimeInterface $starttime The event start time
* @param array $max The module's maximum limit for the event
* @return array Returns an array with maxdaytimestamp and maxdayerror keys.
*/
protected function get_timestamp_max_limit(\DateTimeInterface $starttime, $max) {
// We're doing a similar calculation here as we are for the minimum
// day timestamp. See the explanation above.
$values = [];
$timestamp = $max[0];
$errorstring = $max[1];
$maxdate = (new \DateTimeImmutable())->setTimestamp($timestamp);
$maxstart = $maxdate->setTime(
$starttime->format('H'),
$starttime->format('i'),
$starttime->format('s')
);
$midnight = usergetmidnight($timestamp);
if ($maxdate >= $maxstart) {
$values['maxdaytimestamp'] = $midnight;
} else {
$yesterday = (new \DateTime())->setTimestamp($midnight)->modify('-1 day');
$values['maxdaytimestamp'] = $yesterday->getTimestamp();
}
// Get the human readable error message to display if the max day
// timestamp is violated.
$values['maxdayerror'] = $errorstring;
return $values;
}
/**
* Get the correct minimum midnight day limit based on the event start time
* and the module's minimum timestamp limit.
*
* @deprecated since Moodle 3.6. Please use get_timestamp_min_limit().
* @todo final deprecation. To be removed in Moodle 3.10
* @param \DateTimeInterface $starttime The event start time
* @param array $min The module's minimum limit for the event
* @return array Returns an array with mindaytimestamp and mindayerror keys.
*/
protected function get_module_timestamp_min_limit(\DateTimeInterface $starttime, $min) {
debugging('get_module_timestamp_min_limit() has been deprecated. Please call get_timestamp_min_limit() instead.',
DEBUG_DEVELOPER);
return $this->get_timestamp_min_limit($starttime, $min);
}
/**
* Get the correct maximum midnight day limit based on the event start time
* and the module's maximum timestamp limit.
*
* @deprecated since Moodle 3.6. Please use get_timestamp_max_limit().
* @todo final deprecation. To be removed in Moodle 3.10
* @param \DateTimeInterface $starttime The event start time
* @param array $max The module's maximum limit for the event
* @return array Returns an array with maxdaytimestamp and maxdayerror keys.
*/
protected function get_module_timestamp_max_limit(\DateTimeInterface $starttime, $max) {
debugging('get_module_timestamp_max_limit() has been deprecated. Please call get_timestamp_max_limit() instead.',
DEBUG_DEVELOPER);
return $this->get_timestamp_max_limit($starttime, $max);
}
}
+188
View File
@@ -0,0 +1,188 @@
<?php
// 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/>.
/**
* Contains event class for displaying the upcoming view.
*
* @package core_calendar
* @copyright 2017 Simey Lameze <simey@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_calendar\external;
defined('MOODLE_INTERNAL') || die();
use core\external\exporter;
use renderer_base;
use moodle_url;
use \core_calendar\local\event\container;
/**
* Class for displaying the day view.
*
* @package core_calendar
* @copyright 2017 Simey Lameze <simey@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class calendar_upcoming_exporter extends exporter {
/**
* @var \calendar_information $calendar The calendar to be rendered.
*/
protected $calendar;
/**
* @var moodle_url $url The URL for the upcoming view page.
*/
protected $url;
/**
* Constructor for upcoming exporter.
*
* @param \calendar_information $calendar The calendar being represented.
* @param array $related The related information
*/
public function __construct(\calendar_information $calendar, $related) {
$this->calendar = $calendar;
parent::__construct([], $related);
}
/**
* Return the list of additional properties.
*
* @return array
*/
protected static function define_other_properties() {
return [
'events' => [
'type' => calendar_event_exporter::read_properties_definition(),
'multiple' => true,
],
'defaulteventcontext' => [
'type' => PARAM_INT,
'default' => 0,
],
'filter_selector' => [
'type' => PARAM_RAW,
],
'courseid' => [
'type' => PARAM_INT,
],
'categoryid' => [
'type' => PARAM_INT,
'optional' => true,
'default' => 0,
],
'isloggedin' => [
'type' => PARAM_BOOL,
],
'date' => [
'type' => date_exporter::read_properties_definition(),
],
];
}
/**
* 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->calendar->time;
$cache = $this->related['cache'];
$url = new moodle_url('/calendar/view.php', [
'view' => 'upcoming',
'time' => $timestamp,
'course' => $this->calendar->course->id,
]);
$this->url = $url;
$return['isloggedin'] = isloggedin();
$return['events'] = array_map(function($event) use ($cache, $output, $url) {
$context = $cache->get_context($event);
$course = $cache->get_course($event);
$moduleinstance = $cache->get_module_instance($event);
$exporter = new calendar_event_exporter($event, [
'context' => $context,
'course' => $course,
'moduleinstance' => $moduleinstance,
'daylink' => $url,
'type' => $this->related['type'],
'today' => $this->calendar->time,
]);
$data = $exporter->export($output);
// We need to override default formatted time because it differs from day view.
// Formatted time for upcoming view adds a link to the day view.
$legacyevent = container::get_event_mapper()->from_event_to_legacy_event($event);
$data->formattedtime = calendar_format_event_time($legacyevent, time(), null);
return $data;
}, $this->related['events']);
if ($context = $this->get_default_add_context()) {
$return['defaulteventcontext'] = $context->id;
}
$return['filter_selector'] = $this->get_course_filter_selector($output);
$return['courseid'] = $this->calendar->courseid;
$date = $this->related['type']->timestamp_to_date_array($this->calendar->time);
$return['date'] = (new date_exporter($date))->export($output);
if ($this->calendar->categoryid) {
$return['categoryid'] = $this->calendar->categoryid;
}
return $return;
}
/**
* Get the default context for use when adding a new event.
*
* @return null|\context
*/
protected function get_default_add_context() {
if (calendar_user_can_add_event($this->calendar->course)) {
return \context_course::instance($this->calendar->course->id);
}
return null;
}
/**
* Get the course filter selector.
*
* @param renderer_base $output
* @return string The html code for the course filter selector.
*/
protected function get_course_filter_selector(renderer_base $output) {
return $output->course_filter_selector($this->url, '', $this->calendar->course->id);
}
/**
* 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',
];
}
}
+90
View File
@@ -0,0 +1,90 @@
<?php
// 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/>.
/**
* Class for normalising the date data.
*
* @package core_calendar
* @copyright 2017 Andrew Nicols <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_calendar\external;
defined('MOODLE_INTERNAL') || die();
use core\external\exporter;
/**
* Class for normalising the date data.
*
* @package core_calendar
* @copyright 2017 Andrew Nicols <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class date_exporter extends exporter {
/**
* Constructor for date_exporter.
*
* @param array $data
* @param array $related The related information
*/
public function __construct($data, $related = []) {
$data['timestamp'] = $data[0];
unset($data[0]);
parent::__construct($data, $related);
}
protected static function define_properties() {
return [
'seconds' => [
'type' => PARAM_INT,
],
'minutes' => [
'type' => PARAM_INT,
],
'hours' => [
'type' => PARAM_INT,
],
'mday' => [
'type' => PARAM_INT,
],
'wday' => [
'type' => PARAM_INT,
],
'mon' => [
'type' => PARAM_INT,
],
'year' => [
'type' => PARAM_INT,
],
'yday' => [
'type' => PARAM_INT,
],
'weekday' => [
'type' => PARAM_RAW,
],
'month' => [
'type' => PARAM_RAW,
],
'timestamp' => [
'type' => PARAM_INT,
],
];
}
}
+277
View File
@@ -0,0 +1,277 @@
<?php
// 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/>.
namespace core_calendar\external;
defined('MOODLE_INTERNAL') || die();
require_once($CFG->dirroot . '/calendar/lib.php');
use core\external\exporter;
use core_date;
use DateTimeImmutable;
use renderer_base;
use moodle_url;
/**
* Class for displaying the day view.
*
* @package core_calendar
* @copyright 2017 Andrew Nicols <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class day_exporter extends exporter {
/**
* @var \calendar_information $calendar The calendar being displayed.
*/
protected $calendar;
/**
* @var moodle_url
*/
protected $url;
/**
* 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;
$url = new moodle_url('/calendar/view.php', [
'view' => 'day',
'time' => $calendar->time,
]);
if ($this->calendar->course && SITEID !== $this->calendar->course->id) {
$url->param('course', $this->calendar->course->id);
} else if ($this->calendar->categoryid) {
$url->param('category', $this->calendar->categoryid);
}
$this->url = $url;
parent::__construct($data, $related);
}
/**
* Return the list of properties.
*
* @return array
*/
protected static function define_properties() {
// These are the default properties as returned by getuserdate()
// but without the formatted month and week names.
return [
'seconds' => [
'type' => PARAM_INT,
],
'minutes' => [
'type' => PARAM_INT,
],
'hours' => [
'type' => PARAM_INT,
],
'mday' => [
'type' => PARAM_INT,
],
'wday' => [
'type' => PARAM_INT,
],
'year' => [
'type' => PARAM_INT,
],
'yday' => [
'type' => PARAM_INT,
],
];
}
/**
* Return the list of additional properties.
*
* @return array
*/
protected static function define_other_properties() {
return [
'timestamp' => [
'type' => PARAM_INT,
],
'neweventtimestamp' => [
'type' => PARAM_INT,
],
'viewdaylink' => [
'type' => PARAM_URL,
'optional' => true,
],
'viewdaylinktitle' => [
'type' => PARAM_RAW,
'optional' => true,
],
'events' => [
'type' => calendar_event_exporter::read_properties_definition(),
'multiple' => true,
],
'hasevents' => [
'type' => PARAM_BOOL,
'default' => false,
],
'calendareventtypes' => [
'type' => PARAM_RAW,
'multiple' => true,
],
'previousperiod' => [
'type' => PARAM_INT,
],
'nextperiod' => [
'type' => PARAM_INT,
],
'haslastdayofevent' => [
'type' => PARAM_BOOL,
'default' => false,
],
];
}
/**
* 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) {
$daytimestamp = $this->calendar->time;
$timestamp = $this->data[0];
// Need to account for user's timezone.
$usernow = usergetdate(time());
$today = new DateTimeImmutable(
timezone: core_date::get_user_timezone_object(),
);
// 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(),
'previousperiod' => $this->get_previous_day_timestamp($daytimestamp),
'nextperiod' => $this->get_next_day_timestamp($daytimestamp),
'viewdaylink' => $this->url->out(false),
];
if ($viewdaylinktitle = $this->get_view_link_title()) {
$return['viewdaylinktitle'] = $viewdaylinktitle;
}
$cache = $this->related['cache'];
$eventexporters = array_map(function($event) use ($cache, $output) {
$context = $cache->get_context($event);
$course = $cache->get_course($event);
$moduleinstance = $cache->get_module_instance($event);
$exporter = new calendar_event_exporter($event, [
'context' => $context,
'course' => $course,
'moduleinstance' => $moduleinstance,
'daylink' => $this->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);
$return['hasevents'] = !empty($return['events']);
$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 previous day timestamp.
*
* @param int $daytimestamp The current day timestamp.
* @return int The previous day timestamp.
*/
protected function get_previous_day_timestamp($daytimestamp) {
return $this->related['type']->get_prev_day($daytimestamp);
}
/**
* 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 title for view link.
*
* @return string
*/
protected function get_view_link_title() {
$title = null;
$userdate = userdate($this->data[0], get_string('strftimedayshort'));
if ($this->data['istoday']) {
$title = get_string('todayplustitle', 'calendar', $userdate);
} else if (count($this->related['events'])) {
$title = get_string('eventsfor', 'calendar', $userdate);
}
return $title;
}
}
+87
View File
@@ -0,0 +1,87 @@
<?php
// 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/>.
/**
* Contains event class for displaying the day name.
*
* @package core_calendar
* @copyright 2017 Andrew Nicols <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_calendar\external;
defined('MOODLE_INTERNAL') || die();
use core\external\exporter;
/**
* Class for displaying the day view.
*
* @package core_calendar
* @copyright 2017 Andrew Nicols <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class day_name_exporter extends exporter {
/**
* @var int $dayno The day number.
*/
protected $dayno;
/**
* @var string $shortname The formatted short name of the day.
*/
protected $shortname;
/**
* @var string $fullname The formatted full name of the day.
*/
protected $fullname;
/**
* Constructor.
*
* @param int $dayno The day number.
* @param array $names The list of names.
*/
public function __construct($dayno, $names) {
$data = $names + ['dayno' => $dayno];
parent::__construct($data, []);
}
/**
* Return the list of properties.
*
* @return array
*/
protected static function define_properties() {
return [
'dayno' => [
'type' => PARAM_INT,
],
'shortname' => [
// Note: The calendar type class has already formatted the names.
'type' => PARAM_RAW,
],
'fullname' => [
// Note: The calendar type class has already formatted the names.
'type' => PARAM_RAW,
],
];
}
}
+129
View File
@@ -0,0 +1,129 @@
<?php
// 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/>.
/**
* Contains event class for displaying a calendar event's action.
*
* @package core_calendar
* @copyright 2017 Ryan Wyllie <ryan@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_calendar\external;
defined('MOODLE_INTERNAL') || die();
use core\external\exporter;
use core_calendar\local\event\entities\action_interface;
use core_calendar\local\event\container;
use renderer_base;
/**
* Class for displaying a calendar event's action.
*
* @package core_calendar
* @copyright 2017 Ryan Wyllie <ryan@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class event_action_exporter extends exporter {
/**
* Constructor.
*
* @param action_interface $action The action object.
* @param array $related Related data.
*/
public function __construct(action_interface $action, $related = []) {
$data = new \stdClass();
$data->name = $action->get_name();
$data->url = $action->get_url()->out(false);
$data->itemcount = $action->get_item_count();
$data->actionable = $action->is_actionable();
parent::__construct($data, $related);
}
/**
* Return the list of properties.
*
* @return array
*/
protected static function define_properties() {
return [
'name' => ['type' => PARAM_TEXT],
'url' => ['type' => PARAM_URL],
'itemcount' => ['type' => PARAM_INT],
'actionable' => ['type' => PARAM_BOOL]
];
}
/**
* Return the list of additional properties.
*
* @return array
*/
protected static function define_other_properties() {
return [
'showitemcount' => ['type' => PARAM_BOOL, 'default' => false]
];
}
/**
* 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) {
$event = $this->related['event'];
if (!$event->get_component()) {
return ['showitemcount' => false];
}
$showitemcountcallback = 'core_calendar_event_action_shows_item_count';
$mapper = container::get_event_mapper();
$calevent = $mapper->from_event_to_legacy_event($event);
$params = [$calevent, $this->data->itemcount];
$showitemcount = component_callback($event->get_component(), $showitemcountcallback, $params, false);
// Prepare other values data.
$data = [
'showitemcount' => $showitemcount
];
return $data;
}
/**
* Returns a list of objects that are related.
*
* @return array
*/
protected static function define_related() {
return [
'context' => 'context',
'event' => '\\core_calendar\\local\\event\\entities\\event_interface'
];
}
/**
* Magic method returning parameters for formatting 'name' property
*
* @return bool[]
*/
protected function get_format_parameters_for_name() {
return ['escape' => false];
}
}
+93
View File
@@ -0,0 +1,93 @@
<?php
// 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/>.
/**
* Contains event class for displaying a calendar event.
*
* @package core_calendar
* @copyright 2017 Ryan Wyllie <ryan@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_calendar\external;
defined('MOODLE_INTERNAL') || die();
require_once($CFG->dirroot . "/calendar/lib.php");
use \core_calendar\local\event\container;
use \renderer_base;
/**
* Class for displaying a calendar event.
*
* @package core_calendar
* @copyright 2017 Ryan Wyllie <ryan@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class event_exporter extends event_exporter_base {
/**
* Return the list of additional properties.
*
* @return array
*/
protected static function define_other_properties() {
$values = parent::define_other_properties();
$values['url'] = ['type' => PARAM_URL];
return $values;
}
/**
* 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) {
$values = parent::get_other_values($output);
global $CFG;
require_once($CFG->dirroot.'/course/lib.php');
$event = $this->event;
$context = $this->related['context'];
if ($moduleproxy = $event->get_course_module()) {
$modulename = $moduleproxy->get('modname');
$moduleid = $moduleproxy->get('id');
$url = new \moodle_url(sprintf('/mod/%s/view.php', $modulename), ['id' => $moduleid]);
// Build edit event url for action events.
$params = array('update' => $moduleid, 'return' => true, 'sesskey' => sesskey());
$editurl = new \moodle_url('/course/mod.php', $params);
$values['editurl'] = $editurl->out(false);
} else if ($event->get_type() == 'category') {
$url = $event->get_category()->get_proxied_instance()->get_view_link();
} else if ($event->get_type() == 'course') {
$url = \course_get_url($this->related['course'] ?: SITEID);
} else {
$url = \course_get_url($this->related['course'] ?: SITEID);
}
$values['url'] = $url->out(false);
// Override default formatted time to make sure the date portion of the time is always rendered.
$legacyevent = container::get_event_mapper()->from_event_to_legacy_event($event);
$values['formattedtime'] = calendar_format_event_time($legacyevent, time(), null, false);
return $values;
}
}
+415
View File
@@ -0,0 +1,415 @@
<?php
// 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/>.
/**
* Contains event class for displaying a calendar event.
*
* @package core_calendar
* @copyright 2017 Ryan Wyllie <ryan@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_calendar\external;
defined('MOODLE_INTERNAL') || die();
require_once($CFG->dirroot . "/calendar/lib.php");
require_once($CFG->libdir . "/filelib.php");
use \core\external\exporter;
use \core_calendar\local\event\container;
use \core_calendar\local\event\entities\event_interface;
use \core_calendar\local\event\entities\action_event_interface;
use \core_course\external\course_summary_exporter;
use \core\external\coursecat_summary_exporter;
use \renderer_base;
use moodle_url;
/**
* Class for displaying a calendar event.
*
* @package core_calendar
* @copyright 2017 Ryan Wyllie <ryan@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class event_exporter_base extends exporter {
/**
* @var event_interface $event
*/
protected $event;
/**
* Constructor.
*
* @param event_interface $event
* @param array $related The related data.
*/
public function __construct(event_interface $event, $related = []) {
$this->event = $event;
$starttimestamp = $event->get_times()->get_start_time()->getTimestamp();
$endtimestamp = $event->get_times()->get_end_time()->getTimestamp();
$groupid = $event->get_group() ? $event->get_group()->get('id') : null;
$userid = $event->get_user() ? $event->get_user()->get('id') : null;
$categoryid = $event->get_category() ? $event->get_category()->get('id') : null;
$data = new \stdClass();
$data->id = $event->get_id();
$data->name = $event->get_name();
$data->description = file_rewrite_pluginfile_urls(
$event->get_description()->get_value(),
'pluginfile.php',
$related['context']->id,
'calendar',
'event_description',
$event->get_id()
);
$data->descriptionformat = $event->get_description()->get_format();
$data->location = \core_external\util::format_text($event->get_location(), FORMAT_PLAIN, $related['context']->id)[0];
$data->groupid = $groupid;
$data->userid = $userid;
$data->categoryid = $categoryid;
$data->eventtype = $event->get_type();
$data->timestart = $starttimestamp;
$data->timeduration = $endtimestamp - $starttimestamp;
$data->timesort = $event->get_times()->get_sort_time()->getTimestamp();
$data->timeusermidnight = $event->get_times()->get_usermidnight_time()->getTimestamp();
$data->visible = $event->is_visible() ? 1 : 0;
$data->timemodified = $event->get_times()->get_modified_time()->getTimestamp();
$data->component = $event->get_component();
$data->overdue = $data->timesort < time();
if ($repeats = $event->get_repeats()) {
$data->repeatid = $repeats->get_id();
$data->eventcount = $repeats->get_num() + 1;
}
if ($cm = $event->get_course_module()) {
$data->modulename = $cm->get('modname');
$data->instance = $cm->get('id');
$data->activityname = $cm->get('name');
$component = 'mod_' . $data->modulename;
if (!component_callback_exists($component, 'core_calendar_get_event_action_string')) {
$modulename = get_string('modulename', $data->modulename);
$data->activitystr = get_string('requiresaction', 'calendar', $modulename);
} else {
$data->activitystr = component_callback(
$component,
'core_calendar_get_event_action_string',
[$event->get_type()]
);
}
}
parent::__construct($data, $related);
}
/**
* Return the list of properties.
*
* @return array
*/
protected static function define_properties() {
return [
'id' => ['type' => PARAM_INT],
'name' => ['type' => PARAM_TEXT],
'description' => [
'type' => PARAM_RAW,
'optional' => true,
'default' => null,
'null' => NULL_ALLOWED
],
'descriptionformat' => [
'type' => PARAM_INT,
'optional' => true,
'default' => null,
'null' => NULL_ALLOWED
],
'location' => [
'type' => PARAM_RAW,
'optional' => true,
'default' => null,
'null' => NULL_ALLOWED
],
'categoryid' => [
'type' => PARAM_INT,
'optional' => true,
'default' => null,
'null' => NULL_ALLOWED
],
'groupid' => [
'type' => PARAM_INT,
'optional' => true,
'default' => null,
'null' => NULL_ALLOWED
],
'userid' => [
'type' => PARAM_INT,
'optional' => true,
'default' => null,
'null' => NULL_ALLOWED
],
'repeatid' => [
'type' => PARAM_INT,
'optional' => true,
'default' => null,
'null' => NULL_ALLOWED
],
'eventcount' => [
'type' => PARAM_INT,
'optional' => true,
'default' => null,
'null' => NULL_ALLOWED
],
'component' => [
'type' => PARAM_COMPONENT,
'optional' => true,
'default' => null,
'null' => NULL_ALLOWED
],
'modulename' => [
'type' => PARAM_TEXT,
'optional' => true,
'default' => null,
'null' => NULL_ALLOWED
],
'activityname' => [
'type' => PARAM_TEXT,
'optional' => true,
'default' => null,
'null' => NULL_ALLOWED
],
'activitystr' => [
'type' => PARAM_TEXT,
'optional' => true,
'default' => null,
'null' => NULL_ALLOWED
],
'instance' => [
'type' => PARAM_INT,
'optional' => true,
'default' => null,
'null' => NULL_ALLOWED
],
'eventtype' => ['type' => PARAM_TEXT],
'timestart' => ['type' => PARAM_INT],
'timeduration' => ['type' => PARAM_INT],
'timesort' => ['type' => PARAM_INT],
'timeusermidnight' => ['type' => PARAM_INT],
'visible' => ['type' => PARAM_INT],
'timemodified' => ['type' => PARAM_INT],
'overdue' => [
'type' => PARAM_BOOL,
'optional' => true,
'default' => false,
'null' => NULL_ALLOWED
],
];
}
/**
* Return the list of additional properties.
*
* @return array
*/
protected static function define_other_properties() {
return [
'icon' => [
'type' => event_icon_exporter::read_properties_definition(),
],
'category' => [
'type' => coursecat_summary_exporter::read_properties_definition(),
'optional' => true,
],
'course' => [
'type' => course_summary_exporter::read_properties_definition(),
'optional' => true,
],
'subscription' => [
'type' => event_subscription_exporter::read_properties_definition(),
'optional' => true,
],
'canedit' => [
'type' => PARAM_BOOL
],
'candelete' => [
'type' => PARAM_BOOL
],
'deleteurl' => [
'type' => PARAM_URL
],
'editurl' => [
'type' => PARAM_URL
],
'viewurl' => [
'type' => PARAM_URL
],
'formattedtime' => [
'type' => PARAM_RAW,
],
'formattedlocation' => [
'type' => PARAM_RAW,
],
'isactionevent' => [
'type' => PARAM_BOOL
],
'iscourseevent' => [
'type' => PARAM_BOOL
],
'iscategoryevent' => [
'type' => PARAM_BOOL
],
'groupname' => [
'type' => PARAM_RAW,
'optional' => true,
'default' => null,
'null' => NULL_ALLOWED
],
'normalisedeventtype' => [
'type' => PARAM_TEXT
],
'normalisedeventtypetext' => [
'type' => PARAM_TEXT
],
'action' => [
'type' => event_action_exporter::read_properties_definition(),
'optional' => true,
],
'purpose' => [
'type' => PARAM_TEXT
],
'branded' => [
'type' => PARAM_BOOL,
'optional' => true,
],
];
}
/**
* 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) {
$values = [];
$event = $this->event;
$legacyevent = container::get_event_mapper()->from_event_to_legacy_event($event);
$context = $this->related['context'];
$course = $this->related['course'];
$values['isactionevent'] = false;
$values['iscourseevent'] = false;
$values['iscategoryevent'] = false;
$values['normalisedeventtype'] = $event->get_type();
if ($moduleproxy = $event->get_course_module()) {
// We need a separate property to flag if an event is action event.
// That's required because canedit return true but action action events cannot be edited on the calendar UI.
// But they are considered editable because you can drag and drop the event on the month view.
$values['isactionevent'] = true;
// Activity events are normalised to "look" like course events.
$values['normalisedeventtype'] = 'course';
} else if ($event->get_type() == 'course') {
$values['iscourseevent'] = true;
} else if ($event->get_type() == 'category') {
$values['iscategoryevent'] = true;
}
$timesort = $event->get_times()->get_sort_time()->getTimestamp();
$iconexporter = new event_icon_exporter($event, ['context' => $context]);
$identifier = 'type' . $values['normalisedeventtype'];
$stringexists = get_string_manager()->string_exists($identifier, 'calendar');
if (!$stringexists) {
// Property normalisedeventtype is used to build the name of the CSS class for the events.
$values['normalisedeventtype'] = 'other';
}
$values['normalisedeventtypetext'] = $stringexists ? get_string($identifier, 'calendar') : '';
$purpose = 'none';
$isbranded = false;
if ($moduleproxy) {
$purpose = plugin_supports('mod', $moduleproxy->get('modname'), FEATURE_MOD_PURPOSE, 'none');
$isbranded = component_callback('mod_' . $moduleproxy->get('modname'), 'is_branded') !== null ? : false;
}
$values['purpose'] = $purpose;
$values['branded'] = $isbranded;
$values['icon'] = $iconexporter->export($output);
$subscriptionexporter = new event_subscription_exporter($event);
$values['subscription'] = $subscriptionexporter->export($output);
$proxy = $this->event->get_category();
if ($proxy && $proxy->get('id')) {
$category = $proxy->get_proxied_instance();
$categorysummaryexporter = new coursecat_summary_exporter($category, ['context' => $context]);
$values['category'] = $categorysummaryexporter->export($output);
}
if ($course && $course->id != SITEID) {
$coursesummaryexporter = new course_summary_exporter($course, ['context' => $context]);
$values['course'] = $coursesummaryexporter->export($output);
}
$courseid = (!$course) ? SITEID : $course->id;
$values['canedit'] = calendar_edit_event_allowed($legacyevent, true);
$values['candelete'] = calendar_delete_event_allowed($legacyevent);
$deleteurl = new moodle_url('/calendar/delete.php', ['id' => $event->get_id(), 'course' => $courseid]);
$values['deleteurl'] = $deleteurl->out(false);
$editurl = new moodle_url('/calendar/event.php', ['action' => 'edit', 'id' => $event->get_id(),
'course' => $courseid]);
$values['editurl'] = $editurl->out(false);
$viewurl = new moodle_url('/calendar/view.php', ['view' => 'day', 'course' => $courseid,
'time' => $timesort]);
$viewurl->set_anchor('event_' . $event->get_id());
$values['viewurl'] = $viewurl->out(false);
$values['formattedtime'] = calendar_format_event_time($legacyevent, time(), null, false,
$timesort);
$values['formattedlocation'] = calendar_format_event_location($legacyevent);
if ($group = $event->get_group()) {
$values['groupname'] = format_string($group->get('name'), true,
['context' => \context_course::instance($event->get_course()->get('id'))]);
}
if ($event instanceof action_event_interface) {
// Export event action if applicable.
$actionrelated = [
'context' => $this->related['context'],
'event' => $event
];
$actionexporter = new event_action_exporter($event->get_action(), $actionrelated);
$values['action'] = $actionexporter->export($output);
}
return $values;
}
/**
* Returns a list of objects that are related.
*
* @return array
*/
protected static function define_related() {
return [
'context' => 'context',
'course' => 'stdClass?',
];
}
}
+157
View File
@@ -0,0 +1,157 @@
<?php
// 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/>.
/**
* Contains event class for displaying a calendar event's icon.
*
* @package core_calendar
* @copyright 2017 Ryan Wyllie <ryan@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_calendar\external;
defined('MOODLE_INTERNAL') || die();
use \core\external\exporter;
use \core_calendar\local\event\entities\event_interface;
/**
* Class for displaying a calendar event's icon.
*
* @package core_calendar
* @copyright 2017 Ryan Wyllie <ryan@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class event_icon_exporter extends exporter {
/**
* Constructor.
*
* @param event_interface $event
* @param array $related The related data.
*/
public function __construct(event_interface $event, $related = []) {
global $PAGE;
$coursemodule = $event->get_course_module();
$category = $event->get_category();
$categoryid = $category ? $category->get('id') : null;
$course = $event->get_course();
$courseid = $course ? $course->get('id') : null;
$group = $event->get_group();
$groupid = $group ? $group->get('id') : null;
$user = $event->get_user();
$userid = $user ? $user->get('id') : null;
$isactivityevent = !empty($coursemodule);
$issiteevent = ($course && $courseid == SITEID);
$iscategoryevent = ($category && !empty($categoryid));
$iscourseevent = ($course && !empty($courseid) && $courseid != SITEID && empty($groupid));
$isgroupevent = ($group && !empty($groupid));
$isuserevent = ($user && !empty($userid));
$iconurl = '';
$iconclass = '';
if ($isactivityevent) {
$key = 'monologo';
$component = $coursemodule->get('modname');
$iconurl = get_fast_modinfo($courseid)->get_cm($coursemodule->get('id'))->get_icon_url();
$iconclass = $iconurl->get_param('filtericon') ? '' : 'nofilter';
$iconurl = $iconurl->out(false);
if (get_string_manager()->string_exists($event->get_type(), $component)) {
$alttext = get_string($event->get_type(), $component);
} else {
$alttext = get_string('activityevent', 'calendar');
}
} else if ($event->get_component()) {
// Guess the icon and the title for the component event. By default display calendar icon and the
// plugin name as the alttext.
if ($PAGE->theme->resolve_image_location($event->get_type(), $event->get_component())) {
$key = $event->get_type();
$component = $event->get_component();
} else {
$key = 'i/otherevent';
$component = 'core';
}
if (get_string_manager()->string_exists($event->get_type(), $event->get_component())) {
$alttext = get_string($event->get_type(), $event->get_component());
} else {
$alttext = get_string('pluginname', $event->get_component());
}
} else if ($issiteevent) {
$key = 'i/siteevent';
$component = 'core';
$alttext = get_string('typesite', 'calendar');
} else if ($iscategoryevent) {
$key = 'i/categoryevent';
$component = 'core';
$alttext = get_string('typecategory', 'calendar');
} else if ($iscourseevent) {
$key = 'i/courseevent';
$component = 'core';
$alttext = get_string('typecourse', 'calendar');
} else if ($isgroupevent) {
$key = 'i/groupevent';
$component = 'core';
$alttext = get_string('typegroup', 'calendar');
} else if ($isuserevent) {
$key = 'i/userevent';
$component = 'core';
$alttext = get_string('typeuser', 'calendar');
} else {
// Default to site event icon?
$key = 'i/siteevent';
$component = 'core';
$alttext = get_string('typesite', 'calendar');
}
$data = new \stdClass();
$data->key = $key;
$data->component = $component;
$data->alttext = $alttext;
$data->iconurl = $iconurl;
$data->iconclass = $iconclass;
parent::__construct($data, $related);
}
/**
* Return the list of properties.
*
* @return array
*/
protected static function define_properties() {
return [
'key' => ['type' => PARAM_TEXT],
'component' => ['type' => PARAM_TEXT],
'alttext' => ['type' => PARAM_TEXT],
'iconurl' => ['type' => PARAM_TEXT],
'iconclass' => ['type' => PARAM_TEXT],
];
}
/**
* Returns a list of objects that are related.
*
* @return array
*/
protected static function define_related() {
return [
'context' => 'context',
];
}
}
@@ -0,0 +1,85 @@
<?php
// 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/>.
/**
* Contains event class for displaying a calendar event's subscription.
*
* @package core_calendar
* @copyright 2017 Simey Lameze <simey@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_calendar\external;
defined('MOODLE_INTERNAL') || die();
use \core\external\exporter;
use \core_calendar\local\event\entities\event_interface;
/**
* Class for displaying a calendar event's subscription.
*
* @package core_calendar
* @copyright 2017 Simey Lameze <simey@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class event_subscription_exporter extends exporter {
/**
* Constructor.
*
* @param event_interface $event
*/
public function __construct(event_interface $event) {
global $CFG;
$data = new \stdClass();
$data->displayeventsource = false;
if ($event->get_subscription()) {
$subscription = calendar_get_subscription($event->get_subscription()->get('id'));
if (!empty($subscription) && $CFG->calendar_showicalsource) {
$data->displayeventsource = true;
if (!empty($subscription->url)) {
$data->subscriptionurl = $subscription->url;
}
$data->subscriptionname = $subscription->name;
}
}
parent::__construct($data);
}
/**
* Return the list of properties.
*
* @return array
*/
protected static function define_properties() {
return [
'displayeventsource' => [
'type' => PARAM_BOOL
],
'subscriptionname' => [
'type' => PARAM_RAW,
'optional' => true
],
'subscriptionurl' => [
'type' => PARAM_URL,
'optional' => true
],
];
}
}
+121
View File
@@ -0,0 +1,121 @@
<?php
// 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/>.
/**
* Contains event class for displaying a list of calendar events.
*
* @package core_calendar
* @copyright 2017 Ryan Wyllie <ryan@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_calendar\external;
defined('MOODLE_INTERNAL') || die();
use \core\external\exporter;
use \renderer_base;
/**
* Class for displaying a list of calendar events.
*
* This class uses the events relateds cache in order to get the related
* data for exporting an event without having to naively hit the database
* for each event.
*
* @package core_calendar
* @copyright 2017 Ryan Wyllie <ryan@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class events_exporter extends exporter {
/**
* @var array $events An array of event_interface objects.
*/
protected $events;
/**
* Constructor.
*
* @param array $events An array of event_interface objects
* @param array $related An array of related objects
*/
public function __construct(array $events, $related = []) {
$this->events = $events;
parent::__construct([], $related);
}
/**
* Return the list of additional properties.
*
* @return array
*/
protected static function define_other_properties() {
return [
'events' => [
'type' => event_exporter::read_properties_definition(),
'multiple' => true,
],
'firstid' => [
'type' => PARAM_INT,
'null' => NULL_ALLOWED,
'default' => null,
],
'lastid' => [
'type' => PARAM_INT,
'null' => NULL_ALLOWED,
'default' => null,
],
];
}
/**
* 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) {
$return = [];
$cache = $this->related['cache'];
$return['events'] = array_map(function($event) use ($cache, $output) {
$context = $cache->get_context($event);
$course = $cache->get_course($event);
$exporter = new event_exporter($event, ['context' => $context, 'course' => $course]);
return $exporter->export($output);
}, $this->events);
if ($count = count($return['events'])) {
$return['firstid'] = $return['events'][0]->id;
$return['lastid'] = $return['events'][$count - 1]->id;
}
return $return;
}
/**
* Returns a list of objects that are related.
*
* @return array
*/
protected static function define_related() {
return [
'cache' => 'core_calendar\external\events_related_objects_cache',
];
}
}
@@ -0,0 +1,106 @@
<?php
// 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/>.
/**
* Contains event class for displaying a list of calendar events grouped by course id.
*
* @package core_calendar
* @copyright 2017 Ryan Wyllie <ryan@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_calendar\external;
defined('MOODLE_INTERNAL') || die();
use \core\external\exporter;
use \renderer_base;
/**
* Class for displaying a list of calendar events grouped by course id.
*
* This class uses the events relateds cache in order to get the related
* data for exporting an event without having to naively hit the database
* for each event.
*
* @package core_calendar
* @copyright 2017 Ryan Wyllie <ryan@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class events_grouped_by_course_exporter extends exporter {
/**
* @var array $events An array of event_interface objects
* grouped and index by course id.
*/
protected $eventsbycourse;
/**
* Constructor.
*
* @param array $eventsbycourse An array of event_interface objects
* @param array $related An array of related objects
*/
public function __construct(array $eventsbycourse, $related = []) {
$this->eventsbycourse = $eventsbycourse;
parent::__construct([], $related);
}
/**
* Return the list of additional properties.
*
* @return array
*/
protected static function define_other_properties() {
return [
'groupedbycourse' => [
'type' => events_same_course_exporter::read_properties_definition(),
'multiple' => true,
'default' => [],
],
];
}
/**
* 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) {
$return = [];
$cache = $this->related['cache'];
foreach ($this->eventsbycourse as $courseid => $events) {
$eventsexporter = new events_same_course_exporter(
$courseid, $events, ['cache' => $cache]);
$return['groupedbycourse'][] = $eventsexporter->export($output);
}
return $return;
}
/**
* Returns a list of objects that are related.
*
* @return array
*/
protected static function define_related() {
return [
'cache' => 'core_calendar\external\events_related_objects_cache',
];
}
}
@@ -0,0 +1,288 @@
<?php
// 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/>.
/**
* Contains event class for providing the related objects when exporting a list of calendar events.
*
* @package core_calendar
* @copyright 2017 Ryan Wyllie <ryan@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_calendar\external;
defined('MOODLE_INTERNAL') || die();
use \core_calendar\local\event\entities\event_interface;
/**
* Class to providing the related objects when exporting a list of calendar events.
*
* This class is only meant for use with exporters. It attempts to bulk load
* the related objects for a list of events and cache them to avoid having
* to query the database when exporting each individual event.
*
* @package core_calendar
* @copyright 2017 Ryan Wyllie <ryan@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class events_related_objects_cache {
/**
* @var array $events The events for which we need related objects.
*/
protected $events;
/**
* @var array $courses The related courses.
*/
protected $courses = null;
/**
* @var array $groups The related groups.
*/
protected $groups = null;
/**
* @var array $coursemodules The related course modules.
*/
protected $coursemodules = [];
/**
* @var array $moduleinstances The related module instances.
*/
protected $moduleinstances = null;
/**
* Constructor.
*
* @param array $events Array of event_interface events
* @param array $courses Array of courses to populate the cache with
*/
public function __construct(array $events, array $courses = null) {
$this->events = $events;
if (!is_null($courses)) {
$this->courses = [];
foreach ($courses as $course) {
$this->courses[$course->id] = $course;
}
}
}
/**
* Get the related course object for a given event.
*
* @param event_interface $event The event object.
* @return \stdClass|null
*/
public function get_course(event_interface $event) {
if (is_null($this->courses)) {
$this->load_courses();
}
if ($course = $event->get_course()) {
$courseid = $course->get('id');
return isset($this->courses[$courseid]) ? $this->courses[$courseid] : null;
} else {
return null;
}
}
/**
* Get the related context for a given event.
*
* @param event_interface $event The event object.
* @return \context|null
*/
public function get_context(event_interface $event) {
global $USER;
$categoryid = $event->get_category() ? $event->get_category()->get('id') : null;
$courseid = $event->get_course() ? $event->get_course()->get('id') : null;
$groupid = $event->get_group() ? $event->get_group()->get('id') : null;
$userid = $event->get_user() ? $event->get_user()->get('id') : null;
$moduleid = $event->get_course_module() ? $event->get_course_module()->get('id') : null;
if (!empty($categoryid)) {
return \context_coursecat::instance($categoryid);
} else if (!empty($courseid)) {
return \context_course::instance($event->get_course()->get('id'));
} else if (!empty($groupid)) {
$group = $this->get_group($event);
return \context_course::instance($group->courseid);
} else if (!empty($userid) && $userid == $USER->id) {
return \context_user::instance($userid);
} else if (!empty($userid) && $userid != $USER->id && $moduleid && $moduleid > 0) {
$cm = $this->get_course_module($event);
return \context_course::instance($cm->course);
} else {
return \context_user::instance($userid);
}
}
/**
* Get the related group object for a given event.
*
* @param event_interface $event The event object.
* @return \stdClass|null
*/
public function get_group(event_interface $event) {
if (is_null($this->groups)) {
$this->load_groups();
}
if ($group = $event->get_group()) {
$groupid = $group->get('id');
return isset($this->groups[$groupid]) ? $this->groups[$groupid] : null;
} else {
return null;
}
}
/**
* Get the related course module for a given event.
*
* @param event_interface $event The event object.
* @return \stdClass|null
*/
public function get_course_module(event_interface $event) {
if (!$event->get_course_module()) {
return null;
}
$id = $event->get_course_module()->get('id');
$name = $event->get_course_module()->get('modname');
$key = $name . '_' . $id;
if (!isset($this->coursemodules[$key])) {
$this->coursemodules[$key] = get_coursemodule_from_instance($name, $id, 0, false, MUST_EXIST);
}
return $this->coursemodules[$key];
}
/**
* Get the related module instance for a given event.
*
* @param event_interface $event The event object.
* @return \stdClass|null
*/
public function get_module_instance(event_interface $event) {
if (!$event->get_course_module()) {
return null;
}
if (is_null($this->moduleinstances)) {
$this->load_module_instances();
}
$id = $event->get_course_module()->get('instance');
$name = $event->get_course_module()->get('modname');
if (isset($this->moduleinstances[$name])) {
if (isset($this->moduleinstances[$name][$id])) {
return $this->moduleinstances[$name][$id];
}
}
return null;
}
/**
* Load the list of all of the distinct courses required for the
* list of provided events and save the result in memory.
*/
protected function load_courses() {
global $DB;
$courseids = [];
foreach ($this->events as $event) {
if ($course = $event->get_course()) {
$id = $course->get('id');
$courseids[$id] = true;
}
}
if (empty($courseids)) {
$this->courses = [];
return;
}
list($idsql, $params) = $DB->get_in_or_equal(array_keys($courseids));
$sql = "SELECT * FROM {course} WHERE id {$idsql}";
$this->courses = $DB->get_records_sql($sql, $params);
}
/**
* Load the list of all of the distinct groups required for the
* list of provided events and save the result in memory.
*/
protected function load_groups() {
global $DB;
$groupids = [];
foreach ($this->events as $event) {
if ($group = $event->get_group()) {
$id = $group->get('id');
$groupids[$id] = true;
}
}
if (empty($groupids)) {
$this->groups = [];
return;
}
list($idsql, $params) = $DB->get_in_or_equal(array_keys($groupids));
$sql = "SELECT * FROM {groups} WHERE id {$idsql}";
$this->groups = $DB->get_records_sql($sql, $params);
}
/**
* Load the list of all of the distinct module instances required for the
* list of provided events and save the result in memory.
*/
protected function load_module_instances() {
global $DB;
$this->moduleinstances = [];
$modulestoload = [];
foreach ($this->events as $event) {
if ($module = $event->get_course_module()) {
$id = $module->get('instance');
$name = $module->get('modname');
$ids = isset($modulestoload[$name]) ? $modulestoload[$name] : [];
$ids[$id] = true;
$modulestoload[$name] = $ids;
}
}
if (empty($modulestoload)) {
return;
}
foreach ($modulestoload as $modulename => $ids) {
list($idsql, $params) = $DB->get_in_or_equal(array_keys($ids));
$sql = "SELECT * FROM {" . $modulename . "} WHERE id {$idsql}";
$this->moduleinstances[$modulename] = $DB->get_records_sql($sql, $params);
}
}
}
@@ -0,0 +1,83 @@
<?php
// 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/>.
/**
* Contains event class for displaying a list of calendar events for a single course.
*
* @package core_calendar
* @copyright 2017 Ryan Wyllie <ryan@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_calendar\external;
defined('MOODLE_INTERNAL') || die();
use \renderer_base;
/**
* Class for displaying a list of calendar events for a single course.
*
* This class uses the events relateds cache in order to get the related
* data for exporting an event without having to naively hit the database
* for each event.
*
* @package core_calendar
* @copyright 2017 Ryan Wyllie <ryan@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class events_same_course_exporter extends events_exporter {
/**
* @var array $courseid The id of the course for these events.
*/
protected $courseid;
/**
* Constructor.
*
* @param int $courseid The course id for these events
* @param array $events An array of event_interface objects
* @param array $related An array of related objects
*/
public function __construct($courseid, array $events, $related = []) {
parent::__construct($events, $related);
$this->courseid = $courseid;
}
/**
* Return the list of additional properties.
*
* @return array
*/
protected static function define_other_properties() {
$properties = parent::define_other_properties();
$properties['courseid'] = ['type' => PARAM_INT];
return $properties;
}
/**
* 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) {
$values = parent::get_other_values($output);
$values['courseid'] = $this->courseid;
return $values;
}
}
+97
View File
@@ -0,0 +1,97 @@
<?php
// 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/>.
/**
* This is the external method for exporting a calendar token.
*
* @package core_calendar
* @since Moodle 3.10
* @copyright 2020 Juan Leyva <juan@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_calendar\external\export;
defined('MOODLE_INTERNAL') || die();
global $CFG;
require_once($CFG->dirroot . '/calendar/lib.php');
use context_system;
use core_external\external_api;
use core_external\external_function_parameters;
use core_external\external_single_structure;
use core_external\external_value;
use core_external\external_warnings;
use moodle_exception;
/**
* This is the external method for exporting a calendar token.
*
* @copyright 2020 Juan Leyva <juan@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class token extends external_api {
/**
* Returns description of method parameters.
*
* @return external_function_parameters.
* @since Moodle 3.10
*/
public static function execute_parameters() {
return new external_function_parameters([]);
}
/**
* Return the auth token required for exporting a calendar.
*
* @return array The access information
* @throws moodle_exception
* @since Moodle 3.10
*/
public static function execute() {
global $CFG, $USER;
$context = context_system::instance();
self::validate_context($context);
if (empty($CFG->enablecalendarexport)) {
throw new moodle_exception('Calendar export is disabled in this site.');
}
return [
'token' => calendar_get_export_token($USER),
'warnings' => [],
];
}
/**
* Returns description of method result value.
*
* @return \core_external\external_description.
* @since Moodle 3.10
*/
public static function execute_returns() {
return new external_single_structure(
[
'token' => new external_value(PARAM_RAW, 'The calendar permanent access token for calendar export.'),
'warnings' => new external_warnings(),
]
);
}
}
+153
View File
@@ -0,0 +1,153 @@
<?php
// 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/>.
namespace core_calendar\external;
use core\external\exporter;
use renderer_base;
use stdClass;
use moodle_url;
/**
* Class for exporting calendar footer view options data.
*
* @package core_calendar
* @copyright 2017 Simey Lameze
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class footer_options_exporter extends exporter {
/**
* @var \calendar_information $calendar The calendar to be rendered.
*/
protected $calendar;
/**
* @var int $userid The user id.
*/
protected $userid;
/**
* @var string $token The user sha1 token.
*/
protected $token;
/**
* @var bool $showfullcalendarlink Whether the full calendar link should be displayed or not.
*/
protected $showfullcalendarlink;
/**
* Constructor for month_exporter.
*
* @param \calendar_information $calendar The calendar being represented
* @param int $userid The user id
* @param string $token The user sha1 token.
* @param array $options Display options for the footer. If an option is not set, a default value will be provided.
* It consists of:
* - showfullcalendarlink - bool - Whether to show the full calendar link or not. Defaults to false.
*/
public function __construct(\calendar_information $calendar, $userid, $token, array $options = []) {
$this->calendar = $calendar;
$this->userid = $userid;
$this->token = $token;
$this->showfullcalendarlink = $options['showfullcalendarlink'] ?? false;
}
/**
* Get manage subscription link.
*
* @return string|null The manage subscription hyperlink.
*/
protected function get_manage_subscriptions_link(): ?string {
if (calendar_user_can_add_event($this->calendar->course)) {
$managesubscriptionurl = new moodle_url('/calendar/managesubscriptions.php');
return $managesubscriptionurl->out(true);
}
return null;
}
/**
* 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) {
global $CFG;
$values = new stdClass();
$values->footerlinks = [];
if ($this->showfullcalendarlink) {
if ($this->calendar->courseid !== SITEID) {
$linkname = get_string('coursecalendarlink', 'calendar');
} else {
$linkname = get_string('fullcalendar', 'calendar');
}
$values->footerlinks[] = (object)[
'url' => $this->get_calendar_url(),
'linkname' => $linkname,
];
}
if (!empty($CFG->enablecalendarexport) && $managesubscriptionlink = $this->get_manage_subscriptions_link()) {
$values->footerlinks[] = (object)[
'url' => $managesubscriptionlink,
'linkname' => get_string('managesubscriptions', 'calendar'),
];
}
return (array) $values;
}
/**
* Return the list of additional properties.
*
* @return array
*/
public static function define_other_properties() {
return [
'footerlinks' => [
'type' => [
'url' => [
'type' => PARAM_URL,
],
'linkname' => [
'type' => PARAM_TEXT,
],
],
'multiple' => true,
'optional' => true,
],
];
}
/**
* Build the calendar URL.
*
* @return string The calendar URL.
*/
public function get_calendar_url() {
$url = new moodle_url('/calendar/view.php', [
'view' => 'month',
'time' => $this->calendar->time,
'course' => $this->calendar->courseid,
]);
return $url->out(false);
}
}
+471
View File
@@ -0,0 +1,471 @@
<?php
// 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/>.
/**
* Contains event class for displaying the month view.
*
* @package core_calendar
* @copyright 2017 Andrew Nicols <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_calendar\external;
defined('MOODLE_INTERNAL') || die();
use core\external\exporter;
use renderer_base;
use moodle_url;
/**
* Class for displaying the month view.
*
* @package core_calendar
* @copyright 2017 Andrew Nicols <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class month_exporter extends exporter {
/** @var int Number of calendar instances displayed. */
protected static $calendarinstances = 0;
/** @var int This calendar instance's ID. */
protected $calendarinstanceid = 0;
/**
* @var \calendar_information $calendar The calendar to be rendered.
*/
protected $calendar;
/**
* @var int $firstdayofweek The first day of the week.
*/
protected $firstdayofweek;
/**
* @var moodle_url $url The URL for the events page.
*/
protected $url;
/**
* @var bool $includenavigation Whether navigation should be included on the output.
*/
protected $includenavigation = true;
/**
* @var bool $initialeventsloaded Whether the events have been loaded for this month.
*/
protected $initialeventsloaded = true;
/**
* @var bool $showcoursefilter Whether to render the course filter selector as well.
*/
protected $showcoursefilter = false;
/**
* Constructor for month_exporter.
*
* @param \calendar_information $calendar The calendar being represented
* @param \core_calendar\type_base $type The calendar type (e.g. Gregorian)
* @param array $related The related information
*/
public function __construct(\calendar_information $calendar, \core_calendar\type_base $type, $related) {
// Increment the calendar instances count on initialisation.
self::$calendarinstances++;
// Assign this instance an ID based on the latest calendar instances count.
$this->calendarinstanceid = self::$calendarinstances;
$this->calendar = $calendar;
$this->firstdayofweek = $type->get_starting_weekday();
$this->url = new moodle_url('/calendar/view.php', [
'view' => 'month',
'time' => $calendar->time,
]);
if ($this->calendar->course && SITEID !== $this->calendar->course->id) {
$this->url->param('course', $this->calendar->course->id);
} else if ($this->calendar->categoryid) {
$this->url->param('category', $this->calendar->categoryid);
}
$related['type'] = $type;
$data = [
'url' => $this->url->out(false),
];
parent::__construct($data, $related);
}
protected static function define_properties() {
return [
'url' => [
'type' => PARAM_URL,
],
];
}
/**
* Return the list of additional properties.
*
* @return array
*/
protected static function define_other_properties() {
return [
'courseid' => [
'type' => PARAM_INT,
],
'categoryid' => [
'type' => PARAM_INT,
'optional' => true,
'default' => 0,
],
'filter_selector' => [
'type' => PARAM_RAW,
'optional' => true,
],
'weeks' => [
'type' => week_exporter::read_properties_definition(),
'multiple' => true,
],
'daynames' => [
'type' => day_name_exporter::read_properties_definition(),
'multiple' => true,
],
'view' => [
'type' => PARAM_ALPHA,
],
'date' => [
'type' => date_exporter::read_properties_definition(),
],
'periodname' => [
// Note: We must use RAW here because the calendar type returns the formatted month name based on a
// calendar format.
'type' => PARAM_RAW,
],
'includenavigation' => [
'type' => PARAM_BOOL,
'default' => true,
],
// Tracks whether the first set of events have been loaded and provided
// to the exporter.
'initialeventsloaded' => [
'type' => PARAM_BOOL,
'default' => true,
],
'previousperiod' => [
'type' => date_exporter::read_properties_definition(),
],
'previousperiodlink' => [
'type' => PARAM_URL,
],
'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' => date_exporter::read_properties_definition(),
],
'nextperiodname' => [
// Note: We must use RAW here because the calendar type returns the formatted month name based on a
// calendar format.
'type' => PARAM_RAW,
],
'nextperiodlink' => [
'type' => PARAM_URL,
],
'larrow' => [
// The left arrow defined by the theme.
'type' => PARAM_RAW,
],
'rarrow' => [
// The right arrow defined by the theme.
'type' => PARAM_RAW,
],
'defaulteventcontext' => [
'type' => PARAM_INT,
'default' => 0,
],
'calendarinstanceid' => [
'type' => PARAM_INT,
'default' => 0,
],
'viewingmonth' => [
'type' => PARAM_BOOL,
'default' => true,
],
'showviewselector' => [
'type' => PARAM_BOOL,
'default' => true,
],
'viewinginblock' => [
'type' => PARAM_BOOL,
'default' => false,
],
];
}
/**
* 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) {
$previousperiod = $this->get_previous_month_data();
$nextperiod = $this->get_next_month_data();
$date = $this->related['type']->timestamp_to_date_array($this->calendar->time);
$nextperiodlink = new moodle_url($this->url);
$nextperiodlink->param('time', $nextperiod[0]);
$previousperiodlink = new moodle_url($this->url);
$previousperiodlink->param('time', $previousperiod[0]);
$viewmode = $this->calendar->get_viewmode() ?? 'month';
$return = [
'courseid' => $this->calendar->courseid,
'weeks' => $this->get_weeks($output),
'daynames' => $this->get_day_names($output),
'view' => $viewmode,
'date' => (new date_exporter($date))->export($output),
'periodname' => userdate($this->calendar->time, get_string('strftimemonthyear')),
'previousperiod' => (new date_exporter($previousperiod))->export($output),
'previousperiodname' => userdate($previousperiod[0], get_string('strftimemonth')),
'previousperiodlink' => $previousperiodlink->out(false),
'nextperiod' => (new date_exporter($nextperiod))->export($output),
'nextperiodname' => userdate($nextperiod[0], get_string('strftimemonth')),
'nextperiodlink' => $nextperiodlink->out(false),
'larrow' => $output->larrow(),
'rarrow' => $output->rarrow(),
'includenavigation' => $this->includenavigation,
'initialeventsloaded' => $this->initialeventsloaded,
'calendarinstanceid' => $this->calendarinstanceid,
'showviewselector' => $viewmode === 'month',
'viewinginblock' => $viewmode === 'monthblock',
];
if ($this->showcoursefilter) {
$return['filter_selector'] = $this->get_course_filter_selector($output);
}
if ($context = $this->get_default_add_context()) {
$return['defaulteventcontext'] = $context->id;
}
if ($this->calendar->categoryid) {
$return['categoryid'] = $this->calendar->categoryid;
}
return $return;
}
/**
* Get the course filter selector.
*
* @param renderer_base $output
* @return string The html code for the course filter selector.
*/
protected function get_course_filter_selector(renderer_base $output) {
$content = '';
$content .= $output->course_filter_selector($this->url, '', $this->calendar->course->id, $this->calendarinstanceid);
return $content;
}
/**
* Get the list of day names for display, re-ordered from the first day
* of the week.
*
* @param renderer_base $output
* @return day_name_exporter[]
*/
protected function get_day_names(renderer_base $output) {
$weekdays = $this->related['type']->get_weekdays();
$daysinweek = count($weekdays);
$daynames = [];
for ($i = 0; $i < $daysinweek; $i++) {
// Bump the currentdayno and ensure it loops.
$dayno = ($i + $this->firstdayofweek + $daysinweek) % $daysinweek;
$dayname = new day_name_exporter($dayno, $weekdays[$dayno]);
$daynames[] = $dayname->export($output);
}
return $daynames;
}
/**
* Get the list of week days, ordered into weeks and padded according
* to the value of the first day of the week.
*
* @param renderer_base $output
* @return array The list of weeks.
*/
protected function get_weeks(renderer_base $output) {
$weeks = [];
$alldays = $this->get_days();
$daysinweek = count($this->related['type']->get_weekdays());
// Calculate which day number is the first, and last day of the week.
$firstdayofweek = $this->firstdayofweek;
// The first week is special as it may have padding at the beginning.
$day = reset($alldays);
$firstdayno = $day['wday'];
$prepadding = ($firstdayno + $daysinweek - $firstdayofweek) % $daysinweek;
$daysinfirstweek = $daysinweek - $prepadding;
$days = array_slice($alldays, 0, $daysinfirstweek);
$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($this->calendar, $days, 0, ($daysinweek - count($days)), $this->related);
$weeks[] = $week->export($output);
}
return $weeks;
}
/**
* Get the list of days with the matching date array.
*
* @return array
*/
protected function get_days() {
$date = $this->related['type']->timestamp_to_date_array($this->calendar->time);
$monthdays = $this->related['type']->get_num_days_in_month($date['year'], $date['mon']);
$days = [];
for ($dayno = 1; $dayno <= $monthdays; $dayno++) {
// Get the gregorian representation of the day.
$timestamp = $this->related['type']->convert_to_timestamp($date['year'], $date['mon'], $dayno);
$days[] = $this->related['type']->timestamp_to_date_array($timestamp);
}
return $days;
}
/**
* 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 current month timestamp.
*
* @return int The month timestamp.
*/
protected function get_month_data() {
$date = $this->related['type']->timestamp_to_date_array($this->calendar->time);
$monthtime = $this->related['type']->convert_to_gregorian($date['year'], $date['month'], 1);
return make_timestamp($monthtime['year'], $monthtime['month']);
}
/**
* Get the previous month timestamp.
*
* @return int The previous month timestamp.
*/
protected function get_previous_month_data() {
$type = $this->related['type'];
$date = $type->timestamp_to_date_array($this->calendar->time);
list($date['mon'], $date['year']) = $type->get_prev_month($date['year'], $date['mon']);
$time = $type->convert_to_timestamp($date['year'], $date['mon'], 1);
return $type->timestamp_to_date_array($time);
}
/**
* Get the next month timestamp.
*
* @return int The next month timestamp.
*/
protected function get_next_month_data() {
$type = $this->related['type'];
$date = $type->timestamp_to_date_array($this->calendar->time);
list($date['mon'], $date['year']) = $type->get_next_month($date['year'], $date['mon']);
$time = $type->convert_to_timestamp($date['year'], $date['mon'], 1);
return $type->timestamp_to_date_array($time);
}
/**
* Set whether the navigation should be shown.
*
* @param bool $include
* @return $this
*/
public function set_includenavigation($include) {
$this->includenavigation = $include;
return $this;
}
/**
* Set whether the initial events have already been loaded and
* provided to the exporter.
*
* @param bool $loaded
* @return $this
*/
public function set_initialeventsloaded(bool $loaded) {
$this->initialeventsloaded = $loaded;
return $this;
}
/**
* Set whether the course filter selector should be shown.
*
* @param bool $show
* @return $this
*/
public function set_showcoursefilter(bool $show) {
$this->showcoursefilter = $show;
return $this;
}
/**
* Get the default context for use when adding a new event.
*
* @return null|\context
*/
protected function get_default_add_context() {
if (calendar_user_can_add_event($this->calendar->course)) {
return \context_course::instance($this->calendar->course->id);
}
return null;
}
}
+104
View File
@@ -0,0 +1,104 @@
<?php
// 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/>.
/**
* Calendar external API for deleting the subscription.
*
* @package core_calendar
* @category external
* @copyright 2021 Huong Nguyen <huongnv13@gmail.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_calendar\external\subscription;
defined('MOODLE_INTERNAL') || die();
require_once($CFG->dirroot . '/calendar/lib.php');
use core_external\external_api;
use core_external\external_function_parameters;
use core_external\external_single_structure;
use core_external\external_value;
use core_external\external_warnings;
/**
* Calendar external API for deleting the subscription.
*
* @package core_calendar
* @category external
* @copyright 2021 Huong Nguyen <huongnv13@gmail.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class delete extends external_api {
/**
* Describes the parameters for deleting the subscription.
*
* @return external_function_parameters
* @since Moodle 4.0
*/
public static function execute_parameters(): external_function_parameters {
return new external_function_parameters([
'subscriptionid' => new external_value(PARAM_INT, 'The id of the subscription', VALUE_REQUIRED)
]);
}
/**
* External function to delete the calendar subscription.
*
* @param int $subscriptionid Subscription id.
* @return array
*/
public static function execute(int $subscriptionid): array {
[
'subscriptionid' => $subscriptionid
] = self::validate_parameters(self::execute_parameters(), [
'subscriptionid' => $subscriptionid
]);
$status = false;
$warnings = [];
if (calendar_can_edit_subscription($subscriptionid)) {
// Fetch the subscription from the database making sure it exists.
$sub = calendar_get_subscription($subscriptionid);
calendar_delete_subscription($subscriptionid);
$status = true;
} else {
$warnings = [
'item' => $subscriptionid,
'warningcode' => 'errordeletingsubscription',
'message' => get_string('nopermissions', 'error')
];
}
return [
'status' => $status,
'warnings' => $warnings
];
}
/**
* Describes the data returned from the external function.
*
* @return external_single_structure
* @since Moodle 4.0
*/
public static function execute_returns(): external_single_structure {
return new external_single_structure([
'status' => new external_value(PARAM_BOOL, 'status: true if success'),
'warnings' => new external_warnings()
]);
}
}
+168
View File
@@ -0,0 +1,168 @@
<?php
// 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/>.
/**
* Contains event class for displaying the day on month view.
*
* @package core_calendar
* @copyright 2017 Andrew Nicols <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_calendar\external;
defined('MOODLE_INTERNAL') || die();
use renderer_base;
/**
* Class for displaying the day on month view.
*
* @package core_calendar
* @copyright 2017 Andrew Nicols <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class week_day_exporter extends day_exporter {
/**
* 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) {
parent::__construct($calendar, $data, $related);
// Fix the url for today to be based on the today timestamp
// rather than the calendar_information time set in the parent
// constructor.
$this->url->param('time', $this->data[0]);
}
/**
* 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.
*
* @return array
*/
protected static function define_other_properties() {
$return = parent::define_other_properties();
$return = array_merge($return, [
'popovertitle' => [
'type' => PARAM_RAW,
'default' => '',
],
'daytitle' => [
'type' => PARAM_RAW,
]
]);
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) {
$return = parent::get_other_values($output);
if ($popovertitle = $this->get_popover_title()) {
$return['popovertitle'] = $popovertitle;
}
$return['daytitle'] = $this->get_day_title();
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;
}
/**
* Get the title for this day.
*
* @return string
*/
protected function get_day_title(): string {
$userdate = userdate($this->data[0], get_string('strftimedayshort'));
$numevents = count($this->related['events']);
if ($numevents == 1) {
$title = get_string('dayeventsone', 'calendar', $userdate);
} else if ($numevents) {
$title = get_string('dayeventsmany', 'calendar', ['num' => $numevents, 'day' => $userdate]);
} else {
$title = get_string('dayeventsnone', 'calendar', $userdate);
}
return $title;
}
}
+182
View File
@@ -0,0 +1,182 @@
<?php
// 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/>.
/**
* Contains event class for displaying the week view.
*
* @package core_calendar
* @copyright 2017 Andrew Nicols <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_calendar\external;
defined('MOODLE_INTERNAL') || die();
use core\external\exporter;
use renderer_base;
/**
* Class for displaying the week view.
*
* @package core_calendar
* @copyright 2017 Andrew Nicols <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class week_exporter extends exporter {
/**
* @var array $days An array of day_exporter objects.
*/
protected $days = [];
/**
* @var int $prepadding The number of pre-padding days at the start of the week.
*/
protected $prepadding = 0;
/**
* @var int $postpadding The number of post-padding days at the start of the week.
*/
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(\calendar_information $calendar, $days, $prepadding, $postpadding, $related) {
$this->days = $days;
$this->prepadding = $prepadding;
$this->postpadding = $postpadding;
$this->calendar = $calendar;
parent::__construct([], $related);
}
/**
* Return the list of additional properties.
*
* @return array
*/
protected static function define_other_properties() {
return [
'prepadding' => [
'type' => PARAM_INT,
'multiple' => true,
],
'postpadding' => [
'type' => PARAM_INT,
'multiple' => true,
],
'days' => [
'type' => week_day_exporter::read_properties_definition(),
'multiple' => true,
],
];
}
/**
* 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) {
global $CFG;
$return = [
'prepadding' => [],
'postpadding' => [],
'days' => [],
];
for ($i = 0; $i < $this->prepadding; $i++) {
$return['prepadding'][] = $i;
}
for ($i = 0; $i < $this->postpadding; $i++) {
$return['postpadding'][] = $i;
}
$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) {
$times = $event->get_times();
$starttime = $times->get_start_time()->getTimestamp();
$startdate = $this->related['type']->timestamp_to_date_array($starttime);
$endtime = $times->get_end_time()->getTimestamp();
$enddate = $this->related['type']->timestamp_to_date_array($endtime);
if ((($startdate['year'] * 366) + $startdate['yday']) > ($daydata['year'] * 366) + $daydata['yday']) {
// Starts after today.
continue;
}
if ((($enddate['year'] * 366) + $enddate['yday']) < ($daydata['year'] * 366) + $daydata['yday']) {
// Ends before today.
continue;
}
$events[] = $event;
}
$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'],
]);
$return['days'][] = $day->export($output);
}
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',
];
}
}