Skip to content

Commit

Permalink
48. adapt catalog for api
Browse files Browse the repository at this point in the history
  • Loading branch information
dmitrakovich committed Jan 17, 2025
1 parent b22344b commit 4d25b1f
Show file tree
Hide file tree
Showing 7 changed files with 151 additions and 98 deletions.
111 changes: 111 additions & 0 deletions src/app/Http/Controllers/Api/CatalogController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
<?php

namespace App\Http\Controllers\Api;

use App\Enums\StockTypeEnum;
use App\Events\Analytics\ProductView;
use App\Facades\Sale;
use App\Helpers\UrlHelper;
use App\Http\Controllers\Controller;
use App\Http\Requests\FilterRequest;
use App\Models\Category;
use App\Models\Product;
use App\Services\CatalogService;
use App\Services\FeedbackService;
use App\Services\FilterService;
use App\Services\GoogleTagManagerService;
use App\Services\ProductService;
use App\Services\Seo\CatalogSeoService;
use App\Services\Seo\ProductSeoService;
use App\Services\SliderService;
use Illuminate\Http\JsonResponse;

class CatalogController extends Controller
{
public function index(
FilterRequest $filterRequest,
GoogleTagManagerService $gtmService,
CatalogService $catalogService,
// CatalogSeoService $seoService,
): JsonResponse {
if ($promocode = $filterRequest->get('promocode')) {
Sale::applyPromocode($promocode);
}

$sort = $filterRequest->getSorting();
$currentFilters = $filterRequest->getFilters();
$currentCity = $filterRequest->getCity();
$searchQuery = $filterRequest->input('search');
UrlHelper::setCurrentFilters($currentFilters);
UrlHelper::setCurrentCity($currentCity);

$products = $catalogService->getProducts($currentFilters, $sort, $searchQuery);

$sortingList = [
'rating' => 'по популярности',
'newness' => 'новинки',
'price-up' => 'по возрастанию цены',
'price-down' => 'по убыванию цены',
];

$category = end($currentFilters[Category::class])->getFilterModel();
$badges = $catalogService->getFilterBadges($currentFilters, $searchQuery);

$gtmService->setForCatalog($products, $category, $searchQuery);

$data = [
'products' => $products,
'category' => $category,
'currentFilters' => $currentFilters,
'badges' => $badges,
'filters' => app(FilterService::class)->getAll(),
'sort' => $sort,
'sortingList' => $sortingList,
'searchQuery' => $searchQuery,
];

if (!$products->isNotEmpty()) {
$sliderService = new SliderService();
$data['simpleSliders'] = $sliderService->getSimple();
}
// $seoService
// ->setCurrentFilters($currentFilters)
// ->setCurrentCity($currentCity)
// ->setProducts($products)
// ->generate();

return response()->json($data);
}

/**
* Display the specified resource.
*/
public function show(
Product $product,
// ProductService $productService,
SliderService $sliderService,
// ProductSeoService $seoService,
FeedbackService $feedbackService,
): array {
$product->load([
'tags',
'category',
'countryOfOrigin',
'availableSizes' => fn ($q) => $q->whereHas('stock', fn ($q) => $q->where('type', StockTypeEnum::SHOP))
->with(['stock' => fn ($q) => $q->orderBy('site_sorting', 'asc')->with('city')]),
]);
// $productService->addToRecent($product->id);

// $seoService->setProduct($product)->generate(); // !!!

event(new ProductView($product));

return [
'product' => $product,
'feedbacks' => $feedbackService->getForProduct($product->id),
'similarProducts' => $sliderService->getSimilarProducts($product->id),
'productGroup' => $sliderService->getProductGroup($product->product_group_id),
// 'recentProductsSlider' => $sliderService->getRecentProducts($productService),
];
}
}
49 changes: 0 additions & 49 deletions src/app/Http/Controllers/Api/ProductController.php

This file was deleted.

25 changes: 0 additions & 25 deletions src/app/Http/Controllers/Api/TemporaryController.php

This file was deleted.

