File "CachingService.php"
Full Path: /home/trinadezambia/public_html/admin_panel/app/Services/CachingService.php
File size: 12.32 KB
MIME-type: text/x-php
Charset: utf-8
<?php
namespace App\Services;
use App\Models\Faq;
use App\Models\Feature;
use App\Models\FormField;
use App\Models\Guidance;
use App\Models\LeaveMaster;
use App\Models\SessionYear;
use App\Repositories\Languages\LanguageInterface;
use App\Repositories\SchoolSetting\SchoolSettingInterface;
use App\Repositories\Semester\SemesterInterface;
use App\Repositories\SessionYear\SessionYearInterface;
use App\Repositories\SystemSetting\SystemSettingInterface;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use stdClass;
class CachingService
{
private static $requestCache = [];
/**
* @param $key
* @param callable $callback - Callback function must return a value
* @param int $time = 3600
* @return mixed
*/
public function systemLevelCaching($key, callable $callback, int $time = 3600)
{
return Cache::remember($key, $time, $callback);
}
/**
* @param array|string $key
* @return mixed|string
*/
public function getSystemSettings(array|string $key = '*')
{
try {
$systemSettings = app(SystemSettingInterface::class);
$settings = $this->systemLevelCaching(config('constants.CACHE.SYSTEM.SETTINGS'), function () use ($systemSettings) {
return $systemSettings->all()->pluck('data', 'name');
});
if (($key != '*')) {
/* There is a minor possibility of getting a specific key from the $systemSettings
* So I have not fetched Specific key from DB. Otherwise, Specific key will be fetched here
* And it will be appended to the cached array here
*/
$specificSettings = [];
// If array is given in Key param
if (is_array($key)) {
foreach ($key as $row) {
if ($settings && is_array($settings) && array_key_exists($row, $settings)) {
$specificSettings[$row] = $settings[$row] ?? '';
}
}
return $specificSettings;
}
// If String is given in Key param
if ($settings && is_object($settings) && $settings->has($key)) {
return $settings[$key] ?? '';
}
return "";
}
return $settings;
} catch (\Throwable $th) {
return [];
}
}
public function getLanguages()
{
$languages = app(LanguageInterface::class);
return $this->systemLevelCaching(config('constants.CACHE.SYSTEM.LANGUAGE'), function () use ($languages) {
return $languages->all();
});
}
/**
* @param $key
* @param callable $callback
* @param int|null $schoolId
* @param int $time
* @return mixed
*/
public function schoolLevelCaching($key, callable $callback, $schoolId = null, int $time = 900)
{
if ($schoolId) {
$key .= "_" . $schoolId;
} else {
$key .= "_" . (Auth::user() ? Auth::user()->school_id : null);
}
return Cache::remember($key, $time, $callback);
}
/**
* @param array|string $key
* @param int|null $schoolID
* @return mixed|string
*/
public function getSchoolSettings(array|string $key = '*', $schoolID = null)
{
$schoolSettings = app(SchoolSettingInterface::class);
$schoolID = (!empty($schoolID)) ? $schoolID : Auth::user()->school_id;
$settings = $this->schoolLevelCaching(config('constants.CACHE.SCHOOL.SETTINGS'), function () use ($schoolSettings, $schoolID) {
return $schoolSettings->builder()->where('school_id', $schoolID)->get()->pluck('data', 'name');
}, $schoolID);
if (($key[0] != '*')) {
/* There is a minor possibility of getting a specific key from the $systemSettings
* So I have not fetched Specific key from DB. Otherwise, Specific key will be fetched here
* And it will be appended to the cached array here
*/
// If array is given in Key param
if (is_array($key)) {
$specificSettings = new stdClass();
foreach ($key as $row) {
if ($settings && is_object($settings) && $settings->has($row)) {
$specificSettings->$row = $settings->get($row) ?? '';
}
}
return $specificSettings;
}
// If String is given in Key param
if ($settings && is_object($settings) && $settings->has($key)) {
return $settings->get($key);
}
return "";
}
return $settings;
}
public function removeSchoolCache($key, $schoolID = null)
{
if ($schoolID) {
$key .= "_" . $schoolID;
} else {
$key .= "_" . Auth::user()->school_id;
}
Cache::forget($key);
}
public function removeSystemCache($key)
{
Cache::forget($key);
}
/**
* @param int|null $schoolId
* @return mixed
*/
public function getDefaultSessionYear($schoolId = null)
{
$schoolId = (!empty($schoolId)) ? $schoolId : (Auth::user() ? Auth::user()->school_id : null);
$cacheKey = "defaultSessionYear_" . ($schoolId ?? 'null');
if (isset(self::$requestCache[$cacheKey])) {
return self::$requestCache[$cacheKey];
}
$sessionYear = app(SessionYearInterface::class);
$data = $this->schoolLevelCaching(config('constants.CACHE.SCHOOL.SESSION_YEAR'), function () use ($sessionYear, $schoolId) {
return $sessionYear->default($schoolId);
}, $schoolId);
self::$requestCache[$cacheKey] = $data;
return $data;
}
public function getSessionYear()
{
if (DB::getDefaultConnection() == 'school') {
if (isset(self::$requestCache['sessionYear'])) {
return self::$requestCache['sessionYear'];
}
if (session()->has('session_year_id')) {
$sessionYearId = session()->get('session_year_id');
try {
$data = app(SessionYearInterface::class)->findById($sessionYearId);
self::$requestCache['sessionYear'] = $data;
return $data;
} catch (\Illuminate\Database\Eloquent\ModelNotFoundException $e) {
session()->forget('session_year_id');
session()->save();
}
}
$data = $this->getDefaultSessionYear();
self::$requestCache['sessionYear'] = $data;
return $data;
}
return null;
}
public function setSessionYear($sessionYearId)
{
session()->put('session_year_id', $sessionYearId);
session()->save();
// Clear request-level caches
self::$requestCache = [];
// Reset semester when session year changes to ensure it's valid for the new year
session()->forget('semester_id');
}
public function getSemester()
{
if (isset(self::$requestCache['semester'])) {
return self::$requestCache['semester'];
}
if (session()->has('semester_id')) {
$semesterId = session()->get('semester_id');
try {
$semester = app(SemesterInterface::class)->findById($semesterId);
if ($semester) {
self::$requestCache['semester'] = $semester;
return $semester;
}
} catch (\Illuminate\Database\Eloquent\ModelNotFoundException $e) {
session()->forget('semester_id');
session()->save();
}
}
$data = $this->getDefaultSemesterData();
self::$requestCache['semester'] = $data;
return $data;
}
public function setSemester($semesterId)
{
if (!$semesterId) {
session()->forget('semester_id');
} else {
session()->put('semester_id', $semesterId);
}
session()->save();
// Clear request-level caches
self::$requestCache = [];
}
public function getSemestersBySessionYear($sessionYearId)
{
$semester = app(SemesterInterface::class);
return $this->schoolLevelCaching(config('constants.CACHE.SCHOOL.GET_SEMESTERS_BY_SESSION_YEAR'), function () use ($semester, $sessionYearId) {
return $semester->builder()->where('session_year_id', $sessionYearId)->get();
}, $sessionYearId);
}
/**
* Run a callback with the session year forced to the school's default,
* regardless of what the user has selected in the "Viewing" dropdown.
*
* Use this in controller methods that serve FORM pages / dropdowns so that
* form dropdowns always show data for the current (default) session year,
* not the year the user is currently filtering tables by.
*
* @param callable $callback
* @return mixed
*/
public function withDefaultSessionYear(callable $callback): mixed
{
$original = session('session_year_id'); // may be null
$defaultYear = $this->getDefaultSessionYear();
session(['session_year_id' => $defaultYear->id]);
try {
return $callback();
} finally {
// Restore original state
if ($original === null) {
session()->forget('session_year_id');
} else {
session(['session_year_id' => $original]);
}
}
}
public function getDefaultSemesterData($schoolId = null)
{
$schoolId = (!empty($schoolId)) ? $schoolId : (Auth::user() ? Auth::user()->school_id : null);
$cacheKey = "defaultSemesterData_" . ($schoolId ?? 'null');
if (isset(self::$requestCache[$cacheKey])) {
return self::$requestCache[$cacheKey];
}
$semester = app(SemesterInterface::class);
$timetable = $this->schoolLevelCaching(config('constants.CACHE.SCHOOL.SEMESTER'), function () use ($semester, $schoolId) {
return $semester->default($schoolId);
}, $schoolId);
/*Added empty values so that wherever the code is used, we don't need to add isset over there*/
$data = empty($timetable) ? (object)[
'id' => null,
"name" => null,
"start_month" => null,
"end_month" => null,
"school_id" => null,
"created_at" => null,
"updated_at" => null,
"deleted_at" => null,
] : $timetable;
self::$requestCache[$cacheKey] = $data;
return $data;
}
public function getFeatures()
{
return $this->systemLevelCaching(config('constants.CACHE.SYSTEM.FEATURES'), function () {
return Feature::activeFeatures()->get();
});
}
public function getSchoolExtraFields()
{
return $this->systemLevelCaching(config('constants.CACHE.SYSTEM.SCHOOL_CUSTOM_FORM_FIELDS'), function () {
return FormField::orderBy('rank')->get();
});
}
public function getGuidances()
{
return $this->systemLevelCaching(config('constants.CACHE.SYSTEM.GUIDANCES'), function () {
return Guidance::all();
});
}
public function getSystemFaqs()
{
return $this->systemLevelCaching(config('constants.CACHE.SYSTEM.FAQS'), function () {
return Faq::where('school_id', null)->get();
});
}
public function getDefaultSessionYearLeaveMaster($schoolId = null)
{
$schoolId = $schoolId ?? Auth::user()->school_id;
$sessionYear = $this->getSessionYear();
return $this->schoolLevelCaching(config('constants.CACHE.SCHOOL.LEAVE_MASTER'), function () use ($schoolId, $sessionYear) {
return LeaveMaster::where('school_id', $schoolId)->where('session_year_id', $sessionYear->id)->first();
}, $schoolId);
}
public function getAllSessionYears($schoolId = null)
{
$schoolId = $schoolId ?? Auth::user()->school_id;
return $this->schoolLevelCaching(config('constants.CACHE.SCHOOL.ALL_SESSION_YEARS'), function () use ($schoolId) {
return SessionYear::where('school_id', $schoolId)->get();
}, $schoolId);
}
}