refactor ClientProgramController; replace caching logic with action classes for educational program retrieval and enhance code clarity

This commit is contained in:
F4ilji
2025-07-18 15:57:58 +05:00
parent 839d8edfcd
commit 18d1501b67
13 changed files with 404 additions and 155 deletions
@@ -0,0 +1,53 @@
<?php
namespace App\Containers\Education\Tasks;
use App\Ship\Builders\FilterBuilder;
use Illuminate\Support\Arr;
class BuildFiltersTask
{
public function __construct(
private readonly FilterBuilder $filterBuilder
) {}
public function run(array $filters): array
{
// Сброс фильтров перед новым запуском
$this->filterBuilder->reset();
// Уровень образования
$this->filterBuilder->add(
key: 'level_filter',
type: 'level',
value: $filters['level'] ?? null,
param: 'level'
);
// Форма обучения
$this->filterBuilder->add(
key: 'formEdu_filter',
type: 'form',
value: $filters['form'] ?? null,
param: 'form'
);
// Бюджет
$this->filterBuilder->add(
key: 'budget_filter',
type: 'budget',
value: $filters['budget'] ?? null,
param: 'budget'
);
// Направление
$this->filterBuilder->add(
key: 'direction_filter',
type: 'direction',
value: $filters['direction'] ?? null,
param: 'direction'
);
return $this->filterBuilder->get();
}
}
@@ -0,0 +1,17 @@
<?php
namespace App\Containers\Education\Tasks;
use App\Containers\Education\Models\AdmissionCampaign;
use App\Ship\Enums\CacheKeys;
use Illuminate\Support\Facades\Cache;
class GetActiveAdmissionCampaignTask
{
public function run()
{
return Cache::remember(CacheKeys::ADMISSION_CAMPAIGNS_PREFIX->value, now()->addDay(), function () {
return AdmissionCampaign::where('status', 1)->first();
});
}
}
@@ -0,0 +1,20 @@
<?php
namespace App\Containers\Education\Tasks;
use App\Containers\Education\Models\AdmissionCampaign;
use App\Ship\Enums\CacheKeys;
use Illuminate\Support\Facades\Cache;
class GetAdmissionCampaignNameTask
{
public function run(): string
{
$cacheKey = CacheKeys::EDUCATION_PROGRAM_PREFIX->value . 'active_campaign_name';
return Cache::remember($cacheKey, now()->addHours(1), function () {
$campaign = AdmissionCampaign::query()->where('status', 1)->first();
return $campaign->name;
});
}
}
@@ -0,0 +1,26 @@
<?php
namespace App\Containers\Education\Tasks;
use App\Containers\Education\Models\AdmissionPlan;
use App\Ship\Enums\Education\BudgetEducation;
use Illuminate\Support\Facades\Cache;
class GetEducationalBudgetsTask
{
public function run()
{
$cacheKeyBudgets = 'education_budgets_list';
return Cache::remember($cacheKeyBudgets, now()->addDay(), function () {
return AdmissionPlan::distinct()
->pluck('contests')
->flatten(1)
->filter(fn ($item) => isset($item['places']['form_budget']))
->pluck('places.form_budget')
->unique()
->map(fn ($item) => BudgetEducation::tryFrom($item))
->filter()
->mapWithKeys(fn ($form) => [$form->name => $form->getLabel()]);
});
}
}
@@ -0,0 +1,26 @@
<?php
namespace App\Containers\Education\Tasks;
use App\Containers\Education\Models\AdmissionPlan;
use App\Ship\Enums\Education\FormEducation;
use Illuminate\Support\Facades\Cache;
class GetEducationalFormsTask
{
public function run()
{
$cacheKeyForms = 'education_forms_list';
return Cache::remember($cacheKeyForms, now()->addDay(), function () {
return AdmissionPlan::distinct()
->pluck('contests')
->flatten(1)
->filter(fn ($item) => isset($item['form_education']))
->pluck('form_education')
->unique()
->map(fn ($item) => FormEducation::tryFrom((int)$item))
->filter()
->mapWithKeys(fn ($form) => [$form->name => $form->getLabel()]);
});
}
}
@@ -0,0 +1,18 @@
<?php
namespace App\Containers\Education\Tasks;
use App\Containers\Education\Models\EducationalProgram;
use Illuminate\Support\Facades\Cache;
class GetEducationalLevelsTask
{
public function run()
{
$cacheKeyLevels = 'education_levels_list';
return Cache::remember($cacheKeyLevels, now()->addDay(), function () {
return EducationalProgram::distinct()->pluck('lvl_edu')
->mapWithKeys(fn($level) => [$level->name => $level->getLabel()]);
});
}
}
@@ -0,0 +1,22 @@
<?php
namespace App\Containers\Education\Tasks;
use App\Containers\Education\Models\EducationalProgram;
use App\Ship\Enums\CacheKeys;
use Illuminate\Support\Facades\Cache;
class GetEducationalProgramBySlugTask
{
public function run(string $slug)
{
$cacheKeyProgram = CacheKeys::EDUCATION_PROGRAM_PREFIX->value . md5($slug);
return Cache::remember($cacheKeyProgram, now()->addHours(1), function () use ($slug) {
return EducationalProgram::query()
->where('slug', $slug)
->with(['admission_plans', 'directionStudy', 'seo'])
->firstOrFail();
});
}
}
@@ -0,0 +1,17 @@
<?php
namespace App\Containers\Education\Tasks;
use App\Ship\Contracts\SeoServiceInterface;
use Illuminate\Support\Facades\Cache;
class GetSeoForCurrentPageTask
{
public function run(SeoServiceInterface $seoPageProvider)
{
$cacheKeySeo = 'education_programs_seo';
return Cache::remember($cacheKeySeo, now()->addDay(), function () use ($seoPageProvider) {
return $seoPageProvider->getSeoForCurrentPage();
});
}
}
@@ -0,0 +1,18 @@
<?php
namespace App\Containers\Education\Tasks;
use App\Ship\Contracts\SeoServiceInterface;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Cache;
class GetSeoForModelTask
{
public function run(SeoServiceInterface $seoPageProvider, Model $model)
{
$cacheKeySeo = 'education_program_seo_' . md5($model->slug);
return Cache::remember($cacheKeySeo, now()->addHours(1), function () use ($seoPageProvider, $model) {
return $seoPageProvider->getSeoForModel($model);
});
}
}
@@ -0,0 +1,69 @@
<?php
namespace App\Containers\Education\Tasks;
use App\Containers\Education\Models\AdmissionCampaign;
use App\Containers\Education\Models\DirectionStudy;
use App\Ship\Enums\Education\BudgetEducation;
use App\Ship\Enums\Education\FormEducation;
use App\Ship\Enums\Education\LevelEducational;
use Illuminate\Support\Str;
class ListDirectionStudiesTask
{
public function run(AdmissionCampaign $activeCampaign, array $filters)
{
$query = DirectionStudy::query()
->withAdmissionCampaignByYear($activeCampaign->academic_year)
->withActivePrograms();
if (isset($filters['level'])) {
$query->where('lvl_edu', LevelEducational::fromName($filters['level'])->value);
}
if (isset($filters['form'])) {
$this->applyFormFilter($query, $filters['form']);
}
if (isset($filters['budget'])) {
$this->applyBudgetFilter($query, $filters['budget']);
}
if (isset($filters['direction'])) {
$slugs = $filters['direction'];
if (is_array($slugs)) {
$query->whereIn('slug', $slugs);
}
}
return $query->get();
}
private function applyFormFilter($query, $form)
{
$formValue = Str::of(FormEducation::fromName($form)->value)->toString();
$query->whereHas('programs.admission_plans', function ($query) use ($formValue) {
$query->whereJsonContains('contests', ['form_education' => $formValue]);
})
->with(['programs' => function ($query) use ($formValue) {
$query->whereHas('admission_plans', function ($q) use ($formValue) {
$q->whereJsonContains('contests', ['form_education' => $formValue]);
});
}]);
}
private function applyBudgetFilter($query, $budget): void
{
$budgetValue = Str::of(BudgetEducation::fromName($budget)->value)->toString();
$query->whereHas('programs.admission_plans', function ($query) use ($budgetValue) {
$query->where('contests', 'like', '%"form_budget":"'.$budgetValue.'"%');
})
->with(['programs' => function ($query) use ($budgetValue) {
$query->whereHas('admission_plans', function ($query) use ($budgetValue) {
$query->where('contests', 'like', '%"form_budget":"'.$budgetValue.'"%');
});
}]);
}
}