public function validation($data, $files) { $errors = parent::validation($data, $files); // Check number of appointments vs exclusivity $numappointments = 0; for ($i = 0; $i < $data['appointment_repeats']; $i++) { if ($data['studentid'][$i] > 0) { $numappointments++; } } if ($data['exclusivityenable'] && $data['exclusivity'] <= 0) { $errors['exclusivitygroup'] = get_string('exclusivitypositive', 'scheduler'); } else { if ($data['exclusivityenable'] && $numappointments > $data['exclusivity']) { $errors['exclusivitygroup'] = get_string('exclusivityoverload', 'scheduler', $numappointments); } } // Avoid empty slots starting in the past if ($numappointments == 0 && $data['starttime'] < time()) { $errors['starttime'] = get_string('startpast', 'scheduler'); } // Check whether students have been selected several times for ($i = 0; $i < $data['appointment_repeats']; $i++) { for ($j = 0; $j < $i; $j++) { if ($data['studentid'][$i] > 0 && $data['studentid'][$i] == $data['studentid'][$j]) { $errors['studgroup[' . $i . ']'] = get_string('studentmultiselect', 'scheduler'); $errors['studgroup[' . $j . ']'] = get_string('studentmultiselect', 'scheduler'); } } } if (!isset($data['ignoreconflicts'])) { // Avoid overlapping slots, by asking the user if they'd like to overwrite the existing ones... // for other scheduler, we check independently of exclusivity. Any slot here conflicts // for this scheduler, we check against exclusivity. Any complete slot here conflicts $conflicts_remote = scheduler_get_conflicts($this->scheduler->id, $data['starttime'], $data['starttime'] + $data['duration'] * 60, $data['teacherid'], 0, SCHEDULER_OTHERS, false); $conflicts_local = scheduler_get_conflicts($this->scheduler->id, $data['starttime'], $data['starttime'] + $data['duration'] * 60, $data['teacherid'], 0, SCHEDULER_SELF, true); if (!$conflicts_remote) { $conflicts_remote = array(); } if (!$conflicts_local) { $conflicts_local = array(); } $conflicts = $conflicts_remote + $conflicts_local; // remove itself from conflicts when updating if (array_key_exists($this->slotid, $conflicts)) { unset($conflicts[$this->slotid]); } if (count($conflicts)) { $msg = get_string('slotwarning', 'scheduler'); foreach ($conflicts as $conflict) { $students = scheduler_get_appointed($conflict->id); $slotmsg = userdate($conflict->starttime); $slotmsg .= ' ['; $slotmsg .= $conflict->duration . ' ' . get_string('minutes'); $slotmsg .= ']'; if ($students) { $slotmsg .= ' ('; $appointed = array(); foreach ($students as $astudent) { $appointed[] = fullname($astudent); } if (count($appointed)) { $slotmsg .= implode(', ', $appointed); } unset($appointed); $slotmsg .= ')'; $slotmsg = html_writer::tag('b', $slotmsg); } $msg .= html_writer::div($slotmsg); } $errors['starttime'] = $msg; } } return $errors; }
$data->timeend += DAYSECS; } if ($data->displayfrom == 'now') { $slot->hideuntil = time(); } else { $slot->hideuntil = make_timestamp($eventdate['year'], $eventdate['mon'], $eventdate['mday'], 6, 0) - $data->displayfrom; } if ($data->emailfrom == 'never') { $slot->emaildate = 0; } else { $slot->emaildate = make_timestamp($eventdate['year'], $eventdate['mon'], $eventdate['mday'], 0, 0) - $data->emailfrom; } // echo " generating from " .userdate($slot->starttime)." till ".userdate($data->timeend). " "; // echo " generating on " . ($data->timeend - $slot->starttime) / 60; while ($slot->starttime <= $data->timeend - $data->duration * 60) { $conflicts = scheduler_get_conflicts($scheduler->id, $data->timestart, $data->timestart + $data->duration * 60, $data->teacherid, false, SCHEDULER_ALL); if ($conflicts) { if (!$data->forcewhenoverlap) { print_string('conflictingslots', 'scheduler'); echo '<ul>'; foreach ($conflicts as $aConflict) { $sql = "\n SELECT\n c.fullname,\n c.shortname,\n sl.starttime\n FROM\n {$CFG->prefix}course AS c,\n {$CFG->prefix}scheduler AS s,\n {$CFG->prefix}scheduler_slots AS sl\n WHERE\n s.course = c.id AND\n sl.schedulerid = s.id AND\n sl.id = {$aConflict->id} \n "; $conflictinfo = get_record_sql($sql); echo '<li> ' . userdate($conflictinfo->starttime) . ' ' . usertime($conflictinfo->starttime) . ' ' . get_string('incourse', 'scheduler') . ': ' . $conflictinfo->shortname . ' - ' . $conflictinfo->fullname . "</li>\n"; } echo '</ul><br/>'; } else { // we force, so delete all conflicting before inserting foreach ($conflicts as $conflict) { scheduler_delete_slot($conflict->id); }
function scheduler_action_doaddsession($scheduler, $formdata) { global $DB, $output; $data = (object) $formdata; $fordays = 0; if ($data->rangeend > 0) { $fordays = ($data->rangeend - $data->rangestart) / DAYSECS; } // Create as many slots of $duration as will fit between $starttime and $endtime and that do not conflict. $countslots = 0; $couldnotcreateslots = ''; $startfrom = $data->rangestart + ($data->starthour * 60 + $data->startminute) * 60; $endat = $data->rangestart + ($data->endhour * 60 + $data->endminute) * 60; $slot = new stdClass(); $slot->schedulerid = $scheduler->id; $slot->teacherid = $data->teacherid; $slot->appointmentlocation = $data->appointmentlocation; $slot->exclusivity = $data->exclusivityenable ? $data->exclusivity : 0; if ($data->divide) { $slot->duration = $data->duration; } else { $slot->duration = $data->endhour * 60 + $data->endminute - $data->starthour * 60 - $data->startminute; } $slot->notes = ''; $slot->notesformat = FORMAT_HTML; $slot->timemodified = time(); for ($d = 0; $d <= $fordays; $d++) { $starttime = $startfrom + $d * DAYSECS; $eventdate = usergetdate($starttime); $dayofweek = $eventdate['wday']; if ($dayofweek == 1 && $data->monday == 1 || $dayofweek == 2 && $data->tuesday == 1 || $dayofweek == 3 && $data->wednesday == 1 || $dayofweek == 4 && $data->thursday == 1 || $dayofweek == 5 && $data->friday == 1 || $dayofweek == 6 && $data->saturday == 1 || $dayofweek == 0 && $data->sunday == 1) { $slot->starttime = make_timestamp($eventdate['year'], $eventdate['mon'], $eventdate['mday'], $data->starthour, $data->startminute); $data->timestart = $slot->starttime; $data->timeend = make_timestamp($eventdate['year'], $eventdate['mon'], $eventdate['mday'], $data->endhour, $data->endminute); // this corrects around midnight bug if ($data->timestart > $data->timeend) { $data->timeend += DAYSECS; } if ($data->hideuntilrel == 0) { $slot->hideuntil = time(); } else { $slot->hideuntil = make_timestamp($eventdate['year'], $eventdate['mon'], $eventdate['mday'], 6, 0) - $data->hideuntilrel; } if ($data->emaildaterel == -1) { $slot->emaildate = 0; } else { $slot->emaildate = make_timestamp($eventdate['year'], $eventdate['mon'], $eventdate['mday'], 0, 0) - $data->emaildaterel; } while ($slot->starttime <= $data->timeend - $slot->duration * 60) { $conflicts = scheduler_get_conflicts($scheduler->id, $data->timestart, $data->timestart + $slot->duration * 60, $data->teacherid, 0, SCHEDULER_ALL, false); if ($conflicts) { if (!$data->forcewhenoverlap) { print_string('conflictingslots', 'scheduler'); echo '<ul>'; foreach ($conflicts as $aconflict) { $sql = 'SELECT c.fullname, c.shortname, s.name as schedname, sl.starttime ' . 'FROM {course} c, {scheduler} s, {scheduler_slots} sl ' . 'WHERE s.course = c.id AND sl.schedulerid = s.id AND sl.id = :conflictid'; $conflictinfo = $DB->get_record_sql($sql, array('conflictid' => $aconflict->id)); $msg = $output->userdate($conflictinfo->starttime) . ', ' . $output->usertime($conflictinfo->starttime) . ': '; $msg .= s($conflictinfo->schedname) . ' ' . get_string('incourse', 'scheduler') . ' '; $msg .= $conflictinfo->shortname . ' - ' . $conflictinfo->fullname; echo html_writer::tag('li', $msg); } echo '</ul><br/>'; } else { // we force, so delete all conflicting before inserting foreach ($conflicts as $conflict) { $cslot = $scheduler->get_slot($conflict->id); $cslot->delete(); } } } if (!$conflicts || $data->forcewhenoverlap) { $DB->insert_record('scheduler_slots', $slot, false, true); $countslots++; } $slot->starttime += ($slot->duration + $data->break) * 60; $data->timestart += ($slot->duration + $data->break) * 60; } } } echo $output->action_message(get_string('slotsadded', 'scheduler', $countslots)); }
print_simple_box_end(); // clean all late slots (for every body, anyway, they are passed !!) scheduler_free_late_unused_slots($scheduler->id); /// get information about appointment attention $sql = "\n SELECT\n COUNT(*)\n FROM\n {$CFG->prefix}scheduler_slots AS s,\n {$CFG->prefix}scheduler_appointment AS a\n WHERE\n s.id = a.slotid AND\n a.studentid = {$USER->id} AND\n a.attended = 1 AND\n s.schedulerid = {$scheduler->id}\n "; $hasattended = count_records_sql($sql); /// get available slots $haveunattendedappointments = false; if ($slots = scheduler_get_available_slots($USER->id, $scheduler->id, true)) { $minhidedate = 0; // very far in the past $studentSlots = array(); $studentAttendedSlots = array(); foreach ($slots as $slot) { /// check if other appointement is not "on the way". Student could not apply to it. if (scheduler_get_conflicts($scheduler->id, $slot->starttime, $slot->starttime + $slot->duration * 60, 0, $USER->id, SCHEDULER_OTHERS)) { continue; } /// check if not mine and late, don't care if (!$slot->appointedbyme and $slot->starttime + 60 * $slot->duration < time()) { continue; } /// check what to print in groupsession indication if ($slot->exclusivity == 0) { $slot->groupsession = get_string('yes'); } else { // $consumed = scheduler_get_consumed($scheduler->id, $slot->starttime, $slot->starttime + $slot->duration * 60, $slot->teacher); if ($slot->exclusivity > $slot->population) { $slot->groupsession = get_string('limited', 'scheduler', $slot->exclusivity - $slot->population . "/" . $slot->exclusivity); } else { // should not be visible to students