Files
root d906a915d6
Deploy to Shared Hosting / Shared hosting deploy (push) Failing after 47s
Tests / PHPUnit (push) Failing after 1m20s
add refund logic and fix books inventory logic
2026-08-22 13:44:25 -04:00

526 lines
18 KiB
PHP

<?php
namespace Config;
use CodeIgniter\Config\BaseService;
use App\Services\SemesterScoreService;
use App\Models\SemesterScoreModel;
use App\Models\ConfigurationModel;
use App\Services\Calculators\HomeworkCalculator;
use App\Services\Calculators\QuizCalculator;
use App\Services\Calculators\ProjectCalculator;
use App\Services\Calculators\AttendanceCalculator;
use App\Models\HomeworkModel;
use App\Models\QuizModel;
use App\Models\ProjectModel;
use App\Models\AttendanceRecordModel;
use App\Models\CalendarModel;
use PHPMailer\PHPMailer\PHPMailer;
/**
* Services Configuration file.
*
* Services are simply other classes/libraries that the system uses
* to do its job. This is used by CodeIgniter to allow the core of the
* framework to be swapped out easily without affecting the usage within
* the rest of your application.
*
* This file holds any application-specific services, or service overrides
* that you might need. An example has been included with the general
* method format you should use for your service methods. For more examples,
* see the core Services file at system/Config/Services.php.
*/
class Services extends BaseService
{
/**
* Override CI Email service to enforce a global Reply-To.
*/
public static function email(?array $config = null, bool $getShared = true)
{
if ($getShared) {
return static::getSharedInstance('email', $config);
}
$config = $config ?? config('Email');
$email = new \CodeIgniter\Email\Email($config);
try {
$rtEmail = env('MAIL_DEFAULT_REPLY_TO');
$rtNameRaw = env('MAIL_DEFAULT_REPLY_TO_NAME');
$rtName = 'Al Rahma Sunday School';
if (is_string($rtNameRaw)) {
$rtNameRaw = trim($rtNameRaw);
if ($rtNameRaw !== '' && !preg_match('/^no[- ]?repl(?:y|ay)$/i', $rtNameRaw)) {
$rtName = $rtNameRaw;
}
}
if ($rtEmail) {
$email->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(),
model(\App\Models\ConfigurationModel::class)
);
}
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()
);
}
public static function enrollmentWithdrawal(bool $getShared = true): \App\Services\EnrollmentWithdrawalService
{
if ($getShared) {
return static::getSharedInstance('enrollmentWithdrawal');
}
$db = \Config\Database::connect();
return new \App\Services\EnrollmentWithdrawalService(
$db,
model(\App\Models\StudentModel::class),
model(\App\Models\EnrollmentModel::class),
model(\App\Models\StudentClassModel::class),
model(\App\Models\ClassSectionModel::class),
model(\App\Models\UserModel::class),
model(\App\Models\InvoiceModel::class),
model(\App\Models\RefundModel::class)
);
}
public static function teacherSubmissionReport(bool $getShared = true): \App\Services\TeacherSubmissionReportService
{
if ($getShared) {
return static::getSharedInstance('teacherSubmissionReport');
}
return new \App\Services\TeacherSubmissionReportService(
\Config\Database::connect(),
model(\App\Models\ConfigurationModel::class),
model(\App\Models\StudentClassModel::class),
model(\App\Models\ClassSectionModel::class),
model(\App\Models\UserModel::class)
);
}
public static function administratorDashboard(bool $getShared = true): \App\Services\AdministratorDashboardService
{
if ($getShared) {
return static::getSharedInstance('administratorDashboard');
}
return new \App\Services\AdministratorDashboardService(
\Config\Database::connect(),
model(\App\Models\UserModel::class),
model(\App\Models\LoginActivityModel::class)
);
}
public static function adminNotificationSettings(bool $getShared = true): \App\Services\AdminNotificationSettingsService
{
if ($getShared) {
return static::getSharedInstance('adminNotificationSettings');
}
return new \App\Services\AdminNotificationSettingsService(
\Config\Database::connect(),
model(\App\Models\AdminNotificationSubjectModel::class)
);
}
public static function administratorDirectory(bool $getShared = true): \App\Services\AdministratorDirectoryService
{
if ($getShared) {
return static::getSharedInstance('administratorDirectory');
}
return new \App\Services\AdministratorDirectoryService(
\Config\Database::connect(),
model(\App\Models\StudentClassModel::class),
model(\App\Models\UserModel::class),
model(\App\Models\UserRoleModel::class),
model(\App\Models\InvoiceModel::class),
model(\App\Models\StudentModel::class)
);
}
public static function gradingScore(bool $getShared = true): \App\Services\GradingScoreService
{
if ($getShared) {
return static::getSharedInstance('gradingScore');
}
$configModel = model(\App\Models\ConfigurationModel::class);
$attendanceCalculator = new \App\Services\Calculators\AttendanceCalculator(
model(\App\Models\AttendanceRecordModel::class),
$configModel,
model(\App\Models\CalendarModel::class)
);
return new \App\Services\GradingScoreService(
\Config\Database::connect(),
$configModel,
model(\App\Models\HomeworkModel::class),
model(\App\Models\UserModel::class),
model(\App\Models\StudentClassModel::class),
model(\App\Models\StudentModel::class),
model(\App\Models\TeacherClassModel::class),
model(\App\Models\ClassSectionModel::class),
$attendanceCalculator,
model(\App\Models\GradingLockModel::class),
static::semesterScoreService(),
(string) $configModel->getConfig('school_year'),
(string) getSemester()
);
}
public static function placementGrading(bool $getShared = true): \App\Services\PlacementGradingService
{
if ($getShared) {
return static::getSharedInstance('placementGrading');
}
$configModel = model(\App\Models\ConfigurationModel::class);
return new \App\Services\PlacementGradingService(
\Config\Database::connect(),
model(\App\Models\StudentModel::class),
model(\App\Models\PlacementLevelModel::class),
model(\App\Models\PlacementBatchModel::class),
model(\App\Models\PlacementScoreModel::class),
(string) $configModel->getConfig('school_year')
);
}
public static function belowSixty(bool $getShared = true): \App\Services\BelowSixtyService
{
if ($getShared) {
return static::getSharedInstance('belowSixty');
}
$configModel = model(\App\Models\ConfigurationModel::class);
return new \App\Services\BelowSixtyService(
\Config\Database::connect(),
$configModel,
model(\App\Models\StudentModel::class),
model(\App\Models\StudentClassModel::class),
model(\App\Models\ParentMeetingScheduleModel::class),
model(\App\Models\UserModel::class),
(string) $configModel->getConfig('school_year'),
(string) getSemester()
);
}
public static function studentDecision(bool $getShared = true): \App\Services\StudentDecisionService
{
if ($getShared) {
return static::getSharedInstance('studentDecision');
}
$configModel = model(\App\Models\ConfigurationModel::class);
return new \App\Services\StudentDecisionService(
\Config\Database::connect(),
$configModel,
model(\App\Models\StudentModel::class),
model(\App\Models\StudentClassModel::class),
model(\App\Models\UserModel::class),
(string) $configModel->getConfig('school_year'),
(string) getSemester()
);
}
public static function studentYearStatus(bool $getShared = true): \App\Services\StudentYearStatusService
{
if ($getShared) {
return static::getSharedInstance('studentYearStatus');
}
return new \App\Services\StudentYearStatusService(
\Config\Database::connect(),
model(\App\Models\StudentYearStatusModel::class)
);
}
public static function withdrawalFinancial(bool $getShared = true): \App\Services\WithdrawalFinancialService
{
if ($getShared) {
return static::getSharedInstance('withdrawalFinancial');
}
$db = \Config\Database::connect();
return new \App\Services\WithdrawalFinancialService(
$db,
new \App\Services\WithdrawalRefundCalculator(),
new \App\Services\StudentBookIssueService($db),
new \App\Libraries\InvoiceLedgerService(),
new \App\Libraries\RefundEligibilityService()
);
}
}