Update source into github

This commit is contained in:
pbao9
2025-07-24 16:18:27 +07:00
parent 41419358dd
commit 69851ac7bc
2642 changed files with 284095 additions and 0 deletions
@@ -0,0 +1,418 @@
<?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('admin.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("admin.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 => "admin.product.addon",
2 => "admin.product.domain.add",
3 => "admin.product.hosting",
4 => "admin.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 => "admin.product.addon",
2 => "admin.product.domain.add",
3 => "admin.product.hosting",
4 => "admin.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}");
}
}
}
}
}
}
}