Changes
This commit is contained in:
@@ -20,6 +20,7 @@ use App\Models\Tag;
|
|||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use Doctrine\DBAL\Schema\Column;
|
use Doctrine\DBAL\Schema\Column;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Cache;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use Inertia\Inertia;
|
use Inertia\Inertia;
|
||||||
|
|
||||||
@@ -128,28 +129,52 @@ class ClientPostController extends Controller
|
|||||||
|
|
||||||
public function show(Request $request, $slug)
|
public function show(Request $request, $slug)
|
||||||
{
|
{
|
||||||
$post = new PostResource(Post::where('slug', $slug)->where('publish_at', '<', Carbon::now())->firstOrFail());
|
// Уникальный ключ для кеширования
|
||||||
$routeUrl = route('client.post.index');
|
$cacheKey = 'post_' . md5($slug);
|
||||||
$path = ltrim(parse_url($routeUrl, PHP_URL_PATH), '/');
|
|
||||||
|
|
||||||
$page = Page::where('path', '=', $path)->with('section.pages.section', 'section.mainSection')->first();
|
// Пытаемся получить данные из кеша
|
||||||
|
$data = Cache::remember($cacheKey, now()->addHours(1), function () use ($slug) {
|
||||||
|
// Получаем пост
|
||||||
|
$post = Post::where('slug', $slug)
|
||||||
|
->where('publish_at', '<', Carbon::now())
|
||||||
|
->firstOrFail();
|
||||||
|
|
||||||
if (isset($page->section)) {
|
// Преобразуем пост в ресурс
|
||||||
$breadcrumbs = [
|
$postResource = new PostResource($post);
|
||||||
'mainSection' => new ClientBreadcrumbSection($page->section->mainSection),
|
|
||||||
'subSection' => new ClientBreadcrumbSubSection($page->section),
|
// Получаем путь для страницы
|
||||||
'page' => new ClientBreadcrumbPage($page),
|
$routeUrl = route('client.post.index');
|
||||||
];
|
$path = ltrim(parse_url($routeUrl, PHP_URL_PATH), '/');
|
||||||
} else {
|
|
||||||
|
// Получаем данные страницы
|
||||||
|
$page = Page::where('path', '=', $path)
|
||||||
|
->with('section.pages.section', 'section.mainSection')
|
||||||
|
->first();
|
||||||
|
|
||||||
|
// Формируем хлебные крошки
|
||||||
$breadcrumbs = null;
|
$breadcrumbs = null;
|
||||||
}
|
if (isset($page->section)) {
|
||||||
|
$breadcrumbs = [
|
||||||
|
'mainSection' => new ClientBreadcrumbSection($page->section->mainSection),
|
||||||
|
'subSection' => new ClientBreadcrumbSubSection($page->section),
|
||||||
|
'page' => new ClientBreadcrumbPage($page),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
$seo = $post->seo ?? null;
|
// SEO-данные
|
||||||
|
$seo = $post->seo ?? null;
|
||||||
|
|
||||||
|
// Возвращаем данные для кеширования
|
||||||
|
return [
|
||||||
|
'post' => $postResource,
|
||||||
|
'breadcrumbs' => $breadcrumbs,
|
||||||
|
'seo' => $seo,
|
||||||
|
];
|
||||||
|
});
|
||||||
|
|
||||||
return Inertia::render('Client/Posts/Show', compact('post', 'breadcrumbs', 'seo'));
|
// Возвращаем ответ с использованием кешированных данных
|
||||||
|
return Inertia::render('Client/Posts/Show', $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ use App\Models\MainSection;
|
|||||||
use App\Models\Page;
|
use App\Models\Page;
|
||||||
use App\Models\Post;
|
use App\Models\Post;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Cache;
|
||||||
use Illuminate\Support\Facades\Http;
|
use Illuminate\Support\Facades\Http;
|
||||||
use Illuminate\Support\Facades\Redirect;
|
use Illuminate\Support\Facades\Redirect;
|
||||||
use Inertia\Inertia;
|
use Inertia\Inertia;
|
||||||
@@ -23,7 +24,16 @@ class PageController extends Controller
|
|||||||
{
|
{
|
||||||
public function render($path)
|
public function render($path)
|
||||||
{
|
{
|
||||||
$page = Page::where('path', '=', $path)->with('section.pages.section', 'section.mainSection')->first();
|
// Генерируем уникальный ключ для кеширования
|
||||||
|
$cacheKey = 'page_' . md5($path);
|
||||||
|
|
||||||
|
// Пытаемся получить данные из кеша
|
||||||
|
$page = Cache::remember($cacheKey, now()->addHours(1), function () use ($path) {
|
||||||
|
return Page::where('path', '=', $path)
|
||||||
|
->with('section.pages.section', 'section.mainSection')
|
||||||
|
->first();
|
||||||
|
});
|
||||||
|
|
||||||
if ($page === null) {
|
if ($page === null) {
|
||||||
abort(404);
|
abort(404);
|
||||||
}
|
}
|
||||||
@@ -42,21 +52,16 @@ class PageController extends Controller
|
|||||||
|
|
||||||
$seo = $page->seo ?? null;
|
$seo = $page->seo ?? null;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$page = new PageResource($page);
|
$page = new PageResource($page);
|
||||||
|
|
||||||
$error = $page->code;
|
$error = $page->code;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if ($page->code != 200) {
|
if ($page->code != 200) {
|
||||||
abort($error);
|
abort($error);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Inertia::render($page->template, compact('page', 'subSectionPages', 'breadcrumbs', 'seo'));
|
return Inertia::render($page->template, compact('page', 'subSectionPages', 'breadcrumbs', 'seo'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getRegisteredPages()
|
public function getRegisteredPages()
|
||||||
{
|
{
|
||||||
$pages = PageResource::collection(Page::query()
|
$pages = PageResource::collection(Page::query()
|
||||||
|
|||||||
@@ -13,6 +13,5 @@ class NavigateController extends Controller
|
|||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
return ClientNavigationResource::collection(MainSection::with('subSections.pages')->orderBy('sort', 'asc')->get());
|
return ClientNavigationResource::collection(MainSection::with('subSections.pages')->orderBy('sort', 'asc')->get());
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-3
@@ -6,9 +6,10 @@ use App\Http\Middleware\AccessCheck;
|
|||||||
use App\Http\Middleware\RateLimitCheckMiddleware;
|
use App\Http\Middleware\RateLimitCheckMiddleware;
|
||||||
use App\Http\Middleware\RateLimitCounterMiddleware;
|
use App\Http\Middleware\RateLimitCounterMiddleware;
|
||||||
use Illuminate\Foundation\Http\Kernel as HttpKernel;
|
use Illuminate\Foundation\Http\Kernel as HttpKernel;
|
||||||
use Spatie\Permission\Middlewares\PermissionMiddleware;
|
use Spatie\Permission\Middleware\PermissionMiddleware;
|
||||||
use Spatie\Permission\Middlewares\RoleMiddleware;
|
use Spatie\Permission\Middleware\RoleMiddleware;
|
||||||
use Spatie\Permission\Middlewares\RoleOrPermissionMiddleware;
|
use Spatie\Permission\Middleware\RoleOrPermissionMiddleware;
|
||||||
|
|
||||||
|
|
||||||
class Kernel extends HttpKernel
|
class Kernel extends HttpKernel
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ namespace App\Http\Middleware;
|
|||||||
use App\Http\Resources\ClientNavigationResource;
|
use App\Http\Resources\ClientNavigationResource;
|
||||||
use App\Models\MainSection;
|
use App\Models\MainSection;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Cache;
|
||||||
use Inertia\Middleware;
|
use Inertia\Middleware;
|
||||||
use Tightenco\Ziggy\Ziggy;
|
use Tightenco\Ziggy\Ziggy;
|
||||||
|
|
||||||
@@ -32,6 +33,14 @@ class HandleInertiaRequests extends Middleware
|
|||||||
*/
|
*/
|
||||||
public function share(Request $request): array
|
public function share(Request $request): array
|
||||||
{
|
{
|
||||||
|
$navigation = Cache::remember('navigation', now()->addHours(1), function () {
|
||||||
|
return ClientNavigationResource::collection(
|
||||||
|
MainSection::with('subSections.pages.section')
|
||||||
|
->orderBy('sort', 'asc')
|
||||||
|
->get()
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
return [
|
return [
|
||||||
...parent::share($request),
|
...parent::share($request),
|
||||||
'auth' => [
|
'auth' => [
|
||||||
@@ -41,15 +50,14 @@ class HandleInertiaRequests extends Middleware
|
|||||||
...(new Ziggy)->toArray(),
|
...(new Ziggy)->toArray(),
|
||||||
'location' => $request->url(),
|
'location' => $request->url(),
|
||||||
],
|
],
|
||||||
'navigation' => ClientNavigationResource::collection(MainSection::with('subSections.pages.section')->orderBy('sort', 'asc')->get()),
|
'navigation' => $navigation,
|
||||||
'urlPrev' => function() {
|
'urlPrev' => function() {
|
||||||
if (url()->previous() !== '' && url()->previous() !== url()->current()) {
|
if (url()->previous() !== '' && url()->previous() !== url()->current()) {
|
||||||
return url()->previous();
|
return url()->previous();
|
||||||
} else {
|
} else {
|
||||||
return 'empty'; // Используется в JavaScript для отключения поведения кнопки "Назад"
|
return 'empty';
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ namespace App\Observers;
|
|||||||
|
|
||||||
use App\Models\Post;
|
use App\Models\Post;
|
||||||
use Filament\Notifications\Notification;
|
use Filament\Notifications\Notification;
|
||||||
|
use Illuminate\Support\Facades\Cache;
|
||||||
use Illuminate\Support\Facades\Redirect;
|
use Illuminate\Support\Facades\Redirect;
|
||||||
|
|
||||||
class PostObserver
|
class PostObserver
|
||||||
@@ -13,27 +14,24 @@ class PostObserver
|
|||||||
*/
|
*/
|
||||||
public function saved(Post $post): void
|
public function saved(Post $post): void
|
||||||
{
|
{
|
||||||
$recipient = auth()->user();
|
|
||||||
|
|
||||||
Notification::make()
|
|
||||||
->title('Saved successfully')
|
|
||||||
->sendToDatabase($recipient);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle the Post "updated" event.
|
* Handle the Post "updated" event.
|
||||||
*/
|
*/
|
||||||
public function updated(Post $post): void
|
public function updated(Post $post)
|
||||||
{
|
{
|
||||||
//
|
$this->clearPostCache($post);
|
||||||
|
$this->cachePost($post); // Кешируем обновленный пост
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle the Post "deleted" event.
|
* Очистка кеша при удалении поста.
|
||||||
*/
|
*/
|
||||||
public function deleted(Post $post): void
|
public function deleted(Post $post)
|
||||||
{
|
{
|
||||||
//
|
$this->clearPostCache($post);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -51,4 +49,24 @@ class PostObserver
|
|||||||
{
|
{
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function cachePost(Post $post)
|
||||||
|
{
|
||||||
|
$cacheKey = 'post_' . md5($post->slug);
|
||||||
|
$cacheData = [
|
||||||
|
'post' => $post,
|
||||||
|
'seo' => $post->seo,
|
||||||
|
];
|
||||||
|
|
||||||
|
Cache::put($cacheKey, $cacheData, now()->addHours(1)); // Кешируем на 1 час
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Очистка кеша поста.
|
||||||
|
*/
|
||||||
|
protected function clearPostCache(Post $post)
|
||||||
|
{
|
||||||
|
$cacheKey = 'post_' . md5($post->slug);
|
||||||
|
Cache::forget($cacheKey);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,9 @@
|
|||||||
|
|
||||||
namespace App\Providers;
|
namespace App\Providers;
|
||||||
|
|
||||||
|
use App\Models\Page;
|
||||||
use App\Models\Post;
|
use App\Models\Post;
|
||||||
|
use App\Observers\PageObserver;
|
||||||
use App\Observers\PostObserver;
|
use App\Observers\PostObserver;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use Filament\Facades\Filament;
|
use Filament\Facades\Filament;
|
||||||
@@ -29,6 +31,8 @@ class AppServiceProvider extends ServiceProvider
|
|||||||
public function boot(): void
|
public function boot(): void
|
||||||
{
|
{
|
||||||
setlocale(LC_TIME, 'ru_RU.UTF-8');
|
setlocale(LC_TIME, 'ru_RU.UTF-8');
|
||||||
|
Page::observe(PageObserver::class);
|
||||||
|
Post::observe(PostObserver::class);
|
||||||
Carbon::setLocale(config('app.locale'));
|
Carbon::setLocale(config('app.locale'));
|
||||||
Model::preventLazyLoading(!app()->isProduction());
|
Model::preventLazyLoading(!app()->isProduction());
|
||||||
// URL::forceScheme('https');
|
// URL::forceScheme('https');
|
||||||
|
|||||||
+2
-2
@@ -15,7 +15,7 @@ return [
|
|||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'default' => env('CACHE_DRIVER', 'file'),
|
'default' => env('CACHE_DRIVER', 'redis'),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
@@ -106,6 +106,6 @@ return [
|
|||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'prefix' => env('CACHE_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_cache_'),
|
'prefix' => env('CACHE_PREFIX'),
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|||||||
+2
-2
@@ -121,11 +121,11 @@ return [
|
|||||||
|
|
||||||
'redis' => [
|
'redis' => [
|
||||||
|
|
||||||
'client' => env('REDIS_CLIENT', 'phpredis'),
|
'client' => env('REDIS_CLIENT', 'predis'),
|
||||||
|
|
||||||
'options' => [
|
'options' => [
|
||||||
'cluster' => env('REDIS_CLUSTER', 'redis'),
|
'cluster' => env('REDIS_CLUSTER', 'redis'),
|
||||||
'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_database_'),
|
'prefix' => env('REDIS_PREFIX') . ':',
|
||||||
],
|
],
|
||||||
|
|
||||||
'default' => [
|
'default' => [
|
||||||
|
|||||||
+10
-7
@@ -1,7 +1,7 @@
|
|||||||
version: '3'
|
version: '3'
|
||||||
services:
|
services:
|
||||||
webserver:
|
webserver:
|
||||||
image: nginx:latest
|
image: nginx:1.27.2
|
||||||
volumes:
|
volumes:
|
||||||
- ./:/var/www
|
- ./:/var/www
|
||||||
- ./_docker/nginx/conf.d/:/etc/nginx/conf.d/
|
- ./_docker/nginx/conf.d/:/etc/nginx/conf.d/
|
||||||
@@ -24,7 +24,7 @@ services:
|
|||||||
command: >
|
command: >
|
||||||
sh -c "cron && php artisan inertia:start-ssr & php-fpm"
|
sh -c "cron && php artisan inertia:start-ssr & php-fpm"
|
||||||
|
|
||||||
php-queue:
|
php-queue-worker:
|
||||||
restart: always
|
restart: always
|
||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
@@ -48,13 +48,16 @@ services:
|
|||||||
ports:
|
ports:
|
||||||
- "3306:3306"
|
- "3306:3306"
|
||||||
|
|
||||||
redis:
|
redis-cache:
|
||||||
image: redis:latest
|
image: redis:7.4.2
|
||||||
container_name: ntspi-redis
|
restart: always
|
||||||
|
container_name: ntspi-cache-service
|
||||||
ports:
|
ports:
|
||||||
- "6379:6379"
|
- "6379:6379"
|
||||||
|
command: redis-server --save 20 1 --loglevel warning
|
||||||
volumes:
|
volumes:
|
||||||
- redis_data:/data
|
- cache:/data
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
redis_data:
|
cache:
|
||||||
|
driver: local
|
||||||
+4
-14
@@ -13,31 +13,22 @@ use App\Http\Controllers\ClientProgramController;
|
|||||||
use App\Http\Controllers\ClientScheduleController;
|
use App\Http\Controllers\ClientScheduleController;
|
||||||
use App\Http\Controllers\ClientVacantPositionController;
|
use App\Http\Controllers\ClientVacantPositionController;
|
||||||
use App\Http\Controllers\ClientVirtualExhibitionController;
|
use App\Http\Controllers\ClientVirtualExhibitionController;
|
||||||
use App\Http\Controllers\ClientWidgetFormController;
|
|
||||||
use App\Http\Controllers\EducationalProgramController;
|
use App\Http\Controllers\EducationalProgramController;
|
||||||
use App\Http\Controllers\GenerateSitemapController;
|
use App\Http\Controllers\GenerateSitemapController;
|
||||||
use App\Http\Controllers\LinkToolController;
|
|
||||||
use App\Http\Controllers\MainController;
|
use App\Http\Controllers\MainController;
|
||||||
use App\Http\Controllers\PageController;
|
use App\Http\Controllers\PageController;
|
||||||
use App\Http\Controllers\PersonController;
|
use App\Http\Controllers\PersonController;
|
||||||
use App\Http\Controllers\ScheduleController;
|
|
||||||
use App\Http\Controllers\StudentController;
|
|
||||||
use App\Http\Controllers\UpdateEduDataApiController;
|
use App\Http\Controllers\UpdateEduDataApiController;
|
||||||
use App\Http\Controllers\UpdateViconDataApi;
|
|
||||||
use App\Http\Controllers\VkAuthController;
|
use Illuminate\Support\Facades\Cache;
|
||||||
use App\Http\Controllers\VkPostController;
|
|
||||||
use App\Models\Post;
|
|
||||||
use Illuminate\Support\Facades\Route;
|
use Illuminate\Support\Facades\Route;
|
||||||
use Inertia\Inertia;
|
|
||||||
use Spatie\Sitemap\Sitemap;
|
|
||||||
use Spatie\Sitemap\SitemapGenerator;
|
|
||||||
use Spatie\Sitemap\Tags\Url;
|
|
||||||
|
|
||||||
|
|
||||||
Route::middleware('signed')->get('invitation/{invitation}/accept', \App\Livewire\AcceptInvitation::class)
|
Route::middleware('signed')->get('invitation/{invitation}/accept', \App\Livewire\AcceptInvitation::class)
|
||||||
->name('invitation.accept');
|
->name('invitation.accept');
|
||||||
|
|
||||||
Route::get('/generate-sitemap', [GenerateSitemapController::class, 'index'])->name('generate-sitemap');
|
|
||||||
|
|
||||||
Route::middleware('access-check')->group(function () {
|
Route::middleware('access-check')->group(function () {
|
||||||
|
|
||||||
@@ -98,7 +89,6 @@ Route::middleware('access-check')->group(function () {
|
|||||||
Route::get('/get-data', [UpdateEduDataApiController::class, 'index']);
|
Route::get('/get-data', [UpdateEduDataApiController::class, 'index']);
|
||||||
|
|
||||||
Route::get('{path}', [PageController::class, 'render'])->where('path', '[0-9,a-z,/,-]+')->name('page.view');
|
Route::get('{path}', [PageController::class, 'render'])->where('path', '[0-9,a-z,/,-]+')->name('page.view');
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user