Also moved related PHPUnit tests.
Part of MDL-55611 epic.
if ($issite) {
// Being displayed at site level. This will cause the filter to fall back to auto-detecting
// the list of courses it will be grabbing events from.
- $filtercourse = \core_calendar\api::get_default_courses();
+ $filtercourse = calendar_get_default_courses();
} else {
// Forcibly filter events to include only those from the particular course we are in.
$filtercourse = array($courseid => $this->page->course);
}
- list($courses, $group, $user) = \core_calendar\api::set_filters($filtercourse);
+ list($courses, $group, $user) = calendar_set_filters($filtercourse);
if ($issite) {
// For the front page.
- $this->content->text .= \core_calendar\api::get_mini_calendar($courses, $group, $user, false, false,
+ $this->content->text .= calendar_get_mini($courses, $group, $user, false, false,
'frontpage', $courseid, $time);
// No filters for now.
} else {
// For any other course.
- $this->content->text .= \core_calendar\api::get_mini_calendar($courses, $group, $user, false, false,
+ $this->content->text .= calendar_get_mini($courses, $group, $user, false, false,
'course', $courseid, $time);
$this->content->text .= '<h3 class="eventskey">'.get_string('eventskey', 'calendar').'</h3>';
$this->content->text .= '<div class="filters calendar_filters">' .
- \core_calendar\api::get_filter_controls($this->page->url) . '</div>';
+ calendar_filter_controls($this->page->url) . '</div>';
}
return $this->content;
if ($courseshown == SITEID) {
// Being displayed at site level. This will cause the filter to fall back to auto-detecting
// the list of courses it will be grabbing events from.
- $filtercourse = \core_calendar\api::get_default_courses();
+ $filtercourse = calendar_get_default_courses();
} else {
// Forcibly filter events to include only those from the particular course we are in.
$filtercourse = array($courseshown => $this->page->course);
}
}
- list($courses, $group, $user) = \core_calendar\api::set_filters($filtercourse);
+ list($courses, $group, $user) = calendar_set_filters($filtercourse);
$defaultlookahead = CALENDAR_DEFAULT_UPCOMING_LOOKAHEAD;
if (isset($CFG->calendar_lookahead)) {
$defaultmaxevents = intval($CFG->calendar_maxevents);
}
$maxevents = get_user_preferences('calendar_maxevents', $defaultmaxevents);
- $events = \core_calendar\api::get_upcoming($courses, $group, $user, $lookahead, $maxevents);
+ $events = calendar_get_upcoming($courses, $group, $user, $lookahead, $maxevents);
if (!empty($this->instance)) {
$link = 'view.php?view=day&course='.$courseshown.'&';
if (!isset($events[$i]->time)) {
continue;
}
- $events[$i] = \core_calendar\api::add_event_metadata($events[$i]);
+ $events[$i] = calendar_add_event_metadata($events[$i]);
$content .= '<div class="event"><span class="icon c0">' . $events[$i]->icon . '</span>';
if (!empty($events[$i]->referer)) {
// That's an activity event, so let's provide the hyperlink.
$content .= $events[$i]->referer;
} else {
if (!empty($linkhref)) {
- $href = \core_calendar\api::get_link_href(new \moodle_url(CALENDAR_URL . $linkhref), 0, 0, 0,
+ $href = calendar_get_link_href(new \moodle_url(CALENDAR_URL . $linkhref), 0, 0, 0,
$events[$i]->timestart);
$href->set_anchor('event_' . $events[$i]->id);
$content .= \html_writer::link($href, $events[$i]->name);
namespace core_calendar;
-use context_course;
-
defined('MOODLE_INTERNAL') || die();
require_once($CFG->dirroot . '/calendar/lib.php');
*/
class api {
- /**
- * Return the days of the week.
- *
- * @return array array of days
- */
- public static function get_days() {
- $calendartype = type_factory::get_calendar_instance();
- return $calendartype->get_weekdays();
- }
-
- /**
- * Get the subscription from a given id.
- *
- * @param int $id id of the subscription
- * @return \stdClass Subscription record from DB
- * @throws \moodle_exception for an invalid id
- */
- public static function get_subscription($id) {
- global $DB;
-
- $cache = \cache::make('core', 'calendar_subscriptions');
- $subscription = $cache->get($id);
- if (empty($subscription)) {
- $subscription = $DB->get_record('event_subscriptions', array('id' => $id), '*', MUST_EXIST);
- $cache->set($id, $subscription);
- }
-
- return $subscription;
- }
-
- /**
- * Gets the first day of the week.
- *
- * @return int
- */
- public static function get_starting_weekday() {
- $calendartype = type_factory::get_calendar_instance();
- return $calendartype->get_starting_weekday();
- }
-
- /**
- * Generates the HTML for a miniature calendar.
- *
- * @param array $courses list of course to list events from
- * @param array $groups list of group
- * @param array $users user's info
- * @param int|bool $calmonth calendar month in numeric, default is set to false
- * @param int|bool $calyear calendar month in numeric, default is set to false
- * @param string|bool $placement the place/page the calendar is set to appear - passed on the the controls function
- * @param int|bool $courseid id of the course the calendar is displayed on - passed on the the controls function
- * @param int $time the unixtimestamp representing the date we want to view, this is used instead of $calmonth
- * and $calyear to support multiple calendars
- * @return string $content return html table for mini calendar
- */
- public static function get_mini_calendar($courses, $groups, $users, $calmonth = false, $calyear = false,
- $placement = false, $courseid = false, $time = 0) {
- global $CFG, $OUTPUT, $PAGE;
-
- // Get the calendar type we are using.
- $calendartype = type_factory::get_calendar_instance();
-
- $display = new \stdClass;
-
- // Assume we are not displaying this month for now.
- $display->thismonth = false;
-
- $content = '';
-
- // Do this check for backwards compatibility.
- // The core should be passing a timestamp rather than month and year.
- // If a month and year are passed they will be in Gregorian.
- if (!empty($calmonth) && !empty($calyear)) {
- // Ensure it is a valid date, else we will just set it to the current timestamp.
- if (checkdate($calmonth, 1, $calyear)) {
- $time = make_timestamp($calyear, $calmonth, 1);
- } else {
- $time = time();
- }
- $date = usergetdate($time);
- if ($calmonth == $date['mon'] && $calyear == $date['year']) {
- $display->thismonth = true;
- }
- // We can overwrite date now with the date used by the calendar type,
- // if it is not Gregorian, otherwise there is no need as it is already in Gregorian.
- if ($calendartype->get_name() != 'gregorian') {
- $date = $calendartype->timestamp_to_date_array($time);
- }
- } else if (!empty($time)) {
- // Get the specified date in the calendar type being used.
- $date = $calendartype->timestamp_to_date_array($time);
- $thisdate = $calendartype->timestamp_to_date_array(time());
- if ($date['month'] == $thisdate['month'] && $date['year'] == $thisdate['year']) {
- $display->thismonth = true;
- // If we are the current month we want to set the date to the current date, not the start of the month.
- $date = $thisdate;
- }
- } else {
- // Get the current date in the calendar type being used.
- $time = time();
- $date = $calendartype->timestamp_to_date_array($time);
- $display->thismonth = true;
- }
-
- list($d, $m, $y) = array($date['mday'], $date['mon'], $date['year']); // This is what we want to display.
-
- // Get Gregorian date for the start of the month.
- $gregoriandate = $calendartype->convert_to_gregorian($date['year'], $date['mon'], 1);
-
- // Store the gregorian date values to be used later.
- list($gy, $gm, $gd, $gh, $gmin) = array($gregoriandate['year'], $gregoriandate['month'], $gregoriandate['day'],
- $gregoriandate['hour'], $gregoriandate['minute']);
-
- // Get the max number of days in this month for this calendar type.
- $display->maxdays = self::get_days_in_month($m, $y);
- // Get the starting week day for this month.
- $startwday = dayofweek(1, $m, $y);
- // Get the days in a week.
- $daynames = self::get_days();
- // Store the number of days in a week.
- $numberofdaysinweek = $calendartype->get_num_weekdays();
-
- // Set the min and max weekday.
- $display->minwday = self::get_starting_weekday();
- $display->maxwday = $display->minwday + ($numberofdaysinweek - 1);
-
- // These are used for DB queries, so we want unixtime, so we need to use Gregorian dates.
- $display->tstart = make_timestamp($gy, $gm, $gd, $gh, $gmin, 0);
- $display->tend = $display->tstart + ($display->maxdays * DAYSECS) - 1;
-
- // Align the starting weekday to fall in our display range.
- // This is simple, not foolproof.
- if ($startwday < $display->minwday) {
- $startwday += $numberofdaysinweek;
- }
-
- // Get the events matching our criteria. Don't forget to offset the timestamps for the user's TZ.
- $events = self::get_events($display->tstart, $display->tend, $users, $groups, $courses);
-
- // Set event course class for course events.
- if (!empty($events)) {
- foreach ($events as $eventid => $event) {
- if (!empty($event->modulename)) {
- $cm = get_coursemodule_from_instance($event->modulename, $event->instance);
- if (!\core_availability\info_module::is_user_visible($cm, 0, false)) {
- unset($events[$eventid]);
- }
- }
- }
- }
-
- // This is either a genius idea or an idiot idea: in order to not complicate things, we use this rule: if, after
- // possibly removing SITEID from $courses, there is only one course left, then clicking on a day in the month
- // will also set the $SESSION->cal_courses_shown variable to that one course. Otherwise, we 'd need to add extra
- // arguments to this function.
- $hrefparams = array();
- if (!empty($courses)) {
- $courses = array_diff($courses, array(SITEID));
- if (count($courses) == 1) {
- $hrefparams['course'] = reset($courses);
- }
- }
-
- // We want to have easy access by day, since the display is on a per-day basis.
- self::get_events_by_day($events, $m, $y, $eventsbyday, $durationbyday, $typesbyday, $courses);
-
- // Accessibility: added summary and <abbr> elements.
- $summary = get_string('calendarheading', 'calendar', userdate($display->tstart, get_string('strftimemonthyear')));
- // Begin table.
- $content .= '<table class="minicalendar calendartable" summary="' . $summary . '">';
- if (($placement !== false) && ($courseid !== false)) {
- $content .= '<caption>' . self::get_top_controls($placement,
- array('id' => $courseid, 'time' => $time)) . '</caption>';
- }
- $content .= '<tr class="weekdays">'; // Header row: day names.
-
- // Print out the names of the weekdays.
- for ($i = $display->minwday; $i <= $display->maxwday; $i++) {
- $pos = $i % $numberofdaysinweek;
- $content .= '<th scope="col"><abbr title="' . $daynames[$pos]['fullname'] . '">' .
- $daynames[$pos]['shortname'] . "</abbr></th>\n";
- }
-
- $content .= '</tr><tr>'; // End of day names; prepare for day numbers.
-
- // For the table display. $week is the row; $dayweek is the column.
- $dayweek = $startwday;
-
- // Padding (the first week may have blank days in the beginning).
- for ($i = $display->minwday; $i < $startwday; ++$i) {
- $content .= '<td class="dayblank"> </td>' ."\n";
- }
-
- $weekend = CALENDAR_DEFAULT_WEEKEND;
- if (isset($CFG->calendar_weekend)) {
- $weekend = intval($CFG->calendar_weekend);
- }
-
- // Now display all the calendar.
- $daytime = strtotime('-1 day', $display->tstart);
- for ($day = 1; $day <= $display->maxdays; ++$day, ++$dayweek) {
- $cellattributes = array();
- $daytime = strtotime('+1 day', $daytime);
- if ($dayweek > $display->maxwday) {
- // We need to change week (table row).
- $content .= '</tr><tr>';
- $dayweek = $display->minwday;
- }
-
- // Reset vars.
- if ($weekend & (1 << ($dayweek % $numberofdaysinweek))) {
- // Weekend. This is true no matter what the exact range is.
- $class = 'weekend day';
- } else {
- // Normal working day.
- $class = 'day';
- }
-
- $eventids = array();
- if (!empty($eventsbyday[$day])) {
- $eventids = $eventsbyday[$day];
- }
-
- if (!empty($durationbyday[$day])) {
- $eventids = array_unique(array_merge($eventids, $durationbyday[$day]));
- }
-
- $finishclass = false;
-
- if (!empty($eventids)) {
- // There is at least one event on this day.
- $class .= ' hasevent';
- $hrefparams['view'] = 'day';
- $dayhref = self::get_link_href(new \moodle_url(CALENDAR_URL . 'view.php', $hrefparams), 0, 0, 0, $daytime);
-
- $popupcontent = '';
- foreach ($eventids as $eventid) {
- if (!isset($events[$eventid])) {
- continue;
- }
- $event = new \calendar_event($events[$eventid]);
- $popupalt = '';
- $component = 'moodle';
- if (!empty($event->modulename)) {
- $popupicon = 'icon';
- $popupalt = $event->modulename;
- $component = $event->modulename;
- } else if ($event->courseid == SITEID) { // Site event.
- $popupicon = 'i/siteevent';
- } else if ($event->courseid != 0 && $event->courseid != SITEID
- && $event->groupid == 0) { // Course event.
- $popupicon = 'i/courseevent';
- } else if ($event->groupid) { // Group event.
- $popupicon = 'i/groupevent';
- } else { // Must be a user event.
- $popupicon = 'i/userevent';
- }
-
- if ($event->timeduration) {
- $startdate = $calendartype->timestamp_to_date_array($event->timestart);
- $enddate = $calendartype->timestamp_to_date_array($event->timestart + $event->timeduration - 1);
- if ($enddate['mon'] == $m && $enddate['year'] == $y && $enddate['mday'] == $day) {
- $finishclass = true;
- }
- }
-
- $dayhref->set_anchor('event_' . $event->id);
-
- $popupcontent .= \html_writer::start_tag('div');
- $popupcontent .= $OUTPUT->pix_icon($popupicon, $popupalt, $component);
- // Show ical source if needed.
- if (!empty($event->subscription) && $CFG->calendar_showicalsource) {
- $a = new \stdClass();
- $a->name = format_string($event->name, true);
- $a->source = $event->subscription->name;
- $name = get_string('namewithsource', 'calendar', $a);
- } else {
- if ($finishclass) {
- $samedate = $startdate['mon'] == $enddate['mon'] &&
- $startdate['year'] == $enddate['year'] &&
- $startdate['mday'] == $enddate['mday'];
-
- if ($samedate) {
- $name = format_string($event->name, true);
- } else {
- $name = format_string($event->name, true) . ' (' . get_string('eventendtime', 'calendar') . ')';
- }
- } else {
- $name = format_string($event->name, true);
- }
- }
- $popupcontent .= \html_writer::link($dayhref, $name);
- $popupcontent .= \html_writer::end_tag('div');
- }
-
- if ($display->thismonth && $day == $d) {
- $popupdata = self::get_popup(true, $daytime, $popupcontent);
- } else {
- $popupdata = self::get_popup(false, $daytime, $popupcontent);
- }
-
- // Class and cell content.
- if (isset($typesbyday[$day]['startglobal'])) {
- $class .= ' calendar_event_global';
- } else if (isset($typesbyday[$day]['startcourse'])) {
- $class .= ' calendar_event_course';
- } else if (isset($typesbyday[$day]['startgroup'])) {
- $class .= ' calendar_event_group';
- } else if (isset($typesbyday[$day]['startuser'])) {
- $class .= ' calendar_event_user';
- }
- if ($finishclass) {
- $class .= ' duration_finish';
- }
- $data = array(
- 'url' => $dayhref,
- 'day' => $day,
- 'content' => $popupdata['data-core_calendar-popupcontent'],
- 'title' => $popupdata['data-core_calendar-title']
- );
- $cell = $OUTPUT->render_from_template('core_calendar/minicalendar_day_link', $data);
- } else {
- $cell = $day;
- }
-
- $durationclass = false;
- if (isset($typesbyday[$day]['durationglobal'])) {
- $durationclass = ' duration_global';
- } else if (isset($typesbyday[$day]['durationcourse'])) {
- $durationclass = ' duration_course';
- } else if (isset($typesbyday[$day]['durationgroup'])) {
- $durationclass = ' duration_group';
- } else if (isset($typesbyday[$day]['durationuser'])) {
- $durationclass = ' duration_user';
- }
- if ($durationclass) {
- $class .= ' duration ' . $durationclass;
- }
-
- // If event has a class set then add it to the table day <td> tag.
- // Note: only one colour for minicalendar.
- if (isset($eventsbyday[$day])) {
- foreach ($eventsbyday[$day] as $eventid) {
- if (!isset($events[$eventid])) {
- continue;
- }
- $event = $events[$eventid];
- if (!empty($event->class)) {
- $class .= ' ' . $event->class;
- }
- break;
- }
- }
-
- if ($display->thismonth && $day == $d) {
- // The current cell is for today - add appropriate classes and additional information for styling.
- $class .= ' today';
- $today = get_string('today', 'calendar') . ' ' . userdate(time(), get_string('strftimedayshort'));
-
- if (!isset($eventsbyday[$day]) && !isset($durationbyday[$day])) {
- $class .= ' eventnone';
- $popupdata = self::get_popup(true, false);
- $data = array(
- 'url' => '#',
- 'day' => $day,
- 'content' => $popupdata['data-core_calendar-popupcontent'],
- 'title' => $popupdata['data-core_calendar-title']
- );
- $cell = $OUTPUT->render_from_template('core_calendar/minicalendar_day_link', $data);
- }
- $cell = get_accesshide($today . ' ') . $cell;
- }
-
- // Just display it.
- $cellattributes['class'] = $class;
- $content .= \html_writer::tag('td', $cell, $cellattributes);
- }
-
- // Padding (the last week may have blank days at the end).
- for ($i = $dayweek; $i <= $display->maxwday; ++$i) {
- $content .= '<td class="dayblank"> </td>';
- }
- $content .= '</tr>'; // Last row ends.
-
- $content .= '</table>'; // Tabular display of days ends.
- return $content;
- }
-
- /**
- * Gets the calendar popup.
- *
- * @param bool $today false except when called on the current day.
- * @param mixed $timestart $events[$eventid]->timestart, OR false if there are no events.
- * @param string $popupcontent content for the popup window/layout.
- * @return string eventid for the calendar_tooltip popup window/layout.
- */
- public static function get_popup($today = false, $timestart, $popupcontent = '') {
- $popupcaption = '';
- if ($today) {
- $popupcaption = get_string('today', 'calendar') . ' ';
- }
-
- if (false === $timestart) {
- $popupcaption .= userdate(time(), get_string('strftimedayshort'));
- $popupcontent = get_string('eventnone', 'calendar');
-
- } else {
- $popupcaption .= get_string('eventsfor', 'calendar', userdate($timestart, get_string('strftimedayshort')));
- }
-
- return array(
- 'data-core_calendar-title' => $popupcaption,
- 'data-core_calendar-popupcontent' => $popupcontent,
- );
- }
-
- /**
- * Gets the calendar upcoming events.
- *
- * @param array $courses array of courses
- * @param array|int|bool $groups array of groups, group id or boolean for all/no group events
- * @param array|int|bool $users array of users, user id or boolean for all/no user events
- * @param int $daysinfuture number of days in the future we 'll look
- * @param int $maxevents maximum number of events
- * @param int $fromtime start time
- * @return array $output array of upcoming events
- */
- public static function get_upcoming($courses, $groups, $users, $daysinfuture, $maxevents, $fromtime = 0) {
- global $COURSE;
-
- $display = new \stdClass;
- $display->range = $daysinfuture; // How many days in the future we 'll look.
- $display->maxevents = $maxevents;
-
- $output = array();
-
- $processed = 0;
- $now = time(); // We 'll need this later.
- $usermidnighttoday = usergetmidnight($now);
-
- if ($fromtime) {
- $display->tstart = $fromtime;
- } else {
- $display->tstart = $usermidnighttoday;
- }
-
- // This works correctly with respect to the user's DST, but it is accurate
- // only because $fromtime is always the exact midnight of some day!
- $display->tend = usergetmidnight($display->tstart + DAYSECS * $display->range + 3 * HOURSECS) - 1;
-
- // Get the events matching our criteria.
- $events = self::get_events($display->tstart, $display->tend, $users, $groups, $courses);
-
- // This is either a genius idea or an idiot idea: in order to not complicate things, we use this rule: if, after
- // possibly removing SITEID from $courses, there is only one course left, then clicking on a day in the month
- // will also set the $SESSION->cal_courses_shown variable to that one course. Otherwise, we 'd need to add extra
- // arguments to this function.
- $hrefparams = array();
- if (!empty($courses)) {
- $courses = array_diff($courses, array(SITEID));
- if (count($courses) == 1) {
- $hrefparams['course'] = reset($courses);
- }
- }
-
- if ($events !== false) {
- $modinfo = get_fast_modinfo($COURSE);
- foreach ($events as $event) {
- if (!empty($event->modulename)) {
- if ($event->courseid == $COURSE->id) {
- if (isset($modinfo->instances[$event->modulename][$event->instance])) {
- $cm = $modinfo->instances[$event->modulename][$event->instance];
- if (!$cm->uservisible) {
- continue;
- }
- }
- } else {
- if (!$cm = get_coursemodule_from_instance($event->modulename, $event->instance)) {
- continue;
- }
- if (!\core_availability\info_module::is_user_visible($cm, 0, false)) {
- continue;
- }
- }
- }
-
- if ($processed >= $display->maxevents) {
- break;
- }
-
- $event->time = self::get_format_event_time($event, $now, $hrefparams);
- $output[] = $event;
- $processed++;
- }
- }
-
- return $output;
- }
-
- /**
- * Get a HTML link to a course.
- *
- * @param int $courseid the course id
- * @return string a link to the course (as HTML); empty if the course id is invalid
- */
- public static function get_courselink($courseid) {
- if (!$courseid) {
- return '';
- }
-
- self::get_course_cached($coursecache, $courseid);
- $context = \context_course::instance($courseid);
- $fullname = format_string($coursecache[$courseid]->fullname, true, array('context' => $context));
- $url = new \moodle_url('/course/view.php', array('id' => $courseid));
- $link = \html_writer::link($url, $fullname);
-
- return $link;
- }
-
- /**
- * Get current module cache.
- *
- * @param array $modulecache in memory module cache
- * @param string $modulename name of the module
- * @param int $instance module instance number
- * @return \stdClass|bool $module information
- */
- public static function get_module_cached(&$modulecache, $modulename, $instance) {
- if (!isset($modulecache[$modulename . '_' . $instance])) {
- $modulecache[$modulename . '_' . $instance] = get_coursemodule_from_instance($modulename, $instance);
- }
-
- return $modulecache[$modulename . '_' . $instance];
- }
-
- /**
- * Get current course cache.
- *
- * @param array $coursecache list of course cache
- * @param int $courseid id of the course
- * @return \stdClass $coursecache[$courseid] return the specific course cache
- */
- public static function get_course_cached(&$coursecache, $courseid) {
- if (!isset($coursecache[$courseid])) {
- $coursecache[$courseid] = get_course($courseid);
- }
- return $coursecache[$courseid];
- }
-
- /**
- * Get group from groupid for calendar display.
- *
- * @param int $groupid
- * @return \stdClass group object with fields 'id', 'name' and 'courseid'
- */
- public static function get_group_cached($groupid) {
- static $groupscache = array();
- if (!isset($groupscache[$groupid])) {
- $groupscache[$groupid] = groups_get_group($groupid, 'id,name,courseid');
- }
- return $groupscache[$groupid];
- }
-
- /**
- * Add calendar event metadata.
- *
- * @param \stdClass $event event info
- * @return \stdClass $event metadata
- */
- public static function add_event_metadata($event) {
- global $CFG, $OUTPUT;
-
- // Support multilang in event->name.
- $event->name = format_string($event->name, true);
-
- if (!empty($event->modulename)) { // Activity event.
- // The module name is set. I will assume that it has to be displayed, and
- // also that it is an automatically-generated event. And of course that the
- // fields for get_coursemodule_from_instance are set correctly.
- $module = self::get_module_cached($coursecache, $event->modulename, $event->instance);
-
- if ($module === false) {
- return;
- }
-
- $modulename = get_string('modulename', $event->modulename);
- if (get_string_manager()->string_exists($event->eventtype, $event->modulename)) {
- // Will be used as alt text if the event icon.
- $eventtype = get_string($event->eventtype, $event->modulename);
- } else {
- $eventtype = '';
- }
- $icon = $OUTPUT->image_url('icon', $event->modulename) . '';
-
- $event->icon = '<img src="' . $icon . '" alt="' . $eventtype . '" title="' . $modulename . '" class="icon" />';
- $event->referer = '<a href="' . $CFG->wwwroot . '/mod/' . $event->modulename . '/view.php?id=' .
- $module->id . '">' . $event->name . '</a>';
- $event->courselink = self::get_courselink($module->course);
- $event->cmid = $module->id;
- } else if ($event->courseid == SITEID) { // Site event.
- $event->icon = '<img src="' . $OUTPUT->image_url('i/siteevent') . '" alt="' .
- get_string('globalevent', 'calendar') . '" class="icon" />';
- $event->cssclass = 'calendar_event_global';
- } else if ($event->courseid != 0 && $event->courseid != SITEID && $event->groupid == 0) { // Course event.
- $event->icon = '<img src="' . $OUTPUT->image_url('i/courseevent') . '" alt="' .
- get_string('courseevent', 'calendar') . '" class="icon" />';
- $event->courselink = self::get_courselink($event->courseid);
- $event->cssclass = 'calendar_event_course';
- } else if ($event->groupid) { // Group event.
- if ($group = self::get_group_cached($event->groupid)) {
- $groupname = format_string($group->name, true, \context_course::instance($group->courseid));
- } else {
- $groupname = '';
- }
- $event->icon = \html_writer::empty_tag('image', array('src' => $OUTPUT->image_url('i/groupevent'),
- 'alt' => get_string('groupevent', 'calendar'), 'title' => $groupname, 'class' => 'icon'));
- $event->courselink = self::get_courselink($event->courseid) . ', ' . $groupname;
- $event->cssclass = 'calendar_event_group';
- } else if ($event->userid) { // User event.
- $event->icon = '<img src="' . $OUTPUT->image_url('i/userevent') . '" alt="' .
- get_string('userevent', 'calendar') . '" class="icon" />';
- $event->cssclass = 'calendar_event_user';
- }
-
- return $event;
- }
-
/**
* Get calendar events
*
}, []);
}
- /**
- * Get calendar events by id.
- *
- * @param array $eventids list of event ids
- * @return array Array of event entries, empty array if nothing found
- */
- public static function get_events_by_id($eventids) {
- global $DB;
-
- if (!is_array($eventids) || empty($eventids)) {
- return array();
- }
-
- list($wheresql, $params) = $DB->get_in_or_equal($eventids);
- $wheresql = "id $wheresql";
-
- return $DB->get_records_select('event', $wheresql, $params);
- }
-
- /**
- * Get control options for calendar.
- *
- * @param string $type of calendar
- * @param array $data calendar information
- * @return string $content return available control for the calender in html
- */
- public static function get_top_controls($type, $data) {
- global $PAGE, $OUTPUT;
-
- // Get the calendar type we are using.
- $calendartype = type_factory::get_calendar_instance();
-
- $content = '';
-
- // Ensure course id passed if relevant.
- $courseid = '';
- if (!empty($data['id'])) {
- $courseid = '&course=' . $data['id'];
- }
-
- // If we are passing a month and year then we need to convert this to a timestamp to
- // support multiple calendars. No where in core should these be passed, this logic
- // here is for third party plugins that may use this function.
- if (!empty($data['m']) && !empty($date['y'])) {
- if (!isset($data['d'])) {
- $data['d'] = 1;
- }
- if (!checkdate($data['m'], $data['d'], $data['y'])) {
- $time = time();
- } else {
- $time = make_timestamp($data['y'], $data['m'], $data['d']);
- }
- } else if (!empty($data['time'])) {
- $time = $data['time'];
- } else {
- $time = time();
- }
-
- // Get the date for the calendar type.
- $date = $calendartype->timestamp_to_date_array($time);
-
- $urlbase = $PAGE->url;
-
- // We need to get the previous and next months in certain cases.
- if ($type == 'frontpage' || $type == 'course' || $type == 'month') {
- $prevmonth = self::get_prev_month($date['mon'], $date['year']);
- $prevmonthtime = $calendartype->convert_to_gregorian($prevmonth[1], $prevmonth[0], 1);
- $prevmonthtime = make_timestamp($prevmonthtime['year'], $prevmonthtime['month'], $prevmonthtime['day'],
- $prevmonthtime['hour'], $prevmonthtime['minute']);
-
- $nextmonth = self::get_next_month($date['mon'], $date['year']);
- $nextmonthtime = $calendartype->convert_to_gregorian($nextmonth[1], $nextmonth[0], 1);
- $nextmonthtime = make_timestamp($nextmonthtime['year'], $nextmonthtime['month'], $nextmonthtime['day'],
- $nextmonthtime['hour'], $nextmonthtime['minute']);
- }
-
- switch ($type) {
- case 'frontpage':
- $prevlink = self::get_link_previous(get_string('monthprev', 'access'), $urlbase, false, false, false,
- true, $prevmonthtime);
- $nextlink = self::get_link_next(get_string('monthnext', 'access'), $urlbase, false, false, false, true,
- $nextmonthtime);
- $calendarlink = self::get_link_href(new \moodle_url(CALENDAR_URL . 'view.php', array('view' => 'month')),
- false, false, false, $time);
-
- if (!empty($data['id'])) {
- $calendarlink->param('course', $data['id']);
- }
-
- $right = $nextlink;
-
- $content .= \html_writer::start_tag('div', array('class' => 'calendar-controls'));
- $content .= $prevlink . '<span class="hide"> | </span>';
- $content .= \html_writer::tag('span', \html_writer::link($calendarlink,
- userdate($time, get_string('strftimemonthyear')), array('title' => get_string('monththis', 'calendar'))
- ), array('class' => 'current'));
- $content .= '<span class="hide"> | </span>' . $right;
- $content .= "<span class=\"clearer\"><!-- --></span>\n";
- $content .= \html_writer::end_tag('div');
-
- break;
- case 'course':
- $prevlink = self::get_link_previous(get_string('monthprev', 'access'), $urlbase, false, false, false,
- true, $prevmonthtime);
- $nextlink = self::get_link_next(get_string('monthnext', 'access'), $urlbase, false, false, false,
- true, $nextmonthtime);
- $calendarlink = self::get_link_href(new \moodle_url(CALENDAR_URL . 'view.php', array('view' => 'month')),
- false, false, false, $time);
-
- if (!empty($data['id'])) {
- $calendarlink->param('course', $data['id']);
- }
-
- $content .= \html_writer::start_tag('div', array('class' => 'calendar-controls'));
- $content .= $prevlink . '<span class="hide"> | </span>';
- $content .= \html_writer::tag('span', \html_writer::link($calendarlink,
- userdate($time, get_string('strftimemonthyear')), array('title' => get_string('monththis', 'calendar'))
- ), array('class' => 'current'));
- $content .= '<span class="hide"> | </span>' . $nextlink;
- $content .= "<span class=\"clearer\"><!-- --></span>";
- $content .= \html_writer::end_tag('div');
- break;
- case 'upcoming':
- $calendarlink = self::get_link_href(new \moodle_url(CALENDAR_URL . 'view.php', array('view' => 'upcoming')),
- false, false, false, $time);
- if (!empty($data['id'])) {
- $calendarlink->param('course', $data['id']);
- }
- $calendarlink = \html_writer::link($calendarlink, userdate($time, get_string('strftimemonthyear')));
- $content .= \html_writer::tag('div', $calendarlink, array('class' => 'centered'));
- break;
- case 'display':
- $calendarlink = self::get_link_href(new \moodle_url(CALENDAR_URL . 'view.php', array('view' => 'month')),
- false, false, false, $time);
- if (!empty($data['id'])) {
- $calendarlink->param('course', $data['id']);
- }
- $calendarlink = \html_writer::link($calendarlink, userdate($time, get_string('strftimemonthyear')));
- $content .= \html_writer::tag('h3', $calendarlink);
- break;
- case 'month':
- $prevlink = self::get_link_previous(userdate($prevmonthtime, get_string('strftimemonthyear')),
- 'view.php?view=month' . $courseid . '&', false, false, false, false, $prevmonthtime);
- $nextlink = self::get_link_next(userdate($nextmonthtime, get_string('strftimemonthyear')),
- 'view.php?view=month' . $courseid . '&', false, false, false, false, $nextmonthtime);
-
- $content .= \html_writer::start_tag('div', array('class' => 'calendar-controls'));
- $content .= $prevlink . '<span class="hide"> | </span>';
- $content .= $OUTPUT->heading(userdate($time, get_string('strftimemonthyear')), 2, 'current');
- $content .= '<span class="hide"> | </span>' . $nextlink;
- $content .= '<span class="clearer"><!-- --></span>';
- $content .= \html_writer::end_tag('div')."\n";
- break;
- case 'day':
- $days = self::get_days();
-
- $prevtimestamp = strtotime('-1 day', $time);
- $nexttimestamp = strtotime('+1 day', $time);
-
- $prevdate = $calendartype->timestamp_to_date_array($prevtimestamp);
- $nextdate = $calendartype->timestamp_to_date_array($nexttimestamp);
-
- $prevname = $days[$prevdate['wday']]['fullname'];
- $nextname = $days[$nextdate['wday']]['fullname'];
- $prevlink = self::get_link_previous($prevname, 'view.php?view=day' . $courseid . '&', false, false,
- false, false, $prevtimestamp);
- $nextlink = self::get_link_next($nextname, 'view.php?view=day' . $courseid . '&', false, false, false,
- false, $nexttimestamp);
-
- $content .= \html_writer::start_tag('div', array('class' => 'calendar-controls'));
- $content .= $prevlink;
- $content .= '<span class="hide"> | </span><span class="current">' .userdate($time,
- get_string('strftimedaydate')) . '</span>';
- $content .= '<span class="hide"> | </span>' . $nextlink;
- $content .= "<span class=\"clearer\"><!-- --></span>";
- $content .= \html_writer::end_tag('div') . "\n";
-
- break;
- }
-
- return $content;
- }
-
- /**
- * Formats a filter control element.
- *
- * @param \moodle_url $url of the filter
- * @param int $type constant defining the type filter
- * @return string html content of the element
- */
- public static function get_filter_controls_element(\moodle_url $url, $type) {
- global $OUTPUT;
-
- switch ($type) {
- case CALENDAR_EVENT_GLOBAL:
- $typeforhumans = 'global';
- $class = 'calendar_event_global';
- break;
- case CALENDAR_EVENT_COURSE:
- $typeforhumans = 'course';
- $class = 'calendar_event_course';
- break;
- case CALENDAR_EVENT_GROUP:
- $typeforhumans = 'groups';
- $class = 'calendar_event_group';
- break;
- case CALENDAR_EVENT_USER:
- $typeforhumans = 'user';
- $class = 'calendar_event_user';
- break;
- }
-
- if (self::show_event_type($type)) {
- $icon = $OUTPUT->pix_icon('t/hide', get_string('hide'));
- $str = get_string('hide' . $typeforhumans . 'events', 'calendar');
- } else {
- $icon = $OUTPUT->pix_icon('t/show', get_string('show'));
- $str = get_string('show' . $typeforhumans . 'events', 'calendar');
- }
- $content = \html_writer::start_tag('li', array('class' => 'calendar_event'));
- $content .= \html_writer::start_tag('a', array('href' => $url, 'rel' => 'nofollow'));
- $content .= \html_writer::tag('span', $icon, array('class' => $class));
- $content .= \html_writer::tag('span', $str, array('class' => 'eventname'));
- $content .= \html_writer::end_tag('a');
- $content .= \html_writer::end_tag('li');
-
- return $content;
- }
-
- /**
- * Get the controls filter for calendar.
- *
- * Filter is used to hide calendar info from the display page
- *
- * @param \moodle_url $returnurl return-url for filter controls
- * @return string $content return filter controls in html
- */
- public static function get_filter_controls(\moodle_url $returnurl) {
- $groupevents = true;
-
- $seturl = new \moodle_url('/calendar/set.php', array('return' => base64_encode($returnurl->out_as_local_url(false)),
- 'sesskey' => sesskey()));
- $content = \html_writer::start_tag('ul');
-
- $seturl->param('var', 'showglobal');
- $content .= self::get_filter_controls_element($seturl, CALENDAR_EVENT_GLOBAL);
-
- $seturl->param('var', 'showcourses');
- $content .= self::get_filter_controls_element($seturl, CALENDAR_EVENT_COURSE);
-
- if (isloggedin() && !isguestuser()) {
- if ($groupevents) {
- // This course MIGHT have group events defined, so show the filter.
- $seturl->param('var', 'showgroups');
- $content .= self::get_filter_controls_element($seturl, CALENDAR_EVENT_GROUP);
- }
- $seturl->param('var', 'showuser');
- $content .= self::get_filter_controls_element($seturl, CALENDAR_EVENT_USER);
- }
- $content .= \html_writer::end_tag('ul');
-
- return $content;
- }
-
- /**
- * Return the representation day
- *
- * @param int $tstamp Timestamp in GMT
- * @param int|bool $now current Unix timestamp
- * @param bool $usecommonwords
- * @return string the formatted date/time
- */
- public static function get_day_representation($tstamp, $now = false, $usecommonwords = true) {
-
- static $shortformat;
- if (empty($shortformat)) {
- $shortformat = get_string('strftimedayshort');
- }
-
- if ($now === false) {
- $now = time();
- }
-
- // To have it in one place, if a change is needed.
- $formal = userdate($tstamp, $shortformat);
-
- $datestamp = usergetdate($tstamp);
- $datenow = usergetdate($now);
-
- if ($usecommonwords == false) {
- // We don't want words, just a date.
- return $formal;
- } else if ($datestamp['year'] == $datenow['year'] && $datestamp['yday'] == $datenow['yday']) {
- return get_string('today', 'calendar');
- } else if (($datestamp['year'] == $datenow['year'] && $datestamp['yday'] == $datenow['yday'] - 1 ) ||
- ($datestamp['year'] == $datenow['year'] - 1 && $datestamp['mday'] == 31 && $datestamp['mon'] == 12
- && $datenow['yday'] == 1)) {
- return get_string('yesterday', 'calendar');
- } else if (($datestamp['year'] == $datenow['year'] && $datestamp['yday'] == $datenow['yday'] + 1 ) ||
- ($datestamp['year'] == $datenow['year'] + 1 && $datenow['mday'] == 31 && $datenow['mon'] == 12
- && $datestamp['yday'] == 1)) {
- return get_string('tomorrow', 'calendar');
- } else {
- return $formal;
- }
- }
-
- /**
- * return the formatted representation time
- *
- * @param int $time the timestamp in UTC, as obtained from the database
- * @return string the formatted date/time
- */
- public static function get_time_representation($time) {
- static $langtimeformat = null;
-
- if ($langtimeformat === null) {
- $langtimeformat = get_string('strftimetime');
- }
-
- $timeformat = get_user_preferences('calendar_timeformat');
- if (empty($timeformat)) {
- $timeformat = get_config(null, 'calendar_site_timeformat');
- }
-
- return userdate($time, empty($timeformat) ? $langtimeformat : $timeformat);
- }
-
- /**
- * Adds day, month, year arguments to a URL and returns a moodle_url object.
- *
- * @param string|\moodle_url $linkbase
- * @param int $d The number of the day.
- * @param int $m The number of the month.
- * @param int $y The number of the year.
- * @param int $time the unixtime, used for multiple calendar support. The values $d,
- * $m and $y are kept for backwards compatibility.
- * @return \moodle_url|null $linkbase
- */
- public static function get_link_href($linkbase, $d, $m, $y, $time = 0) {
- if (empty($linkbase)) {
- return null;
- }
-
- if (!($linkbase instanceof \moodle_url)) {
- $linkbase = new \moodle_url($linkbase);
- }
-
- // If a day, month and year were passed then convert it to a timestamp. If these were passed
- // then we can assume the day, month and year are passed as Gregorian, as no where in core
- // should we be passing these values rather than the time.
- if (!empty($d) && !empty($m) && !empty($y)) {
- if (checkdate($m, $d, $y)) {
- $time = make_timestamp($y, $m, $d);
- } else {
- $time = time();
- }
- } else if (empty($time)) {
- $time = time();
- }
-
- $linkbase->param('time', $time);
-
- return $linkbase;
- }
-
- /**
- * Build and return a previous month HTML link, with an arrow.
- *
- * @param string $text The text label.
- * @param string|\moodle_url $linkbase The URL stub.
- * @param int $d The number of the date.
- * @param int $m The number of the month.
- * @param int $y year The number of the year.
- * @param bool $accesshide Default visible, or hide from all except screenreaders.
- * @param int $time the unixtime, used for multiple calendar support. The values $d,
- * $m and $y are kept for backwards compatibility.
- * @return string HTML string.
- */
- public static function get_link_previous($text, $linkbase, $d, $m, $y, $accesshide = false, $time = 0) {
- $href = self::get_link_href(new \moodle_url($linkbase), $d, $m, $y, $time);
-
- if (empty($href)) {
- return $text;
- }
-
- return link_arrow_left($text, (string)$href, $accesshide, 'previous');
- }
-
- /**
- * Build and return a next month HTML link, with an arrow.
- *
- * @param string $text The text label.
- * @param string|\moodle_url $linkbase The URL stub.
- * @param int $d the number of the Day
- * @param int $m The number of the month.
- * @param int $y The number of the year.
- * @param bool $accesshide Default visible, or hide from all except screenreaders.
- * @param int $time the unixtime, used for multiple calendar support. The values $d,
- * $m and $y are kept for backwards compatibility.
- * @return string HTML string.
- */
- public static function get_link_next($text, $linkbase, $d, $m, $y, $accesshide = false, $time = 0) {
- $href = self::get_link_href(new \moodle_url($linkbase), $d, $m, $y, $time);
-
- if (empty($href)) {
- return $text;
- }
-
- return link_arrow_right($text, (string)$href, $accesshide, 'next');
- }
-
- /**
- * Return the number of days in month
- *
- * @param int $month the number of the month.
- * @param int $year the number of the year
- * @return int
- */
- public static function get_days_in_month($month, $year) {
- $calendartype = type_factory::get_calendar_instance();
- return $calendartype->get_num_days_in_month($year, $month);
- }
-
- /**
- * Get the next following month
- *
- * @param int $month the number of the month.
- * @param int $year the number of the year.
- * @return array the following month
- */
- public static function get_next_month($month, $year) {
- $calendartype = type_factory::get_calendar_instance();
- return $calendartype->get_next_month($year, $month);
- }
-
- /**
- * Get the previous month.
- *
- * @param int $month the number of the month.
- * @param int $year the number of the year.
- * @return array previous month
- */
- public static function get_prev_month($month, $year) {
- $calendartype = type_factory::get_calendar_instance();
- return $calendartype->get_prev_month($year, $month);
- }
-
- /**
- * Get per-day basis events.
- *
- * @param array $events list of events
- * @param int $month the number of the month
- * @param int $year the number of the year
- * @param array $eventsbyday event on specific day
- * @param array $durationbyday duration of the event in days
- * @param array $typesbyday event type (eg: global, course, user, or group)
- * @param array $courses list of courses
- * @return void
- */
- public static function get_events_by_day($events, $month, $year, &$eventsbyday, &$durationbyday, &$typesbyday, &$courses) {
- $calendartype = type_factory::get_calendar_instance();
-
- $eventsbyday = array();
- $typesbyday = array();
- $durationbyday = array();
-
- if ($events === false) {
- return;
- }
-
- foreach ($events as $event) {
- $startdate = $calendartype->timestamp_to_date_array($event->timestart);
- if ($event->timeduration) {
- $enddate = $calendartype->timestamp_to_date_array($event->timestart + $event->timeduration - 1);
- } else {
- $enddate = $startdate;
- }
-
- // Simple arithmetic: $year * 13 + $month is a distinct integer for each distinct ($year, $month) pair.
- if (!($startdate['year'] * 13 + $startdate['mon'] <= $year * 13 + $month) &&
- ($enddate['year'] * 13 + $enddate['mon'] >= $year * 13 + $month)) {
- continue;
- }
-
- $eventdaystart = intval($startdate['mday']);
-
- if ($startdate['mon'] == $month && $startdate['year'] == $year) {
- // Give the event to its day.
- $eventsbyday[$eventdaystart][] = $event->id;
-
- // Mark the day as having such an event.
- if ($event->courseid == SITEID && $event->groupid == 0) {
- $typesbyday[$eventdaystart]['startglobal'] = true;
- // Set event class for global event.
- $events[$event->id]->class = 'calendar_event_global';
- } else if ($event->courseid != 0 && $event->courseid != SITEID && $event->groupid == 0) {
- $typesbyday[$eventdaystart]['startcourse'] = true;
- // Set event class for course event.
- $events[$event->id]->class = 'calendar_event_course';
- } else if ($event->groupid) {
- $typesbyday[$eventdaystart]['startgroup'] = true;
- // Set event class for group event.
- $events[$event->id]->class = 'calendar_event_group';
- } else if ($event->userid) {
- $typesbyday[$eventdaystart]['startuser'] = true;
- // Set event class for user event.
- $events[$event->id]->class = 'calendar_event_user';
- }
- }
-
- if ($event->timeduration == 0) {
- // Proceed with the next.
- continue;
- }
-
- // The event starts on $month $year or before.
- if ($startdate['mon'] == $month && $startdate['year'] == $year) {
- $lowerbound = intval($startdate['mday']);
- } else {
- $lowerbound = 0;
- }
-
- // Also, it ends on $month $year or later.
- if ($enddate['mon'] == $month && $enddate['year'] == $year) {
- $upperbound = intval($enddate['mday']);
- } else {
- $upperbound = self::get_days_in_month($month, $year);
- }
-
- // Mark all days between $lowerbound and $upperbound (inclusive) as duration.
- for ($i = $lowerbound + 1; $i <= $upperbound; ++$i) {
- $durationbyday[$i][] = $event->id;
- if ($event->courseid == SITEID && $event->groupid == 0) {
- $typesbyday[$i]['durationglobal'] = true;
- } else if ($event->courseid != 0 && $event->courseid != SITEID && $event->groupid == 0) {
- $typesbyday[$i]['durationcourse'] = true;
- } else if ($event->groupid) {
- $typesbyday[$i]['durationgroup'] = true;
- } else if ($event->userid) {
- $typesbyday[$i]['durationuser'] = true;
- }
- }
-
- }
- return;
- }
-
- /**
- * Returns the courses to load events for, the
- *
- * @param array $courseeventsfrom An array of courses to load calendar events for
- * @param bool $ignorefilters specify the use of filters, false is set as default
- * @return array An array of courses, groups, and user to load calendar events for based upon filters
- */
- public static function set_filters(array $courseeventsfrom, $ignorefilters = false) {
- global $USER, $CFG;
-
- // For backwards compatability we have to check whether the courses array contains
- // just id's in which case we need to load course objects.
- $coursestoload = array();
- foreach ($courseeventsfrom as $id => $something) {
- if (!is_object($something)) {
- $coursestoload[] = $id;
- unset($courseeventsfrom[$id]);
- }
- }
-
- $courses = array();
- $user = false;
- $group = false;
-
- // Get the capabilities that allow seeing group events from all groups.
- $allgroupscaps = array('moodle/site:accessallgroups', 'moodle/calendar:manageentries');
-
- $isloggedin = isloggedin();
-
- if ($ignorefilters || self::show_event_type(CALENDAR_EVENT_COURSE)) {
- $courses = array_keys($courseeventsfrom);
- }
- if ($ignorefilters || self::show_event_type(CALENDAR_EVENT_GLOBAL)) {
- $courses[] = SITEID;
- }
- $courses = array_unique($courses);
- sort($courses);
-
- if (!empty($courses) && in_array(SITEID, $courses)) {
- // Sort courses for consistent colour highlighting.
- // Effectively ignoring SITEID as setting as last course id.
- $key = array_search(SITEID, $courses);
- unset($courses[$key]);
- $courses[] = SITEID;
- }
-
- if ($ignorefilters || ($isloggedin && self::show_event_type(CALENDAR_EVENT_USER))) {
- $user = $USER->id;
- }
-
- if (!empty($courseeventsfrom) && (self::show_event_type(CALENDAR_EVENT_GROUP) || $ignorefilters)) {
-
- if (count($courseeventsfrom) == 1) {
- $course = reset($courseeventsfrom);
- if (has_any_capability($allgroupscaps, \context_course::instance($course->id))) {
- $coursegroups = groups_get_all_groups($course->id, 0, 0, 'g.id');
- $group = array_keys($coursegroups);
- }
- }
- if ($group === false) {
- if (!empty($CFG->calendar_adminseesall) && has_any_capability($allgroupscaps, \context_system::instance())) {
- $group = true;
- } else if ($isloggedin) {
- $groupids = array();
- foreach ($courseeventsfrom as $courseid => $course) {
- // If the user is an editing teacher in there.
- if (!empty($USER->groupmember[$course->id])) {
- // We've already cached the users groups for this course so we can just use that.
- $groupids = array_merge($groupids, $USER->groupmember[$course->id]);
- } else if ($course->groupmode != NOGROUPS || !$course->groupmodeforce) {
- // If this course has groups, show events from all of those related to the current user.
- $coursegroups = groups_get_user_groups($course->id, $USER->id);
- $groupids = array_merge($groupids, $coursegroups['0']);
- }
- }
- if (!empty($groupids)) {
- $group = $groupids;
- }
- }
- }
- }
- if (empty($courses)) {
- $courses = false;
- }
-
- return array($courses, $group, $user);
- }
-
- /**
- * Return the capability for editing calendar event
- *
- * @param \calendar_event $event event object
- * @return bool capability to edit event
- */
- public static function can_edit_event($event) {
- global $USER, $DB;
-
- // Must be logged in.
- if (!isloggedin()) {
- return false;
- }
-
- // Can not be using guest account.
- if (isguestuser()) {
- return false;
- }
-
- // You cannot edit calendar subscription events presently.
- if (!empty($event->subscriptionid)) {
- if (!empty($event->subscription->url)) {
- // This event can be updated externally, so it cannot be edited.
- return false;
- }
- }
-
- $sitecontext = \context_system::instance();
-
- // If user has manageentries at site level, return true.
- if (has_capability('moodle/calendar:manageentries', $sitecontext)) {
- return true;
- }
-
- // If groupid is set, it's definitely a group event.
- if (!empty($event->groupid)) {
- // Allow users to add/edit group events if -
- // 1) They have manageentries for the course OR
- // 2) They have managegroupentries AND are in the group.
- $group = $DB->get_record('groups', array('id' => $event->groupid));
- return $group && (
- has_capability('moodle/calendar:manageentries', $event->context) ||
- (has_capability('moodle/calendar:managegroupentries', $event->context)
- && groups_is_member($event->groupid)));
- } else if (!empty($event->courseid)) {
- // If groupid is not set, but course is set, it's definiely a course event.
- return has_capability('moodle/calendar:manageentries', $event->context);
- } else if (!empty($event->userid) && $event->userid == $USER->id) {
- // If course is not set, but userid id set, it's a user event.
- return (has_capability('moodle/calendar:manageownentries', $event->context));
- } else if (!empty($event->userid)) {
- return (has_capability('moodle/calendar:manageentries', $event->context));
- }
-
- return false;
- }
-
- /**
- * Returns the default courses to display on the calendar when there isn't a specific
- * course to display.
- *
- * @return array $courses Array of courses to display
- */
- public static function get_default_courses() {
- global $CFG, $DB;
-
- if (!isloggedin()) {
- return array();
- }
-
- if (!empty($CFG->calendar_adminseesall) && has_capability('moodle/calendar:manageentries', \context_system::instance())) {
- $select = ', ' . \context_helper::get_preload_record_columns_sql('ctx');
- $join = "LEFT JOIN {context} ctx ON (ctx.instanceid = c.id AND ctx.contextlevel = :contextlevel)";
- $sql = "SELECT c.* $select
- FROM {course} c
- $join
- WHERE EXISTS (SELECT 1 FROM {event} e WHERE e.courseid = c.id)
- ";
- $courses = $DB->get_records_sql($sql, array('contextlevel' => CONTEXT_COURSE), 0, 20);
- foreach ($courses as $course) {
- \context_helper::preload_from_record($course);
- }
- return $courses;
- }
-
- $courses = enrol_get_my_courses();
-
- return $courses;
- }
-
- /**
- * Get event format time
- *
- * @param \calendar_event $event event object
- * @param int $now current time in gmt
- * @param array $linkparams list of params for event link
- * @param bool $usecommonwords the words as formatted date/time.
- * @param int $showtime determine the show time GMT timestamp
- * @return string $eventtime link/string for event time
- */
- public static function get_format_event_time($event, $now, $linkparams = null, $usecommonwords = true, $showtime = 0) {
- $starttime = $event->timestart;
- $endtime = $event->timestart + $event->timeduration;
-
- if (empty($linkparams) || !is_array($linkparams)) {
- $linkparams = array();
- }
-
- $linkparams['view'] = 'day';
-
- // OK, now to get a meaningful display.
- // Check if there is a duration for this event.
- if ($event->timeduration) {
- // Get the midnight of the day the event will start.
- $usermidnightstart = usergetmidnight($starttime);
- // Get the midnight of the day the event will end.
- $usermidnightend = usergetmidnight($endtime);
- // Check if we will still be on the same day.
- if ($usermidnightstart == $usermidnightend) {
- // Check if we are running all day.
- if ($event->timeduration == DAYSECS) {
- $time = get_string('allday', 'calendar');
- } else { // Specify the time we will be running this from.
- $datestart = self::get_time_representation($starttime);
- $dateend = self::get_time_representation($endtime);
- $time = $datestart . ' <strong>»</strong> ' . $dateend;
- }
-
- // Set printable representation.
- if (!$showtime) {
- $day = self::get_day_representation($event->timestart, $now, $usecommonwords);
- $url = self::get_link_href(new \moodle_url(CALENDAR_URL . 'view.php', $linkparams), 0, 0, 0, $endtime);
- $eventtime = \html_writer::link($url, $day) . ', ' . $time;
- } else {
- $eventtime = $time;
- }
- } else { // It must spans two or more days.
- $daystart = self::get_day_representation($event->timestart, $now, $usecommonwords) . ', ';
- if ($showtime == $usermidnightstart) {
- $daystart = '';
- }
- $timestart = self::get_time_representation($event->timestart);
- $dayend = self::get_day_representation($event->timestart + $event->timeduration, $now, $usecommonwords) . ', ';
- if ($showtime == $usermidnightend) {
- $dayend = '';
- }
- $timeend = self::get_time_representation($event->timestart + $event->timeduration);
-
- // Set printable representation.
- if ($now >= $usermidnightstart && $now < strtotime('+1 day', $usermidnightstart)) {
- $url = self::get_link_href(new \moodle_url(CALENDAR_URL . 'view.php', $linkparams), 0, 0, 0, $endtime);
- $eventtime = $timestart . ' <strong>»</strong> ' . \html_writer::link($url, $dayend) . $timeend;
- } else {
- // The event is in the future, print start and end links.
- $url = self::get_link_href(new \moodle_url(CALENDAR_URL . 'view.php', $linkparams), 0, 0, 0, $starttime);
- $eventtime = \html_writer::link($url, $daystart) . $timestart . ' <strong>»</strong> ';
-
- $url = self::get_link_href(new \moodle_url(CALENDAR_URL . 'view.php', $linkparams), 0, 0, 0, $endtime);
- $eventtime .= \html_writer::link($url, $dayend) . $timeend;
- }
- }
- } else { // There is no time duration.
- $time = self::get_time_representation($event->timestart);
- // Set printable representation.
- if (!$showtime) {
- $day = self::get_day_representation($event->timestart, $now, $usecommonwords);
- $url = self::get_link_href(new \moodle_url(CALENDAR_URL . 'view.php', $linkparams), 0, 0, 0, $starttime);
- $eventtime = \html_writer::link($url, $day) . ', ' . trim($time);
- } else {
- $eventtime = $time;
- }
- }
-
- // Check if It has expired.
- if ($event->timestart + $event->timeduration < $now) {
- $eventtime = '<span class="dimmed_text">' . str_replace(' href=', ' class="dimmed" href=', $eventtime) . '</span>';
- }
-
- return $eventtime;
- }
-
- /**
- * Checks to see if the requested type of event should be shown for the given user.
- *
- * @param int $type The type to check the display for (default is to display all)
- * @param \stdClass|int|null $user The user to check for - by default the current user
- * @return bool True if the tyep should be displayed false otherwise
- */
- public static function show_event_type($type, $user = null) {
- $default = CALENDAR_EVENT_GLOBAL + CALENDAR_EVENT_COURSE + CALENDAR_EVENT_GROUP + CALENDAR_EVENT_USER;
-
- if (get_user_preferences('calendar_persistflt', 0, $user) === 0) {
- global $SESSION;
- if (!isset($SESSION->calendarshoweventtype)) {
- $SESSION->calendarshoweventtype = $default;
- }
- return $SESSION->calendarshoweventtype & $type;
- } else {
- return get_user_preferences('calendar_savedflt', $default, $user) & $type;
- }
- }
-
- /**
- * Sets the display of the event type given $display.
- *
- * If $display = true the event type will be shown.
- * If $display = false the event type will NOT be shown.
- * If $display = null the current value will be toggled and saved.
- *
- * @param int $type object of CALENDAR_EVENT_XXX
- * @param bool $display option to display event type
- * @param \stdClass|int $user moodle user object or id, null means current user
- */
- public static function set_event_type_display($type, $display = null, $user = null) {
- $persist = get_user_preferences('calendar_persistflt', 0, $user);
- $default = CALENDAR_EVENT_GLOBAL + CALENDAR_EVENT_COURSE + CALENDAR_EVENT_GROUP + CALENDAR_EVENT_USER;
- if ($persist === 0) {
- global $SESSION;
- if (!isset($SESSION->calendarshoweventtype)) {
- $SESSION->calendarshoweventtype = $default;
- }
- $preference = $SESSION->calendarshoweventtype;
- } else {
- $preference = get_user_preferences('calendar_savedflt', $default, $user);
- }
- $current = $preference & $type;
- if ($display === null) {
- $display = !$current;
- }
- if ($display && !$current) {
- $preference += $type;
- } else if (!$display && $current) {
- $preference -= $type;
- }
- if ($persist === 0) {
- $SESSION->calendarshoweventtype = $preference;
- } else {
- if ($preference == $default) {
- unset_user_preference('calendar_savedflt', $user);
- } else {
- set_user_preference('calendar_savedflt', $preference, $user);
- }
- }
- }
-
- /**
- * Get calendar's allowed types
- *
- * @param \stdClass $allowed list of allowed edit for event type
- * @param \stdClass|int $course object of a course or course id
- */
- public static function get_allowed_types(&$allowed, $course = null) {
- global $USER, $DB;
-
- $allowed = new \stdClass();
- $allowed->user = has_capability('moodle/calendar:manageownentries', \context_system::instance());
- $allowed->groups = false;
- $allowed->courses = false;
- $allowed->site = has_capability('moodle/calendar:manageentries', \context_course::instance(SITEID));
-
- if (!empty($course)) {
- if (!is_object($course)) {
- $course = $DB->get_record('course', array('id' => $course), '*', MUST_EXIST);
- }
- if ($course->id != SITEID) {
- $coursecontext = \context_course::instance($course->id);
- $allowed->user = has_capability('moodle/calendar:manageownentries', $coursecontext);
-
- if (has_capability('moodle/calendar:manageentries', $coursecontext)) {
- $allowed->courses = array($course->id => 1);
-
- if ($course->groupmode != NOGROUPS || !$course->groupmodeforce) {
- if (has_capability('moodle/site:accessallgroups', $coursecontext)) {
- $allowed->groups = groups_get_all_groups($course->id);
- } else {
- $allowed->groups = groups_get_all_groups($course->id, $USER->id);
- }
- }
- } else if (has_capability('moodle/calendar:managegroupentries', $coursecontext)) {
- if ($course->groupmode != NOGROUPS || !$course->groupmodeforce) {
- if (has_capability('moodle/site:accessallgroups', $coursecontext)) {
- $allowed->groups = groups_get_all_groups($course->id);
- } else {
- $allowed->groups = groups_get_all_groups($course->id, $USER->id);
- }
- }
- }
- }
- }
- }
-
- /**
- * See if user can add calendar entries at all
- * used to print the "New Event" button
- *
- * @param \stdClass $course object of a course or course id
- * @return bool has the capability to add at least one event type
- */
- public static function can_add_event_to_course($course) {
- if (!isloggedin() || isguestuser()) {
- return false;
- }
-
- self::get_allowed_types($allowed, $course);
-
- return (bool)($allowed->user || $allowed->groups || $allowed->courses || $allowed->site);
- }
-
- /**
- * Check wether the current user is permitted to add events
- *
- * @param \stdClass $event object of event
- * @return bool has the capability to add event
- */
- public static function can_add_event($event) {
- global $USER, $DB;
-
- // Can not be using guest account.
- if (!isloggedin() or isguestuser()) {
- return false;
- }
-
- $sitecontext = \context_system::instance();
-
- // If user has manageentries at site level, always return true.
- if (has_capability('moodle/calendar:manageentries', $sitecontext)) {
- return true;
- }
-
- switch ($event->eventtype) {
- case 'course':
- return has_capability('moodle/calendar:manageentries', $event->context);
- case 'group':
- // Allow users to add/edit group events if -
- // 1) They have manageentries (= entries for whole course).
- // 2) They have managegroupentries AND are in the group.
- $group = $DB->get_record('groups', array('id' => $event->groupid));
- return $group && (
- has_capability('moodle/calendar:manageentries', $event->context) ||
- (has_capability('moodle/calendar:managegroupentries', $event->context)
- && groups_is_member($event->groupid)));
- case 'user':
- if ($event->userid == $USER->id) {
- return (has_capability('moodle/calendar:manageownentries', $event->context));
- }
- // There is intentionally no 'break'.
- case 'site':
- return has_capability('moodle/calendar:manageentries', $event->context);
- default:
- return has_capability('moodle/calendar:manageentries', $event->context);
- }
- }
-
- /**
- * Returns option list for the poll interval setting.
- *
- * @return array An array of poll interval options. Interval => description.
- */
- public static function get_poll_interval_choices() {
- return array(
- '0' => new \lang_string('never', 'calendar'),
- HOURSECS => new \lang_string('hourly', 'calendar'),
- DAYSECS => new \lang_string('daily', 'calendar'),
- WEEKSECS => new \lang_string('weekly', 'calendar'),
- '2628000' => new \lang_string('monthly', 'calendar'),
- YEARSECS => new \lang_string('annually', 'calendar')
- );
- }
-
- /**
- * Returns option list of available options for the calendar event type, given the current user and course.
- *
- * @param int $courseid The id of the course
- * @return array An array containing the event types the user can create.
- */
- public static function get_event_type_choices($courseid) {
- $choices = array();
- $allowed = new \stdClass;
- self::get_allowed_types($allowed, $courseid);
-
- if ($allowed->user) {
- $choices['user'] = get_string('userevents', 'calendar');
- }
- if ($allowed->site) {
- $choices['site'] = get_string('siteevents', 'calendar');
- }
- if (!empty($allowed->courses)) {
- $choices['course'] = get_string('courseevents', 'calendar');
- }
- if (!empty($allowed->groups) and is_array($allowed->groups)) {
- $choices['group'] = get_string('group');
- }
-
- return array($choices, $allowed->groups);
- }
-
- /**
- * Add an iCalendar subscription to the database.
- *
- * @param \stdClass $sub The subscription object (e.g. from the form)
- * @return int The insert ID, if any.
- */
- public static function add_subscription($sub) {
- global $DB, $USER, $SITE;
-
- if ($sub->eventtype === 'site') {
- $sub->courseid = $SITE->id;
- } else if ($sub->eventtype === 'group' || $sub->eventtype === 'course') {
- $sub->courseid = $sub->course;
- } else {
- // User events.
- $sub->courseid = 0;
- }
- $sub->userid = $USER->id;
-
- // File subscriptions never update.
- if (empty($sub->url)) {
- $sub->pollinterval = 0;
- }
-
- if (!empty($sub->name)) {
- if (empty($sub->id)) {
- $id = $DB->insert_record('event_subscriptions', $sub);
- // We cannot cache the data here because $sub is not complete.
- $sub->id = $id;
- // Trigger event, calendar subscription added.
- $eventparams = array('objectid' => $sub->id,
- 'context' => self::get_calendar_context($sub),
- 'other' => array('eventtype' => $sub->eventtype, 'courseid' => $sub->courseid)
- );
- $event = \core\event\calendar_subscription_created::create($eventparams);
- $event->trigger();
- return $id;
- } else {
- // Why are we doing an update here?
- self::update_subscription($sub);
- return $sub->id;
- }
- } else {
- print_error('errorbadsubscription', 'importcalendar');
- }
- }
-
- /**
- * Add an iCalendar event to the Moodle calendar.
- *
- * @param \stdClass $event The RFC-2445 iCalendar event
- * @param int $courseid The course ID
- * @param int $subscriptionid The iCalendar subscription ID
- * @param string $timezone The X-WR-TIMEZONE iCalendar property if provided
- * @return int Code: CALENDAR_IMPORT_EVENT_UPDATED = updated, CALENDAR_IMPORT_EVENT_INSERTED = inserted, 0 = error
- */
- public static function add_icalendar_event($event, $courseid, $subscriptionid, $timezone='UTC') {
- global $DB;
-
- // Probably an unsupported X-MICROSOFT-CDO-BUSYSTATUS event.
- if (empty($event->properties['SUMMARY'])) {
- return 0;
- }
-
- $name = $event->properties['SUMMARY'][0]->value;
- $name = str_replace('\n', '<br />', $name);
- $name = str_replace('\\', '', $name);
- $name = preg_replace('/\s+/u', ' ', $name);
-
- $eventrecord = new \stdClass;
- $eventrecord->name = clean_param($name, PARAM_NOTAGS);
-
- if (empty($event->properties['DESCRIPTION'][0]->value)) {
- $description = '';
- } else {
- $description = $event->properties['DESCRIPTION'][0]->value;
- $description = clean_param($description, PARAM_NOTAGS);
- $description = str_replace('\n', '<br />', $description);
- $description = str_replace('\\', '', $description);
- $description = preg_replace('/\s+/u', ' ', $description);
- }
- $eventrecord->description = $description;
-
- // Probably a repeating event with RRULE etc. TODO: skip for now.
- if (empty($event->properties['DTSTART'][0]->value)) {
- return 0;
- }
-
- if (isset($event->properties['DTSTART'][0]->parameters['TZID'])) {
- $tz = $event->properties['DTSTART'][0]->parameters['TZID'];
- } else {
- $tz = $timezone;
- }
- $tz = \core_date::normalise_timezone($tz);
- $eventrecord->timestart = strtotime($event->properties['DTSTART'][0]->value . ' ' . $tz);
- if (empty($event->properties['DTEND'])) {
- $eventrecord->timeduration = 0; // No duration if no end time specified.
- } else {
- if (isset($event->properties['DTEND'][0]->parameters['TZID'])) {
- $endtz = $event->properties['DTEND'][0]->parameters['TZID'];
- } else {
- $endtz = $timezone;
- }
- $endtz = \core_date::normalise_timezone($endtz);
- $eventrecord->timeduration = strtotime($event->properties['DTEND'][0]->value . ' ' . $endtz) - $eventrecord->timestart;
- }
-
- // Check to see if it should be treated as an all day event.
- if ($eventrecord->timeduration == DAYSECS) {
- // Check to see if the event started at Midnight on the imported calendar.
- date_default_timezone_set($timezone);
- if (date('H:i:s', $eventrecord->timestart) === "00:00:00") {
- // This event should be an all day event.
- $eventrecord->timeduration = 0;
- }
- \core_date::set_default_server_timezone();
- }
-
- $eventrecord->uuid = $event->properties['UID'][0]->value;
- $eventrecord->timemodified = time();
-
- // Add the iCal subscription details if required.
- // We should never do anything with an event without a subscription reference.
- $sub = self::get_subscription($subscriptionid);
- $eventrecord->subscriptionid = $subscriptionid;
- $eventrecord->userid = $sub->userid;
- $eventrecord->groupid = $sub->groupid;
- $eventrecord->courseid = $sub->courseid;
- $eventrecord->eventtype = $sub->eventtype;
-
- if ($updaterecord = $DB->get_record('event', array('uuid' => $eventrecord->uuid,
- 'subscriptionid' => $eventrecord->subscriptionid))) {
- $eventrecord->id = $updaterecord->id;
- $return = CALENDAR_IMPORT_EVENT_UPDATED; // Update.
- } else {
- $return = CALENDAR_IMPORT_EVENT_INSERTED; // Insert.
- }
- if ($createdevent = \calendar_event::create($eventrecord, false)) {
- if (!empty($event->properties['RRULE'])) {
- // Repeating events.
- date_default_timezone_set($tz); // Change time zone to parse all events.
- $rrule = new rrule_manager($event->properties['RRULE'][0]->value);
- $rrule->parse_rrule();
- $rrule->create_events($createdevent);
- \core_date::set_default_server_timezone(); // Change time zone back to what it was.
- }
- return $return;
- } else {
- return 0;
- }
- }
-
- /**
- * Update a subscription from the form data in one of the rows in the existing subscriptions table.
- *
- * @param int $subscriptionid The ID of the subscription we are acting upon.
- * @param int $pollinterval The poll interval to use.
- * @param int $action The action to be performed. One of update or remove.
- * @return string A log of the import progress, including errors
- */
- public static function process_subscription_row($subscriptionid, $pollinterval, $action) {
- // Fetch the subscription from the database making sure it exists.
- $sub = self::get_subscription($subscriptionid);
-
- // Update or remove the subscription, based on action.
- switch ($action) {
- case CALENDAR_SUBSCRIPTION_UPDATE:
- // Skip updating file subscriptions.
- if (empty($sub->url)) {
- break;
- }
- $sub->pollinterval = $pollinterval;
- self::update_subscription($sub);
-
- // Update the events.
- return "<p>" . get_string('subscriptionupdated', 'calendar', $sub->name) . "</p>" .
- self::update_subscription_events($subscriptionid);
- case CALENDAR_SUBSCRIPTION_REMOVE:
- self::delete_subscription($subscriptionid);
- return get_string('subscriptionremoved', 'calendar', $sub->name);
- break;
- default:
- break;
- }
- return '';
- }
-
- /**
- * Delete subscription and all related events.
- *
- * @param int|\stdClass $subscription subscription or it's id, which needs to be deleted.
- */
- public static function delete_subscription($subscription) {
- global $DB;
-
- if (!is_object($subscription)) {
- $subscription = $DB->get_record('event_subscriptions', array('id' => $subscription), '*', MUST_EXIST);
- }
-
- // Delete subscription and related events.
- $DB->delete_records('event', array('subscriptionid' => $subscription->id));
- $DB->delete_records('event_subscriptions', array('id' => $subscription->id));
- \cache_helper::invalidate_by_definition('core', 'calendar_subscriptions', array(), array($subscription->id));
-
- // Trigger event, calendar subscription deleted.
- $eventparams = array('objectid' => $subscription->id,
- 'context' => self::get_calendar_context($subscription),
- 'other' => array('courseid' => $subscription->courseid)
- );
- $event = \core\event\calendar_subscription_deleted::create($eventparams);
- $event->trigger();
- }
-
- /**
- * From a URL, fetch the calendar and return an iCalendar object.
- *
- * @param string $url The iCalendar URL
- * @return \iCalendar The iCalendar object
- * @throws \moodle_exception
- */
- public static function get_icalendar($url) {
- global $CFG;
-
- require_once($CFG->libdir . '/filelib.php');
-
- $curl = new \curl();
- $curl->setopt(array('CURLOPT_FOLLOWLOCATION' => 1, 'CURLOPT_MAXREDIRS' => 5));
- $calendar = $curl->get($url);
-
- // Http code validation should actually be the job of curl class.
- if (!$calendar || $curl->info['http_code'] != 200 || !empty($curl->errorno)) {
- throw new \moodle_exception('errorinvalidicalurl', 'calendar');
- }
-
- $ical = new \iCalendar();
- $ical->unserialize($calendar);
-
- return $ical;
- }
-
- /**
- * Import events from an iCalendar object into a course calendar.
- *
- * @param \iCalendar $ical The iCalendar object.
- * @param int $courseid The course ID for the calendar.
- * @param int $subscriptionid The subscription ID.
- * @return string A log of the import progress, including errors.
- */
- public static function import_icalendar_events($ical, $courseid, $subscriptionid = null) {
- global $DB;
-
- $return = '';
- $eventcount = 0;
- $updatecount = 0;
-
- // Large calendars take a while...
- if (!CLI_SCRIPT) {
- \core_php_time_limit::raise(300);
- }
-
- // Mark all events in a subscription with a zero timestamp.
- if (!empty($subscriptionid)) {
- $sql = "UPDATE {event} SET timemodified = :time WHERE subscriptionid = :id";
- $DB->execute($sql, array('time' => 0, 'id' => $subscriptionid));
- }
-
- // Grab the timezone from the iCalendar file to be used later.
- if (isset($ical->properties['X-WR-TIMEZONE'][0]->value)) {
- $timezone = $ical->properties['X-WR-TIMEZONE'][0]->value;
- } else {
- $timezone = 'UTC';
- }
-
- $return = '';
- foreach ($ical->components['VEVENT'] as $event) {
- $res = self::add_icalendar_event($event, $courseid, $subscriptionid, $timezone);
- switch ($res) {
- case CALENDAR_IMPORT_EVENT_UPDATED:
- $updatecount++;
- break;
- case CALENDAR_IMPORT_EVENT_INSERTED:
- $eventcount++;
- break;
- case 0:
- $return .= '<p>' . get_string('erroraddingevent', 'calendar') . ': ';
- if (empty($event->properties['SUMMARY'])) {
- $return .= '(' . get_string('notitle', 'calendar') . ')';
- } else {
- $return .= $event->properties['SUMMARY'][0]->value;
- }
- $return .= "</p>\n";
- break;
- }
- }
-
- $return .= "<p>" . get_string('eventsimported', 'calendar', $eventcount) . "</p> ";
- $return .= "<p>" . get_string('eventsupdated', 'calendar', $updatecount) . "</p>";
-
- // Delete remaining zero-marked events since they're not in remote calendar.
- if (!empty($subscriptionid)) {
- $deletecount = $DB->count_records('event', array('timemodified' => 0, 'subscriptionid' => $subscriptionid));
- if (!empty($deletecount)) {
- $DB->delete_records('event', array('timemodified' => 0, 'subscriptionid' => $subscriptionid));
- $return .= "<p> " . get_string('eventsdeleted', 'calendar') . ": {$deletecount} </p>\n";
- }
- }
-
- return $return;
- }
-
- /**
- * Fetch a calendar subscription and update the events in the calendar.
- *
- * @param int $subscriptionid The course ID for the calendar.
- * @return string A log of the import progress, including errors.
- */
- public static function update_subscription_events($subscriptionid) {
- $sub = self::get_subscription($subscriptionid);
-
- // Don't update a file subscription.
- if (empty($sub->url)) {
- return 'File subscription not updated.';
- }
-
- $ical = self::get_icalendar($sub->url);
- $return = self::import_icalendar_events($ical, $sub->courseid, $subscriptionid);
- $sub->lastupdated = time();
-
- self::update_subscription($sub);
-
- return $return;
- }
-
- /**
- * Update a calendar subscription. Also updates the associated cache.
- *
- * @param \stdClass|array $subscription Subscription record.
- * @throws \coding_exception If something goes wrong
- */
- public static function update_subscription($subscription) {
- global $DB;
-
- if (is_array($subscription)) {
- $subscription = (object)$subscription;
- }
- if (empty($subscription->id) || !$DB->record_exists('event_subscriptions', array('id' => $subscription->id))) {
- throw new \coding_exception('Cannot update a subscription without a valid id');
- }
-
- $DB->update_record('event_subscriptions', $subscription);
-
- // Update cache.
- $cache = \cache::make('core', 'calendar_subscriptions');
- $cache->set($subscription->id, $subscription);
-
- // Trigger event, calendar subscription updated.
- $eventparams = array('userid' => $subscription->userid,
- 'objectid' => $subscription->id,
- 'context' => self::get_calendar_context($subscription),
- 'other' => array('eventtype' => $subscription->eventtype, 'courseid' => $subscription->courseid)
- );
- $event = \core\event\calendar_subscription_updated::create($eventparams);
- $event->trigger();
- }
-
- /**
- * Checks to see if the user can edit a given subscription feed.
- *
- * @param mixed $subscriptionorid Subscription object or id
- * @return bool true if current user can edit the subscription else false
- */
- public static function can_edit_subscription($subscriptionorid) {
- if (is_array($subscriptionorid)) {
- $subscription = (object)$subscriptionorid;
- } else if (is_object($subscriptionorid)) {
- $subscription = $subscriptionorid;
- } else {
- $subscription = self::get_subscription($subscriptionorid);
- }
-
- $allowed = new \stdClass;
- $courseid = $subscription->courseid;
- $groupid = $subscription->groupid;
-
- self::get_allowed_types($allowed, $courseid);
- switch ($subscription->eventtype) {
- case 'user':
- return $allowed->user;
- case 'course':
- if (isset($allowed->courses[$courseid])) {
- return $allowed->courses[$courseid];
- } else {
- return false;
- }
- case 'site':
- return $allowed->site;
- case 'group':
- if (isset($allowed->groups[$groupid])) {
- return $allowed->groups[$groupid];
- } else {
- return false;
- }
- default:
- return false;
- }
- }
-
- /**
- * Helper function to determine the context of a calendar subscription.
- * Subscriptions can be created in two contexts COURSE, or USER.
- *
- * @param \stdClass $subscription
- * @return \context instance
- */
- public static function get_calendar_context($subscription) {
- // Determine context based on calendar type.
- if ($subscription->eventtype === 'site') {
- $context = \context_course::instance(SITEID);
- } else if ($subscription->eventtype === 'group' || $subscription->eventtype === 'course') {
- $context = \context_course::instance($subscription->courseid);
- } else {
- $context = \context_user::instance($subscription->userid);
- }
- return $context;
- }
-
/**
* Get a list of action events for the logged in user by the given
* timesort values.
}
$course = new std_proxy($dbrow->courseid, function($id) {
- return \core_calendar\api::get_course_cached($this->coursecachereference, $id);
+ return calendar_get_course_cached($this->coursecachereference, $id);
});
if ($dbrow->groupid) {
$group = new std_proxy($dbrow->groupid, function($id) {
- return \core_calendar\api::get_group_cached($id);
+ return calendar_get_group_cached($id);
});
}
$dbrow->modulename,
$dbrow->instance,
function($modulename, $instance) {
- return \core_calendar\api::get_module_cached(
+ return calendar_get_module_cached(
$this->modulecachereference,
$modulename,
$instance
if ($dbrow->subscriptionid) {
$subscription = new std_proxy($dbrow->subscriptionid, function($id) {
- return \core_calendar\api::get_subscription($id);
+ return calendar_get_subscription($id);
});
}
$subqueryconditions = [];
// Get the user's courses. Otherwise, get the default courses being shown by the calendar.
- $usercourses = \core_calendar\api::get_default_courses();
+ $usercourses = calendar_get_default_courses();
// Set calendar filters.
- list($usercourses, $usergroups, $user) = \core_calendar\api::set_filters($usercourses, true);
+ list($usercourses, $usergroups, $user) = calendar_set_filters($usercourses, true);
$subqueryparams = [];
// Flag to indicate whether the query needs to exclude group overrides.
}
// Check the user has the required capabilities to edit an event
-if (!\core_calendar\api::can_edit_event($event)) {
+if (!calendar_edit_event_allowed($event)) {
print_error('nopermissions');
}
$issite = false;
} else {
$course = get_site();
- $courses = \core_calendar\api::get_default_courses();
+ $courses = calendar_get_default_courses();
$issite = true;
}
require_login($course, false);
if ($eventid !== 0) {
$title = get_string('editevent', 'calendar');
$event = calendar_event::load($eventid);
- if (!\core_calendar\api::can_edit_event($event)) {
+ if (!calendar_edit_event_allowed($event)) {
print_error('nopermissions');
}
$event->action = $action;
$event->timedurationuntil = $event->timestart + $event->timeduration;
$event->count_repeats();
- if (!\core_calendar\api::can_add_event($event)) {
+ if (!calendar_add_event_allowed($event)) {
print_error('nopermissions');
}
} else {
$title = get_string('newevent', 'calendar');
- \core_calendar\api::get_allowed_types($formoptions->eventtypes, $course);
+ calendar_get_allowed_types($formoptions->eventtypes, $course);
$event = new stdClass();
$event->action = $action;
$event->course = $courseid;
}
$event->timestart = $time;
$event = new calendar_event($event);
- if (!\core_calendar\api::can_add_event($event)) {
+ if (!calendar_add_event_allowed($event)) {
print_error('nopermissions');
}
}
$issite = false;
} else {
$course = get_site();
- $courses = \core_calendar\api::get_default_courses();
+ $courses = calendar_get_default_courses();
$issite = true;
}
require_course_login($course);
$PAGE->navbar->add($course->shortname, new moodle_url('/course/view.php', array('id'=>$course->id)));
}
$link = new moodle_url(CALENDAR_URL.'view.php', array('view'=>'upcoming', 'course'=>$calendar->courseid));
-$PAGE->navbar->add(get_string('calendar', 'calendar'), \core_calendar\api::get_link_href($link, 0, 0, 0, $time));
+$PAGE->navbar->add(get_string('calendar', 'calendar'), calendar_get_link_href($link, 0, 0, 0, $time));
$PAGE->navbar->add($pagetitle);
$PAGE->set_title($course->shortname.': '.get_string('calendar', 'calendar').': '.$pagetitle);
// If today it's weekend, give the "next week" option.
'allownextweek' => $weekend & (1 << $now['wday']),
// If it's the last week of the month, give the "next month" option.
- 'allownextmonth' => \core_calendar\api::get_days_in_month($now['mon'], $now['year']) - $now['mday'] < $numberofdaysinweek,
+ 'allownextmonth' => calendar_days_in_month($now['mon'], $now['year']) - $now['mday'] < $numberofdaysinweek,
// If today it's weekend but tomorrow it isn't, do NOT give the "this week" option.
'allowthisweek' => !(($weekend & (1 << $now['wday'])) && !($weekend & (1 << (($now['wday'] + 1) % $numberofdaysinweek))))
);
if(!empty($what) && !empty($time)) {
if(in_array($what, $allowed_what) && in_array($time, $allowed_time)) {
$courses = enrol_get_users_courses($user->id, true, 'id, visible, shortname');
- // Array of courses that we will pass to \core_calendar\api::get_events() which
+ // Array of courses that we will pass to calendar_get_events() which
// is initially set to the list of the user's courses.
$paramcourses = $courses;
if ($what == 'all' || $what == 'groups') {
switch($time) {
case 'weeknow':
- $startweekday = \core_calendar\api::get_starting_weekday();
+ $startweekday = calendar_get_starting_weekday();
$startmonthday = find_day_in_month($now['mday'] - ($numberofdaysinweek - 1), $startweekday, $now['mon'], $now['year']);
$startmonth = $now['mon'];
$startyear = $now['year'];
- if ($startmonthday > \core_calendar\api::get_days_in_month($startmonth, $startyear)) {
- list($startmonth, $startyear) = \core_calendar\api::get_next_month($startmonth, $startyear);
+ if ($startmonthday > calendar_days_in_month($startmonth, $startyear)) {
+ list($startmonth, $startyear) = calendar_add_month($startmonth, $startyear);
$startmonthday = find_day_in_month(1, $startweekday, $startmonth, $startyear);
}
$gregoriandate = $calendartype->convert_to_gregorian($startyear, $startmonth, $startmonthday);
$endmonthday = $startmonthday + $numberofdaysinweek;
$endmonth = $startmonth;
$endyear = $startyear;
- if ($endmonthday > \core_calendar\api::get_days_in_month($endmonth, $endyear)) {
- list($endmonth, $endyear) = \core_calendar\api::get_next_month($endmonth, $endyear);
+ if ($endmonthday > calendar_days_in_month($endmonth, $endyear)) {
+ list($endmonth, $endyear) = calendar_add_month($endmonth, $endyear);
$endmonthday = find_day_in_month(1, $startweekday, $endmonth, $endyear);
}
$gregoriandate = $calendartype->convert_to_gregorian($endyear, $endmonth, $endmonthday);
$gregoriandate['hour'], $gregoriandate['minute']);
break;
case 'weeknext':
- $startweekday = \core_calendar\api::get_starting_weekday();
+ $startweekday = calendar_get_starting_weekday();
$startmonthday = find_day_in_month($now['mday'] + 1, $startweekday, $now['mon'], $now['year']);
$startmonth = $now['mon'];
$startyear = $now['year'];
- if ($startmonthday > \core_calendar\api::get_days_in_month($startmonth, $startyear)) {
- list($startmonth, $startyear) = \core_calendar\api::get_next_month($startmonth, $startyear);
+ if ($startmonthday > calendar_days_in_month($startmonth, $startyear)) {
+ list($startmonth, $startyear) = calendar_add_month($startmonth, $startyear);
$startmonthday = find_day_in_month(1, $startweekday, $startmonth, $startyear);
}
$gregoriandate = $calendartype->convert_to_gregorian($startyear, $startmonth, $startmonthday);
$endmonthday = $startmonthday + $numberofdaysinweek;
$endmonth = $startmonth;
$endyear = $startyear;
- if ($endmonthday > \core_calendar\api::get_days_in_month($endmonth, $endyear)) {
- list($endmonth, $endyear) = \core_calendar\api::get_next_month($endmonth, $endyear);
+ if ($endmonthday > calendar_days_in_month($endmonth, $endyear)) {
+ list($endmonth, $endyear) = calendar_add_month($endmonth, $endyear);
$endmonthday = find_day_in_month(1, $startweekday, $endmonth, $endyear);
}
$gregoriandate = $calendartype->convert_to_gregorian($endyear, $endmonth, $endmonthday);
$timestart = make_timestamp($gregoriandate['year'], $gregoriandate['month'], $gregoriandate['day'],
$gregoriandate['hour'], $gregoriandate['minute']);
- $timeend = $timestart + (\core_calendar\api::get_days_in_month($now['mon'], $now['year']) * DAYSECS);
+ $timeend = $timestart + (calendar_days_in_month($now['mon'], $now['year']) * DAYSECS);
break;
case 'monthnext':
// Get the next month for this calendar.
- list($nextmonth, $nextyear) = \core_calendar\api::get_next_month($now['mon'], $now['year']);
+ list($nextmonth, $nextyear) = calendar_add_month($now['mon'], $now['year']);
// Convert to gregorian.
$gregoriandate = $calendartype->convert_to_gregorian($nextyear, $nextmonth, 1);
// Create the timestamps.
$timestart = make_timestamp($gregoriandate['year'], $gregoriandate['month'], $gregoriandate['day'],
$gregoriandate['hour'], $gregoriandate['minute']);
- $timeend = $timestart + (\core_calendar\api::get_days_in_month($nextmonth, $nextyear) * DAYSECS);
+ $timeend = $timestart + (calendar_days_in_month($nextmonth, $nextyear) * DAYSECS);
break;
case 'recentupcoming':
//Events in the last 5 or next 60 days
die();
}
}
-$events = \core_calendar\api::get_events($timestart, $timeend, $users, $groups, array_keys($paramcourses), false);
+$events = calendar_get_events($timestart, $timeend, $users, $groups, array_keys($paramcourses), false);
$ical = new iCalendar;
$ical->add_property('method', 'PUBLISH');
$eventobj = calendar_event::load($event['eventid']);
// Let's check if the user is allowed to delete an event.
- if (!\core_calendar\api::can_edit_event($eventobj)) {
+ if (!calendar_edit_event_allowed($eventobj)) {
throw new moodle_exception("nopermissions");
}
// Time to do the magic.
}
// Event list does not check visibility and permissions, we'll check that later.
- $eventlist = \core_calendar\api::get_events($params['options']['timestart'], $params['options']['timeend'],
+ $eventlist = calendar_get_events($params['options']['timestart'], $params['options']['timeend'],
$funcparam['users'], $funcparam['groups'], $funcparam['courses'], true, $params['options']['ignorehidden']);
// WS expects arrays.
$events = array();
// We need to get events asked for eventids.
- if ($eventsbyid = \core_calendar\api::get_events_by_id($params['events']['eventids'])) {
+ if ($eventsbyid = calendar_get_events_by_id($params['events']['eventids'])) {
$eventlist += $eventsbyid;
}
(!empty($eventobj->groupid) && in_array($eventobj->groupid, $groups)) ||
(!empty($eventobj->courseid) && in_array($eventobj->courseid, $courses)) ||
($USER->id == $eventobj->userid) ||
- (\core_calendar\api::can_edit_event($eventid))) {
+ (calendar_edit_event_allowed($eventid))) {
$events[$eventid] = $event;
} else {
$warnings[] = array('item' => $eventid, 'warningcode' => 'nopermissions', 'message' => 'you do not have permissions to view this event');
$eventobj = new calendar_event($event);
// Let's check if the user is allowed to delete an event.
- if (!\core_calendar\api::can_add_event($eventobj)) {
+ if (!calendar_add_event_allowed($eventobj)) {
$warnings [] = array('item' => $event['name'], 'warningcode' => 'nopermissions', 'message' => 'you do not have permissions to create this event');
continue;
}
}
if (!empty($data->subscriptionid)) {
- $data->subscription = \core_calendar\api::get_subscription($data->subscriptionid);
+ $data->subscription = calendar_get_subscription($data->subscriptionid);
}
// Default to a user event.
if (empty($this->properties->id) || $this->properties->id < 1) {
if ($checkcapability) {
- if (!\core_calendar\api::can_add_event($this->properties)) {
+ if (!calendar_add_event_allowed($this->properties)) {
print_error('nopermissiontoupdatecalendar');
}
}
} else {
if ($checkcapability) {
- if (!\core_calendar\api::can_edit_event($this->properties)) {
+ if (!calendar_edit_event_allowed($this->properties)) {
print_error('nopermissiontoupdatecalendar');
}
}
public function prepare_for_view(stdClass $course, array $coursestoload, $ignorefilters = false) {
$this->courseid = $course->id;
$this->course = $course;
- list($courses, $group, $user) = \core_calendar\api::set_filters($coursestoload, $ignorefilters);
+ list($courses, $group, $user) = calendar_set_filters($coursestoload, $ignorefilters);
$this->courses = $courses;
$this->groups = $group;
$this->users = $user;
$subqueryconditions = [];
// Get the user's courses. Otherwise, get the default courses being shown by the calendar.
- $usercourses = \core_calendar\api::get_default_courses();
+ $usercourses = calendar_get_default_courses();
// Set calendar filters.
- list($usercourses, $usergroups, $user) = \core_calendar\api::set_filters($usercourses, true);
+ list($usercourses, $usergroups, $user) = calendar_set_filters($usercourses, true);
$subqueryparams = [];
// Flag to indicate whether the query needs to exclude group overrides.
* @return array array of days
*/
function calendar_get_days() {
- return \core_calendar\api::get_days();
+ $calendartype = \core_calendar\type_factory::get_calendar_instance();
+ return $calendartype->get_weekdays();
}
/**
* @throws moodle_exception for an invalid id
*/
function calendar_get_subscription($id) {
- return \core_calendar\api::get_subscription($id);
+ global $DB;
+
+ $cache = \cache::make('core', 'calendar_subscriptions');
+ $subscription = $cache->get($id);
+ if (empty($subscription)) {
+ $subscription = $DB->get_record('event_subscriptions', array('id' => $id), '*', MUST_EXIST);
+ $cache->set($id, $subscription);
+ }
+
+ return $subscription;
}
/**
* @return int
*/
function calendar_get_starting_weekday() {
- return \core_calendar\api::get_starting_weekday();
+ $calendartype = \core_calendar\type_factory::get_calendar_instance();
+ return $calendartype->get_starting_weekday();
}
/**
*/
function calendar_get_mini($courses, $groups, $users, $calmonth = false, $calyear = false, $placement = false,
$courseid = false, $time = 0) {
- return \core_calendar\api::get_mini_calendar($courses, $groups, $users, $calmonth, $calyear, $placement,
- $courseid, $time);
+ global $CFG, $OUTPUT;
+
+ // Get the calendar type we are using.
+ $calendartype = \core_calendar\type_factory::get_calendar_instance();
+
+ $display = new \stdClass;
+
+ // Assume we are not displaying this month for now.
+ $display->thismonth = false;
+
+ $content = '';
+
+ // Do this check for backwards compatibility.
+ // The core should be passing a timestamp rather than month and year.
+ // If a month and year are passed they will be in Gregorian.
+ if (!empty($calmonth) && !empty($calyear)) {
+ // Ensure it is a valid date, else we will just set it to the current timestamp.
+ if (checkdate($calmonth, 1, $calyear)) {
+ $time = make_timestamp($calyear, $calmonth, 1);
+ } else {
+ $time = time();
+ }
+ $date = usergetdate($time);
+ if ($calmonth == $date['mon'] && $calyear == $date['year']) {
+ $display->thismonth = true;
+ }
+ // We can overwrite date now with the date used by the calendar type,
+ // if it is not Gregorian, otherwise there is no need as it is already in Gregorian.
+ if ($calendartype->get_name() != 'gregorian') {
+ $date = $calendartype->timestamp_to_date_array($time);
+ }
+ } else if (!empty($time)) {
+ // Get the specified date in the calendar type being used.
+ $date = $calendartype->timestamp_to_date_array($time);
+ $thisdate = $calendartype->timestamp_to_date_array(time());
+ if ($date['month'] == $thisdate['month'] && $date['year'] == $thisdate['year']) {
+ $display->thismonth = true;
+ // If we are the current month we want to set the date to the current date, not the start of the month.
+ $date = $thisdate;
+ }
+ } else {
+ // Get the current date in the calendar type being used.
+ $time = time();
+ $date = $calendartype->timestamp_to_date_array($time);
+ $display->thismonth = true;
+ }
+
+ list($d, $m, $y) = array($date['mday'], $date['mon'], $date['year']); // This is what we want to display.
+
+ // Get Gregorian date for the start of the month.
+ $gregoriandate = $calendartype->convert_to_gregorian($date['year'], $date['mon'], 1);
+
+ // Store the gregorian date values to be used later.
+ list($gy, $gm, $gd, $gh, $gmin) = array($gregoriandate['year'], $gregoriandate['month'], $gregoriandate['day'],
+ $gregoriandate['hour'], $gregoriandate['minute']);
+
+ // Get the max number of days in this month for this calendar type.
+ $display->maxdays = calendar_days_in_month($m, $y);
+ // Get the starting week day for this month.
+ $startwday = dayofweek(1, $m, $y);
+ // Get the days in a week.
+ $daynames = calendar_get_days();
+ // Store the number of days in a week.
+ $numberofdaysinweek = $calendartype->get_num_weekdays();
+
+ // Set the min and max weekday.
+ $display->minwday = calendar_get_starting_weekday();
+ $display->maxwday = $display->minwday + ($numberofdaysinweek - 1);
+
+ // These are used for DB queries, so we want unixtime, so we need to use Gregorian dates.
+ $display->tstart = make_timestamp($gy, $gm, $gd, $gh, $gmin, 0);
+ $display->tend = $display->tstart + ($display->maxdays * DAYSECS) - 1;
+
+ // Align the starting weekday to fall in our display range.
+ // This is simple, not foolproof.
+ if ($startwday < $display->minwday) {
+ $startwday += $numberofdaysinweek;
+ }
+
+ // Get the events matching our criteria. Don't forget to offset the timestamps for the user's TZ.
+ $events = calendar_get_events($display->tstart, $display->tend, $users, $groups, $courses);
+
+ // Set event course class for course events.
+ if (!empty($events)) {
+ foreach ($events as $eventid => $event) {
+ if (!empty($event->modulename)) {
+ $cm = get_coursemodule_from_instance($event->modulename, $event->instance);
+ if (!\core_availability\info_module::is_user_visible($cm, 0, false)) {
+ unset($events[$eventid]);
+ }
+ }
+ }
+ }
+
+ // This is either a genius idea or an idiot idea: in order to not complicate things, we use this rule: if, after
+ // possibly removing SITEID from $courses, there is only one course left, then clicking on a day in the month
+ // will also set the $SESSION->cal_courses_shown variable to that one course. Otherwise, we 'd need to add extra
+ // arguments to this function.
+ $hrefparams = array();
+ if (!empty($courses)) {
+ $courses = array_diff($courses, array(SITEID));
+ if (count($courses) == 1) {
+ $hrefparams['course'] = reset($courses);
+ }
+ }
+
+ // We want to have easy access by day, since the display is on a per-day basis.
+ calendar_events_by_day($events, $m, $y, $eventsbyday, $durationbyday, $typesbyday, $courses);
+
+ // Accessibility: added summary and <abbr> elements.
+ $summary = get_string('calendarheading', 'calendar', userdate($display->tstart, get_string('strftimemonthyear')));
+ // Begin table.
+ $content .= '<table class="minicalendar calendartable" summary="' . $summary . '">';
+ if (($placement !== false) && ($courseid !== false)) {
+ $content .= '<caption>' . calendar_top_controls($placement,
+ array('id' => $courseid, 'time' => $time)) . '</caption>';
+ }
+ $content .= '<tr class="weekdays">'; // Header row: day names.
+
+ // Print out the names of the weekdays.
+ for ($i = $display->minwday; $i <= $display->maxwday; $i++) {
+ $pos = $i % $numberofdaysinweek;
+ $content .= '<th scope="col"><abbr title="' . $daynames[$pos]['fullname'] . '">' .
+ $daynames[$pos]['shortname'] . "</abbr></th>\n";
+ }
+
+ $content .= '</tr><tr>'; // End of day names; prepare for day numbers.
+
+ // For the table display. $week is the row; $dayweek is the column.
+ $dayweek = $startwday;
+
+ // Padding (the first week may have blank days in the beginning).
+ for ($i = $display->minwday; $i < $startwday; ++$i) {
+ $content .= '<td class="dayblank"> </td>' ."\n";
+ }
+
+ $weekend = CALENDAR_DEFAULT_WEEKEND;
+ if (isset($CFG->calendar_weekend)) {
+ $weekend = intval($CFG->calendar_weekend);
+ }
+
+ // Now display all the calendar.
+ $daytime = strtotime('-1 day', $display->tstart);
+ for ($day = 1; $day <= $display->maxdays; ++$day, ++$dayweek) {
+ $cellattributes = array();
+ $daytime = strtotime('+1 day', $daytime);
+ if ($dayweek > $display->maxwday) {
+ // We need to change week (table row).
+ $content .= '</tr><tr>';
+ $dayweek = $display->minwday;
+ }
+
+ // Reset vars.
+ if ($weekend & (1 << ($dayweek % $numberofdaysinweek))) {
+ // Weekend. This is true no matter what the exact range is.
+ $class = 'weekend day';
+ } else {
+ // Normal working day.
+ $class = 'day';
+ }
+
+ $eventids = array();
+ if (!empty($eventsbyday[$day])) {
+ $eventids = $eventsbyday[$day];
+ }
+
+ if (!empty($durationbyday[$day])) {
+ $eventids = array_unique(array_merge($eventids, $durationbyday[$day]));
+ }
+
+ $finishclass = false;
+
+ if (!empty($eventids)) {
+ // There is at least one event on this day.
+ $class .= ' hasevent';
+ $hrefparams['view'] = 'day';
+ $dayhref = calendar_get_link_href(new \moodle_url(CALENDAR_URL . 'view.php', $hrefparams), 0, 0, 0, $daytime);
+
+ $popupcontent = '';
+ foreach ($eventids as $eventid) {
+ if (!isset($events[$eventid])) {
+ continue;
+ }
+ $event = new \calendar_event($events[$eventid]);
+ $popupalt = '';
+ $component = 'moodle';
+ if (!empty($event->modulename)) {
+ $popupicon = 'icon';
+ $popupalt = $event->modulename;
+ $component = $event->modulename;
+ } else if ($event->courseid == SITEID) { // Site event.
+ $popupicon = 'i/siteevent';
+ } else if ($event->courseid != 0 && $event->courseid != SITEID
+ && $event->groupid == 0) { // Course event.
+ $popupicon = 'i/courseevent';
+ } else if ($event->groupid) { // Group event.
+ $popupicon = 'i/groupevent';
+ } else { // Must be a user event.
+ $popupicon = 'i/userevent';
+ }
+
+ if ($event->timeduration) {
+ $startdate = $calendartype->timestamp_to_date_array($event->timestart);
+ $enddate = $calendartype->timestamp_to_date_array($event->timestart + $event->timeduration - 1);
+ if ($enddate['mon'] == $m && $enddate['year'] == $y && $enddate['mday'] == $day) {
+ $finishclass = true;
+ }
+ }
+
+ $dayhref->set_anchor('event_' . $event->id);
+
+ $popupcontent .= \html_writer::start_tag('div');
+ $popupcontent .= $OUTPUT->pix_icon($popupicon, $popupalt, $component);
+ // Show ical source if needed.
+ if (!empty($event->subscription) && $CFG->calendar_showicalsource) {
+ $a = new \stdClass();
+ $a->name = format_string($event->name, true);
+ $a->source = $event->subscription->name;
+ $name = get_string('namewithsource', 'calendar', $a);
+ } else {
+ if ($finishclass) {
+ $samedate = $startdate['mon'] == $enddate['mon'] &&
+ $startdate['year'] == $enddate['year'] &&
+ $startdate['mday'] == $enddate['mday'];
+
+ if ($samedate) {
+ $name = format_string($event->name, true);
+ } else {
+ $name = format_string($event->name, true) . ' (' . get_string('eventendtime', 'calendar') . ')';
+ }
+ } else {
+ $name = format_string($event->name, true);
+ }
+ }
+ $popupcontent .= \html_writer::link($dayhref, $name);
+ $popupcontent .= \html_writer::end_tag('div');
+ }
+
+ if ($display->thismonth && $day == $d) {
+ $popupdata = calendar_get_popup(true, $daytime, $popupcontent);
+ } else {
+ $popupdata = calendar_get_popup(false, $daytime, $popupcontent);
+ }
+
+ // Class and cell content.
+ if (isset($typesbyday[$day]['startglobal'])) {
+ $class .= ' calendar_event_global';
+ } else if (isset($typesbyday[$day]['startcourse'])) {
+ $class .= ' calendar_event_course';
+ } else if (isset($typesbyday[$day]['startgroup'])) {
+ $class .= ' calendar_event_group';
+ } else if (isset($typesbyday[$day]['startuser'])) {
+ $class .= ' calendar_event_user';
+ }
+ if ($finishclass) {
+ $class .= ' duration_finish';
+ }
+ $data = array(
+ 'url' => $dayhref,
+ 'day' => $day,
+ 'content' => $popupdata['data-core_calendar-popupcontent'],
+ 'title' => $popupdata['data-core_calendar-title']
+ );
+ $cell = $OUTPUT->render_from_template('core_calendar/minicalendar_day_link', $data);
+ } else {
+ $cell = $day;
+ }
+
+ $durationclass = false;
+ if (isset($typesbyday[$day]['durationglobal'])) {
+ $durationclass = ' duration_global';
+ } else if (isset($typesbyday[$day]['durationcourse'])) {
+ $durationclass = ' duration_course';
+ } else if (isset($typesbyday[$day]['durationgroup'])) {
+ $durationclass = ' duration_group';
+ } else if (isset($typesbyday[$day]['durationuser'])) {
+ $durationclass = ' duration_user';
+ }
+ if ($durationclass) {
+ $class .= ' duration ' . $durationclass;
+ }
+
+ // If event has a class set then add it to the table day <td> tag.
+ // Note: only one colour for minicalendar.
+ if (isset($eventsbyday[$day])) {
+ foreach ($eventsbyday[$day] as $eventid) {
+ if (!isset($events[$eventid])) {
+ continue;
+ }
+ $event = $events[$eventid];
+ if (!empty($event->class)) {
+ $class .= ' ' . $event->class;
+ }
+ break;
+ }
+ }
+
+ if ($display->thismonth && $day == $d) {
+ // The current cell is for today - add appropriate classes and additional information for styling.
+ $class .= ' today';
+ $today = get_string('today', 'calendar') . ' ' . userdate(time(), get_string('strftimedayshort'));
+
+ if (!isset($eventsbyday[$day]) && !isset($durationbyday[$day])) {
+ $class .= ' eventnone';
+ $popupdata = calendar_get_popup(true, false);
+ $data = array(
+ 'url' => '#',
+ 'day' => $day,
+ 'content' => $popupdata['data-core_calendar-popupcontent'],
+ 'title' => $popupdata['data-core_calendar-title']
+ );
+ $cell = $OUTPUT->render_from_template('core_calendar/minicalendar_day_link', $data);
+ }
+ $cell = get_accesshide($today . ' ') . $cell;
+ }
+
+ // Just display it.
+ $cellattributes['class'] = $class;
+ $content .= \html_writer::tag('td', $cell, $cellattributes);
+ }
+
+ // Padding (the last week may have blank days at the end).
+ for ($i = $dayweek; $i <= $display->maxwday; ++$i) {
+ $content .= '<td class="dayblank"> </td>';
+ }
+ $content .= '</tr>'; // Last row ends.
+
+ $content .= '</table>'; // Tabular display of days ends.
+ return $content;
}
/**
* @return string eventid for the calendar_tooltip popup window/layout.
*/
function calendar_get_popup($today = false, $timestart, $popupcontent = '') {
- return \core_calendar\api::get_popup($today, $timestart, $popupcontent);
+ $popupcaption = '';
+ if ($today) {
+ $popupcaption = get_string('today', 'calendar') . ' ';
+ }
+
+ if (false === $timestart) {
+ $popupcaption .= userdate(time(), get_string('strftimedayshort'));
+ $popupcontent = get_string('eventnone', 'calendar');
+
+ } else {
+ $popupcaption .= get_string('eventsfor', 'calendar', userdate($timestart, get_string('strftimedayshort')));
+ }
+
+ return array(
+ 'data-core_calendar-title' => $popupcaption,
+ 'data-core_calendar-popupcontent' => $popupcontent,
+ );
}
/**
* @return array $output array of upcoming events
*/
function calendar_get_upcoming($courses, $groups, $users, $daysinfuture, $maxevents, $fromtime=0) {
- return \core_calendar\api::get_upcoming($courses, $groups, $users, $daysinfuture, $maxevents, $fromtime);
+ global $COURSE;
+
+ $display = new \stdClass;
+ $display->range = $daysinfuture; // How many days in the future we 'll look.
+ $display->maxevents = $maxevents;
+
+ $output = array();
+
+ $processed = 0;
+ $now = time(); // We 'll need this later.
+ $usermidnighttoday = usergetmidnight($now);
+
+ if ($fromtime) {
+ $display->tstart = $fromtime;
+ } else {
+ $display->tstart = $usermidnighttoday;
+ }
+
+ // This works correctly with respect to the user's DST, but it is accurate
+ // only because $fromtime is always the exact midnight of some day!
+ $display->tend = usergetmidnight($display->tstart + DAYSECS * $display->range + 3 * HOURSECS) - 1;
+
+ // Get the events matching our criteria.
+ $events = calendar_get_events($display->tstart, $display->tend, $users, $groups, $courses);
+
+ // This is either a genius idea or an idiot idea: in order to not complicate things, we use this rule: if, after
+ // possibly removing SITEID from $courses, there is only one course left, then clicking on a day in the month
+ // will also set the $SESSION->cal_courses_shown variable to that one course. Otherwise, we 'd need to add extra
+ // arguments to this function.
+ $hrefparams = array();
+ if (!empty($courses)) {
+ $courses = array_diff($courses, array(SITEID));
+ if (count($courses) == 1) {
+ $hrefparams['course'] = reset($courses);
+ }
+ }
+
+ if ($events !== false) {
+ $modinfo = get_fast_modinfo($COURSE);
+ foreach ($events as $event) {
+ if (!empty($event->modulename)) {
+ if ($event->courseid == $COURSE->id) {
+ if (isset($modinfo->instances[$event->modulename][$event->instance])) {
+ $cm = $modinfo->instances[$event->modulename][$event->instance];
+ if (!$cm->uservisible) {
+ continue;
+ }
+ }
+ } else {
+ if (!$cm = get_coursemodule_from_instance($event->modulename, $event->instance)) {
+ continue;
+ }
+ if (!\core_availability\info_module::is_user_visible($cm, 0, false)) {
+ continue;
+ }
+ }
+ }
+
+ if ($processed >= $display->maxevents) {
+ break;
+ }
+
+ $event->time = calendar_format_event_time($event, $now, $hrefparams);
+ $output[] = $event;
+ $processed++;
+ }
+ }
+
+ return $output;
}
/**
* @return string a link to the course (as HTML); empty if the course id is invalid
*/
function calendar_get_courselink($courseid) {
- return \core_calendar\api::get_courselink($courseid);
+ if (!$courseid) {
+ return '';
+ }
+
+ calendar_get_course_cached($coursecache, $courseid);
+ $context = \context_course::instance($courseid);
+ $fullname = format_string($coursecache[$courseid]->fullname, true, array('context' => $context));
+ $url = new \moodle_url('/course/view.php', array('id' => $courseid));
+ $link = \html_writer::link($url, $fullname);
+
+ return $link;
}
/**
* Get current module cache.
*
- * @param array $coursecache list of course cache
+ * @param array $modulecache in memory module cache
* @param string $modulename name of the module
* @param int $instance module instance number
* @return stdClass|bool $module information
*/
-function calendar_get_module_cached(&$coursecache, $modulename, $instance) {
- // We have a new implementation of this function in the calendar API class,
- // so the old implementation must remain here.
- $module = get_coursemodule_from_instance($modulename, $instance);
-
- if ($module === false) {
- return false;
+function calendar_get_module_cached(&$modulecache, $modulename, $instance) {
+ if (!isset($modulecache[$modulename . '_' . $instance])) {
+ $modulecache[$modulename . '_' . $instance] = get_coursemodule_from_instance($modulename, $instance);
}
- if (!calendar_get_course_cached($coursecache, $module->course)) {
- return false;
- }
- return $module;
+
+ return $modulecache[$modulename . '_' . $instance];
}
/**
* @return stdClass $coursecache[$courseid] return the specific course cache
*/
function calendar_get_course_cached(&$coursecache, $courseid) {
- return \core_calendar\api::get_course_cached($coursecache, $courseid);
+ if (!isset($coursecache[$courseid])) {
+ $coursecache[$courseid] = get_course($courseid);
+ }
+ return $coursecache[$courseid];
}
/**
* @return stdClass group object with fields 'id', 'name' and 'courseid'
*/
function calendar_get_group_cached($groupid) {
- return \core_calendar\api::get_group_cached($groupid);
+ static $groupscache = array();
+ if (!isset($groupscache[$groupid])) {
+ $groupscache[$groupid] = groups_get_group($groupid, 'id,name,courseid');
+ }
+ return $groupscache[$groupid];
}
/**
* @return stdClass $event metadata
*/
function calendar_add_event_metadata($event) {
- return \core_calendar\api::add_event_metadata($event);
+ global $CFG, $OUTPUT;
+
+ // Support multilang in event->name.
+ $event->name = format_string($event->name, true);
+
+ if (!empty($event->modulename)) { // Activity event.
+ // The module name is set. I will assume that it has to be displayed, and
+ // also that it is an automatically-generated event. And of course that the
+ // fields for get_coursemodule_from_instance are set correctly.
+ $module = calendar_get_module_cached($coursecache, $event->modulename, $event->instance);
+
+ if ($module === false) {
+ return;
+ }
+
+ $modulename = get_string('modulename', $event->modulename);
+ if (get_string_manager()->string_exists($event->eventtype, $event->modulename)) {
+ // Will be used as alt text if the event icon.
+ $eventtype = get_string($event->eventtype, $event->modulename);
+ } else {
+ $eventtype = '';
+ }
+ $icon = $OUTPUT->image_url('icon', $event->modulename) . '';
+
+ $event->icon = '<img src="' . $icon . '" alt="' . $eventtype . '" title="' . $modulename . '" class="icon" />';
+ $event->referer = '<a href="' . $CFG->wwwroot . '/mod/' . $event->modulename . '/view.php?id=' .
+ $module->id . '">' . $event->name . '</a>';
+ $event->courselink = calendar_get_courselink($module->course);
+ $event->cmid = $module->id;
+ } else if ($event->courseid == SITEID) { // Site event.
+ $event->icon = '<img src="' . $OUTPUT->image_url('i/siteevent') . '" alt="' .
+ get_string('globalevent', 'calendar') . '" class="icon" />';
+ $event->cssclass = 'calendar_event_global';
+ } else if ($event->courseid != 0 && $event->courseid != SITEID && $event->groupid == 0) { // Course event.
+ $event->icon = '<img src="' . $OUTPUT->image_url('i/courseevent') . '" alt="' .
+ get_string('courseevent', 'calendar') . '" class="icon" />';
+ $event->courselink = calendar_get_courselink($event->courseid);
+ $event->cssclass = 'calendar_event_course';
+ } else if ($event->groupid) { // Group event.
+ if ($group = calendar_get_group_cached($event->groupid)) {
+ $groupname = format_string($group->name, true, \context_course::instance($group->courseid));
+ } else {
+ $groupname = '';
+ }
+ $event->icon = \html_writer::empty_tag('image', array('src' => $OUTPUT->image_url('i/groupevent'),
+ 'alt' => get_string('groupevent', 'calendar'), 'title' => $groupname, 'class' => 'icon'));
+ $event->courselink = calendar_get_courselink($event->courseid) . ', ' . $groupname;
+ $event->cssclass = 'calendar_event_group';
+ } else if ($event->userid) { // User event.
+ $event->icon = '<img src="' . $OUTPUT->image_url('i/userevent') . '" alt="' .
+ get_string('userevent', 'calendar') . '" class="icon" />';
+ $event->cssclass = 'calendar_event_user';
+ }
+
+ return $event;
}
/**
* @return array Array of event entries, empty array if nothing found
*/
function calendar_get_events_by_id($eventids) {
- return \core_calendar\api::get_events_by_id($eventids);
+ global $DB;
+
+ if (!is_array($eventids) || empty($eventids)) {
+ return array();
+ }
+
+ list($wheresql, $params) = $DB->get_in_or_equal($eventids);
+ $wheresql = "id $wheresql";
+
+ return $DB->get_records_select('event', $wheresql, $params);
}
/**
* @return string $content return available control for the calender in html
*/
function calendar_top_controls($type, $data) {
- return \core_calendar\api::get_top_controls($type, $data);
+ global $PAGE, $OUTPUT;
+
+ // Get the calendar type we are using.
+ $calendartype = \core_calendar\type_factory::get_calendar_instance();
+
+ $content = '';
+
+ // Ensure course id passed if relevant.
+ $courseid = '';
+ if (!empty($data['id'])) {
+ $courseid = '&course=' . $data['id'];
+ }
+
+ // If we are passing a month and year then we need to convert this to a timestamp to
+ // support multiple calendars. No where in core should these be passed, this logic
+ // here is for third party plugins that may use this function.
+ if (!empty($data['m']) && !empty($date['y'])) {
+ if (!isset($data['d'])) {
+ $data['d'] = 1;
+ }
+ if (!checkdate($data['m'], $data['d'], $data['y'])) {
+ $time = time();
+ } else {
+ $time = make_timestamp($data['y'], $data['m'], $data['d']);
+ }
+ } else if (!empty($data['time'])) {
+ $time = $data['time'];
+ } else {
+ $time = time();
+ }
+
+ // Get the date for the calendar type.
+ $date = $calendartype->timestamp_to_date_array($time);
+
+ $urlbase = $PAGE->url;
+
+ // We need to get the previous and next months in certain cases.
+ if ($type == 'frontpage' || $type == 'course' || $type == 'month') {
+ $prevmonth = calendar_sub_month($date['mon'], $date['year']);
+ $prevmonthtime = $calendartype->convert_to_gregorian($prevmonth[1], $prevmonth[0], 1);
+ $prevmonthtime = make_timestamp($prevmonthtime['year'], $prevmonthtime['month'], $prevmonthtime['day'],
+ $prevmonthtime['hour'], $prevmonthtime['minute']);
+
+ $nextmonth = calendar_add_month($date['mon'], $date['year']);
+ $nextmonthtime = $calendartype->convert_to_gregorian($nextmonth[1], $nextmonth[0], 1);
+ $nextmonthtime = make_timestamp($nextmonthtime['year'], $nextmonthtime['month'], $nextmonthtime['day'],
+ $nextmonthtime['hour'], $nextmonthtime['minute']);
+ }
+
+ switch ($type) {
+ case 'frontpage':
+ $prevlink = calendar_get_link_previous(get_string('monthprev', 'access'), $urlbase, false, false, false,
+ true, $prevmonthtime);
+ $nextlink = calendar_get_link_next(get_string('monthnext', 'access'), $urlbase, false, false, false, true,
+ $nextmonthtime);
+ $calendarlink = calendar_get_link_href(new \moodle_url(CALENDAR_URL . 'view.php', array('view' => 'month')),
+ false, false, false, $time);
+
+ if (!empty($data['id'])) {
+ $calendarlink->param('course', $data['id']);
+ }
+
+ $right = $nextlink;
+
+ $content .= \html_writer::start_tag('div', array('class' => 'calendar-controls'));
+ $content .= $prevlink . '<span class="hide"> | </span>';
+ $content .= \html_writer::tag('span', \html_writer::link($calendarlink,
+ userdate($time, get_string('strftimemonthyear')), array('title' => get_string('monththis', 'calendar'))
+ ), array('class' => 'current'));
+ $content .= '<span class="hide"> | </span>' . $right;
+ $content .= "<span class=\"clearer\"><!-- --></span>\n";
+ $content .= \html_writer::end_tag('div');
+
+ break;
+ case 'course':
+ $prevlink = calendar_get_link_previous(get_string('monthprev', 'access'), $urlbase, false, false, false,
+ true, $prevmonthtime);
+ $nextlink = calendar_get_link_next(get_string('monthnext', 'access'), $urlbase, false, false, false,
+ true, $nextmonthtime);
+ $calendarlink = calendar_get_link_href(new \moodle_url(CALENDAR_URL . 'view.php', array('view' => 'month')),
+ false, false, false, $time);
+
+ if (!empty($data['id'])) {
+ $calendarlink->param('course', $data['id']);
+ }
+
+ $content .= \html_writer::start_tag('div', array('class' => 'calendar-controls'));
+ $content .= $prevlink . '<span class="hide"> | </span>';
+ $content .= \html_writer::tag('span', \html_writer::link($calendarlink,
+ userdate($time, get_string('strftimemonthyear')), array('title' => get_string('monththis', 'calendar'))
+ ), array('class' => 'current'));
+ $content .= '<span class="hide"> | </span>' . $nextlink;
+ $content .= "<span class=\"clearer\"><!-- --></span>";
+ $content .= \html_writer::end_tag('div');
+ break;
+ case 'upcoming':
+ $calendarlink = calendar_get_link_href(new \moodle_url(CALENDAR_URL . 'view.php', array('view' => 'upcoming')),
+ false, false, false, $time);
+ if (!empty($data['id'])) {
+ $calendarlink->param('course', $data['id']);
+ }
+ $calendarlink = \html_writer::link($calendarlink, userdate($time, get_string('strftimemonthyear')));
+ $content .= \html_writer::tag('div', $calendarlink, array('class' => 'centered'));
+ break;
+ case 'display':
+ $calendarlink = calendar_get_link_href(new \moodle_url(CALENDAR_URL . 'view.php', array('view' => 'month')),
+ false, false, false, $time);
+ if (!empty($data['id'])) {
+ $calendarlink->param('course', $data['id']);
+ }
+ $calendarlink = \html_writer::link($calendarlink, userdate($time, get_string('strftimemonthyear')));
+ $content .= \html_writer::tag('h3', $calendarlink);
+ break;
+ case 'month':
+ $prevlink = calendar_get_link_previous(userdate($prevmonthtime, get_string('strftimemonthyear')),
+ 'view.php?view=month' . $courseid . '&', false, false, false, false, $prevmonthtime);
+ $nextlink = calendar_get_link_next(userdate($nextmonthtime, get_string('strftimemonthyear')),
+ 'view.php?view=month' . $courseid . '&', false, false, false, false, $nextmonthtime);
+
+ $content .= \html_writer::start_tag('div', array('class' => 'calendar-controls'));
+ $content .= $prevlink . '<span class="hide"> | </span>';
+ $content .= $OUTPUT->heading(userdate($time, get_string('strftimemonthyear')), 2, 'current');
+ $content .= '<span class="hide"> | </span>' . $nextlink;
+ $content .= '<span class="clearer"><!-- --></span>';
+ $content .= \html_writer::end_tag('div')."\n";
+ break;
+ case 'day':
+ $days = calendar_get_days();
+
+ $prevtimestamp = strtotime('-1 day', $time);
+ $nexttimestamp = strtotime('+1 day', $time);
+
+ $prevdate = $calendartype->timestamp_to_date_array($prevtimestamp);
+ $nextdate = $calendartype->timestamp_to_date_array($nexttimestamp);
+
+ $prevname = $days[$prevdate['wday']]['fullname'];
+ $nextname = $days[$nextdate['wday']]['fullname'];
+ $prevlink = calendar_get_link_previous($prevname, 'view.php?view=day' . $courseid . '&', false, false,
+ false, false, $prevtimestamp);
+ $nextlink = calendar_get_link_next($nextname, 'view.php?view=day' . $courseid . '&', false, false, false,
+ false, $nexttimestamp);
+
+ $content .= \html_writer::start_tag('div', array('class' => 'calendar-controls'));
+ $content .= $prevlink;
+ $content .= '<span class="hide"> | </span><span class="current">' .userdate($time,
+ get_string('strftimedaydate')) . '</span>';
+ $content .= '<span class="hide"> | </span>' . $nextlink;
+ $content .= "<span class=\"clearer\"><!-- --></span>";
+ $content .= \html_writer::end_tag('div') . "\n";
+
+ break;
+ }
+
+ return $content;
}
/**
* @return string html content of the element
*/
function calendar_filter_controls_element(moodle_url $url, $type) {
- return \core_calendar\api::get_filter_controls_element($url, $type);
+ global $OUTPUT;
+
+ switch ($type) {
+ case CALENDAR_EVENT_GLOBAL:
+ $typeforhumans = 'global';
+ $class = 'calendar_event_global';
+ break;
+ case CALENDAR_EVENT_COURSE:
+ $typeforhumans = 'course';
+ $class = 'calendar_event_course';
+ break;
+ case CALENDAR_EVENT_GROUP:
+ $typeforhumans = 'groups';
+ $class = 'calendar_event_group';
+ break;
+ case CALENDAR_EVENT_USER:
+ $typeforhumans = 'user';
+ $class = 'calendar_event_user';
+ break;
+ }
+
+ if (calendar_show_event_type($type)) {
+ $icon = $OUTPUT->pix_icon('t/hide', get_string('hide'));
+ $str = get_string('hide' . $typeforhumans . 'events', 'calendar');
+ } else {
+ $icon = $OUTPUT->pix_icon('t/show', get_string('show'));
+ $str = get_string('show' . $typeforhumans . 'events', 'calendar');
+ }
+ $content = \html_writer::start_tag('li', array('class' => 'calendar_event'));
+ $content .= \html_writer::start_tag('a', array('href' => $url, 'rel' => 'nofollow'));
+ $content .= \html_writer::tag('span', $icon, array('class' => $class));
+ $content .= \html_writer::tag('span', $str, array('class' => 'eventname'));
+ $content .= \html_writer::end_tag('a');
+ $content .= \html_writer::end_tag('li');
+
+ return $content;
}
/**
* @return string $content return filter controls in html
*/
function calendar_filter_controls(moodle_url $returnurl) {
- return \core_calendar\api::get_filter_controls($returnurl);
+ $groupevents = true;
+
+ $seturl = new \moodle_url('/calendar/set.php', array('return' => base64_encode($returnurl->out_as_local_url(false)),
+ 'sesskey' => sesskey()));
+ $content = \html_writer::start_tag('ul');
+
+ $seturl->param('var', 'showglobal');
+ $content .= calendar_filter_controls_element($seturl, CALENDAR_EVENT_GLOBAL);
+
+ $seturl->param('var', 'showcourses');
+ $content .= calendar_filter_controls_element($seturl, CALENDAR_EVENT_COURSE);
+
+ if (isloggedin() && !isguestuser()) {
+ if ($groupevents) {
+ // This course MIGHT have group events defined, so show the filter.
+ $seturl->param('var', 'showgroups');
+ $content .= calendar_filter_controls_element($seturl, CALENDAR_EVENT_GROUP);
+ }
+ $seturl->param('var', 'showuser');
+ $content .= calendar_filter_controls_element($seturl, CALENDAR_EVENT_USER);
+ }
+ $content .= \html_writer::end_tag('ul');
+
+ return $content;
}
/**
* @return string the formatted date/time
*/
function calendar_day_representation($tstamp, $now = false, $usecommonwords = true) {
- return \core_calendar\api::get_day_representation($tstamp, $now, $usecommonwords);
+ static $shortformat;
+
+ if (empty($shortformat)) {
+ $shortformat = get_string('strftimedayshort');
+ }
+
+ if ($now === false) {
+ $now = time();
+ }
+
+ // To have it in one place, if a change is needed.
+ $formal = userdate($tstamp, $shortformat);
+
+ $datestamp = usergetdate($tstamp);
+ $datenow = usergetdate($now);
+
+ if ($usecommonwords == false) {
+ // We don't want words, just a date.
+ return $formal;
+ } else if ($datestamp['year'] == $datenow['year'] && $datestamp['yday'] == $datenow['yday']) {
+ return get_string('today', 'calendar');
+ } else if (($datestamp['year'] == $datenow['year'] && $datestamp['yday'] == $datenow['yday'] - 1 ) ||
+ ($datestamp['year'] == $datenow['year'] - 1 && $datestamp['mday'] == 31 && $datestamp['mon'] == 12
+ && $datenow['yday'] == 1)) {
+ return get_string('yesterday', 'calendar');
+ } else if (($datestamp['year'] == $datenow['year'] && $datestamp['yday'] == $datenow['yday'] + 1 ) ||
+ ($datestamp['year'] == $datenow['year'] + 1 && $datenow['mday'] == 31 && $datenow['mon'] == 12
+ && $datestamp['yday'] == 1)) {
+ return get_string('tomorrow', 'calendar');
+ } else {
+ return $formal;
+ }
}
/**
* @return string the formatted date/time
*/
function calendar_time_representation($time) {
- return \core_calendar\api::get_time_representation($time);
+ static $langtimeformat = null;
+
+ if ($langtimeformat === null) {
+ $langtimeformat = get_string('strftimetime');
+ }
+
+ $timeformat = get_user_preferences('calendar_timeformat');
+ if (empty($timeformat)) {
+ $timeformat = get_config(null, 'calendar_site_timeformat');
+ }
+
+ return userdate($time, empty($timeformat) ? $langtimeformat : $timeformat);
}
/**
* @return moodle_url|null $linkbase
*/
function calendar_get_link_href($linkbase, $d, $m, $y, $time = 0) {
- return \core_calendar\api::get_link_href($linkbase, $d, $m, $y, $time);
+ if (empty($linkbase)) {
+ return null;
+ }
+
+ if (!($linkbase instanceof \moodle_url)) {
+ $linkbase = new \moodle_url($linkbase);
+ }
+
+ // If a day, month and year were passed then convert it to a timestamp. If these were passed
+ // then we can assume the day, month and year are passed as Gregorian, as no where in core
+ // should we be passing these values rather than the time.
+ if (!empty($d) && !empty($m) && !empty($y)) {
+ if (checkdate($m, $d, $y)) {
+ $time = make_timestamp($y, $m, $d);
+ } else {
+ $time = time();
+ }
+ } else if (empty($time)) {
+ $time = time();
+ }
+
+ $linkbase->param('time', $time);
+
+ return $linkbase;
}
/**
* @return string HTML string.
*/
function calendar_get_link_previous($text, $linkbase, $d, $m, $y, $accesshide = false, $time = 0) {
- return \core_calendar\api::get_link_previous($text, $linkbase, $d, $m, $y, $accesshide, $time);
+ $href = calendar_get_link_href(new \moodle_url($linkbase), $d, $m, $y, $time);
+
+ if (empty($href)) {
+ return $text;
+ }
+
+ return link_arrow_left($text, (string)$href, $accesshide, 'previous');
}
/**
* @return string HTML string.
*/
function calendar_get_link_next($text, $linkbase, $d, $m, $y, $accesshide = false, $time = 0) {
- return \core_calendar\api::get_link_next($text, $linkbase, $d, $m, $y, $accesshide, $time);
+ $href = calendar_get_link_href(new \moodle_url($linkbase), $d, $m, $y, $time);
+
+ if (empty($href)) {
+ return $text;
+ }
+
+ return link_arrow_right($text, (string)$href, $accesshide, 'next');
}
/**
* @return int
*/
function calendar_days_in_month($month, $year) {
- return \core_calendar\api::get_days_in_month($month, $year);
+ $calendartype = \core_calendar\type_factory::get_calendar_instance();
+ return $calendartype->get_num_days_in_month($year, $month);
}
/**
* @return array the following month
*/
function calendar_add_month($month, $year) {
- return \core_calendar\api::get_next_month($month, $year);
+ $calendartype = \core_calendar\type_factory::get_calendar_instance();
+ return $calendartype->get_next_month($year, $month);
}
/**
* @return array previous month
*/
function calendar_sub_month($month, $year) {
- return \core_calendar\api::get_prev_month($month, $year);
+ $calendartype = \core_calendar\type_factory::get_calendar_instance();
+ return $calendartype->get_prev_month($year, $month);
}
/**
* @return void
*/
function calendar_events_by_day($events, $month, $year, &$eventsbyday, &$durationbyday, &$typesbyday, &$courses) {
- \core_calendar\api::get_events_by_day($events, $month, $year, $eventsbyday, $durationbyday, $typesbyday, $courses);
+ $calendartype = \core_calendar\type_factory::get_calendar_instance();
+
+ $eventsbyday = array();
+ $typesbyday = array();
+ $durationbyday = array();
+
+ if ($events === false) {
+ return;
+ }
+
+ foreach ($events as $event) {
+ $startdate = $calendartype->timestamp_to_date_array($event->timestart);
+ if ($event->timeduration) {
+ $enddate = $calendartype->timestamp_to_date_array($event->timestart + $event->timeduration - 1);
+ } else {
+ $enddate = $startdate;
+ }
+
+ // Simple arithmetic: $year * 13 + $month is a distinct integer for each distinct ($year, $month) pair.
+ if (!($startdate['year'] * 13 + $startdate['mon'] <= $year * 13 + $month) &&
+ ($enddate['year'] * 13 + $enddate['mon'] >= $year * 13 + $month)) {
+ continue;
+ }
+
+ $eventdaystart = intval($startdate['mday']);
+
+ if ($startdate['mon'] == $month && $startdate['year'] == $year) {
+ // Give the event to its day.
+ $eventsbyday[$eventdaystart][] = $event->id;
+
+ // Mark the day as having such an event.
+ if ($event->courseid == SITEID && $event->groupid == 0) {
+ $typesbyday[$eventdaystart]['startglobal'] = true;
+ // Set event class for global event.
+ $events[$event->id]->class = 'calendar_event_global';
+ } else if ($event->courseid != 0 && $event->courseid != SITEID && $event->groupid == 0) {
+ $typesbyday[$eventdaystart]['startcourse'] = true;
+ // Set event class for course event.
+ $events[$event->id]->class = 'calendar_event_course';
+ } else if ($event->groupid) {
+ $typesbyday[$eventdaystart]['startgroup'] = true;
+ // Set event class for group event.
+ $events[$event->id]->class = 'calendar_event_group';
+ } else if ($event->userid) {
+ $typesbyday[$eventdaystart]['startuser'] = true;
+ // Set event class for user event.
+ $events[$event->id]->class = 'calendar_event_user';
+ }
+ }
+
+ if ($event->timeduration == 0) {
+ // Proceed with the next.
+ continue;
+ }
+
+ // The event starts on $month $year or before.
+ if ($startdate['mon'] == $month && $startdate['year'] == $year) {
+ $lowerbound = intval($startdate['mday']);
+ } else {
+ $lowerbound = 0;
+ }
+
+ // Also, it ends on $month $year or later.
+ if ($enddate['mon'] == $month && $enddate['year'] == $year) {
+ $upperbound = intval($enddate['mday']);
+ } else {
+ $upperbound = calendar_days_in_month($month, $year);
+ }
+
+ // Mark all days between $lowerbound and $upperbound (inclusive) as duration.
+ for ($i = $lowerbound + 1; $i <= $upperbound; ++$i) {
+ $durationbyday[$i][] = $event->id;
+ if ($event->courseid == SITEID && $event->groupid == 0) {
+ $typesbyday[$i]['durationglobal'] = true;
+ } else if ($event->courseid != 0 && $event->courseid != SITEID && $event->groupid == 0) {
+ $typesbyday[$i]['durationcourse'] = true;
+ } else if ($event->groupid) {
+ $typesbyday[$i]['durationgroup'] = true;
+ } else if ($event->userid) {
+ $typesbyday[$i]['durationuser'] = true;
+ }
+ }
+
+ }
+ return;
}
/**
* @return array An array of courses, groups, and user to load calendar events for based upon filters
*/
function calendar_set_filters(array $courseeventsfrom, $ignorefilters = false) {
- return \core_calendar\api::set_filters($courseeventsfrom, $ignorefilters);
+ global $USER, $CFG;
+
+ // For backwards compatability we have to check whether the courses array contains
+ // just id's in which case we need to load course objects.
+ $coursestoload = array();
+ foreach ($courseeventsfrom as $id => $something) {
+ if (!is_object($something)) {
+ $coursestoload[] = $id;
+ unset($courseeventsfrom[$id]);
+ }
+ }
+
+ $courses = array();
+ $user = false;
+ $group = false;
+
+ // Get the capabilities that allow seeing group events from all groups.
+ $allgroupscaps = array('moodle/site:accessallgroups', 'moodle/calendar:manageentries');
+
+ $isloggedin = isloggedin();
+
+ if ($ignorefilters || calendar_show_event_type(CALENDAR_EVENT_COURSE)) {
+ $courses = array_keys($courseeventsfrom);
+ }
+ if ($ignorefilters || calendar_show_event_type(CALENDAR_EVENT_GLOBAL)) {
+ $courses[] = SITEID;
+ }
+ $courses = array_unique($courses);
+ sort($courses);
+
+ if (!empty($courses) && in_array(SITEID, $courses)) {
+ // Sort courses for consistent colour highlighting.
+ // Effectively ignoring SITEID as setting as last course id.
+ $key = array_search(SITEID, $courses);
+ unset($courses[$key]);
+ $courses[] = SITEID;
+ }
+
+ if ($ignorefilters || ($isloggedin && calendar_show_event_type(CALENDAR_EVENT_USER))) {
+ $user = $USER->id;
+ }
+
+ if (!empty($courseeventsfrom) && (calendar_show_event_type(CALENDAR_EVENT_GROUP) || $ignorefilters)) {
+
+ if (count($courseeventsfrom) == 1) {
+ $course = reset($courseeventsfrom);
+ if (has_any_capability($allgroupscaps, \context_course::instance($course->id))) {
+ $coursegroups = groups_get_all_groups($course->id, 0, 0, 'g.id');
+ $group = array_keys($coursegroups);
+ }
+ }
+ if ($group === false) {
+ if (!empty($CFG->calendar_adminseesall) && has_any_capability($allgroupscaps, \context_system::instance())) {
+ $group = true;
+ } else if ($isloggedin) {
+ $groupids = array();
+ foreach ($courseeventsfrom as $courseid => $course) {
+ // If the user is an editing teacher in there.
+ if (!empty($USER->groupmember[$course->id])) {
+ // We've already cached the users groups for this course so we can just use that.
+ $groupids = array_merge($groupids, $USER->groupmember[$course->id]);
+ } else if ($course->groupmode != NOGROUPS || !$course->groupmodeforce) {
+ // If this course has groups, show events from all of those related to the current user.
+ $coursegroups = groups_get_user_groups($course->id, $USER->id);
+ $groupids = array_merge($groupids, $coursegroups['0']);
+ }
+ }
+ if (!empty($groupids)) {
+ $group = $groupids;
+ }
+ }
+ }
+ }
+ if (empty($courses)) {
+ $courses = false;
+ }
+
+ return array($courses, $group, $user);
}
/**
* @return bool capability to edit event
*/
function calendar_edit_event_allowed($event) {
- return \core_calendar\api::can_edit_event($event);
+ global $USER, $DB;
+
+ // Must be logged in.
+ if (!isloggedin()) {
+ return false;
+ }
+
+ // Can not be using guest account.
+ if (isguestuser()) {
+ return false;
+ }
+
+ // You cannot edit URL based calendar subscription events presently.
+ if (!empty($event->subscriptionid)) {
+ if (!empty($event->subscription->url)) {
+ // This event can be updated externally, so it cannot be edited.
+ return false;
+ }
+ }
+
+ $sitecontext = \context_system::instance();
+
+ // If user has manageentries at site level, return true.
+ if (has_capability('moodle/calendar:manageentries', $sitecontext)) {
+ return true;
+ }
+
+ // If groupid is set, it's definitely a group event.
+ if (!empty($event->groupid)) {
+ // Allow users to add/edit group events if -
+ // 1) They have manageentries for the course OR
+ // 2) They have managegroupentries AND are in the group.
+ $group = $DB->get_record('groups', array('id' => $event->groupid));
+ return $group && (
+ has_capability('moodle/calendar:manageentries', $event->context) ||
+ (has_capability('moodle/calendar:managegroupentries', $event->context)
+ && groups_is_member($event->groupid)));
+ } else if (!empty($event->courseid)) {
+ // If groupid is not set, but course is set, it's definiely a course event.
+ return has_capability('moodle/calendar:manageentries', $event->context);
+ } else if (!empty($event->userid) && $event->userid == $USER->id) {
+ // If course is not set, but userid id set, it's a user event.
+ return (has_capability('moodle/calendar:manageownentries', $event->context));
+ } else if (!empty($event->userid)) {
+ return (has_capability('moodle/calendar:manageentries', $event->context));
+ }
+
+ return false;
}
/**
* @return array $courses Array of courses to display
*/
function calendar_get_default_courses() {
- return \core_calendar\api::get_default_courses();
+ global $CFG, $DB;
+
+ if (!isloggedin()) {
+ return array();
+ }
+
+ if (!empty($CFG->calendar_adminseesall) && has_capability('moodle/calendar:manageentries', \context_system::instance())) {
+ $select = ', ' . \context_helper::get_preload_record_columns_sql('ctx');
+ $join = "LEFT JOIN {context} ctx ON (ctx.instanceid = c.id AND ctx.contextlevel = :contextlevel)";
+ $sql = "SELECT c.* $select
+ FROM {course} c
+ $join
+ WHERE EXISTS (SELECT 1 FROM {event} e WHERE e.courseid = c.id)
+ ";
+ $courses = $DB->get_records_sql($sql, array('contextlevel' => CONTEXT_COURSE), 0, 20);
+ foreach ($courses as $course) {
+ \context_helper::preload_from_record($course);
+ }
+ return $courses;
+ }
+
+ $courses = enrol_get_my_courses();
+
+ return $courses;
}
/**
* @return string $eventtime link/string for event time
*/
function calendar_format_event_time($event, $now, $linkparams = null, $usecommonwords = true, $showtime = 0) {
- return \core_calendar\api::get_format_event_time($event, $now, $linkparams, $usecommonwords, $showtime);
+ $starttime = $event->timestart;
+ $endtime = $event->timestart + $event->timeduration;
+
+ if (empty($linkparams) || !is_array($linkparams)) {
+ $linkparams = array();
+ }
+
+ $linkparams['view'] = 'day';
+
+ // OK, now to get a meaningful display.
+ // Check if there is a duration for this event.
+ if ($event->timeduration) {
+ // Get the midnight of the day the event will start.
+ $usermidnightstart = usergetmidnight($starttime);
+ // Get the midnight of the day the event will end.
+ $usermidnightend = usergetmidnight($endtime);
+ // Check if we will still be on the same day.
+ if ($usermidnightstart == $usermidnightend) {
+ // Check if we are running all day.
+ if ($event->timeduration == DAYSECS) {
+ $time = get_string('allday', 'calendar');
+ } else { // Specify the time we will be running this from.
+ $datestart = calendar_time_representation($starttime);
+ $dateend = calendar_time_representation($endtime);
+ $time = $datestart . ' <strong>»</strong> ' . $dateend;
+ }
+
+ // Set printable representation.
+ if (!$showtime) {
+ $day = calendar_day_representation($event->timestart, $now, $usecommonwords);
+ $url = calendar_get_link_href(new \moodle_url(CALENDAR_URL . 'view.php', $linkparams), 0, 0, 0, $endtime);
+ $eventtime = \html_writer::link($url, $day) . ', ' . $time;
+ } else {
+ $eventtime = $time;
+ }
+ } else { // It must spans two or more days.
+ $daystart = calendar_day_representation($event->timestart, $now, $usecommonwords) . ', ';
+ if ($showtime == $usermidnightstart) {
+ $daystart = '';
+ }
+ $timestart = calendar_time_representation($event->timestart);
+ $dayend = calendar_day_representation($event->timestart + $event->timeduration, $now, $usecommonwords) . ', ';
+ if ($showtime == $usermidnightend) {
+ $dayend = '';
+ }
+ $timeend = calendar_time_representation($event->timestart + $event->timeduration);
+
+ // Set printable representation.
+ if ($now >= $usermidnightstart && $now < strtotime('+1 day', $usermidnightstart)) {
+ $url = calendar_get_link_href(new \moodle_url(CALENDAR_URL . 'view.php', $linkparams), 0, 0, 0, $endtime);
+ $eventtime = $timestart . ' <strong>»</strong> ' . \html_writer::link($url, $dayend) . $timeend;
+ } else {
+ // The event is in the future, print start and end links.
+ $url = calendar_get_link_href(new \moodle_url(CALENDAR_URL . 'view.php', $linkparams), 0, 0, 0, $starttime);
+ $eventtime = \html_writer::link($url, $daystart) . $timestart . ' <strong>»</strong> ';
+
+ $url = calendar_get_link_href(new \moodle_url(CALENDAR_URL . 'view.php', $linkparams), 0, 0, 0, $endtime);
+ $eventtime .= \html_writer::link($url, $dayend) . $timeend;
+ }
+ }
+ } else { // There is no time duration.
+ $time = calendar_time_representation($event->timestart);
+ // Set printable representation.
+ if (!$showtime) {
+ $day = calendar_day_representation($event->timestart, $now, $usecommonwords);
+ $url = calendar_get_link_href(new \moodle_url(CALENDAR_URL . 'view.php', $linkparams), 0, 0, 0, $starttime);
+ $eventtime = \html_writer::link($url, $day) . ', ' . trim($time);
+ } else {
+ $eventtime = $time;
+ }
+ }
+
+ // Check if It has expired.
+ if ($event->timestart + $event->timeduration < $now) {
+ $eventtime = '<span class="dimmed_text">' . str_replace(' href=', ' class="dimmed" href=', $eventtime) . '</span>';
+ }
+
+ return $eventtime;
}
/**
* @return bool True if the tyep should be displayed false otherwise
*/
function calendar_show_event_type($type, $user = null) {
- return \core_calendar\api::show_event_type($type, $user);
+ $default = CALENDAR_EVENT_GLOBAL + CALENDAR_EVENT_COURSE + CALENDAR_EVENT_GROUP + CALENDAR_EVENT_USER;
+
+ if (get_user_preferences('calendar_persistflt', 0, $user) === 0) {
+ global $SESSION;
+ if (!isset($SESSION->calendarshoweventtype)) {
+ $SESSION->calendarshoweventtype = $default;
+ }
+ return $SESSION->calendarshoweventtype & $type;
+ } else {
+ return get_user_preferences('calendar_savedflt', $default, $user) & $type;
+ }
}
/**
* @param stdClass|int $user moodle user object or id, null means current user
*/
function calendar_set_event_type_display($type, $display = null, $user = null) {
- \core_calendar\api::set_event_type_display($type, $display, $user);
+ $persist = get_user_preferences('calendar_persistflt', 0, $user);
+ $default = CALENDAR_EVENT_GLOBAL + CALENDAR_EVENT_COURSE + CALENDAR_EVENT_GROUP + CALENDAR_EVENT_USER;
+ if ($persist === 0) {
+ global $SESSION;
+ if (!isset($SESSION->calendarshoweventtype)) {
+ $SESSION->calendarshoweventtype = $default;
+ }
+ $preference = $SESSION->calendarshoweventtype;
+ } else {
+ $preference = get_user_preferences('calendar_savedflt', $default, $user);
+ }
+ $current = $preference & $type;
+ if ($display === null) {
+ $display = !$current;
+ }
+ if ($display && !$current) {
+ $preference += $type;
+ } else if (!$display && $current) {
+ $preference -= $type;
+ }
+ if ($persist === 0) {
+ $SESSION->calendarshoweventtype = $preference;
+ } else {
+ if ($preference == $default) {
+ unset_user_preference('calendar_savedflt', $user);
+ } else {
+ set_user_preference('calendar_savedflt', $preference, $user);
+ }
+ }
}
/**
* @param stdClass|int $course object of a course or course id
*/
function calendar_get_allowed_types(&$allowed, $course = null) {
- \core_calendar\api::get_allowed_types($allowed, $course);
+ global $USER, $DB;
+
+ $allowed = new \stdClass();
+ $allowed->user = has_capability('moodle/calendar:manageownentries', \context_system::instance());
+ $allowed->groups = false;
+ $allowed->courses = false;
+ $allowed->site = has_capability('moodle/calendar:manageentries', \context_course::instance(SITEID));
+
+ if (!empty($course)) {
+ if (!is_object($course)) {
+ $course = $DB->get_record('course', array('id' => $course), '*', MUST_EXIST);
+ }
+ if ($course->id != SITEID) {
+ $coursecontext = \context_course::instance($course->id);
+ $allowed->user = has_capability('moodle/calendar:manageownentries', $coursecontext);
+
+ if (has_capability('moodle/calendar:manageentries', $coursecontext)) {
+ $allowed->courses = array($course->id => 1);
+
+ if ($course->groupmode != NOGROUPS || !$course->groupmodeforce) {
+ if (has_capability('moodle/site:accessallgroups', $coursecontext)) {
+ $allowed->groups = groups_get_all_groups($course->id);
+ } else {
+ $allowed->groups = groups_get_all_groups($course->id, $USER->id);
+ }
+ }
+ } else if (has_capability('moodle/calendar:managegroupentries', $coursecontext)) {
+ if ($course->groupmode != NOGROUPS || !$course->groupmodeforce) {
+ if (has_capability('moodle/site:accessallgroups', $coursecontext)) {
+ $allowed->groups = groups_get_all_groups($course->id);
+ } else {
+ $allowed->groups = groups_get_all_groups($course->id, $USER->id);
+ }
+ }
+ }
+ }
+ }
}
/**
* @return bool has the capability to add at least one event type
*/
function calendar_user_can_add_event($course) {
- return \core_calendar\api::can_add_event_to_course($course);
+ if (!isloggedin() || isguestuser()) {
+ return false;
+ }
+
+ calendar_get_allowed_types($allowed, $course);
+
+ return (bool)($allowed->user || $allowed->groups || $allowed->courses || $allowed->site);
}
/**
* @return bool has the capability to add event
*/
function calendar_add_event_allowed($event) {
- return \core_calendar\api::can_add_event($event);
+ global $USER, $DB;
+
+ // Can not be using guest account.
+ if (!isloggedin() or isguestuser()) {
+ return false;
+ }
+
+ $sitecontext = \context_system::instance();
+
+ // If user has manageentries at site level, always return true.
+ if (has_capability('moodle/calendar:manageentries', $sitecontext)) {
+ return true;
+ }
+
+ switch ($event->eventtype) {
+ case 'course':
+ return has_capability('moodle/calendar:manageentries', $event->context);
+ case 'group':
+ // Allow users to add/edit group events if -
+ // 1) They have manageentries (= entries for whole course).
+ // 2) They have managegroupentries AND are in the group.
+ $group = $DB->get_record('groups', array('id' => $event->groupid));
+ return $group && (
+ has_capability('moodle/calendar:manageentries', $event->context) ||
+ (has_capability('moodle/calendar:managegroupentries', $event->context)
+ && groups_is_member($event->groupid)));
+ case 'user':
+ if ($event->userid == $USER->id) {
+ return (has_capability('moodle/calendar:manageownentries', $event->context));
+ }
+ // There is intentionally no 'break'.
+ case 'site':
+ return has_capability('moodle/calendar:manageentries', $event->context);
+ default:
+ return has_capability('moodle/calendar:manageentries', $event->context);
+ }
}
/**
* @return array An array of poll interval options. Interval => description.
*/
function calendar_get_pollinterval_choices() {
- return \core_calendar\api::get_poll_interval_choices();
+ return array(
+ '0' => new \lang_string('never', 'calendar'),
+ HOURSECS => new \lang_string('hourly', 'calendar'),
+ DAYSECS => new \lang_string('daily', 'calendar'),
+ WEEKSECS => new \lang_string('weekly', 'calendar'),
+ '2628000' => new \lang_string('monthly', 'calendar'),
+ YEARSECS => new \lang_string('annually', 'calendar')
+ );
}
/**
* @return array An array containing the event types the user can create.
*/
function calendar_get_eventtype_choices($courseid) {
- return \core_calendar\api::get_event_type_choices($courseid);
+ $choices = array();
+ $allowed = new \stdClass;
+ calendar_get_allowed_types($allowed, $courseid);
+
+ if ($allowed->user) {
+ $choices['user'] = get_string('userevents', 'calendar');
+ }
+ if ($allowed->site) {
+ $choices['site'] = get_string('siteevents', 'calendar');
+ }
+ if (!empty($allowed->courses)) {
+ $choices['course'] = get_string('courseevents', 'calendar');
+ }
+ if (!empty($allowed->groups) and is_array($allowed->groups)) {
+ $choices['group'] = get_string('group');
+ }
+
+ return array($choices, $allowed->groups);
}
/**
* @return int The insert ID, if any.
*/
function calendar_add_subscription($sub) {
- return \core_calendar\api::add_subscription($sub);
+ global $DB, $USER, $SITE;
+
+ if ($sub->eventtype === 'site') {
+ $sub->courseid = $SITE->id;
+ } else if ($sub->eventtype === 'group' || $sub->eventtype === 'course') {
+ $sub->courseid = $sub->course;
+ } else {
+ // User events.
+ $sub->courseid = 0;
+ }
+ $sub->userid = $USER->id;
+
+ // File subscriptions never update.
+ if (empty($sub->url)) {
+ $sub->pollinterval = 0;
+ }
+
+ if (!empty($sub->name)) {
+ if (empty($sub->id)) {
+ $id = $DB->insert_record('event_subscriptions', $sub);
+ // We cannot cache the data here because $sub is not complete.
+ $sub->id = $id;
+ // Trigger event, calendar subscription added.
+ $eventparams = array('objectid' => $sub->id,
+ 'context' => calendar_get_calendar_context($sub),
+ 'other' => array('eventtype' => $sub->eventtype, 'courseid' => $sub->courseid)
+ );
+ $event = \core\event\calendar_subscription_created::create($eventparams);
+ $event->trigger();
+ return $id;
+ } else {
+ // Why are we doing an update here?
+ calendar_update_subscription($sub);
+ return $sub->id;
+ }
+ } else {
+ print_error('errorbadsubscription', 'importcalendar');
+ }
}
/**
* @return int Code: CALENDAR_IMPORT_EVENT_UPDATED = updated, CALENDAR_IMPORT_EVENT_INSERTED = inserted, 0 = error
*/
function calendar_add_icalendar_event($event, $courseid, $subscriptionid, $timezone='UTC') {
- return \core_calendar\api::add_icalendar_event($event, $courseid, $subscriptionid, $timezone);
+ global $DB;
+
+ // Probably an unsupported X-MICROSOFT-CDO-BUSYSTATUS event.
+ if (empty($event->properties['SUMMARY'])) {
+ return 0;
+ }
+
+ $name = $event->properties['SUMMARY'][0]->value;
+ $name = str_replace('\n', '<br />', $name);
+ $name = str_replace('\\', '', $name);
+ $name = preg_replace('/\s+/u', ' ', $name);
+
+ $eventrecord = new \stdClass;
+ $eventrecord->name = clean_param($name, PARAM_NOTAGS);
+
+ if (empty($event->properties['DESCRIPTION'][0]->value)) {
+ $description = '';
+ } else {
+ $description = $event->properties['DESCRIPTION'][0]->value;
+ $description = clean_param($description, PARAM_NOTAGS);
+ $description = str_replace('\n', '<br />', $description);
+ $description = str_replace('\\', '', $description);
+ $description = preg_replace('/\s+/u', ' ', $description);
+ }
+ $eventrecord->description = $description;
+
+ // Probably a repeating event with RRULE etc. TODO: skip for now.
+ if (empty($event->properties['DTSTART'][0]->value)) {
+ return 0;
+ }
+
+ if (isset($event->properties['DTSTART'][0]->parameters['TZID'])) {
+ $tz = $event->properties['DTSTART'][0]->parameters['TZID'];
+ } else {
+ $tz = $timezone;
+ }
+ $tz = \core_date::normalise_timezone($tz);
+ $eventrecord->timestart = strtotime($event->properties['DTSTART'][0]->value . ' ' . $tz);
+ if (empty($event->properties['DTEND'])) {
+ $eventrecord->timeduration = 0; // No duration if no end time specified.
+ } else {
+ if (isset($event->properties['DTEND'][0]->parameters['TZID'])) {
+ $endtz = $event->properties['DTEND'][0]->parameters['TZID'];
+ } else {
+ $endtz = $timezone;
+ }
+ $endtz = \core_date::normalise_timezone($endtz);
+ $eventrecord->timeduration = strtotime($event->properties['DTEND'][0]->value . ' ' . $endtz) - $eventrecord->timestart;
+ }
+
+ // Check to see if it should be treated as an all day event.
+ if ($eventrecord->timeduration == DAYSECS) {
+ // Check to see if the event started at Midnight on the imported calendar.
+ date_default_timezone_set($timezone);
+ if (date('H:i:s', $eventrecord->timestart) === "00:00:00") {
+ // This event should be an all day event.
+ $eventrecord->timeduration = 0;
+ }
+ \core_date::set_default_server_timezone();
+ }
+
+ $eventrecord->uuid = $event->properties['UID'][0]->value;
+ $eventrecord->timemodified = time();
+
+ // Add the iCal subscription details if required.
+ // We should never do anything with an event without a subscription reference.
+ $sub = calendar_get_subscription($subscriptionid);
+ $eventrecord->subscriptionid = $subscriptionid;
+ $eventrecord->userid = $sub->userid;
+ $eventrecord->groupid = $sub->groupid;
+ $eventrecord->courseid = $sub->courseid;
+ $eventrecord->eventtype = $sub->eventtype;
+
+ if ($updaterecord = $DB->get_record('event', array('uuid' => $eventrecord->uuid,
+ 'subscriptionid' => $eventrecord->subscriptionid))) {
+ $eventrecord->id = $updaterecord->id;
+ $return = CALENDAR_IMPORT_EVENT_UPDATED; // Update.
+ } else {
+ $return = CALENDAR_IMPORT_EVENT_INSERTED; // Insert.
+ }
+ if ($createdevent = \calendar_event::create($eventrecord, false)) {
+ if (!empty($event->properties['RRULE'])) {
+ // Repeating events.
+ date_default_timezone_set($tz); // Change time zone to parse all events.
+ $rrule = new rrule_manager($event->properties['RRULE'][0]->value);
+ $rrule->parse_rrule();
+ $rrule->create_events($createdevent);
+ \core_date::set_default_server_timezone(); // Change time zone back to what it was.
+ }
+ return $return;
+ } else {
+ return 0;
+ }
}
/**
* @return string A log of the import progress, including errors
*/
function calendar_process_subscription_row($subscriptionid, $pollinterval, $action) {
- return \core_calendar\api::process_subscription_row($subscriptionid, $pollinterval, $action);
+ // Fetch the subscription from the database making sure it exists.
+ $sub = calendar_get_subscription($subscriptionid);
+
+ // Update or remove the subscription, based on action.
+ switch ($action) {
+ case CALENDAR_SUBSCRIPTION_UPDATE:
+ // Skip updating file subscriptions.
+ if (empty($sub->url)) {
+ break;
+ }
+ $sub->pollinterval = $pollinterval;
+ calendar_update_subscription($sub);
+
+ // Update the events.
+ return "<p>" . get_string('subscriptionupdated', 'calendar', $sub->name) . "</p>" .
+ calendar_update_subscription_events($subscriptionid);
+ case CALENDAR_SUBSCRIPTION_REMOVE:
+ calendar_delete_subscription($subscriptionid);
+ return get_string('subscriptionremoved', 'calendar', $sub->name);
+ break;
+ default:
+ break;
+ }
+ return '';
}
/**
* @param int|stdClass $subscription subscription or it's id, which needs to be deleted.
*/
function calendar_delete_subscription($subscription) {
- \core_calendar\api::delete_subscription($subscription);
+ global $DB;
+
+ if (!is_object($subscription)) {
+ $subscription = $DB->get_record('event_subscriptions', array('id' => $subscription), '*', MUST_EXIST);
+ }
+
+ // Delete subscription and related events.
+ $DB->delete_records('event', array('subscriptionid' => $subscription->id));
+ $DB->delete_records('event_subscriptions', array('id' => $subscription->id));
+ \cache_helper::invalidate_by_definition('core', 'calendar_subscriptions', array(), array($subscription->id));
+
+ // Trigger event, calendar subscription deleted.
+ $eventparams = array('objectid' => $subscription->id,
+ 'context' => calendar_get_calendar_context($subscription),
+ 'other' => array('courseid' => $subscription->courseid)
+ );
+ $event = \core\event\calendar_subscription_deleted::create($eventparams);
+ $event->trigger();
}
/**
* @return iCalendar The iCalendar object
*/
function calendar_get_icalendar($url) {
- return \core_calendar\api::get_icalendar($url);
+ global $CFG;
+
+ require_once($CFG->libdir . '/filelib.php');
+
+ $curl = new \curl();
+ $curl->setopt(array('CURLOPT_FOLLOWLOCATION' => 1, 'CURLOPT_MAXREDIRS' => 5));
+ $calendar = $curl->get($url);
+
+ // Http code validation should actually be the job of curl class.
+ if (!$calendar || $curl->info['http_code'] != 200 || !empty($curl->errorno)) {
+ throw new \moodle_exception('errorinvalidicalurl', 'calendar');
+ }
+
+ $ical = new \iCalendar();
+ $ical->unserialize($calendar);
+
+ return $ical;
}
/**
* @return string A log of the import progress, including errors.
*/
function calendar_import_icalendar_events($ical, $courseid, $subscriptionid = null) {
- return \core_calendar\api::import_icalendar_events($ical, $courseid, $subscriptionid);
+ global $DB;
+
+ $return = '';
+ $eventcount = 0;
+ $updatecount = 0;
+
+ // Large calendars take a while...
+ if (!CLI_SCRIPT) {
+ \core_php_time_limit::raise(300);
+ }
+
+ // Mark all events in a subscription with a zero timestamp.
+ if (!empty($subscriptionid)) {
+ $sql = "UPDATE {event} SET timemodified = :time WHERE subscriptionid = :id";
+ $DB->execute($sql, array('time' => 0, 'id' => $subscriptionid));
+ }
+
+ // Grab the timezone from the iCalendar file to be used later.
+ if (isset($ical->properties['X-WR-TIMEZONE'][0]->value)) {
+ $timezone = $ical->properties['X-WR-TIMEZONE'][0]->value;
+ } else {
+ $timezone = 'UTC';
+ }
+
+ $return = '';
+ foreach ($ical->components['VEVENT'] as $event) {
+ $res = calendar_add_icalendar_event($event, $courseid, $subscriptionid, $timezone);
+ switch ($res) {
+ case CALENDAR_IMPORT_EVENT_UPDATED:
+ $updatecount++;
+ break;
+ case CALENDAR_IMPORT_EVENT_INSERTED:
+ $eventcount++;
+ break;
+ case 0:
+ $return .= '<p>' . get_string('erroraddingevent', 'calendar') . ': ';
+ if (empty($event->properties['SUMMARY'])) {
+ $return .= '(' . get_string('notitle', 'calendar') . ')';
+ } else {
+ $return .= $event->properties['SUMMARY'][0]->value;
+ }
+ $return .= "</p>\n";
+ break;
+ }
+ }
+
+ $return .= "<p>" . get_string('eventsimported', 'calendar', $eventcount) . "</p> ";
+ $return .= "<p>" . get_string('eventsupdated', 'calendar', $updatecount) . "</p>";
+
+ // Delete remaining zero-marked events since they're not in remote calendar.
+ if (!empty($subscriptionid)) {
+ $deletecount = $DB->count_records('event', array('timemodified' => 0, 'subscriptionid' => $subscriptionid));
+ if (!empty($deletecount)) {
+ $DB->delete_records('event', array('timemodified' => 0, 'subscriptionid' => $subscriptionid));
+ $return .= "<p> " . get_string('eventsdeleted', 'calendar') . ": {$deletecount} </p>\n";
+ }
+ }
+
+ return $return;
}
/**
* @return string A log of the import progress, including errors.
*/
function calendar_update_subscription_events($subscriptionid) {
- return \core_calendar\api::update_subscription_events($subscriptionid);
+ $sub = calendar_get_subscription($subscriptionid);
+
+ // Don't update a file subscription.
+ if (empty($sub->url)) {
+ return 'File subscription not updated.';
+ }
+
+ $ical = calendar_get_icalendar($sub->url);
+ $return = calendar_import_icalendar_events($ical, $sub->courseid, $subscriptionid);
+ $sub->lastupdated = time();
+
+ calendar_update_subscription($sub);
+
+ return $return;
}
/**
* @since Moodle 2.5
*/
function calendar_update_subscription($subscription) {
- \core_calendar\api::update_subscription($subscription);
+ global $DB;
+
+ if (is_array($subscription)) {
+ $subscription = (object)$subscription;
+ }
+ if (empty($subscription->id) || !$DB->record_exists('event_subscriptions', array('id' => $subscription->id))) {
+ throw new \coding_exception('Cannot update a subscription without a valid id');
+ }
+
+ $DB->update_record('event_subscriptions', $subscription);
+
+ // Update cache.
+ $cache = \cache::make('core', 'calendar_subscriptions');
+ $cache->set($subscription->id, $subscription);
+
+ // Trigger event, calendar subscription updated.
+ $eventparams = array('userid' => $subscription->userid,
+ 'objectid' => $subscription->id,
+ 'context' => calendar_get_calendar_context($subscription),
+ 'other' => array('eventtype' => $subscription->eventtype, 'courseid' => $subscription->courseid)
+ );
+ $event = \core\event\calendar_subscription_updated::create($eventparams);
+ $event->trigger();
}
/**
* @return bool true if current user can edit the subscription else false
*/
function calendar_can_edit_subscription($subscriptionorid) {
- return \core_calendar\api::can_edit_subscription($subscriptionorid);
+ if (is_array($subscriptionorid)) {
+ $subscription = (object)$subscriptionorid;
+ } else if (is_object($subscriptionorid)) {
+ $subscription = $subscriptionorid;
+ } else {
+ $subscription = calendar_get_subscription($subscriptionorid);
+ }
+
+ $allowed = new \stdClass;
+ $courseid = $subscription->courseid;
+ $groupid = $subscription->groupid;
+
+ calendar_get_allowed_types($allowed, $courseid);
+ switch ($subscription->eventtype) {
+ case 'user':
+ return $allowed->user;
+ case 'course':
+ if (isset($allowed->courses[$courseid])) {
+ return $allowed->courses[$courseid];
+ } else {
+ return false;
+ }
+ case 'site':
+ return $allowed->site;
+ case 'group':
+ if (isset($allowed->groups[$groupid])) {
+ return $allowed->groups[$groupid];
+ } else {
+ return false;
+ }
+ default:
+ return false;
+ }
}
/**
* @return context instance
*/
function calendar_get_calendar_context($subscription) {
- return \core_calendar\api::get_calendar_context($subscription);
+ // Determine context based on calendar type.
+ if ($subscription->eventtype === 'site') {
+ $context = \context_course::instance(SITEID);
+ } else if ($subscription->eventtype === 'group' || $subscription->eventtype === 'course') {
+ $context = \context_course::instance($subscription->courseid);
+ } else {
+ $context = \context_user::instance($subscription->userid);
+ }
+ return $context;
}
/**
$courses = array($course->id => $course);
} else {
$course = get_site();
- $courses = \core_calendar\api::get_default_courses();
+ $courses = calendar_get_default_courses();
}
require_course_login($course);
-if (!\core_calendar\api::can_add_event_to_course($course)) {
+if (!calendar_user_can_add_event($course)) {
print_error('errorcannotimport', 'calendar');
}
$formdata = $form->get_data();
if (!empty($formdata)) {
require_sesskey(); // Must have sesskey for all actions.
- $subscriptionid = \core_calendar\api::add_subscription($formdata);
+ $subscriptionid = calendar_add_subscription($formdata);
if ($formdata->importfrom == CALENDAR_IMPORT_FROM_FILE) {
// Blank the URL if it's a file import.
$formdata->url = '';
$calendar = $form->get_file_content('importfile');
$ical = new iCalendar();
$ical->unserialize($calendar);
- $importresults = \core_calendar\api::import_icalendar_events($ical, $courseid, $subscriptionid);
+ $importresults = calendar_import_icalendar_events($ical, $courseid, $subscriptionid);
} else {
try {
- $importresults = \core_calendar\api::update_subscription_events($subscriptionid);
+ $importresults = calendar_update_subscription_events($subscriptionid);
} catch (moodle_exception $e) {
// Delete newly added subscription and show invalid url error.
- \core_calendar\api::delete_subscription($subscriptionid);
+ calendar_delete_subscription($subscriptionid);
print_error($e->errorcode, $e->module, $PAGE->url);
}
}
} else if (!empty($subscriptionid)) {
// The user is wanting to perform an action upon an existing subscription.
require_sesskey(); // Must have sesskey for all actions.
- if (\core_calendar\api::can_edit_subscription($subscriptionid)) {
+ if (calendar_can_edit_subscription($subscriptionid)) {
try {
- $importresults = \core_calendar\api::process_subscription_row($subscriptionid, $pollinterval, $action);
+ $importresults = calendar_process_subscription_row($subscriptionid, $pollinterval, $action);
} catch (moodle_exception $e) {
// If exception caught, then user should be redirected to page where he/she came from.
print_error($e->errorcode, $e->module, $PAGE->url);
// Filter subscriptions which user can't edit.
foreach($subscriptions as $subscription) {
- if (!\core_calendar\api::can_edit_subscription($subscription)) {
+ if (!calendar_can_edit_subscription($subscription)) {
unset($subscriptions[$subscription->id]);
}
}
$mform->setForceLtr('url');
// Poll interval
- $choices = \core_calendar\api::get_poll_interval_choices();
+ $choices = calendar_get_pollinterval_choices();
$mform->addElement('select', 'pollinterval', get_string('pollinterval', 'calendar'), $choices);
$mform->setDefault('pollinterval', 604800);
$mform->addHelpButton('pollinterval', 'pollinterval', 'calendar');
$mform->disabledIf('importfile', 'importfrom', 'eq', CALENDAR_IMPORT_FROM_URL);
// Eventtype: 0 = user, 1 = global, anything else = course ID.
- list($choices, $groups) = \core_calendar\api::get_event_type_choices($courseid);
+ list($choices, $groups) = calendar_get_eventtype_choices($courseid);
$mform->addElement('select', 'eventtype', get_string('eventkind', 'calendar'), $choices);
$mform->addRule('eventtype', get_string('required'), 'required');
$mform->setType('eventtype', PARAM_ALPHA);
public function fake_block_filters($courseid, $day, $month, $year, $view, $courses) {
$returnurl = $this->page->url;
$returnurl->param('course', $courseid);
- return html_writer::tag('div', \core_calendar\api::get_filter_controls($returnurl),
+ return html_writer::tag('div', calendar_filter_controls($returnurl),
array('class' => 'calendar_filters filters'));
}
$date = $calendartype->timestamp_to_date_array($calendar->time);
- $prevmonth = \core_calendar\api::get_prev_month($date['mon'], $date['year']);
+ $prevmonth = calendar_sub_month($date['mon'], $date['year']);
$prevmonthtime = $calendartype->convert_to_gregorian($prevmonth[1], $prevmonth[0], 1);
$prevmonthtime = make_timestamp($prevmonthtime['year'], $prevmonthtime['month'], $prevmonthtime['day'],
$prevmonthtime['hour'], $prevmonthtime['minute']);
- $nextmonth = \core_calendar\api::get_next_month($date['mon'], $date['year']);
+ $nextmonth = calendar_add_month($date['mon'], $date['year']);
$nextmonthtime = $calendartype->convert_to_gregorian($nextmonth[1], $nextmonth[0], 1);
$nextmonthtime = make_timestamp($nextmonthtime['year'], $nextmonthtime['month'], $nextmonthtime['day'],
$nextmonthtime['hour'], $nextmonthtime['minute']);
$content = html_writer::start_tag('div', array('class' => 'minicalendarblock'));
- $content .= \core_calendar\api::get_mini_calendar($calendar->courses, $calendar->groups, $calendar->users,
+ $content .= calendar_get_mini($calendar->courses, $calendar->groups, $calendar->users,
false, false, 'display', $calendar->courseid, $prevmonthtime);
$content .= html_writer::end_tag('div');
$content .= html_writer::start_tag('div', array('class' => 'minicalendarblock'));
- $content .= \core_calendar\api::get_mini_calendar($calendar->courses, $calendar->groups, $calendar->users,
+ $content .= calendar_get_mini($calendar->courses, $calendar->groups, $calendar->users,
false, false, 'display', $calendar->courseid, $calendar->time);
$content .= html_writer::end_tag('div');
$content .= html_writer::start_tag('div', array('class' => 'minicalendarblock'));
- $content .= \core_calendar\api::get_mini_calendar($calendar->courses, $calendar->groups, $calendar->users,
+ $content .= calendar_get_mini($calendar->courses, $calendar->groups, $calendar->users,
false, false, 'display', $calendar->courseid, $nextmonthtime);
$content .= html_writer::end_tag('div');
return $content;
$returnurl = $this->page->url;
}
- $events = \core_calendar\api::get_upcoming($calendar->courses, $calendar->groups, $calendar->users,
+ $events = calendar_get_upcoming($calendar->courses, $calendar->groups, $calendar->users,
1, 100, $calendar->timestamp_today());
$output = html_writer::start_tag('div', array('class'=>'header'));
$output .= $this->course_filter_selector($returnurl, get_string('dayviewfor', 'calendar'));
- if (\core_calendar\api::can_add_event_to_course($calendar->course)) {
+ if (calendar_user_can_add_event($calendar->course)) {
$output .= $this->add_event_button($calendar->course->id, 0, 0, 0, $calendar->time);
}
$output .= html_writer::end_tag('div');
// Controls
- $output .= html_writer::tag('div', \core_calendar\api::get_top_controls('day', array('id' => $calendar->courseid,
+ $output .= html_writer::tag('div', calendar_top_controls('day', array('id' => $calendar->courseid,
'time' => $calendar->time)), array('class' => 'controls'));
if (empty($events)) {
$event = new calendar_event($event);
$event->calendarcourseid = $calendar->courseid;
if ($event->timestart >= $calendar->timestamp_today() && $event->timestart <= $calendar->timestamp_tomorrow()-1) { // Print it now
- $event->time = \core_calendar\api::get_format_event_time($event, time(), null, false,
+ $event->time = calendar_format_event_time($event, time(), null, false,
$calendar->timestamp_today());
$output .= $this->event($event);
} else { // Save this for later
$output .= html_writer::span(get_string('spanningevents', 'calendar'),
'calendar-information calendar-span-multiple-days');
foreach ($underway as $event) {
- $event->time = \core_calendar\api::get_format_event_time($event, time(), null, false,
+ $event->time = calendar_format_event_time($event, time(), null, false,
$calendar->timestamp_today());
$output .= $this->event($event);
}
public function event(calendar_event $event, $showactions=true) {
global $CFG;
- $event = \core_calendar\api::add_event_metadata($event);
+ $event = calendar_add_event_metadata($event);
$context = $event->context;
$output = '';
$output .= $this->output->box_start('card-header clearfix');
- if (\core_calendar\api::can_edit_event($event) && $showactions) {
+ if (calendar_edit_event_allowed($event) && $showactions) {
if (empty($event->cmid)) {
$editlink = new moodle_url(CALENDAR_URL.'event.php', array('action' => 'edit', 'id' => $event->id));
$deletelink = new moodle_url(CALENDAR_URL.'delete.php', array('id' => $event->id));
$output .= html_writer::tag('span', $event->time, array('class' => 'date pull-xs-right m-r-1'));
} else {
$attrs = array('class' => 'date pull-xs-right m-r-1');
- $output .= html_writer::tag('span', \core_calendar\api::get_time_representation($event->timestart), $attrs);
+ $output .= html_writer::tag('span', calendar_time_representation($event->timestart), $attrs);
}
if (!empty($event->courselink)) {
$output .= html_writer::tag('div', $event->courselink, array('class' => 'course'));
// Get the starting week day for this month.
$startwday = dayofweek(1, $date['mon'], $date['year']);
// Get the days in a week.
- $daynames = \core_calendar\api::get_days();
+ $daynames = calendar_get_days();
// Store the number of days in a week.
$numberofdaysinweek = $calendartype->get_num_weekdays();
- $display->minwday = \core_calendar\api::get_starting_weekday();
+ $display->minwday = calendar_get_starting_weekday();
$display->maxwday = $display->minwday + ($numberofdaysinweek - 1);
- $display->maxdays = \core_calendar\api::get_days_in_month($date['mon'], $date['year']);
+ $display->maxdays = calendar_days_in_month($date['mon'], $date['year']);
// These are used for DB queries, so we want unixtime, so we need to use Gregorian dates.
$display->tstart = make_timestamp($gy, $gm, $gd, $gh, $gmin, 0);
}
// Get events from database
- $events = \core_calendar\api::get_events($display->tstart, $display->tend, $calendar->users, $calendar->groups,
+ $events = calendar_get_events($display->tstart, $display->tend, $calendar->users, $calendar->groups,
$calendar->courses);
if (!empty($events)) {
foreach($events as $eventid => $event) {
}
// Extract information: events vs. time
- \core_calendar\api::get_events_by_day($events, $date['mon'], $date['year'], $eventsbyday, $durationbyday,
+ calendar_events_by_day($events, $date['mon'], $date['year'], $eventsbyday, $durationbyday,
$typesbyday, $calendar->courses);
$output = html_writer::start_tag('div', array('class'=>'header'));
$output .= $this->course_filter_selector($returnurl, get_string('detailedmonthviewfor', 'calendar'));
- if (\core_calendar\api::can_add_event_to_course($calendar->course)) {
+ if (calendar_user_can_add_event($calendar->course)) {
$output .= $this->add_event_button($calendar->course->id, 0, 0, 0, $calendar->time);
}
$output .= html_writer::end_tag('div', array('class'=>'header'));
// Controls
- $output .= html_writer::tag('div', \core_calendar\api::get_top_controls('month', array('id' => $calendar->courseid,
+ $output .= html_writer::tag('div', calendar_top_controls('month', array('id' => $calendar->courseid,
'time' => $calendar->time)), array('class' => 'controls'));
$table = new html_table();
// Reset vars
$cell = new html_table_cell();
- $dayhref = \core_calendar\api::get_link_href(new moodle_url(CALENDAR_URL . 'view.php',
+ $dayhref = calendar_get_link_href(new moodle_url(CALENDAR_URL . 'view.php',
array('view' => 'day', 'course' => $calendar->courseid)), 0, 0, 0, $daytime);
$cellclasses = array();
$returnurl = $this->page->url;
}
- $events = \core_calendar\api::get_upcoming($calendar->courses, $calendar->groups, $calendar->users,
+ $events = calendar_get_upcoming($calendar->courses, $calendar->groups, $calendar->users,
$futuredays, $maxevents);
$output = html_writer::start_tag('div', array('class'=>'header'));
$output .= $this->course_filter_selector($returnurl, get_string('upcomingeventsfor', 'calendar'));
- if (\core_calendar\api::can_add_event_to_course($calendar->course)) {
+ if (calendar_user_can_add_event($calendar->course)) {
$output .= $this->add_event_button($calendar->course->id);
}
$output .= html_writer::end_tag('div');
// Assemble pollinterval control.
$html .= html_writer::start_tag('div', array('style' => 'float:left;'));
$html .= html_writer::start_tag('select', array('name' => 'pollinterval', 'class' => 'custom-select'));
- foreach (\core_calendar\api::get_poll_interval_choices() as $k => $v) {
+ foreach (calendar_get_pollinterval_choices() as $k => $v) {
$attributes = array();
if ($k == $subscription->pollinterval) {
$attributes['selected'] = 'selected';
switch($var) {
case 'showgroups':
- \core_calendar\api::set_event_type_display(CALENDAR_EVENT_GROUP);
+ calendar_set_event_type_display(CALENDAR_EVENT_GROUP);
break;
case 'showcourses':
- \core_calendar\api::set_event_type_display(CALENDAR_EVENT_COURSE);
+ calendar_set_event_type_display(CALENDAR_EVENT_COURSE);
break;
case 'showglobal':
- \core_calendar\api::set_event_type_display(CALENDAR_EVENT_GLOBAL);
+ calendar_set_event_type_display(CALENDAR_EVENT_GLOBAL);
break;
case 'showuser':
- \core_calendar\api::set_event_type_display(CALENDAR_EVENT_USER);
+ calendar_set_event_type_display(CALENDAR_EVENT_USER);
break;
}
$this->resetAfterTest();
}
- public function test_get_course_cached() {
- // Setup some test courses.
- $course1 = $this->getDataGenerator()->create_course();
- $course2 = $this->getDataGenerator()->create_course();
- $course3 = $this->getDataGenerator()->create_course();
-
- // Load courses into cache.
- $coursecache = null;
- \core_calendar\api::get_course_cached($coursecache, $course1->id);
- \core_calendar\api::get_course_cached($coursecache, $course2->id);
- \core_calendar\api::get_course_cached($coursecache, $course3->id);
-
- // Verify the cache.
- $this->assertArrayHasKey($course1->id, $coursecache);
- $cachedcourse1 = $coursecache[$course1->id];
- $this->assertEquals($course1->id, $cachedcourse1->id);
- $this->assertEquals($course1->shortname, $cachedcourse1->shortname);
- $this->assertEquals($course1->fullname, $cachedcourse1->fullname);
-
- $this->assertArrayHasKey($course2->id, $coursecache);
- $cachedcourse2 = $coursecache[$course2->id];
- $this->assertEquals($course2->id, $cachedcourse2->id);
- $this->assertEquals($course2->shortname, $cachedcourse2->shortname);
- $this->assertEquals($course2->fullname, $cachedcourse2->fullname);
-
- $this->assertArrayHasKey($course3->id, $coursecache);
- $cachedcourse3 = $coursecache[$course3->id];
- $this->assertEquals($course3->id, $cachedcourse3->id);
- $this->assertEquals($course3->shortname, $cachedcourse3->shortname);
- $this->assertEquals($course3->fullname, $cachedcourse3->fullname);
- }
-
- /**
- * Test that the get_events() function only returns activity events that are enabled.
- */
- public function test_get_events_with_disabled_module() {
- global $DB;
- $this->setAdminUser();
- $generator = $this->getDataGenerator();
- $course = $generator->create_course();
- $assigngenerator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
- $assigninstance = $assigngenerator->create_instance(['course' => $course->id]);
- $lessongenerator = $this->getDataGenerator()->get_plugin_generator('mod_lesson');
- $lessoninstance = $lessongenerator->create_instance(['course' => $course->id]);
- $student = $generator->create_user();
- $generator->enrol_user($student->id, $course->id, 'student');
- $this->setUser($student);
- $events = [
- [
- 'name' => 'Start of assignment',
- 'description' => '',
- 'format' => 1,
- 'courseid' => $course->id,
- 'groupid' => 0,
- 'userid' => 2,
- 'modulename' => 'assign',
- 'instance' => $assigninstance->id,
- 'eventtype' => 'due',
- 'timestart' => time(),
- 'timeduration' => 86400,
- 'visible' => 1
- ], [
- 'name' => 'Start of lesson',
- 'description' => '',
- 'format' => 1,
- 'courseid' => $course->id,
- 'groupid' => 0,
- 'userid' => 2,
- 'modulename' => 'lesson',
- 'instance' => $lessoninstance->id,
- 'eventtype' => 'end',
- 'timestart' => time(),
- 'timeduration' => 86400,
- 'visible' => 1
- ]
- ];
- foreach ($events as $event) {
- calendar_event::create($event, false);
- }
- $timestart = time() - 60;
- $timeend = time() + 60;
- // Get all events.
- $events = \core_calendar\api::get_events($timestart, $timeend, true, 0, true);
- $this->assertCount(2, $events);
- // Disable the lesson module.
- $modulerecord = $DB->get_record('modules', ['name' => 'lesson']);
- $modulerecord->visible = 0;
- $DB->update_record('modules', $modulerecord);
- // Check that we only return the assign event.
- $events = \core_calendar\api::get_events($timestart, $timeend, true, 0, true);
- $this->assertCount(1, $events);
- $event = reset($events);
- $this->assertEquals('assign', $event->modulename);
- }
-
- /**
- * Test for calendar_get_events() when there are user and group overrides.
- */
- public function test_calendar_get_events_with_overrides() {
- global $DB;
- $generator = $this->getDataGenerator();
- $course = $generator->create_course();
- $plugingenerator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
- if (!isset($params['course'])) {
- $params['course'] = $course->id;
- }
- $instance = $plugingenerator->create_instance($params);
- // Create users.
- $useroverridestudent = $generator->create_user();
- $group1student = $generator->create_user();
- $group2student = $generator->create_user();
- $group12student = $generator->create_user();
- $nogroupstudent = $generator->create_user();
- // Enrol users.
- $generator->enrol_user($useroverridestudent->id, $course->id, 'student');
- $generator->enrol_user($group1student->id, $course->id, 'student');
- $generator->enrol_user($group2student->id, $course->id, 'student');
- $generator->enrol_user($group12student->id, $course->id, 'student');
- $generator->enrol_user($nogroupstudent->id, $course->id, 'student');
- // Create groups.
- $group1 = $generator->create_group(['courseid' => $course->id]);
- $group2 = $generator->create_group(['courseid' => $course->id]);
- // Add members to groups.
- $generator->create_group_member(['groupid' => $group1->id, 'userid' => $group1student->id]);
- $generator->create_group_member(['groupid' => $group2->id, 'userid' => $group2student->id]);
- $generator->create_group_member(['groupid' => $group1->id, 'userid' => $group12student->id]);
- $generator->create_group_member(['groupid' => $group2->id, 'userid' => $group12student->id]);
- $now = time();
- // Events with the same module name, instance and event type.
- $events = [
- [
- 'name' => 'Assignment 1 due date',
- 'description' => '',
- 'format' => 0,
- 'courseid' => $course->id,
- 'groupid' => 0,
- 'userid' => 2,
- 'modulename' => 'assign',
- 'instance' => $instance->id,
- 'eventtype' => 'due',
- 'timestart' => $now,
- 'timeduration' => 0,
- 'visible' => 1
- ], [
- 'name' => 'Assignment 1 due date - User override',
- 'description' => '',
- 'format' => 1,
- 'courseid' => 0,
- 'groupid' => 0,
- 'userid' => $useroverridestudent->id,
- 'modulename' => 'assign',
- 'instance' => $instance->id,
- 'eventtype' => 'due',
- 'timestart' => $now + 86400,
- 'timeduration' => 0,
- 'visible' => 1,
- 'priority' => CALENDAR_EVENT_USER_OVERRIDE_PRIORITY
- ], [
- 'name' => 'Assignment 1 due date - Group A override',
- 'description' => '',
- 'format' => 1,
- 'courseid' => $course->id,
- 'groupid' => $group1->id,
- 'userid' => 2,
- 'modulename' => 'assign',
- 'instance' => $instance->id,
- 'eventtype' => 'due',
- 'timestart' => $now + (2 * 86400),
- 'timeduration' => 0,
- 'visible' => 1,
- 'priority' => 1,
- ], [
- 'name' => 'Assignment 1 due date - Group B override',
- 'description' => '',
- 'format' => 1,
- 'courseid' => $course->id,
- 'groupid' => $group2->id,
- 'userid' => 2,
- 'modulename' => 'assign',
- 'instance' => $instance->id,
- 'eventtype' => 'due',
- 'timestart' => $now + (3 * 86400),
- 'timeduration' => 0,
- 'visible' => 1,
- 'priority' => 2,
- ],
- ];
- foreach ($events as $event) {
- calendar_event::create($event, false);
- }
- $timestart = $now - 100;
- $timeend = $now + (3 * 86400);
- $groups = [$group1->id, $group2->id];
- // Get user override events.
- $this->setUser($useroverridestudent);
- $events = \core_calendar\api::get_events($timestart, $timeend, $useroverridestudent->id, $groups, $course->id);
- $this->assertCount(1, $events);
- $event = reset($events);
- $this->assertEquals('Assignment 1 due date - User override', $event->name);
- // Get event for user with override but with the timestart and timeend parameters only covering the original event.
- $events = \core_calendar\api::get_events($timestart, $now, $useroverridestudent->id, $groups, $course->id);
- $this->assertCount(0, $events);
- // Get events for user that does not belong to any group and has no user override events.
- $this->setUser($nogroupstudent);
- $events = \core_calendar\api::get_events($timestart, $timeend, $nogroupstudent->id, $groups, $course->id);
- $this->assertCount(1, $events);
- $event = reset($events);
- $this->assertEquals('Assignment 1 due date', $event->name);
- // Get events for user that belongs to groups A and B and has no user override events.
- $this->setUser($group12student);
- $events = \core_calendar\api::get_events($timestart, $timeend, $group12student->id, $groups, $course->id);
- $this->assertCount(1, $events);
- $event = reset($events);
- $this->assertEquals('Assignment 1 due date - Group B override', $event->name);
- // Get events for user that belongs to group A and has no user override events.
- $this->setUser($group1student);
- $events = \core_calendar\api::get_events($timestart, $timeend, $group1student->id, $groups, $course->id);
- $this->assertCount(1, $events);
- $event = reset($events);
- $this->assertEquals('Assignment 1 due date - Group A override', $event->name);
- // Add repeating events.
- $repeatingevents = [
- [
- 'name' => 'Repeating site event',
- 'description' => '',
- 'format' => 1,
- 'courseid' => SITEID,
- 'groupid' => 0,
- 'userid' => 2,
- 'repeatid' => $event->id,
- 'modulename' => '0',
- 'instance' => 0,
- 'eventtype' => 'site',
- 'timestart' => $now + 86400,
- 'timeduration' => 0,
- 'visible' => 1,
- ],
- [
- 'name' => 'Repeating site event',
- 'description' => '',
- 'format' => 1,
- 'courseid' => SITEID,
- 'groupid' => 0,
- 'userid' => 2,
- 'repeatid' => $event->id,
- 'modulename' => '0',
- 'instance' => 0,
- 'eventtype' => 'site',
- 'timestart' => $now + (2 * 86400),
- 'timeduration' => 0,
- 'visible' => 1,
- ],
- ];
- foreach ($repeatingevents as $event) {
- calendar_event::create($event, false);
- }
- // Make sure repeating events are not filtered out.
- $events = \core_calendar\api::get_events($timestart, $timeend, true, true, true);
- $this->assertCount(3, $events);
- }
-
- /**
- * Test the update_subscription() function.
- */
- public function test_update_subscription() {
- $this->resetAfterTest(true);
-
- $subscription = new stdClass();
- $subscription->eventtype = 'site';
- $subscription->name = 'test';
- $id = \core_calendar\api::add_subscription($subscription);
-
- $subscription = \core_calendar\api::get_subscription($id);
- $subscription->name = 'awesome';
- \core_calendar\api::update_subscription($subscription);
- $sub = \core_calendar\api::get_subscription($id);
- $this->assertEquals($subscription->name, $sub->name);
-
- $subscription = \core_calendar\api::get_subscription($id);
- $subscription->name = 'awesome2';
- $subscription->pollinterval = 604800;
- \core_calendar\api::update_subscription($subscription);
- $sub = \core_calendar\api::get_subscription($id);
- $this->assertEquals($subscription->name, $sub->name);
- $this->assertEquals($subscription->pollinterval, $sub->pollinterval);
-
- $subscription = new stdClass();
- $subscription->name = 'awesome4';
- $this->expectException('coding_exception');
- \core_calendar\api::update_subscription($subscription);
- }
-
- public function test_add_subscription() {
- global $DB, $CFG;
-
- require_once($CFG->dirroot . '/lib/bennu/bennu.inc.php');
-
- $this->resetAfterTest(true);
-
- // Test for Microsoft Outlook 2010.
- $subscription = new stdClass();
- $subscription->name = 'Microsoft Outlook 2010';
- $subscription->importfrom = CALENDAR_IMPORT_FROM_FILE;
- $subscription->eventtype = 'site';
- $id = \core_calendar\api::add_subscription($subscription);
-
- $calendar = file_get_contents($CFG->dirroot . '/lib/tests/fixtures/ms_outlook_2010.ics');
- $ical = new iCalendar();
- $ical->unserialize($calendar);
- $this->assertEquals($ical->parser_errors, array());
-
- $sub = \core_calendar\api::get_subscription($id);
- \core_calendar\api::import_icalendar_events($ical, $sub->courseid, $sub->id);
- $count = $DB->count_records('event', array('subscriptionid' => $sub->id));
- $this->assertEquals($count, 1);
-
- // Test for OSX Yosemite.
- $subscription = new stdClass();
- $subscription->name = 'OSX Yosemite';
- $subscription->importfrom = CALENDAR_IMPORT_FROM_FILE;
- $subscription->eventtype = 'site';
- $id = \core_calendar\api::add_subscription($subscription);
-
- $calendar = file_get_contents($CFG->dirroot . '/lib/tests/fixtures/osx_yosemite.ics');
- $ical = new iCalendar();
- $ical->unserialize($calendar);
- $this->assertEquals($ical->parser_errors, array());
-
- $sub = \core_calendar\api::get_subscription($id);
- \core_calendar\api::import_icalendar_events($ical, $sub->courseid, $sub->id);
- $count = $DB->count_records('event', array('subscriptionid' => $sub->id));
- $this->assertEquals($count, 1);
-
- // Test for Google Gmail.
- $subscription = new stdClass();
- $subscription->name = 'Google Gmail';
- $subscription->importfrom = CALENDAR_IMPORT_FROM_FILE;
- $subscription->eventtype = 'site';
- $id = \core_calendar\api::add_subscription($subscription);
-
- $calendar = file_get_contents($CFG->dirroot . '/lib/tests/fixtures/google_gmail.ics');
- $ical = new iCalendar();
- $ical->unserialize($calendar);
- $this->assertEquals($ical->parser_errors, array());
-
- $sub = \core_calendar\api::get_subscription($id);
- \core_calendar\api::import_icalendar_events($ical, $sub->courseid, $sub->id);
- $count = $DB->count_records('event', array('subscriptionid' => $sub->id));
- $this->assertEquals($count, 1);
- }
-
/**
* Requesting calendar events from a given time should return all events with a sort
* time at or after the requested time. All events prior to that time should not
userdate($this->user->timecreated));
// Test the calendar/lib.php functions.
- $this->assertEquals($calendar->get_weekdays(), \core_calendar\api::get_days());
- $this->assertEquals($calendar->get_starting_weekday(), \core_calendar\api::get_starting_weekday());
- $this->assertEquals($calendar->get_num_days_in_month('1986', '9'), \core_calendar\api::get_days_in_month('9', '1986'));
- $this->assertEquals($calendar->get_next_month('1986', '9'), \core_calendar\api::get_next_month('9', '1986'));
- $this->assertEquals($calendar->get_prev_month('1986', '9'), \core_calendar\api::get_prev_month('9', '1986'));
+ $this->assertEquals($calendar->get_weekdays(), calendar_get_days());
+ $this->assertEquals($calendar->get_starting_weekday(), calendar_get_starting_weekday());
+ $this->assertEquals($calendar->get_num_days_in_month('1986', '9'), calendar_days_in_month('9', '1986'));
+ $this->assertEquals($calendar->get_next_month('1986', '9'), calendar_add_month('9', '1986'));
+ $this->assertEquals($calendar->get_prev_month('1986', '9'), calendar_sub_month('9', '1986'));
// Test the lib/moodle.php functions.
$this->assertEquals($calendar->get_num_days_in_month('1986', '9'), days_in_month('9', '1986'));
// Trigger and capture the event.
$sink = $this->redirectEvents();
- $id = \core_calendar\api::add_subscription($subscription);
+ $id = calendar_add_subscription($subscription);
$events = $sink->get_events();
$event = reset($events);
$subscription->eventtype = 'site';
$subscription->name = 'test';
$subscription->courseid = $this->course->id;
- $subscription->id = \core_calendar\api::add_subscription($subscription);
+ $subscription->id = calendar_add_subscription($subscription);
// Now edit it.
$subscription->name = 'awesome';
// Trigger and capture the event.
$sink = $this->redirectEvents();
- \core_calendar\api::update_subscription($subscription);
+ calendar_update_subscription($subscription);
$events = $sink->get_events();
$event = reset($events);
// Check that the event data is valid.
$subscription->eventtype = 'site';
$subscription->name = 'test';
$subscription->courseid = $this->course->id;
- $subscription->id = \core_calendar\api::add_subscription($subscription);
+ $subscription->id = calendar_add_subscription($subscription);
// Trigger and capture the event.
$sink = $this->redirectEvents();
- \core_calendar\api::delete_subscription($subscription);
+ calendar_delete_subscription($subscription);
$events = $sink->get_events();
$event = reset($events);
// Check that the event data is valid.
--- /dev/null
+<?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 the class containing unit tests for the calendar lib.
+ *
+ * @package core_calendar
+ * @copyright 2017 Mark Nelson <markn@moodle.com>
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+require_once(__DIR__ . '/helpers.php');
+
+/**
+ * Class contaning unit tests for the calendar lib.
+ *
+ * @package core_calendar
+ * @copyright 2017 Mark Nelson <markn@moodle.com>
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class core_calendar_lib_testcase extends advanced_testcase {
+
+ /**
+ * Tests set up
+ */
+ protected function setUp() {
+ $this->resetAfterTest();
+ }
+
+ /**
+ * Test that the get_events() function only returns activity events that are enabled.
+ */
+ public function test_get_events_with_disabled_module() {
+ global $DB;
+ $this->setAdminUser();
+ $generator = $this->getDataGenerator();
+ $course = $generator->create_course();
+ $assigngenerator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
+ $assigninstance = $assigngenerator->create_instance(['course' => $course->id]);
+ $lessongenerator = $this->getDataGenerator()->get_plugin_generator('mod_lesson');
+ $lessoninstance = $lessongenerator->create_instance(['course' => $course->id]);
+ $student = $generator->create_user();
+ $generator->enrol_user($student->id, $course->id, 'student');
+ $this->setUser($student);
+ $events = [
+ [
+ 'name' => 'Start of assignment',
+ 'description' => '',
+ 'format' => 1,
+ 'courseid' => $course->id,
+ 'groupid' => 0,
+ 'userid' => 2,
+ 'modulename' => 'assign',
+ 'instance' => $assigninstance->id,
+ 'eventtype' => 'due',
+ 'timestart' => time(),
+ 'timeduration' => 86400,
+ 'visible' => 1
+ ], [
+ 'name' => 'Start of lesson',
+ 'description' => '',
+ 'format' => 1,
+ 'courseid' => $course->id,
+ 'groupid' => 0,
+ 'userid' => 2,
+ 'modulename' => 'lesson',
+ 'instance' => $lessoninstance->id,
+ 'eventtype' => 'end',
+ 'timestart' => time(),
+ 'timeduration' => 86400,
+ 'visible' => 1
+ ]
+ ];
+ foreach ($events as $event) {
+ calendar_event::create($event, false);
+ }
+ $timestart = time() - 60;
+ $timeend = time() + 60;
+ // Get all events.
+ $events = calendar_get_events($timestart, $timeend, true, 0, true);
+ $this->assertCount(2, $events);
+ // Disable the lesson module.
+ $modulerecord = $DB->get_record('modules', ['name' => 'lesson']);
+ $modulerecord->visible = 0;
+ $DB->update_record('modules', $modulerecord);
+ // Check that we only return the assign event.
+ $events = calendar_get_events($timestart, $timeend, true, 0, true);
+ $this->assertCount(1, $events);
+ $event = reset($events);
+ $this->assertEquals('assign', $event->modulename);
+ }
+
+ /**
+ * Test for calendar_get_events() when there are user and group overrides.
+ */
+ public function test_calendar_get_events_with_overrides() {
+ global $DB;
+ $generator = $this->getDataGenerator();
+ $course = $generator->create_course();
+ $plugingenerator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
+ if (!isset($params['course'])) {
+ $params['course'] = $course->id;
+ }
+ $instance = $plugingenerator->create_instance($params);
+ // Create users.
+ $useroverridestudent = $generator->create_user();
+ $group1student = $generator->create_user();
+ $group2student = $generator->create_user();
+ $group12student = $generator->create_user();
+ $nogroupstudent = $generator->create_user();
+ // Enrol users.
+ $generator->enrol_user($useroverridestudent->id, $course->id, 'student');
+ $generator->enrol_user($group1student->id, $course->id, 'student');
+ $generator->enrol_user($group2student->id, $course->id, 'student');
+ $generator->enrol_user($group12student->id, $course->id, 'student');
+ $generator->enrol_user($nogroupstudent->id, $course->id, 'student');
+ // Create groups.
+ $group1 = $generator->create_group(['courseid' => $course->id]);
+ $group2 = $generator->create_group(['courseid' => $course->id]);
+ // Add members to groups.
+ $generator->create_group_member(['groupid' => $group1->id, 'userid' => $group1student->id]);
+ $generator->create_group_member(['groupid' => $group2->id, 'userid' => $group2student->id]);
+ $generator->create_group_member(['groupid' => $group1->id, 'userid' => $group12student->id]);
+ $generator->create_group_member(['groupid' => $group2->id, 'userid' => $group12student->id]);
+ $now = time();
+ // Events with the same module name, instance and event type.
+ $events = [
+ [
+ 'name' => 'Assignment 1 due date',
+ 'description' => '',
+ 'format' => 0,
+ 'courseid' => $course->id,
+ 'groupid' => 0,
+ 'userid' => 2,
+ 'modulename' => 'assign',
+ 'instance' => $instance->id,
+ 'eventtype' => 'due',
+ 'timestart' => $now,
+ 'timeduration' => 0,
+ 'visible' => 1
+ ], [
+ 'name' => 'Assignment 1 due date - User override',
+ 'description' => '',
+ 'format' => 1,
+ 'courseid' => 0,
+ 'groupid' => 0,
+ 'userid' => $useroverridestudent->id,
+ 'modulename' => 'assign',
+ 'instance' => $instance->id,
+ 'eventtype' => 'due',
+ 'timestart' => $now + 86400,
+ 'timeduration' => 0,
+ 'visible' => 1,
+ 'priority' => CALENDAR_EVENT_USER_OVERRIDE_PRIORITY
+ ], [
+ 'name' => 'Assignment 1 due date - Group A override',
+ 'description' => '',
+ 'format' => 1,
+ 'courseid' => $course->id,
+ 'groupid' => $group1->id,
+ 'userid' => 2,
+ 'modulename' => 'assign',
+ 'instance' => $instance->id,
+ 'eventtype' => 'due',
+ 'timestart' => $now + (2 * 86400),
+ 'timeduration' => 0,
+ 'visible' => 1,
+ 'priority' => 1,
+ ], [
+ 'name' => 'Assignment 1 due date - Group B override',
+ 'description' => '',
+ 'format' => 1,
+ 'courseid' => $course->id,
+ 'groupid' => $group2->id,
+ 'userid' => 2,
+ 'modulename' => 'assign',
+ 'instance' => $instance->id,
+ 'eventtype' => 'due',
+ 'timestart' => $now + (3 * 86400),
+ 'timeduration' => 0,
+ 'visible' => 1,
+ 'priority' => 2,
+ ],
+ ];
+ foreach ($events as $event) {
+ calendar_event::create($event, false);
+ }
+ $timestart = $now - 100;
+ $timeend = $now + (3 * 86400);
+ $groups = [$group1->id, $group2->id];
+ // Get user override events.
+ $this->setUser($useroverridestudent);
+ $events = calendar_get_events($timestart, $timeend, $useroverridestudent->id, $groups, $course->id);
+ $this->assertCount(1, $events);
+ $event = reset($events);
+ $this->assertEquals('Assignment 1 due date - User override', $event->name);
+ // Get event for user with override but with the timestart and timeend parameters only covering the original event.
+ $events = calendar_get_events($timestart, $now, $useroverridestudent->id, $groups, $course->id);
+ $this->assertCount(0, $events);
+ // Get events for user that does not belong to any group and has no user override events.
+ $this->setUser($nogroupstudent);
+ $events = calendar_get_events($timestart, $timeend, $nogroupstudent->id, $groups, $course->id);
+ $this->assertCount(1, $events);
+ $event = reset($events);
+ $this->assertEquals('Assignment 1 due date', $event->name);
+ // Get events for user that belongs to groups A and B and has no user override events.
+ $this->setUser($group12student);
+ $events = calendar_get_events($timestart, $timeend, $group12student->id, $groups, $course->id);
+ $this->assertCount(1, $events);
+ $event = reset($events);
+ $this->assertEquals('Assignment 1 due date - Group B override', $event->name);
+ // Get events for user that belongs to group A and has no user override events.
+ $this->setUser($group1student);
+ $events = calendar_get_events($timestart, $timeend, $group1student->id, $groups, $course->id);
+ $this->assertCount(1, $events);
+ $event = reset($events);
+ $this->assertEquals('Assignment 1 due date - Group A override', $event->name);
+ // Add repeating events.
+ $repeatingevents = [
+ [
+ 'name' => 'Repeating site event',
+ 'description' => '',
+ 'format' => 1,
+ 'courseid' => SITEID,
+ 'groupid' => 0,
+ 'userid' => 2,
+ 'repeatid' => $event->id,
+ 'modulename' => '0',
+ 'instance' => 0,
+ 'eventtype' => 'site',
+ 'timestart' => $now + 86400,
+ 'timeduration' => 0,
+ 'visible' => 1,
+ ],
+ [
+ 'name' => 'Repeating site event',
+ 'description' => '',
+ 'format' => 1,
+ 'courseid' => SITEID,
+ 'groupid' => 0,
+ 'userid' => 2,
+ 'repeatid' => $event->id,
+ 'modulename' => '0',
+ 'instance' => 0,
+ 'eventtype' => 'site',
+ 'timestart' => $now + (2 * 86400),
+ 'timeduration' => 0,
+ 'visible' => 1,
+ ],
+ ];
+ foreach ($repeatingevents as $event) {
+ calendar_event::create($event, false);
+ }
+ // Make sure repeating events are not filtered out.
+ $events = calendar_get_events($timestart, $timeend, true, true, true);
+ $this->assertCount(3, $events);
+ }
+
+ public function test_get_course_cached() {
+ // Setup some test courses.
+ $course1 = $this->getDataGenerator()->create_course();
+ $course2 = $this->getDataGenerator()->create_course();
+ $course3 = $this->getDataGenerator()->create_course();
+
+ // Load courses into cache.
+ $coursecache = null;
+ calendar_get_course_cached($coursecache, $course1->id);
+ calendar_get_course_cached($coursecache, $course2->id);
+ calendar_get_course_cached($coursecache, $course3->id);
+
+ // Verify the cache.
+ $this->assertArrayHasKey($course1->id, $coursecache);
+ $cachedcourse1 = $coursecache[$course1->id];
+ $this->assertEquals($course1->id, $cachedcourse1->id);
+ $this->assertEquals($course1->shortname, $cachedcourse1->shortname);
+ $this->assertEquals($course1->fullname, $cachedcourse1->fullname);
+
+ $this->assertArrayHasKey($course2->id, $coursecache);
+ $cachedcourse2 = $coursecache[$course2->id];
+ $this->assertEquals($course2->id, $cachedcourse2->id);
+ $this->assertEquals($course2->shortname, $cachedcourse2->shortname);
+ $this->assertEquals($course2->fullname, $cachedcourse2->fullname);
+
+ $this->assertArrayHasKey($course3->id, $coursecache);
+ $cachedcourse3 = $coursecache[$course3->id];
+ $this->assertEquals($course3->id, $cachedcourse3->id);
+ $this->assertEquals($course3->shortname, $cachedcourse3->shortname);
+ $this->assertEquals($course3->fullname, $cachedcourse3->fullname);
+ }
+
+ /**
+ * Test the update_subscription() function.
+ */
+ public function test_update_subscription() {
+ $this->resetAfterTest(true);
+
+ $subscription = new stdClass();
+ $subscription->eventtype = 'site';
+ $subscription->name = 'test';
+ $id = calendar_add_subscription($subscription);
+
+ $subscription = calendar_get_subscription($id);
+ $subscription->name = 'awesome';
+ calendar_update_subscription($subscription);
+ $sub = calendar_get_subscription($id);
+ $this->assertEquals($subscription->name, $sub->name);
+
+ $subscription = calendar_get_subscription($id);
+ $subscription->name = 'awesome2';
+ $subscription->pollinterval = 604800;
+ calendar_update_subscription($subscription);
+ $sub = calendar_get_subscription($id);
+ $this->assertEquals($subscription->name, $sub->name);
+ $this->assertEquals($subscription->pollinterval, $sub->pollinterval);
+
+ $subscription = new stdClass();
+ $subscription->name = 'awesome4';
+ $this->expectException('coding_exception');
+ calendar_update_subscription($subscription);
+ }
+
+ public function test_add_subscription() {
+ global $DB, $CFG;
+
+ require_once($CFG->dirroot . '/lib/bennu/bennu.inc.php');
+
+ $this->resetAfterTest(true);
+
+ // Test for Microsoft Outlook 2010.
+ $subscription = new stdClass();
+ $subscription->name = 'Microsoft Outlook 2010';
+ $subscription->importfrom = CALENDAR_IMPORT_FROM_FILE;
+ $subscription->eventtype = 'site';
+ $id = calendar_add_subscription($subscription);
+
+ $calendar = file_get_contents($CFG->dirroot . '/lib/tests/fixtures/ms_outlook_2010.ics');
+ $ical = new iCalendar();
+ $ical->unserialize($calendar);
+ $this->assertEquals($ical->parser_errors, array());
+
+ $sub = calendar_get_subscription($id);
+ calendar_import_icalendar_events($ical, $sub->courseid, $sub->id);
+ $count = $DB->count_records('event', array('subscriptionid' => $sub->id));
+ $this->assertEquals($count, 1);
+
+ // Test for OSX Yosemite.
+ $subscription = new stdClass();
+ $subscription->name = 'OSX Yosemite';
+ $subscription->importfrom = CALENDAR_IMPORT_FROM_FILE;
+ $subscription->eventtype = 'site';
+ $id = calendar_add_subscription($subscription);
+
+ $calendar = file_get_contents($CFG->dirroot . '/lib/tests/fixtures/osx_yosemite.ics');
+ $ical = new iCalendar();
+ $ical->unserialize($calendar);
+ $this->assertEquals($ical->parser_errors, array());
+
+ $sub = calendar_get_subscription($id);
+ calendar_import_icalendar_events($ical, $sub->courseid, $sub->id);
+ $count = $DB->count_records('event', array('subscriptionid' => $sub->id));
+ $this->assertEquals($count, 1);
+
+ // Test for Google Gmail.
+ $subscription = new stdClass();
+ $subscription->name = 'Google Gmail';
+ $subscription->importfrom = CALENDAR_IMPORT_FROM_FILE;
+ $subscription->eventtype = 'site';
+ $id = calendar_add_subscription($subscription);
+
+ $calendar = file_get_contents($CFG->dirroot . '/lib/tests/fixtures/google_gmail.ics');
+ $ical = new iCalendar();
+ $ical->unserialize($calendar);
+ $this->assertEquals($ical->parser_errors, array());
+
+ $sub = calendar_get_subscription($id);
+ calendar_import_icalendar_events($ical, $sub->courseid, $sub->id);
+ $count = $DB->count_records('event', array('subscriptionid' => $sub->id));
+ $this->assertEquals($count, 1);
+ }
+}
\ No newline at end of file
navigation_node::override_active_url(new moodle_url('/course/view.php', array('id' => $course->id)));
} else {
$course = get_site();
- $courses = \core_calendar\api::get_default_courses();
+ $courses = calendar_get_default_courses();
$issite = true;
}
echo $OUTPUT->container_start('bottom');
if (!empty($CFG->enablecalendarexport)) {
echo $OUTPUT->single_button(new moodle_url('export.php', array('course'=>$courseid)), get_string('exportcalendar', 'calendar'));
- if (\core_calendar\api::can_add_event_to_course($course)) {
+ if (calendar_user_can_add_event($course)) {
echo $OUTPUT->single_button(new moodle_url('/calendar/managesubscriptions.php', array('course'=>$courseid)), get_string('managesubscriptions', 'calendar'));
}
if (isloggedin()) {
foreach ($subscriptions as $sub) {
mtrace("Updating calendar subscription {$sub->name} in course {$sub->courseid}");
try {
- $log = \core_calendar\api::update_subscription_events($sub->id);
+ $log = calendar_update_subscription_events($sub->id);
mtrace(trim(strip_tags($log)));
} catch (\moodle_exception $ex) {
mtrace('Error updating calendar subscription: ' . $ex->getMessage());
$subscription->url = $subscriptionurl;
$subscription->pollinterval = 86400;
$subscription->lastupdated = 0;
- \core_calendar\api::add_subscription($subscription);
+ calendar_add_subscription($subscription);
$this->expectOutputRegex('/Events imported: .* Events updated:/');
$task = new \core\task\calendar_cron_task();
$subscription->url = 'brokenurl';
$subscription->pollinterval = 86400;
$subscription->lastupdated = 0;
- \core_calendar\api::add_subscription($subscription);
+ calendar_add_subscription($subscription);
$this->expectOutputRegex('/Error updating calendar subscription: The given iCal URL is invalid/');
$task = new \core\task\calendar_cron_task();
$calendarform = new core_user\form\calendar_form(null, array('userid' => $user->id));
$user->timeformat = get_user_preferences('calendar_timeformat', '');
-$user->startwday = \core_calendar\api::get_starting_weekday();
+$user->startwday = calendar_get_starting_weekday();
$user->maxevents = get_user_preferences('calendar_maxevents', $defaultmaxevents);
$user->lookahead = get_user_preferences('calendar_lookahead', $defaultlookahead);
$user->persistflt = get_user_preferences('calendar_persistflt', 0);