17 changes: 10 additions & 7 deletions src/app/Http/Requests/FilterRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,16 @@ public function rules()
*/
public function getSorting(): string
{
$session = $this->session();
$sorting = $this->input('sort') ?? $session->get('sorting', Product::DEFAULT_SORT);
if ($sorting != $session->get('sorting')) {
$session->put('sorting', $sorting);
$sorting = $this->input('sort');

if ($this->hasSession()) {
$sessionSorting = $this->session()->get('sorting');
if ($sorting && $sorting !== $sessionSorting) {
$this->session()->put('sorting', $sorting);
}
}

return $sorting;
return $sorting ?? Product::DEFAULT_SORT;
}

/**
Expand All @@ -55,7 +58,7 @@ public function getFilters(): array
$slugs = array_filter(explode('/', 'catalog/' . $this->path));
$filters = $this->getStaticFilters($slugs);

Url::whereIn('slug', $slugs)
Url::query()->whereIn('slug', $slugs)
->with('filters')
->get(['slug', 'model_type', 'model_id'])
->sortBy(fn (Url $url) => array_search($url->slug, $slugs))
Expand All @@ -75,7 +78,7 @@ public function getCity(): ?City
{
$citySlug = $this->route('city');

return $citySlug ? City::where('slug', $citySlug)->first() : null;
return $citySlug ? City::query()->where('slug', $citySlug)->first() : null;
}

/**
Expand Down
8 changes: 8 additions & 0 deletions src/app/Models/Category.php
Original file line number Diff line number Diff line change
Expand Up @@ -262,4 +262,12 @@ public function getNameWithParents(): string

return $name;
}

/**
* Mark filter as invisible
*/
public function isInvisible(): bool
{
return $this->isRoot();
}
}
26 changes: 14 additions & 12 deletions src/app/Services/CatalogService.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,23 +55,25 @@ public function getProducts(array $filters, string $sort, ?string $search = null
return $products;
}

public function getFilterBadges(?array $currentFiltersGroups, ?string $searchQuery = null): array
public function getFilterBadges(array $currentFiltersGroups = [], ?string $searchQuery = null): array
{
$badges = [];
if (!empty($currentFiltersGroups)) {
foreach ($currentFiltersGroups as $currentFiltersGroupKey => $currentFiltersGroup) {
foreach ($currentFiltersGroup as $currentFilterKey => $currentFilter) {
$filterModel = $currentFilter->filters;
if ($filterModel->isInvisible() || $filterModel->slug === 'catalog' || ($currentFiltersGroupKey == Category::class) && ($currentFilterKey != array_key_last($currentFiltersGroup))) {
continue;
}
$badges[] = (object)[
'name' => $filterModel->getBadgeName(),
'url' => UrlHelper::generate([], [$filterModel]),
];
foreach ($currentFiltersGroups as $filterModel => $currentFiltersGroup) {
if ($filterModel === Category::class) {
$currentFiltersGroup = [end($currentFiltersGroup)];
}
foreach ($currentFiltersGroup as $currentFilter) {
$filterModel = $currentFilter->filters;
if ($filterModel->isInvisible()) {
continue;
}
$badges[] = (object)[
'name' => $filterModel->getBadgeName(),
'url' => UrlHelper::generate([], [$filterModel]),
];
}
}

if ($searchQuery) {
$badges[] = (object)[
'name' => 'Поиск: ' . mb_strimwidth($searchQuery, 0, 12, '...'),
Expand Down
13 changes: 8 additions & 5 deletions src/routes/api.php
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
<?php

use App\Facades\Device;
use App\Http\Controllers\Api\AppController;
use App\Http\Controllers\Api\ProductController;
use App\Http\Controllers\Api\TemporaryController;
use App\Http\Controllers\Api\CatalogController;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;

Route::get('/user', function (Request $request) {
return $request->user();
return [
'user' => $request->user(),
'device' => Device::current(),
];
})->middleware('auth:sanctum');

Route::get('app-init', [AppController::class, 'init']);
Route::get('catalog/{path?}', [TemporaryController::class, 'catalog'])->where('path', '[a-zA-Z0-9/_-]+');
Route::get('product/{product:slug}', [ProductController::class, 'show'])->withTrashed()->name('product.show'); // ! test
Route::get('catalog/{path?}', [CatalogController::class, 'index'])->where('path', '[a-zA-Z0-9/_-]+');
Route::get('product/{product:slug}', [CatalogController::class, 'show'])->withTrashed()->name('product.show');

0 comments on commit 4d25b1f

Please sign in to comment.