/** * Deletes an event and if selected an repeated events in the same series * * This function deletes an event, any associated events if $deleterepeated=true, * and cleans up any files associated with the events. * * @see self::delete() * * @param bool $deleterepeated delete event repeatedly * @return bool succession of deleting event */ public function delete($deleterepeated = false) { global $DB; // If $this->properties->id is not set then something is wrong if (empty($this->properties->id)) { debugging('Attempting to delete an event before it has been loaded', DEBUG_DEVELOPER); return false; } $calevent = $DB->get_record('event', array('id' => $this->properties->id), '*', MUST_EXIST); // Delete the event $DB->delete_records('event', array('id' => $this->properties->id)); // Trigger an event for the delete action. $eventargs = array('context' => $this->properties->context, 'objectid' => $this->properties->id, 'other' => array('repeatid' => empty($this->properties->repeatid) ? 0 : $this->properties->repeatid, 'timestart' => $this->properties->timestart, 'name' => $this->properties->name)); $event = \core\event\calendar_event_deleted::create($eventargs); $event->add_record_snapshot('event', $calevent); $event->trigger(); // If we are deleting parent of a repeated event series, promote the next event in the series as parent if ($this->properties->id == $this->properties->repeatid && !$deleterepeated) { $newparent = $DB->get_field_sql("SELECT id from {event} where repeatid = ? order by id ASC", array($this->properties->id), IGNORE_MULTIPLE); if (!empty($newparent)) { $DB->execute("UPDATE {event} SET repeatid = ? WHERE repeatid = ?", array($newparent, $this->properties->id)); // Get all records where the repeatid is the same as the event being removed $events = $DB->get_records('event', array('repeatid' => $newparent)); // For each of the returned events trigger the event_update hook and an update event. foreach ($events as $event) { // Trigger an event for the update. $eventargs['objectid'] = $event->id; $eventargs['other']['timestart'] = $event->timestart; $event = \core\event\calendar_event_updated::create($eventargs); $event->trigger(); self::calendar_event_hook('update_event', array($event, false)); } } } // If the editor context hasn't already been set then set it now if ($this->editorcontext === null) { $this->editorcontext = $this->properties->context; } // If the context has been set delete all associated files if ($this->editorcontext !== null) { $fs = get_file_storage(); $files = $fs->get_area_files($this->editorcontext->id, 'calendar', 'event_description', $this->properties->id); foreach ($files as $file) { $file->delete(); } } // Fire the event deleted hook self::calendar_event_hook('delete_event', array($this->properties->id, $deleterepeated)); // If we need to delete repeated events then we will fetch them all and delete one by one if ($deleterepeated && !empty($this->properties->repeatid) && $this->properties->repeatid > 0) { // Get all records where the repeatid is the same as the event being removed $events = $DB->get_records('event', array('repeatid' => $this->properties->repeatid)); // For each of the returned events populate a calendar_event object and call delete // make sure the arg passed is false as we are already deleting all repeats foreach ($events as $event) { $event = new calendar_event($event); $event->delete(false); } } return true; }
/** * Tests for event validations related to calendar_event_deleted event. */ public function test_calendar_event_deleted_validations() { $this->resetAfterTest(); $context = context_user::instance($this->user->id); // Test not setting other['repeatid']. try { \core\event\calendar_event_deleted::create(array('context' => $context, 'objectid' => 2, 'other' => array('timestart' => time(), 'name' => 'event'))); $this->fail("Event validation should not allow \\core\\event\\calendar_event_deleted to be triggered without\n other['repeatid']"); } catch (coding_exception $e) { $this->assertContains('The \'repeatid\' value must be set in other.', $e->getMessage()); } // Test not setting other['name']. try { \core\event\calendar_event_deleted::create(array('context' => $context, 'objectid' => 2, 'other' => array('repeatid' => 0, 'timestart' => time()))); $this->fail("Event validation should not allow \\core\\event\\calendar_event_deleted to be triggered without\n other['name']"); } catch (coding_exception $e) { $this->assertContains('The \'name\' value must be set in other.', $e->getMessage()); } // Test not setting other['timestart']. try { \core\event\calendar_event_deleted::create(array('context' => $context, 'objectid' => 2, 'other' => array('name' => 'event', 'repeatid' => 0))); $this->fail("Event validation should not allow \\core\\event\\calendar_event_deleted to be triggered without\n other['timestart']"); } catch (coding_exception $e) { $this->assertContains('The \'timestart\' value must be set in other.', $e->getMessage()); } }