with .
- //$nexttext = link_arrow_right(get_string('monthnext', 'access'), $url='', $accesshide=true);
- //$prevtext = link_arrow_left(get_string('monthprev', 'access'), $url='', $accesshide=true);
+ // 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], $date['mday']);
+ $prevmonthtime = make_timestamp($prevmonthtime['year'], $prevmonthtime['month'], $prevmonthtime['day']);
- switch($type) {
+ $nextmonth = calendar_add_month($date['mon'], $date['year']);
+ $nextmonthtime = $calendartype->convert_to_gregorian($nextmonth[1], $nextmonth[0], $date['mday']);
+ $nextmonthtime = make_timestamp($nextmonthtime['year'], $nextmonthtime['month'], $nextmonthtime['day']);
+ }
+
+ switch ($type) {
case 'frontpage':
- list($prevmonth, $prevyear) = calendar_sub_month($data['m'], $data['y']);
- list($nextmonth, $nextyear) = calendar_add_month($data['m'], $data['y']);
- $nextlink = calendar_get_link_next(get_string('monthnext', 'access'), $urlbase, 0, $nextmonth, $nextyear, true);
- $prevlink = calendar_get_link_previous(get_string('monthprev', 'access'), $urlbase, 0, $prevmonth, $prevyear, true);
+ $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);
- $calendarlink = calendar_get_link_href(new moodle_url(CALENDAR_URL.'view.php', array('view'=>'month')), 1, $data['m'], $data['y']);
if (!empty($data['id'])) {
$calendarlink->param('course', $data['id']);
}
@@ -881,12 +895,10 @@ function calendar_top_controls($type, $data) {
break;
case 'course':
- list($prevmonth, $prevyear) = calendar_sub_month($data['m'], $data['y']);
- list($nextmonth, $nextyear) = calendar_add_month($data['m'], $data['y']);
- $nextlink = calendar_get_link_next(get_string('monthnext', 'access'), $urlbase, 0, $nextmonth, $nextyear, true);
- $prevlink = calendar_get_link_previous(get_string('monthprev', 'access'), $urlbase, 0, $prevmonth, $prevyear, true);
+ $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);
- $calendarlink = calendar_get_link_href(new moodle_url(CALENDAR_URL.'view.php', array('view'=>'month')), 1, $data['m'], $data['y']);
if (!empty($data['id'])) {
$calendarlink->param('course', $data['id']);
}
@@ -907,7 +919,7 @@ function calendar_top_controls($type, $data) {
$content .= html_writer::end_tag('div');
break;
case 'upcoming':
- $calendarlink = calendar_get_link_href(new moodle_url(CALENDAR_URL.'view.php', array('view'=>'upcoming')), 1, $data['m'], $data['y']);
+ $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']);
}
@@ -915,7 +927,7 @@ function calendar_top_controls($type, $data) {
$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')), 1, $data['m'], $data['y']);
+ $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']);
}
@@ -923,12 +935,8 @@ function calendar_top_controls($type, $data) {
$content .= html_writer::tag('h3', $calendarlink);
break;
case 'month':
- list($prevmonth, $prevyear) = calendar_sub_month($data['m'], $data['y']);
- list($nextmonth, $nextyear) = calendar_add_month($data['m'], $data['y']);
- $prevdate = make_timestamp($prevyear, $prevmonth, 1);
- $nextdate = make_timestamp($nextyear, $nextmonth, 1);
- $prevlink = calendar_get_link_previous(userdate($prevdate, get_string('strftimemonthyear')), 'view.php?view=month'.$courseid.'&', 1, $prevmonth, $prevyear);
- $nextlink = calendar_get_link_next(userdate($nextdate, get_string('strftimemonthyear')), 'view.php?view=month'.$courseid.'&', 1, $nextmonth, $nextyear);
+ $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);
if (right_to_left()) {
$left = $nextlink;
@@ -946,13 +954,17 @@ function calendar_top_controls($type, $data) {
break;
case 'day':
$days = calendar_get_days();
- $data['d'] = $date['mday']; // Just for convenience
- $prevdate = usergetdate(make_timestamp($data['y'], $data['m'], $data['d'] - 1));
- $nextdate = usergetdate(make_timestamp($data['y'], $data['m'], $data['d'] + 1));
- $prevname = calendar_wday_name($days[$prevdate['wday']]);
- $nextname = calendar_wday_name($days[$nextdate['wday']]);
- $prevlink = calendar_get_link_previous($prevname, 'view.php?view=day'.$courseid.'&', $prevdate['mday'], $prevdate['mon'], $prevdate['year']);
- $nextlink = calendar_get_link_next($nextname, 'view.php?view=day'.$courseid.'&', $nextdate['mday'], $nextdate['mon'], $nextdate['year']);
+
+ $prevtimestamp = $time - DAYSECS;
+ $nexttimestamp = $time + DAYSECS;
+
+ $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);
if (right_to_left()) {
$left = $nextlink;
@@ -1133,24 +1145,33 @@ function calendar_time_representation($time) {
* @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
*/
-function calendar_get_link_href($linkbase, $d, $m, $y) {
+function calendar_get_link_href($linkbase, $d, $m, $y, $time = 0) {
if (empty($linkbase)) {
return '';
}
if (!($linkbase instanceof moodle_url)) {
$linkbase = new moodle_url($linkbase);
}
- if (!empty($d)) {
- $linkbase->param('cal_d', $d);
- }
- if (!empty($m)) {
- $linkbase->param('cal_m', $m);
- }
- if (!empty($y)) {
- $linkbase->param('cal_y', $y);
+
+ // 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;
}
@@ -1163,10 +1184,12 @@ function calendar_get_link_href($linkbase, $d, $m, $y) {
* @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.
*/
-function calendar_get_link_previous($text, $linkbase, $d, $m, $y, $accesshide=false) {
- $href = calendar_get_link_href(new moodle_url($linkbase), $d, $m, $y);
+function calendar_get_link_previous($text, $linkbase, $d, $m, $y, $accesshide = false, $time = 0) {
+ $href = calendar_get_link_href(new moodle_url($linkbase), $d, $m, $y, $time);
if (empty($href)) {
return $text;
}
@@ -1182,10 +1205,12 @@ function calendar_get_link_previous($text, $linkbase, $d, $m, $y, $accesshide=fa
* @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.
*/
-function calendar_get_link_next($text, $linkbase, $d, $m, $y, $accesshide=false) {
- $href = calendar_get_link_href(new moodle_url($linkbase), $d, $m, $y);
+function calendar_get_link_next($text, $linkbase, $d, $m, $y, $accesshide = false, $time = 0) {
+ $href = calendar_get_link_href(new moodle_url($linkbase), $d, $m, $y, $time);
if (empty($href)) {
return $text;
}
@@ -1210,7 +1235,8 @@ function calendar_wday_name($englishname) {
* @return int
*/
function calendar_days_in_month($month, $year) {
- return intval(date('t', mktime(0, 0, 0, $month, 1, $year)));
+ $calendartype = \core_calendar\type_factory::get_calendar_instance();
+ return $calendartype->get_num_days_in_month($year, $month);
}
/**
@@ -1239,8 +1265,7 @@ function calendar_get_block_upcoming($events, $linkhref = NULL, $showcourselink
$content .= $events[$i]->referer;
} else {
if(!empty($linkhref)) {
- $ed = usergetdate($events[$i]->timestart);
- $href = calendar_get_link_href(new moodle_url(CALENDAR_URL.$linkhref), $ed['mday'], $ed['mon'], $ed['year']);
+ $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);
}
@@ -1262,38 +1287,27 @@ function calendar_get_block_upcoming($events, $linkhref = NULL, $showcourselink
/**
* Get the next following month
*
- * If the current month is December, it will get the first month of the following year.
- *
- *
* @param int $month the number of the month.
* @param int $year the number of the year.
* @return array the following month
*/
function calendar_add_month($month, $year) {
- if($month == 12) {
- return array(1, $year + 1);
- }
- else {
- return array($month + 1, $year);
- }
+ // Get the calendar type we are using.
+ $calendartype = \core_calendar\type_factory::get_calendar_instance();
+ return $calendartype->get_next_month($year, $month);
}
/**
- * Get the previous month
- *
- * If the current month is January, it will get the last month of the previous year.
+ * Get the previous month.
*
* @param int $month the number of the month.
* @param int $year the number of the year.
* @return array previous month
*/
function calendar_sub_month($month, $year) {
- if($month == 1) {
- return array(12, $year - 1);
- }
- else {
- return array($month - 1, $year);
- }
+ // Get the calendar type we are using.
+ $calendartype = \core_calendar\type_factory::get_calendar_instance();
+ return $calendartype->get_prev_month($year, $month);
}
/**
@@ -1309,6 +1323,9 @@ function calendar_sub_month($month, $year) {
* @return void
*/
function calendar_events_by_day($events, $month, $year, &$eventsbyday, &$durationbyday, &$typesbyday, &$courses) {
+ // Get the calendar type we are using.
+ $calendartype = \core_calendar\type_factory::get_calendar_instance();
+
$eventsbyday = array();
$typesbyday = array();
$durationbyday = array();
@@ -1317,12 +1334,11 @@ function calendar_events_by_day($events, $month, $year, &$eventsbyday, &$duratio
return;
}
- foreach($events as $event) {
-
- $startdate = usergetdate($event->timestart);
+ foreach ($events as $event) {
+ $startdate = $calendartype->timestamp_to_date_array($event->timestart);
// Set end date = start date if no duration
if ($event->timeduration) {
- $enddate = usergetdate($event->timestart + $event->timeduration - 1);
+ $enddate = $calendartype->timestamp_to_date_array($event->timestart + $event->timeduration - 1);
} else {
$enddate = $startdate;
}
@@ -1637,90 +1653,81 @@ function calendar_preferences_button(stdClass $course) {
* @param int $showtime determine the show time GMT timestamp
* @return string $eventtime link/string for event time
*/
-function calendar_format_event_time($event, $now, $linkparams = null, $usecommonwords = true, $showtime=0) {
- $startdate = usergetdate($event->timestart);
- $enddate = usergetdate($event->timestart + $event->timeduration);
- $usermidnightstart = usergetmidnight($event->timestart);
-
- if($event->timeduration) {
- // To avoid doing the math if one IF is enough :)
- $usermidnightend = usergetmidnight($event->timestart + $event->timeduration);
- }
- else {
- $usermidnightend = $usermidnightstart;
- }
+function calendar_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...
- // First of all we have to construct a human-readable date/time representation
-
- if($event->timeduration) {
- // It has a duration
- if($usermidnightstart == $usermidnightend ||
- ($event->timestart == $usermidnightstart) && ($event->timeduration == 86400 || $event->timeduration == 86399) ||
- ($event->timestart + $event->timeduration <= $usermidnightstart + 86400)) {
- // But it's all on the same day
- $timestart = calendar_time_representation($event->timestart);
- $timeend = calendar_time_representation($event->timestart + $event->timeduration);
- $time = $timestart.' » '.$timeend;
-
- if ($event->timestart == $usermidnightstart && ($event->timeduration == 86400 || $event->timeduration == 86399)) {
+ // 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 . ' » ' . $dateend;
}
- // Set printable representation
+ // 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), $enddate['mday'], $enddate['mon'], $enddate['year']);
- $eventtime = html_writer::link($url, $day).', '.$time;
+ $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 spans two or more days
- $daystart = calendar_day_representation($event->timestart, $now, $usecommonwords).', ';
+ } 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).', ';
+ $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 < ($usermidnightstart + 86400)) {
- $url = calendar_get_link_href(new moodle_url(CALENDAR_URL.'view.php', $linkparams), $enddate['mday'], $enddate['mon'], $enddate['year']);
- $eventtime = $timestart.' » '.html_writer::link($url, $dayend).$timeend;
+ // Set printable representation.
+ if ($now >= $usermidnightstart && $now < ($usermidnightstart + DAYSECS)) {
+ $url = calendar_get_link_href(new moodle_url(CALENDAR_URL . 'view.php', $linkparams), 0, 0, 0, $endtime);
+ $eventtime = $timestart . ' » ' . html_writer::link($url, $dayend) . $timeend;
} else {
- $url = calendar_get_link_href(new moodle_url(CALENDAR_URL.'view.php', $linkparams), $enddate['mday'], $enddate['mon'], $enddate['year']);
- $eventtime = html_writer::link($url, $daystart).$timestart.' » ';
+ $url = calendar_get_link_href(new moodle_url(CALENDAR_URL . 'view.php', $linkparams), 0, 0, 0, $endtime);
+ $eventtime = html_writer::link($url, $daystart) . $timestart . ' » ';
- $url = calendar_get_link_href(new moodle_url(CALENDAR_URL.'view.php', $linkparams), $startdate['mday'], $startdate['mon'], $startdate['year']);
- $eventtime .= html_writer::link($url, $dayend).$timeend;
+ $url = calendar_get_link_href(new moodle_url(CALENDAR_URL . 'view.php', $linkparams), 0, 0, 0, $starttime);
+ $eventtime .= html_writer::link($url, $dayend) . $timeend;
}
}
- } else {
+ } else { // There is no time duration.
$time = calendar_time_representation($event->timestart);
-
- // Set printable representation
+ // 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), $startdate['mday'], $startdate['mon'], $startdate['year']);
- $eventtime = html_writer::link($url, $day).', '.trim($time);
+ $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;
}
}
- if($event->timestart + $event->timeduration < $now) {
- // It has expired
- $eventtime = ''.str_replace(' href=', ' class="dimmed" href=', $eventtime).'';
+ // Check if It has expired.
+ if ($event->timestart + $event->timeduration < $now) {
+ $eventtime = '' . str_replace(' href=', ' class="dimmed" href=', $eventtime) . '';
}
return $eventtime;
@@ -2632,14 +2639,14 @@ class calendar_event {
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class calendar_information {
- /** @var int The day */
- public $day;
- /** @var int The month */
- public $month;
-
- /** @var int The year */
- public $year;
+ /**
+ * @var int The timestamp
+ *
+ * Rather than setting the day, month and year we will set a timestamp which will be able
+ * to be used by multiple calendars.
+ */
+ public $time;
/** @var int A course id */
public $courseid = null;
@@ -2659,26 +2666,34 @@ class calendar_information {
* @param int $day the number of the day
* @param int $month the number of the month
* @param int $year the number of the year
+ * @param int $time the unixtimestamp representing the date we want to view, this is used instead of $calmonth
+ * and $calyear to support multiple calendars
*/
- public function __construct($day=0, $month=0, $year=0) {
-
- $date = usergetdate(time());
-
- if (empty($day)) {
- $day = $date['mday'];
+ public function __construct($day = 0, $month = 0, $year = 0, $time = 0) {
+ // 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. This is done for BC.
+ if (!empty($day) || !empty($month) || !empty($year)) {
+ $date = usergetdate(time());
+ if (empty($day)) {
+ $day = $date['mday'];
+ }
+ if (empty($month)) {
+ $month = $date['mon'];
+ }
+ if (empty($year)) {
+ $year = $date['year'];
+ }
+ if (checkdate($month, $day, $year)) {
+ $this->time = make_timestamp($year, $month, $day);
+ } else {
+ $this->time = time();
+ }
+ } else if (!empty($time)) {
+ $this->time = $time;
+ } else {
+ $this->time = time();
}
-
- if (empty($month)) {
- $month = $date['mon'];
- }
-
- if (empty($year)) {
- $year = $date['year'];
- }
-
- $this->day = $day;
- $this->month = $month;
- $this->year = $year;
}
/**
@@ -2719,13 +2734,14 @@ class calendar_information {
}
return true;
}
+
/**
* Gets todays timestamp for the calendar
*
* @return int today timestamp
*/
public function timestamp_today() {
- return make_timestamp($this->year, $this->month, $this->day);
+ return $this->time;
}
/**
* Gets tomorrows timestamp for the calendar
@@ -2733,7 +2749,7 @@ class calendar_information {
* @return int tomorrow timestamp
*/
public function timestamp_tomorrow() {
- return make_timestamp($this->year, $this->month, $this->day+1);
+ return $this->time + DAYSECS;
}
/**
* Adds the pretend blocks for the calendar
@@ -2745,7 +2761,7 @@ class calendar_information {
public function add_sidecalendar_blocks(core_calendar_renderer $renderer, $showfilters=false, $view=null) {
if ($showfilters) {
$filters = new block_contents();
- $filters->content = $renderer->fake_block_filters($this->courseid, $this->day, $this->month, $this->year, $view, $this->courses);
+ $filters->content = $renderer->fake_block_filters($this->courseid, 0, 0, 0, $view, $this->courses);
$filters->footer = '';
$filters->title = get_string('eventskey', 'calendar');
$renderer->add_pretend_calendar_block($filters, BLOCK_POS_RIGHT);
diff --git a/calendar/preferences.php b/calendar/preferences.php
index 165466d6479..aeb502dadd9 100644
--- a/calendar/preferences.php
+++ b/calendar/preferences.php
@@ -32,7 +32,7 @@ if (isset($CFG->calendar_maxevents)) {
$prefs = new stdClass;
$prefs->timeformat = get_user_preferences('calendar_timeformat', '');
-$prefs->startwday = get_user_preferences('calendar_startwday', calendar_get_starting_weekday());
+$prefs->startwday = calendar_get_starting_weekday();
$prefs->maxevents = get_user_preferences('calendar_maxevents', $defaultmaxevents);
$prefs->lookahead = get_user_preferences('calendar_lookahead', $defaultlookahead);
$prefs->persistflt = get_user_preferences('calendar_persistflt', 0);
diff --git a/calendar/renderer.php b/calendar/renderer.php
index 4fc9a05d76c..efb4725baf9 100644
--- a/calendar/renderer.php
+++ b/calendar/renderer.php
@@ -166,18 +166,27 @@ class core_calendar_renderer extends plugin_renderer_base {
* @return string
*/
public function fake_block_threemonths(calendar_information $calendar) {
+ // Get the calendar type we are using.
+ $calendartype = \core_calendar\type_factory::get_calendar_instance();
- list($prevmon, $prevyr) = calendar_sub_month($calendar->month, $calendar->year);
- list($nextmon, $nextyr) = calendar_add_month($calendar->month, $calendar->year);
+ $date = $calendartype->timestamp_to_date_array($calendar->time);
- $content = html_writer::start_tag('div', array('class'=>'minicalendarblock'));
- $content .= calendar_get_mini( $calendar->courses, $calendar->groups, $calendar->users, $prevmon, $prevyr, 'display', $calendar->courseid);
+ $prevmonth = calendar_sub_month($date['mon'], $date['year']);
+ $prevmonthtime = $calendartype->convert_to_gregorian($prevmonth[1], $prevmonth[0], $date['mday']);
+ $prevmonthtime = make_timestamp($prevmonthtime['year'], $prevmonthtime['month'], $prevmonthtime['day']);
+
+ $nextmonth = calendar_add_month($date['mon'], $date['year']);
+ $nextmonthtime = $calendartype->convert_to_gregorian($nextmonth[1], $nextmonth[0], $date['mday']);
+ $nextmonthtime = make_timestamp($nextmonthtime['year'], $nextmonthtime['month'], $nextmonthtime['day']);
+
+ $content = html_writer::start_tag('div', array('class' => 'minicalendarblock'));
+ $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 .= calendar_get_mini($calendar->courses, $calendar->groups, $calendar->users, $calendar->month, $calendar->year, 'display', $calendar->courseid);
+ $content .= html_writer::start_tag('div', array('class' => 'minicalendarblock'));
+ $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 .= calendar_get_mini($calendar->courses, $calendar->groups, $calendar->users, $nextmon, $nextyr, 'display', $calendar->courseid);
+ $content .= html_writer::start_tag('div', array('class' => 'minicalendarblock'));
+ $content .= calendar_get_mini($calendar->courses, $calendar->groups, $calendar->users, false, false, 'display', $calendar->courseid, $nextmonthtime);
$content .= html_writer::end_tag('div');
return $content;
}
@@ -199,24 +208,31 @@ class core_calendar_renderer extends plugin_renderer_base {
* @param int $day
* @param int $month
* @param int $year
+ * @param int $time the unixtime, used for multiple calendar support. The values $day,
+ * $month and $year are kept for backwards compatibility.
* @return string
*/
- protected function add_event_button($courseid, $day=null, $month=null, $year=null) {
+ protected function add_event_button($courseid, $day = null, $month = null, $year = null, $time = null) {
+ // 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. This is done for BC.
+ if (!empty($day) && !empty($month) && !empty($year)) {
+ if (checkdate($month, $day, $year)) {
+ $time = make_timestamp($year, $month, $day);
+ } else {
+ $time = time();
+ }
+ } else if (empty($time)) {
+ $time = time();
+ }
+
$output = html_writer::start_tag('div', array('class'=>'buttons'));
- $output .= html_writer::start_tag('form', array('action'=>CALENDAR_URL.'event.php', 'method'=>'get'));
+ $output .= html_writer::start_tag('form', array('action' => CALENDAR_URL . 'event.php', 'method' => 'get'));
$output .= html_writer::start_tag('div');
- $output .= html_writer::empty_tag('input', array('type'=>'hidden', 'name'=>'action', 'value'=>'new'));
- $output .= html_writer::empty_tag('input', array('type'=>'hidden', 'name'=>'course', 'value'=>$courseid));
- if ($day !== null) {
- $output .= html_writer::empty_tag('input', array('type'=>'hidden', 'name'=>'cal_d', 'value'=>$day));
- }
- if ($month !== null) {
- $output .= html_writer::empty_tag('input', array('type'=>'hidden', 'name'=>'cal_m', 'value'=>$month));
- }
- if ($year !== null) {
- $output .= html_writer::empty_tag('input', array('type'=>'hidden', 'name'=>'cal_y', 'value'=>$year));
- }
- $output .= html_writer::empty_tag('input', array('type'=>'submit', 'value'=>get_string('newevent', 'calendar')));
+ $output .= html_writer::empty_tag('input', array('type'=>'hidden', 'name' => 'action', 'value' => 'new'));
+ $output .= html_writer::empty_tag('input', array('type'=>'hidden', 'name' => 'course', 'value' => $courseid));
+ $output .= html_writer::empty_tag('input', array('type'=>'hidden', 'name' => 'time', 'value' => $time));
+ $output .= html_writer::empty_tag('input', array('type'=>'submit', 'value' => get_string('newevent', 'calendar')));
$output .= html_writer::end_tag('div');
$output .= html_writer::end_tag('form');
$output .= html_writer::end_tag('div');
@@ -235,18 +251,17 @@ class core_calendar_renderer extends plugin_renderer_base {
$returnurl = $this->page->url;
}
- $calendar->checkdate();
$events = calendar_get_upcoming($calendar->courses, $calendar->groups, $calendar->users, 1, 100, $calendar->timestamp_today());
$output = html_writer::start_tag('div', array('class'=>'header'));
if (calendar_user_can_add_event($calendar->course)) {
- $output .= $this->add_event_button($calendar->course->id, $calendar->day, $calendar->month, $calendar->year);
+ $output .= $this->add_event_button($calendar->course->id, 0, 0, 0, $calendar->time);
}
//$output .= html_writer::tag('label', get_string('dayview', 'calendar'), array('for'=>'cal_course_flt_jump'));
$output .= $this->course_filter_selector($returnurl, get_string('dayview', 'calendar'));
$output .= html_writer::end_tag('div');
// Controls
- $output .= html_writer::tag('div', calendar_top_controls('day', array('id' => $calendar->courseid, 'd' => $calendar->day, 'm' => $calendar->month, 'y' => $calendar->year)), array('class'=>'controls'));
+ $output .= html_writer::tag('div', calendar_top_controls('day', array('id' => $calendar->courseid, 'time' => $calendar->time)), array('class'=>'controls'));
if (empty($events)) {
// There is nothing to display today.
@@ -376,6 +391,7 @@ class core_calendar_renderer extends plugin_renderer_base {
* Displays a month in detail
*
* @param calendar_information $calendar
+ * @param moodle_url $returnurl the url to return to
* @return string
*/
public function show_month_detailed(calendar_information $calendar, moodle_url $returnurl = null) {
@@ -385,34 +401,52 @@ class core_calendar_renderer extends plugin_renderer_base {
$returnurl = $this->page->url;
}
- $date = usergetdate(time());
+ // Get the calendar type we are using.
+ $calendartype = \core_calendar\type_factory::get_calendar_instance();
+ // Store the display settings.
$display = new stdClass;
- $display->minwday = get_user_preferences('calendar_startwday', calendar_get_starting_weekday());
- $display->maxwday = $display->minwday + 6;
- $display->thismonth = ($date['mon'] == $calendar->month);
- $display->maxdays = calendar_days_in_month($calendar->month, $calendar->year);
+ $display->thismonth = false;
- $startwday = 0;
- if (get_user_timezone_offset() < 99) {
- // We 'll keep these values as GMT here, and offset them when the time comes to query the db
- $display->tstart = gmmktime(0, 0, 0, $calendar->month, 1, $calendar->year); // This is GMT
- $display->tend = gmmktime(23, 59, 59, $calendar->month, $display->maxdays, $calendar->year); // GMT
- $startwday = gmdate('w', $display->tstart); // $display->tstart is already GMT, so don't use date(): messes with server's TZ
- } else {
- // no timezone info specified
- $display->tstart = mktime(0, 0, 0, $calendar->month, 1, $calendar->year);
- $display->tend = mktime(23, 59, 59, $calendar->month, $display->maxdays, $calendar->year);
- $startwday = date('w', $display->tstart); // $display->tstart not necessarily GMT, so use date()
+ // Get the specified date in the calendar type being used.
+ $date = $calendartype->timestamp_to_date_array($calendar->time);
+ $thisdate = $calendartype->timestamp_to_date_array(time());
+ if ($date['mon'] == $thisdate['mon'] && $date['year'] == $thisdate['year']) {
+ $display->thismonth = true;
+ $date = $thisdate;
+ $calendar->time = time();
}
+ // Get Gregorian date.
+ $gregoriandate = $calendartype->convert_to_gregorian($date['year'], $date['mon'], 1);
+
+ // Store the gregorian year and month to be used later.
+ list($gy, $gm, $gd, $gh, $gmin) = array($gregoriandate['year'], $gregoriandate['month'], $gregoriandate['day'],
+ $gregoriandate['hour'], $gregoriandate['minute']);
+
+ // Get the starting week day for this month.
+ $startwday = dayofweek(1, $date['mon'], $date['year']);
+ // Get the days in a week.
+ $daynames = calendar_get_days();
+ // Store the number of days in a week.
+ $numberofdaysinweek = $calendartype->get_num_weekdays();
+
+ $display->minwday = calendar_get_starting_weekday();
+ $display->maxwday = $display->minwday + ($numberofdaysinweek - 1);
+ $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);
+ $display->tend = make_timestamp($gy, $gm, $display->maxdays, 23, 59, 59);
+
// Align the starting weekday to fall in our display range
+ // This is simple, not foolproof.
if ($startwday < $display->minwday) {
- $startwday += 7;
+ $startwday += $numberofdaysinweek;
}
// Get events from database
- $events = calendar_get_events(usertime($display->tstart), usertime($display->tend), $calendar->users, $calendar->groups, $calendar->courses);
+ $events = calendar_get_events($display->tstart, $display->tend, $calendar->users, $calendar->groups, $calendar->courses);
if (!empty($events)) {
foreach($events as $eventid => $event) {
$event = new calendar_event($event);
@@ -426,61 +460,33 @@ class core_calendar_renderer extends plugin_renderer_base {
}
// Extract information: events vs. time
- calendar_events_by_day($events, $calendar->month, $calendar->year, $eventsbyday, $durationbyday, $typesbyday, $calendar->courses);
+ calendar_events_by_day($events, $date['mon'], $date['year'], $eventsbyday, $durationbyday, $typesbyday, $calendar->courses);
$output = html_writer::start_tag('div', array('class'=>'header'));
if (calendar_user_can_add_event($calendar->course)) {
- $output .= $this->add_event_button($calendar->course->id, null, $calendar->month, $calendar->year);
+ $output .= $this->add_event_button($calendar->course->id, 0, 0, 0, $calendar->time);
}
$output .= get_string('detailedmonthview', 'calendar').': '.$this->course_filter_selector($returnurl);
$output .= html_writer::end_tag('div', array('class'=>'header'));
// Controls
- $output .= html_writer::tag('div', calendar_top_controls('month', array('id' => $calendar->courseid, 'm' => $calendar->month, 'y' => $calendar->year)), array('class'=>'controls'));
-
- $days = calendar_get_days();
+ $output .= html_writer::tag('div', calendar_top_controls('month', array('id' => $calendar->courseid, 'time' => $calendar->time)), array('class' => 'controls'));
$table = new html_table();
$table->attributes = array('class'=>'calendarmonth calendartable');
- $time = make_timestamp($calendar->year, $calendar->month);
- $table->summary = get_string('calendarheading', 'calendar', userdate($time, get_string('strftimemonthyear')));
+ $table->summary = get_string('calendarheading', 'calendar', userdate($calendar->time, get_string('strftimemonthyear')));
$table->data = array();
- $header = new html_table_row();
- $header->attributes = array('class'=>'weekdays');
- $header->cells = array();
+ // Get the day names as the header.
+ $header = array();
for($i = $display->minwday; $i <= $display->maxwday; ++$i) {
- // This uses the % operator to get the correct weekday no matter what shift we have
- // applied to the $display->minwday : $display->maxwday range from the default 0 : 6
- $cell = new html_table_cell(get_string($days[$i % 7], 'calendar'));
- $cell->header = true;
- $header->cells[] = $cell;
+ $header[] = $daynames[$i % $numberofdaysinweek]['shortname'];
}
+ $table->head = $header;
// For the table display. $week is the row; $dayweek is the column.
$week = 1;
$dayweek = $startwday;
- // Create an array of all the week days.
- $wdays = array(0 => ''. get_string('sun', 'calendar'). '',
- 1 => ''. get_string('mon', 'calendar'). '',
- 2 => ''. get_string('tue', 'calendar'). '',
- 3 => ''. get_string('wed', 'calendar'). '',
- 4 => ''. get_string('thu', 'calendar'). '',
- 5 => ''. get_string('fri', 'calendar'). '',
- 6 => ''. get_string('sat', 'calendar'). '');
-
- // Loop only if the day offset is greater than 0.
- // This loop involves shifting the days around until the desired start day
- // is at the start of the array.
- $daycount = 0;
- while ($display->minwday > $daycount++) {
- $wdays_end = array_shift($wdays);
- array_push($wdays, $wdays_end);
- }
-
- // Now we set the (modified) array to the table header to be displayed.
- $table->head = $wdays;
-
$row = new html_table_row(array());
// Paddding (the first week may have blank days in the beginning)
@@ -496,7 +502,9 @@ class core_calendar_renderer extends plugin_renderer_base {
$weekend = intval($CFG->calendar_weekend);
}
- for ($calendar->day = 1; $calendar->day <= $display->maxdays; ++$calendar->day, ++$dayweek) {
+ $daytime = $display->tstart - DAYSECS;
+ for ($day = 1; $day <= $display->maxdays; ++$day, ++$dayweek) {
+ $daytime = $daytime + DAYSECS;
if($dayweek > $display->maxwday) {
// We need to change week (table row)
$table->data[] = $row;
@@ -507,36 +515,36 @@ class core_calendar_renderer extends plugin_renderer_base {
// Reset vars
$cell = new html_table_cell();
- $dayhref = calendar_get_link_href(new moodle_url(CALENDAR_URL.'view.php', array('view'=>'day', 'course'=>$calendar->courseid)), $calendar->day, $calendar->month, $calendar->year);
+ $dayhref = calendar_get_link_href(new moodle_url(CALENDAR_URL.'view.php', array('view' => 'day', 'course' => $calendar->courseid)), 0, 0, 0, $daytime);
$cellclasses = array();
- if ($weekend & (1 << ($dayweek % 7))) {
+ if ($weekend & (1 << ($dayweek % $numberofdaysinweek))) {
// Weekend. This is true no matter what the exact range is.
$cellclasses[] = 'weekend';
}
// Special visual fx if an event is defined
- if (isset($eventsbyday[$calendar->day])) {
- if(count($eventsbyday[$calendar->day]) == 1) {
+ if (isset($eventsbyday[$day])) {
+ if(count($eventsbyday[$day]) == 1) {
$title = get_string('oneevent', 'calendar');
} else {
- $title = get_string('manyevents', 'calendar', count($eventsbyday[$calendar->day]));
+ $title = get_string('manyevents', 'calendar', count($eventsbyday[$day]));
}
- $cell->text = html_writer::tag('div', html_writer::link($dayhref, $calendar->day, array('title'=>$title)), array('class'=>'day'));
+ $cell->text = html_writer::tag('div', html_writer::link($dayhref, $day, array('title'=>$title)), array('class'=>'day'));
} else {
- $cell->text = html_writer::tag('div', $calendar->day, array('class'=>'day'));
+ $cell->text = html_writer::tag('div', $day, array('class'=>'day'));
}
// Special visual fx if an event spans many days
$durationclass = false;
- if (isset($typesbyday[$calendar->day]['durationglobal'])) {
+ if (isset($typesbyday[$day]['durationglobal'])) {
$durationclass = 'duration_global';
- } else if (isset($typesbyday[$calendar->day]['durationcourse'])) {
+ } else if (isset($typesbyday[$day]['durationcourse'])) {
$durationclass = 'duration_course';
- } else if (isset($typesbyday[$calendar->day]['durationgroup'])) {
+ } else if (isset($typesbyday[$day]['durationgroup'])) {
$durationclass = 'duration_group';
- } else if (isset($typesbyday[$calendar->day]['durationuser'])) {
+ } else if (isset($typesbyday[$day]['durationuser'])) {
$durationclass = 'duration_user';
}
if ($durationclass) {
@@ -545,16 +553,16 @@ class core_calendar_renderer extends plugin_renderer_base {
}
// Special visual fx for today
- if ($display->thismonth && $calendar->day == $date['mday']) {
+ if ($display->thismonth && $day == $date['mday']) {
$cellclasses[] = 'day today';
} else {
$cellclasses[] = 'day nottoday';
}
$cell->attributes = array('class'=>join(' ',$cellclasses));
- if (isset($eventsbyday[$calendar->day])) {
+ if (isset($eventsbyday[$day])) {
$cell->text .= html_writer::start_tag('ul', array('class'=>'events-new'));
- foreach($eventsbyday[$calendar->day] as $eventindex) {
+ foreach($eventsbyday[$day] as $eventindex) {
// If event has a class set then add it to the event
tag
$attributes = array();
if (!empty($events[$eventindex]->class)) {
@@ -566,9 +574,9 @@ class core_calendar_renderer extends plugin_renderer_base {
}
$cell->text .= html_writer::end_tag('ul');
}
- if (isset($durationbyday[$calendar->day])) {
+ if (isset($durationbyday[$day])) {
$cell->text .= html_writer::start_tag('ul', array('class'=>'events-underway'));
- foreach($durationbyday[$calendar->day] as $eventindex) {
+ foreach($durationbyday[$day] as $eventindex) {
$cell->text .= html_writer::tag('li', '['.format_string($events[$eventindex]->name,true).']', array('class'=>'events-underway'));
}
$cell->text .= html_writer::end_tag('ul');
diff --git a/calendar/tests/behat/behat_calendar.php b/calendar/tests/behat/behat_calendar.php
new file mode 100644
index 00000000000..01dc79bfb33
--- /dev/null
+++ b/calendar/tests/behat/behat_calendar.php
@@ -0,0 +1,62 @@
+.
+
+/**
+ * Behat calendar-related steps definitions.
+ *
+ * @package core_calendar
+ * @category test
+ * @copyright 2013 Mark Nelson
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+// NOTE: no MOODLE_INTERNAL used, this file may be required by behat before including /config.php.
+require_once(__DIR__ . '/../../../lib/behat/behat_base.php');
+
+use Behat\Behat\Context\Step\Given as Given;
+use Behat\Gherkin\Node\TableNode as TableNode;
+
+/**
+ * Contains functions used by behat to test functionality.
+ *
+ * @package core_calendar
+ * @category test
+ * @copyright 2013 Mark Nelson
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class behat_calendar extends behat_base {
+
+ /**
+ * Create event.
+ *
+ * @Given /^I create a calendar event with form data:$/
+ * @param TableNode $data
+ * @return array the list of actions to perform
+ */
+ public function i_create_a_calendar_event_with_form_data($data) {
+ // Get the event name.
+ $eventname = $data->getRow(1);
+ $eventname = $eventname[1];
+
+ return array(
+ new Given('I follow "' . get_string('monththis', 'calendar') . '"'),
+ new Given('I click on "' . get_string('newevent', 'calendar') .'" "button"'),
+ new Given('I fill the moodle form with:', $data),
+ new Given('I press "' . get_string('savechanges') . '"'),
+ new Given('I should see "' . $eventname . '"')
+ );
+ }
+}
\ No newline at end of file
diff --git a/calendar/tests/behat/calendar.feature b/calendar/tests/behat/calendar.feature
new file mode 100644
index 00000000000..fc68157a72e
--- /dev/null
+++ b/calendar/tests/behat/calendar.feature
@@ -0,0 +1,84 @@
+@core @core_calendar
+Feature: Perform basic calendar functionality
+ In order to ensure the calendar works as expected
+ As an admin
+ I need to create calendar data
+
+ Background:
+ Given the following "users" exists:
+ | username | firstname | lastname | email |
+ | student1 | Student | 1 | student1@asd.com |
+ | student2 | Student | 2 | student2@asd.com |
+ And the following "courses" exists:
+ | fullname | shortname | format |
+ | Course 1 | C1 | topics |
+ And the following "course enrolments" exists:
+ | user | course | role |
+ | student1 | C1 | student |
+ When I log in as "admin"
+ And I follow "Course 1"
+ And I turn editing mode on
+ And I add the "Calendar" block
+
+ Scenario: Create a site event
+ And I create a calendar event with form data:
+ | Type of event | site |
+ | Event title | Really awesome event! |
+ | Description | Come join this awesome event, sucka! |
+ And I log out
+ And I log in as "student1"
+ And I follow "Course 1"
+ And I follow "This month"
+ And I should see "Really awesome event!"
+ And I log out
+ And I log in as "student2"
+ And I follow "This month"
+ And I should see "Really awesome event!"
+
+ Scenario: Create a course event
+ And I create a calendar event with form data:
+ | Type of event | course |
+ | Event title | Really awesome event! |
+ | Description | Come join this awesome event, sucka! |
+ And I log out
+ And I log in as "student1"
+ And I follow "Course 1"
+ And I follow "This month"
+ And I should see "Really awesome event!"
+ And I log out
+ And I log in as "student2"
+ And I follow "This month"
+ And I should not see "Really awesome event!"
+
+ Scenario: Create a user event
+ And I create a calendar event with form data:
+ | Type of event | user |
+ | Event title | Really awesome event! |
+ | Description | Come join this awesome event, sucka! |
+ And I log out
+ And I log in as "student1"
+ And I follow "Course 1"
+ And I follow "This month"
+ And I should not see "Really awesome event!"
+
+ Scenario: Delete an event
+ And I create a calendar event with form data:
+ | Type of event | user |
+ | Event title | Really awesome event! |
+ | Description | Come join this awesome event, sucka! |
+ And I click on "//div[@class='commands']//a[contains(@href, 'delete')]" "xpath_element"
+ And I click on "Delete" "button"
+ And I should not see "Really awesome event!"
+
+ Scenario: Edit an event
+ And I create a calendar event with form data:
+ | Type of event | user |
+ | Event title | Really awesome event! |
+ | Description | Come join this awesome event, sucka! |
+ And I click on "//div[@class='commands']//a[contains(@href, 'edit')]" "xpath_element"
+ And I fill the moodle form with:
+ | Event title | Mediocre event :( |
+ | Description | Wait, this event isn't that great. |
+ And I press "Save changes"
+ And I should see "Mediocre event"
+
diff --git a/calendar/tests/calendartype_test.php b/calendar/tests/calendartype_test.php
index 9f117992c76..596c8382063 100644
--- a/calendar/tests/calendartype_test.php
+++ b/calendar/tests/calendartype_test.php
@@ -33,6 +33,9 @@ require_once($CFG->dirroot . '/calendar/tests/calendartype_test_example.php');
require_once($CFG->libdir . '/form/dateselector.php');
require_once($CFG->libdir . '/form/datetimeselector.php');
+// Used to test the calendar/lib.php functions.
+require_once($CFG->dirroot . '/calendar/lib.php');
+
// Used to test the user datetime profile field.
require_once($CFG->dirroot . '/user/profile/lib.php');
require_once($CFG->dirroot . '/user/profile/definelib.php');
@@ -70,8 +73,8 @@ class core_calendar_type_testcase extends advanced_testcase {
$this->resetAfterTest();
// Test setting it as the 'Test' calendar type.
- $this->set_calendar_type('test');
- $this->assertEquals('test', \core_calendar\type_factory::get_calendar_type());
+ $this->set_calendar_type('test_example');
+ $this->assertEquals('test_example', \core_calendar\type_factory::get_calendar_type());
// Test setting it as the 'Gregorian' calendar type.
$this->set_calendar_type('gregorian');
@@ -90,7 +93,7 @@ class core_calendar_type_testcase extends advanced_testcase {
$this->core_functions_test('gregorian');
// Test that the core functions reproduce the same results as the test calendar.
- $this->core_functions_test('test');
+ $this->core_functions_test('test_example');
}
/**
@@ -120,7 +123,7 @@ class core_calendar_type_testcase extends advanced_testcase {
$date2['hour'] = 0; // The dateselector element does not have hours.
$date2['minute'] = 0; // The dateselector element does not have minutes.
$date2['timestamp'] = 1372896000;
- $this->convert_dateselector_to_unixtime_test('dateselector', 'test', $date2);
+ $this->convert_dateselector_to_unixtime_test('dateselector', 'test_example', $date2);
$date3 = array();
$date3['day'] = 4;
@@ -138,12 +141,12 @@ class core_calendar_type_testcase extends advanced_testcase {
$date4['hour'] = 1;
$date4['minute'] = 17;
$date4['timestamp'] = 1372979700;
- $this->convert_dateselector_to_unixtime_test('datetimeselector', 'test', $date4);
+ $this->convert_dateselector_to_unixtime_test('datetimeselector', 'test_example', $date4);
// The date selector element values are set by using the function usergetdate, here we want to check that
// the unixtime passed is being successfully converted to the correct values for the calendar type.
$this->convert_unixtime_to_dateselector_test('gregorian', $date3);
- $this->convert_unixtime_to_dateselector_test('test', $date4);
+ $this->convert_unixtime_to_dateselector_test('test_example', $date4);
}
/**
@@ -166,7 +169,7 @@ class core_calendar_type_testcase extends advanced_testcase {
// the year 1967 should be saved in the DB, as 1/1/1970 converts to 30/10/1967 in Gregorian.
$date['expectedminyear'] = '1967';
$date['expectedmaxyear'] = '2010';
- $this->datetime_field_submission_test('test', $date);
+ $this->datetime_field_submission_test('test_example', $date);
}
/**
@@ -183,6 +186,17 @@ class core_calendar_type_testcase extends advanced_testcase {
// Test the userdate function.
$this->assertEquals($calendar->timestamp_to_date_string($this->user->timecreated, '', 99, true, true),
userdate($this->user->timecreated));
+
+ // Test the calendar/lib.php functions.
+ $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('1986', '9'));
+ $this->assertEquals($calendar->get_next_month('1986', '9'), calendar_add_month('1986', '9'));
+ $this->assertEquals($calendar->get_prev_month('1986', '9'), calendar_sub_month('1986', '9'));
+
+ // Test the lib/moodle.php functions.
+ $this->assertEquals($calendar->get_num_days_in_month('1986', '9'), days_in_month('1986', '9'));
+ $this->assertEquals($calendar->get_weekday('1986', '9', '16'), dayofweek('16', '9', '1986'));
}
/**
diff --git a/calendar/tests/calendartype_test_example.php b/calendar/tests/calendartype_test_example.php
index 679422e9256..862cdc7b549 100644
--- a/calendar/tests/calendartype_test_example.php
+++ b/calendar/tests/calendartype_test_example.php
@@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see .
-namespace calendartype_test;
+namespace calendartype_test_example;
use \core_calendar\type_base;
/**
@@ -29,6 +29,15 @@ use \core_calendar\type_base;
*/
class structure extends type_base {
+ /**
+ * Returns the name of the calendar.
+ *
+ * @return string the calendar name
+ */
+ public function get_name() {
+ return 'test_example';
+ }
+
/**
* Returns a list of all the possible days for all months.
*
@@ -84,10 +93,90 @@ class structure extends type_base {
return 2050;
}
+ /**
+ * Returns the number of days in a week.
+ *
+ * @return int the number of days
+ */
+ public function get_num_weekdays() {
+ return 7;
+ }
+
+ /**
+ * Returns an indexed list of all the names of the weekdays.
+ *
+ * The list starts with the index 0. Each index, representing a
+ * day, must be an array that contains the indexes 'shortname'
+ * and 'fullname'.
+ *
+ * @return array array of days
+ */
+ public function get_weekdays() {
+ return '';
+ }
+
+ /**
+ * Returns the index of the starting week day.
+ *
+ * @return int
+ */
+ public function get_starting_weekday() {
+ return '';
+ }
+
+ /**
+ * Returns the index of the weekday for a specific calendar date.
+ *
+ * @param int $year
+ * @param int $month
+ * @param int $day
+ * @return int
+ */
+ public function get_weekday($year, $month, $day) {
+ return '';
+ }
+
+ /**
+ * Returns the number of days in a given month.
+ *
+ * @param int $year
+ * @param int $month
+ * @return int the number of days
+ */
+ public function get_num_days_in_month($year, $month) {
+ return '';
+ }
+
+ /**
+ * Get the previous month.
+ *
+ * If the current month is January, it will get the last month of the previous year.
+ *
+ * @param int $year
+ * @param int $month
+ * @return array previous month and year
+ */
+ public function get_prev_month($year, $month) {
+ return '';
+ }
+
+ /**
+ * Get the next month.
+ *
+ * If the current month is December, it will get the first month of the following year.
+ *
+ * @param int $year
+ * @param int $month
+ * @return array the following month and year
+ */
+ public function get_next_month($year, $month) {
+ return '';
+ }
+
/**
* Returns a formatted string that represents a date in user time.
*
- * @param int $date the timestamp in UTC, as obtained from the database
+ * @param int $time the timestamp in UTC, as obtained from the database
* @param string $format strftime format
* @param int|float|string $timezone the timezone to use
* {@link http://docs.moodle.org/dev/Time_API#Timezone}
@@ -97,7 +186,7 @@ class structure extends type_base {
* if false then the leading zero is maintained
* @return string the formatted date/time
*/
- public function timestamp_to_date_string($date, $format, $timezone, $fixday, $fixhour) {
+ public function timestamp_to_date_string($time, $format, $timezone, $fixday, $fixhour) {
return '';
}
@@ -110,7 +199,7 @@ class structure extends type_base {
* {@link http://docs.moodle.org/dev/Time_API#Timezone}
* @return array an array that represents the date in user time
*/
- public function timestamp_to_date_array($time, $timezone) {
+ public function timestamp_to_date_array($time, $timezone = 99) {
$gregoriancalendar = \core_calendar\type_factory::get_calendar_instance('gregorian');
$date = $gregoriancalendar->timestamp_to_date_array($time, $timezone);
$newdate = $this->convert_from_gregorian($date['year'], $date['mon'], $date['mday'],
@@ -143,10 +232,10 @@ class structure extends type_base {
list($year, $month, $day, $hour, $minute) = explode('/', $date);
return array('year' => (int) $year,
- 'month' => (int) $month,
- 'day' => (int) $day,
- 'hour' => (int) $hour,
- 'minute' => (int) $minute);
+ 'month' => (int) $month,
+ 'day' => (int) $day,
+ 'hour' => (int) $hour,
+ 'minute' => (int) $minute);
}
@@ -168,9 +257,9 @@ class structure extends type_base {
list($year, $month, $day, $hour, $minute) = explode('/', $date);
return array('year' => (int) $year,
- 'month' => (int) $month,
- 'day' => (int) $day,
- 'hour' => (int) $hour,
- 'minute' => (int) $minute);
+ 'month' => (int) $month,
+ 'day' => (int) $day,
+ 'hour' => (int) $hour,
+ 'minute' => (int) $minute);
}
}
diff --git a/calendar/type/gregorian/classes/structure.php b/calendar/type/gregorian/classes/structure.php
index d209864d299..cf50cfca7c7 100644
--- a/calendar/type/gregorian/classes/structure.php
+++ b/calendar/type/gregorian/classes/structure.php
@@ -26,6 +26,18 @@ use core_calendar\type_base;
*/
class structure extends type_base {
+ /**
+ * Returns the name of the calendar.
+ *
+ * This is the non-translated name, usually just
+ * the name of the folder.
+ *
+ * @return string the calendar name
+ */
+ public function get_name() {
+ return 'gregorian';
+ }
+
/**
* Returns a list of all the possible days for all months.
*
@@ -81,6 +93,140 @@ class structure extends type_base {
return 2050;
}
+ /**
+ * Returns the number of days in a week.
+ *
+ * @return int the number of days
+ */
+ public function get_num_weekdays() {
+ return 7;
+ }
+
+ /**
+ * Returns an indexed list of all the names of the weekdays.
+ *
+ * The list starts with the index 0. Each index, representing a
+ * day, must be an array that contains the indexes 'shortname'
+ * and 'fullname'.
+ *
+ * @return array array of days
+ */
+ public function get_weekdays() {
+ return array(
+ 0 => array(
+ 'shortname' => get_string('sun', 'calendar'),
+ 'fullname' => get_string('sunday', 'calendar')
+ ),
+ 1 => array(
+ 'shortname' => get_string('mon', 'calendar'),
+ 'fullname' => get_string('monday', 'calendar')
+ ),
+ 2 => array(
+ 'shortname' => get_string('tue', 'calendar'),
+ 'fullname' => get_string('tuesday', 'calendar')
+ ),
+ 3 => array(
+ 'shortname' => get_string('wed', 'calendar'),
+ 'fullname' => get_string('wednesday', 'calendar')
+ ),
+ 4 => array(
+ 'shortname' => get_string('thu', 'calendar'),
+ 'fullname' => get_string('thursday', 'calendar')
+ ),
+ 5 => array(
+ 'shortname' => get_string('fri', 'calendar'),
+ 'fullname' => get_string('friday', 'calendar')
+ ),
+ 6 => array(
+ 'shortname' => get_string('sat', 'calendar'),
+ 'fullname' => get_string('saturday', 'calendar')
+ ),
+ );
+ }
+
+ /**
+ * Returns the index of the starting week day.
+ *
+ * This may vary, for example some may consider Monday as the start of the week,
+ * where as others may consider Sunday the start.
+ *
+ * @return int
+ */
+ public function get_starting_weekday() {
+ global $CFG;
+
+ if (isset($CFG->calendar_startwday)) {
+ $firstday = $CFG->calendar_startwday;
+ } else {
+ $firstday = get_string('firstdayofweek', 'langconfig');
+ }
+
+ if (!is_numeric($firstday)) {
+ $startingweekday = CALENDAR_DEFAULT_STARTING_WEEKDAY;
+ } else {
+ $startingweekday = intval($firstday) % 7;
+ }
+
+ return get_user_preferences('calendar_startwday', $startingweekday);
+ }
+
+ /**
+ * Returns the index of the weekday for a specific calendar date.
+ *
+ * @param int $year
+ * @param int $month
+ * @param int $day
+ * @return int
+ */
+ public function get_weekday($year, $month, $day) {
+ return intval(date('w', mktime(12, 0, 0, $month, $day, $year)));
+ }
+
+ /**
+ * Returns the number of days in a given month.
+ *
+ * @param int $year
+ * @param int $month
+ * @return int the number of days
+ */
+ public function get_num_days_in_month($year, $month) {
+ return intval(date('t', mktime(0, 0, 0, $month, 1, $year)));
+ }
+
+ /**
+ * Get the previous month.
+ *
+ * If the current month is January, it will get the last month of the previous year.
+ *
+ * @param int $year
+ * @param int $month
+ * @return array previous month and year
+ */
+ public function get_prev_month($year, $month) {
+ if ($month == 1) {
+ return array(12, $year - 1);
+ } else {
+ return array($month - 1, $year);
+ }
+ }
+
+ /**
+ * Get the next month.
+ *
+ * If the current month is December, it will get the first month of the following year.
+ *
+ * @param int $year
+ * @param int $month
+ * @return array the following month and year
+ */
+ public function get_next_month($year, $month) {
+ if ($month == 12) {
+ return array(1, $year + 1);
+ } else {
+ return array($month + 1, $year);
+ }
+ }
+
/**
* Returns a formatted string that represents a date in user time.
*
@@ -94,7 +240,7 @@ class structure extends type_base {
* If parameter fixday = true (default), then take off leading
* zero from %d, else maintain it.
*
- * @param int $date the timestamp in UTC, as obtained from the database
+ * @param int $time the timestamp in UTC, as obtained from the database
* @param string $format strftime format
* @param int|float|string $timezone the timezone to use
* {@link http://docs.moodle.org/dev/Time_API#Timezone}
@@ -104,7 +250,7 @@ class structure extends type_base {
* if false then the leading zero is maintained
* @return string the formatted date/time
*/
- public function timestamp_to_date_string($date, $format, $timezone, $fixday, $fixhour) {
+ public function timestamp_to_date_string($time, $format, $timezone, $fixday, $fixhour) {
global $CFG;
if (empty($format)) {
@@ -134,7 +280,7 @@ class structure extends type_base {
// Add daylight saving offset for string timezones only, as we can't get dst for
// float values. if timezone is 99 (user default timezone), then try update dst.
if ((99 == $timezone) || !is_numeric($timezone)) {
- $date += dst_offset_on($date, $timezone);
+ $time += dst_offset_on($time, $timezone);
}
$timezone = get_user_timezone_offset($timezone);
@@ -142,24 +288,24 @@ class structure extends type_base {
// If we are running under Windows convert to windows encoding and then back to UTF-8
// (because it's impossible to specify UTF-8 to fetch locale info in Win32).
if (abs($timezone) > 13) { // Server time.
- $datestring = date_format_string($date, $format, $timezone);
+ $datestring = date_format_string($time, $format, $timezone);
if ($fixday) {
- $daystring = ltrim(str_replace(array(' 0', ' '), '', strftime(' %d', $date)));
+ $daystring = ltrim(str_replace(array(' 0', ' '), '', strftime(' %d', $time)));
$datestring = str_replace('DD', $daystring, $datestring);
}
if ($fixhour) {
- $hourstring = ltrim(str_replace(array(' 0', ' '), '', strftime(' %I', $date)));
+ $hourstring = ltrim(str_replace(array(' 0', ' '), '', strftime(' %I', $time)));
$datestring = str_replace('HH', $hourstring, $datestring);
}
} else {
- $date += (int)($timezone * 3600);
- $datestring = date_format_string($date, $format, $timezone);
+ $time += (int)($timezone * 3600);
+ $datestring = date_format_string($time, $format, $timezone);
if ($fixday) {
- $daystring = ltrim(str_replace(array(' 0', ' '), '', gmstrftime(' %d', $date)));
+ $daystring = ltrim(str_replace(array(' 0', ' '), '', gmstrftime(' %d', $time)));
$datestring = str_replace('DD', $daystring, $datestring);
}
if ($fixhour) {
- $hourstring = ltrim(str_replace(array(' 0', ' '), '', gmstrftime(' %I', $date)));
+ $hourstring = ltrim(str_replace(array(' 0', ' '), '', gmstrftime(' %I', $time)));
$datestring = str_replace('HH', $hourstring, $datestring);
}
}
@@ -176,7 +322,7 @@ class structure extends type_base {
* dst offset is applied {@link http://docs.moodle.org/dev/Time_API#Timezone}
* @return array an array that represents the date in user time
*/
- public function timestamp_to_date_array($time, $timezone) {
+ public function timestamp_to_date_array($time, $timezone = 99) {
return usergetdate($time, $timezone);
}
@@ -192,7 +338,7 @@ class structure extends type_base {
* @param int $day
* @param int $hour
* @param int $minute
- * @return array the converted day, month, year, hour and minute.
+ * @return array the converted date
*/
public function convert_from_gregorian($year, $month, $day, $hour = 0, $minute = 0) {
$date = array();
@@ -217,7 +363,7 @@ class structure extends type_base {
* @param int $day
* @param int $hour
* @param int $minute
- * @return array the converted day, month, year, hour and minute.
+ * @return array the converted date
*/
public function convert_to_gregorian($year, $month, $day, $hour = 0, $minute = 0) {
$date = array();
diff --git a/calendar/type/gregorian/version.php b/calendar/type/gregorian/version.php
index deeac17ed5e..cec41a3e402 100644
--- a/calendar/type/gregorian/version.php
+++ b/calendar/type/gregorian/version.php
@@ -24,6 +24,6 @@
defined('MOODLE_INTERNAL') || die();
-$plugin->version = 2013082300; // The current plugin version (Date: YYYYMMDDXX).
-$plugin->requires = 2012120300; // Requires this Moodle version.
+$plugin->version = 2013100200; // The current plugin version (Date: YYYYMMDDXX).
+$plugin->requires = 2013082300; // Requires this Moodle version.
$plugin->component = 'calendartype_gregorian'; // Full name of the plugin (used for diagnostics).
diff --git a/calendar/view.php b/calendar/view.php
index 73e5924e89d..8e6f7d4de39 100644
--- a/calendar/view.php
+++ b/calendar/view.php
@@ -46,26 +46,36 @@ require_once($CFG->dirroot.'/calendar/lib.php');
$courseid = optional_param('course', SITEID, PARAM_INT);
$view = optional_param('view', 'upcoming', PARAM_ALPHA);
-$day = optional_param('cal_d', 0, PARAM_INT);
-$mon = optional_param('cal_m', 0, PARAM_INT);
-$yr = optional_param('cal_y', 0, PARAM_INT);
+$day = optional_param('cal_d', 0, PARAM_INT);
+$mon = optional_param('cal_m', 0, PARAM_INT);
+$year = optional_param('cal_y', 0, PARAM_INT);
+$time = optional_param('time', 0, PARAM_INT);
$url = new moodle_url('/calendar/view.php');
+
if ($courseid != SITEID) {
$url->param('course', $courseid);
}
+
if ($view !== 'upcoming') {
$url->param('view', $view);
}
-if ($day !== 0) {
- $url->param('cal_d', $day);
-}
-if ($mon !== 0) {
- $url->param('cal_m', $mon);
-}
-if ($yr !== 0) {
- $url->param('cal_y', $yr);
+
+// 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. This is done for BC.
+if (!empty($day) && !empty($mon) && !empty($year)) {
+ if (checkdate($mon, $day, $year)) {
+ $time = make_timestamp($year, $mon, $day);
+ } else {
+ $time = time();
+ }
+} else if (empty($time)) {
+ $time = time();
}
+
+$url->param('time', $time);
+
$PAGE->set_url($url);
if ($courseid != SITEID && !empty($courseid)) {
@@ -78,23 +88,16 @@ if ($courseid != SITEID && !empty($courseid)) {
$courses = calendar_get_default_courses();
$issite = true;
}
+
require_course_login($course);
-$calendar = new calendar_information($day, $mon, $yr);
+$calendar = new calendar_information(0, 0, 0, $time);
$calendar->prepare_for_view($course, $courses);
-$now = usergetdate(time());
$pagetitle = '';
$strcalendar = get_string('calendar', 'calendar');
-if (!checkdate($mon, $day, $yr)) {
- $day = intval($now['mday']);
- $mon = intval($now['mon']);
- $yr = intval($now['year']);
-}
-$time = make_timestamp($yr, $mon, $day);
-
switch($view) {
case 'day':
$PAGE->navbar->add(userdate($time, get_string('strftimedate')));
diff --git a/lib/form/dateselector.php b/lib/form/dateselector.php
index 4e94b09360d..7676edbccdd 100644
--- a/lib/form/dateselector.php
+++ b/lib/form/dateselector.php
@@ -99,7 +99,7 @@ class MoodleQuickForm_date_selector extends MoodleQuickForm_group {
}
}
// The YUI2 calendar only supports the gregorian calendar type.
- if (\core_calendar\type_factory::get_calendar_type() === 'gregorian') {
+ if ($calendartype->get_name() === 'gregorian') {
form_init_date_js();
}
}
@@ -126,7 +126,7 @@ class MoodleQuickForm_date_selector extends MoodleQuickForm_group {
$this->_elements[] = @MoodleQuickForm::createElement('select', 'month', get_string('month', 'form'), $months, $this->getAttributes(), true);
$this->_elements[] = @MoodleQuickForm::createElement('select', 'year', get_string('year', 'form'), $years, $this->getAttributes(), true);
// The YUI2 calendar only supports the gregorian calendar type so only display the calendar image if this is being used.
- if (\core_calendar\type_factory::get_calendar_type() === 'gregorian') {
+ if ($calendartype->get_name() === 'gregorian') {
$this->_elements[] = @MoodleQuickForm::createElement('image', 'calendar', $OUTPUT->pix_url('i/calendar', 'moodle'),
array('title' => get_string('calendar', 'calendar'), 'class' => 'visibleifjs'));
}
diff --git a/lib/form/datetimeselector.php b/lib/form/datetimeselector.php
index e3a908ec3df..f80f3566050 100644
--- a/lib/form/datetimeselector.php
+++ b/lib/form/datetimeselector.php
@@ -101,7 +101,7 @@ class MoodleQuickForm_date_time_selector extends MoodleQuickForm_group {
}
}
// The YUI2 calendar only supports the gregorian calendar type.
- if (\core_calendar\type_factory::get_calendar_type() === 'gregorian') {
+ if ($calendartype->get_name() === 'gregorian') {
form_init_date_js();
}
}
@@ -141,7 +141,7 @@ class MoodleQuickForm_date_time_selector extends MoodleQuickForm_group {
$this->_elements[] = @MoodleQuickForm::createElement('select', 'minute', get_string('minute', 'form'), $minutes, $this->getAttributes(), true);
}
// The YUI2 calendar only supports the gregorian calendar type so only display the calendar image if this is being used.
- if (\core_calendar\type_factory::get_calendar_type() === 'gregorian') {
+ if ($calendartype->get_name() === 'gregorian') {
$this->_elements[] = @MoodleQuickForm::createElement('image', 'calendar', $OUTPUT->pix_url('i/calendar', 'moodle'),
array('title' => get_string('calendar', 'calendar'), 'class' => 'visibleifjs'));
}
diff --git a/lib/moodlelib.php b/lib/moodlelib.php
index 094c76bcac5..72cad759d1e 100644
--- a/lib/moodlelib.php
+++ b/lib/moodlelib.php
@@ -2685,8 +2685,10 @@ function dst_offset_on($time, $strtimezone = null) {
* @return int
*/
function find_day_in_month($startday, $weekday, $month, $year) {
+ $calendartype = \core_calendar\type_factory::get_calendar_instance();
$daysinmonth = days_in_month($month, $year);
+ $daysinweek = count($calendartype->get_weekdays());
if ($weekday == -1) {
// Don't care about weekday, so return:
@@ -2696,46 +2698,40 @@ function find_day_in_month($startday, $weekday, $month, $year) {
}
// From now on we 're looking for a specific weekday.
-
// Give "end of month" its actual value, since we know it.
if ($startday == -1) {
$startday = -1 * $daysinmonth;
}
// Starting from day $startday, the sign is the direction.
-
if ($startday < 1) {
-
$startday = abs($startday);
- $lastmonthweekday = strftime('%w', mktime(12, 0, 0, $month, $daysinmonth, $year));
+ $lastmonthweekday = dayofweek($daysinmonth, $month, $year);
// This is the last such weekday of the month.
$lastinmonth = $daysinmonth + $weekday - $lastmonthweekday;
if ($lastinmonth > $daysinmonth) {
- $lastinmonth -= 7;
+ $lastinmonth -= $daysinweek;
}
// Find the first such weekday <= $startday.
while ($lastinmonth > $startday) {
- $lastinmonth -= 7;
+ $lastinmonth -= $daysinweek;
}
return $lastinmonth;
-
} else {
-
- $indexweekday = strftime('%w', mktime(12, 0, 0, $month, $startday, $year));
+ $indexweekday = dayofweek($startday, $month, $year);
$diff = $weekday - $indexweekday;
if ($diff < 0) {
- $diff += 7;
+ $diff += $daysinweek;
}
// This is the first such weekday of the month equal to or after $startday.
$firstfromindex = $startday + $diff;
return $firstfromindex;
-
}
}
@@ -2749,7 +2745,8 @@ function find_day_in_month($startday, $weekday, $month, $year) {
* @return int
*/
function days_in_month($month, $year) {
- return intval(date('t', mktime(12, 0, 0, $month, 1, $year)));
+ $calendartype = \core_calendar\type_factory::get_calendar_instance();
+ return $calendartype->get_num_days_in_month($year, $month);
}
/**
@@ -2763,8 +2760,8 @@ function days_in_month($month, $year) {
* @return int
*/
function dayofweek($day, $month, $year) {
- // I wonder if this is any different from strftime('%w', mktime(12, 0, 0, $month, $daysinmonth, $year, 0));.
- return intval(date('w', mktime(12, 0, 0, $month, $day, $year)));
+ $calendartype = \core_calendar\type_factory::get_calendar_instance();
+ return $calendartype->get_weekday($year, $month, $day);
}
// USER AUTHENTICATION AND LOGIN.