0 || ($errors['error_count'] ?? 0) > 0)) ) { return null; } $referenceDate = new \DateTimeImmutable($matches[1] . '-09-01'); } catch (\Throwable) { return null; } return $birthDate > $referenceDate ? null : $birthDate->diff($referenceDate)->y; } public static function parentDecisionMessage( array $student, ?array $decisionRow, string $targetSchoolYear, ?string $fallMakeupExamOn = null ): array { $name = trim((string) ($student['firstname'] ?? '') . ' ' . (string) ($student['lastname'] ?? '')); $name = $name !== '' ? $name : 'The student'; $decision = DeliberationDecision::normalize($decisionRow['decision'] ?? null); $source = strtolower(trim((string) ($decisionRow['source'] ?? ''))); if ($decision === DeliberationDecision::EXPELLED) { return self::message($name . ': ' . self::EXPELLED_MESSAGE, true, 'danger'); } if ($decision === DeliberationDecision::WITHDRAWN || ($student['enrollment_status'] ?? null) === 'withdrawn') { return self::message($name . ': ' . self::WITHDRAWN_MESSAGE, true, 'warning'); } if ($decision === DeliberationDecision::DEFERRED_DECISION) { return self::message($name . ': ' . self::DEFERRED_MESSAGE, true, 'warning'); } if ($decision === null && $source === 'pending') { return self::message($name . ': ' . self::MISSING_DECISION_MESSAGE, true, 'warning'); } $age = self::ageOnSeptemberFirst($student['dob'] ?? null, $targetSchoolYear); if ($age !== null && $age >= 18) { return self::message(str_replace('The student', $name, self::ADULT_STUDENT_MESSAGE), true, 'danger'); } if ($decision === DeliberationDecision::MAKE_UP_EXAM) { $dateText = $fallMakeupExamOn !== null ? ' on ' . local_date($fallMakeupExamOn, 'm-d-Y') : ''; return self::message( $name . ' has a make-up exam decision. Enrollment is allowed, but the student will initially remain in the same grade as the closed school year until the fall make-up exam' . $dateText . ' is passed and administration confirms promotion.', false, 'warning' ); } if ($decision === DeliberationDecision::REPEAT_CLASS) { $previousClass = trim((string) ($decisionRow['class_section_name'] ?? '')); $previousClass = $previousClass !== '' ? $previousClass : 'the same class'; return self::message($name . ' has a repeat class decision and is accepted only in ' . $previousClass . '.', false, 'info'); } if ($decision === DeliberationDecision::PASSED || ($decision === null && $source !== 'pending' && trim((string) ($decisionRow['decision'] ?? '')) === '')) { return self::message('', false, 'info'); } return self::message( $name . ' does not have a final academic decision that permits online re-enrollment. Please contact the administration.', true, 'warning' ); } private static function message(string $message, bool $blocking, string $level): array { return [ 'message' => $message, 'blocking' => $blocking, 'level' => $level, ]; } }