Skip to content

Commit

Permalink
70. new product slugs
Browse files Browse the repository at this point in the history
  • Loading branch information
dmitrakovich committed Jan 14, 2025
1 parent aebe4d9 commit 2253d4d
Show file tree
Hide file tree
Showing 11 changed files with 129 additions and 28 deletions.
2 changes: 2 additions & 0 deletions src/app/Admin/Controllers/ProductController.php
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,8 @@ public function restore(int $productId)
*/
protected function form()
{
abort(400, 'Проводятся технические работы. Временно не доступно.');

$form = new Form(new Product());
$product = null;
$productFromStock = $this->getStockProduct();
Expand Down
1 change: 1 addition & 0 deletions src/app/Admin/Models/Product.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
* @property int $id
* @property int|null $one_c_id
* @property string $slug
* @property string $old_slug
* @property string $sku
* @property int $label_id
* @property float $buy_price
Expand Down
49 changes: 49 additions & 0 deletions src/app/Http/Controllers/Api/ProductController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php

namespace App\Http\Controllers\Api;

use App\Enums\StockTypeEnum;
use App\Events\Analytics\ProductView;
use App\Http\Controllers\Controller;
use App\Models\Product;
use App\Services\FeedbackService;
use App\Services\ProductService;
use App\Services\Seo\ProductSeoService;
use App\Services\SliderService;

class ProductController extends Controller
{
public function __construct(
// private readonly ProductService $productService,
private readonly SliderService $sliderService,
// private readonly ProductSeoService $seoService,
private readonly FeedbackService $feedbackService,
) {}

/**
* Display the specified resource.
*/
public function show(Product $product)
{
$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')]),
]);
// $this->productService->addToRecent($product->id);

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

event(new ProductView($product));

return [
'product' => $product,
'feedbacks' => $this->feedbackService->getForProduct($product->id),
'similarProducts' => $this->sliderService->getSimilarProducts($product->id),
'productGroup' => $this->sliderService->getProductGroup($product->product_group_id),
// 'recentProductsSlider' => $this->sliderService->getRecentProducts($this->productService),
];
}
}
16 changes: 2 additions & 14 deletions src/app/Http/Controllers/Api/TemporaryController.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,8 @@

use App\Http\Controllers\Controller;
use App\Http\Controllers\Shop\CatalogController;
use App\Http\Controllers\Shop\ProductController;
use App\Http\Requests\FilterRequest;
use App\Models\Product;
use App\Models\Url;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Str;

