fix bugs and deletes unnecessary files

This commit is contained in:
F4ilji
2025-04-04 22:59:34 +05:00
parent b6fb523aaa
commit 8aeef476ae
25 changed files with 314 additions and 420 deletions
@@ -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
{
@@ -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();
});
}),
]),
]);
}
}
}
@@ -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;
}
}
}
@@ -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,
@@ -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',
@@ -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(),
@@ -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'));
}
}
+15 -8
View File
@@ -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',
@@ -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'));
+14 -16
View File
@@ -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(''));
}
+73 -100
View File
@@ -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
+14 -9
View File
@@ -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);
@@ -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
+13
View File
@@ -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
-21
View File
@@ -1,21 +0,0 @@
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews -Indexes
</IfModule>
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]
</IfModule>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 661 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

-13
View File
@@ -1,13 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Мой проект</title>
<link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet">
<title>Document</title>
</head>
<body>
<h1 class="bg-primaryBlue">test</h1>
</body>
</html>
-81
View File
@@ -1,81 +0,0 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
width="1676.000000pt" height="1676.000000pt" viewBox="0 0 1676.000000 1676.000000"
preserveAspectRatio="xMidYMid meet">
<metadata>
Created by potrace 1.14, written by Peter Selinger 2001-2017
</metadata>
<g transform="translate(0.000000,1676.000000) scale(0.100000,-0.100000)"
fill="#000000" stroke="none">
<path d="M4230 12340 c0 -1577 3 -1980 13 -1981 6 0 917 -2 2022 -3 1106 -2
2014 -3 2020 -4 5 -1 -49 -59 -120 -128 -72 -69 -254 -246 -405 -394 -151
-147 -311 -302 -355 -345 -44 -43 -212 -206 -374 -364 -162 -157 -329 -320
-371 -361 -43 -41 -202 -196 -355 -345 -152 -148 -318 -310 -369 -359 -113
-110 -672 -653 -741 -721 -159 -155 -454 -442 -688 -669 -146 -143 -265 -262
-263 -265 3 -5 4037 -7 4056 -2 3 0 4 889 2 1973 -1 1085 -2 1978 -2 1983 0 6
0 894 1 1975 0 1081 0 1971 0 1978 -1 9 -415 12 -2036 12 l-2035 0 0 -1980z
m3778 -1 l2 -1696 -1743 0 -1744 0 0 1696 0 1696 1741 0 1741 0 3 -1696z"/>
<path d="M8925 14309 c28 -4 73 -11 100 -14 81 -11 280 -53 425 -91 452 -119
916 -326 1293 -577 51 -33 94 -65 95 -69 2 -4 9 -8 15 -8 7 0 23 -10 37 -23
14 -12 41 -34 60 -47 37 -26 42 -29 78 -59 13 -11 42 -34 65 -53 226 -181 475
-440 667 -693 191 -251 347 -518 480 -820 61 -138 172 -466 195 -575 2 -8 12
-55 24 -105 22 -102 48 -248 57 -321 3 -27 7 -60 9 -74 26 -163 26 -686 0
-840 -2 -14 -7 -47 -10 -75 -5 -44 -25 -164 -41 -250 -10 -56 -44 -191 -69
-280 -14 -49 -28 -97 -30 -105 -49 -187 -233 -593 -370 -817 -85 -138 -203
-313 -225 -333 -3 -3 -27 -34 -55 -70 -101 -131 -157 -193 -329 -365 -168
-167 -278 -262 -441 -383 -60 -44 -121 -89 -135 -100 -49 -36 -237 -151 -350
-214 -303 -168 -598 -288 -954 -389 -77 -21 -149 -41 -160 -43 -12 -2 -75 -15
-141 -29 -66 -14 -140 -28 -165 -32 -25 -3 -72 -10 -105 -15 -33 -5 -87 -12
-120 -15 -33 -3 -71 -8 -85 -10 -30 -5 -224 -17 -340 -20 -47 -2 -88 -3 -91
-4 -4 -1 -6 -892 -6 -1981 l0 -1979 176 4 c207 5 378 13 476 21 39 3 88 7 111
9 34 2 110 10 214 20 62 6 268 33 310 40 14 2 60 9 103 15 43 6 88 13 100 15
44 7 143 25 167 30 14 3 36 7 49 10 456 86 944 222 1389 387 75 28 155 57 177
65 22 8 46 19 52 25 7 6 13 7 13 3 0 -4 11 0 25 9 13 9 29 16 34 16 39 0 667
300 873 416 43 24 80 44 83 44 3 0 18 8 33 19 15 10 101 63 192 117 414 247
838 557 1215 889 254 223 609 582 791 800 70 83 86 102 114 135 46 53 244 310
311 402 343 474 647 1017 873 1560 192 462 349 980 436 1438 21 106 59 336 65
389 4 30 8 62 10 71 2 9 6 41 10 71 3 30 8 70 10 89 4 35 8 75 20 224 4 44 9
100 12 125 2 25 6 1033 8 2239 l4 2192 -3942 -1 c-2169 -1 -3920 -5 -3892 -10z
m7508 -4238 l28 -1 -6 -102 c-6 -107 -13 -208 -20 -280 -14 -140 -17 -165 -20
-188 -2 -14 -6 -46 -9 -72 -6 -46 -13 -99 -21 -147 -2 -13 -7 -45 -11 -70 -4
-25 -8 -55 -10 -66 -3 -11 -7 -36 -10 -55 -3 -19 -12 -66 -20 -105 -8 -38 -17
-86 -20 -105 -12 -75 -108 -444 -159 -615 -120 -397 -246 -714 -446 -1120 -49
-99 -104 -207 -122 -240 -18 -33 -44 -80 -58 -105 -13 -25 -32 -56 -40 -70 -9
-14 -40 -65 -69 -115 -87 -148 -292 -453 -422 -627 -66 -90 -124 -165 -127
-168 -4 -3 -22 -25 -41 -50 -19 -25 -39 -50 -45 -56 -5 -6 -26 -30 -45 -54
-19 -24 -45 -55 -58 -68 -12 -14 -41 -48 -65 -76 -146 -173 -548 -575 -747
-746 -14 -12 -36 -31 -50 -43 -14 -12 -68 -57 -120 -100 -52 -43 -103 -84
-112 -92 -57 -47 -276 -211 -348 -260 -47 -33 -87 -62 -90 -65 -21 -26 -516
-334 -680 -423 -30 -16 -75 -41 -100 -55 -24 -14 -132 -69 -240 -123 -170 -84
-248 -120 -494 -228 -27 -11 -55 -21 -62 -21 -8 0 -14 -5 -14 -10 0 -6 -3 -9
-7 -8 -7 2 -200 -69 -283 -104 -42 -17 -430 -146 -510 -168 -92 -26 -398 -108
-425 -114 -11 -3 -60 -14 -110 -25 -49 -11 -101 -22 -115 -25 -14 -2 -68 -14
-120 -24 -52 -11 -113 -23 -135 -26 -48 -8 -64 -11 -180 -30 -90 -16 -116 -19
-210 -31 -27 -3 -66 -8 -85 -11 -19 -3 -57 -8 -85 -10 -27 -2 -64 -6 -82 -9
-28 -4 -67 -8 -213 -20 -80 -6 -304 -19 -355 -19 l-50 -1 0 1698 0 1697 35 1
c19 1 46 2 60 4 14 1 59 5 100 9 80 7 105 10 215 27 39 6 84 13 100 15 17 2
53 9 80 14 28 5 61 11 75 14 63 11 255 58 350 86 58 17 113 32 124 35 10 2 73
23 140 46 544 186 1060 481 1501 858 113 97 353 334 435 430 30 35 60 69 66
75 14 15 125 156 149 190 11 16 25 33 30 40 6 6 47 65 91 131 382 566 612
1209 678 1890 3 22 5 50 5 62 1 17 8 22 34 25 25 2 3456 1 3570 -1z"/>
<path d="M4199 10332 c-21 -22 -223 -213 -470 -443 -20 -19 -96 -90 -168 -158
-72 -68 -141 -133 -154 -143 -12 -11 -83 -77 -157 -148 -74 -70 -151 -142
-170 -160 -32 -29 -239 -223 -316 -295 -60 -57 -269 -253 -304 -285 -43 -40
-268 -251 -325 -305 -24 -22 -96 -89 -161 -150 -65 -60 -132 -123 -149 -140
-32 -30 -217 -204 -369 -345 -44 -41 -97 -91 -117 -110 -20 -19 -92 -87 -160
-150 -67 -63 -139 -131 -160 -150 -20 -19 -87 -82 -149 -140 -62 -58 -129
-121 -150 -140 -108 -101 -280 -263 -316 -297 -172 -162 -306 -287 -346 -323
-27 -23 -48 -45 -48 -49 0 -3 947 -6 2105 -6 1158 0 2105 -2 2105 -5 0 -2 -27
-29 -59 -60 -146 -135 -278 -258 -316 -295 -36 -34 -187 -175 -299 -279 -17
-16 -92 -86 -167 -157 -75 -71 -145 -137 -157 -147 -12 -10 -81 -75 -154 -144
-73 -69 -145 -136 -159 -149 -25 -23 -252 -236 -329 -309 -37 -35 -246 -230
-310 -290 -19 -18 -95 -89 -168 -158 -73 -69 -141 -132 -151 -141 -15 -14
-176 -165 -326 -306 -48 -46 -265 -248 -304 -284 -14 -13 -87 -81 -161 -151
-74 -70 -151 -142 -170 -160 -47 -43 -277 -258 -310 -290 -14 -14 -89 -83
-165 -155 -178 -167 -271 -253 -369 -346 -43 -41 -91 -86 -107 -100 -16 -14
-29 -28 -29 -31 0 -4 949 -6 2110 -6 l2110 -1 0 3960 c0 2177 -3 3959 -7 3958
-5 0 -15 -8 -24 -17z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 5.4 KiB

-19
View File
@@ -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"
}