Rework admin panel and other
This commit is contained in:
@@ -2,37 +2,76 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Enums\CacheKeys;
|
||||
use App\Http\Resources\ClientAcademicJournalListResource;
|
||||
use App\Http\Resources\ClientVirtualExhibitionListResource;
|
||||
use App\Models\AcademicJournal;
|
||||
use App\Models\JournalIssue;
|
||||
use App\Models\VirtualExhibition;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Services\App\Breadcrumb\BreadcrumbService;
|
||||
use App\Services\App\Seo\SeoPageProvider;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Inertia\Inertia;
|
||||
|
||||
class ClientAcademicJournalController extends Controller
|
||||
{
|
||||
public function __construct(readonly SeoPageProvider $seoPageProvider){}
|
||||
|
||||
public function index()
|
||||
{
|
||||
$journals = ClientAcademicJournalListResource::collection(AcademicJournal::query()->get());
|
||||
$journals = Cache::remember(
|
||||
CacheKeys::ACADEMIC_JOURNALS_PREFIX->value . 'list',
|
||||
now()->addWeek(), // Кешируем на неделю, так как журналы меняются редко
|
||||
function () {
|
||||
return ClientAcademicJournalListResource::collection(
|
||||
AcademicJournal::query()->get()
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
return Inertia::render('Client/AcademicJournals/Index', compact('journals'));
|
||||
$seo = $this->seoPageProvider->getSeoForCurrentPage();
|
||||
|
||||
return Inertia::render('Client/AcademicJournals/Index', compact('journals', 'seo'));
|
||||
}
|
||||
|
||||
public function show(string $slug)
|
||||
{
|
||||
$journal = new ClientAcademicJournalListResource(AcademicJournal::query()->where('slug', '=', $slug)->firstOrFail());
|
||||
$journalIssues = JournalIssue::where('academic_journal_id', $journal->id)
|
||||
->groupBy('year_publication')->get();
|
||||
// Кешируем основной журнал
|
||||
[$journal, $seo] = Cache::remember(
|
||||
CacheKeys::ACADEMIC_JOURNAL_PREFIX->value . $slug,
|
||||
now()->addWeek(),
|
||||
function () use ($slug) {
|
||||
$journal = AcademicJournal::query()
|
||||
->where('slug', $slug)
|
||||
->firstOrFail();
|
||||
$seo = $this->seoPageProvider->getSeoForModel($journal);
|
||||
return [
|
||||
new ClientAcademicJournalListResource($journal),
|
||||
$seo
|
||||
];
|
||||
}
|
||||
);
|
||||
|
||||
$journals = [];
|
||||
// Кешируем выпуски журнала, сгруппированные по годам
|
||||
$journals = Cache::remember(
|
||||
CacheKeys::ACADEMIC_JOURNAL_PREFIX->value . 'issues_' . $slug,
|
||||
now()->addWeek(),
|
||||
function () use ($journal) {
|
||||
$journalIssues = JournalIssue::where('academic_journal_id', $journal->id)
|
||||
->get()
|
||||
->groupBy('year_publication');
|
||||
|
||||
foreach ($journalIssues as $year => $journalGroup) {
|
||||
$journals[] = [
|
||||
'year_publication' => $year,
|
||||
'journalIssues' => $journalGroup
|
||||
];
|
||||
}
|
||||
return Inertia::render('Client/AcademicJournals/Show', compact('journal', 'journals'));
|
||||
$groupedIssues = [];
|
||||
foreach ($journalIssues as $year => $journalGroup) {
|
||||
$groupedIssues[] = [
|
||||
'year_publication' => $year,
|
||||
'journalIssues' => $journalGroup
|
||||
];
|
||||
}
|
||||
|
||||
return $groupedIssues;
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
return Inertia::render('Client/AcademicJournals/Show', compact('journal', 'journals', 'seo'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Enums\CacheKeys;
|
||||
use App\Enums\FormEducation;
|
||||
use App\Http\Resources\AdditionalEducationCategoryPreviewResource;
|
||||
use App\Http\Resources\AdditionalEducationCategoryResource;
|
||||
@@ -14,128 +15,148 @@ use App\Models\AdditionalEducation;
|
||||
use App\Models\AdditionalEducationCategory;
|
||||
use App\Models\DirectionAdditionalEducation;
|
||||
use App\Models\Page;
|
||||
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 ClientAdditionalEducationController extends Controller
|
||||
{
|
||||
public function __construct(readonly SeoPageProvider $seoPageProvider){}
|
||||
|
||||
|
||||
public function index(Request $request)
|
||||
{
|
||||
$cacheKey = md5(serialize([
|
||||
'direction' => $request->input('direction'),
|
||||
'form' => $request->input('form'),
|
||||
'category' => $request->input('category'),
|
||||
]));
|
||||
|
||||
$directionAdditionalEducations = DirectionAdditionalEducationResource::collection(
|
||||
DirectionAdditionalEducation::query()
|
||||
->where('is_active', true)
|
||||
->whereHas('additionalEducationCategories', function ($q) {
|
||||
$q->whereHas('additionalEducations');
|
||||
})->get());
|
||||
|
||||
$additionalEducations = AdditionalEducationCategoryResource::collection(AdditionalEducationCategory::query()
|
||||
->WithActivePrograms()
|
||||
->where('is_active', '=', true)
|
||||
->when($request->input('direction'), function ($q, $direction) {
|
||||
$q->whereHas('direction', function ($query) use ($direction) {
|
||||
$query->where('slug', $direction);
|
||||
});
|
||||
})
|
||||
->when(request()->input('form'), function ($query, $form) {
|
||||
$query->whereHas('additionalEducations', function ($q) use ($form) {
|
||||
$q->where('form_education', FormEducation::fromName($form));
|
||||
});
|
||||
$query->with(['additionalEducations' => function ($q) use ($form) {
|
||||
$q->where('form_education', FormEducation::fromName($form));
|
||||
}]);
|
||||
})
|
||||
->when(request()->input('category'), function ($query) {
|
||||
$slugs = request()->input('category');
|
||||
if (is_array($slugs)) {
|
||||
$query->whereIn('slug', $slugs);
|
||||
}
|
||||
})
|
||||
->has('additionalEducations')
|
||||
->get());
|
||||
|
||||
$categories = AdditionalEducationCategoryPreviewResource::collection(
|
||||
AdditionalEducationCategory::query()
|
||||
->where('is_active', true)
|
||||
->has('additionalEducations')
|
||||
->get()
|
||||
// Основные данные (кешируются)
|
||||
$directionAdditionalEducations = Cache::remember(
|
||||
CacheKeys::ADDITIONAL_EDUCATIONAL_PROGRAMS_PREFIX->value . 'directions_' . $cacheKey,
|
||||
now()->addDay(),
|
||||
function () {
|
||||
return DirectionAdditionalEducationResource::collection(
|
||||
DirectionAdditionalEducation::query()
|
||||
->where('is_active', true)
|
||||
->whereHas('additionalEducationCategories', fn ($q) => $q->whereHas('additionalEducations'))
|
||||
->get()
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
$additionalEducations = Cache::remember(
|
||||
CacheKeys::ADDITIONAL_EDUCATIONAL_PROGRAMS_PREFIX->value . $cacheKey,
|
||||
now()->addDay(),
|
||||
function () use ($request) {
|
||||
return AdditionalEducationCategoryResource::collection(
|
||||
AdditionalEducationCategory::query()
|
||||
->WithActivePrograms()
|
||||
->where('is_active', true)
|
||||
->when($request->direction, fn ($q, $direction) =>
|
||||
$q->whereHas('direction', fn ($query) => $query->where('slug', $direction))
|
||||
)
|
||||
->when($request->form, fn ($query, $form) =>
|
||||
$query->whereHas('additionalEducations', fn ($q) =>
|
||||
$q->where('form_education', FormEducation::fromName($form))
|
||||
)
|
||||
->when($request->category, fn ($query) =>
|
||||
is_array($request->category)
|
||||
? $query->whereIn('slug', $request->category)
|
||||
: $query
|
||||
)
|
||||
->has('additionalEducations')
|
||||
->get()
|
||||
));
|
||||
}
|
||||
);
|
||||
|
||||
$categories = Cache::remember(
|
||||
CacheKeys::ADDITIONAL_EDUCATIONAL_PROGRAMS_PREFIX->value . 'categories',
|
||||
now()->addWeek(),
|
||||
function () {
|
||||
return AdditionalEducationCategoryPreviewResource::collection(
|
||||
AdditionalEducationCategory::query()
|
||||
->where('is_active', true)
|
||||
->has('additionalEducations')
|
||||
->get()
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
// Динамические данные (не кешируются)
|
||||
$categoriesContent = [];
|
||||
if (request()->input('category')) {
|
||||
foreach (request()->input('category') as $item) {
|
||||
$categoriesContent[$item] = new AdditionalEducationCategoryResource(AdditionalEducationCategory::where('slug', $item)->first());
|
||||
if ($request->category) {
|
||||
foreach ((array)$request->category as $item) {
|
||||
$categoriesContent[$item] = new AdditionalEducationCategoryResource(
|
||||
AdditionalEducationCategory::where('slug', $item)->first()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$forms_education = [];
|
||||
foreach (FormEducation::cases() as $case) {
|
||||
$forms_education[$case->name] = $case->getLabel();
|
||||
}
|
||||
$forms_education = array_reduce(
|
||||
FormEducation::cases(),
|
||||
fn ($acc, $case) => $acc + [$case->name => $case->getLabel()],
|
||||
[]
|
||||
);
|
||||
|
||||
$filters = [
|
||||
'direction_filter' => [
|
||||
'type' => 'direction',
|
||||
'value' => request()->input('direction'),
|
||||
'value' => $request->input('direction'),
|
||||
'param' => 'direction'
|
||||
],
|
||||
'form_education_filter' => [
|
||||
'type' => 'form',
|
||||
'value' => request()->input('form'),
|
||||
'value' => $request->input('form'),
|
||||
'param' => 'form'
|
||||
],
|
||||
'category_filter' => [
|
||||
'type' => 'category',
|
||||
'value' => request()->input('category'),
|
||||
'value' => $request->input('category'),
|
||||
'param' => 'category',
|
||||
'content' => $categoriesContent,
|
||||
],
|
||||
];
|
||||
|
||||
$routeUrl = route('client.additionalEducation.index');
|
||||
$path = ltrim(parse_url($routeUrl, PHP_URL_PATH), '/');
|
||||
$seo = $this->seoPageProvider->getSeoForCurrentPage();
|
||||
|
||||
$page = Page::where('path', '=', $path)->with('section.pages.section', 'section.mainSection')->first();
|
||||
|
||||
if (isset($page->section)) {
|
||||
$breadcrumbs = [
|
||||
'mainSection' => new ClientBreadcrumbSection($page->section->mainSection),
|
||||
'subSection' => new ClientBreadcrumbSubSection($page->section),
|
||||
'page' => new ClientBreadcrumbPage($page),
|
||||
];
|
||||
} else {
|
||||
$breadcrumbs = null;
|
||||
}
|
||||
|
||||
return Inertia::render('Client/Additional-educations/Index',
|
||||
compact(
|
||||
'directionAdditionalEducations',
|
||||
'additionalEducations',
|
||||
'filters',
|
||||
'forms_education',
|
||||
'categories',
|
||||
'breadcrumbs'
|
||||
));
|
||||
return Inertia::render('Client/Additional-educations/Index', compact(
|
||||
'directionAdditionalEducations',
|
||||
'additionalEducations',
|
||||
'filters',
|
||||
'forms_education',
|
||||
'categories',
|
||||
'seo'
|
||||
));
|
||||
}
|
||||
|
||||
public function show(string $slug)
|
||||
{
|
||||
$additionalEducation = new AdditionalEducationResource(AdditionalEducation::query()->with('category.direction')->where('slug', $slug)->first());
|
||||
$routeUrl = route('client.additionalEducation.index');
|
||||
$path = ltrim(parse_url($routeUrl, PHP_URL_PATH), '/');
|
||||
// Кешируем основную программу дополнительного образования
|
||||
[$additionalEducation, $seo] = 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
|
||||
];
|
||||
}
|
||||
);
|
||||
|
||||
$page = Page::where('path', '=', $path)->with('section.pages.section', 'section.mainSection')->first();
|
||||
// SEO-данные берём из кешированного ресурса
|
||||
|
||||
if (isset($page->section)) {
|
||||
$breadcrumbs = [
|
||||
'mainSection' => new ClientBreadcrumbSection($page->section->mainSection),
|
||||
'subSection' => new ClientBreadcrumbSubSection($page->section),
|
||||
'page' => new ClientBreadcrumbPage($page),
|
||||
];
|
||||
} else {
|
||||
$breadcrumbs = null;
|
||||
}
|
||||
|
||||
$seo = $additionalEducation->seo ?? null;
|
||||
|
||||
return Inertia::render('Client/Additional-educations/Show', compact('additionalEducation', 'breadcrumbs', 'seo'));
|
||||
}
|
||||
}
|
||||
return Inertia::render('Client/Additional-educations/Show', compact(
|
||||
'additionalEducation',
|
||||
'seo'
|
||||
));
|
||||
}}
|
||||
|
||||
@@ -2,34 +2,93 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Enums\CacheKeys;
|
||||
use App\Http\Resources\ClientDepartmentPreviewResource;
|
||||
use App\Http\Resources\DepartmentResource;
|
||||
use App\Models\Department;
|
||||
use App\Models\Faculty;
|
||||
use App\Services\App\Breadcrumb\BreadcrumbService;
|
||||
use App\Services\App\Seo\SeoPageProvider;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Inertia\Inertia;
|
||||
|
||||
class ClientDepartmentController extends Controller
|
||||
{
|
||||
public function __construct(readonly SeoPageProvider $seoPageProvider){}
|
||||
|
||||
public function show(string $facultySlug, string $departmentSlug)
|
||||
{
|
||||
$faculty = Faculty::query()->where('slug', $facultySlug)->first();
|
||||
$departments = ClientDepartmentPreviewResource::collection(
|
||||
Department::query()
|
||||
->where('is_active', true)
|
||||
->where('faculty_id', $faculty->id)
|
||||
->get()
|
||||
);
|
||||
$department = new DepartmentResource(Department::query()
|
||||
->where('slug', $departmentSlug)
|
||||
->where('is_active', true)
|
||||
->with(['faculty', 'workers.userDetail', 'teachers.userDetail', 'programs.directionStudy'])
|
||||
->first());
|
||||
$directions = $this->groupProgramsByDirection($department->programs);
|
||||
// Ключ для кеширования
|
||||
$cacheKey = "{$facultySlug}_{$departmentSlug}";
|
||||
|
||||
$seo = $department->seo ?? null;
|
||||
return Inertia::render('Client/Departments/Show', compact('department', 'departments', 'directions', 'seo'));
|
||||
// Кешируем факультет
|
||||
$faculty = Cache::remember(
|
||||
CacheKeys::FACULTY_PREFIX->value . $facultySlug,
|
||||
now()->addDay(),
|
||||
function () use ($facultySlug) {
|
||||
return Faculty::query()
|
||||
->where('slug', $facultySlug)
|
||||
->first();
|
||||
}
|
||||
);
|
||||
|
||||
// Кешируем список активных кафедр факультета
|
||||
$departments = Cache::remember(
|
||||
CacheKeys::DEPARTMENTS_PREFIX->value . 'active_' . $faculty->id,
|
||||
now()->addDay(),
|
||||
function () use ($faculty) {
|
||||
return ClientDepartmentPreviewResource::collection(
|
||||
Department::query()
|
||||
->where('is_active', true)
|
||||
->where('faculty_id', $faculty->id)
|
||||
->get()
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
// Кешируем полные данные кафедры с отношениями
|
||||
[$department, $seo] = Cache::remember(
|
||||
CacheKeys::DEPARTMENT_PREFIX->value . $cacheKey,
|
||||
now()->addDay(),
|
||||
function () use ($departmentSlug) {
|
||||
$department = Department::query()
|
||||
->where('slug', $departmentSlug)
|
||||
->where('is_active', true)
|
||||
->with([
|
||||
'faculty',
|
||||
'workers.userDetail',
|
||||
'teachers.userDetail',
|
||||
'programs.directionStudy',
|
||||
'seo'
|
||||
])
|
||||
->first();
|
||||
|
||||
$seo = $this->seoPageProvider->getSeoForModel($department);
|
||||
return [
|
||||
new DepartmentResource($department),
|
||||
$seo
|
||||
];
|
||||
}
|
||||
);
|
||||
|
||||
// Кешируем сгруппированные направления
|
||||
$directions = Cache::remember(
|
||||
CacheKeys::DEPARTMENT_PREFIX->value . 'directions_' . $cacheKey,
|
||||
now()->addDay(),
|
||||
function () use ($department) {
|
||||
return $this->groupProgramsByDirection($department->programs);
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
return Inertia::render('Client/Departments/Show', compact(
|
||||
'department',
|
||||
'departments',
|
||||
'directions',
|
||||
'seo',
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -4,22 +4,31 @@ namespace App\Http\Controllers;
|
||||
|
||||
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 Inertia\Inertia;
|
||||
|
||||
class ClientDivisionController extends Controller
|
||||
{
|
||||
public function __construct(readonly SeoPageProvider $seoPageProvider){}
|
||||
|
||||
public function index()
|
||||
{
|
||||
$divisions = DivisionResource::collection(Division::query()->where('is_active', true)->get());
|
||||
return Inertia::render('Client/Divisions/Index', compact('divisions'));
|
||||
|
||||
$seo = $this->seoPageProvider->getSeoForCurrentPage();
|
||||
|
||||
return Inertia::render('Client/Divisions/Index', compact('divisions', 'seo'));
|
||||
}
|
||||
|
||||
public function show(string $slug)
|
||||
{
|
||||
$divisions = DivisionResource::collection(Division::query()->where('is_active', true)->get());
|
||||
$division = new DivisionResource(Division::with('workers.userDetail')->where('is_active', true)->where('slug', $slug)->firstOrFail());
|
||||
$seo = $division->seo ?? null;
|
||||
$division = new DivisionResource($divisionModel = Division::with(['workers.userDetail', 'seo'])->where('is_active', true)->where('slug', $slug)->firstOrFail());
|
||||
|
||||
$seo = $this->seoPageProvider->getSeoForModel($divisionModel);
|
||||
|
||||
return Inertia::render('Client/Divisions/Show', compact('divisions', 'division', 'seo'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Enums\CacheKeys;
|
||||
use App\Http\Resources\ClientBreadcrumbPage;
|
||||
use App\Http\Resources\ClientBreadcrumbSection;
|
||||
use App\Http\Resources\ClientBreadcrumbSubSection;
|
||||
@@ -13,53 +14,102 @@ use App\Models\Event;
|
||||
use App\Models\EventCategory;
|
||||
use App\Models\Page;
|
||||
use App\Services\App\Breadcrumb\BreadcrumbService;
|
||||
use App\Services\App\Seo\SeoPageProvider;
|
||||
use Carbon\Carbon;
|
||||
use DateTime;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Inertia\Inertia;
|
||||
|
||||
class ClientEventController extends Controller
|
||||
{
|
||||
public function __construct(private readonly BreadcrumbService $breadcrumbService){}
|
||||
|
||||
public function __construct(readonly SeoPageProvider $seoPageProvider){}
|
||||
|
||||
public function index(Request $request): \Inertia\Response
|
||||
{
|
||||
$currentDate = $this->getCurrentDate($request);
|
||||
$cacheKey = md5(serialize([$currentDate, $request->all()]));
|
||||
|
||||
$events = Cache::remember(
|
||||
CacheKeys::EVENTS_PREFIX->value . $cacheKey,
|
||||
now()->addHours(12),
|
||||
fn() => $this->getEvents($currentDate)
|
||||
);
|
||||
|
||||
$eventDates = Cache::remember(
|
||||
CacheKeys::EVENTS_PREFIX->value . 'dates_' . $cacheKey,
|
||||
now()->addHours(12),
|
||||
fn() => $this->getEventDates($this->getFilters())
|
||||
);
|
||||
|
||||
$categories = Cache::remember(
|
||||
CacheKeys::EVENTS_PREFIX->value . 'categories',
|
||||
now()->addDay(),
|
||||
fn() => ClientEventCategoryResource::collection(EventCategory::has('events')->get())
|
||||
);
|
||||
|
||||
$filters = $this->getFilters();
|
||||
$eventDates = $this->getEventDates($filters);
|
||||
|
||||
$events = $this->getEvents($currentDate);
|
||||
$categories = ClientEventCategoryResource::collection(EventCategory::has('events')->get());
|
||||
$seo = $this->seoPageProvider->getSeoForCurrentPage();
|
||||
|
||||
$breadcrumbs = $this->breadcrumbService->generateBreadcrumbs('client.event.index');
|
||||
|
||||
|
||||
return Inertia::render('Client/Events/Index', compact('eventDates', 'events', 'currentDate', 'filters', 'categories', 'breadcrumbs'));
|
||||
return Inertia::render('Client/Events/Index', compact(
|
||||
'eventDates',
|
||||
'events',
|
||||
'currentDate',
|
||||
'filters',
|
||||
'categories',
|
||||
'seo'
|
||||
));
|
||||
}
|
||||
|
||||
public function show(string $slug): \Inertia\Response
|
||||
{
|
||||
$event = new ClientEventFullResource(Event::where('slug', '=', $slug)->with('category')->first());
|
||||
[$event, $seo] = 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
|
||||
];
|
||||
}
|
||||
);
|
||||
|
||||
$breadcrumbs = $this->breadcrumbService->generateBreadcrumbs('client.event.index');
|
||||
|
||||
$seo = $event->seo ?? null;
|
||||
|
||||
return Inertia::render('Client/Events/Show', compact('event', 'breadcrumbs', 'seo'));
|
||||
return Inertia::render('Client/Events/Show', compact(
|
||||
'event',
|
||||
'seo'
|
||||
));
|
||||
}
|
||||
|
||||
public function archive(Request $request): \Inertia\Response
|
||||
{
|
||||
$cacheKey = md5(serialize($request->all()));
|
||||
|
||||
$events = Cache::remember(
|
||||
CacheKeys::EVENTS_PREFIX->value . 'archive_' . $cacheKey,
|
||||
now()->addDay(),
|
||||
fn() => $this->getEventsArchive()
|
||||
);
|
||||
|
||||
$categories = Cache::remember(
|
||||
CacheKeys::EVENTS_PREFIX->value . 'categories',
|
||||
now()->addDay(),
|
||||
fn() => ClientEventCategoryResource::collection(EventCategory::has('events')->get())
|
||||
);
|
||||
|
||||
$filters = $this->getFilters();
|
||||
|
||||
$events = $this->getEventsArchive();
|
||||
$categories = ClientEventCategoryResource::collection(EventCategory::has('events')->get());
|
||||
$seo = $this->seoPageProvider->getSeoForCurrentPage();
|
||||
|
||||
$breadcrumbs = $this->breadcrumbService->generateBreadcrumbs('client.event.archive');
|
||||
|
||||
|
||||
return Inertia::render('Client/Events/Archive', compact('events', 'filters', 'categories', 'breadcrumbs'));
|
||||
return Inertia::render('Client/Events/Archive', compact(
|
||||
'events',
|
||||
'filters',
|
||||
'categories',
|
||||
'seo'
|
||||
));
|
||||
}
|
||||
|
||||
private function getCurrentDate(Request $request): array
|
||||
@@ -164,7 +214,12 @@ class ClientEventController extends Controller
|
||||
->orderBy('event_date_start')
|
||||
->get();
|
||||
|
||||
$mappingDates = $events->map(function ($event) {
|
||||
// Получаем массив без ключей
|
||||
|
||||
|
||||
|
||||
// Извлекаем уникальные даты из событий
|
||||
return $events->map(function ($event) {
|
||||
$date = new DateTime($event->event_date_start);
|
||||
return [
|
||||
'day' => $date->format('j'),
|
||||
@@ -182,12 +237,7 @@ class ClientEventController extends Controller
|
||||
];
|
||||
})
|
||||
->sortKeys() // Сортируем ключи по возрастанию
|
||||
->values(); // Получаем массив без ключей
|
||||
|
||||
|
||||
|
||||
// Извлекаем уникальные даты из событий
|
||||
return $mappingDates;
|
||||
->values();
|
||||
}
|
||||
|
||||
private function getFilters(): array
|
||||
|
||||
@@ -2,26 +2,75 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Enums\CacheKeys;
|
||||
use App\Http\Resources\FacultyResource;
|
||||
use App\Http\Resources\FullFacultyResource;
|
||||
use App\Models\Faculty;
|
||||
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 ClientFacultyController extends Controller
|
||||
{
|
||||
public function index()
|
||||
public function __construct(readonly SeoPageProvider $seoPageProvider){}
|
||||
|
||||
|
||||
public function index(Request $request)
|
||||
{
|
||||
$faculties = FacultyResource::collection(Faculty::query()->where('is_active', true)->get());
|
||||
return Inertia::render('Client/Faculties/Index', compact('faculties'));
|
||||
$faculties = Cache::remember(
|
||||
CacheKeys::FACULTIES_PREFIX->value . 'active_list',
|
||||
now()->addDay(), // Кешируем на 1 день
|
||||
function () {
|
||||
return FacultyResource::collection(
|
||||
Faculty::query()
|
||||
->where('is_active', true)
|
||||
->get()
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
$seo = $this->seoPageProvider->getSeoForCurrentPage();
|
||||
|
||||
return Inertia::render('Client/Faculties/Index', compact('faculties', 'seo'));
|
||||
}
|
||||
|
||||
|
||||
public function show(string $slug)
|
||||
{
|
||||
$faculties = FacultyResource::collection(Faculty::query()->where('is_active', true)->get());
|
||||
$faculty = new FullFacultyResource(Faculty::where('slug', $slug)->where('is_active', true)->with(['departments.faculty', 'workers.userDetail'])->firstOrFail());
|
||||
$seo = $faculty->seo ?? null;
|
||||
// Кешируем список факультетов
|
||||
$faculties = Cache::remember(
|
||||
CacheKeys::FACULTIES_PREFIX->value . 'active_list',
|
||||
now()->addDay(),
|
||||
function () {
|
||||
return FacultyResource::collection(
|
||||
Faculty::query()
|
||||
->where('is_active', true)
|
||||
->get()
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
// Кешируем данные конкретного факультета
|
||||
[$faculty, $seo] = Cache::remember(
|
||||
CacheKeys::FACULTY_PREFIX->value . $slug,
|
||||
now()->addDay(),
|
||||
function () use ($slug) {
|
||||
$faculty = 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
|
||||
];
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
|
||||
return Inertia::render('Client/Faculties/Show', compact('faculty', 'faculties', 'seo'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,14 +3,9 @@
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Http\Resources\CategoryResource;
|
||||
use App\Http\Resources\ClientBreadcrumbPage;
|
||||
use App\Http\Resources\ClientBreadcrumbSection;
|
||||
use App\Http\Resources\ClientBreadcrumbSubSection;
|
||||
use App\Http\Resources\ClientNavigationResource;
|
||||
use App\Http\Resources\ClientPostListResource;
|
||||
use App\Http\Resources\ClientTagResource;
|
||||
use App\Http\Resources\MainSectionResource;
|
||||
use App\Http\Resources\PageResource;
|
||||
|
||||
use App\Http\Resources\PostResource;
|
||||
use App\Models\Category;
|
||||
use App\Models\MainSection;
|
||||
@@ -18,8 +13,8 @@ use App\Models\Page;
|
||||
use App\Models\Post;
|
||||
use App\Models\Tag;
|
||||
use App\Services\App\Breadcrumb\BreadcrumbService;
|
||||
use App\Services\App\Seo\SeoPageProvider;
|
||||
use Carbon\Carbon;
|
||||
use Doctrine\DBAL\Schema\Column;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
@@ -27,12 +22,12 @@ use Inertia\Inertia;
|
||||
|
||||
class ClientPostController extends Controller
|
||||
{
|
||||
public function __construct(private readonly BreadcrumbService $breadcrumbService){}
|
||||
public function __construct(readonly SeoPageProvider $seoPageProvider){}
|
||||
|
||||
public function index(Request $request)
|
||||
{
|
||||
// Кешируем список тегов
|
||||
$tagIds = Cache::remember('tag_ids', now()->addHours(1), function () {
|
||||
$tagIds = Cache::remember('tag_ids', now()->addHours(), function () {
|
||||
return DB::table('taggables')
|
||||
->distinct()
|
||||
->select('tag_id')
|
||||
@@ -132,11 +127,9 @@ class ClientPostController extends Controller
|
||||
],
|
||||
];
|
||||
|
||||
$breadcrumbs = $this->breadcrumbService->generateBreadcrumbs('client.post.index');
|
||||
$seo = $this->seoPageProvider->getSeoForCurrentPage();
|
||||
|
||||
|
||||
|
||||
return Inertia::render('Client/Posts/Index', compact('filters', 'posts', 'categories', 'tags', 'breadcrumbs'));
|
||||
return Inertia::render('Client/Posts/Index', compact('filters', 'posts', 'categories', 'tags', 'seo'));
|
||||
}
|
||||
|
||||
public function show(Request $request, $slug)
|
||||
@@ -154,19 +147,17 @@ class ClientPostController extends Controller
|
||||
// Преобразуем пост в ресурс
|
||||
$postResource = new PostResource($post);
|
||||
|
||||
$breadcrumbs = $this->breadcrumbService->generateBreadcrumbs('client.post.index');
|
||||
|
||||
// SEO-данные
|
||||
$seo = $post->seo ?? null;
|
||||
$seo = $this->seoPageProvider->getSeoForModel($post);
|
||||
|
||||
// Возвращаем данные для кеширования
|
||||
return [
|
||||
'post' => $postResource,
|
||||
'breadcrumbs' => $breadcrumbs,
|
||||
'seo' => $seo,
|
||||
];
|
||||
});
|
||||
|
||||
|
||||
// Возвращаем ответ с использованием кешированных данных
|
||||
return Inertia::render('Client/Posts/Show', $data);
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Enums\BudgetEducation;
|
||||
use App\Enums\CacheKeys;
|
||||
use App\Enums\FormEducation;
|
||||
use App\Enums\LevelEducational;
|
||||
use App\Http\Resources\CampaignDegreeResource;
|
||||
@@ -16,121 +17,150 @@ use App\Models\CampaignDegree;
|
||||
use App\Models\DirectionStudy;
|
||||
use App\Models\EducationalProgram;
|
||||
use App\Models\MainSection;
|
||||
use App\Services\App\Seo\SeoPageProvider;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Str;
|
||||
use Inertia\Inertia;
|
||||
|
||||
class ClientProgramController extends Controller
|
||||
{
|
||||
public function __construct(readonly SeoPageProvider $seoPageProvider){}
|
||||
|
||||
public function index(Request $request)
|
||||
{
|
||||
$activeCampaign = AdmissionCampaign::query()->where('status', 1)->first();
|
||||
$cacheKey = CacheKeys::EDUCATION_PROGRAMS_PREFIX->value . md5(serialize($request->all()));
|
||||
|
||||
$uniqueValues = EducationalProgram::distinct()->pluck('lvl_edu');
|
||||
$levelsEducational = $uniqueValues->mapWithKeys(function ($level) {
|
||||
return [$level->name => $level->getLabel()];
|
||||
});
|
||||
$data = Cache::remember($cacheKey, now()->addHours(1), function () use ($request) {
|
||||
$activeCampaign = AdmissionCampaign::query()->where('status', 1)->first();
|
||||
|
||||
$direction_studies = DirectionStudy::query()
|
||||
->withAdmissionCampaignByYear($activeCampaign->academic_year)
|
||||
->withActivePrograms()
|
||||
->get();
|
||||
$uniqueValues = EducationalProgram::distinct()->pluck('lvl_edu');
|
||||
$levelsEducational = $uniqueValues->mapWithKeys(function ($level) {
|
||||
return [$level->name => $level->getLabel()];
|
||||
});
|
||||
|
||||
$level = request()->input('level');
|
||||
$form = request()->input('form');
|
||||
$budget = request()->input('budget');
|
||||
|
||||
$naprs = DirectionStudyResource::collection(
|
||||
DirectionStudy::query()
|
||||
$direction_studies = 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);
|
||||
}
|
||||
})
|
||||
->get()
|
||||
);
|
||||
->get();
|
||||
|
||||
$level = request()->input('level');
|
||||
$form = request()->input('form');
|
||||
$budget = request()->input('budget');
|
||||
|
||||
$naprs = 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);
|
||||
}
|
||||
})
|
||||
->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();
|
||||
|
||||
|
||||
$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'
|
||||
],
|
||||
];
|
||||
|
||||
return Inertia::render('Client/Programs/Index',
|
||||
compact(
|
||||
return compact(
|
||||
'naprs',
|
||||
'campaignName',
|
||||
'levelsEducational',
|
||||
'filters',
|
||||
'formsEdu',
|
||||
'budgetEdu',
|
||||
'direction_studies'
|
||||
));
|
||||
'direction_studies',
|
||||
'seo'
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
return Inertia::render('Client/Programs/Index', $data);
|
||||
}
|
||||
|
||||
public function show(string $slug)
|
||||
{
|
||||
$program = new EducationalProgramFullResource(EducationalProgram::query()->where('slug', $slug)->with(['admission_plans', 'directionStudy'])->firstOrFail());
|
||||
$formsEducational = BudgetEducation::cases();
|
||||
$formsEducational = collect($formsEducational);
|
||||
$formsEdu = $formsEducational->mapWithKeys(function ($formEducational) {
|
||||
return [$formEducational->value => $formEducational->getLabel()];
|
||||
$cacheKey = CacheKeys::EDUCATION_PROGRAM_PREFIX->value . md5($slug);
|
||||
|
||||
$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');
|
||||
});
|
||||
|
||||
$seo = $program->seo ?? null;
|
||||
return Inertia::render('Client/Programs/Show', compact('program', 'formsEdu', 'seo'));
|
||||
return Inertia::render('Client/Programs/Show', $data);
|
||||
}
|
||||
|
||||
private function getAdmissionCampaignName() : string
|
||||
private function getAdmissionCampaignName(): string
|
||||
{
|
||||
$campaign = AdmissionCampaign::query()->where('status', 1)->first();
|
||||
return $campaign->name;
|
||||
}
|
||||
$cacheKey = CacheKeys::EDUCATION_PROGRAM_PREFIX->value . 'active_campaign_name';
|
||||
|
||||
return Cache::remember($cacheKey, now()->addHours(1), function () {
|
||||
$campaign = AdmissionCampaign::query()->where('status', 1)->first();
|
||||
return $campaign->name;
|
||||
});
|
||||
}
|
||||
|
||||
private function applyFormFilter($query, $form)
|
||||
{
|
||||
@@ -150,7 +180,6 @@ class ClientProgramController extends Controller
|
||||
{
|
||||
$budgetValue = Str::of(BudgetEducation::fromName($budget)->value)->toString();
|
||||
|
||||
|
||||
$query->whereHas('programs.admission_plans', function ($query) use ($budgetValue) {
|
||||
$query->whereJsonContains('contests', ['financing_source' => $budgetValue]);
|
||||
})
|
||||
@@ -160,5 +189,4 @@ class ClientProgramController extends Controller
|
||||
});
|
||||
}]);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -8,11 +8,14 @@ use App\Http\Resources\ScheduleResource;
|
||||
use App\Models\EducationalGroup;
|
||||
use App\Models\Faculty;
|
||||
use App\Models\Schedule;
|
||||
use App\Services\App\Seo\SeoPageProvider;
|
||||
use Illuminate\Http\Request;
|
||||
use Inertia\Inertia;
|
||||
|
||||
class ClientScheduleController extends Controller
|
||||
{
|
||||
public function __construct(readonly SeoPageProvider $seoPageProvider){}
|
||||
|
||||
public function index(Request $request)
|
||||
{
|
||||
$educationalGroups = ClientEducationalGroupResource::collection(EducationalGroup::query()
|
||||
@@ -46,10 +49,6 @@ class ClientScheduleController extends Controller
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
$forms_education = [];
|
||||
foreach (FormEducation::cases() as $case) {
|
||||
$forms_education[$case->name] = $case->getLabel();
|
||||
@@ -78,8 +77,10 @@ class ClientScheduleController extends Controller
|
||||
]
|
||||
];
|
||||
|
||||
$seo = $this->seoPageProvider->getSeoForCurrentPage();
|
||||
|
||||
// Возвращаем данные в представление
|
||||
return Inertia::render('Client/Schedules/Index', compact('educationalGroups', 'filters', 'forms_education', 'schedulesByFaculty'));
|
||||
return Inertia::render('Client/Schedules/Index', compact('educationalGroups', 'filters', 'forms_education', 'schedulesByFaculty', 'seo'));
|
||||
}
|
||||
|
||||
public function show($id)
|
||||
|
||||
@@ -2,22 +2,31 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Enums\CacheKeys;
|
||||
use App\Enums\PostStatus;
|
||||
use App\Http\Resources\AdditionalEducationSearchResource;
|
||||
use App\Http\Resources\PostThumbnailResource;
|
||||
use App\Models\AdditionalEducation;
|
||||
use App\Models\Post;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
|
||||
class ClientWidgetAdditionalEducationalProgramController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
return AdditionalEducationSearchResource::collection(
|
||||
AdditionalEducation::query()
|
||||
->where('is_active', true)
|
||||
->orderBy('title', 'desc')
|
||||
->get());
|
||||
return Cache::remember(
|
||||
CacheKeys::ADDITIONAL_EDUCATIONAL_PROGRAMS_PREFIX->value . 'search_list',
|
||||
now()->addDay(), // Кешируем на 1 день
|
||||
function () {
|
||||
return AdditionalEducationSearchResource::collection(
|
||||
AdditionalEducation::query()
|
||||
->where('is_active', true)
|
||||
->orderBy('title', 'desc')
|
||||
->get()
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,14 +2,26 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Enums\CacheKeys;
|
||||
use App\Http\Resources\ClientContactWidgetResource;
|
||||
use App\Http\Resources\ClientPageReferenceListResource;
|
||||
use App\Models\ContactWidget;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
|
||||
class ClientWidgetContactController extends Controller
|
||||
{
|
||||
public function show(string $slug)
|
||||
{
|
||||
return new ClientContactWidgetResource(ContactWidget::query()->where('slug', $slug)->first());
|
||||
return Cache::remember(
|
||||
CacheKeys::CONTACT_WIDGET_PREFIX->value . $slug,
|
||||
now()->addHours(12), // Кешируем на 12 часов
|
||||
function () use ($slug) {
|
||||
return new ClientContactWidgetResource(
|
||||
ContactWidget::query()
|
||||
->where('slug', $slug)
|
||||
->first()
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,19 +2,28 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Enums\CacheKeys;
|
||||
use App\Enums\EducationalProgramStatus;
|
||||
use App\Http\Resources\EducationalProgramSearchResource;
|
||||
use App\Models\EducationalProgram;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
|
||||
class ClientWidgetEducationalProgramController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
return EducationalProgramSearchResource::collection(
|
||||
EducationalProgram::query()
|
||||
->where('status', EducationalProgramStatus::PUBLISHED)
|
||||
->orderBy('name', 'desc')
|
||||
->get());
|
||||
return Cache::remember(
|
||||
CacheKeys::EDUCATION_PROGRAMS_PREFIX->value . 'search_list',
|
||||
now()->addDay(), // Кешируем на 1 день
|
||||
function () {
|
||||
return EducationalProgramSearchResource::collection(
|
||||
EducationalProgram::query()
|
||||
->where('status', EducationalProgramStatus::PUBLISHED)
|
||||
->orderBy('name', 'desc')
|
||||
->get()
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,14 +2,26 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Enums\CacheKeys;
|
||||
use App\Http\Resources\ClientPageReferenceListResource;
|
||||
use App\Models\PageReferenceList;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
|
||||
class ClientWidgetPageReferenceListController extends Controller
|
||||
{
|
||||
public function show(string $slug)
|
||||
{
|
||||
return new ClientPageReferenceListResource(PageReferenceList::query()->where('slug', $slug)->first());
|
||||
return Cache::remember(
|
||||
CacheKeys::PAGE_REFERENCE_LIST_PREFIX->value . $slug,
|
||||
now()->addWeek(), // Кешируем на неделю, так как справочники меняются редко
|
||||
function () use ($slug) {
|
||||
return new ClientPageReferenceListResource(
|
||||
PageReferenceList::query()
|
||||
->where('slug', $slug)
|
||||
->first()
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,9 @@ class ClientWidgetSliderController extends Controller
|
||||
$slider = Slider::query()
|
||||
->where('slug', $slug)
|
||||
->where('is_active', true)
|
||||
->with('slides')
|
||||
->with(['slides' => function($query) {
|
||||
$query->where('is_active', true);
|
||||
}])
|
||||
->first();
|
||||
|
||||
return $slider ?: null;
|
||||
|
||||
@@ -14,6 +14,7 @@ use App\Http\Resources\RegisteredPageResource;
|
||||
use App\Models\MainSection;
|
||||
use App\Models\Page;
|
||||
use App\Models\Post;
|
||||
use App\Services\App\Seo\SeoPageProvider;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
@@ -22,7 +23,9 @@ use Inertia\Inertia;
|
||||
|
||||
class PageController extends Controller
|
||||
{
|
||||
public function render(Request $request, $path)
|
||||
public function __construct(readonly SeoPageProvider $seoPageProvider){}
|
||||
|
||||
public function render(string $path): \Inertia\Response
|
||||
{
|
||||
// Генерируем уникальный ключ для кеширования
|
||||
$cacheKey = 'page_' . md5($path);
|
||||
@@ -37,45 +40,17 @@ class PageController extends Controller
|
||||
if ($page === null) {
|
||||
abort(404);
|
||||
}
|
||||
$subSectionPages = $page->section ? PageResource::collection($page->section->pages) : null;
|
||||
|
||||
if (isset($page->section)) {
|
||||
$subSectionPages = PageResource::collection($page->section->pages);
|
||||
$breadcrumbs = [
|
||||
'mainSection' => new ClientBreadcrumbSection($page->section->mainSection),
|
||||
'subSection' => new ClientBreadcrumbSubSection($page->section),
|
||||
'page' => new ClientBreadcrumbPage($page),
|
||||
];
|
||||
} else {
|
||||
$subSectionPages = null;
|
||||
$breadcrumbs = null;
|
||||
}
|
||||
|
||||
$seo = $page->seo ?? null;
|
||||
$seo = $this->seoPageProvider->getSeoForModel($page);
|
||||
|
||||
$page = new PageResource($page);
|
||||
|
||||
$error = $page->code;
|
||||
|
||||
if ($page->code != 200) {
|
||||
abort($error);
|
||||
abort($page->code);
|
||||
}
|
||||
|
||||
return Inertia::render('Page', compact('page', 'subSectionPages', 'breadcrumbs', 'seo'));
|
||||
}
|
||||
public function getRegisteredPages()
|
||||
{
|
||||
$pages = PageResource::collection(Page::query()
|
||||
->when(request()->input('search'), function ($query, $search) {
|
||||
$query->where('title', 'like', "%{$search}%");
|
||||
})
|
||||
->where('is_registered', true)
|
||||
->where('is_visible', true)
|
||||
->orderBy('id', 'desc')
|
||||
->paginate(request()->input('perPage', 9))
|
||||
->withQueryString());
|
||||
$filters = [
|
||||
'search' => request()->input('search'),
|
||||
];
|
||||
return Inertia::render('AdminPanel/Pages/Registered', compact('pages', 'filters'));
|
||||
return Inertia::render('Page', compact('page', 'subSectionPages', 'seo'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Enums\CacheKeys;
|
||||
use App\Http\Resources\ClientFullInfoPersonResource;
|
||||
use App\Http\Resources\ClientNavigationResource;
|
||||
use App\Http\Resources\MainSectionResource;
|
||||
@@ -10,23 +11,30 @@ use App\Http\Resources\UserResource;
|
||||
use App\Models\MainSection;
|
||||
use App\Models\User;
|
||||
use App\Models\UserDetail;
|
||||
use App\Services\App\Seo\SeoPageProvider;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Inertia\Inertia;
|
||||
|
||||
class PersonController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
$persons = UserDetailResource::collection(UserDetail::all());
|
||||
$filters = [
|
||||
'search' => request()->input('search'),
|
||||
];
|
||||
return Inertia::render('Client/Persons/Index', compact('persons', 'filters'));
|
||||
}
|
||||
public function __construct(readonly SeoPageProvider $seoPageProvider){}
|
||||
|
||||
public function show(string $slug)
|
||||
{
|
||||
$person = new ClientFullInfoPersonResource(User::query()->with(['userDetail', 'departments_work.faculty', 'departments_teach.faculty', 'divisions', 'faculties'])->where('slug', $slug)->firstOrFail());
|
||||
return Inertia::render('Client/Persons/Show', compact('person'));
|
||||
$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', 'seo'])
|
||||
->where('slug', $slug)
|
||||
->firstOrFail();
|
||||
$seo = $this->seoPageProvider->getSeoForModel($person);
|
||||
return [
|
||||
new ClientFullInfoPersonResource($person),
|
||||
$seo
|
||||
];
|
||||
});
|
||||
|
||||
return Inertia::render('Client/Persons/Show', compact('person', 'seo'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ use App\Http\Resources\EventSearchResource;
|
||||
use App\Http\Resources\FacultySearchResource;
|
||||
use App\Http\Resources\PageSearchResource;
|
||||
use App\Http\Resources\PostSearchResource;
|
||||
use App\Http\Resources\StaticPageSearchResource;
|
||||
use App\Http\Resources\UserSearchResource;
|
||||
use App\Models\AdditionalEducation;
|
||||
use App\Models\EducationalGroup;
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Services\Filament\Services\CategoryFinderService;
|
||||
use App\Services\Filament\Services\StaticFileSearch;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
|
||||
class StaticSearchController extends Controller
|
||||
{
|
||||
public function search(Request $request)
|
||||
{
|
||||
return app(StaticFileSearch::class)
|
||||
->search(
|
||||
$request->input('search'),
|
||||
$request->input('page', 1)
|
||||
);
|
||||
}
|
||||
|
||||
public function getCategories()
|
||||
{
|
||||
return Cache::remember('page_static_categories', now()->addWeek(), function () {
|
||||
return app(CategoryFinderService::class)->getCategories();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace App\Http;
|
||||
|
||||
use App\Http\Middleware\AccessCheck;
|
||||
use App\Http\Middleware\FormTimePeriodMiddleware;
|
||||
use App\Http\Middleware\InternalRequestOnly;
|
||||
use App\Http\Middleware\LimitPost;
|
||||
use App\Http\Middleware\RateLimitCheckMiddleware;
|
||||
@@ -86,6 +87,7 @@ class Kernel extends HttpKernel
|
||||
'ensure.browser' => InternalRequestOnly::class,
|
||||
'superadmin' => \App\Http\Middleware\EnsureUserIsSuperadmin::class,
|
||||
'limit.post' => LimitPost::class,
|
||||
'form.time.period' => FormTimePeriodMiddleware::class,
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use App\Models\CustomForm;
|
||||
use Carbon\Carbon;
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class FormTimePeriodMiddleware
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
|
||||
*/
|
||||
public function handle(Request $request, Closure $next): Response
|
||||
{
|
||||
$form = CustomForm::select('settings')->find($request->route('id'));
|
||||
|
||||
if (!$form) {
|
||||
abort(Response::HTTP_NOT_FOUND, 'Form not found');
|
||||
}
|
||||
|
||||
if (!isset($form->settings['period'])) {
|
||||
abort(Response::HTTP_BAD_REQUEST, 'Invalid form settings');
|
||||
}
|
||||
|
||||
$period = $form->settings['period'];
|
||||
|
||||
try {
|
||||
$start_time = Carbon::parse($period['start_time']);
|
||||
$end_time = Carbon::parse($period['end_time']);
|
||||
} catch (\Exception $e) {
|
||||
abort(Response::HTTP_BAD_REQUEST, 'Invalid time format');
|
||||
}
|
||||
|
||||
$now = Carbon::now();
|
||||
|
||||
if ($now >= $start_time && $now <= $end_time) {
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
abort(Response::HTTP_FORBIDDEN, 'Form is not available at this time');
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ namespace App\Http\Middleware;
|
||||
|
||||
use App\Http\Resources\ClientNavigationResource;
|
||||
use App\Models\MainSection;
|
||||
use App\Services\App\Breadcrumb\BreadcrumbService;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Inertia\Middleware;
|
||||
@@ -11,28 +12,16 @@ use Tightenco\Ziggy\Ziggy;
|
||||
|
||||
class HandleInertiaRequests extends Middleware
|
||||
{
|
||||
/**
|
||||
* The root template that is loaded on the first page visit.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $rootView = 'app';
|
||||
|
||||
/**
|
||||
* Determine the current asset version.
|
||||
*/
|
||||
public function version(Request $request): string|null
|
||||
public function version(Request $request): ?string
|
||||
{
|
||||
return parent::version($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Define the props that are shared by default.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function share(Request $request): array
|
||||
{
|
||||
// Навигация (кешированная)
|
||||
$navigation = Cache::remember('navigation', now()->addHours(1), function () {
|
||||
return ClientNavigationResource::collection(
|
||||
MainSection::with('subSections.pages.section')
|
||||
@@ -41,6 +30,9 @@ class HandleInertiaRequests extends Middleware
|
||||
);
|
||||
});
|
||||
|
||||
// Хлебные крошки (автоматически по текущему URL)
|
||||
$breadcrumbs = app(BreadcrumbService::class)->generateBreadcrumbs();
|
||||
|
||||
return [
|
||||
...parent::share($request),
|
||||
'auth' => [
|
||||
@@ -51,13 +43,13 @@ class HandleInertiaRequests extends Middleware
|
||||
'location' => $request->url(),
|
||||
],
|
||||
'navigation' => $navigation,
|
||||
'urlPrev' => function() {
|
||||
if (url()->previous() !== '' && url()->previous() !== url()->current()) {
|
||||
'breadcrumbs' => $breadcrumbs, // Добавляем хлебные крошки
|
||||
'urlPrev' => function () {
|
||||
if (url()->previous() !== url()->current()) {
|
||||
return url()->previous();
|
||||
} else {
|
||||
return 'empty';
|
||||
}
|
||||
return 'empty';
|
||||
},
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,8 +15,8 @@ class ClientBreadcrumbSection extends JsonResource
|
||||
public function toArray(Request $request): array
|
||||
{
|
||||
return [
|
||||
'title' => $this->title,
|
||||
'slug' => $this->slug,
|
||||
'title' => $this->title ?? null,
|
||||
'slug' => $this->slug ?? null,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ class ClientEventFullResource extends JsonResource
|
||||
'event_time_start' => Carbon::parse($this->event_time_start)->format('H:i'),
|
||||
'address' => $this->address,
|
||||
'is_online' => $this->is_online,
|
||||
'category' => $this->category->title ?? null,
|
||||
'category' => $this->category ?? null,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ class ClientEventResource extends JsonResource
|
||||
'event_time_start' => Carbon::parse($this->event_time_start)->format('H:i'),
|
||||
'address' => $this->address,
|
||||
'is_online' => $this->is_online,
|
||||
'category' => $this->category->title ?? null,
|
||||
'category' => $this->category ?? null,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user