diff --git a/calendar/managesubscriptions_form.php b/calendar/classes/local/event/forms/managesubscriptions.php similarity index 80% rename from calendar/managesubscriptions_form.php rename to calendar/classes/local/event/forms/managesubscriptions.php index 12ab3ac5b74..0e5a0b6df83 100644 --- a/calendar/managesubscriptions_form.php +++ b/calendar/classes/local/event/forms/managesubscriptions.php @@ -21,26 +21,30 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @package calendar */ +namespace core_calendar\local\event\forms; -if (!defined('MOODLE_INTERNAL')) { - die('Direct access to this script is forbidden.'); /// It must be included from a Moodle page -} +defined('MOODLE_INTERNAL') || die(); -require_once($CFG->libdir.'/formslib.php'); +require_once($CFG->libdir . '/formslib.php'); /** * Form for adding a subscription to a Moodle course calendar. * @copyright 2012 Jonathan Harker * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -class calendar_addsubscription_form extends moodleform { +class managesubscriptions extends \moodleform { + + use eventtype; /** * Defines the form used to add calendar subscriptions. */ public function definition() { $mform = $this->_form; - $courseid = optional_param('course', 0, PARAM_INT); + $eventtypes = calendar_get_all_allowed_types(); + if (empty($eventtypes)) { + print_error('nopermissiontoupdatecalendar'); + } $mform->addElement('header', 'addsubscriptionform', get_string('importcalendarheading', 'calendar')); @@ -77,24 +81,10 @@ class calendar_addsubscription_form extends moodleform { $mform->disabledIf('url', 'importfrom', 'eq', CALENDAR_IMPORT_FROM_FILE); $mform->disabledIf('importfile', 'importfrom', 'eq', CALENDAR_IMPORT_FROM_URL); + // Add the select elements for the available event types. + $this->add_event_type_elements($mform, $eventtypes); + // Eventtype: 0 = user, 1 = global, anything else = course ID. - 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); - - if (!empty($groups) and is_array($groups)) { - $groupoptions = array(); - foreach ($groups as $group) { - $groupoptions[$group->id] = $group->name; - } - $mform->addElement('select', 'groupid', get_string('typegroup', 'calendar'), $groupoptions); - $mform->setType('groupid', PARAM_INT); - $mform->disabledIf('groupid', 'eventtype', 'noteq', 'group'); - } - - $mform->addElement('hidden', 'course'); - $mform->setType('course', PARAM_INT); $mform->addElement('submit', 'add', get_string('add')); } @@ -110,6 +100,14 @@ class calendar_addsubscription_form extends moodleform { $errors = parent::validation($data, $files); + $coursekey = isset($data['groupcourseid']) ? 'groupcourseid' : 'courseid'; + $eventtypes = calendar_get_all_allowed_types(); + $eventtype = isset($data['eventtype']) ? $data['eventtype'] : null; + + if (empty($eventtype) || !isset($eventtypes[$eventtype])) { + $errors['eventtype'] = get_string('invalideventtype', 'calendar'); + } + if ($data['importfrom'] == CALENDAR_IMPORT_FROM_FILE) { if (empty($data['importfile'])) { $errors['importfile'] = get_string('errorrequiredurlorfile', 'calendar'); @@ -117,7 +115,7 @@ class calendar_addsubscription_form extends moodleform { // Make sure the file area is not empty and contains only one file. $draftitemid = $data['importfile']; $fs = get_file_storage(); - $usercontext = context_user::instance($USER->id); + $usercontext = \context_user::instance($USER->id); $files = $fs->get_area_files($usercontext->id, 'user', 'draft', $draftitemid, 'id DESC', false); if (count($files) !== 1) { $errors['importfile'] = get_string('errorrequiredurlorfile', 'calendar'); @@ -140,7 +138,7 @@ class calendar_addsubscription_form extends moodleform { public function definition_after_data() { $mform =& $this->_form; - $mform->applyFilter('url', 'calendar_addsubscription_form::strip_webcal'); + $mform->applyFilter('url', static::class . '::strip_webcal'); $mform->applyFilter('url', 'trim'); } diff --git a/calendar/lib.php b/calendar/lib.php index 8c20f9a34c0..f228ee8c15e 100644 --- a/calendar/lib.php +++ b/calendar/lib.php @@ -2580,12 +2580,36 @@ function calendar_get_eventtype_choices($courseid) { function calendar_add_subscription($sub) { global $DB, $USER, $SITE; + // Undo the form definition work around to allow us to have two different + // course selectors present depending on which event type the user selects. + if (!empty($sub->groupcourseid)) { + $sub->courseid = $sub->groupcourseid; + unset($sub->groupcourseid); + } + + // Pull the group id back out of the value. The form saves the value + // as "-" to allow the javascript to work correctly. + if (!empty($sub->groupid)) { + list($courseid, $groupid) = explode('-', $sub->groupid); + $sub->courseid = $courseid; + $sub->groupid = $groupid; + } + + // Default course id if none is set. + if (empty($sub->courseid)) { + if ($sub->eventtype === 'site') { + $sub->courseid = SITEID; + } else { + $sub->courseid = 0; + } + } + if ($sub->eventtype === 'site') { $sub->courseid = $SITE->id; } else if ($sub->eventtype === 'group' || $sub->eventtype === 'course') { - $sub->courseid = $sub->course; + $sub->courseid = $sub->courseid; } else if ($sub->eventtype === 'category') { - $sub->categoryid = $sub->category; + $sub->categoryid = $sub->categoryid; } else { // User events. $sub->courseid = 0; @@ -2605,8 +2629,25 @@ function calendar_add_subscription($sub) { // Trigger event, calendar subscription added. $eventparams = array('objectid' => $sub->id, 'context' => calendar_get_calendar_context($sub), - 'other' => array('eventtype' => $sub->eventtype, 'courseid' => $sub->courseid) + 'other' => array( + 'eventtype' => $sub->eventtype, + ) ); + switch ($sub->eventtype) { + case 'category': + $eventparams['other']['categoryid'] = $sub->categoryid; + break; + case 'course': + $eventparams['other']['courseid'] = $sub->courseid; + break; + case 'group': + $eventparams['other']['courseid'] = $sub->courseid; + $eventparams['other']['groupid'] = $sub->groupid; + break; + default: + $eventparams['other']['courseid'] = $sub->courseid; + } + $event = \core\event\calendar_subscription_created::create($eventparams); $event->trigger(); return $id; @@ -2624,13 +2665,13 @@ function calendar_add_subscription($sub) { * Add an iCalendar event to the Moodle calendar. * * @param stdClass $event The RFC-2445 iCalendar event - * @param int $courseid The course ID + * @param int $unused Deprecated * @param int $subscriptionid The iCalendar subscription ID * @param string $timezone The X-WR-TIMEZONE iCalendar property if provided * @throws dml_exception A DML specific exception is thrown for invalid subscriptionids. * @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') { +function calendar_add_icalendar_event($event, $unused = null, $subscriptionid, $timezone='UTC') { global $DB; // Probably an unsupported X-MICROSOFT-CDO-BUSYSTATUS event. @@ -2703,6 +2744,7 @@ function calendar_add_icalendar_event($event, $courseid, $subscriptionid, $timez $eventrecord->userid = $sub->userid; $eventrecord->groupid = $sub->groupid; $eventrecord->courseid = $sub->courseid; + $eventrecord->categoryid = $sub->categoryid; $eventrecord->eventtype = $sub->eventtype; if ($updaterecord = $DB->get_record('event', array('uuid' => $eventrecord->uuid, @@ -2783,8 +2825,24 @@ function calendar_delete_subscription($subscription) { // Trigger event, calendar subscription deleted. $eventparams = array('objectid' => $subscription->id, 'context' => calendar_get_calendar_context($subscription), - 'other' => array('courseid' => $subscription->courseid) + 'other' => array( + 'eventtype' => $subscription->eventtype, + ) ); + switch ($subscription->eventtype) { + case 'category': + $eventparams['other']['categoryid'] = $subscription->categoryid; + break; + case 'course': + $eventparams['other']['courseid'] = $subscription->courseid; + break; + case 'group': + $eventparams['other']['courseid'] = $subscription->courseid; + $eventparams['other']['groupid'] = $subscription->groupid; + break; + default: + $eventparams['other']['courseid'] = $subscription->courseid; + } $event = \core\event\calendar_subscription_deleted::create($eventparams); $event->trigger(); } @@ -2823,7 +2881,7 @@ function calendar_get_icalendar($url) { * @param int $subscriptionid The subscription ID. * @return string A log of the import progress, including errors. */ -function calendar_import_icalendar_events($ical, $courseid, $subscriptionid = null) { +function calendar_import_icalendar_events($ical, $unused = null, $subscriptionid = null) { global $DB; $return = ''; @@ -2850,7 +2908,7 @@ function calendar_import_icalendar_events($ical, $courseid, $subscriptionid = nu $return = ''; foreach ($ical->components['VEVENT'] as $event) { - $res = calendar_add_icalendar_event($event, $courseid, $subscriptionid, $timezone); + $res = calendar_add_icalendar_event($event, null, $subscriptionid, $timezone); switch ($res) { case CALENDAR_IMPORT_EVENT_UPDATED: $updatecount++; @@ -2900,7 +2958,7 @@ function calendar_update_subscription_events($subscriptionid) { } $ical = calendar_get_icalendar($sub->url); - $return = calendar_import_icalendar_events($ical, $sub->courseid, $subscriptionid); + $return = calendar_import_icalendar_events($ical, null, $subscriptionid); $sub->lastupdated = time(); calendar_update_subscription($sub); @@ -2935,8 +2993,24 @@ function calendar_update_subscription($subscription) { $eventparams = array('userid' => $subscription->userid, 'objectid' => $subscription->id, 'context' => calendar_get_calendar_context($subscription), - 'other' => array('eventtype' => $subscription->eventtype, 'courseid' => $subscription->courseid) + 'other' => array( + 'eventtype' => $subscription->eventtype, + ) ); + switch ($subscription->eventtype) { + case 'category': + $eventparams['other']['categoryid'] = $subscription->categoryid; + break; + case 'course': + $eventparams['other']['courseid'] = $subscription->courseid; + break; + case 'group': + $eventparams['other']['courseid'] = $subscription->courseid; + $eventparams['other']['groupid'] = $subscription->groupid; + break; + default: + $eventparams['other']['courseid'] = $subscription->courseid; + } $event = \core\event\calendar_subscription_updated::create($eventparams); $event->trigger(); } @@ -2958,9 +3032,14 @@ function calendar_can_edit_subscription($subscriptionorid) { $allowed = new \stdClass; $courseid = $subscription->courseid; + $categoryid = $subscription->categoryid; $groupid = $subscription->groupid; + $category = null; - calendar_get_allowed_types($allowed, $courseid); + if (!empty($categoryid)) { + $category = \coursecat::get($categoryid); + } + calendar_get_allowed_types($allowed, $courseid, null, $category); switch ($subscription->eventtype) { case 'user': return $allowed->user; @@ -2970,6 +3049,12 @@ function calendar_can_edit_subscription($subscriptionorid) { } else { return false; } + case 'category': + if (isset($allowed->categories[$categoryid])) { + return $allowed->categories[$categoryid]; + } else { + return false; + } case 'site': return $allowed->site; case 'group': diff --git a/calendar/managesubscriptions.php b/calendar/managesubscriptions.php index f1c74d67238..75ddc09f192 100644 --- a/calendar/managesubscriptions.php +++ b/calendar/managesubscriptions.php @@ -26,10 +26,10 @@ require_once('../config.php'); require_once($CFG->libdir.'/bennu/bennu.inc.php'); require_once($CFG->dirroot.'/course/lib.php'); require_once($CFG->dirroot.'/calendar/lib.php'); -require_once($CFG->dirroot.'/calendar/managesubscriptions_form.php'); // Required use. -$courseid = optional_param('course', SITEID, PARAM_INT); +$courseid = optional_param('course', null, PARAM_INT); +$categoryid = optional_param('category', null, PARAM_INT); // Used for processing subscription actions. $subscriptionid = optional_param('id', 0, PARAM_INT); $pollinterval = optional_param('pollinterval', 0, PARAM_INT); @@ -39,6 +39,9 @@ $url = new moodle_url('/calendar/managesubscriptions.php'); if ($courseid != SITEID) { $url->param('course', $courseid); } +if ($categoryid) { + $url->param('categoryid', $categoryid); +} navigation_node::override_active_url(new moodle_url('/calendar/view.php', array('view' => 'month'))); $PAGE->set_url($url); $PAGE->set_pagelayout('admin'); @@ -58,7 +61,7 @@ if (!calendar_user_can_add_event($course)) { print_error('errorcannotimport', 'calendar'); } -$form = new calendar_addsubscription_form(null); +$form = new \core_calendar\local\event\forms\managesubscriptions(); $form->set_data(array( 'course' => $course->id )); @@ -75,7 +78,7 @@ if (!empty($formdata)) { $calendar = $form->get_file_content('importfile'); $ical = new iCalendar(); $ical->unserialize($calendar); - $importresults = calendar_import_icalendar_events($ical, $courseid, $subscriptionid); + $importresults = calendar_import_icalendar_events($ical, null, $subscriptionid); } else { try { $importresults = calendar_update_subscription_events($subscriptionid); @@ -102,11 +105,54 @@ if (!empty($formdata)) { } } -$sql = 'SELECT * - FROM {event_subscriptions} - WHERE courseid = :courseid - OR (courseid = 0 AND userid = :userid)'; -$params = array('courseid' => $courseid, 'userid' => $USER->id); +$types = calendar_get_all_allowed_types(); + +$searches = []; +$params = []; + +$usedefaultfilters = true; +if (!empty($courseid) && $courseid == SITEID && isset($types['site'])) { + $searches[] = "(eventtype = 'site')"; + $searches[] = "(eventtype = 'user' AND userid = :userid)"; + $params['userid'] = $USER->id; + $usedefaultfilters = false; +} + +if (!empty($courseid) && isset($types['course']) && array_key_exists($courseid, $types['course'])) { + $searches[] = "((eventtype = 'course' OR eventtype = 'group') AND courseid = :courseid)"; + $params += ['courseid' => $courseid]; + $usedefaultfilters = false; +} + +if (!empty($categoryid) && isset($types['category']) && array_key_exists($categoryid, $types['category'])) { + $searches[] = "(eventtype = 'category' AND categoryid = :categoryid)"; + $params += ['categoryid' => $categoryid]; + $usedefaultfilters = false; +} + +if ($usedefaultfilters) { + $searches[] = "(eventtype = 'user' AND userid = :userid)"; + $params['userid'] = $USER->id; + + if (isset($types['site'])) { + $searches[] = "(eventtype = 'site' AND courseid = :siteid)"; + $params += ['siteid' => SITEID]; + } + + if (isset($types['course'])) { + list($courseinsql, $courseparams) = $DB->get_in_or_equal(array_keys($types['course']), SQL_PARAMS_NAMED, 'course'); + $searches[] = "((eventtype = 'course' OR eventtype = 'group') AND courseid {$courseinsql})"; + $params += $courseparams; + } + + if (isset($types['category'])) { + list($categoryinsql, $categoryparams) = $DB->get_in_or_equal(array_keys($types['category']), SQL_PARAMS_NAMED, 'category'); + $searches[] = "(eventtype = 'category' AND categoryid {$categoryinsql})"; + $params += $categoryparams; + } +} + +$sql = "SELECT * FROM {event_subscriptions} WHERE " . implode(' OR ', $searches);; $subscriptions = $DB->get_records_sql($sql, $params); // Print title and header. diff --git a/calendar/renderer.php b/calendar/renderer.php index 7193a970e64..e8dadbe4e37 100644 --- a/calendar/renderer.php +++ b/calendar/renderer.php @@ -283,12 +283,12 @@ class core_calendar_renderer extends plugin_renderer_base { /** * Renders a table containing information about calendar subscriptions. * - * @param int $courseid + * @param int $unused * @param array $subscriptions * @param string $importresults * @return string */ - public function subscription_details($courseid, $subscriptions, $importresults = '') { + public function subscription_details($unused = null, $subscriptions, $importresults = '') { $table = new html_table(); $table->head = array( get_string('colcalendar', 'calendar'), @@ -318,7 +318,7 @@ class core_calendar_renderer extends plugin_renderer_base { $lastupdated = userdate($sub->lastupdated, get_string('strftimedatetimeshort', 'langconfig')); } - $cell = new html_table_cell($this->subscription_action_form($sub, $courseid)); + $cell = new html_table_cell($this->subscription_action_form($sub)); $cell->colspan = 2; $type = $sub->eventtype . 'events'; @@ -342,10 +342,9 @@ class core_calendar_renderer extends plugin_renderer_base { * Creates a form to perform actions on a given subscription. * * @param stdClass $subscription - * @param int $courseid * @return string */ - protected function subscription_action_form($subscription, $courseid) { + protected function subscription_action_form($subscription) { // Assemble form for the subscription row. $html = html_writer::start_tag('form', array('action' => new moodle_url('/calendar/managesubscriptions.php'), 'method' => 'post')); if (empty($subscription->url)) { @@ -367,7 +366,6 @@ class core_calendar_renderer extends plugin_renderer_base { $html .= html_writer::end_tag('div'); } $html .= html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'sesskey', 'value' => sesskey())); - $html .= html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'course', 'value' => $courseid)); $html .= html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'id', 'value' => $subscription->id)); $html .= html_writer::start_tag('div', array('class' => 'btn-group pull-right')); if (!empty($subscription->url)) { diff --git a/calendar/tests/events_test.php b/calendar/tests/events_test.php index 6f78848a059..5750d507f55 100644 --- a/calendar/tests/events_test.php +++ b/calendar/tests/events_test.php @@ -423,9 +423,9 @@ class core_calendar_events_testcase extends advanced_testcase { } /** - * Tests for calendar_subscription_added event. + * Tests for calendar_subscription_added event for a site subscription. */ - public function test_calendar_subscription_created() { + public function test_calendar_subscription_created_site() { global $CFG; require_once($CFG->dirroot . '/calendar/lib.php'); $this->resetAfterTest(true); @@ -447,15 +447,115 @@ class core_calendar_events_testcase extends advanced_testcase { $this->assertEquals($id, $event->objectid); $this->assertEquals($subscription->courseid, $event->other['courseid']); $this->assertEquals($subscription->eventtype, $event->other['eventtype']); + $this->assertArrayNotHasKey('categoryid', $event->other); + $this->assertArrayNotHasKey('groupid', $event->other); + $this->assertDebuggingNotCalled(); + $sink->close(); + } + + /** + * Tests for calendar_subscription_added event for a category subscription. + */ + public function test_calendar_subscription_created_category() { + global $CFG; + require_once($CFG->dirroot . '/calendar/lib.php'); + $this->resetAfterTest(true); + + $categoryid = $this->course->category; + + // Create a mock subscription. + $subscription = new stdClass(); + $subscription->eventtype = 'category'; + $subscription->name = 'test'; + $subscription->categoryid = $categoryid; + + // Trigger and capture the event. + $sink = $this->redirectEvents(); + $id = calendar_add_subscription($subscription); + + $events = $sink->get_events(); + $event = reset($events); + // Check that the event data is valid. + $this->assertInstanceOf('\core\event\calendar_subscription_created', $event); + $this->assertEquals($id, $event->objectid); + $this->assertEquals($categoryid, $event->other['categoryid']); + $this->assertEquals($subscription->eventtype, $event->other['eventtype']); + $this->assertArrayNotHasKey('courseid', $event->other); + $this->assertArrayNotHasKey('groupid', $event->other); + $this->assertDebuggingNotCalled(); + $sink->close(); + } + + /** + * Tests for calendar_subscription_added event for a course subscription. + */ + public function test_calendar_subscription_created_course() { + global $CFG; + require_once($CFG->dirroot . '/calendar/lib.php'); + $this->resetAfterTest(true); + + // Create a mock subscription. + $subscription = new stdClass(); + $subscription->eventtype = 'course'; + $subscription->name = 'test'; + $subscription->courseid = $this->course->id; + + // Trigger and capture the event. + $sink = $this->redirectEvents(); + $id = calendar_add_subscription($subscription); + + $events = $sink->get_events(); + $event = reset($events); + // Check that the event data is valid. + $this->assertInstanceOf('\core\event\calendar_subscription_created', $event); + $this->assertEquals($id, $event->objectid); + $this->assertEquals($subscription->courseid, $event->other['courseid']); + $this->assertEquals($subscription->eventtype, $event->other['eventtype']); + $this->assertArrayNotHasKey('categoryid', $event->other); + $this->assertArrayNotHasKey('groupid', $event->other); $this->assertDebuggingNotCalled(); $sink->close(); } /** - * Tests for calendar_subscription_updated event. + * Tests for calendar_subscription_added event for a group subscription. */ - public function test_calendar_subscription_updated() { + public function test_calendar_subscription_created_group() { + global $CFG; + require_once($CFG->dirroot . '/calendar/lib.php'); + $this->resetAfterTest(true); + + $courseid = $this->course->id; + $groupid = 42; + + // Create a mock subscription. + $subscription = new stdClass(); + $subscription->eventtype = 'group'; + $subscription->name = 'test'; + $subscription->groupid = "{$courseid}-{$groupid}"; + + // Trigger and capture the event. + $sink = $this->redirectEvents(); + $id = calendar_add_subscription($subscription); + + $events = $sink->get_events(); + $event = reset($events); + // Check that the event data is valid. + $this->assertInstanceOf('\core\event\calendar_subscription_created', $event); + $this->assertEquals($id, $event->objectid); + $this->assertEquals($courseid, $event->other['courseid']); + $this->assertEquals($groupid, $event->other['groupid']); + $this->assertEquals($subscription->eventtype, $event->other['eventtype']); + $this->assertArrayNotHasKey('categoryid', $event->other); + $this->assertDebuggingNotCalled(); + $sink->close(); + } + + /** + * Tests for calendar_subscription_updated event for a site subscription. + */ + public function test_calendar_subscription_updated_site() { global $CFG; require_once($CFG->dirroot . '/calendar/lib.php'); $this->resetAfterTest(true); @@ -479,15 +579,120 @@ class core_calendar_events_testcase extends advanced_testcase { $this->assertEquals($subscription->id, $event->objectid); $this->assertEquals($subscription->courseid, $event->other['courseid']); $this->assertEquals($subscription->eventtype, $event->other['eventtype']); + $this->assertArrayNotHasKey('categoryid', $event->other); + $this->assertArrayNotHasKey('groupid', $event->other); $this->assertDebuggingNotCalled(); $sink->close(); - } /** - * Tests for calendar_subscription_deleted event. + * Tests for calendar_subscription_updated event for a category subscription. */ - public function test_calendar_subscription_deleted() { + public function test_calendar_subscription_updated_category() { + global $CFG; + require_once($CFG->dirroot . '/calendar/lib.php'); + $this->resetAfterTest(true); + + $categoryid = $this->course->category; + + // Create a mock subscription. + $subscription = new stdClass(); + $subscription->eventtype = 'category'; + $subscription->name = 'test'; + $subscription->categoryid = $categoryid; + $subscription->id = calendar_add_subscription($subscription); + // Now edit it. + $subscription->name = 'awesome'; + + // Trigger and capture the event. + $sink = $this->redirectEvents(); + calendar_update_subscription($subscription); + $events = $sink->get_events(); + $event = reset($events); + // Check that the event data is valid. + $this->assertInstanceOf('\core\event\calendar_subscription_updated', $event); + $this->assertEquals($subscription->id, $event->objectid); + $this->assertEquals($categoryid, $event->other['categoryid']); + $this->assertEquals($subscription->eventtype, $event->other['eventtype']); + $this->assertArrayNotHasKey('courseid', $event->other); + $this->assertArrayNotHasKey('groupid', $event->other); + $this->assertDebuggingNotCalled(); + $sink->close(); + } + + /** + * Tests for calendar_subscription_updated event for a group subscription. + */ + public function test_calendar_subscription_updated_course() { + global $CFG; + require_once($CFG->dirroot . '/calendar/lib.php'); + $this->resetAfterTest(true); + + // Create a mock subscription. + $subscription = new stdClass(); + $subscription->eventtype = 'course'; + $subscription->name = 'test'; + $subscription->courseid = $this->course->id; + $subscription->id = calendar_add_subscription($subscription); + // Now edit it. + $subscription->name = 'awesome'; + + // Trigger and capture the event. + $sink = $this->redirectEvents(); + calendar_update_subscription($subscription); + $events = $sink->get_events(); + $event = reset($events); + // Check that the event data is valid. + $this->assertInstanceOf('\core\event\calendar_subscription_updated', $event); + $this->assertEquals($subscription->id, $event->objectid); + $this->assertEquals($this->course->id, $event->other['courseid']); + $this->assertEquals($subscription->eventtype, $event->other['eventtype']); + $this->assertArrayNotHasKey('categoryid', $event->other); + $this->assertArrayNotHasKey('groupid', $event->other); + $this->assertDebuggingNotCalled(); + $sink->close(); + } + + /** + * Tests for calendar_subscription_updated event for a course subscription. + */ + public function test_calendar_subscription_updated_group() { + global $CFG; + require_once($CFG->dirroot . '/calendar/lib.php'); + $this->resetAfterTest(true); + + $courseid = $this->course->id; + $groupid = 42; + + // Create a mock subscription. + $subscription = new stdClass(); + $subscription->eventtype = 'group'; + $subscription->name = 'test'; + $subscription->groupid = "{$courseid}-{$groupid}"; + $subscription->id = calendar_add_subscription($subscription); + // Now edit it. + $subscription->name = 'awesome'; + + // Trigger and capture the event. + $sink = $this->redirectEvents(); + calendar_update_subscription($subscription); + $events = $sink->get_events(); + $event = reset($events); + // Check that the event data is valid. + $this->assertInstanceOf('\core\event\calendar_subscription_updated', $event); + $this->assertEquals($subscription->id, $event->objectid); + $this->assertEquals($this->course->id, $event->other['courseid']); + $this->assertEquals($groupid, $event->other['groupid']); + $this->assertEquals($subscription->eventtype, $event->other['eventtype']); + $this->assertArrayNotHasKey('categoryid', $event->other); + $this->assertDebuggingNotCalled(); + $sink->close(); + } + + /** + * Tests for calendar_subscription_deleted event for a site subscription. + */ + public function test_calendar_subscription_deleted_site() { global $CFG; require_once($CFG->dirroot . '/calendar/lib.php'); $this->resetAfterTest(true); @@ -512,4 +717,102 @@ class core_calendar_events_testcase extends advanced_testcase { $sink->close(); } + + /** + * Tests for calendar_subscription_deleted event for a category subscription. + */ + public function test_calendar_subscription_deleted_category() { + global $CFG; + require_once($CFG->dirroot . '/calendar/lib.php'); + $this->resetAfterTest(true); + + $categoryid = $this->course->category; + + // Create a mock subscription. + $subscription = new stdClass(); + $subscription->eventtype = 'category'; + $subscription->name = 'test'; + $subscription->categoryid = $categoryid; + $subscription->id = calendar_add_subscription($subscription); + + // Trigger and capture the event. + $sink = $this->redirectEvents(); + calendar_delete_subscription($subscription); + $events = $sink->get_events(); + $event = reset($events); + // Check that the event data is valid. + $this->assertInstanceOf('\core\event\calendar_subscription_deleted', $event); + $this->assertEquals($subscription->id, $event->objectid); + $this->assertEquals($categoryid, $event->other['categoryid']); + $this->assertEquals($subscription->eventtype, $event->other['eventtype']); + $this->assertArrayNotHasKey('courseid', $event->other); + $this->assertArrayNotHasKey('groupid', $event->other); + $this->assertDebuggingNotCalled(); + $sink->close(); + } + + /** + * Tests for calendar_subscription_deleted event for a course. + */ + public function test_calendar_subscription_deleted_course() { + global $CFG; + require_once($CFG->dirroot . '/calendar/lib.php'); + $this->resetAfterTest(true); + + // Create a mock subscription. + $subscription = new stdClass(); + $subscription->eventtype = 'course'; + $subscription->name = 'test'; + $subscription->courseid = $this->course->id; + $subscription->id = calendar_add_subscription($subscription); + + // Trigger and capture the event. + $sink = $this->redirectEvents(); + calendar_delete_subscription($subscription); + $events = $sink->get_events(); + $event = reset($events); + // Check that the event data is valid. + $this->assertInstanceOf('\core\event\calendar_subscription_deleted', $event); + $this->assertEquals($subscription->id, $event->objectid); + $this->assertEquals($this->course->id, $event->other['courseid']); + $this->assertEquals($subscription->eventtype, $event->other['eventtype']); + $this->assertArrayNotHasKey('categoryid', $event->other); + $this->assertArrayNotHasKey('groupid', $event->other); + $this->assertDebuggingNotCalled(); + $sink->close(); + } + + /** + * Tests for calendar_subscription_deleted event for a group. + */ + public function test_calendar_subscription_deleted_group() { + global $CFG; + require_once($CFG->dirroot . '/calendar/lib.php'); + $this->resetAfterTest(true); + + $courseid = $this->course->id; + $groupid = 42; + + // Create a mock subscription. + $subscription = new stdClass(); + $subscription->eventtype = 'group'; + $subscription->name = 'test'; + $subscription->groupid = "{$courseid}-{$groupid}"; + $subscription->id = calendar_add_subscription($subscription); + + // Trigger and capture the event. + $sink = $this->redirectEvents(); + calendar_delete_subscription($subscription); + $events = $sink->get_events(); + $event = reset($events); + // Check that the event data is valid. + $this->assertInstanceOf('\core\event\calendar_subscription_deleted', $event); + $this->assertEquals($subscription->id, $event->objectid); + $this->assertEquals($this->course->id, $event->other['courseid']); + $this->assertEquals($groupid, $event->other['groupid']); + $this->assertEquals($subscription->eventtype, $event->other['eventtype']); + $this->assertArrayNotHasKey('categoryid', $event->other); + $this->assertDebuggingNotCalled(); + $sink->close(); + } } diff --git a/calendar/tests/lib_test.php b/calendar/tests/lib_test.php index ce2f1ef7eb5..081738ee92c 100644 --- a/calendar/tests/lib_test.php +++ b/calendar/tests/lib_test.php @@ -188,7 +188,7 @@ class core_calendar_lib_testcase extends advanced_testcase { $this->assertEquals($ical->parser_errors, array()); $sub = calendar_get_subscription($id); - calendar_import_icalendar_events($ical, $sub->courseid, $sub->id); + calendar_import_icalendar_events($ical, null, $sub->id); $count = $DB->count_records('event', array('subscriptionid' => $sub->id)); $this->assertEquals($count, 1); @@ -205,7 +205,7 @@ class core_calendar_lib_testcase extends advanced_testcase { $this->assertEquals($ical->parser_errors, array()); $sub = calendar_get_subscription($id); - calendar_import_icalendar_events($ical, $sub->courseid, $sub->id); + calendar_import_icalendar_events($ical, null, $sub->id); $count = $DB->count_records('event', array('subscriptionid' => $sub->id)); $this->assertEquals($count, 1); @@ -222,7 +222,7 @@ class core_calendar_lib_testcase extends advanced_testcase { $this->assertEquals($ical->parser_errors, array()); $sub = calendar_get_subscription($id); - calendar_import_icalendar_events($ical, $sub->courseid, $sub->id); + calendar_import_icalendar_events($ical, null, $sub->id); $count = $DB->count_records('event', array('subscriptionid' => $sub->id)); $this->assertEquals($count, 1); } diff --git a/lib/classes/event/calendar_subscription_created.php b/lib/classes/event/calendar_subscription_created.php index 4b2c6502cab..6749e95e393 100644 --- a/lib/classes/event/calendar_subscription_created.php +++ b/lib/classes/event/calendar_subscription_created.php @@ -79,11 +79,17 @@ class calendar_subscription_created extends base * @return \moodle_url */ public function get_url() { - if (($this->other['courseid'] == SITEID) || ($this->other['courseid'] == 0)) { - return new \moodle_url('calendar/managesubscriptions.php'); - } else { - return new \moodle_url('calendar/managesubscriptions.php', array('course' => $this->other['courseid'])); + $params = []; + if ($this->other['eventtype'] == 'course' || $this->other['eventtype'] == 'group') { + $params['course'] = $this->other['courseid']; + if ($this->other['eventtype'] == 'group' && isset($this->other['groupid'])) { + $params['group'] = $this->other['groupid']; + } } + if ($this->other['eventtype'] == 'category' && isset($this->other['categoryid'])) { + $params['category'] = $this->other['categoryid']; + } + return new \moodle_url('/calendar/managesubscriptions.php', $params); } /** @@ -103,8 +109,16 @@ class calendar_subscription_created extends base if (!isset($this->other['eventtype'])) { throw new \coding_exception('The \'eventtype\' value must be set in other.'); } - if (!isset($this->other['courseid'])) { - throw new \coding_exception('The \'courseid\' value must be set in other.'); + if ($this->other['eventtype'] == 'course' || $this->other['eventtype'] == 'group') { + if (!isset($this->other['courseid'])) { + throw new \coding_exception('The \'courseid\' value must be set in other.'); + } + if ($this->other['eventtype'] == 'group' && !isset($this->other['groupid'])) { + throw new \coding_exception('The \'groupid\' value must be set in other.'); + } + } + if ($this->other['eventtype'] == 'category' && !isset($this->other['categoryid'])) { + throw new \coding_exception('The \'categoryid\' value must be set in other.'); } } diff --git a/lib/classes/event/calendar_subscription_deleted.php b/lib/classes/event/calendar_subscription_deleted.php index 0f7ab2ae997..b3bbdcab5bf 100644 --- a/lib/classes/event/calendar_subscription_deleted.php +++ b/lib/classes/event/calendar_subscription_deleted.php @@ -78,11 +78,26 @@ class calendar_subscription_deleted extends base * @return \moodle_url */ public function get_url() { - if (($this->other['courseid'] == SITEID) || ($this->other['courseid'] == 0)) { - return new \moodle_url('calendar/managesubscriptions.php'); + $params = []; + if (isset($this->other['eventtype'])) { + if ($this->other['eventtype'] == 'course' || $this->other['eventtype'] == 'group') { + $params['course'] = $this->other['courseid']; + if ($this->other['eventtype'] == 'group' && isset($this->other['groupid'])) { + $params['group'] = $this->other['groupid']; + } + } + if ($this->other['eventtype'] == 'category' && isset($this->other['categoryid'])) { + $params['category'] = $this->other['categoryid']; + } } else { - return new \moodle_url('calendar/managesubscriptions.php', array('course' => $this->other['courseid'])); + // This is a legacy event. + // Prior to specification of the eventtype there were only two params. + if (($this->other['courseid'] != SITEID) && ($this->other['courseid'] != 0)) { + $params['course'] = $this->other['courseid']; + } } + return new \moodle_url('/calendar/managesubscriptions.php', $params); + } /** @@ -99,8 +114,19 @@ class calendar_subscription_deleted extends base if (!isset($this->objectid)) { throw new \coding_exception('The \'objectid\' must be set.'); } - if (!isset($this->other['courseid'])) { - throw new \coding_exception('The \'courseid\' value must be set in other.'); + if (!isset($this->other['eventtype'])) { + throw new \coding_exception('The \'eventtype\' value must be set in other.'); + } + if ($this->other['eventtype'] == 'course' || $this->other['eventtype'] == 'group') { + if (!isset($this->other['courseid'])) { + throw new \coding_exception('The \'courseid\' value must be set in other.'); + } + if ($this->other['eventtype'] == 'group' && !isset($this->other['groupid'])) { + throw new \coding_exception('The \'groupid\' value must be set in other.'); + } + } + if ($this->other['eventtype'] == 'category' && !isset($this->other['categoryid'])) { + throw new \coding_exception('The \'categoryid\' value must be set in other.'); } } diff --git a/lib/classes/event/calendar_subscription_updated.php b/lib/classes/event/calendar_subscription_updated.php index eb610338e35..a8d6d0377de 100644 --- a/lib/classes/event/calendar_subscription_updated.php +++ b/lib/classes/event/calendar_subscription_updated.php @@ -79,11 +79,17 @@ class calendar_subscription_updated extends base * @return \moodle_url */ public function get_url() { - if (($this->other['courseid'] == SITEID) || ($this->other['courseid'] == 0)) { - return new \moodle_url('calendar/managesubscriptions.php'); - } else { - return new \moodle_url('calendar/managesubscriptions.php', array('course' => $this->other['courseid'])); + $params = []; + if ($this->other['eventtype'] == 'course' || $this->other['eventtype'] == 'group') { + $params['course'] = $this->other['courseid']; + if ($this->other['eventtype'] == 'group' && isset($this->other['groupid'])) { + $params['group'] = $this->other['groupid']; + } } + if ($this->other['eventtype'] == 'category' && isset($this->other['categoryid'])) { + $params['category'] = $this->other['categoryid']; + } + return new \moodle_url('/calendar/managesubscriptions.php', $params); } /** @@ -103,8 +109,16 @@ class calendar_subscription_updated extends base if (!isset($this->other['eventtype'])) { throw new \coding_exception('The \'eventtype\' value must be set in other.'); } - if (!isset($this->other['courseid'])) { - throw new \coding_exception('The \'courseid\' value must be set in other.'); + if ($this->other['eventtype'] == 'course' || $this->other['eventtype'] == 'group') { + if (!isset($this->other['courseid'])) { + throw new \coding_exception('The \'courseid\' value must be set in other.'); + } + if ($this->other['eventtype'] == 'group' && !isset($this->other['groupid'])) { + throw new \coding_exception('The \'groupid\' value must be set in other.'); + } + } + if ($this->other['eventtype'] == 'category' && !isset($this->other['categoryid'])) { + throw new \coding_exception('The \'categoryid\' value must be set in other.'); } } diff --git a/lib/db/install.xml b/lib/db/install.xml index bbf96b4be67..03e5684d4ad 100644 --- a/lib/db/install.xml +++ b/lib/db/install.xml @@ -1,5 +1,5 @@ - @@ -2858,6 +2858,7 @@ + diff --git a/lib/db/upgrade.php b/lib/db/upgrade.php index 50599a736eb..c5815a74180 100644 --- a/lib/db/upgrade.php +++ b/lib/db/upgrade.php @@ -2793,5 +2793,20 @@ function xmldb_main_upgrade($oldversion) { upgrade_main_savepoint(true, 2017102100.01); } + if ($oldversion < 2017110200.00) { + + // Define field categoryid to be added to event_subscriptions. + $table = new xmldb_table('event_subscriptions'); + $field = new xmldb_field('categoryid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'url'); + + // Conditionally launch add field categoryid. + if (!$dbman->field_exists($table, $field)) { + $dbman->add_field($table, $field); + } + + // Main savepoint reached. + upgrade_main_savepoint(true, 2017110200.00); + } + return true; } diff --git a/version.php b/version.php index 22b7843cdbe..4857adba0ca 100644 --- a/version.php +++ b/version.php @@ -29,7 +29,7 @@ defined('MOODLE_INTERNAL') || die(); -$version = 2017110100.00; // YYYYMMDD = weekly release date of this DEV branch. +$version = 2017110200.00; // YYYYMMDD = weekly release date of this DEV branch. // RR = release increments - 00 in DEV branches. // .XX = incremental changes.