class TemporaryController extends Controller
{
Expand All @@ -19,18 +15,10 @@ class TemporaryController extends Controller
*/
public function catalog(FilterRequest $request): JsonResponse
{
$path = $request->route('path');
$slug = (string)Str::of($path)->explode('/')->last();
$url = Url::search($slug);

$isCatalog = !($url && $url['model_type'] === Product::class);

$view = $isCatalog
? app(CatalogController::class)->show($request)
: app(ProductController::class)->show($url->model_id);
$view = app(CatalogController::class)->show($request);

return response()->json([
'is_catalog' => $isCatalog,
'is_catalog' => true,
'data' => $view->getData(),
]);
}
Expand Down
6 changes: 3 additions & 3 deletions src/app/Http/Controllers/Shop/ProductController.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,15 @@ public function __construct(
/**
* Display the specified product.
*/
public function show(int $id): View
public function show(Product $product): View
{
$product = Product::with([
$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')]),
])->withTrashed()->findOrFail($id);
]);
$this->productService->addToRecent($product->id);
$this->setProductUrlToFeedback();

Expand Down
3 changes: 2 additions & 1 deletion src/app/Models/Product.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
* @property int $id
* @property int|null $one_c_id
* @property string $slug
* @property string $old_slug
* @property string $sku
* @property int $label_id
* @property float $buy_price
Expand Down Expand Up @@ -275,7 +276,7 @@ public function getFullName(): string
*/
public function getUrl(): string
{
return $this->url ?? ($this->url = $this->category->getUrl() . '/' . $this->slug);
return route('product.show', $this->slug);
}

/**
Expand Down
18 changes: 14 additions & 4 deletions src/app/Models/Url.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\MorphTo;
use Illuminate\Support\Facades\Cache;

/**
Expand All @@ -11,6 +12,9 @@
* @property int $model_id
* @property string|null $redirect
*
* @property-read \Illuminate\Database\Eloquent\Model|null $model
* @property-read \Illuminate\Database\Eloquent\Model|null $filters
*
* @mixin \Illuminate\Database\Eloquent\Builder
*/
class Url extends Model
Expand All @@ -27,10 +31,8 @@ class Url extends Model

/**
* Найти url model по slug
*
* @return object
*/
public static function search(string $slug)
public static function search(string $slug): ?self
{
// return Cache::tags(['catalog_slugs'])
// ->rememberForever($slug, function () use ($slug) {
Expand All @@ -40,10 +42,18 @@ public static function search(string $slug)
// if (!empty($url->redirect)) return redirect($url->redirect);
}

/**
* Get the related model
*/
public function model(): MorphTo
{
return $this->morphTo();
}

/**
* Get the parent filters model
*/
public function filters()
public function filters(): MorphTo
{
return $this->morphTo('filters', 'model_type', 'model_id');
}
Expand Down
2 changes: 1 addition & 1 deletion src/app/Providers/RouteServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public function map(): void

protected function mapApiRoutes(): void
{
Route::middleware(['api', /* 'device.auth', */ 'web']) // todo: remove web middleware !!!
Route::middleware(['api', 'device.auth'])
->prefix('api/' . self::API_VERSION)
->as('api.')
->group(base_path('routes/api.php'));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php

use App\Models\Product;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Str;

return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('products', function (Blueprint $table) {
$table->dropUnique(['slug']);
$table->renameColumn('slug', 'old_slug');
$table->string('slug', 50)->nullable()->after('one_c_id')->unique();
});

Product::withTrashed()
->with(['category'])
->each(function (Product $product) {
$product->update(['slug' => Str::slug($product->shortName())]);
});

Schema::table('products', function (Blueprint $table) {
$table->string('slug', 50)->nullable(false)->change();
});
}

/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('products', function (Blueprint $table) {
$table->dropUnique(['slug']);
$table->dropColumn('slug');
});

Schema::table('products', function (Blueprint $table) {
$table->renameColumn('old_slug', 'slug');
$table->unique(['slug']);
});
}
};
2 changes: 2 additions & 0 deletions src/routes/api.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<?php

use App\Http\Controllers\Api\AppController;
use App\Http\Controllers\Api\ProductController;
use App\Http\Controllers\Api\TemporaryController;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
Expand All @@ -11,3 +12,4 @@

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
10 changes: 5 additions & 5 deletions src/routes/web.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@

Route::post('currency/switch', [CurrencyController::class, 'switch'])->name('currency-switcher');

Route::get('product/{product:slug}', [ProductController::class, 'show'])->withTrashed()->name('product.show');

Route::group([], function () {
Route::post('/quick/{product}', [ProductController::class, 'quickView'])->withTrashed()->name('product.quick');
Route::get('ajax-next-page', [CatalogController::class, 'ajaxNextPage']);
Expand All @@ -69,11 +71,9 @@
$slug = (string)Str::of($path)->explode('/')->last();
$url = Url::search($slug);

if (isset($url) && $url['model_type'] === Product::class) {
return app(ProductController::class)->show($url->model_id);
} else {
return app(CatalogController::class)->show($request);
}
return $url?->model_type === Product::class
? redirect(status: 301)->route('product.show', $url->model->slug)
: app(CatalogController::class)->show($request);
};
Route::get('catalog/city-{city}/{path?}', $check_catalog)->where('path', '[a-zA-Z0-9/_-]+')->name('shop-city');
Route::get('catalog/{path?}', $check_catalog)->where('path', '[a-zA-Z0-9/_-]+')->name('shop');
Expand Down

0 comments on commit 2253d4d

Please sign in to comment.