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