diff --git a/backup/moodle2/backup_attendance_stepslib.php b/backup/moodle2/backup_attendance_stepslib.php
index 877f6e8..275903b 100644
--- a/backup/moodle2/backup_attendance_stepslib.php
+++ b/backup/moodle2/backup_attendance_stepslib.php
@@ -53,7 +53,7 @@ class backup_attendance_activity_structure_step extends backup_activity_structur
$sessions = new backup_nested_element('sessions');
$session = new backup_nested_element('session', array('id'), array(
'groupid', 'sessdate', 'duration', 'lasttaken', 'lasttakenby',
- 'timemodified', 'description', 'descriptionformat'));
+ 'timemodified', 'description', 'descriptionformat', 'caleventid'));
// XML nodes declaration - user data.
$logs = new backup_nested_element('logs');
diff --git a/backup/moodle2/restore_attendance_stepslib.php b/backup/moodle2/restore_attendance_stepslib.php
index f8c0dae..97bd5ed 100644
--- a/backup/moodle2/restore_attendance_stepslib.php
+++ b/backup/moodle2/restore_attendance_stepslib.php
@@ -117,6 +117,7 @@ class restore_attendance_activity_structure_step extends restore_activity_struct
$data->lasttaken = $this->apply_date_offset($data->lasttaken);
$data->lasttakenby = $this->get_mappingid('user', $data->lasttakenby);
$data->timemodified = $this->apply_date_offset($data->timemodified);
+ $data->caleventid = $this->get_mappingid('event', $data->caleventid);
$newitemid = $DB->insert_record('attendance_sessions', $data);
$this->set_mapping('attendance_session', $oldid, $newitemid, true);
diff --git a/classes/calendar_helpers.php b/classes/calendar_helpers.php
new file mode 100644
index 0000000..fe30c95
--- /dev/null
+++ b/classes/calendar_helpers.php
@@ -0,0 +1,136 @@
+.
+/**
+ * Calendar related functions
+ *
+ * @package mod_attendance
+ * @copyright 2016 Vyacheslav Strelkov
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+require_once(dirname(__FILE__).'/../../../calendar/lib.php');
+
+/**
+ * Create single calendar event bases on session data.
+ *
+ * @param stdClass $session initial sessions to take data from
+ * @return bool result of calendar event creation
+ */
+function create_calendar_event(&$session) {
+ // We don't want to create multiple calendar events for 1 session.
+ if ($session->caleventid) {
+ return $session->caleventid;
+ }
+
+ global $DB;
+ $attendance = $DB->get_record('attendance', array('id' => $session->attendanceid));
+
+ $caleventdata = new stdClass();
+ $caleventdata->name = $attendance->name;
+ $caleventdata->courseid = $attendance->course;
+ $caleventdata->groupid = $session->groupid;
+ $caleventdata->instance = $session->attendanceid;
+ $caleventdata->timestart = $session->sessdate;
+ $caleventdata->timeduration = $session->duration;
+ $caleventdata->eventtype = 'attendance';
+ $caleventdata->timemodified = time();
+ $caleventdata->modulename = 'attendance';
+
+ $calevent = new stdClass();
+ if ($calevent = calendar_event::create($caleventdata, false)) {
+ $session->caleventid = $calevent->id;
+ $DB->set_field('attendance_sessions', 'caleventid', $session->caleventid, array('id' => $session->id));
+ return true;
+ } else {
+ return false;
+ }
+}
+
+/**
+ * Create multiple calendar events based on sessions data.
+ *
+ * @param array %sessionsids array of sessions ids
+ */
+function create_calendar_events($sessionsids) {
+ global $DB;
+ $sessions = $DB->get_recordset_list('attendance_sessions', 'id', $sessionsids);
+
+ foreach ($sessions as $session) {
+ create_calendar_event($session);
+ if ($session->caleventid) {
+ $DB->update_record('attendance_sessions', $session);
+ }
+ }
+}
+
+/**
+ * Update calendar event duration and date
+ *
+ * @param $caleventid int calendar event id
+ * @param $timeduration int duration of the event
+ * @param $timestart int start time of the event
+ * @return bool result of updating
+ */
+function update_calendar_event($caleventid, $timeduration, $timestart = null) {
+ $caleventdata = new stdClass();
+ $caleventdata->timeduration = $timeduration;
+ $caleventdata->timestart = $timestart;
+ $caleventdata->timemodified = time();
+
+ $calendarevent = calendar_event::load($caleventid);
+ if ($calendarevent) {
+ return $calendarevent->update($caleventdata) ? true : false;
+ } else {
+ return false;
+ }
+}
+
+/**
+ * Delete calendar events for sessions
+ *
+ * @param array %sessionsids array of sessions ids
+ * @return bool result of updating
+ */
+function delete_calendar_events($sessionsids) {
+ global $DB;
+ $caleventsids = existing_calendar_events_ids($sessionsids);
+ if ($caleventsids) {
+ $DB->delete_records_list('event', 'id', $caleventsids);
+ }
+
+ $sessions = $DB->get_recordset_list('attendance_sessions', 'id', $sessionsids);
+ foreach ($sessions as $session) {
+ $session->caleventid = 0;
+ $DB->update_record('attendance_sessions', $session);
+ }
+}
+
+/**
+ * Check if calendar events are created for given sessions
+ *
+ * @param array $sessionsids of sessions ids
+ * @return array | bool array of existing calendar events or false if none found
+ */
+function existing_calendar_events_ids($sessionsids) {
+ global $DB;
+ $caleventsids = array_keys($DB->get_records_list('attendance_sessions', 'id', $sessionsids, '', 'caleventid'));
+ $existingcaleventsids = array_filter($caleventsids);
+ if (! empty($existingcaleventsids)) {
+ return $existingcaleventsids;
+ } else {
+ return false;
+ }
+}
\ No newline at end of file
diff --git a/classes/sessions_page_params.php b/classes/sessions_page_params.php
index e59d8a3..0731b29 100644
--- a/classes/sessions_page_params.php
+++ b/classes/sessions_page_params.php
@@ -30,12 +30,14 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class mod_attendance_sessions_page_params {
- const ACTION_ADD = 1;
- const ACTION_UPDATE = 2;
- const ACTION_DELETE = 3;
- const ACTION_DELETE_SELECTED = 4;
- const ACTION_CHANGE_DURATION = 5;
- const ACTION_DELETE_HIDDEN = 6;
+ const ACTION_ADD = 1;
+ const ACTION_UPDATE = 2;
+ const ACTION_DELETE = 3;
+ const ACTION_DELETE_SELECTED = 4;
+ const ACTION_CHANGE_DURATION = 5;
+ const ACTION_DELETE_HIDDEN = 6;
+ const ACTION_CREATE_CAL_EVENTS = 7;
+ const ACTION_DELETE_CAL_EVENTS = 8;
/** @var int view mode of taking attendance page*/
public $action;
diff --git a/classes/structure.php b/classes/structure.php
index a89bd20..9d67b12 100644
--- a/classes/structure.php
+++ b/classes/structure.php
@@ -22,6 +22,8 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
+require_once(dirname(__FILE__) . '/calendar_helpers.php');
+
/**
* Main class with all Attendance related info.
*
@@ -349,6 +351,9 @@ class mod_attendance_structure {
$sess->description);
$DB->set_field('attendance_sessions', 'description', $description, array('id' => $sess->id));
+ $sess->caleventid = 0;
+ create_calendar_event($sess);
+
$infoarray = array();
$infoarray[] = construct_session_full_date_time($sess->sessdate, $sess->duration);
@@ -390,6 +395,8 @@ class mod_attendance_structure {
$sess->timemodified = time();
$DB->update_record('attendance_sessions', $sess);
+ update_calendar_event($sess->caleventid, $sess->duration, $sess->sessdate);
+
$info = construct_session_full_date_time($sess->sessdate, $sess->duration);
$event = \mod_attendance\event\session_updated::create(array(
'objectid' => $this->id,
@@ -884,6 +891,9 @@ class mod_attendance_structure {
public function delete_sessions($sessionsids) {
global $DB;
+ if (existing_calendar_events_ids($sessionsids)) {
+ delete_calendar_events($sessionsids);
+ }
list($sql, $params) = $DB->get_in_or_equal($sessionsids);
$DB->delete_records_select('attendance_log', "sessionid $sql", $params);
@@ -905,6 +915,9 @@ class mod_attendance_structure {
$sess->duration = $duration;
$sess->timemodified = $now;
$DB->update_record('attendance_sessions', $sess);
+ if ($sess->caleventid) {
+ update_calendar_event($sess->caleventid, $duration);
+ }
$event = \mod_attendance\event\session_duration_updated::create(array(
'objectid' => $this->id,
'context' => $this->context,
diff --git a/db/install.xml b/db/install.xml
index e683ef6..bf40a99 100644
--- a/db/install.xml
+++ b/db/install.xml
@@ -32,6 +32,7 @@
+
@@ -40,6 +41,7 @@
+
diff --git a/db/upgrade.php b/db/upgrade.php
index 20ae691..3494fde 100644
--- a/db/upgrade.php
+++ b/db/upgrade.php
@@ -14,6 +14,8 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see .
+require_once(dirname(__FILE__) . '/upgradelib.php');
+
/**
* upgrade processes for this module.
*
@@ -158,5 +160,22 @@ function xmldb_attendance_upgrade($oldversion=0) {
upgrade_mod_savepoint(true, 2015040503, 'attendance');
}
+ if ($oldversion < 2016052202) {
+ // Adding field to store calendar event ids.
+ $table = new xmldb_table('attendance_sessions');
+ $field = new xmldb_field('caleventid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', null);
+
+ // Conditionally launch add field statusset.
+ if (!$dbman->field_exists($table, $field)) {
+ $dbman->add_field($table, $field);
+ }
+
+ // Creating events for all existing sessions.
+ create_calendar_events();
+
+ // Attendance savepoint reached.
+ upgrade_mod_savepoint(true, 2016052202, 'attendance');
+ }
+
return $result;
}
diff --git a/db/upgradelib.php b/db/upgradelib.php
new file mode 100644
index 0000000..92f96c7
--- /dev/null
+++ b/db/upgradelib.php
@@ -0,0 +1,50 @@
+.
+
+/**
+ * Helper functions to keep upgrade.php clean.
+ *
+ * @package mod_attendance
+ * @copyright 2016 Vyacheslav Strelkov
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+function create_calendar_events() {
+ global $DB;
+
+ $attendances = $DB->get_records('attendance', null, null, 'id, name, course');
+ foreach ($attendances as $att) {
+ $sessionsdata = $DB->get_records('attendance_sessions', array('attendanceid' => $att->id), null,
+ 'id, groupid, sessdate, duration, description, descriptionformat');
+ foreach ($sessionsdata as $session) {
+ $calevent = new stdClass();
+ $calevent->name = $att->name;
+ $calevent->courseid = $att->course;
+ $calevent->groupid = $session->groupid;
+ $calevent->instance = $att->id;
+ $calevent->timestart = $session->sessdate;
+ $calevent->timeduration = $session->duration;
+ $calevent->eventtype = 'attendance';
+ $calevent->timemodified = time();
+ $calevent->modulename = 'attendance';
+ $calevent->description = $session->description;
+ $calevent->format = $session->descriptionformat;
+
+ $caleventid = $DB->insert_record('event', $calevent);
+ $DB->set_field('attendance_sessions', 'caleventid', $caleventid, array('id' => $session->id));
+ }
+ }
+}
diff --git a/lang/en/attendance.php b/lang/en/attendance.php
index edc0ec9..d1f54ab 100644
--- a/lang/en/attendance.php
+++ b/lang/en/attendance.php
@@ -59,6 +59,8 @@ $string['attendance:viewreports'] = 'Viewing Reports';
$string['attforblockdirstillexists'] = 'old mod/attforblock directory still exists - you must delete this directory on your server before running this upgrade.';
$string['attrecords'] = 'Attendances records';
$string['calclose'] = 'Close';
+$string['caleventcreated'] = 'Calendar event for session successfully created';
+$string['caleventdeleted'] = 'Calendar event for session successfully deleted';
$string['calmonths'] = 'January,February,March,April,May,June,July,August,September,October,November,December';
$string['calshow'] = 'Choose date';
$string['caltoday'] = 'Today';
@@ -75,6 +77,8 @@ $string['commonsessions'] = 'All students';
$string['confirmdeleteuser'] = 'Are you sure you want to delete user \'{$a->fullname}\' ({$a->email})?
All of their attendance records will be permanently deleted.';
$string['countofselected'] = 'Count of selected';
$string['copyfrom'] = 'Copy attendance data from';
+$string['createcalevents'] = 'Create calendar events';
+$string['createcheckcalevents'] = 'Are you sure you want to create the calendar events for the following sessions?';
$string['createmultiplesessions'] = 'Create multiple sessions';
$string['createmultiplesessions_help'] = 'This function allows you to create multiple sessions in one simple step.
The sessions begin on the date of the base session and continue until the \'repeat until\' date.
@@ -88,6 +92,8 @@ $string['days'] = 'Days';
$string['defaults'] = 'Defaults';
$string['defaultdisplaymode'] = 'Default display mode';
$string['delete'] = 'Delete';
+$string['deletecalevents'] = 'Delete calendar events';
+$string['deletecheckcalevents'] = 'Are you absolutely sure you want to delete the calendar events for the following sessions?';
$string['deletelogs'] = 'Delete attendance data';
$string['deleteselected'] = 'Delete selected';
$string['deletesession'] = 'Delete session';
diff --git a/lib.php b/lib.php
index dad7d2f..f484a6f 100644
--- a/lib.php
+++ b/lib.php
@@ -22,6 +22,8 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
+require_once(dirname(__FILE__) . '/classes/calendar_helpers.php');
+
/**
* Returns the information if the module supports a feature
*
@@ -102,6 +104,9 @@ function attendance_delete_instance($id) {
}
if ($sessids = array_keys($DB->get_records('attendance_sessions', array('attendanceid' => $id), '', 'id'))) {
+ if (existing_calendar_events_ids($sessids)) {
+ delete_calendar_events($sessids);
+ }
$DB->delete_records_list('attendance_log', 'sessionid', $sessids);
$DB->delete_records('attendance_sessions', array('attendanceid' => $id));
}
@@ -119,6 +124,9 @@ function attendance_delete_course($course, $feedback=true) {
$attids = array_keys($DB->get_records('attendance', array('course' => $course->id), '', 'id'));
$sessids = array_keys($DB->get_records_list('attendance_sessions', 'attendanceid', $attids, '', 'id'));
+ if (existing_calendar_events_ids($sessids)) {
+ delete_calendar_events($sessids);
+ }
if ($sessids) {
$DB->delete_records_list('attendance_log', 'sessionid', $sessids);
}
@@ -194,6 +202,10 @@ function attendance_reset_userdata($data) {
}
if (!empty($data->reset_attendance_sessions)) {
+ $sessionsids = array_keys($DB->get_records_list('attendance_sessions', 'attendanceid', $attids, '', 'id'));
+ if (existing_calendar_events_ids($sessionsids)) {
+ delete_calendar_events($sessionsids);
+ }
$DB->delete_records_list('attendance_sessions', 'attendanceid', $attids);
$status[] = array(
diff --git a/renderer.php b/renderer.php
index ec70c5d..ba328f1 100644
--- a/renderer.php
+++ b/renderer.php
@@ -320,7 +320,9 @@ class mod_attendance_renderer extends plugin_renderer_base {
}
$options = array(mod_attendance_sessions_page_params::ACTION_DELETE_SELECTED => get_string('delete'),
- mod_attendance_sessions_page_params::ACTION_CHANGE_DURATION => get_string('changeduration', 'attendance'));
+ mod_attendance_sessions_page_params::ACTION_CHANGE_DURATION => get_string('changeduration', 'attendance'),
+ mod_attendance_sessions_page_params::ACTION_CREATE_CAL_EVENTS => get_string('createcalevents', 'attendance'),
+ mod_attendance_sessions_page_params::ACTION_DELETE_CAL_EVENTS => get_string('deletecalevents', 'attendance'));
$controls = html_writer::select($options, 'action');
$attributes = array(
diff --git a/sessions.php b/sessions.php
index f879a1a..0ffba45 100644
--- a/sessions.php
+++ b/sessions.php
@@ -133,15 +133,25 @@ switch ($att->pageparams->action) {
echo $OUTPUT->footer();
exit;
case mod_attendance_sessions_page_params::ACTION_DELETE_SELECTED:
+ case mod_attendance_sessions_page_params::ACTION_CREATE_CAL_EVENTS:
+ case mod_attendance_sessions_page_params::ACTION_DELETE_CAL_EVENTS:
$confirm = optional_param('confirm', null, PARAM_INT);
+ $message = get_string('deletecheckfull', '', get_string('session', 'attendance'));
if (isset($confirm) && confirm_sesskey()) {
$sessionsids = required_param('sessionsids', PARAM_ALPHANUMEXT);
$sessionsids = explode('_', $sessionsids);
-
- $att->delete_sessions($sessionsids);
- attendance_update_users_grade($att);
- redirect($att->url_manage(), get_string('sessiondeleted', 'attendance'));
+ if ($att->pageparams->action == mod_attendance_sessions_page_params::ACTION_DELETE_SELECTED) {
+ $att->delete_sessions($sessionsids);
+ attendance_update_users_grade($att);
+ redirect($att->url_manage(), get_string('sessiondeleted', 'attendance'));
+ } else if ($att->pageparams->action == mod_attendance_sessions_page_params::ACTION_CREATE_CAL_EVENTS) {
+ create_calendar_events($sessionsids);
+ redirect($att->url_manage(), get_string('createcheckcalevents', 'attendance'));
+ } else if ($att->pageparams->action == mod_attendance_sessions_page_params::ACTION_DELETE_CAL_EVENTS) {
+ delete_calendar_events($sessionsids);
+ redirect($att->url_manage(), get_string('deletecheckcalevents', 'attendance'));
+ }
}
$sessid = optional_param_array('sessid', '', PARAM_SEQUENCE);
if (empty($sessid)) {
@@ -149,7 +159,12 @@ switch ($att->pageparams->action) {
}
$sessionsinfo = $att->get_sessions_info($sessid);
- $message = get_string('deletecheckfull', '', get_string('session', 'attendance'));
+ if ($att->pageparams->action == mod_attendance_sessions_page_params::ACTION_CREATE_CAL_EVENTS) {
+ $message = get_string('createcheckcalevents', 'attendance');
+ } else if ($att->pageparams->action == mod_attendance_sessions_page_params::ACTION_DELETE_CAL_EVENTS) {
+ $message = get_string('deletecheckcalevents', 'attendance');
+ }
+
$message .= html_writer::empty_tag('br');
foreach ($sessionsinfo as $sessinfo) {
$message .= html_writer::empty_tag('br');
diff --git a/tests/behat/calendar_features.feature b/tests/behat/calendar_features.feature
new file mode 100644
index 0000000..fe3b2cf
--- /dev/null
+++ b/tests/behat/calendar_features.feature
@@ -0,0 +1,81 @@
+@mod @mod_attendance @javascript
+Feature: Test the calendar related features in the attendance module
+
+ Background:
+ Given the following "courses" exist:
+ | fullname | shortname |
+ | Course 1 | C1 |
+ And the following "users" exist:
+ | username | firstname | lastname | email |
+ | teacher1 | Teacher | 1 | teacher1@example.com |
+ | student1 | Student | 1 | student1@example.com |
+ And the following "course enrolments" exist:
+ | course | user | role |
+ | C1 | teacher1 | editingteacher |
+ | C1 | student1 | student |
+ And I log in as "teacher1"
+ And I follow "Course 1"
+ And I turn editing mode on
+ And I add a "Attendance" to section "1" and I fill the form with:
+ | Name | Test attendance |
+ And I log out
+
+ Scenario: Calendar events can be created automatically with sessions creation
+ When I log in as "teacher1"
+ And I follow "Course 1"
+ And I follow "Test attendance"
+ And I follow "Add session"
+ And I set the following fields to these values:
+ | id_sestime_starthour | 01 |
+ | id_sestime_endhour | 02 |
+ And I click on "id_submitbutton" "button"
+ And I follow "Course 1"
+ And I follow "Go to calendar"
+ Then I should see "Test attendance"
+ And I log out
+ And I log in as "student1"
+ And I follow "Go to calendar"
+ Then I should see "Test attendance"
+
+ Scenario: Teacher can delete and create calendar events for sessions
+ When I log in as "teacher1"
+ And I follow "Course 1"
+ And I follow "Test attendance"
+ And I follow "Add session"
+ And I set the following fields to these values:
+ | id_sestime_starthour | 01 |
+ | id_sestime_endhour | 02 |
+ And I click on "id_submitbutton" "button"
+ And I set the following fields to these values:
+ | cb_selector | 1 |
+ | menuaction | Delete calendar events |
+ And I click on "OK" "button"
+ And I click on "Continue" "button"
+ And I follow "Course 1"
+ And I follow "Go to calendar"
+ Then I should not see "Test attendance"
+ And I log out
+ And I log in as "student1"
+ And I follow "Go to calendar"
+ Then I should not see "Test attendance"
+ And I log out
+ And I log in as "teacher1"
+ And I follow "Course 1"
+ And I follow "Test attendance"
+ And I follow "Add session"
+ And I set the following fields to these values:
+ | id_sestime_starthour | 01 |
+ | id_sestime_endhour | 02 |
+ And I click on "id_submitbutton" "button"
+ And I set the following fields to these values:
+ | cb_selector | 1 |
+ | menuaction | Create calendar events |
+ And I click on "OK" "button"
+ And I click on "Continue" "button"
+ And I follow "Course 1"
+ And I follow "Go to calendar"
+ Then I should see "Test attendance"
+ And I log out
+ And I log in as "student1"
+ And I follow "Go to calendar"
+ Then I should see "Test attendance"
\ No newline at end of file
diff --git a/version.php b/version.php
index baff4bf..4ed5a32 100644
--- a/version.php
+++ b/version.php
@@ -22,7 +22,7 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
-$plugin->version = 2016052201;
+$plugin->version = 2016052202;
$plugin->requires = 2016052300;
$plugin->release = '3.1.1.0';
$plugin->maturity = MATURITY_STABLE;