- Changed view extends from "admin.main" to "administrator.layout.master" across multiple files. - Updated route names in admin.php and administrator.php to reflect new structure for user, order, invoice, and other management functionalities. - Adjusted view includes to point to the new directory structure for blocks and components. - Ensured all permission checks remain intact while refactoring the views.
419 lines
16 KiB
PHP
419 lines
16 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\admin;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Repositories\Addon\AddonRepositoryInterface;
|
|
use App\Repositories\Domain\DomainRepositoryInterface;
|
|
use App\Repositories\Group\GroupRepositoryInterface;
|
|
use App\Repositories\Hosting\HostingRepositoryInterface;
|
|
use App\Repositories\Os\OsRepositoryInterface;
|
|
use App\Repositories\Type\TypeRepositoryInterface;
|
|
use App\Repositories\VPS\VPSRepositoryInterface;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Cache;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Validator;
|
|
|
|
class ProductController extends Controller
|
|
{
|
|
public function __construct(
|
|
public TypeRepositoryInterface $typeRepository,
|
|
public GroupRepositoryInterface $groupRepository,
|
|
public VPSRepositoryInterface $vpsRepository,
|
|
public HostingRepositoryInterface $hostingRepository,
|
|
public DomainRepositoryInterface $domainRepository,
|
|
public AddonRepositoryInterface $addonRepository,
|
|
public OsRepositoryInterface $osRepository,
|
|
) {
|
|
parent::__construct();
|
|
}
|
|
|
|
public function index(Request $request)
|
|
{
|
|
$groups = $this->groupRepository->filter(
|
|
[
|
|
'page' => $request->get('page') ?? 1
|
|
],
|
|
[]
|
|
);
|
|
$groups->getCollection()->transform(function ($item) {
|
|
$item->products = $this->groupRepository->getProduct($item->id, $item->type_id);
|
|
return $item;
|
|
});
|
|
|
|
$title = "List All Product";
|
|
|
|
return view('administrator.pages.product.index', compact('title', 'groups'));
|
|
}
|
|
|
|
public function create(Request $request)
|
|
{
|
|
$step = $request->get('step') ?? 1;
|
|
$title = 'Add new product';
|
|
$group = $this->groupRepository->getAll();
|
|
$type = $this->typeRepository->getAll();
|
|
if ($step === 1) {
|
|
return view("administrator.pages.product.first", compact('group', 'type', 'title'));
|
|
}
|
|
|
|
$validator = Validator::make($request->except('_token'), [
|
|
'step' => 'required',
|
|
'type' => 'required'
|
|
]);
|
|
if ($validator->fails()) {
|
|
return back()->withErrors($validator->getMessageBag());
|
|
}
|
|
|
|
$type_id = (int) $request->type;
|
|
$group_id = (int) $request->group;
|
|
$product_name = $request->name;
|
|
|
|
$view = null;
|
|
|
|
$view = match ((int) $type_id) {
|
|
1 => "administrator.pages.product.addon",
|
|
2 => "administrator.pages.product.domain.add",
|
|
3 => "administrator.pages.product.hosting",
|
|
4 => "administrator.pages.product.vps"
|
|
};
|
|
|
|
// Thêm dữ liệu OS cho VPS
|
|
$data = compact('type_id', 'group_id', 'title', 'group', 'type', 'product_name');
|
|
if ((int) $type_id === 4) {
|
|
$data['os'] = $this->osRepository->filter(['status' => 1], ['osGroup']);
|
|
}
|
|
|
|
return view($view, $data);
|
|
}
|
|
|
|
public function store(Request $request)
|
|
{
|
|
if (!$request->type_id)
|
|
return back()->withErrors('Please choose Type Product');
|
|
$validator = null;
|
|
$repository = match ((int) $request->type_id) {
|
|
1 => $this->addonRepository,
|
|
2 => $this->domainRepository,
|
|
3 => $this->hostingRepository,
|
|
4 => $this->vpsRepository,
|
|
default => throw new \UnexpectedValueException("Invalid type_id: " . $request->type_id)
|
|
};
|
|
$route = match ((int) $request->type_id) {
|
|
1 => route('addon.index'),
|
|
2 => route('domain.index'),
|
|
default => route('product.index')
|
|
};
|
|
$validator = match ((int) $request->type_id) {
|
|
1 => Validator::make($request->all(), [
|
|
'name' => 'required',
|
|
'price' => 'required|numeric',
|
|
'min' => 'required|numeric',
|
|
'max' => 'required|numeric',
|
|
'step' => 'required|numeric',
|
|
'prefix' => 'required',
|
|
'type_id' => 'required|numeric'
|
|
]),
|
|
2 => Validator::make($request->all(), [
|
|
'name' => 'required',
|
|
'price' => 'required',
|
|
'renewal' => 'required',
|
|
'transfer' => 'required',
|
|
'type_id' => 'required',
|
|
'auto_reg' => 'required',
|
|
'status' => 'required'
|
|
]),
|
|
3 => Validator::make($request->all(), [
|
|
'name' => 'required',
|
|
'price' => 'required',
|
|
'description' => 'required',
|
|
'template' => 'required',
|
|
'type_id' => 'required',
|
|
'group_id' => 'required',
|
|
'status' => 'required'
|
|
]),
|
|
4 => Validator::make($request->all(), [
|
|
'name' => 'required',
|
|
'cpu' => 'required',
|
|
'ram' => 'required',
|
|
'disk' => 'required',
|
|
'bandwidth' => 'required',
|
|
'module_host_id' => 'required|not_in:0',
|
|
'price' => 'required',
|
|
'type_id' => 'required',
|
|
'group_id' => 'required',
|
|
'status' => 'required'
|
|
])
|
|
};
|
|
|
|
if ($validator->fails()) {
|
|
return back()->withErrors($validator->getMessageBag());
|
|
}
|
|
if ($repository) {
|
|
DB::beginTransaction();
|
|
try {
|
|
if ((int) $request->type_id === 4 && method_exists($repository, 'createWithOs')) {
|
|
// VPS with OS relationship
|
|
$osIds = $request->input('operating_systems', []);
|
|
$repository->createWithOs($request->all(), $osIds);
|
|
} else {
|
|
$repository->create($request->all());
|
|
}
|
|
|
|
// Clear all related caches after successful creation
|
|
$this->clearProductCaches($request->type_id, $request->group_id);
|
|
|
|
DB::commit();
|
|
} catch (\Exception $error) {
|
|
DB::rollBack();
|
|
return back()->withErrors($error->getMessage());
|
|
}
|
|
|
|
return redirect($route)->with('success', 'Add new product success');
|
|
}
|
|
return back()->withErrors("Can't find a model by Type");
|
|
}
|
|
|
|
public function edit(Request $request)
|
|
{
|
|
$validator = Validator::make($request->all(), [
|
|
'product_id' => 'required',
|
|
'type_id' => 'required'
|
|
]);
|
|
if ($validator->fails()) {
|
|
return back()->withErrors($validator->getMessageBag());
|
|
}
|
|
$type_id = (int) $request->type_id;
|
|
|
|
$title = 'View product item';
|
|
$group = $this->groupRepository->getAll();
|
|
$type = $this->typeRepository->getAll();
|
|
$view = match ((int) $type_id) {
|
|
1 => "administrator.pages.product.addon",
|
|
2 => "administrator.pages.product.domain.add",
|
|
3 => "administrator.pages.product.hosting",
|
|
4 => "administrator.pages.product.vps"
|
|
};
|
|
$repository = match ((int) $type_id) {
|
|
1 => $this->addonRepository,
|
|
2 => $this->domainRepository,
|
|
3 => $this->hostingRepository,
|
|
4 => $this->vpsRepository,
|
|
default => throw new \UnexpectedValueException("Invalid type_id: " . $request->type_id)
|
|
};
|
|
if ($repository && method_exists($repository, 'findWithRelationships')) {
|
|
// Load relationships based on product type
|
|
$relationships = ['host.datacenter'];
|
|
if ((int) $type_id === 4) {
|
|
$relationships[] = 'operatingSystems';
|
|
}
|
|
|
|
$product = $repository->findWithRelationships($request->product_id, $relationships);
|
|
|
|
// Thêm dữ liệu OS cho VPS
|
|
$data = compact('type_id', 'product', 'title', 'group', 'type');
|
|
if ((int) $type_id === 4) {
|
|
$data['os'] = $this->osRepository->filter(['status' => 1], ['osGroup']);
|
|
}
|
|
|
|
return view($view, $data);
|
|
}
|
|
return back()->withErrors("Can't find a model by Type");
|
|
}
|
|
|
|
public function update(Request $request)
|
|
{
|
|
$validator = Validator::make($request->all(), [
|
|
'product_id' => 'required',
|
|
'type_id' => 'required'
|
|
]);
|
|
if ($validator->fails()) {
|
|
return back()->withErrors($validator->getMessageBag());
|
|
}
|
|
$route = match ((int) $request->type_id) {
|
|
1 => route('addon.index'),
|
|
2 => route('domain.index'),
|
|
default => route('product.index')
|
|
};
|
|
$repository = match ((int) $request->type_id) {
|
|
1 => $this->addonRepository,
|
|
2 => $this->domainRepository,
|
|
3 => $this->hostingRepository,
|
|
4 => $this->vpsRepository,
|
|
default => throw new \UnexpectedValueException("Invalid type_id: " . $request->type_id)
|
|
};
|
|
|
|
$product = $repository->find($request->product_id);
|
|
if (!$product)
|
|
return back()->withErrors("Can't find a product item");
|
|
|
|
$validator = match ((int) $request->type_id) {
|
|
1 => Validator::make($request->all(), [
|
|
'name' => 'required',
|
|
'price' => 'required|numeric',
|
|
'min' => 'required|numeric',
|
|
'max' => 'required|numeric',
|
|
'step' => 'required|numeric',
|
|
'prefix' => 'required',
|
|
'type_id' => 'required|numeric'
|
|
]),
|
|
2 => Validator::make($request->all(), [
|
|
'name' => 'required',
|
|
'price' => 'required',
|
|
'renewal' => 'required',
|
|
'transfer' => 'required',
|
|
'type_id' => 'required',
|
|
'auto_reg' => 'required',
|
|
'status' => 'required'
|
|
]),
|
|
3 => Validator::make($request->all(), [
|
|
'name' => 'required',
|
|
'price' => 'required',
|
|
'description' => 'required',
|
|
'cpu' => 'required',
|
|
'ram' => 'required',
|
|
'disk' => 'required',
|
|
'bandwidth' => 'required',
|
|
'ip' => 'required',
|
|
'template' => 'required',
|
|
'type_id' => 'required',
|
|
'group_id' => 'required',
|
|
'status' => 'required'
|
|
]),
|
|
4 => Validator::make($request->all(), [
|
|
'name' => 'required',
|
|
'cpu' => 'required',
|
|
'ram' => 'required',
|
|
'disk' => 'required',
|
|
'bandwidth' => 'required',
|
|
'module_host_id' => 'required|not_in:0',
|
|
'price' => 'required',
|
|
'type_id' => 'required',
|
|
'group_id' => 'required',
|
|
'status' => 'required'
|
|
])
|
|
};
|
|
|
|
if ($validator->fails()) {
|
|
return back()->withErrors($validator->getMessageBag());
|
|
}
|
|
if ($repository) {
|
|
try {
|
|
DB::beginTransaction();
|
|
if ((int) $request->type_id === 4 && method_exists($repository, 'updateWithOs')) {
|
|
// VPS with OS relationship
|
|
$osIds = $request->input('operating_systems', []);
|
|
$repository->updateWithOs($request->get('product_id'), $request->all(), $osIds);
|
|
} else {
|
|
$repository->update($request->get('product_id'), $request->all());
|
|
}
|
|
|
|
// Clear all related caches after successful update
|
|
$this->clearProductCaches($request->type_id, $request->group_id);
|
|
|
|
DB::commit();
|
|
} catch (\Exception $error) {
|
|
DB::rollBack();
|
|
return back()->withErrors($error->getMessage());
|
|
}
|
|
return redirect($route)->with('success', 'Update new information product success');
|
|
}
|
|
return back()->withErrors("Can't find a model by Type");
|
|
}
|
|
|
|
public function destroy(Request $request)
|
|
{
|
|
$validator = Validator::make($request->all(), [
|
|
'product_id' => 'required',
|
|
'type' => 'required'
|
|
]);
|
|
if ($validator->fails()) {
|
|
return back()->withErrors($validator->getMessageBag());
|
|
}
|
|
|
|
|
|
$repository = match ((int) $request->type) {
|
|
1 => $this->addonRepository,
|
|
2 => $this->domainRepository,
|
|
3 => $this->hostingRepository,
|
|
4 => $this->vpsRepository,
|
|
default => throw new \UnexpectedValueException("Invalid type_id: " . $request->type_id)
|
|
};
|
|
$route = match ((int) $request->type) {
|
|
1 => route('addon.index'),
|
|
2 => route('domain.index'),
|
|
default => route('product.index')
|
|
};
|
|
|
|
if ($repository) {
|
|
|
|
$product = $repository->find($request->product_id);
|
|
|
|
if (!$product)
|
|
return back()->withErrors("Can't find a product item");
|
|
|
|
try {
|
|
DB::beginTransaction();
|
|
$repository->delete($request->get('product_id'));
|
|
|
|
// Clear all related caches after successful deletion
|
|
$this->clearProductCaches($request->type, $product->group_id ?? null);
|
|
|
|
DB::commit();
|
|
} catch (\Exception $error) {
|
|
DB::rollBack();
|
|
return back()->withErrors($error->getMessage());
|
|
}
|
|
return redirect($route)->with('success', 'Deleted successfully');
|
|
}
|
|
return back()->withErrors("Can't find a Product");
|
|
}
|
|
|
|
/**
|
|
* Clear all product-related caches
|
|
*/
|
|
private function clearProductCaches($typeId, $groupId = null)
|
|
{
|
|
// Clear general shop caches
|
|
Cache::forget('shop_types_with_groups');
|
|
|
|
if ($typeId) {
|
|
// Clear type-specific group cache
|
|
Cache::forget("groups_type_{$typeId}");
|
|
|
|
if ($groupId) {
|
|
// Clear product cache for specific type and group
|
|
Cache::forget("products_type_{$typeId}_group_{$groupId}");
|
|
|
|
// Clear paginated product caches - we need to clear multiple pages
|
|
$group = $this->groupRepository->find($groupId);
|
|
if ($group && $group->slug) {
|
|
// Clear group product caches for multiple pages (assuming max 10 pages)
|
|
for ($page = 1; $page <= 10; $page++) {
|
|
Cache::forget("group_products_{$group->slug}_page_{$page}");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Clear all VPS and Hosting caches if type is not specified
|
|
if (!$typeId) {
|
|
$types = [3, 4]; // Hosting and VPS
|
|
foreach ($types as $type) {
|
|
Cache::forget("groups_type_{$type}");
|
|
|
|
// Clear all group caches for this type
|
|
$groups = $this->groupRepository->filter(['type_id' => $type]);
|
|
foreach ($groups as $group) {
|
|
Cache::forget("products_type_{$type}_group_{$group->id}");
|
|
if ($group->slug) {
|
|
for ($page = 1; $page <= 10; $page++) {
|
|
Cache::forget("group_products_{$group->slug}_page_{$page}");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|