refactor ClientAdditionalEducationController; replace caching logic with action classes for data retrieval and improve code clarity

This commit is contained in:
F4ilji
2025-07-18 14:31:19 +05:00
parent b8235404b8
commit 839d8edfcd
9 changed files with 284 additions and 142 deletions
@@ -0,0 +1,39 @@
<?php
namespace App\Containers\AdditionalEducation\Actions;
use App\Containers\AdditionalEducation\Data\Resources\AdditionalEducationResource;
use App\Containers\AdditionalEducation\Tasks\FindAdditionalEducationBySlugTask;
use App\Ship\Actions\Action;
use App\Ship\Contracts\SeoServiceInterface;
use Illuminate\Http\Request;
class GetAdditionalEducationBySlugAction
{
public function __construct(
readonly SeoServiceInterface $seoPageProvider,
readonly FindAdditionalEducationBySlugTask $findAdditionalEducationBySlugTask,
) {}
public function run(string $slug, Request $request): array
{
$additionalEducationModel = $this->findAdditionalEducationBySlugTask->run($slug);
$seo = $this->seoPageProvider->getSeoForModel($additionalEducationModel);
$settingsPage = $request->attributes->get('settings_page') ?? [];
if (array_key_exists('custom_form', $settingsPage)) {
$form = $settingsPage['custom_form'];
} else {
$form = null;
}
$additionalEducation = new AdditionalEducationResource($additionalEducationModel);
return compact(
'additionalEducation',
'seo',
'form',
);
}
}
@@ -0,0 +1,43 @@
<?php
namespace App\Containers\AdditionalEducation\Actions;
use App\Containers\AdditionalEducation\Tasks\GetAllAdditionalEducationCategoriesPreviewTask;
use App\Containers\AdditionalEducation\Tasks\GetDirectionAdditionalEducationsTask;
use App\Containers\AdditionalEducation\Tasks\GetFilteredAdditionalEducationCategoriesTask;
use App\Containers\AdditionalEducation\Tasks\BuildFormsEducationArrayTask;
use App\Containers\AdditionalEducation\Tasks\BuildAdditionalEducationFiltersTask;
use App\Ship\Actions\Action;
use App\Ship\Contracts\SeoServiceInterface;
use Illuminate\Http\Request;
class GetAllAdditionalEducationsAction
{
public function __construct(
readonly SeoServiceInterface $seoPageProvider,
readonly GetDirectionAdditionalEducationsTask $getDirectionAdditionalEducationsTask,
readonly GetFilteredAdditionalEducationCategoriesTask $getFilteredAdditionalEducationCategoriesTask,
readonly GetAllAdditionalEducationCategoriesPreviewTask $getAllAdditionalEducationCategoriesPreviewTask,
readonly BuildFormsEducationArrayTask $buildFormsEducationArrayTask,
readonly BuildAdditionalEducationFiltersTask $buildAdditionalEducationFiltersTask,
) {}
public function run(Request $request): array
{
$directionAdditionalEducations = $this->getDirectionAdditionalEducationsTask->run($request);
$additionalEducations = $this->getFilteredAdditionalEducationCategoriesTask->run($request);
$categories = $this->getAllAdditionalEducationCategoriesPreviewTask->run();
$forms_education = $this->buildFormsEducationArrayTask->run();
$seo = $this->seoPageProvider->getSeoForCurrentPage();
$filters = $this->buildAdditionalEducationFiltersTask->run($request);
return compact(
'directionAdditionalEducations',
'additionalEducations',
'filters',
'forms_education',
'categories',
'seo'
);
}
}
@@ -0,0 +1,46 @@
<?php
namespace App\Containers\AdditionalEducation\Tasks;
use App\Containers\AdditionalEducation\Data\Resources\AdditionalEducationCategoryResource;
use App\Containers\AdditionalEducation\Models\AdditionalEducationCategory;
use App\Ship\Enums\Education\FormEducation;
use Illuminate\Http\Request;
class BuildAdditionalEducationFiltersTask
{
public function run(Request $request): array
{
$categoriesContent = [];
if ($request->category) {
foreach ((array)$request->category as $item) {
$categoriesContent[$item] = (new GetFilteredAdditionalEducationCategoriesTask())->run(new Request(['category' => $item]))->first();
}
}
$forms_education = array_reduce(
FormEducation::cases(),
fn ($acc, $case) => $acc + [$case->name => $case->getLabel()],
[]
);
return [
'direction_filter' => [
'type' => 'direction',
'value' => $request->input('direction'),
'param' => 'direction'
],
'form_education_filter' => [
'type' => 'form',
'value' => $request->input('form'),
'param' => 'form'
],
'category_filter' => [
'type' => 'category',
'value' => $request->input('category'),
'param' => 'category',
'content' => $categoriesContent,
],
];
}
}
@@ -0,0 +1,17 @@
<?php
namespace App\Containers\AdditionalEducation\Tasks;
use App\Ship\Enums\Education\FormEducation;
class BuildFormsEducationArrayTask
{
public function run(): array
{
return array_reduce(
FormEducation::cases(),
fn ($acc, $case) => $acc + [$case->name => $case->getLabel()],
[]
);
}
}
@@ -0,0 +1,20 @@
<?php
namespace App\Containers\AdditionalEducation\Tasks;
use App\Containers\AdditionalEducation\Models\AdditionalEducation;
use App\Ship\Enums\CacheKeys;
use App\Ship\Tasks\Task;
use Illuminate\Support\Facades\Cache;
class FindAdditionalEducationBySlugTask
{
public function run(string $slug)
{
return Cache::remember(
CacheKeys::ADDITIONAL_EDUCATIONAL_PROGRAM_PREFIX->value . $slug,
now()->addDay(),
fn() => AdditionalEducation::with('category.direction')->where('slug', $slug)->firstOrFail()
);
}
}
@@ -0,0 +1,28 @@
<?php
namespace App\Containers\AdditionalEducation\Tasks;
use App\Containers\AdditionalEducation\Data\Resources\AdditionalEducationCategoryPreviewResource;
use App\Containers\AdditionalEducation\Models\AdditionalEducationCategory;
use App\Ship\Enums\CacheKeys;
use App\Ship\Tasks\Task;
use Illuminate\Support\Facades\Cache;
class GetAllAdditionalEducationCategoriesPreviewTask
{
public function run()
{
return Cache::remember(
CacheKeys::ADDITIONAL_EDUCATIONAL_PROGRAMS_PREFIX->value . 'categories',
now()->addWeek(),
function () {
return AdditionalEducationCategoryPreviewResource::collection(
AdditionalEducationCategory::query()
->where('is_active', true)
->has('additionalEducations')
->get()
);
}
);
}
}
@@ -0,0 +1,31 @@
<?php
namespace App\Containers\AdditionalEducation\Tasks;
use App\Containers\AdditionalEducation\Data\Resources\DirectionAdditionalEducationResource;
use App\Containers\AdditionalEducation\Models\DirectionAdditionalEducation;
use App\Ship\Enums\CacheKeys;
use App\Ship\Tasks\Task;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
class GetDirectionAdditionalEducationsTask
{
public function run(Request $request)
{
$cacheKey = md5(serialize($request->all()));
return Cache::remember(
CacheKeys::ADDITIONAL_EDUCATIONAL_PROGRAMS_PREFIX->value . 'directions_' . $cacheKey,
now()->addDay(),
function () {
return DirectionAdditionalEducationResource::collection(
DirectionAdditionalEducation::query()
->where('is_active', true)
->whereHas('additionalEducationCategories', fn ($q) => $q->whereHas('additionalEducations'))
->get()
);
}
);
}
}
@@ -0,0 +1,47 @@
<?php
namespace App\Containers\AdditionalEducation\Tasks;
use App\Containers\AdditionalEducation\Data\Resources\AdditionalEducationCategoryResource;
use App\Containers\AdditionalEducation\Models\AdditionalEducationCategory;
use App\Ship\Enums\CacheKeys;
use App\Ship\Enums\Education\FormEducation;
use App\Ship\Tasks\Task;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
class GetFilteredAdditionalEducationCategoriesTask
{
public function run(Request $request)
{
$cacheKey = md5(serialize($request->all()));
return Cache::remember(
CacheKeys::ADDITIONAL_EDUCATIONAL_PROGRAMS_PREFIX->value . $cacheKey,
now()->addDay(),
function () use ($request) {
$query = AdditionalEducationCategory::query()
->has('additionalEducations')
->withActivePrograms()
->where('is_active', true);
if ($request->has('form')) {
$formValue = FormEducation::fromName($request->form)->value;
$query->whereHas('additionalEducations', fn ($q) => $q->where('form_education', $formValue))
->with(['additionalEducations' => fn ($q) => $q->where('form_education', $formValue)]);
}
if ($request->has('category')) {
$slugs = is_array($request->category) ? $request->category : [$request->category];
$query->whereIn('slug', $slugs);
}
if ($request->has('direction')) {
$query->whereHas('direction', fn($q) => $q->where('slug', $request->direction));
}
return AdditionalEducationCategoryResource::collection($query->get());
}
);
}
}
@@ -2,160 +2,31 @@
namespace App\Containers\AdditionalEducation\UI\WEB\Controllers;
use App\Containers\AdditionalEducation\Data\Resources\AdditionalEducationCategoryPreviewResource;
use App\Containers\AdditionalEducation\Data\Resources\AdditionalEducationCategoryResource;
use App\Containers\AdditionalEducation\Data\Resources\AdditionalEducationResource;
use App\Containers\AdditionalEducation\Data\Resources\DirectionAdditionalEducationResource;
use App\Containers\AdditionalEducation\Models\AdditionalEducation;
use App\Containers\AdditionalEducation\Models\AdditionalEducationCategory;
use App\Containers\AdditionalEducation\Models\DirectionAdditionalEducation;
use App\Ship\Contracts\SeoServiceInterface;
use App\Containers\AdditionalEducation\Actions\GetAllAdditionalEducationsAction;
use App\Containers\AdditionalEducation\Actions\GetAdditionalEducationBySlugAction;
use App\Ship\Controllers\Controller;
use App\Ship\Enums\CacheKeys;
use App\Ship\Enums\Education\FormEducation;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Inertia\Inertia;
class ClientAdditionalEducationController extends Controller
{
public function __construct(readonly SeoServiceInterface $seoPageProvider){}
public function __construct(
readonly GetAllAdditionalEducationsAction $getAllAdditionalEducationsAction,
readonly GetAdditionalEducationBySlugAction $getAdditionalEducationBySlugAction
){}
public function index(Request $request): \Inertia\Response
{
$cacheKey = md5(serialize($request->all()));
$data = $this->getAllAdditionalEducationsAction->run($request);
// Основные данные (кешируются)
$directionAdditionalEducations = Cache::remember(
CacheKeys::ADDITIONAL_EDUCATIONAL_PROGRAMS_PREFIX->value . 'directions_' . $cacheKey,
now()->addDay(),
function () {
return DirectionAdditionalEducationResource::collection(
DirectionAdditionalEducation::query()
->where('is_active', true)
->whereHas('additionalEducationCategories', fn ($q) => $q->whereHas('additionalEducations'))
->get()
);
}
);
$additionalEducations = Cache::remember(
CacheKeys::ADDITIONAL_EDUCATIONAL_PROGRAMS_PREFIX->value . $cacheKey,
now()->addDay(),
function () use ($request) {
$query = AdditionalEducationCategory::query()
->has('additionalEducations')
->withActivePrograms()
->where('is_active', true);
if ($request->has('form')) {
$formValue = FormEducation::fromName($request->form)->value;
$query->whereHas('additionalEducations', fn ($q) => $q->where('form_education', $formValue))
->with(['additionalEducations' => fn ($q) => $q->where('form_education', $formValue)]);
}
if ($request->has('category')) {
$slugs = is_array($request->category) ? $request->category : [$request->category];
$query->whereIn('slug', $slugs);
}
if ($request->has('direction')) {
$query->whereHas('direction', fn($q) => $q->where('slug', $request->direction));
}
return AdditionalEducationCategoryResource::collection($query->get());
}
);
$categories = Cache::remember(
CacheKeys::ADDITIONAL_EDUCATIONAL_PROGRAMS_PREFIX->value . 'categories',
now()->addWeek(),
function () {
return AdditionalEducationCategoryPreviewResource::collection(
AdditionalEducationCategory::query()
->where('is_active', true)
->has('additionalEducations')
->get()
);
}
);
// Динамические данные (не кешируются)
$categoriesContent = [];
if ($request->category) {
foreach ((array)$request->category as $item) {
$categoriesContent[$item] = new AdditionalEducationCategoryResource(
AdditionalEducationCategory::where('slug', $item)->first()
);
}
}
$forms_education = array_reduce(
FormEducation::cases(),
fn ($acc, $case) => $acc + [$case->name => $case->getLabel()],
[]
);
$filters = [
'direction_filter' => [
'type' => 'direction',
'value' => $request->input('direction'),
'param' => 'direction'
],
'form_education_filter' => [
'type' => 'form',
'value' => $request->input('form'),
'param' => 'form'
],
'category_filter' => [
'type' => 'category',
'value' => $request->input('category'),
'param' => 'category',
'content' => $categoriesContent,
],
];
$seo = $this->seoPageProvider->getSeoForCurrentPage();
return Inertia::render('Client/Additional-educations/Index', compact(
'directionAdditionalEducations',
'additionalEducations',
'filters',
'forms_education',
'categories',
'seo'
));
return Inertia::render('Client/Additional-educations/Index', $data);
}
public function show(string $slug): \Inertia\Response
public function show(string $slug, Request $request): \Inertia\Response
{
$additionalEducationModel = Cache::remember(
CacheKeys::ADDITIONAL_EDUCATIONAL_PROGRAM_PREFIX->value . $slug,
now()->addDay(),
fn() => AdditionalEducation::with('category.direction')->where('slug', $slug)->firstOrFail()
);
$data = $this->getAdditionalEducationBySlugAction->run($slug, $request);
$seo = Cache::remember(
CacheKeys::ADDITIONAL_EDUCATIONAL_PROGRAM_PREFIX->value . 'seo_' . $slug,
now()->addDay(),
fn() => $this->seoPageProvider->getSeoForModel($additionalEducationModel)
);
$settingsPage = request()->attributes->get('settings_page') ?? [];
if (array_key_exists('custom_form', $settingsPage)) {
$form = $settingsPage['custom_form'];
} else {
$form = null;
}
$additionalEducation = new AdditionalEducationResource($additionalEducationModel);
return Inertia::render('Client/Additional-educations/Show', compact(
'additionalEducation',
'seo',
'form',
));
}}
return Inertia::render('Client/Additional-educations/Show', $data);
}
}