From 8aeef476aec7d4b3e940b93c773e48e9d4def175 Mon Sep 17 00:00:00 2001 From: F4ilji Date: Fri, 4 Apr 2025 22:59:34 +0500 Subject: [PATCH] fix bugs and deletes unnecessary files --- .../DepartmentsRelationManager.php | 2 + .../SubSectionsRelationManager.php | 48 ++++- .../RelationManagers/PagesRelationManager.php | 114 ++++-------- .../ClientAcademicJournalController.php | 28 +-- .../ClientAdditionalEducationController.php | 28 ++- .../ClientDepartmentController.php | 25 +-- .../Controllers/ClientDivisionController.php | 30 ++- .../Controllers/ClientEventController.php | 23 ++- .../Controllers/ClientFacultyController.php | 19 +- app/Http/Controllers/ClientPostController.php | 30 ++- .../Controllers/ClientProgramController.php | 173 ++++++++---------- app/Http/Controllers/PersonController.php | 23 ++- .../App/Breadcrumb/BreadcrumbService.php | 44 +++-- public/.gitignore | 13 ++ public/.htaccess | 21 --- public/android-chrome-192x192.png | Bin 2713 -> 0 bytes public/android-chrome-512x512.png | Bin 7897 -> 0 bytes public/apple-touch-icon.png | Bin 2401 -> 0 bytes public/favicon-16x16.png | Bin 661 -> 0 bytes public/favicon-32x32.png | Bin 1035 -> 0 bytes public/favicon.ico | Bin 15086 -> 0 bytes public/mstile-150x150.png | Bin 3238 -> 0 bytes public/raspisanie/index.html | 13 -- public/safari-pinned-tab.svg | 81 -------- public/site.webmanifest | 19 -- 25 files changed, 314 insertions(+), 420 deletions(-) create mode 100644 public/.gitignore delete mode 100644 public/.htaccess delete mode 100644 public/android-chrome-192x192.png delete mode 100644 public/android-chrome-512x512.png delete mode 100644 public/apple-touch-icon.png delete mode 100644 public/favicon-16x16.png delete mode 100644 public/favicon-32x32.png delete mode 100644 public/favicon.ico delete mode 100644 public/mstile-150x150.png delete mode 100644 public/raspisanie/index.html delete mode 100644 public/safari-pinned-tab.svg delete mode 100644 public/site.webmanifest 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 7e7a005e5ea293c05226e5eadf29b24bf5e85276..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2713 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 diff --git a/public/android-chrome-512x512.png b/public/android-chrome-512x512.png deleted file mode 100644 index 6163d9318a7ec8117b62ea8b80d81db49ae67a31..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7897 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 E2M4YNj{pDw diff --git a/public/apple-touch-icon.png b/public/apple-touch-icon.png deleted file mode 100644 index 6d9c70db998464c5981a6914e29b16c2237de222..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2401 zcmZ`*c~sJi68`0$OV-u&ni>@55@jSV*EJU`5k(6afHGLAoF? z5@h~c6(k1uz1&|Q0htH~cLxA?maVjLR#p;&&%0pU0pPMe0Hj?50I?*M_6-1tFaVeh z0RXFF0MLx4HJ`MR6r|3fP9T6SN_KCDB$6i}-JRvX$!bXNgFIfmD4C=nheSAdC-4?% zNuJ)rS}!_UT3#5pypl?P>k5_2J$M}{m#*)Y0T16ptlIagf^f4w+{*kzJyQGb>B!k) zw}n3t20Od_6w1#>-DdrnAD8LDe8!UBBagr!b|yBbJ#Fb}Z(jhF=&2Va?M-4#b7+&P z^P7VBl-1Zp+lUUlKuSSI>Z(0>=YPTO+@EnMLs*U@hbd*Bi3_Bibo`>JEa+H;pBpPf zPU3Qpjfd1ScLRZU9q{32hJLq|v3zvW5}QM}-dpmHddfZvJ#Ef00{ujzD0IHXUv^V%AW*TX%#I`DvjewH?T2T5bZ_U&O$MN}%?wnc=}Qk* z=%40=N0&q>c%_2L!R z4M0J=*!0FX>9hh{V{AXKTVv;iSgpCZJkhuP?4xDjb_w*ubE!cng*OwqPW!4YoW_ir zp6ezPZr*o-$qZSvCGZYu3)z;+8`o&qfz;^iWR|b;a@yHr{WtEQTvS)bb^9wYU3&JK zpK8GaVeCV=F|jgM5E}l~yEzc~BRa_3{t{`MEZqy5f>3pp7z2=r*2TX`ki)xu&|s3fpI*OpXD9qqaNMXur~01@JDg7YxvJ+CwjL$F^gpdW znPhJlO0Y8h?zi#cdopOp0fdEd!OD&-aNLwXuCb^OWg~bIw!z6gVx0r7UT@O%rxOEe zJJR~*4>FIvU5FCrt8M2t@7`qV-JQ%B%oXkv$N#`X8KR1J87?{IRXXmBIHm8R zt6HJRsv9TT@4);1KzfuOEc^_mlQk1sooO88V2Ym0iK_ODD6Xt-!u}frv9jhKAMy2V zAp3N}z-faza5~-rWNZwMV z_9%U-vM*S}`2w$2RXfUtqdL4F$=fJ$2+gNXPIbpuvFe{&Kg;Y+e0@L<8SvJIt&ba< z>0UJwud9r#%1}gA$Muliw~}(*t=0|YRb)3U+Vvu&R@UtySeG3{1#?lJ2Q&J`|$k(ZaoAl8&T>X~G_v}KaF z&qvLT35;(1Z$ zy*Z=dH4%`Cu!!tF$NT7*&NNzcTDxAxEuK#0Z&#blfe!E&n z(eK+{3gDn*o(fZ4wkQ5bcvp0-B%{n` z$-#G1s%d|41>Bt$ao<x-mfJW1E5Acb?aTT78)iukoMCnURaooy2=1Nh`@`y3nQDvRZJ<3@a{s_^Fq`xr)VQ7DvE zEk3u7^JZ~#GAB5O&n}2-{ZUoNdD2OK?~3aFHG0FHmFQz`LM^N0K3Tt#VD8~RGY_vQ zXPV9(lG}mC3|TUE4Bo159U*ZJo673QDb`3<_g_q`U9cp{_u*^GZgL;`nm*hbQ4T98 ztI!?HAF@q}-g&9*c12ZP4O4qCA3Zjn@$2?zFJ4`UFBb<#F%KqbkVByU_v9AF;+9Po zji9<~Pl<}E?2fRFS7Ba6s%k^v=Mg_Nk13AVCuS1!Z)$i9HDwpx4>6>8A_ImPnRE|U z+JS}ys(b8RUQDrQa60!<;8N?&??*2V-g*hdctYQfP9_J zC?_SiEo2cjYvQ~P1<%|vHuNfA*}02i_jr!l_O!Zb?J@>QA6Vt;m zv%@AP-Y~coTq0&r7|aR=GtTf1{SN}}QYbb&@&6NoC+0^a1i#DPrwEv{@!;s#OX1k4 zFfbu8It+}BCY%R=1lp8PSs}*P(D1ECPcQN-29Sm*8J|~DgQ%hM)uq+Ih&0pAP-)0> pZ*b4Z0Grjz(qYN>q`8#38UwSMy9h!@vjWKo0O^cI)HsHu{|g$5cGCa= diff --git a/public/favicon-16x16.png b/public/favicon-16x16.png deleted file mode 100644 index 34cc8e9e264808d726e74b699d2cdf174e8697d1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 661 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^xl_H+M9WCijSl0AZa z85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP=YDR+ueoXe|!I#{Xiaj ziKnkC`wLbvW<^bRtM*k442)KuE{-7@=Tk4*X9pLG9Q$~F=T6=&3y(^8d9Ml(EGd}8 z;U_CoBQDC-w63W;JNzT7MOVHrVe!n{vB&z4TpP{WTo_wMy39?7uf{_EQGWkkFSLcJBFF+R?f@51nY5 z(89f3q_TE*=GBGXe0RPb*mK5O|Kz`pvb+a3ZdA+1Ze66SxL(=3ROR$GpD%YOS_^Gm zxZ%M>{zJ9#DSbAk8+BAHPp10cG5&C2l4Q6~&GoWX6Q)Y1edYDtW0-vM!n|d!%#A$; z8(yzlxc%3@Uuox7$?Lu1Y0Z|)mOkCuXZgl*^#iy3S(~O+wk9j{>LxGl((JlZcE_ST zY~ft1l?LIrGE3?syKiconju1Z}+TAqEUs)e_f; zl9a@fRIB8oR3OD*WME{XYhbEtWE5gxY-Mb0Wn!ppU|?lnaDlTj4@E<6eoAIqC2kE1 zLk?a7Y6!0ii6{w5ELSKf%1_J8NmVGREJ#(zEGS84V5pe$_!AFDVVH)-DgV=FJf8+J zFe`KGC36ca3wuu%VHQ?!X)rmQ!mPYGMB(&}D<_VeIU;j}{d9xJ0xvy=SK@*tpPWpm Q01boFyt=akR{0Ox`ITmS$7 diff --git a/public/favicon-32x32.png b/public/favicon-32x32.png deleted file mode 100644 index eef1c287009be481514186ec3af53dbec9268174..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1035 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKpuOE zr>`sf3sx~^MXh_r*93s_8$4YcLp+Ypy?Qn~CRBp$!+lHROf_Z2z}X_lTyI~{bLpNM zp`+BncF@(=QG_LY*M(k%Ag9%fv=8ogi1E0X8s4O<$6_x~s(8z_t8Bv*t!*2lqMftV z<xu?c0RW||9jv0>T^3AJ#V~aW%rf%@;~BR_v1dR!=8zgUNmgK zt9^&1QuJhI{;!CzOoO+z!nGGUkNH}zj?8@XZC>ZT6RTJ3K0bZwv7Y6>diJ#ydSCpa zdpU7e)U>)uT|v7)_li9UEDyVCcIox2pT)QB+pbip?2eDwerc-2ifK>3PDltmU^ahc z^_eLTXtjd>iVRR9@8A9 z2~U-u7F`ri^S&J#QSIq9`I4T#%LO9U zFBqmB^Y>fvfb)0lr1a3zyRX-ATD`lj^?kwOhrIpWi(WJwK2{_?X|2)cTVW+vVzrGr z_I{DQ_sPSq`jX;ep-Dbx<9uf}D3*SH?d`GScJ{X?`t!ee1LXA+vmr&<@||8rN$hKe2gAgcK1EKSa$QFweHLg zm8u)6XXl-IoHc)P-x;y<)h8#cxl#Oio!8Eot99IUdiU8Km%Vd6e@p3W&a`(2&l;qy zKb^L;sPRn4blH&D?U#4`yOX(l*D~&G^Mk+ic&d&u*G)gN=(OW)zr(A<=9(|x+juWI z>1xKt8=EFn$C)n5J;>{I;x5lL-m>JsTbJFMd@%Lkvi50HU)<5s6kELf^dq&2#ebw^ z^>-TQ%c(Eo|5I`L%jLc>sqjCEt9G>gJ}7FuZ@w0fevvM5kF^VgkC zhRU;V-)-JjY*%vR`X$f*Oof~mwwW|BvICQ|YKdz^NlIc#s#S7PDv)9@GB7gHH89mR zG72#;wlX%hGBMINFt9Q(c=#~+Gm3`X{FKbJO57SI?78g^)DT`35>XPASgue|l%JNF zld4csS&*ubSx}P9z)&&g@h2XR!Y~buQ~syVcs>ncU{>bVOXe0<7WSSj!Yr)d(qM8p wg;{xXh{EX`S56!`b42C{`{@Rc1zvg#ufzpQJ~^3A1zN%2>FVdQ&MBb@07pp5Bme*a diff --git a/public/favicon.ico b/public/favicon.ico deleted file mode 100644 index a340c956cf6cc8ff086125e6a4a98c1bfc68609c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15086 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 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" -}