Files
getgreen-backend/app/Http/Controllers/Dashboard/Compilation/Controller.php

219 lines
6.8 KiB
PHP
Executable File

<?php
namespace App\Http\Controllers\Dashboard\Compilation;
use App\Http\Controllers\Controller as ExController;
use App\Models\Category;
use App\Models\Compilation;
use App\Models\Product;
use Illuminate\Http\Request;
use App\Http\Requests\Dashboard\Compilation\Store as StoreRequest;
use App\Http\Requests\Dashboard\Compilation\Update as UpdateRequest;
use App\Jobs\Dashboard\Compilation\Store as StoreJob;
use App\Jobs\Dashboard\Compilation\Update as UpdateJob;
class Controller extends ExController
{
protected $products;
protected $compilation;
protected $categories;
/**
* Controller constructor.
* @param Product $product
* @param Compilation $compilation
* @param Category $category
*/
public function __construct(Product $product, Compilation $compilation, Category $category)
{
$this->products = $product;
$this->compilation = $compilation;
$this->categories = $category;
}
/**
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function index()
{
$this->authorize('view', 'compilations');
$compilations = Compilation::orderBy('position', 'asc')->get();
return view('dashboard.compilations.index', compact('compilations'));
}
public function store(StoreRequest $request)
{
if ($request->isMethod('get')) {
$this->authorize('create', 'compilations');
$categories = $this->categoryOptions();
return view('dashboard.compilations.store', compact('categories'));
}
$this->dispatchSync(new StoreJob($request));
$this->success(trans('admin.messages.created'));
return response()->json([
'status' => true
]);
}
/**
* @param Compilation $compilation
* @param UpdateRequest $request
* @return \Illuminate\Contracts\View\Factory|\Illuminate\Http\JsonResponse|\Illuminate\View\View
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function update(Compilation $compilation, UpdateRequest $request)
{
if ($request->isMethod('get')) {
// $this->authorize('content-manager');
$this->authorize('update', 'compilations');
$products = $compilation->dashboardProducts()
->select('products.id', 'products.name', 'products.poster')
->get();
foreach ($products as $product) {
$product->poster = $product->getPoster();
$product->name = $product->name['ru'];
}
$compilation->setRelation('products', $products);
$categories = $this->categoryOptions();
return view('dashboard.compilations.update', compact('compilation', 'categories'));
}
$this->dispatchSync(new UpdateJob($request, $compilation));
$this->info(trans('admin.messages.updated'));
return response()->json([
'status' => true
]);
}
/**
* @param Request $request
* @return \Illuminate\Http\JsonResponse
*/
public function search(Request $request)
{
$query = trim((string) $request->name);
$categoryId = (int) $request->get('category_id');
$product = $this->products
->newQuery()
->whereNull('child_id')
->when($categoryId > 0, function ($builder) use ($categoryId) {
$categoryIds = $this->categoryIdsWithChildren($categoryId);
if (empty($categoryIds)) {
$builder->whereRaw('1 = 0');
return;
}
$builder->whereHas('categories', function ($category) use ($categoryIds) {
$category->whereIn('categories.id', $categoryIds);
});
})
->when($query !== '', function ($builder) use ($query) {
$builder->where(function ($search) use ($query) {
$search
->where('name->ru', 'like', '%' . $query . '%')
->orWhere('name->uz', 'like', '%' . $query . '%')
->orWhere('article_number', 'like', '%' . $query . '%');
});
})
->orderBy('id', 'desc')
->limit(30)
->get()
->map(function ($product) {
return [
'id' => $product->id,
'poster' => $product->getPoster(),
'name' => $product->name['ru']
];
});
return response()->json([
'status' => true,
'products' => $product
]);
}
private function categoryIdsWithChildren(int $categoryId): array
{
if (!Category::whereKey($categoryId)->exists()) {
return [];
}
return $this->collectCategoryIds($categoryId);
}
private function collectCategoryIds(int $categoryId, array $visited = []): array
{
if (in_array($categoryId, $visited, true)) {
return [];
}
$visited[] = $categoryId;
$ids = [$categoryId];
$children = Category::where('parent_id', $categoryId)
->orderBy('position')
->pluck('id');
foreach ($children as $childId) {
$ids = array_merge($ids, $this->collectCategoryIds((int) $childId, $visited));
}
return array_values(array_unique($ids));
}
private function categoryOptions($parentId = null, string $prefix = '')
{
return Category::select('id', 'name', 'parent_id')
->when($parentId === null, function ($query) {
$query->whereNull('parent_id');
}, function ($query) use ($parentId) {
$query->where('parent_id', $parentId);
})
->orderBy('position')
->get()
->flatMap(function (Category $category) use ($prefix) {
$ru = $category->name['ru'] ?? $category->name['uz'] ?? '';
$uz = $category->name['uz'] ?? $ru;
return collect([[
'id' => $category->id,
'name' => [
'ru' => $prefix . $ru,
'uz' => $prefix . $uz,
],
]])->merge($this->categoryOptions($category->id, $prefix . '- '));
})
->values();
}
/**
* @param Compilation $compilation
* @return \Illuminate\Http\RedirectResponse
* @throws \Exception
*/
public function delete(Compilation $compilation)
{
$this->authorize('delete', 'compilations');
$compilation->delete();
$this->info(trans('admin.messages.updated'));
return redirect()->back();
}
}