format( 'm' ); $year = (int) $now->format( 'Y' ); $windows = $this->configured_windows(); $rollover_month = $windows[1]['start']['month'] ?? 9; return $month >= $rollover_month ? $year : $year - 1; } /** * Returns the teaching period currently running for $reference (defaults * to now), based on Settings → Academic Year Period Windows. * * Falls back to the legacy Sep–Jan / Feb–Aug split when no window is * configured for any period (e.g. a fresh install, or a cadence whose * windows the admin hasn't set yet). */ public function current_period( ?\DateTimeImmutable $reference = null ): int { $now = $reference ?? new \DateTimeImmutable( 'now', wp_timezone() ); $today = (int) $now->format( 'n' ) * 100 + (int) $now->format( 'j' ); foreach ( $this->configured_windows() as $period => $window ) { if ( $this->in_window( $today, $window ) ) { return $period; } } $month = (int) $now->format( 'm' ); return ( $month >= 9 || 1 === $month ) ? 1 : 2; } /** * Formats a start-year as e.g. 2025 → "2025/26". */ public function format( int $academic_year ): string { $short_next = substr( (string) ( $academic_year + 1 ), -2 ); return "{$academic_year}/{$short_next}"; } /** * @return array * Only periods the admin has actually configured a window for. */ private function configured_windows(): array { $settings = get_option( 'academiccrew_settings', [] ); $windows = $settings['period_windows'] ?? []; $result = []; foreach ( $windows as $period => $window ) { if ( ! empty( $window['start']['month'] ) && ! empty( $window['end']['month'] ) ) { $result[ (int) $period ] = $window; } } ksort( $result ); return $result; } /** Whether $today (an n*100+j "month-day" int) falls inside $window, handling year wraparound. */ private function in_window( int $today, array $window ): bool { $start = (int) $window['start']['month'] * 100 + (int) $window['start']['day']; $end = (int) $window['end']['month'] * 100 + (int) $window['end']['day']; return $start <= $end ? ( $today >= $start && $today <= $end ) : ( $today >= $start || $today <= $end ); // window crosses the new year } }