diff --git a/app/Filament/Resources/FacultyResource/RelationManagers/DepartmentsRelationManager.php b/app/Filament/Resources/FacultyResource/RelationManagers/DepartmentsRelationManager.php index 4edd5f9..15e3afa 100644 --- a/app/Filament/Resources/FacultyResource/RelationManagers/DepartmentsRelationManager.php +++ b/app/Filament/Resources/FacultyResource/RelationManagers/DepartmentsRelationManager.php @@ -13,6 +13,8 @@ use Illuminate\Database\Eloquent\SoftDeletingScope; class DepartmentsRelationManager extends RelationManager { protected static string $relationship = 'departments'; + protected static ?string $title = 'Кафедры'; + public function form(Form $form): Form { diff --git a/app/Filament/Resources/MainSectionResource/RelationManagers/SubSectionsRelationManager.php b/app/Filament/Resources/MainSectionResource/RelationManagers/SubSectionsRelationManager.php index f998a31..2b9e645 100644 --- a/app/Filament/Resources/MainSectionResource/RelationManagers/SubSectionsRelationManager.php +++ b/app/Filament/Resources/MainSectionResource/RelationManagers/SubSectionsRelationManager.php @@ -2,6 +2,7 @@ namespace App\Filament\Resources\MainSectionResource\RelationManagers; +use App\Models\SubSection; use Filament\Forms; use Filament\Forms\Components\TextInput; use Filament\Forms\Form; @@ -24,12 +25,18 @@ class SubSectionsRelationManager extends RelationManager { return $form ->schema([ - Forms\Components\TextInput::make('title')->label('Название подраздела')->required() + Forms\Components\TextInput::make('title') + ->label('Название подраздела') + ->required() ->live(onBlur: true) ->afterStateUpdated(function (string $operation, string $state, Forms\Set $set) { $set('slug', Str::slug($state)); }), - TextInput::make('slug')->label('Slug')->unique(ignoreRecord: true)->readOnly()->required(), + TextInput::make('slug') + ->label('Slug') + ->unique(ignoreRecord: true) + ->readOnly() + ->required(), ]); } @@ -47,16 +54,45 @@ class SubSectionsRelationManager extends RelationManager ]) ->headerActions([ Tables\Actions\CreateAction::make(), - Tables\Actions\AssociateAction::make() + Tables\Actions\Action::make('associate') + ->label('Прикрепить подраздел') + ->color('success') + ->form([ + Forms\Components\Select::make('recordId') + ->label('Подраздел') + ->searchable() + ->preload() + ->options(SubSection::whereNull('main_section_id')->pluck('title', 'id')) + ->required(), + ]) + ->action(function (array $data): void { + $subSection = SubSection::find($data['recordId']); + $subSection->mainSection()->associate($this->getOwnerRecord()); + $subSection->save(); + }), ]) ->actions([ Tables\Actions\EditAction::make(), - Tables\Actions\DetachAction::make(), + Tables\Actions\Action::make('detach') + ->label('Открепить') + ->color('danger') // Красный цвет + ->icon('heroicon-o-x-mark') + ->action(function ($record) { + $record->mainSection()->dissociate(); + $record->save(); + }), ]) ->bulkActions([ Tables\Actions\BulkActionGroup::make([ - Tables\Actions\DetachBulkAction::make(), + Tables\Actions\Action::make('bulkDetach') + ->label('Открепить выбранные') + ->action(function ($records) { + $records->each(function ($record) { + $record->mainSection()->dissociate(); + $record->save(); + }); + }), ]), ]); } -} +} \ No newline at end of file diff --git a/app/Filament/Resources/SubSectionResource/RelationManagers/PagesRelationManager.php b/app/Filament/Resources/SubSectionResource/RelationManagers/PagesRelationManager.php index 77e34b4..91abbd3 100644 --- a/app/Filament/Resources/SubSectionResource/RelationManagers/PagesRelationManager.php +++ b/app/Filament/Resources/SubSectionResource/RelationManagers/PagesRelationManager.php @@ -3,6 +3,7 @@ namespace App\Filament\Resources\SubSectionResource\RelationManagers; use App\Filament\Components\Forms\PageForm; +use App\Models\Page; use App\Models\SubSection; use Filament\Forms; use Filament\Forms\Form; @@ -18,13 +19,11 @@ class PagesRelationManager extends RelationManager protected static ?string $title = 'Страницы'; - public function form(Form $form): Form { return PageForm::getForm($form); } - public function table(Table $table): Table { return $table @@ -36,86 +35,49 @@ class PagesRelationManager extends RelationManager // ]) ->headerActions([ - Tables\Actions\CreateAction::make()->mutateFormDataUsing(function ($data) { - $subSection = SubSection::find($data['sub_section_id']); - - - if ($subSection == null) { - $data['path'] = $data['slug']; - } elseif($subSection->mainSection == null) { - $data['path'] = $subSection->slug . '/' . $data['slug']; - } else { - $data['path'] = $subSection->mainSection->slug . '/' . $subSection->slug . '/' . $data['slug']; - } - unset($data['sub_section_id']); - - - - - $result = ""; - foreach ($data['content'] as $block) { - $result .= $this->getDataFromBlocks($block); - } - - // Удаляем лишние пробелы и переносы строк - $result = preg_replace('/\s+/', ' ', $result); - $result = trim($result); - - - // Приводим текст к нижнему регистру - $data['search_data'] = strtolower($result); - - return $data; - }), - Tables\Actions\AssociateAction::make(), + Tables\Actions\CreateAction::make(), + Tables\Actions\Action::make('associate') + ->label('Прикрепить страницу') + ->color('success') + ->searchable() + ->preload() + ->button() + ->form([ + Forms\Components\Select::make('recordId') + ->label('Страница') + ->options(Page::whereNull('sub_section_id')->whereNotNull('title')->pluck('title', 'id')) + ->required(), + ]) + ->action(function (array $data): void { + $page = Page::find($data['recordId']); + $page->section()->associate($this->getOwnerRecord()); + $page->save(); // Вызовет наблюдатели + }), ]) ->actions([ Tables\Actions\EditAction::make(), - Tables\Actions\DetachAction::make(), + Tables\Actions\Action::make('detach') + ->label('Открепить') + ->color('danger') + ->icon('heroicon-o-x-mark') + ->action(function (Page $record) { + $record->section()->dissociate(); + $record->save(); // Вызовет наблюдатели + }), ]) ->bulkActions([ Tables\Actions\BulkActionGroup::make([ - Tables\Actions\DetachBulkAction::make(), + Tables\Actions\Action::make('bulkDetach') + ->label('Открепить выбранные') + ->color('danger') + ->icon('heroicon-o-x-mark') + ->action(function ($records) { + $records->each(function (Page $record) { + $record->section()->dissociate(); + $record->save(); // Вызовет наблюдатели для каждой записи + }); + }), ]), ]); } - - - private function getDataFromBlocks($block) : string - { - $data = ""; - switch ($block['type']) { - case 'paragraph': - $data .= strip_tags($block['data']['content']) . " "; - break; - case 'heading': - $data .= strip_tags($block['data']['content']) . " "; - break; - case 'files': - foreach ($block['data']['file'] as $file) { - $data .= $file['title'] . " "; - } - break; - case 'person': - $data .= $block['data']['name'] . " "; - break; - case 'stepper': - $data .= $block['data']['step_name'] . " "; - foreach ($block['data']['steps'] as $step) { - $data .= $step['title'] . " "; - $data .= strip_tags($step['content']) . " "; - } - break; - case 'tabs': - foreach ($block['data']['tab'] as $item) { - foreach ($item['content'] as $block) { - $data .= $this->getDataFromBlocks($block); - }; - }; - break; - - } - return $data; - } - -} +} \ No newline at end of file diff --git a/app/Http/Controllers/ClientAcademicJournalController.php b/app/Http/Controllers/ClientAcademicJournalController.php index eec9efb..82e8f61 100644 --- a/app/Http/Controllers/ClientAcademicJournalController.php +++ b/app/Http/Controllers/ClientAcademicJournalController.php @@ -15,11 +15,11 @@ class ClientAcademicJournalController extends Controller { public function __construct(readonly SeoPageProvider $seoPageProvider){} - public function index() + public function index(): \Inertia\Response { $journals = Cache::remember( CacheKeys::ACADEMIC_JOURNALS_PREFIX->value . 'list', - now()->addWeek(), // Кешируем на неделю, так как журналы меняются редко + now()->addWeek(), function () { return ClientAcademicJournalListResource::collection( AcademicJournal::query()->get() @@ -32,24 +32,30 @@ class ClientAcademicJournalController extends Controller return Inertia::render('Client/AcademicJournals/Index', compact('journals', 'seo')); } - public function show(string $slug) + public function show(string $slug): \Inertia\Response { - // Кешируем основной журнал - [$journal, $seo] = Cache::remember( + $journalData = Cache::remember( CacheKeys::ACADEMIC_JOURNAL_PREFIX->value . $slug, now()->addWeek(), function () use ($slug) { - $journal = AcademicJournal::query() + return AcademicJournal::query() ->where('slug', $slug) ->firstOrFail(); - $seo = $this->seoPageProvider->getSeoForModel($journal); - return [ - new ClientAcademicJournalListResource($journal), - $seo - ]; } ); + $seo = Cache::remember( + CacheKeys::ACADEMIC_JOURNAL_PREFIX->value . 'seo_' . $slug, + now()->addWeek(), + function () use ($journalData) { + return $this->seoPageProvider->getSeoForModel($journalData); + } + ); + + $journal = new ClientAcademicJournalListResource($journalData); + + + // Кешируем выпуски журнала, сгруппированные по годам $journals = Cache::remember( CacheKeys::ACADEMIC_JOURNAL_PREFIX->value . 'issues_' . $slug, diff --git a/app/Http/Controllers/ClientAdditionalEducationController.php b/app/Http/Controllers/ClientAdditionalEducationController.php index 557561a..7be3893 100644 --- a/app/Http/Controllers/ClientAdditionalEducationController.php +++ b/app/Http/Controllers/ClientAdditionalEducationController.php @@ -26,7 +26,7 @@ class ClientAdditionalEducationController extends Controller public function __construct(readonly SeoPageProvider $seoPageProvider){} - public function index(Request $request) + public function index(Request $request): \Inertia\Response { $cacheKey = md5(serialize([ 'direction' => $request->input('direction'), @@ -134,26 +134,22 @@ class ClientAdditionalEducationController extends Controller 'seo' )); } - public function show(string $slug) + public function show(string $slug): \Inertia\Response { - // Кешируем основную программу дополнительного образования - [$additionalEducation, $seo] = Cache::remember( + $additionalEducationModel = Cache::remember( CacheKeys::ADDITIONAL_EDUCATIONAL_PROGRAM_PREFIX->value . $slug, now()->addDay(), - function () use ($slug) { - $additionalEducation = AdditionalEducation::query() - ->with('category.direction') - ->where('slug', $slug) - ->first(); - $seo = $this->seoPageProvider->getSeoForModel($additionalEducation); - return [ - new AdditionalEducationResource($additionalEducation), - $seo - ]; - } + fn() => AdditionalEducation::with('category.direction')->where('slug', $slug)->firstOrFail() ); - // SEO-данные берём из кешированного ресурса + $seo = Cache::remember( + CacheKeys::ADDITIONAL_EDUCATIONAL_PROGRAM_PREFIX->value . 'seo_' . $slug, + now()->addDay(), + fn() => $this->seoPageProvider->getSeoForModel($additionalEducationModel) + ); + + $additionalEducation = new AdditionalEducationResource($additionalEducationModel); + return Inertia::render('Client/Additional-educations/Show', compact( 'additionalEducation', diff --git a/app/Http/Controllers/ClientDepartmentController.php b/app/Http/Controllers/ClientDepartmentController.php index 212f3fe..1dbf0e6 100644 --- a/app/Http/Controllers/ClientDepartmentController.php +++ b/app/Http/Controllers/ClientDepartmentController.php @@ -35,6 +35,7 @@ class ClientDepartmentController extends Controller ); + // Кешируем список активных кафедр факультета $departments = Cache::remember( CacheKeys::DEPARTMENTS_PREFIX->value . 'active_' . $faculty->id, @@ -49,12 +50,11 @@ class ClientDepartmentController extends Controller } ); - // Кешируем полные данные кафедры с отношениями - [$department, $seo] = Cache::remember( + $departmentModel = Cache::remember( CacheKeys::DEPARTMENT_PREFIX->value . $cacheKey, now()->addDay(), function () use ($departmentSlug) { - $department = Department::query() + return Department::query() ->where('slug', $departmentSlug) ->where('is_active', true) ->with([ @@ -64,17 +64,20 @@ class ClientDepartmentController extends Controller 'programs.directionStudy', 'seo' ]) - ->first(); - - $seo = $this->seoPageProvider->getSeoForModel($department); - return [ - new DepartmentResource($department), - $seo - ]; + ->firstOrFail(); } ); - // Кешируем сгруппированные направления + $seo = Cache::remember( + CacheKeys::DEPARTMENT_PREFIX->value . 'seo_' . $cacheKey, + now()->addDay(), + function () use ($departmentModel) { + return $this->seoPageProvider->getSeoForModel($departmentModel); + } + ); + + $department = new DepartmentResource($departmentModel); + $directions = Cache::remember( CacheKeys::DEPARTMENT_PREFIX->value . 'directions_' . $cacheKey, now()->addDay(), diff --git a/app/Http/Controllers/ClientDivisionController.php b/app/Http/Controllers/ClientDivisionController.php index b2d6e58..c0e16af 100644 --- a/app/Http/Controllers/ClientDivisionController.php +++ b/app/Http/Controllers/ClientDivisionController.php @@ -2,11 +2,13 @@ namespace App\Http\Controllers; +use App\Enums\CacheKeys; use App\Http\Resources\DivisionResource; use App\Models\Division; use App\Services\App\Breadcrumb\BreadcrumbService; use App\Services\App\Seo\SeoPageProvider; use Illuminate\Http\Request; +use Illuminate\Support\Facades\Cache; use Inertia\Inertia; class ClientDivisionController extends Controller @@ -15,20 +17,36 @@ class ClientDivisionController extends Controller public function index() { - $divisions = DivisionResource::collection(Division::query()->where('is_active', true)->get()); + $divisions = Cache::remember(CacheKeys::DIVISIONS_PREFIX->value . 'list', now()->addDay(), function () { + return DivisionResource::collection( + Division::query()->where('is_active', true)->get() + ); + }); - $seo = $this->seoPageProvider->getSeoForCurrentPage(); + $seo = Cache::remember(CacheKeys::DIVISIONS_PREFIX->value . 'seo', now()->addDay(), function () { + return $this->seoPageProvider->getSeoForCurrentPage(); + }); return Inertia::render('Client/Divisions/Index', compact('divisions', 'seo')); } - public function show(string $slug) + public function show(string $slug): \Inertia\Response { - $divisions = DivisionResource::collection(Division::query()->where('is_active', true)->get()); - $division = new DivisionResource($divisionModel = Division::with(['workers.userDetail', 'seo'])->where('is_active', true)->where('slug', $slug)->firstOrFail()); + $divisions = Cache::remember(CacheKeys::DIVISIONS_PREFIX->value . 'list', now()->addDay(), function () { + return DivisionResource::collection( + Division::query()->where('is_active', true)->get() + ); + }); - $seo = $this->seoPageProvider->getSeoForModel($divisionModel); + $divisionData = Cache::remember(CacheKeys::DIVISION_PREFIX->value . $slug, now()->addDay(), function () use ($slug) { + return Division::with(['workers.userDetail', 'seo'])->where('is_active', true)->where('slug', $slug)->firstOrFail(); + }); + + $seo = $this->seoPageProvider->getSeoForModel($divisionData); + + $division = new DivisionResource($divisionData); return Inertia::render('Client/Divisions/Show', compact('divisions', 'division', 'seo')); } + } diff --git a/app/Http/Controllers/ClientEventController.php b/app/Http/Controllers/ClientEventController.php index 9570431..bb22084 100644 --- a/app/Http/Controllers/ClientEventController.php +++ b/app/Http/Controllers/ClientEventController.php @@ -64,19 +64,26 @@ class ClientEventController extends Controller public function show(string $slug): \Inertia\Response { - [$event, $seo] = Cache::remember( + $eventModel = Cache::remember( CacheKeys::EVENT_PREFIX->value . $slug, now()->addDay(), - function ($slug) { - $event = Event::where('slug', $slug)->with(['category', 'seo'])->first(); - $seo = $this->seoPageProvider->getSeoForModel($event); - return [ - new ClientEventFullResource($event), - $seo - ]; + function () use ($slug) { + return Event::where('slug', $slug) + ->with(['category', 'seo']) + ->firstOrFail(); } ); + $seo = Cache::remember( + CacheKeys::EVENT_PREFIX->value . 'seo_' . $slug, + now()->addDay(), + function () use ($eventModel) { + return $this->seoPageProvider->getSeoForModel($eventModel); + } + ); + + $event = new ClientEventFullResource($eventModel); + return Inertia::render('Client/Events/Show', compact( 'event', diff --git a/app/Http/Controllers/ClientFacultyController.php b/app/Http/Controllers/ClientFacultyController.php index c81f0df..e27d880 100644 --- a/app/Http/Controllers/ClientFacultyController.php +++ b/app/Http/Controllers/ClientFacultyController.php @@ -53,22 +53,27 @@ class ClientFacultyController extends Controller ); // Кешируем данные конкретного факультета - [$faculty, $seo] = Cache::remember( + $faculty = Cache::remember( CacheKeys::FACULTY_PREFIX->value . $slug, now()->addDay(), function () use ($slug) { - $faculty = Faculty::where('slug', $slug) + return Faculty::where('slug', $slug) ->where('is_active', true) ->with(['departments.faculty', 'workers.userDetail', 'seo']) ->firstOrFail(); - $seo = $this->seoPageProvider->getSeoForModel($faculty); - return [ - new FullFacultyResource($faculty), - $seo - ]; } ); + $seo = Cache::remember( + CacheKeys::FACULTY_PREFIX->value . "SEO_" . $slug, + now()->addDay(), + function () use ($faculty) { + return $this->seoPageProvider->getSeoForModel($faculty); + } + ); + + $faculty = new FullFacultyResource($faculty); + return Inertia::render('Client/Faculties/Show', compact('faculty', 'faculties', 'seo')); diff --git a/app/Http/Controllers/ClientPostController.php b/app/Http/Controllers/ClientPostController.php index 03e0e24..73c9009 100644 --- a/app/Http/Controllers/ClientPostController.php +++ b/app/Http/Controllers/ClientPostController.php @@ -2,6 +2,7 @@ namespace App\Http\Controllers; +use App\Enums\CacheKeys; use App\Http\Resources\CategoryResource; use App\Http\Resources\ClientPostListResource; use App\Http\Resources\ClientTagResource; @@ -138,28 +139,25 @@ class ClientPostController extends Controller $cacheKey = 'post_' . md5($slug); // Пытаемся получить данные из кеша - $data = Cache::remember($cacheKey, now()->addHours(1), function () use ($slug) { - // Получаем пост - $post = Post::where('slug', $slug) + $postData = Cache::remember( + CacheKeys::POST_PREFIX->value . $slug, + now()->addHours(1), + fn() => Post::where('slug', $slug) ->where('publish_at', '<', Carbon::now()) - ->firstOrFail(); + ->firstOrFail() + ); - // Преобразуем пост в ресурс - $postResource = new PostResource($post); + $seo = Cache::remember( + CacheKeys::POST_PREFIX->value . 'seo_' . $slug, + now()->addHours(1), + fn() => $this->seoPageProvider->getSeoForModel($postData) + ); - // SEO-данные - $seo = $this->seoPageProvider->getSeoForModel($post); - - // Возвращаем данные для кеширования - return [ - 'post' => $postResource, - 'seo' => $seo, - ]; - }); + $post = new PostResource($postData); // Возвращаем ответ с использованием кешированных данных - return Inertia::render('Client/Posts/Show', $data); + return Inertia::render('Client/Posts/Show', compact('')); } diff --git a/app/Http/Controllers/ClientProgramController.php b/app/Http/Controllers/ClientProgramController.php index 9f18d32..034e37c 100644 --- a/app/Http/Controllers/ClientProgramController.php +++ b/app/Http/Controllers/ClientProgramController.php @@ -28,128 +28,101 @@ class ClientProgramController extends Controller { public function __construct(readonly SeoPageProvider $seoPageProvider){} - public function index(Request $request) + public function index(Request $request): \Inertia\Response { $cacheKey = CacheKeys::EDUCATION_PROGRAMS_PREFIX->value . md5(serialize($request->all())); + $cacheKeyLevels = 'education_levels_list'; + $cacheKeyForms = 'education_forms_list'; + $cacheKeyBudgets = 'education_budgets_list'; + $cacheKeySeo = 'education_programs_seo'; - $data = Cache::remember($cacheKey, now()->addHours(1), function () use ($request) { - $activeCampaign = AdmissionCampaign::query()->where('status', 1)->first(); + $activeCampaign = Cache::remember('active_admission_campaign', now()->addDay(), function () { + return AdmissionCampaign::where('status', 1)->first(); + }); - $uniqueValues = EducationalProgram::distinct()->pluck('lvl_edu'); - $levelsEducational = $uniqueValues->mapWithKeys(function ($level) { - return [$level->name => $level->getLabel()]; - }); + $levelsEducational = Cache::remember($cacheKeyLevels, now()->addDay(), function () { + return EducationalProgram::distinct()->pluck('lvl_edu') + ->mapWithKeys(fn($level) => [$level->name => $level->getLabel()]); + }); - $direction_studies = DirectionStudy::query() - ->withAdmissionCampaignByYear($activeCampaign->academic_year) - ->withActivePrograms() - ->get(); + $formsEdu = Cache::remember($cacheKeyForms, now()->addDay(), function () { + return collect(FormEducation::cases()) + ->mapWithKeys(fn($form) => [$form->name => $form->getLabel()]); + }); - $level = request()->input('level'); - $form = request()->input('form'); - $budget = request()->input('budget'); + $budgetEdu = Cache::remember($cacheKeyBudgets, now()->addDay(), function () { + return collect(BudgetEducation::cases()) + ->mapWithKeys(fn($type) => [$type->name => $type->getLabel()]); + }); - $naprs = DirectionStudyResource::collection( + $seo = Cache::remember($cacheKeySeo, now()->addDay(), function () { + return $this->seoPageProvider->getSeoForCurrentPage(); + }); + + $naprs = Cache::remember($cacheKey, now()->addHours(1), function () use ($request, $activeCampaign) { + return DirectionStudyResource::collection( DirectionStudy::query() ->withAdmissionCampaignByYear($activeCampaign->academic_year) ->withActivePrograms() ->with('programs.admission_plans') - ->when($level, function ($query) use ($level) { - $query->where('lvl_edu', LevelEducational::fromName($level)->value); - }) - ->when($form, function ($query) use ($form) { - $this->applyFormFilter($query, $form); - }) - ->when($budget, function ($query) use ($budget) { - $this->applyBudgetFilter($query, $budget); - }) - ->when(request()->input('direction'), function ($query) { - $slugs = request()->input('direction'); - if (is_array($slugs)) { - $query->whereIn('slug', $slugs); - } - }) + ->when($request->input('level'), fn($q, $level) => + $q->where('lvl_edu', LevelEducational::fromName($level)->value)) + ->when($request->input('form'), fn($q, $form) => + $this->applyFormFilter($q, $form)) + ->when($request->input('budget'), fn($q, $budget) => + $this->applyBudgetFilter($q, $budget)) + ->when($request->input('direction'), fn($q, $slugs) => + is_array($slugs) ? $q->whereIn('slug', $slugs) : $q) ->get() ); - - $campaignName = $this->getAdmissionCampaignName(); - $formsEducational = FormEducation::cases(); - $formsEducational = collect($formsEducational); - $formsEdu = $formsEducational->mapWithKeys(function ($formEducational) { - return [$formEducational->name => $formEducational->getLabel()]; - }); - $typesBudget = BudgetEducation::cases(); - $typesBudget = collect($typesBudget); - $budgetEdu = $typesBudget->mapWithKeys(function ($typeBudget) { - return [$typeBudget->name => $typeBudget->getLabel()]; - }); - - $filters = [ - 'level_filter' => [ - 'type' => 'level', - 'value' => request()->input('level'), - 'param' => 'level' - ], - 'budget_filter' => [ - 'type' => 'budget', - 'value' => request()->input('budget'), - 'param' => 'budget' - ], - 'formEdu_filter' => [ - 'type' => 'form', - 'value' => request()->input('form'), - 'param' => 'form' - ], - 'direction_filter' => [ - 'type' => 'direction', - 'value' => request()->input('direction'), - 'param' => 'direction' - ], - ]; - - $seo = $this->seoPageProvider->getSeoForCurrentPage(); - - - return compact( - 'naprs', - 'campaignName', - 'levelsEducational', - 'filters', - 'formsEdu', - 'budgetEdu', - 'direction_studies', - 'seo' - ); }); + $data = [ + 'naprs' => $naprs, + 'campaignName' => $this->getAdmissionCampaignName(), + 'levelsEducational' => $levelsEducational, + 'filters' => [ + 'level_filter' => ['type' => 'level', 'value' => $request->input('level'), 'param' => 'level'], + 'budget_filter' => ['type' => 'budget', 'value' => $request->input('budget'), 'param' => 'budget'], + 'formEdu_filter' => ['type' => 'form', 'value' => $request->input('form'), 'param' => 'form'], + 'direction_filter' => ['type' => 'direction', 'value' => $request->input('direction'), 'param' => 'direction'], + ], + 'formsEdu' => $formsEdu, + 'budgetEdu' => $budgetEdu, + 'direction_studies' => DirectionStudy::query() + ->withAdmissionCampaignByYear($activeCampaign->academic_year) + ->withActivePrograms() + ->get(), + 'seo' => $seo + ]; return Inertia::render('Client/Programs/Index', $data); } - - public function show(string $slug) + public function show(string $slug): \Inertia\Response { - $cacheKey = CacheKeys::EDUCATION_PROGRAM_PREFIX->value . md5($slug); + $cacheKeyProgram = CacheKeys::EDUCATION_PROGRAM_PREFIX->value . md5($slug); + $cacheKeySeo = CacheKeys::EDUCATION_PROGRAM_PREFIX->value . 'seo_' . md5($slug); + $cacheKeyForms = 'education_forms_list'; - $data = Cache::remember($cacheKey, now()->addHours(1), function () use ($slug) { - $program = new EducationalProgramFullResource( - $programModel = EducationalProgram::query() - ->where('slug', $slug) - ->with(['admission_plans', 'directionStudy', 'seo']) - ->firstOrFail() - ); - - $formsEducational = BudgetEducation::cases(); - $formsEducational = collect($formsEducational); - $formsEdu = $formsEducational->mapWithKeys(function ($formEducational) { - return [$formEducational->value => $formEducational->getLabel()]; - }); - - $seo = $this->seoPageProvider->getSeoForModel($programModel); - - return compact('program', 'formsEdu', 'seo'); + $programModel = Cache::remember($cacheKeyProgram, now()->addHours(1), function () use ($slug) { + return EducationalProgram::query() + ->where('slug', $slug) + ->with(['admission_plans', 'directionStudy', 'seo']) + ->firstOrFail(); }); - return Inertia::render('Client/Programs/Show', $data); + $formsEdu = Cache::remember($cacheKeyForms, now()->addDay(), function () { + return collect(BudgetEducation::cases()) + ->mapWithKeys(fn($form) => [$form->value => $form->getLabel()]); + }); + + $seo = Cache::remember($cacheKeySeo, now()->addHours(1), function () use ($programModel) { + return $this->seoPageProvider->getSeoForModel($programModel); + }); + + $program = new EducationalProgramFullResource($programModel); + + return Inertia::render('Client/Programs/Show', compact('program', 'formsEdu', 'seo')); } private function getAdmissionCampaignName(): string diff --git a/app/Http/Controllers/PersonController.php b/app/Http/Controllers/PersonController.php index 3a4ccd9..af3e20e 100644 --- a/app/Http/Controllers/PersonController.php +++ b/app/Http/Controllers/PersonController.php @@ -17,16 +17,21 @@ class PersonController extends Controller { $cacheKey = CacheKeys::USER_PREFIX->value . md5($slug); - [$person, $seo] = Cache::remember($cacheKey, now()->addHours(24), function () use ($slug) { - $person = User::query()->with(['userDetail', 'departments_work.faculty', 'departments_teach.faculty', 'divisions', 'faculties']) + $personData = Cache::remember( + CacheKeys::USER_PREFIX->value . $slug, + now()->addHours(24), + fn() => User::with(['userDetail', 'departments_work.faculty', 'departments_teach.faculty', 'divisions', 'faculties']) ->where('slug', $slug) - ->firstOrFail(); - $seo = $this->seoPageProvider->getSeoForModel($person); - return [ - new ClientFullInfoPersonResource($person), - $seo - ]; - }); + ->firstOrFail() + ); + + $seo = Cache::remember( + CacheKeys::USER_PREFIX->value . 'seo_' . $slug, + now()->addHours(24), + fn() => $this->seoPageProvider->getSeoForModel($personData) + ); + + $person = new ClientFullInfoPersonResource($personData); diff --git a/app/Services/App/Breadcrumb/BreadcrumbService.php b/app/Services/App/Breadcrumb/BreadcrumbService.php index 170eb75..ba73d33 100644 --- a/app/Services/App/Breadcrumb/BreadcrumbService.php +++ b/app/Services/App/Breadcrumb/BreadcrumbService.php @@ -11,31 +11,23 @@ use Illuminate\Support\Facades\Route; class BreadcrumbService { - public function generateBreadcrumbs(): ?array + public function generateBreadcrumbs($routeN = null): ?array { - $routeName = Route::currentRouteName(); - + $routeName = $routeN ?? Route::currentRouteName(); // Пытаемся найти index-версию маршрута $indexRouteName = $this->getIndexRouteName($routeName); - - if ($indexRouteName === null) { - return null; - } - - - // Используем index-версию, если она существует - $finalRouteName = Route::has($indexRouteName) ? $indexRouteName : null; - - if ($finalRouteName === null) { - return null; - } - + $finalRouteName = Route::has($indexRouteName) ? $indexRouteName : $routeName; $path = $this->generatePath($finalRouteName); + // Если path null, возвращаем null + if ($path === null) { + return null; + } + $page = Cache::remember('page_' . $path, now()->addHours(1), function () use ($path) { return Page::where('path', $path) ->with('section.pages.section', 'section.mainSection') @@ -53,21 +45,33 @@ class BreadcrumbService ]; } - private function generatePath(string $routeName): string + private function generatePath(string $routeName): ?string { if ($routeName === 'page.view') { return request()->path(); } - $routeUrl = route($routeName); - return ltrim(parse_url($routeUrl, PHP_URL_PATH), '/'); + try { + $route = Route::getRoutes()->getByName($routeName); + + // Если у маршрута есть обязательные параметры без значений по умолчанию, возвращаем null + if ($route && count($route->parameterNames()) > 0) { + return null; + } + + $routeUrl = route($routeName); + return ltrim(parse_url($routeUrl, PHP_URL_PATH), '/'); + } catch (\Exception $e) { + return null; + } } - private function getIndexRouteName(string $routeName = null): string|null + private function getIndexRouteName(string $routeName = null): ?string { if ($routeName === null) { return null; } + $parts = explode('.', $routeName); // Если в маршруте нет точек или он уже заканчивается на index diff --git a/public/.gitignore b/public/.gitignore new file mode 100644 index 0000000..153343e --- /dev/null +++ b/public/.gitignore @@ -0,0 +1,13 @@ +./build +android-chrome-192x192.png +android-chrome-512x512.png +apple-touch-icon.png +favicon-16x16.png +favicon-32x32.png +favicon.ico +safari-pinned-tab.svg +mstile-150x150.png +site.webmanifest +robots.txt +./sveden +./abitur diff --git a/public/.htaccess b/public/.htaccess deleted file mode 100644 index 3aec5e2..0000000 --- a/public/.htaccess +++ /dev/null @@ -1,21 +0,0 @@ - - - Options -MultiViews -Indexes - - - RewriteEngine On - - # Handle Authorization Header - RewriteCond %{HTTP:Authorization} . - RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] - - # Redirect Trailing Slashes If Not A Folder... - RewriteCond %{REQUEST_FILENAME} !-d - RewriteCond %{REQUEST_URI} (.+)/$ - RewriteRule ^ %1 [L,R=301] - - # Send Requests To Front Controller... - RewriteCond %{REQUEST_FILENAME} !-d - RewriteCond %{REQUEST_FILENAME} !-f - RewriteRule ^ index.php [L] - diff --git a/public/android-chrome-192x192.png b/public/android-chrome-192x192.png deleted file mode 100644 index 7e7a005..0000000 Binary files a/public/android-chrome-192x192.png and /dev/null differ diff --git a/public/android-chrome-512x512.png b/public/android-chrome-512x512.png deleted file mode 100644 index 6163d93..0000000 Binary files a/public/android-chrome-512x512.png and /dev/null differ diff --git a/public/apple-touch-icon.png b/public/apple-touch-icon.png deleted file mode 100644 index 6d9c70d..0000000 Binary files a/public/apple-touch-icon.png and /dev/null differ diff --git a/public/favicon-16x16.png b/public/favicon-16x16.png deleted file mode 100644 index 34cc8e9..0000000 Binary files a/public/favicon-16x16.png and /dev/null differ diff --git a/public/favicon-32x32.png b/public/favicon-32x32.png deleted file mode 100644 index eef1c28..0000000 Binary files a/public/favicon-32x32.png and /dev/null differ diff --git a/public/favicon.ico b/public/favicon.ico deleted file mode 100644 index a340c95..0000000 Binary files a/public/favicon.ico and /dev/null differ diff --git a/public/mstile-150x150.png b/public/mstile-150x150.png deleted file mode 100644 index e53c2d3..0000000 Binary files a/public/mstile-150x150.png and /dev/null differ diff --git a/public/raspisanie/index.html b/public/raspisanie/index.html deleted file mode 100644 index 675464f..0000000 --- a/public/raspisanie/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - Мой проект - - Document - - -

test

- - \ No newline at end of file diff --git a/public/safari-pinned-tab.svg b/public/safari-pinned-tab.svg deleted file mode 100644 index 1c90342..0000000 --- a/public/safari-pinned-tab.svg +++ /dev/null @@ -1,81 +0,0 @@ - - - - -Created by potrace 1.14, written by Peter Selinger 2001-2017 - - - - - - - diff --git a/public/site.webmanifest b/public/site.webmanifest deleted file mode 100644 index d0751c0..0000000 --- a/public/site.webmanifest +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "\u041d\u0422\u0413\u0421\u041f\u0418", - "short_name": "\u041d\u0422\u0413\u0421\u041f\u0418", - "icons": [ - { - "src": "/android-chrome-192x192.png", - "sizes": "192x192", - "type": "image/png" - }, - { - "src": "/android-chrome-512x512.png", - "sizes": "512x512", - "type": "image/png" - } - ], - "theme_color": "#000000", - "background_color": "#000000", - "display": "standalone" -}