MDL-59287 calendar_events: Update modules to create all events.
authorAdrian Greeve <adrian@moodle.com>
Mon, 3 Jul 2017 04:04:58 +0000 (12:04 +0800)
committerAdrian Greeve <adrian@moodle.com>
Mon, 10 Jul 2017 01:40:02 +0000 (09:40 +0800)
All events equals all calendar events including completion events.

19 files changed:
mod/assign/lib.php
mod/assign/locallib.php
mod/assign/upgrade.txt
mod/chat/lib.php
mod/chat/upgrade.txt
mod/choice/lib.php
mod/choice/upgrade.txt
mod/data/lib.php
mod/data/upgrade.txt
mod/feedback/lib.php
mod/feedback/upgrade.txt
mod/lesson/lib.php
mod/lesson/upgrade.txt
mod/quiz/lib.php
mod/quiz/upgrade.txt
mod/scorm/lib.php
mod/scorm/upgrade.txt
mod/workshop/lib.php
mod/workshop/upgrade.txt

index 860f5ad..7c6b896 100644 (file)
@@ -94,12 +94,31 @@ function assign_reset_userdata($data) {
  * only assignment events belonging to the course specified are checked.
  *
  * @param int $courseid
+ * @param int|stdClass $instance Assign module instance or ID.
+ * @param int|stdClass $cm Course module object or ID (not used in this module).
  * @return bool
  */
-function assign_refresh_events($courseid = 0) {
+function assign_refresh_events($courseid = 0, $instance = null, $cm = null) {
     global $CFG, $DB;
     require_once($CFG->dirroot . '/mod/assign/locallib.php');
 
+    // If we have instance information then we can just update the one event instead of updating all events.
+    if (isset($instance)) {
+        if (!is_object($instance)) {
+            $instance = $DB->get_record('assign', array('id' => $instance), '*', MUST_EXIST);
+        }
+        if (isset($cm)) {
+            if (!is_object($cm)) {
+                assign_prepare_update_events($instance);
+                return true;
+            } else {
+                $course = get_course($instance->course);
+                assign_prepare_update_events($instance, $course, $cm);
+                return true;
+            }
+        }
+    }
+
     if ($courseid) {
         // Make sure that the course id is numeric.
         if (!is_numeric($courseid)) {
@@ -118,29 +137,41 @@ function assign_refresh_events($courseid = 0) {
         }
     }
     foreach ($assigns as $assign) {
+        assign_prepare_update_events($assign);
+    }
+
+    return true;
+}
+
+/**
+ * This actually updates the normal and completion calendar events.
+ *
+ * @param  stdClass $assign Assignment object (from DB).
+ * @param  stdClass $course Course object.
+ * @param  stdClass $cm Course module object.
+ */
+function assign_prepare_update_events($assign, $course = null, $cm = null) {
+    global $DB;
+    if (!isset($course)) {
         // Get course and course module for the assignment.
         list($course, $cm) = get_course_and_cm_from_instance($assign->id, 'assign', $assign->course);
-
-        // Refresh the assignment's calendar events.
-        $context = context_module::instance($cm->id);
-        $assignment = new assign($context, $cm, $course);
-        $assignment->update_calendar($cm->id);
-
-        // Refresh the calendar events also for the assignment overrides.
-        $overrides = $DB->get_records('assign_overrides', ['assignid' => $assign->id], '',
-                                      'id, groupid, userid, duedate, sortorder');
-        foreach ($overrides as $override) {
-            if (empty($override->userid)) {
-                unset($override->userid);
-            }
-            if (empty($override->groupid)) {
-                unset($override->groupid);
-            }
-            assign_update_events($assignment, $override);
+    }
+    // Refresh the assignment's calendar events.
+    $context = context_module::instance($cm->id);
+    $assignment = new assign($context, $cm, $course);
+    $assignment->update_calendar($cm->id);
+    // Refresh the calendar events also for the assignment overrides.
+    $overrides = $DB->get_records('assign_overrides', ['assignid' => $assign->id], '',
+                                  'id, groupid, userid, duedate, sortorder');
+    foreach ($overrides as $override) {
+        if (empty($override->userid)) {
+            unset($override->userid);
         }
+        if (empty($override->groupid)) {
+            unset($override->groupid);
+        }
+        assign_update_events($assignment, $override);
     }
-
-    return true;
 }
 
 /**
index a763f37..cebdddc 100644 (file)
@@ -692,6 +692,10 @@ class assign {
             // In the case of upgrades the coursemodule has not been set,
             // so we need to wait before calling these two.
             $this->update_calendar($formdata->coursemodule);
+            if (!empty($formdata->completionexpected)) {
+                \core_completion\api::update_completion_date_event($formdata->coursemodule, 'assign', $this->instance,
+                        $formdata->completionexpected);
+            }
             $this->update_gradebook(false, $formdata->coursemodule);
 
         }
@@ -1296,6 +1300,9 @@ class assign {
         }
 
         $this->update_calendar($this->get_course_module()->id);
+        $completionexpected = (!empty($formdata->completionexpected)) ? $formdata->completionexpected : null;
+        \core_completion\api::update_completion_date_event($this->get_course_module()->id, 'assign', $this->instance,
+                $completionexpected);
         $this->update_gradebook(false, $this->get_course_module()->id);
 
         $update = new stdClass();
index aed4fb5..32accf6 100644 (file)
@@ -6,6 +6,9 @@ This files describes API changes in the assign code.
 * Fixed calendar event types for overridden due dates from 'close' to 'due'.
 * Removed calendar event type of 'open', since mod_assign only has the 'due' event type. No point in creating an override event
 for an event type that does not exist.
+* assign_refresh_events() Now takes two additional parameters to refine the update to a specific instance. This function
+  now optionally takes the module instance object or ID, and the course module object or ID. Please try to send the full
+  objects instead of the ids to save DB calls.
 
 === 3.2 ===
 * External function mod_assign_external::get_assignments now returns additional optional fields:
index 76c8205..7a91799 100644 (file)
@@ -133,6 +133,11 @@ function chat_add_instance($chat) {
 
         calendar_event::create($event);
     }
+
+    if (!empty($chat->completionexpected)) {
+        \core_completion\api::update_completion_date_event($chat->coursemodule, 'chat', $returnid, $chat->completionexpected);
+    }
+
     return $returnid;
 }
 
@@ -192,6 +197,9 @@ function chat_update_instance($chat) {
         }
     }
 
+    $completionexpected = (!empty($chat->completionexpected)) ? $chat->completionexpected : null;
+    \core_completion\api::update_completion_date_event($chat->coursemodule, 'chat', $chat->id, $completionexpected);
+
     return true;
 }
 
@@ -431,11 +439,29 @@ function chat_cron () {
  *
  * @global object
  * @param int $courseid
+ * @param int|stdClass $instance Chat module instance or ID.
+ * @param int|stdClass $cm Course module object or ID.
  * @return bool
  */
-function chat_refresh_events($courseid = 0) {
+function chat_refresh_events($courseid = 0, $instance = null, $cm = null) {
     global $DB;
 
+    // If we have instance information then we can just update the one event instead of updating all events.
+    if (isset($instance)) {
+        if (!is_object($instance)) {
+            $instance = $DB->get_record('chat', array('id' => $instance), '*', MUST_EXIST);
+        }
+        if (isset($cm)) {
+            if (!is_object($cm)) {
+                chat_prepare_update_events($instance);
+                return true;
+            } else {
+                chat_prepare_update_events($instance, $cm);
+                return true;
+            }
+        }
+    }
+
     if ($courseid) {
         if (! $chats = $DB->get_records("chat", array("course" => $courseid))) {
             return true;
@@ -445,37 +471,46 @@ function chat_refresh_events($courseid = 0) {
             return true;
         }
     }
-    $moduleid = $DB->get_field('modules', 'id', array('name' => 'chat'));
-
     foreach ($chats as $chat) {
-        $cm = get_coursemodule_from_instance('chat', $chat->id, $chat->course);
-        $event = new stdClass();
-        $event->name        = $chat->name;
-        $event->type        = CALENDAR_EVENT_TYPE_ACTION;
-        $event->description = format_module_intro('chat', $chat, $cm->id);
-        $event->timestart   = $chat->chattime;
-        $event->timesort    = $chat->chattime;
-
-        if ($event->id = $DB->get_field('event', 'id', array('modulename' => 'chat', 'instance' => $chat->id))) {
-            $calendarevent = calendar_event::load($event->id);
-            $calendarevent->update($event);
-        } else if ($chat->schedule > 0) {
-            // The chat is scheduled and the event should be published.
-            $event->courseid    = $chat->course;
-            $event->groupid     = 0;
-            $event->userid      = 0;
-            $event->modulename  = 'chat';
-            $event->instance    = $chat->id;
-            $event->eventtype   = CHAT_EVENT_TYPE_CHATTIME;
-            $event->timeduration = 0;
-            $event->visible = $DB->get_field('course_modules', 'visible', array('module' => $moduleid, 'instance' => $chat->id));
-
-            calendar_event::create($event);
-        }
+        chat_prepare_update_events($chat);
     }
     return true;
 }
 
+/**
+ * Updates both the normal and completion calendar events for chat.
+ *
+ * @param  stdClass $chat The chat object (from the DB)
+ * @param  stdClass $cm The course module object.
+ */
+function chat_prepare_update_events($chat, $cm = null) {
+    global $DB;
+    if (!isset($cm)) {
+        $cm = get_coursemodule_from_instance('chat', $chat->id, $chat->course);
+    }
+    $event = new stdClass();
+    $event->name        = $chat->name;
+    $event->type        = CALENDAR_EVENT_TYPE_ACTION;
+    $event->description = format_module_intro('chat', $chat, $cm->id);
+    $event->timestart   = $chat->chattime;
+    $event->timesort    = $chat->chattime;
+    if ($event->id = $DB->get_field('event', 'id', array('modulename' => 'chat', 'instance' => $chat->id))) {
+        $calendarevent = calendar_event::load($event->id);
+        $calendarevent->update($event);
+    } else if ($chat->schedule > 0) {
+        // The chat is scheduled and the event should be published.
+        $event->courseid    = $chat->course;
+        $event->groupid     = 0;
+        $event->userid      = 0;
+        $event->modulename  = 'chat';
+        $event->instance    = $chat->id;
+        $event->eventtype   = CHAT_EVENT_TYPE_CHATTIME;
+        $event->timeduration = 0;
+        $event->visible = $cm->visible;
+        calendar_event::create($event);
+    }
+}
+
 // Functions that require some SQL.
 
 /**
index 2bda899..2adcaf0 100644 (file)
@@ -1,6 +1,11 @@
 This files describes API changes in /mod/chat/*,
 information provided here is intended especially for developers.
 
+=== 3.3 ===
+
+* chat_refresh_events() Now takes two additional parameters to refine the update to a specific instance. This function
+  now optionally takes the module instance object or ID, and the course module object or ID. Please try to send the full
+  objects instead of the ids to save DB calls.
 
 === 2.4 ===
 
index 58ad781..124e081 100644 (file)
@@ -140,6 +140,10 @@ function choice_add_instance($choice) {
 
     // Add calendar events if necessary.
     choice_set_events($choice);
+    if (!empty($choice->completionexpected)) {
+        \core_completion\api::update_completion_date_event($choice->coursemodule, 'choice', $choice->id,
+                $choice->completionexpected);
+    }
 
     return $choice->id;
 }
@@ -189,6 +193,8 @@ function choice_update_instance($choice) {
 
     // Add calendar events if necessary.
     choice_set_events($choice);
+    $completionexpected = (!empty($choice->completionexpected)) ? $choice->completionexpected : null;
+    \core_completion\api::update_completion_date_event($choice->coursemodule, 'choice', $choice->id, $completionexpected);
 
     return $DB->update_record('choice', $choice);
 
@@ -1119,17 +1125,28 @@ function choice_get_availability_status($choice) {
 /**
  * This standard function will check all instances of this module
  * and make sure there are up-to-date events created for each of them.
- * If courseid = 0, then every chat event in the site is checked, else
- * only chat events belonging to the course specified are checked.
+ * If courseid = 0, then every choice event in the site is checked, else
+ * only choice events belonging to the course specified are checked.
  * This function is used, in its new format, by restore_refresh_events()
  *
  * @param int $courseid
+ * @param int|stdClass $instance Choice module instance or ID.
+ * @param int|stdClass $cm Course module object or ID (not used in this module).
  * @return bool
  */
-function choice_refresh_events($courseid = 0) {
+function choice_refresh_events($courseid = 0, $instance = null, $cm = null) {
     global $DB, $CFG;
     require_once($CFG->dirroot.'/mod/choice/locallib.php');
 
+    // If we have instance information then we can just update the one event instead of updating all events.
+    if (isset($instance)) {
+        if (!is_object($instance)) {
+            $instance = $DB->get_record('choice', array('id' => $instance), '*', MUST_EXIST);
+        }
+        choice_set_events($instance);
+        return true;
+    }
+
     if ($courseid) {
         if (! $choices = $DB->get_records("choice", array("course" => $courseid))) {
             return true;
index 40d80d4..c92bedd 100644 (file)
@@ -1,6 +1,12 @@
 This files describes API changes in /mod/choice/*,
 information provided here is intended especially for developers.
 
+=== 3.3 ===
+
+* choice_refresh_events() Now takes two additional parameters to refine the update to a specific instance. This function
+  now optionally takes the module instance object or ID, and the course module object or ID. Please try to send the full
+  objects instead of the ids to save DB calls.
+
 === 3.2 ===
 
 * Events mod_choice\event\answer_submitted and mod_choice\event\answer_updated
index fba3839..2d50f84 100644 (file)
@@ -982,6 +982,9 @@ function data_add_instance($data, $mform = null) {
 
     // Add calendar events if necessary.
     data_set_events($data);
+    if (!empty($data->completionexpected)) {
+        \core_completion\api::update_completion_date_event($data->coursemodule, 'data', $data->id, $data->completionexpected);
+    }
 
     data_grade_item_update($data);
 
@@ -1019,6 +1022,8 @@ function data_update_instance($data) {
 
     // Add calendar events if necessary.
     data_set_events($data);
+    $completionexpected = (!empty($data->completionexpected)) ? $data->completionexpected : null;
+    \core_completion\api::update_completion_date_event($data->coursemodule, 'data', $data->id, $completionexpected);
 
     data_grade_item_update($data);
 
@@ -4071,12 +4076,23 @@ function data_process_submission(stdClass $mod, $fields, stdClass $datarecord) {
  * This function is used, in its new format, by restore_refresh_events()
  *
  * @param int $courseid
+ * @param int|stdClass $instance Data module instance or ID.
+ * @param int|stdClass $cm Course module object or ID (not used in this module).
  * @return bool
  */
-function data_refresh_events($courseid = 0) {
+function data_refresh_events($courseid = 0, $instance = null, $cm = null) {
     global $DB, $CFG;
     require_once($CFG->dirroot.'/mod/data/locallib.php');
 
+    // If we have instance information then we can just update the one event instead of updating all events.
+    if (isset($instance)) {
+        if (!is_object($instance)) {
+            $instance = $DB->get_record('data', array('id' => $instance), '*', MUST_EXIST);
+        }
+        data_set_events($instance);
+        return true;
+    }
+
     if ($courseid) {
         if (! $data = $DB->get_records("data", array("course" => $courseid))) {
             return true;
index 6bfdef7..5c4a0d0 100644 (file)
@@ -13,6 +13,9 @@ information provided here is intended especially for developers.
 * Required entries has been added to the Activity completion setting of mod_form. Entries required for completion
     (in the entries section) is no longer displayed for new instances and will be deprecated in a future release
     in favour of the new completion setting.
+* data_refresh_events() Now takes two additional parameters to refine the update to a specific instance. This function
+  now optionally takes the module instance object or ID, and the course module object or ID. Please try to send the full
+  objects instead of the ids to save DB calls.
 
 === 3.2 ===
 
index d242b19..ce93172 100644 (file)
@@ -110,6 +110,11 @@ function feedback_add_instance($feedback) {
     }
     $context = context_module::instance($feedback->coursemodule);
 
+    if (!empty($feedback->completionexpected)) {
+        \core_completion\api::update_completion_date_event($feedback->coursemodule, 'feedback', $feedback->id,
+                $feedback->completionexpected);
+    }
+
     $editoroptions = feedback_get_editor_options();
 
     // process the custom wysiwyg editor in page_after_submit
@@ -148,6 +153,8 @@ function feedback_update_instance($feedback) {
 
     //create or update the new events
     feedback_set_events($feedback);
+    $completionexpected = (!empty($feedback->completionexpected)) ? $feedback->completionexpected : null;
+    \core_completion\api::update_completion_date_event($feedback->coursemodule, 'feedback', $feedback->id, $completionexpected);
 
     $context = context_module::instance($feedback->coursemodule);
 
@@ -879,11 +886,22 @@ function feedback_set_events($feedback) {
  * This function is used, in its new format, by restore_refresh_events()
  *
  * @param int $courseid
+ * @param int|stdClass $instance Feedback module instance or ID.
+ * @param int|stdClass $cm Course module object or ID (not used in this module).
  * @return bool
  */
-function feedback_refresh_events($courseid = 0) {
+function feedback_refresh_events($courseid = 0, $instance = null, $cm = null) {
     global $DB;
 
+    // If we have instance information then we can just update the one event instead of updating all events.
+    if (isset($instance)) {
+        if (!is_object($instance)) {
+            $instance = $DB->get_record('feedback', array('id' => $instance), '*', MUST_EXIST);
+        }
+        feedback_set_events($instance);
+        return true;
+    }
+
     if ($courseid) {
         if (! $feedbacks = $DB->get_records("feedback", array("course" => $courseid))) {
             return true;
index 1312170..beb5cb6 100644 (file)
@@ -2,6 +2,9 @@
 
 * Method get_current_completed_tmp in mod_feedback_completion class is now public.
 * Function feedback_set_tmp_values is not deprecated anymore.
+* feedback_refresh_events() Now takes two additional parameters to refine the update to a specific instance. This function
+  now optionally takes the module instance object or ID, and the course module object or ID. Please try to send the full
+  objects instead of the ids to save DB calls.
 
 === 3.1 ===
 
index e838f5d..38aa4b0 100644 (file)
@@ -304,11 +304,22 @@ function lesson_get_group_override_priorities($lessonid) {
  * This function is used, in its new format, by restore_refresh_events()
  *
  * @param int $courseid
+ * @param int|stdClass $instance Lesson module instance or ID.
+ * @param int|stdClass $cm Course module object or ID (not used in this module).
  * @return bool
  */
-function lesson_refresh_events($courseid = 0) {
+function lesson_refresh_events($courseid = 0, $instance = null, $cm = null) {
     global $DB;
 
+    // If we have instance information then we can just update the one event instead of updating all events.
+    if (isset($instance)) {
+        if (!is_object($instance)) {
+            $instance = $DB->get_record('lesson', array('id' => $instance), '*', MUST_EXIST);
+        }
+        lesson_update_events($instance);
+        return true;
+    }
+
     if ($courseid == 0) {
         if (!$lessons = $DB->get_records('lesson')) {
             return true;
@@ -979,6 +990,8 @@ function lesson_process_pre_save(&$lesson) {
 function lesson_process_post_save(&$lesson) {
     // Update the events relating to this lesson.
     lesson_update_events($lesson);
+    $completionexpected = (!empty($lesson->completionexpected)) ? $lesson->completionexpected : null;
+    \core_completion\api::update_completion_date_event($lesson->coursemodule, 'lesson', $lesson, $completionexpected);
 }
 
 
index 9372654..7267ef4 100644 (file)
@@ -8,6 +8,9 @@ This files describes API changes in the lesson code.
 
 * lesson::callback_on_view() has an additional optional parameter $redirect default to true.
   It can be set to false to avoid redirection and return the page to redirect.
+* lesson_refresh_events() Now takes two additional parameters to refine the update to a specific instance. This function
+  now optionally takes the module instance object or ID, and the course module object or ID. Please try to send the full
+  objects instead of the ids to save DB calls.
 
 === 3.1 ===
 * Removed the unused file reformat.php
index de6d1de..ced1a1b 100644 (file)
@@ -858,11 +858,22 @@ function quiz_grade_item_delete($quiz) {
  * This function is used, in its new format, by restore_refresh_events()
  *
  * @param int $courseid
+ * @param int|stdClass $instance Quiz module instance or ID.
+ * @param int|stdClass $cm Course module object or ID (not used in this module).
  * @return bool
  */
-function quiz_refresh_events($courseid = 0) {
+function quiz_refresh_events($courseid = 0, $instance = null, $cm = null) {
     global $DB;
 
+    // If we have instance information then we can just update the one event instead of updating all events.
+    if (isset($instance)) {
+        if (!is_object($instance)) {
+            $instance = $DB->get_record('quiz', array('id' => $instance), '*', MUST_EXIST);
+        }
+        quiz_update_events($instance);
+        return true;
+    }
+
     if ($courseid == 0) {
         if (!$quizzes = $DB->get_records('quiz')) {
             return true;
@@ -1177,6 +1188,8 @@ function quiz_after_add_or_update($quiz) {
 
     // Update the events relating to this quiz.
     quiz_update_events($quiz);
+    $completionexpected = (!empty($quiz->completionexpected)) ? $quiz->completionexpected : null;
+    \core_completion\api::update_completion_date_event($quiz->coursemodule, 'quiz', $quiz->id, $completionexpected);
 
     // Update related grade item.
     quiz_grade_item_update($quiz);
index 3568c52..ef70bdb 100644 (file)
@@ -1,5 +1,11 @@
 This files describes API changes in the quiz code.
 
+=== 3.3 ===
+
+* quiz_refresh_events() Now takes two additional parameters to refine the update to a specific instance. This function
+  now optionally takes the module instance object or ID, and the course module object or ID. Please try to send the full
+  objects instead of the ids to save DB calls.
+
 === 3.2 ===
 
 * External functions mod_quiz_external::get_attempt_data, mod_quiz_external::get_attempt_summary
index d4bfce3..7b8b91a 100644 (file)
@@ -166,6 +166,9 @@ function scorm_add_instance($scorm, $mform=null) {
 
     scorm_grade_item_update($record);
     scorm_update_calendar($record, $cmid);
+    if (!empty($scorm->completionexpected)) {
+        \core_completion\api::update_completion_date_event($cmid, 'scorm', $record, $scorm->completionexpected);
+    }
 
     return $record->id;
 }
@@ -244,6 +247,8 @@ function scorm_update_instance($scorm, $mform=null) {
     }
 
     $DB->update_record('scorm', $scorm);
+    // We need to find this out before we blow away the form data.
+    $completionexpected = (!empty($scorm->completionexpected)) ? $scorm->completionexpected : null;
 
     $scorm = $DB->get_record('scorm', array('id' => $scorm->id));
 
@@ -257,6 +262,7 @@ function scorm_update_instance($scorm, $mform=null) {
     scorm_grade_item_update($scorm);
     scorm_update_grades($scorm);
     scorm_update_calendar($scorm, $cmid);
+    \core_completion\api::update_completion_date_event($cmid, 'scorm', $scorm, $completionexpected);
 
     return true;
 }
@@ -1586,13 +1592,31 @@ function mod_scorm_get_fontawesome_icon_map() {
  * only scorm events belonging to the course specified are checked.
  *
  * @param int $courseid
+ * @param int|stdClass $instance scorm module instance or ID.
+ * @param int|stdClass $cm Course module object or ID.
  * @return bool
  */
-function scorm_refresh_events($courseid = 0) {
+function scorm_refresh_events($courseid = 0, $instance = null, $cm = null) {
     global $CFG, $DB;
 
     require_once($CFG->dirroot . '/mod/scorm/locallib.php');
 
+    // If we have instance information then we can just update the one event instead of updating all events.
+    if (isset($instance)) {
+        if (!is_object($instance)) {
+            $instance = $DB->get_record('scorm', array('id' => $instance), '*', MUST_EXIST);
+        }
+        if (isset($cm)) {
+            if (!is_object($cm)) {
+                $cm = (object)array('id' => $cm);
+            }
+        } else {
+            $cm = get_coursemodule_from_instance('scorm', $instance->id);
+        }
+        scorm_update_calendar($instance, $cm->id);
+        return true;
+    }
+
     if ($courseid) {
         // Make sure that the course id is numeric.
         if (!is_numeric($courseid)) {
index 9b5fed8..458a994 100644 (file)
@@ -1,5 +1,11 @@
 This files describes API changes in the mod_scorm code.
 
+=== 3.3 ===
+
+* scorm_refresh_events() Now takes two additional parameters to refine the update to a specific instance. This function
+  now optionally takes the module instance object or ID, and the course module object or ID. Please try to send the full
+  objects instead of the ids to save DB calls.
+
 === 3.1 ===
 * Group and groupings support has now been enabled.
 
index 635774d..e23e31b 100644 (file)
@@ -138,6 +138,9 @@ function workshop_add_instance(stdclass $workshop) {
 
     // create calendar events
     workshop_calendar_update($workshop, $workshop->coursemodule);
+    if (!empty($workshop->completionexpected)) {
+        \core_completion\api::update_completion_date_event($cmid, 'workshop', $workshop->id, $workshop->completionexpected);
+    }
 
     return $workshop->id;
 }
@@ -211,6 +214,8 @@ function workshop_update_instance(stdclass $workshop) {
 
     // update calendar events
     workshop_calendar_update($workshop, $workshop->coursemodule);
+    $completionexpected = (!empty($workshop->completionexpected)) ? $workshop->completionexpected : null;
+    \core_completion\api::update_completion_date_event($workshop->coursemodule, 'workshop', $workshop->id, $completionexpected);
 
     return true;
 }
@@ -291,11 +296,29 @@ function workshop_delete_instance($id) {
  * only workshop events belonging to the course specified are checked.
  *
  * @param  integer $courseid The Course ID.
+ * @param int|stdClass $instance workshop module instance or ID.
+ * @param int|stdClass $cm Course module object or ID.
  * @return bool Returns true if the calendar events were successfully updated.
  */
-function workshop_refresh_events($courseid = 0) {
+function workshop_refresh_events($courseid = 0, $instance = null, $cm = null) {
     global $DB;
 
+    // If we have instance information then we can just update the one event instead of updating all events.
+    if (isset($instance)) {
+        if (!is_object($instance)) {
+            $instance = $DB->get_record('workshop', array('id' => $instance), '*', MUST_EXIST);
+        }
+        if (isset($cm)) {
+            if (!is_object($cm)) {
+                $cm = (object)array('id' => $cm);
+            }
+        } else {
+            $cm = get_coursemodule_from_instance('workshop', $instance->id);
+        }
+        workshop_calendar_update($instance, $cm->id);
+        return true;
+    }
+
     if ($courseid) {
         // Make sure that the course id is numeric.
         if (!is_numeric($courseid)) {
index 7a76f64..4d89470 100644 (file)
@@ -1,6 +1,12 @@
 This files describes API changes in /mod/workshop - activity modules,
 information provided here is intended especially for developers.
 
+=== 3.3 ===
+
+* workshop_refresh_events() Now takes two additional parameters to refine the update to a specific instance. This function
+  now optionally takes the module instance object or ID, and the course module object or ID. Please try to send the full
+  objects instead of the ids to save DB calls.
+
 === 2.7 ===
 
 * The method workshop::log() has been deprecated in the workshop module. Please use the event classes instead