/** * Cascade NOE date and duration changes to students who have already confirmed * @param int $id The NOE ID * @param array $new The new exam details * @param array $old The old exam details * @param int $user_id The user ID */ protected function cascadeExamStartAndDuration($id, array $new, array $old, $user_id) { if ($old === $new) { return; } $requestsModel = new Requests($this->db); //Fetch all the students who have already confirmed an exam for this NOE $sql = "SELECT e.official_evaluation_starttime, e.official_evaluation_endtime, e.extra_time_minutes,\n e.extra_time_choice, e.request_id, e.student_num, CONCAT_WS(' ', s.first_name, s.last_name) AS name,\n s.email, p.course_code, p.course_section, p.teach_method, p.exam_type\n FROM ventus_exam_requests e\n JOIN org_students s\n ON e.student_num = s.student_id\n JOIN ventus_professor_exam_requests p\n ON e.professor_exam_request_id = p.exam_request_id\n WHERE e.professor_exam_request_id = :id\n AND e.is_cancelled = 0;"; $exams = $this->db->query($sql, array('id' => $id))->fetchAll(); foreach ($exams as $s) { $newData['extra_time_minutes'] = (int) $s['extra_time_minutes']; //Has the exam duration changed? If so, we need the update the extra time minutes for a request if ($old['exam_duration'] !== $new['exam_duration']) { //The ratio is old duration to new duration is used to derive the new extra time minutes given the old extra time minutes $newData['extra_time_minutes'] = (int) $s['extra_time_minutes'] * (int) $new['exam_duration'] / (int) $old['exam_duration']; } //Regular end time is always start date + minutes set by professor $duration = new \DateInterval("PT{$new['exam_duration']}M"); $newData['evaluation_endtime'] = \DateTime::createFromFormat(DATETIME_MYSQL, $new['exam_date'])->add($duration); //Default case: There is no extra time, use the information provided by the professor $newData['official_evaluation_starttime'] = new \DateTime($new['exam_date']); $newData['official_evaluation_endtime'] = clone $newData['evaluation_endtime']; //Case where student does have extra time if (!empty($newData['extra_time_minutes']) && !empty($s['extra_time_choice'])) { $extra_time = new \DateInterval("PT{$newData['extra_time_minutes']}M"); switch ($s['extra_time_choice']) { case "start-of-exam": $newData['official_evaluation_starttime']->sub($extra_time); break; case "end-of-exam": $newData['official_evaluation_endtime']->add($extra_time); break; } } $adjusted_times = $requestsModel->fitExamWithinRange($newData['official_evaluation_starttime'], $newData['official_evaluation_endtime'], $s['exam_type'] === 'final'); $newData['official_evaluation_starttime'] = $adjusted_times['start']; $newData['official_evaluation_endtime'] = $adjusted_times['end']; //Update exam times $newKeys = array('evaluation_endtime', 'official_evaluation_starttime', 'official_evaluation_endtime', 'extra_time_minutes'); $newData = $this->db->pick($newKeys, $newData); $newData['evaluation_endtime'] = $newData['evaluation_endtime']->format(DATETIME_MYSQL); $newData['official_evaluation_starttime'] = $newData['official_evaluation_starttime']->format(DATETIME_MYSQL); $newData['official_evaluation_endtime'] = $newData['official_evaluation_endtime']->format(DATETIME_MYSQL); $newData['emp_id'] = $user_id; $newData['request_id'] = $s['request_id']; $uSql = "UPDATE ventus_exam_requests\n SET evaluation_endtime = :evaluation_endtime, official_evaluation_starttime = :official_evaluation_starttime,\n official_evaluation_endtime = :official_evaluation_endtime, extra_time_minutes = :extra_time_minutes,\n emp_id = :emp_id, updated_on = NOW()\n WHERE request_id = :request_id;"; $this->db->query($uSql, $newData); $this->sendExamChangeNotificationToStudent($s['name'], $s['email'], "{$s['course_code']}{$s['course_section']} {$s['teach_method']}", $newData['official_evaluation_starttime'], $newData['official_evaluation_endtime'], $new['exam_duration']); } }