app->singleton(ApplicationUrlService::class); $this->app->singleton(AttendancePolicyService::class); $this->app->singleton(SemesterRangeService::class); $this->app->singleton(AttendanceRecordSyncService::class); $this->app->singleton(StudentAttendanceWriterService::class); $this->app->singleton(TeacherAttendanceSubmissionService::class); $this->app->singleton(AttendanceAutoPublishService::class); $this->app->bind(AttendanceMailerService::class, DefaultAttendanceMailerService::class); $this->app->singleton(StaffTimeOffLinkService::class); $this->app->singleton(InvoiceConfigService::class); $this->app->bind(InvoiceGradeService::class, function ($app) { $config = $app->make(InvoiceConfigService::class); return new InvoiceGradeService($config->getGradeFee()); }); $this->app->bind(InvoiceTuitionService::class, function ($app) { $config = $app->make(InvoiceConfigService::class); return new InvoiceTuitionService( $app->make(InvoiceGradeService::class), $config->getGradeFee(), $config->getFirstStudentFee(), $config->getSecondStudentFee(), $config->getYouthFee(), $config->getTimezone() ); }); } public function boot(): void { $this->registerSqliteRegexpFunction(); Gate::policy(NavItem::class, NavItemPolicy::class); Gate::policy(ClassSection::class, ClassSectionPolicy::class); Gate::policy(IpAttempt::class, IpAttemptPolicy::class); Gate::policy(LateSlipLog::class, LateSlipLogPolicy::class); Gate::policy(Message::class, MessagePolicy::class); Gate::policy(Preferences::class, PreferencesPolicy::class); Gate::policy(Staff::class, StaffPolicy::class); Gate::policy(SupportRequest::class, SupportRequestPolicy::class); Gate::policy(Setting::class, SettingPolicy::class); Gate::policy(ClassProgressReport::class, ClassProgressReportPolicy::class); // Re-register the sanctum guard driver to ensure it is available even // when a stale cached config lacks the sanctum auth guard entry. Auth::resolved(function ($auth): void { $auth->extend('sanctum', function ($app, $name, array $config) use ($auth) { return tap( new \Illuminate\Auth\RequestGuard( new \Laravel\Sanctum\Guard( $auth, config('sanctum.expiration'), $config['provider'] ?? null, config('sanctum.last_used_at', true), ), request(), $auth->createUserProvider($config['provider'] ?? null), ), fn ($guard) => app()->refresh('request', $guard, 'setRequest'), ); }); }); $this->app->resolving(FormRequest::class, function (FormRequest $request, $app): void { $request->setContainer($app)->setRedirector($app->make(Redirector::class)); }); } private function registerSqliteRegexpFunction(): void { try { $connection = DB::connection(); if ($connection->getDriverName() !== 'sqlite') { return; } $pdo = $connection->getPdo(); if (! method_exists($pdo, 'sqliteCreateFunction')) { return; } $pdo->sqliteCreateFunction('REGEXP', static function ($pattern, $value): int { if ($pattern === null || $value === null) { return 0; } return preg_match('/'.str_replace('/', '\\/', (string) $pattern).'/', (string) $value) === 1 ? 1 : 0; }, 2); } catch (\Throwable) { // Some unit tests boot without a configured database; SQLite compatibility is best-effort there. } } }