setReplyTo($rtEmail, $rtName); } } catch (\Throwable $e) { // Ignore; ensure service is still usable even if headers not yet setable } return $email; } public static function PHPMailer(bool $getShared = true) { if ($getShared) { return static::getSharedInstance('PHPMailer'); } $mail = new PHPMailer(true); $host = (string) env('MAIL_DEFAULT_HOST', env('SMTP_HOST', 'smtp.gmail.com')); $user = (string) env('MAIL_DEFAULT_USER', env('SMTP_USER', '')); $pass = (string) env('MAIL_DEFAULT_PASS', env('SMTP_PASS', '')); $port = (int) env('MAIL_DEFAULT_PORT', env('SMTP_PORT', 465)); $encryption = strtolower((string) env('MAIL_DEFAULT_ENCRYPTION', env('SMTP_ENCRYPTION', 'ssl'))); $mail->isSMTP(); $mail->Host = $host; $mail->SMTPAuth = true; $mail->Username = $user; $mail->Password = $pass; $mail->SMTPSecure = in_array($encryption, ['tls', 'starttls'], true) ? PHPMailer::ENCRYPTION_STARTTLS : PHPMailer::ENCRYPTION_SMTPS; $mail->Port = $port > 0 ? $port : 465; $mail->Timeout = 10; $mail->SMTPKeepAlive = false; $mail->SMTPDebug = 0; $mail->Debugoutput = 'error_log'; return $mail; } /** * Build (or fetch a shared) SemesterScoreService instance. * * Usage: * $svc = service('semesterScoreService'); // shared * $svc = \Config\Services::semesterScoreService(); // shared * $svc = \Config\Services::semesterScoreService(false); // NEW instance (not shared) */ public static function semesterScoreService(bool $getShared = true): SemesterScoreService { if ($getShared) { return static::getSharedInstance('semesterScoreService'); } // Core models $scoreModel = new SemesterScoreModel(); $configModel = new ConfigurationModel(); // Calculators (inject their models) $homeworkCalc = new HomeworkCalculator(new HomeworkModel()); $quizCalc = new QuizCalculator(new QuizModel()); $projectCalc = new ProjectCalculator(new ProjectModel()); $attendanceCalc = new AttendanceCalculator( new AttendanceRecordModel(), new ConfigurationModel(), new CalendarModel() ); // If you later add Midterm/Final/Participation calculators, plug them in here. return new SemesterScoreService( $scoreModel, $configModel, $homeworkCalc, $quizCalc, $projectCalc, $attendanceCalc ); } public static function roleService($getShared = true) { if ($getShared) { return static::getSharedInstance('roleService'); } return new \App\Services\RoleService(); } public static function emailService($getShared = true) { if ($getShared) { return static::getSharedInstance('emailService'); } // Replace with your real EmailService class + constructor args return new \App\Services\EmailService(); } /** * TimeService shared builder (timezone detection + conversions). */ public static function timeService(bool $getShared = true): \App\Services\TimeService { if ($getShared) { return static::getSharedInstance('timeService'); } return new \App\Services\TimeService(); } /** * Shared API client for outbound HTTP to external services. */ public static function apiClient(bool $getShared = true): \App\Services\ApiClient { if ($getShared) { return static::getSharedInstance('apiClient'); } $apiConfig = config('Api'); $options = [ 'baseURI' => $apiConfig->baseURL ?: null, 'timeout' => $apiConfig->timeout, 'headers' => $apiConfig->defaultHeaders, ]; // Remove null/empty values that may cause issues $options = array_filter($options, static function ($v) { return $v !== null && $v !== ''; }); $http = static::curlrequest($options); return new \App\Services\ApiClient($http, $apiConfig); } public static function schoolYearContext(bool $getShared = true): \App\Services\SchoolYearContextService { if ($getShared) { return static::getSharedInstance('schoolYearContext'); } return new \App\Services\SchoolYearContextService( model(\App\Models\SchoolYearModel::class), static::schoolYearAccessPolicy() ); } public static function schoolYearAccessPolicy(bool $getShared = true): \App\Services\SchoolYearAccessPolicy { if ($getShared) { return static::getSharedInstance('schoolYearAccessPolicy'); } return new \App\Services\SchoolYearAccessPolicy(); } public static function schoolYearViewData(bool $getShared = true): \App\Services\SchoolYearViewDataService { if ($getShared) { return static::getSharedInstance('schoolYearViewData'); } return new \App\Services\SchoolYearViewDataService( static::schoolYearContext(), static::schoolYearAccessPolicy() ); } public static function schoolYearWriteGuard(bool $getShared = true): \App\Services\SchoolYearWriteGuard { if ($getShared) { return static::getSharedInstance('schoolYearWriteGuard'); } return new \App\Services\SchoolYearWriteGuard(); } public static function schoolYearValidation(bool $getShared = true): \App\Services\SchoolYearValidationService { if ($getShared) { return static::getSharedInstance('schoolYearValidation'); } return new \App\Services\SchoolYearValidationService( model(\App\Models\SchoolYearModel::class) ); } public static function staffDirectorySync(bool $getShared = true): \App\Services\StaffDirectorySyncService { if ($getShared) { return static::getSharedInstance('staffDirectorySync'); } return new \App\Services\StaffDirectorySyncService( model(\App\Models\StaffModel::class), model(\App\Models\UserModel::class), model(\App\Models\ConfigurationModel::class), \Config\Database::connect() ); } public static function schoolYearManagement(bool $getShared = true): \App\Services\SchoolYearManagementService { if ($getShared) { return static::getSharedInstance('schoolYearManagement'); } return new \App\Services\SchoolYearManagementService( model(\App\Models\SchoolYearModel::class), model(\App\Models\ConfigurationModel::class), model(\App\Models\SchoolYearTransitionLogModel::class), model(\App\Models\SchoolYearClosingBatchModel::class), static::schoolYearValidation(), \Config\Database::connect() ); } public static function schoolYearClosing(bool $getShared = true): \App\Services\SchoolYearClosingService { if ($getShared) { return static::getSharedInstance('schoolYearClosing'); } return new \App\Services\SchoolYearClosingService( model(\App\Models\SchoolYearModel::class), model(\App\Models\SchoolYearClosingBatchModel::class), model(\App\Models\SchoolYearClosingItemModel::class), static::schoolYearManagement(), \Config\Database::connect() ); } public static function enrollmentTransition(bool $getShared = true): \App\Services\EnrollmentTransitionService { if ($getShared) { return static::getSharedInstance('enrollmentTransition'); } return new \App\Services\EnrollmentTransitionService(\Config\Database::connect()); } public static function enrollmentStatus(bool $getShared = true): \App\Services\EnrollmentStatusService { if ($getShared) { return static::getSharedInstance('enrollmentStatus'); } return new \App\Services\EnrollmentStatusService(\Config\Database::connect()); } public static function enrollmentRegistrationEmail(bool $getShared = true): \App\Services\EnrollmentRegistrationEmailService { if ($getShared) { return static::getSharedInstance('enrollmentRegistrationEmail'); } return new \App\Services\EnrollmentRegistrationEmailService( \Config\Database::connect(), static::enrollmentTransition(), static::emailService() ); } public static function financialAid(bool $getShared = true): \App\Services\FinancialAidService { if ($getShared) { return static::getSharedInstance('financialAid'); } return new \App\Services\FinancialAidService( model(\App\Models\FinancialAidRequestModel::class), model(\App\Models\InvoiceModel::class), model(\App\Models\DiscountVoucherModel::class), model(\App\Models\DiscountUsageModel::class), new \App\Libraries\InvoiceLedgerService() ); } }