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

362 lines
12 KiB
PHP
Executable File

<?php
namespace App\Http\Controllers\Dashboard\Category;
use App\Models\Brand;
use App\Models\Category;
use App\Http\Controllers\Controller as ExController;
use App\Http\Requests\Dashboard\Category\Request as StoreRequest;
use App\Http\Requests\Dashboard\Category\Update as UpdateRequest;
use App\Jobs\Dashboard\Category\Store as StoreJob;
use App\Jobs\Dashboard\Category\Update as UpdateJob;
use App\Models\Characteristic;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;
use Throwable;
class Controller extends ExController
{
/**
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function index()
{
$this->authorize('view', 'categories');
$categories = $this->categoryTree();
return view('dashboard.category.index', compact('categories'));
}
private function categoryTree($parentId = null, array $visited = [])
{
return Category::select('id', 'name', 'position', 'parent_id', 'image')
->when($parentId === null, function ($query) {
$query->whereNull('parent_id');
}, function ($query) use ($parentId) {
$query->where('parent_id', $parentId);
})
->orderBy('position', 'asc')
->get()
->map(function (Category $category) use ($visited) {
if (in_array($category->id, $visited, true)) {
return [
'id' => $category->id,
'category' => $category->name['ru'] ?? $category->name['uz'] ?? '',
'position' => $category->position,
'parent_id' => $category->parent_id,
'image' => $category->image,
'image_url' => $category->image_url,
'children' => [],
];
}
return [
'id' => $category->id,
'category' => $category->name['ru'] ?? $category->name['uz'] ?? '',
'position' => $category->position,
'parent_id' => $category->parent_id,
'image' => $category->image,
'image_url' => $category->image_url,
'children' => $this->categoryTree($category->id, [...$visited, $category->id]),
];
});
}
/**
* @param StoreRequest $request
* @return \Illuminate\Contracts\View\Factory|\Illuminate\Http\JsonResponse|\Illuminate\View\View
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function store(StoreRequest $request)
{
if ($request->isMethod('get')) {
$this->authorize('view', 'categories');
$brands = Brand::all();
$brands->map(function ($brand) {
$brand->name = $brand->name['ru'];
});
$parent_categories = Category::with('parent')->get();
return view('dashboard.category.store', compact('brands', 'parent_categories'));
}
try {
$category = DB::transaction(function () use ($request) {
$category = $this->dispatchSync(new StoreJob($request));
if (!empty($request->char)) {
foreach ($request->char as $char) {
Characteristic::create([
'name' => $char['name'] ?? ['ru' => '', 'uz' => ''],
'type' => $char['type'] ?? 'text',
'category_id' => $category->id,
'filter' => filter_var($char['filter'] ?? false, FILTER_VALIDATE_BOOLEAN)
]);
}
}
return $category;
});
} catch (Throwable $exception) {
Log::error('Category store failed', [
'message' => $exception->getMessage(),
'trace' => $exception->getTraceAsString(),
]);
return response()->json([
'status' => false,
'message' => 'Category could not be saved.',
'error' => config('app.debug') ? $exception->getMessage() : null,
], 500);
}
if ($category) {
$this->success(trans('admin.messages.created'));
}
return response()->json([
'status' => true
]);
}
/**
* @param $category
* @param UpdateRequest $request
* @return \Illuminate\Contracts\View\Factory|\Illuminate\Http\JsonResponse|\Illuminate\View\View
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function update($category, UpdateRequest $request)
{
$category = Category::findOrFail($category);
if ($request->isMethod('get')) {
$this->authorize('update', 'categories');
$parent_categories = Category::with('parent')->whereNotIn('id', [$category->id])->get();
$brands = Brand::all();
$brands->map(function ($brand) {
$brand->name = $brand->name['ru'];
});
$category->loadMissing(['brands', 'characteristics']);
$category->brands->map(function ($brand) {
$brand->name = $brand->name['ru'];
});
return view('dashboard.category.update', compact('parent_categories', 'category', 'brands'));
}
try {
$image = $request->getImage($category);
DB::transaction(function () use ($category, $request, $image) {
$this->dispatchSync(new UpdateJob($category, $request, $image));
if (!empty($request->char)) {
foreach ($request->char as $char) {
if ($char['id'] == null || $char['id'] == 'null') {
Characteristic::create([
'name' => $char['name'] ?? ['ru' => '', 'uz' => ''],
'type' => $char['type'] ?? 'text',
'category_id' => $category->id,
'filter' => filter_var($char['filter'] ?? false, FILTER_VALIDATE_BOOLEAN)
]);
} else {
Characteristic::where('id', $char['id'])->update([
'name' => $char['name'] ?? ['ru' => '', 'uz' => ''],
'type' => $char['type'] ?? 'text',
'filter' => filter_var($char['filter'] ?? false, FILTER_VALIDATE_BOOLEAN)
]);
}
}
}
if (!empty($request->deletes['char'])) {
$chars = Characteristic::whereIn('id', $request->deletes['char'])->get();
foreach ($chars as $char) {
$char->values()->detach();
$char->delete();
}
}
});
} catch (Throwable $exception) {
Log::error('Category update failed', [
'category_id' => $category->id,
'message' => $exception->getMessage(),
'trace' => $exception->getTraceAsString(),
]);
return response()->json([
'status' => false,
'message' => 'Category could not be saved.',
'error' => config('app.debug') ? $exception->getMessage() : null,
], 500);
}
$this->success(trans('admin.messages.updated'));
return response()->json([
'status' => true
]);
}
/**
* @param Category $category
* @return \Illuminate\Http\RedirectResponse
* @throws \Exception
*/
public function delete($category)
{
$this->authorize('delete', 'categories');
$category = Category::findOrFail($category);
Storage::delete($category->image);
$category->delete();
$this->info(trans('admin.messages.deleted'));
return redirect()->back();
}
/**
* @param Request $request
* @return \Illuminate\Http\JsonResponse
*/
public function position_save(Request $request)
{
DB::transaction(function () use ($request) {
$this->saveCategoryPositions($request->input('categories', []), null);
});
$this->info(trans('admin.messages.updated'));
return response()->json([
'status' => true
]);
}
private function saveCategoryPositions(array $categories, $parentId = null): void
{
foreach (array_values($categories) as $index => $category) {
$cat = Category::find($category['id'] ?? null);
if (!$cat) {
continue;
}
$cat->parent_id = $this->normalizeParentId($parentId);
$cat->position = $index + 1;
$cat->save();
if (!empty($category['children']) && is_array($category['children'])) {
$this->saveCategoryPositions($category['children'], $cat->id);
}
}
}
private function normalizeParentId($parentId)
{
if (in_array($parentId, [null, '', 'null', 'NULL', 0, '0'], true)) {
return null;
}
return $parentId;
}
/**
* @return array
*/
public function test()
{
$categories = Category::select('id', 'name->ru as category')
->where('parent_id', null)
->with('parents.parents.parents')->get();
$cat = $this->category($categories->toArray());
$cats = array_merge(...$cat);
return $cats;
}
/**
* @param $categories
* @return array
*/
private function category($categories)
{
return array_map(function ($cat) {
$arr = [];
if (count($cat['parents']) > 0) {
$arr[] = [
'id' => $cat['id'],
'category' => $cat['name']['ru'],
'$isDisabled' => true
];
foreach ($cat['parents'] as $parent) {
if (count($parent['parents']) > 0) {
if (count($parent['parents']) > 0) {
$arr[] = [
'id' => $parent['id'],
'category' => $parent['name']['ru'],
'$isDisabled' => true
];
foreach ($parent['parents'] as $paren) {
$arr[] = [
'id' => $paren['id'],
'category' => $paren['name']['ru'],
'$isDisabled' => false
];
}
} else {
$arr[] = [
'id' => $parent['id'],
'category' => $parent['name']['ru'],
'$isDisabled' => false
];
}
} else {
$arr[] = [
'id' => $parent['id'],
'category' => $parent['name']['ru'],
'$isDisabled' => false
];
}
}
return $arr;
} else {
$arr = [
'id' => $cat['id'],
'category' => $cat['name']['ru'],
'$isDisabled' => false
];
return $arr;
}
}, $categories);
}
/**
* @return string
*/
public function json()
{
$categories = Category::select('id', 'name', 'parent_id as parrent', 'position', 'published')->latest('id')->get();
$data = "data ='{$categories}';";
return $data;
}
}